diff --git a/ANNOUNCE b/ANNOUNCE index 0fb688344..825837614 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,46 +1,33 @@ -*** ANNOUNCE: SWIG 1.3.35 (7 April 2008) *** +*** ANNOUNCE: SWIG 2.0.6 (30 April 2012) *** http://www.swig.org - -We're pleased to announce SWIG-1.3.35, the latest installment in the -SWIG development effort. SWIG-1.3.35 includes a number of bug fixes -and large number of enhancements throughout. +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-1.3.35.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-1.3.35.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 diff --git a/CCache/COPYING b/CCache/COPYING new file mode 100644 index 000000000..a43ea2126 --- /dev/null +++ b/CCache/COPYING @@ -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. + + + Copyright (C) 19yy + + 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. + + , 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. diff --git a/CCache/Makefile.in b/CCache/Makefile.in new file mode 100644 index 000000000..d8f9042fe --- /dev/null +++ b/CCache/Makefile.in @@ -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 diff --git a/CCache/README b/CCache/README new file mode 100644 index 000000000..6e68a6eb0 --- /dev/null +++ b/CCache/README @@ -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 + diff --git a/CCache/README.swig b/CCache/README.swig new file mode 100644 index 000000000..aea0f3d82 --- /dev/null +++ b/CCache/README.swig @@ -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. diff --git a/CCache/args.c b/CCache/args.c new file mode 100644 index 000000000..31e5471c1 --- /dev/null +++ b/CCache/args.c @@ -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;iargv = (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; iargc; ) { + 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++; + } + } +} diff --git a/CCache/ccache.c b/CCache/ccache.c new file mode 100644 index 000000000..d1696da88 --- /dev/null +++ b/CCache/ccache.c @@ -0,0 +1,1388 @@ +/* + a re-implementation of the compilercache scripts in C + + The idea is based on the shell-script compilercache by Erik Thiele + + Copyright (C) Andrew Tridgell 2002 + Copyright (C) Martin Pool 2003 + + 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" + +/* verbose mode */ +int ccache_verbose = 0; + +/* the base cache directory */ +char *cache_dir = NULL; + +/* the directory for temporary files */ +static char *temp_dir = NULL; + +/* the debug logfile name, if set */ +char *cache_logfile = NULL; + +/* the argument list after processing */ +static ARGS *stripped_args; + +/* the original argument list */ +static ARGS *orig_args; + +/* the output filename being compiled to */ +static char *output_file; + +/* the source file */ +static char *input_file; + +/* the name of the file containing the cached object code */ +static char *hashname; + +/* the extension of the file after pre-processing */ +static const char *i_extension; + +/* the name of the temporary pre-processor file */ +static char *i_tmpfile; + +/* are we compiling a .i or .ii file directly? */ +static int direct_i_file; + +/* the name of the cpp stderr file */ +static char *cpp_stderr; + +/* the name of the statistics file */ +char *stats_file = NULL; + +/* can we safely use the unification hashing backend? */ +static int enable_unify; + +/* should we strip -c when running the preprocessor only? */ +static int strip_c_option; + +/* customisation for using the SWIG compiler */ +static int swig; + +/* a list of supported file extensions, and the equivalent + extension for code that has been through the pre-processor +*/ +static struct { + char *extension; + char *i_extension; +} extensions[] = { + {"c", "i"}, + {"C", "ii"}, + {"m", "mi"}, + {"cc", "ii"}, + {"CC", "ii"}, + {"cpp", "ii"}, + {"CPP", "ii"}, + {"cxx", "ii"}, + {"CXX", "ii"}, + {"c++", "ii"}, + {"C++", "ii"}, + {"i", "i"}, + {"ii", "ii"}, + {NULL, NULL}}; + +/* + something went badly wrong - just execute the real compiler +*/ +static void failed(void) +{ + char *e; + + /* delete intermediate pre-processor file if needed */ + if (i_tmpfile) { + if (!direct_i_file) { + unlink(i_tmpfile); + } + free(i_tmpfile); + i_tmpfile = NULL; + } + + /* delete the cpp stderr file if necessary */ + if (cpp_stderr) { + unlink(cpp_stderr); + free(cpp_stderr); + cpp_stderr = NULL; + } + + /* strip any local args */ + args_strip(orig_args, "--ccache-"); + + if ((e=getenv("CCACHE_PREFIX"))) { + char *p = find_executable(e, MYNAME); + if (!p) { + cc_log("could not find executable (%s)\n", e); + perror(e); + exit(1); + } + args_add_prefix(orig_args, p); + } + + if (ccache_verbose) { + display_execute_args(orig_args->argv); + } + + if (swig) { + putenv("CCACHE_OUTFILES"); + } + +#ifndef _WIN32 + execv(orig_args->argv[0], orig_args->argv); + cc_log("execv returned (%s)!\n", strerror(errno)); + perror(orig_args->argv[0]); + exit(1); +#else + /* execv on Windows causes the 'non-regular' testcase to fail, so use Win32 API instead */ + { + PROCESS_INFORMATION pinfo; + STARTUPINFO sinfo; + BOOL ret; + DWORD exitcode; + char *args; + + ZeroMemory(&pinfo, sizeof(PROCESS_INFORMATION)); + ZeroMemory(&sinfo, sizeof(STARTUPINFO)); + sinfo.cb = sizeof(STARTUPINFO); + args = argvtos(orig_args->argv); + ret = CreateProcessA(orig_args->argv[0], args, NULL, NULL, TRUE, 0, NULL, NULL, + &sinfo, &pinfo); + if (!ret) { + exitcode = 1; + cc_log("CreateProcessA failed starting %s\n", orig_args->argv[0]); + perror_win32(orig_args->argv[0]); + } else { + WaitForSingleObject(pinfo.hProcess, INFINITE); + GetExitCodeProcess(pinfo.hProcess, &exitcode); + CloseHandle(pinfo.hProcess); + CloseHandle(pinfo.hThread); + } + free(args); + exit(exitcode); + } +#endif +} + + +/* return a string to be used to distinguish temporary files + this also tries to cope with NFS by adding the local hostname +*/ +static const char *tmp_string(void) +{ + static char *ret; + + if (!ret) { + char hostname[200]; + strcpy(hostname, "unknown"); +#if HAVE_GETHOSTNAME + gethostname(hostname, sizeof(hostname)-1); +#endif + hostname[sizeof(hostname)-1] = 0; + if (asprintf(&ret, "%s.%u", hostname, (unsigned)getpid()) == -1) { + fatal("could not allocate tmp_string"); + } + } + + return ret; +} + +/* update cached file sizes and count helper function for to_cache() */ +static void to_cache_stats_helper(struct stat *pstat, char *cached_filename, char *tmp_outfiles, int *files_size, int *cached_files_count) +{ +#if ENABLE_ZLIB + /* do an extra stat on the cache file for the size statistics */ + if (stat(cached_filename, pstat) != 0) { + cc_log("failed to stat cache files - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + if (tmp_outfiles) { + unlink(tmp_outfiles); + } + failed(); + } +#else + (void)cached_filename; + (void)tmp_outfiles; +#endif + (*files_size) += file_size(pstat); + (*cached_files_count)++; +} + +/* run the real compiler and put the result in cache */ +static void to_cache(ARGS *args) +{ + char *path_stderr; + char *tmp_stdout, *tmp_stderr, *tmp_outfiles; + struct stat st1; + int status; + int cached_files_count = 0; + int files_size = 0; + + x_asprintf(&tmp_stdout, "%s/tmp.stdout.%s", temp_dir, tmp_string()); + x_asprintf(&tmp_stderr, "%s/tmp.stderr.%s", temp_dir, tmp_string()); + x_asprintf(&tmp_outfiles, "%s/tmp.outfiles.%s", temp_dir, tmp_string()); + + if (strip_c_option && !swig) { + args_add(stripped_args, "-c"); + } + + if (output_file) { + args_add(args, "-o"); + args_add(args, output_file); + } + + /* Turn off DEPENDENCIES_OUTPUT when running cc1, because + * otherwise it will emit a line like + * + * tmp.stdout.vexed.732.o: /home/mbp/.ccache/tmp.stdout.vexed.732.i + * + * unsetenv() is on BSD and Linux but not portable. */ + putenv("DEPENDENCIES_OUTPUT"); + + /* Give SWIG a filename for it to create and populate with a list of files that it generates */ + if (swig) { + char *ccache_outfiles; + x_asprintf(&ccache_outfiles, "CCACHE_OUTFILES=%s", tmp_outfiles); + unlink(tmp_outfiles); + if (getenv("CCACHE_OUTFILES") || putenv(ccache_outfiles) == -1) { + cc_log("CCACHE_OUTFILES env variable already set or could not be set\n"); + stats_update(STATS_ERROR); + failed(); + } + } + + if (getenv("CCACHE_CPP2")) { + args_add(args, input_file); + } else { + if (swig) { + args_add(args, "-nopreprocess"); + } + args_add(args, i_tmpfile); + } + status = execute(args->argv, tmp_stdout, tmp_stderr); + args_pop(args, 3); + + if (stat(tmp_stdout, &st1) != 0 || st1.st_size != 0) { + cc_log("compiler produced stdout for %s\n", input_file); + stats_update(STATS_STDOUT); + unlink(tmp_stdout); + unlink(tmp_stderr); + unlink(tmp_outfiles); + if (!swig) unlink(output_file); + failed(); + } + unlink(tmp_stdout); + + if (status != 0) { + int fd; + cc_log("compile of %s gave status = %d\n", input_file, status); + stats_update(STATS_STATUS); + + fd = open(tmp_stderr, O_RDONLY | O_BINARY); + if (fd != -1) { + if (cpp_stderr) { + /* we might have some stderr from cpp */ + int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY); + if (fd2 != -1) { + copy_fd(fd2, 2); + close(fd2); + unlink(cpp_stderr); + cpp_stderr = NULL; + } + } + + /* we can use a quick method of + getting the failed output */ + copy_fd(fd, 2); + close(fd); + unlink(tmp_stderr); + if (i_tmpfile && !direct_i_file) { + unlink(i_tmpfile); + } + exit(status); + } + + unlink(tmp_stderr); + unlink(tmp_outfiles); + if (!swig) unlink(output_file); + failed(); + } else { + int hardlink = (getenv("CCACHE_NOCOMPRESS") != 0) && (getenv("CCACHE_HARDLINK") != 0); + if (swig) { + /* read the list of generated files and copy each of them into the cache */ + FILE *file; + file = fopen(tmp_outfiles, "r"); + if (file) { + char out_filename[FILENAME_MAX + 1]; + char out_filename_cache[FILENAME_MAX + 1]; + while (fgets(out_filename, FILENAME_MAX, file)) { + char *linefeed = strchr(out_filename, '\n'); + if (linefeed) { + char *potential_cr = linefeed - 1; + if (potential_cr >= out_filename && *potential_cr == '\r') + *potential_cr = 0; + *linefeed = 0; + + if (cached_files_count == 0) { + strcpy(out_filename_cache, hashname); + } else { + sprintf(out_filename_cache, "%s.%d", hashname, cached_files_count); + } + + if (commit_to_cache(out_filename, out_filename_cache, hardlink) != 0) { + fclose(file); + unlink(tmp_outfiles); + failed(); + } + to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count); + } else { + cached_files_count = 0; + break; + } + } + fclose(file); + if (cached_files_count == 0) { + cc_log("failed to copy output files to cache - internal error\n"); + stats_update(STATS_ERROR); + unlink(tmp_outfiles); + failed(); + } + + /* also copy the (uncompressed) file containing the list of generated files into the cache */ + sprintf(out_filename_cache, "%s.outfiles", hashname); + if (stat(tmp_outfiles, &st1) != 0 || + safe_rename(tmp_outfiles, out_filename_cache) != 0) { + cc_log("failed to copy outfiles file to cache - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + unlink(tmp_outfiles); + failed(); + } + to_cache_stats_helper(&st1, out_filename_cache, tmp_outfiles, &files_size, &cached_files_count); + unlink(tmp_outfiles); + } else { + cc_log("failed to open temp outfiles file - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + failed(); + } + } else { + if (commit_to_cache(output_file, hashname, hardlink) != 0) { + failed(); + } + to_cache_stats_helper(&st1, hashname, 0, &files_size, &cached_files_count); + } + } + + x_asprintf(&path_stderr, "%s.stderr", hashname); + + if (stat(tmp_stderr, &st1) != 0 || + move_file(tmp_stderr, path_stderr) != 0) { + cc_log("failed to rename tmp files - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + failed(); + } + + to_cache_stats_helper(&st1, path_stderr, 0, &files_size, &cached_files_count); + + cc_log("Placed %d files for %s into cache\n", cached_files_count, input_file); + stats_tocache(files_size, cached_files_count); + + free(tmp_stderr); + free(tmp_stdout); + free(tmp_outfiles); + free(path_stderr); +} + +/* find the hash for a command. The hash includes all argument lists, + plus the output from running the compiler with -E */ +static void find_hash(ARGS *args) +{ + int i; + char *path_stdout, *path_stderr; + char *hash_dir; + char *s; + struct stat st; + int status; + int nlevels = 2; + char *input_base; + char *tmp; + + if ((s = getenv("CCACHE_NLEVELS"))) { + nlevels = atoi(s); + if (nlevels < 1) nlevels = 1; + if (nlevels > 8) nlevels = 8; + } + + hash_start(); + + /* when we are doing the unifying tricks we need to include + the input file name in the hash to get the warnings right */ + if (enable_unify || swig) { + hash_string(input_file); + } + + if (swig) { + if (output_file) { + hash_string(output_file); + } + } else { + /* we have to hash the extension, as a .i file isn't treated the same + by the compiler as a .ii file */ + hash_string(i_extension); + } + + /* first the arguments */ + for (i=1;iargc;i++) { + /* some arguments don't contribute to the hash. The + theory is that these arguments will change the + output of -E if they are going to have any effect + at all, or they only affect linking */ + if (i < args->argc-1) { + if (strcmp(args->argv[i], "-I") == 0 || + strcmp(args->argv[i], "-include") == 0 || + strcmp(args->argv[i], "-L") == 0 || + strcmp(args->argv[i], "-D") == 0 || + strcmp(args->argv[i], "-idirafter") == 0 || + strcmp(args->argv[i], "-isystem") == 0) { + i++; + continue; + } + } + if (strncmp(args->argv[i], "-I", 2) == 0 || + strncmp(args->argv[i], "-L", 2) == 0 || + strncmp(args->argv[i], "-D", 2) == 0 || + strncmp(args->argv[i], "-idirafter", 10) == 0 || + strncmp(args->argv[i], "-isystem", 8) == 0) { + continue; + } + + if (strncmp(args->argv[i], "--specs=", 8) == 0 && + stat(args->argv[i]+8, &st) == 0) { + /* if given a explicit specs file, then hash that file, but + don't include the path to it in the hash */ + hash_file(args->argv[i]+8); + continue; + } + + /* all other arguments are included in the hash */ + hash_string(args->argv[i]); + } + + /* the compiler driver size and date. This is a simple minded way + to try and detect compiler upgrades. It is not 100% reliable */ + if (stat(args->argv[0], &st) != 0) { + cc_log("Couldn't stat the compiler!? (argv[0]='%s')\n", args->argv[0]); + stats_update(STATS_COMPILER); + failed(); + } + + /* also include the hash of the compiler name - as some compilers + use hard links and behave differently depending on the real name */ + if (st.st_nlink > 1) { + hash_string(str_basename(args->argv[0])); + } + + hash_int(st.st_size); + hash_int(st.st_mtime); + + /* possibly hash the current working directory */ + if (getenv("CCACHE_HASHDIR")) { + char *cwd = gnu_getcwd(); + if (cwd) { + hash_string(cwd); + free(cwd); + } + } + + /* ~/hello.c -> tmp.hello.123.i + limit the basename to 10 + characters in order to cope with filesystem with small + maximum filename length limits */ + input_base = str_basename(input_file); + tmp = strchr(input_base, '.'); + if (tmp != NULL) { + *tmp = 0; + } + if (strlen(input_base) > 10) { + input_base[10] = 0; + } + + /* now the run */ + x_asprintf(&path_stdout, "%s/%s.tmp.%s.%s", temp_dir, + input_base, tmp_string(), + i_extension); + x_asprintf(&path_stderr, "%s/tmp.cpp_stderr.%s", temp_dir, tmp_string()); + + if (!direct_i_file) { + /* run cpp on the input file to obtain the .i */ + args_add(args, "-E"); + args_add(args, input_file); + status = execute(args->argv, path_stdout, path_stderr); + args_pop(args, 2); + } else { + /* we are compiling a .i or .ii file - that means we + can skip the cpp stage and directly form the + correct i_tmpfile */ + path_stdout = x_strdup(input_file); + if (create_empty_file(path_stderr) != 0) { + cc_log("failed to create empty stderr file\n"); + stats_update(STATS_ERROR); + failed(); + } + status = 0; + } + + if (status != 0) { + if (!direct_i_file) { + unlink(path_stdout); + } + unlink(path_stderr); + cc_log("the preprocessor gave %d\n", status); + stats_update(STATS_PREPROCESSOR); + failed(); + } + + /* if the compilation is with -g then we have to include the whole of the + preprocessor output, which means we are sensitive to line number + information. Otherwise we can discard line number info, which makes + us less sensitive to reformatting changes + + Note! I have now disabled the unification code by default + as it gives the wrong line numbers for warnings. Pity. + */ + if (!enable_unify) { + hash_file(path_stdout); + } else { + if (unify_hash(path_stdout) != 0) { + stats_update(STATS_ERROR); + failed(); + } + } + hash_file(path_stderr); + + i_tmpfile = path_stdout; + + if (!getenv("CCACHE_CPP2")) { + /* if we are using the CPP trick then we need to remember this stderr + data and output it just before the main stderr from the compiler + pass */ + cpp_stderr = path_stderr; + } else { + unlink(path_stderr); + free(path_stderr); + } + + /* we use a N level subdir for the cache path to reduce the impact + on filesystems which are slow for large directories + */ + s = hash_result(); + x_asprintf(&hash_dir, "%s/%c", cache_dir, s[0]); + x_asprintf(&stats_file, "%s/stats", hash_dir); + for (i=1; i= out_filename && *potential_cr == '\r') + *potential_cr = 0; + *linefeed = 0; + + if (retrieved_files_count == 0) { + strcpy(out_filename_cache, hashname); + } else { + sprintf(out_filename_cache, "%s.%d", hashname, retrieved_files_count); + } + + passfail = retrieve_from_cache(out_filename_cache, out_filename, hardlink); + if (passfail == -1) { + break; + } + + retrieved_files_count++; + } else { + cc_log("failed to copy output files from cache - internal error\n"); + stats_update(STATS_ERROR); + passfail = -1; + break; + } + } + if (retrieved_files_count == 0) { + cc_log("failed to copy output files from cache - internal error\n"); + stats_update(STATS_ERROR); + passfail = -1; + } + fclose(file); + } else { + cc_log("failed to open cached outfiles file - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + } + } else { + passfail = retrieve_from_cache(hashname, output_file, hardlink); + } + + free(stderr_file); + if (passfail == -1) { + close(fd_stderr); + unlink(stderr_file); + return; + } + } + + /* get rid of the intermediate preprocessor file */ + if (i_tmpfile) { + if (!direct_i_file) { + unlink(i_tmpfile); + } + free(i_tmpfile); + i_tmpfile = NULL; + } + + /* send the cpp stderr, if applicable */ + fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY); + if (fd_cpp_stderr != -1) { + copy_fd(fd_cpp_stderr, 2); + close(fd_cpp_stderr); + unlink(cpp_stderr); + free(cpp_stderr); + cpp_stderr = NULL; + } + + /* send the stderr */ + copy_fd(fd_stderr, 2); + close(fd_stderr); + + /* and exit with the right status code */ + if (first) { + cc_log("got cached result for %s\n", input_file); + stats_update(STATS_CACHED); + } + + exit(0); +} + +/* find the real compiler. We just search the PATH to find a executable of the + same name that isn't a link to ourselves */ +static void find_compiler(int argc, char **argv) +{ + char *base; + char *path; + + orig_args = args_init(argc, argv); + + base = str_basename(argv[0]); + + /* we might be being invoked like "ccache gcc -c foo.c" */ + if (strcmp(base, MYNAME) == 0) { + args_remove_first(orig_args); + free(base); + if (strchr(argv[1],'/') +#ifdef _WIN32 + || strchr(argv[1],'\\') +#endif + ) { + /* a full path was given */ + return; + } + base = str_basename(argv[1]); + } + + /* support user override of the compiler */ + if ((path=getenv("CCACHE_CC"))) { + base = x_strdup(path); + } + + orig_args->argv[0] = find_executable(base, MYNAME); + + /* can't find the compiler! */ + if (!orig_args->argv[0]) { + stats_update(STATS_COMPILER); + cc_log("could not find compiler (%s)\n", base); + perror(base); + exit(1); + } +} + + +/* check a filename for C/C++ extension. Return the pre-processor + extension */ +static const char *check_extension(const char *fname, int *direct_i) +{ + int i; + const char *p; + + if (direct_i) { + *direct_i = 0; + } + + if (swig) return "ii"; /* any file extension is acceptable as input for SWIG */ + + p = strrchr(fname, '.'); + if (!p) return NULL; + p++; + for (i=0; extensions[i].extension; i++) { + if (strcmp(p, extensions[i].extension) == 0) { + if (direct_i && strcmp(p, extensions[i].i_extension) == 0) { + *direct_i = 1; + } + p = getenv("CCACHE_EXTENSION"); + if (p) return p; + return extensions[i].i_extension; + } + } + return NULL; +} + + +/* + process the compiler options to form the correct set of options + for obtaining the preprocessor output +*/ +static void process_args(int argc, char **argv) +{ + int i; + int found_c_opt = 0; + 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); + + args_add(stripped_args, argv[0]); + + /* -c not required for SWIG */ + if (swig) { + found_c_opt = 1; + } + + for (i=1; iargv[0]); + if (strstr(basename, "swig") || getenv("CCACHE_SWIG")) { + swig = 1; + } + free(basename); +} + +/* the main ccache driver function */ +static void ccache(int argc, char *argv[]) +{ + /* 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")) { + cc_log("ccache is disabled\n"); + failed(); + } + + if (getenv("CCACHE_STRIPC")) { + strip_c_option = 1; + } + + if (getenv("CCACHE_UNIFY")) { + enable_unify = 1; + } + + detect_swig(); + + /* process argument list, returning a new set of arguments for pre-processing */ + process_args(orig_args->argc, orig_args->argv); + + /* run with -E to find the hash */ + find_hash(stripped_args); + + /* if we can return from cache at this point then do */ + from_cache(1); + + if (getenv("CCACHE_READONLY")) { + cc_log("read-only set - doing real compile\n"); + failed(); + } + + /* run real compiler, sending output to cache */ + to_cache(stripped_args); + + /* return from cache */ + from_cache(0); + + /* oh oh! */ + cc_log("secondary from_cache failed!\n"); + stats_update(STATS_ERROR); + failed(); +} + + +static void usage(void) +{ + printf("%s, a compiler cache including support for SWIG. Version %s\n", MYNAME, CCACHE_VERSION); + printf("Copyright Andrew Tridgell, 2002\n\n"); + + printf("Usage:\n"); + printf("\t" MYNAME " [options]\n"); + printf("\t" MYNAME " compiler [compile options]\n"); + 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 set maximum files in cache\n"); + printf("-M set maximum size of cache (use G, M or K)\n"); + printf("-h this help page\n"); + 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[]) +{ + int c; + size_t v; + + while ((c = getopt(argc, argv, "hszcCF:M:V")) != -1) { + switch (c) { + case 'V': + printf("%s version %s\n", MYNAME, CCACHE_VERSION); + printf("Copyright Andrew Tridgell 2002\n"); + printf("Released under the GNU GPL v2 or later\n"); + exit(0); + + case 'h': + usage(); + 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); + 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); + 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: + usage(); + exit(1); + } + } + + return 0; +} + + +/* Make a copy of stderr that will not be cached, so things like + distcc can send networking errors to it. */ +static void setup_uncached_err(void) +{ + char *buf; + int uncached_fd; + + uncached_fd = dup(2); + if (uncached_fd == -1) { + cc_log("dup(2) failed\n"); + stats_update(STATS_ERROR); + failed(); + } + + /* leak a pointer to the environment */ + x_asprintf(&buf, "UNCACHED_ERR_FD=%d", uncached_fd); + + if (putenv(buf) == -1) { + cc_log("putenv failed\n"); + stats_update(STATS_ERROR); + failed(); + } +} + + +int main(int argc, char *argv[]) +{ + char *p; + + cache_dir = getenv("CCACHE_DIR"); + if (!cache_dir) { + const char *home_directory = get_home_directory(); + if (home_directory) { + x_asprintf(&cache_dir, "%s/.ccache", home_directory); + } + } + + cache_logfile = getenv("CCACHE_LOGFILE"); + + if (getenv("CCACHE_VERBOSE")) { + ccache_verbose = 1; + } + + setup_uncached_err(); + + + /* the user might have set CCACHE_UMASK */ + p = getenv("CCACHE_UMASK"); + if (p) { + mode_t mask; + errno = 0; + mask = strtol(p, NULL, 8); + if (errno == 0) { + umask(mask); + } + } + + + /* check if we are being invoked as "ccache" */ + if (strlen(argv[0]) >= strlen(MYNAME) && + strcmp(argv[0] + strlen(argv[0]) - strlen(MYNAME), MYNAME) == 0) { + if (argc < 2) { + usage(); + exit(1); + } + /* if the first argument isn't an option, then assume we are + being passed a compiler name and options */ + if (argv[1][0] == '-') { + return ccache_main(argc, argv); + } + } + + /* make sure the cache dir exists */ + if (cache_dir && (create_dir(cache_dir) != 0)) { + fprintf(stderr,"ccache: failed to create %s (%s)\n", + cache_dir, strerror(errno)); + exit(1); + } + + temp_dir = getenv("CCACHE_TEMPDIR"); + if (!temp_dir) { + x_asprintf(&temp_dir, "%s/temp", cache_dir); + /* make sure temp dir exists if not supplied by user */ + if (temp_dir && create_dir(temp_dir) != 0) { + fprintf(stderr,"ccache: failed to create %s (%s)\n", + temp_dir, strerror(errno)); + 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; +} diff --git a/CCache/ccache.h b/CCache/ccache.h new file mode 100644 index 000000000..668ce8288 --- /dev/null +++ b/CCache/ccache.h @@ -0,0 +1,205 @@ +#include "ccache_swig_config.h" + +#define CCACHE_VERSION SWIG_VERSION + +#ifndef _WIN32 +#include "config.h" +#else +#include +#define PACKAGE_NAME "ccache-swig.exe" +#endif + +#include +#include +#include +#include +#include +#include + +#ifndef _WIN32 + #include + #include +#else +#define _WIN32_WINNT 0x0500 + #include + #include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_PWD_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef ENABLE_ZLIB +#include +#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 diff --git a/CCache/ccache.yo b/CCache/ccache.yo new file mode 100644 index 000000000..2477662dc --- /dev/null +++ b/CCache/ccache.yo @@ -0,0 +1,422 @@ +whenman( +COMMENT(html output not great if included when using html2doc) +manpage(ccache-swig)(1)()()() +) + +whenhtml(htmlcommand( + + + + +ccache-swig(1) manpage + + + + +

Using SWIG with ccache - ccache-swig(1) manpage

+ +
+ + +)) + + +manpagename(ccache-swig)(a fast compiler cache) + +whenhtml(htmlcommand( +ccache-swig - a fast compiler cache +)) + +manpagesynopsis() + +ccache-swig [OPTION] + +ccache-swig [COMPILER OPTIONS] + + [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 set maximum files in cache +-M 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 )) 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 )) 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( + + + + +)) diff --git a/CCache/ccache_swig_config.h.in b/CCache/ccache_swig_config.h.in new file mode 100644 index 000000000..bbb205f77 --- /dev/null +++ b/CCache/ccache_swig_config.h.in @@ -0,0 +1 @@ +#define SWIG_VERSION "@PACKAGE_VERSION@" diff --git a/CCache/cleanup.c b/CCache/cleanup.c new file mode 100644 index 000000000..99312283e --- /dev/null +++ b/CCache/cleanup.c @@ -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;ifname) != 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;ifname); + 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); +} diff --git a/CCache/configure.in b/CCache/configure.in new file mode 100644 index 000000000..dfbf86dbc --- /dev/null +++ b/CCache/configure.in @@ -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 ], +[ +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 +#include +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 diff --git a/CCache/debian/NEWS b/CCache/debian/NEWS new file mode 100644 index 000000000..be245dc7d --- /dev/null +++ b/CCache/debian/NEWS @@ -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 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 Sat, 11 Jun 2005 13:54:33 -0400 diff --git a/CCache/debian/README.Debian b/CCache/debian/README.Debian new file mode 100644 index 000000000..5478bb720 --- /dev/null +++ b/CCache/debian/README.Debian @@ -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 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 Sun, 20 May 2007 17:35:36 +1200 diff --git a/CCache/debian/changelog b/CCache/debian/changelog new file mode 100644 index 000000000..45500d4bd --- /dev/null +++ b/CCache/debian/changelog @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 Thu, 16 Jan 2003 11:42:38 +0100 + +ccache (1.9-1) unstable; urgency=low + + * New upstream release (closes: #144920) + + -- Paul Russell Mon, 13 May 2002 10:01:09 +0200 + +ccache (1.8-1) unstable; urgency=low + + * New upstream release (closes: #145401) + + -- Paul Russell 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 Wed, 10 Apr 2002 17:51:21 +0200 + +ccache (1.4-1) unstable; urgency=low + + * New upstream release + + -- Paul Russell Wed, 3 Apr 2002 03:41:46 +0200 + +ccache (1.2-1) unstable; urgency=low + + * Initial Release. + + -- Paul Russell Sun, 31 Mar 2002 14:08:57 +0200 + diff --git a/CCache/debian/compat b/CCache/debian/compat new file mode 100644 index 000000000..1e8b31496 --- /dev/null +++ b/CCache/debian/compat @@ -0,0 +1 @@ +6 diff --git a/CCache/debian/control b/CCache/debian/control new file mode 100644 index 000000000..0b7e57282 --- /dev/null +++ b/CCache/debian/control @@ -0,0 +1,20 @@ +Source: ccache +Section: devel +Priority: optional +Maintainer: Francois Marier +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. diff --git a/CCache/debian/copyright b/CCache/debian/copyright new file mode 100644 index 000000000..7ac791dc5 --- /dev/null +++ b/CCache/debian/copyright @@ -0,0 +1,29 @@ +This package was debianized by Paul Russell 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 + +Copyright: 2002-2005 Andrew Tridgell + + 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. diff --git a/CCache/debian/dirs b/CCache/debian/dirs new file mode 100644 index 000000000..8ceb4c4e8 --- /dev/null +++ b/CCache/debian/dirs @@ -0,0 +1,3 @@ +usr/bin +usr/lib/ccache +usr/share/man/man1 diff --git a/CCache/debian/docs b/CCache/debian/docs new file mode 100644 index 000000000..e845566c0 --- /dev/null +++ b/CCache/debian/docs @@ -0,0 +1 @@ +README diff --git a/CCache/debian/examples b/CCache/debian/examples new file mode 100644 index 000000000..fc549228c --- /dev/null +++ b/CCache/debian/examples @@ -0,0 +1,2 @@ +debian/update-ccache +manage-cache.sh diff --git a/CCache/debian/patches/01_no_home.diff b/CCache/debian/patches/01_no_home.diff new file mode 100644 index 000000000..019634c0c --- /dev/null +++ b/CCache/debian/patches/01_no_home.diff @@ -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; + } + diff --git a/CCache/debian/patches/02_ccache-compressed.diff b/CCache/debian/patches/02_ccache-compressed.diff new file mode 100644 index 000000000..5740c2ca4 --- /dev/null +++ b/CCache/debian/patches/02_ccache-compressed.diff @@ -0,0 +1,1026 @@ +Index: ccache.1 +=================================================================== +RCS file: /home/cvsroot/lars/ccache/ccache.1,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.6 +diff -u -r1.1.1.1.2.1 -r1.6 +--- ccache.1 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ ccache.1 21 Nov 2004 18:19:28 -0000 1.6 +@@ -210,7 +210,8 @@ + 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\&. ++\&'make\&' that rely on modification times\&. Hard links are never made for ++compressed cache files\&. + .IP + .IP "\fBCCACHE_RECACHE\fP" + This forces ccache to not use any cached +@@ -257,6 +258,11 @@ + the default\&. On HP-UX set this environment variable to "i" if you use + the aCC compiler\&. + .IP ++.IP "\fBCCACHE_NOCOMPRESS\fP" ++If you set the environment variable ++CCACHE_NOCOMPRESS then there is no compression used on files that go ++into the cache\&. ++.IP + .PP + .SH "CACHE SIZE MANAGEMENT" + .PP +@@ -269,6 +275,14 @@ + below the numbers you specified in order to avoid doing the cache + clean operation too often\&. + .PP ++.SH "CACHE COMPRESSION" ++.PP ++By default 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\&. ++.PP + .SH "HOW IT WORKS" + .PP + The basic idea is to detect when you are compiling exactly the same +Index: ccache.c +=================================================================== +RCS file: /home/cvsroot/lars/ccache/ccache.c,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.9 +diff -u -r1.1.1.1.2.1 -r1.9 +--- ccache.c 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ ccache.c 21 Nov 2004 18:19:28 -0000 1.9 +@@ -199,7 +199,7 @@ + fd = open(tmp_stderr, O_RDONLY | O_BINARY); + if (fd != -1) { + if (strcmp(output_file, "/dev/null") == 0 || +- rename(tmp_hashname, output_file) == 0 || errno == ENOENT) { ++ move_file(tmp_hashname, output_file) == 0 || errno == ENOENT) { + if (cpp_stderr) { + /* we might have some stderr from cpp */ + int fd2 = open(cpp_stderr, O_RDONLY | O_BINARY); +@@ -231,14 +231,25 @@ + x_asprintf(&path_stderr, "%s.stderr", hashname); + + if (stat(tmp_stderr, &st1) != 0 || +- stat(tmp_hashname, &st2) != 0 || +- rename(tmp_hashname, hashname) != 0 || +- rename(tmp_stderr, path_stderr) != 0) { ++ stat(tmp_hashname, &st2) != 0 || ++ move_file(tmp_hashname, hashname) != 0 || ++ move_file(tmp_stderr, path_stderr) != 0) { + cc_log("failed to rename tmp files - %s\n", strerror(errno)); + stats_update(STATS_ERROR); + failed(); + } + ++#if ENABLE_ZLIB ++ /* do an extra stat on the cache files for ++ the size statistics */ ++ if (stat(path_stderr, &st1) != 0 || ++ stat(hashname, &st2) != 0) { ++ cc_log("failed to stat cache files - %s\n", strerror(errno)); ++ stats_update(STATS_ERROR); ++ failed(); ++ } ++#endif ++ + cc_log("Placed %s into cache\n", output_file); + stats_tocache(file_size(&st1) + file_size(&st2)); + +@@ -474,7 +485,13 @@ + } + + /* the user might be disabling cache hits */ ++#ifndef ENABLE_ZLIB ++ /* if the cache file is compressed we must recache */ ++ if ((first && getenv("CCACHE_RECACHE")) || ++ test_if_compressed(hashname) == 1) { ++#else + if (first && getenv("CCACHE_RECACHE")) { ++#endif + close(fd_stderr); + unlink(stderr_file); + free(stderr_file); +@@ -487,7 +504,9 @@ + ret = 0; + } else { + unlink(output_file); +- if (getenv("CCACHE_HARDLINK")) { ++ /* only make a hardlink if the cache file is uncompressed */ ++ if (getenv("CCACHE_HARDLINK") && ++ test_if_compressed(hashname) == 0) { + ret = link(hashname, output_file); + } else { + ret = copy_file(hashname, output_file); +Index: ccache.h +=================================================================== +RCS file: /home/cvsroot/lars/ccache/ccache.h,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.7 +diff -u -r1.1.1.1.2.1 -r1.7 +--- ccache.h 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ ccache.h 21 Nov 2004 18:19:28 -0000 1.7 +@@ -23,6 +23,10 @@ + #include + #endif + ++#ifdef ENABLE_ZLIB ++#include ++#endif ++ + #define STATUS_NOTFOUND 3 + #define STATUS_FATAL 4 + #define STATUS_NOCACHE 5 +@@ -36,6 +40,13 @@ + #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, +@@ -79,6 +90,8 @@ + + void copy_fd(int fd_in, int fd_out); + int copy_file(const char *src, const char *dest); ++int move_file(const char *src, const char *dest); ++int test_if_compressed(const char *filename); + + int create_dir(const char *dir); + void x_asprintf(char **ptr, const char *format, ...); +Index: ccache.yo +=================================================================== +RCS file: /home/cvsroot/lars/ccache/ccache.yo,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.5 +diff -u -r1.1.1.1.2.1 -r1.5 +--- ccache.yo 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ ccache.yo 21 Nov 2004 18:19:28 -0000 1.5 +@@ -169,6 +169,11 @@ + 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. +@@ -181,7 +186,8 @@ + 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. ++'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 +@@ -236,6 +242,14 @@ + below the numbers you specified in order to avoid doing the cache + clean operation too often. + ++manpagesection(CACHE COMPRESSION) ++ ++By default 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 +@@ -294,6 +308,8 @@ + 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) +Index: config.h.in +=================================================================== +RCS file: /home/cvsroot/lars/ccache/config.h.in,v +retrieving revision 1.1.1.1 +retrieving revision 1.2 +diff -u -r1.1.1.1 -r1.2 +--- config.h.in 30 Apr 2004 13:13:41 -0000 1.1.1.1 ++++ config.h.in 4 May 2004 20:49:26 -0000 1.2 +@@ -98,3 +98,6 @@ + + /* Define _GNU_SOURCE so that we get all necessary prototypes */ + #undef _GNU_SOURCE ++ ++/* Define to 1 if you like to have zlib compression for the ccache. */ ++#undef ENABLE_ZLIB +Index: configure +=================================================================== +RCS file: /home/cvsroot/lars/ccache/configure,v +retrieving revision 1.1.1.1.2.1 +diff -u -r1.1.1.1.2.1 configure +--- configure 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ configure 21 Nov 2004 18:24:42 -0000 +@@ -836,6 +836,11 @@ + + cat <<\_ACEOF + ++Optional Features: ++ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) ++ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --enable-zlib enable zlib support for ccache compression ++ + Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags +@@ -936,7 +941,7 @@ + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi +- cd "$ac_popdir" ++ cd $ac_popdir + done + fi + +@@ -1859,7 +1864,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -1917,7 +1923,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2033,7 +2040,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2087,7 +2095,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2132,7 +2141,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2176,7 +2186,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2609,7 +2620,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2681,7 +2693,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2735,7 +2748,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2806,7 +2820,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2860,7 +2875,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2927,7 +2943,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -2997,7 +3014,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3078,7 +3096,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3248,7 +3267,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3319,7 +3339,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3509,7 +3530,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3611,7 +3633,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3676,7 +3699,8 @@ + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && +- { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err' ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? +@@ -3775,6 +3799,229 @@ + + fi + ++# Check whether --enable-zlib or --disable-zlib was given. ++if test "${enable_zlib+set}" = set; then ++ enableval="$enable_zlib" ++ ++else ++ enable_zlib=yes ++fi; ++ ++if test x"$enable_zlib" = x"yes"; then ++ if test "${ac_cv_header_zlib_h+set}" = set; then ++ echo "$as_me:$LINENO: checking for zlib.h" >&5 ++echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 ++if test "${ac_cv_header_zlib_h+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++fi ++echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 ++echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 ++else ++ # Is the header compilable? ++echo "$as_me:$LINENO: checking zlib.h usability" >&5 ++echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++$ac_includes_default ++#include ++_ACEOF ++rm -f conftest.$ac_objext ++if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ++ (eval $ac_compile) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest.$ac_objext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_header_compiler=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_header_compiler=no ++fi ++rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 ++echo "${ECHO_T}$ac_header_compiler" >&6 ++ ++# Is the header present? ++echo "$as_me:$LINENO: checking zlib.h presence" >&5 ++echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6 ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++_ACEOF ++if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 ++ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } >/dev/null; then ++ if test -s conftest.err; then ++ ac_cpp_err=$ac_c_preproc_warn_flag ++ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag ++ else ++ ac_cpp_err= ++ fi ++else ++ ac_cpp_err=yes ++fi ++if test -z "$ac_cpp_err"; then ++ ac_header_preproc=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ ac_header_preproc=no ++fi ++rm -f conftest.err conftest.$ac_ext ++echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 ++echo "${ECHO_T}$ac_header_preproc" >&6 ++ ++# So? What about this header? ++case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in ++ yes:no: ) ++ { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5 ++echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5 ++echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;} ++ ac_header_preproc=yes ++ ;; ++ no:yes:* ) ++ { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5 ++echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5 ++echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5 ++echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5 ++echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5 ++echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;} ++ { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5 ++echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;} ++ ( ++ cat <<\_ASBOX ++## ------------------------------------------ ## ++## Report this to the AC_PACKAGE_NAME lists. ## ++## ------------------------------------------ ## ++_ASBOX ++ ) | ++ sed "s/^/$as_me: WARNING: /" >&2 ++ ;; ++esac ++echo "$as_me:$LINENO: checking for zlib.h" >&5 ++echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6 ++if test "${ac_cv_header_zlib_h+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_cv_header_zlib_h=$ac_header_preproc ++fi ++echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5 ++echo "${ECHO_T}$ac_cv_header_zlib_h" >&6 ++ ++fi ++if test $ac_cv_header_zlib_h = yes; then ++ echo "$as_me:$LINENO: checking for gzdopen in -lz" >&5 ++echo $ECHO_N "checking for gzdopen in -lz... $ECHO_C" >&6 ++if test "${ac_cv_lib_z_gzdopen+set}" = set; then ++ echo $ECHO_N "(cached) $ECHO_C" >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-lz $LIBS" ++cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++ ++/* Override any gcc2 internal prototype to avoid an error. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++/* We use char because int might match the return type of a gcc2 ++ builtin and then its argument prototype would still apply. */ ++char gzdopen (); ++int ++main () ++{ ++gzdopen (); ++ ; ++ return 0; ++} ++_ACEOF ++rm -f conftest.$ac_objext conftest$ac_exeext ++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 ++ (eval $ac_link) 2>conftest.er1 ++ ac_status=$? ++ grep -v '^ *+' conftest.er1 >conftest.err ++ rm -f conftest.er1 ++ cat conftest.err >&5 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && ++ { ac_try='test -z "$ac_c_werror_flag" ++ || test ! -s conftest.err' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; } && ++ { ac_try='test -s conftest$ac_exeext' ++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 ++ (eval $ac_try) 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ ac_cv_lib_z_gzdopen=yes ++else ++ echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++ac_cv_lib_z_gzdopen=no ++fi ++rm -f conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++echo "$as_me:$LINENO: result: $ac_cv_lib_z_gzdopen" >&5 ++echo "${ECHO_T}$ac_cv_lib_z_gzdopen" >&6 ++if test $ac_cv_lib_z_gzdopen = yes; then ++ LIBS="-lz $LIBS"; cat >>confdefs.h <<\_ACEOF ++#define ENABLE_ZLIB 1 ++_ACEOF ++ ++fi ++ ++fi ++ ++ ++fi ++ + ac_config_files="$ac_config_files Makefile" + + cat >confcache <<\_ACEOF +@@ -4568,6 +4815,11 @@ + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + ++ if test x"$ac_file" != x-; then ++ { echo "$as_me:$LINENO: creating $ac_file" >&5 ++echo "$as_me: creating $ac_file" >&6;} ++ rm -f "$ac_file" ++ fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ +@@ -4606,12 +4858,6 @@ + fi;; + esac + done` || { (exit 1); exit 1; } +- +- if test x"$ac_file" != x-; then +- { echo "$as_me:$LINENO: creating $ac_file" >&5 +-echo "$as_me: creating $ac_file" >&6;} +- rm -f "$ac_file" +- fi + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +Index: configure.in +=================================================================== +RCS file: /home/cvsroot/lars/ccache/configure.in,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.4 +diff -u -r1.1.1.1.2.1 -r1.4 +--- configure.in 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ configure.in 21 Nov 2004 18:19:28 -0000 1.4 +@@ -68,5 +68,14 @@ + AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ]) + fi + ++dnl Check for zlib. ++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))) ++fi ++ + AC_CONFIG_FILES([Makefile]) + AC_OUTPUT +Index: util.c +=================================================================== +RCS file: /home/cvsroot/lars/ccache/util.c,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.11 +diff -u -r1.1.1.1.2.1 -r1.11 +--- util.c 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ util.c 21 Nov 2004 18:19:28 -0000 1.11 +@@ -44,6 +44,7 @@ + exit(1); + } + ++#ifndef ENABLE_ZLIB + /* copy all data from one file descriptor to another */ + void copy_fd(int fd_in, int fd_out) + { +@@ -57,6 +58,11 @@ + } + } + ++/* move a file using rename */ ++int move_file(const char *src, const char *dest) { ++ return rename(src, dest); ++} ++ + /* copy a file - used when hard links don't work + the copy is done via a temporary file and atomic rename + */ +@@ -120,6 +126,174 @@ + return 0; + } + ++#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 from the cache, decompressing it */ ++int copy_file(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; ++} + + /* make sure a directory exists */ + int create_dir(const char *dir) +Index: manage-cache.sh +=================================================================== +RCS file: manage-cache.sh +diff -N manage-cache.sh +--- manage-cache.sh 1 Jan 1970 00:00:00 -0000 ++++ manage-cache.sh-cache.sh 12 May 2004 19:22:20 -0000 1.1 +@@ -0,0 +1,68 @@ ++#!/bin/bash ++# ++# 2004-05-12 lars@gustaebel.de ++ ++CCACHE_DIR=${CCACHE_DIR:-$HOME/.ccache} ++ ++echo "Do you want to compress or decompress the ccache in $CCACHE_DIR?" ++read -p "Type c or d: " mode ++ ++if [ "$mode" != "c" ] && [ "$mode" != "d" ] ++then ++ exit 1 ++fi ++ ++is_compressed() { ++ test "$(head -c 2 $1)" = $'\x1f\x8b' ++ return $? ++} ++ ++tmpfile=$(mktemp) ++ ++for dir in 0 1 2 3 4 5 6 7 8 9 a b c d e f ++do ++ # process ccache subdir ++ echo -n "$dir " ++ ++ # find cache files ++ find $CCACHE_DIR/$dir -type f -name '*-*' | ++ sort > $tmpfile ++ ++ oldsize=$(cat $CCACHE_DIR/$dir/stats | cut -d ' ' -f 13) ++ newsize=0 ++ ++ while read file ++ do ++ # empty files will be ignored since compressing ++ # them makes them bigger ++ test $(stat -c %s $file) -eq 0 && continue ++ ++ if [ $mode = c ] ++ then ++ if ! is_compressed $file ++ then ++ gzip $file ++ mv $file.gz $file ++ fi ++ else ++ if is_compressed $file ++ then ++ mv $file $file.gz ++ gzip -d $file.gz ++ fi ++ fi ++ ++ # calculate new size statistic for this subdir ++ let newsize=$newsize+$(stat -c "%B*%b" $file)/1024 ++ done < $tmpfile ++ ++ # update statistic file ++ read -a numbers < $CCACHE_DIR/$dir/stats ++ numbers[12]=$newsize ++ echo "${numbers[*]} " > $CCACHE_DIR/$dir/stats ++done ++echo ++ ++# clean up ++rm $tmpfile ++ +Index: Makefile.in +=================================================================== +RCS file: /home/cvsroot/lars/ccache/Makefile.in,v +retrieving revision 1.1.1.1.2.1 +retrieving revision 1.12 +diff -u -r1.1.1.1.2.1 -r1.12 +--- Makefile.in 21 Nov 2004 17:55:36 -0000 1.1.1.1.2.1 ++++ Makefile.in 21 Nov 2004 18:19:28 -0000 1.12 +@@ -11,6 +11,7 @@ + CFLAGS=@CFLAGS@ -I. + EXEEXT=@EXEEXT@ + ++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 +@@ -20,7 +21,7 @@ + docs: ccache.1 web/ccache-man.html + + ccache$(EXEEXT): $(OBJS) $(HEADERS) +- $(CC) $(CFLAGS) -o $@ $(OBJS) ++ $(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) + + ccache.1: ccache.yo + -yodl2man -o ccache.1 ccache.yo diff --git a/CCache/debian/patches/03_long_options.diff b/CCache/debian/patches/03_long_options.diff new file mode 100644 index 000000000..3235c3806 --- /dev/null +++ b/CCache/debian/patches/03_long_options.diff @@ -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 + + /* 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 set maximum files in cache\n"); +- printf("-M 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 , --max-files= set maximum files in cache\n"); ++ printf("-M , --max-size= 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 set maximum files in cache +--M 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 , \-\-max-files= set maximum files in cache ++\-M , \-\-max-size= 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 , --max-files=\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 , --max-size=\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 diff --git a/CCache/debian/patches/04_ignore_profile.diff b/CCache/debian/patches/04_ignore_profile.diff new file mode 100644 index 000000000..568375092 --- /dev/null +++ b/CCache/debian/patches/04_ignore_profile.diff @@ -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) { diff --git a/CCache/debian/patches/05_nfs_fix.diff b/CCache/debian/patches/05_nfs_fix.diff new file mode 100644 index 000000000..662d97639 --- /dev/null +++ b/CCache/debian/patches/05_nfs_fix.diff @@ -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 diff --git a/CCache/debian/patches/06_md.diff b/CCache/debian/patches/06_md.diff new file mode 100644 index 000000000..3f68850ca --- /dev/null +++ b/CCache/debian/patches/06_md.diff @@ -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 */ diff --git a/CCache/debian/patches/07_cachedirtag.diff b/CCache/debian/patches/07_cachedirtag.diff new file mode 100644 index 000000000..683b48d14 --- /dev/null +++ b/CCache/debian/patches/07_cachedirtag.diff @@ -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 diff --git a/CCache/debian/patches/08_manpage_hyphens.diff b/CCache/debian/patches/08_manpage_hyphens.diff new file mode 100644 index 000000000..55ced4a23 --- /dev/null +++ b/CCache/debian/patches/08_manpage_hyphens.diff @@ -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" diff --git a/CCache/debian/patches/09_respect_ldflags.diff b/CCache/debian/patches/09_respect_ldflags.diff new file mode 100644 index 000000000..0ce2c2de3 --- /dev/null +++ b/CCache/debian/patches/09_respect_ldflags.diff @@ -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 diff --git a/CCache/debian/patches/10_lru_cleanup.diff b/CCache/debian/patches/10_lru_cleanup.diff new file mode 100644 index 000000000..24463e529 --- /dev/null +++ b/CCache/debian/patches/10_lru_cleanup.diff @@ -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) { diff --git a/CCache/debian/patches/11_utimes.diff b/CCache/debian/patches/11_utimes.diff new file mode 100644 index 000000000..2886bf3d6 --- /dev/null +++ b/CCache/debian/patches/11_utimes.diff @@ -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 + #endif ++#ifdef HAVE_SYS_TIME_H ++#include ++#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 header file. */ + #undef HAVE_INTTYPES_H + +@@ -31,6 +34,9 @@ + /* Define to 1 if you have the header file, and it defines `DIR'. */ + #undef HAVE_NDIR_H + ++/* Define to 1 if you have the 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 header file. */ + #undef HAVE_SYS_STAT_H + ++/* Define to 1 if you have the header file. */ ++#undef HAVE_SYS_TIME_H ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_SYS_TYPES_H + +@@ -69,6 +78,9 @@ + /* Define to 1 if you have the 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( diff --git a/CCache/debian/patches/12_cachesize_permissions.diff b/CCache/debian/patches/12_cachesize_permissions.diff new file mode 100644 index 000000000..28801b771 --- /dev/null +++ b/CCache/debian/patches/12_cachesize_permissions.diff @@ -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); diff --git a/CCache/debian/patches/13_html_links.diff b/CCache/debian/patches/13_html_links.diff new file mode 100644 index 000000000..dadf1b6c2 --- /dev/null +++ b/CCache/debian/patches/13_html_links.diff @@ -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 @@ +
  • fixed handling of HOME environment variable + + +-See the manual page for details ++See the manual page for details + on the new options.

    + +-You can get this release from the download directory ++You can get this release from the download directory + +

    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 @@ + +

    Documentation

    + +-See the manual page ++See the manual page + + +

    Performance

    +@@ -116,7 +116,7 @@ +

    Download

    + + You can download the latest release from the download directory.

    ++href="http://ccache.samba.org/ftp/ccache/">download directory.

    + + For the bleeding edge, you can fetch ccache via CVS or + rsync. To fetch via cvs use the following command: diff --git a/CCache/debian/patches/14_hardlink_doc.diff b/CCache/debian/patches/14_hardlink_doc.diff new file mode 100644 index 000000000..bd9e25ba6 --- /dev/null +++ b/CCache/debian/patches/14_hardlink_doc.diff @@ -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: +

      +
    • Use the same CCACHE_DIR environment variable setting +-
    • Set the CCACHE_NOLINK environment variable ++
    • Unset the CCACHE_HARDLINK environment variable +
    • Make sure everyone sets the CCACHE_UMASK environment variable + to 002, this ensures that cached files are accessible to everyone in + the group. diff --git a/CCache/debian/patches/CREDITS b/CCache/debian/patches/CREDITS new file mode 100644 index 000000000..c4e323b7b --- /dev/null +++ b/CCache/debian/patches/CREDITS @@ -0,0 +1,47 @@ +01_no_home.diff: + Francois Marier + Made especially for the Debian package. + +02_ccache_compressed.diff: + Lars Gustäbel + http://www.gustaebel.de/lars/ccache/ (downloaded on 2007-05-20) + +03_long_options.diff: + Francois Marier + Made especially for the Debian package. + +04_ignore_profile.diff: + Ted Percival + http://bugs.debian.org/cgi-bin/bugreport.cgi?msg=20;filename=ccache-profile.patch;att=1;bug=215849 + +05_nfs_fix.diff: + John Coiner + http://lists.samba.org/archive/ccache/2007q1/000265.html + +06_md.diff: + Andrea Bittau + http://darkircop.org/ccache/ccache-2.4-md.patch (downloaded on 2007-06-30) + +07_cachedirtag.diff: + Karl Chen + http://lists.samba.org/archive/ccache/2008q1/000316.html (downloaded on 2008-02-02) + +08_manpage_hyphens.diff: + Francois Marier + Made especially for the Debian package. + +09_respect_ldflags.diff: + Lisa Seelye + 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 + http://lists.samba.org/archive/ccache/2008q2/000339.html (downloaded on 2008-04-11) + +11_utimes.diff: + Robin H. Johnson + 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 + Made especially for the Debian package to fix http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=332527 diff --git a/CCache/debian/rules b/CCache/debian/rules new file mode 100644 index 000000000..c5b538b78 --- /dev/null +++ b/CCache/debian/rules @@ -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 diff --git a/CCache/debian/update-ccache b/CCache/debian/update-ccache new file mode 100644 index 000000000..0ef97a140 --- /dev/null +++ b/CCache/debian/update-ccache @@ -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 +# + +DIRECTORY=/usr/local/bin +CCACHE=/usr/bin/ccache +CCDIR=/usr/lib/ccache + +usage() { + echo "Usage: `basename $0` [--directory ] [--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 diff --git a/CCache/debian/watch b/CCache/debian/watch new file mode 100644 index 000000000..a72959e50 --- /dev/null +++ b/CCache/debian/watch @@ -0,0 +1,2 @@ +version=2 +http://samba.org/ftp/ccache/ccache-(.*)\.tar\.gz diff --git a/CCache/execute.c b/CCache/execute.c new file mode 100644 index 000000000..165b91e66 --- /dev/null +++ b/CCache/execute.c @@ -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); + } +} diff --git a/CCache/hash.c b/CCache/hash.c new file mode 100644 index 000000000..d0ce8a6ba --- /dev/null +++ b/CCache/hash.c @@ -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; +} diff --git a/CCache/install-sh b/CCache/install-sh new file mode 100755 index 000000000..58719246f --- /dev/null +++ b/CCache/install-sh @@ -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 diff --git a/CCache/mdfour.c b/CCache/mdfour.c new file mode 100644 index 000000000..b098e0215 --- /dev/null +++ b/CCache/mdfour.c @@ -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 diff --git a/CCache/mdfour.h b/CCache/mdfour.h new file mode 100644 index 000000000..92ef2f831 --- /dev/null +++ b/CCache/mdfour.h @@ -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); + + + + diff --git a/CCache/packaging/README b/CCache/packaging/README new file mode 100644 index 000000000..fadc342c4 --- /dev/null +++ b/CCache/packaging/README @@ -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 diff --git a/CCache/packaging/ccache.spec b/CCache/packaging/ccache.spec new file mode 100644 index 000000000..0972121d7 --- /dev/null +++ b/CCache/packaging/ccache.spec @@ -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 +- Created the package diff --git a/CCache/snprintf.c b/CCache/snprintf.c new file mode 100644 index 000000000..32187c1a5 --- /dev/null +++ b/CCache/snprintf.c @@ -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 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 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 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 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 +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif +#ifdef HAVE_CTYPE_H +#include +#endif +#include +#include +#ifdef HAVE_STDLIB_H +#include +#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 + /* 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 = ""; + } + + 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 */ diff --git a/CCache/stats.c b/CCache/stats.c new file mode 100644 index 000000000..92bc4a835 --- /dev/null +++ b/CCache/stats.c @@ -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= (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); +} diff --git a/CCache/test.sh b/CCache/test.sh new file mode 100755 index 000000000..9581c85e3 --- /dev/null +++ b/CCache/test.sh @@ -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 diff --git a/CCache/unify.c b/CCache/unify.c new file mode 100644 index 000000000..a93d48a02 --- /dev/null +++ b/CCache/unify.c @@ -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 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= 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 +} + diff --git a/CCache/util.c b/CCache/util.c new file mode 100644 index 000000000..bba232492 --- /dev/null +++ b/CCache/util.c @@ -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 diff --git a/CCache/web/index.html b/CCache/web/index.html new file mode 100644 index 000000000..4af839135 --- /dev/null +++ b/CCache/web/index.html @@ -0,0 +1,158 @@ + + + +ccache + + +

      ccache

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

      + +The idea came from Erik Thiele wrote the original compilercache program +as a bourne shell script. ccache is a re-implementation of Erik's idea +in C with more features and better performance.

      + +

      Latest release

      + +The latest release is ccache 2.4. + +
        +
      • Added CCACHE_READONLY option +
      • Added CCACHE_TEMPDIR option +
      • fixed handling of hard-linked compilers on AIX +
      • added O_BINARY support, to try and support win32 compiles +
      • show cache directory in stats output +
      • fixed handling of HOME environment variable +
      + +See the manual page for details +on the new options.

      + +You can get this release from the download directory + +

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

      Why bother?

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

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

      + +I put the effort into writing ccache for 2 reasons. The first is the +Samba build farm +(http://build.samba.org/) +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.

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

      Is it safe?

      + +Yes. The most important aspect of a compiler cache is to always +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.

      + +I have coded ccache very carefully to try to provide these guarantees. + +

      Features

      + +
        +
      • keeps statistics on hits/misses +
      • automatic cache size management +
      • can cache compiles that generate warnings +
      • easy installation +
      • very low overhead +
      • uses hard links where possible to avoid copies +
      + +

      Documentation

      + +See the manual page + + +

      Performance

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

      + + + + + + +
          ccache  compilercache
      normal 13m 4s 13m 4s
      uncached 13m 15s 15m 41s
      cached 2m 45s 4m 26s
      + +

      How to use it

      + +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".

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

      Download

      + +You can download the latest release from the download directory.

      + +For the bleeding edge, you can fetch ccache via CVS or +rsync. To fetch via cvs use the following command: + +

      +  cvs -d :pserver:cvs@pserver.samba.org:/cvsroot co ccache
      +
      + +To fetch via rsync use this command: + +
      +  rsync -Pavz samba.org::ftp/unpacked/ccache .
      +
      + +

      Related projects

      + +Here are some related programs you may find interesting + +
        +
      • distcc - a distributed compilation system +
      • cachecc1 - a gcc specific cache +
      • gocache - a cross platform compiler cache +
      +

      + +

      Mailing list

      + +

      A mailing +list is available for discussion of ccache. + + +


      + +Andrew Tridgell
      +bugs@ccache.samba.org +
      + + + diff --git a/CHANGES b/CHANGES index fc3018a1d..70af78333 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,2545 @@ SWIG (Simplified Wrapper and Interface Generator) -See CHANGES.current for current version. +See the CHANGES.current file for changes in the current version. +See the RELEASENOTES file for a summary of changes in each release. + +Version 2.0.5 (19 April 2012) +============================= + +2012-04-14: wsfulton + [Lua] Apply patch #3517435 from Miles Bader - prefer to use Lua_pushglobaltable + +2012-04-14: wsfulton + [Ruby] Apply patch #3517769 from Robin Stocker to fix compile error on MacRuby using RSTRING_PTR. + +2012-04-13: wsfulton + Apply patch #3511009 from Leif Middelschulte for slightly optimised char * variable wrappers. + +2012-04-13: wsfulton + [Lua] Apply #3219676 from Shane Liesegang which adds: + - support for %factory + - a __tostring method + - a __disown method + +2012-04-13: wsfulton + [Xml] Apply #3513569 which adds a catchlist to the xml output. + +2012-04-05: olly + [Lua] Add support for Lua 5.2 (patch SF#3514593 from Miles Bader) + +2012-03-26: xavier98 + [octave] Apply patch #3425993 from jgillis: add extra logic to the octave_swig_type::dims(void) method: it checks if the user has defined a __dims__ method and uses this in stead of returning (1,1) + [octave] Apply patch #3424833 from jgillis: make is_object return true for swig types + +2012-03-24: wsfulton + [D] Apply #3502431 to fix duplicate symbols in multiple modules. + +2012-03-21: wsfulton + Fix #3494791 - %$isglobal for %rename matching. + +2012-03-20: wsfulton + Fix #3487706 and #3391906 - missing stddef.h include for ptrdiff_t when using %import + for STL containers and compiling with g++-4.6. An include of stddef.h is now only + generated when SWIG generates STL helper templates which require ptrdiff_t. If you + were previously relying on "#include " always being generated when using a + %include of an STL header, you may now need to add this in manually. + +2012-03-16: wsfulton + Apply patch #3392264 from Sebastien Bine to parse (unsigned) long long types in enum value assignment. + +2012-03-16: wsfulton + Apply patch #3505530 from Karl Wette to allow custom allocators in STL string classes for the UTL languages. + +2012-03-13: wsfulton + Apply patch #3468362 from Karl Wette to fix %include inside %define. + +2012-03-13: wsfulton + [Python, Ruby, Octave, R] Fix #3475492 - iterating through std::vector wrappers of enumerations. + +2012-02-27: xavier98 (patches from Karl Wette) + [Octave] Use -globals . to load global variables in module namespace + [Octave] Comment declaration of unimplemented function swig_register_director + [Octave] Fix OCTAVE_PATH in octave Makefiles + [Octave] Add support for std::list - fix li_std_containers_int test + [Octave] Fix imports test + +2012-02-16: wsfulton + [Java] Make generated support functions in arrays_java.i static so that generated code + from multiple instances of SWIG can be compiled and linked together - problem reported by + Evan Krause. + +2012-01-24: wsfulton + Fix crash with bad regex - bug #3474250. + +2012-01-24: wsfulton + [Python] Add Python stepped slicing support to the STL wrappers (std::vector, std::list). + Assigning to a slice, reading a slice and deleting a slice with steps now work. + For example: + + %template(vector_i) std::vector + + vi = vector_i(range(10)) + print list(vi) + vi[1:4:2] = [111, 333] + print list(vi) + del vi[3:10:3] + print list(vi) + print list(vi[::-1]) + + gives (same behaviour as native Python sequences such as list): + + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + [0, 111, 2, 333, 4, 5, 6, 7, 8, 9] + [0, 111, 2, 4, 5, 7, 8] + [8, 7, 5, 4, 2, 111, 0] + +2012-01-23: klickverbot + [D] Correctly annotate function pointers with C linkage. + [D] Exception and Error have become blessed names; removed d_exception_name test case. + +2012-01-20: wsfulton + [Python] Fix some indexing bugs in Python STL wrappers when the index is negative, eg: + + %template(vector_i) std::vector + + iv=vector_i([0,1,2,3,4,5]) + iv[-7:] + + now returns [0, 1, 2, 3, 4, 5] instead of [5]. + + vv[7:9] = [22,33] + + now returns [0, 1, 2, 3, 4, 5, 22, 33] instead of "index out range" error. + + Also fix some segfaults when replacing ranges, eg when il is a std::list wrapper: + + il[0:2] = [11] + +2012-01-17: wsfulton + [Go] Fix forward class declaration within a class when used as a base. + +2012-01-07: wsfulton + [C#] Add support for %nspace when using directors. + +2012-01-06: wsfulton + [Java] Patch #3452560 from Brant Kyser - add support for %nspace when using directors. + +2011-12-21: wsfulton + The 'directorin' typemap now accepts $1, $2 etc expansions instead of having to use workarounds - + $1_name, $2_name etc. + +2011-12-20: wsfulton + [Java] Add (char *STRING, size_t LENGTH) director typemaps. + +2011-12-20: wsfulton + [C#, Go, Java, D] Add support for the 'directorargout' typemap. + +2011-12-20: wsfulton + [Ocaml, Octave, PHP, Python, Ruby] Correct special variables in 'directorargout' typemap. + This change will break any 'directorargout' typemaps you may have written. Please change: + $result to $1 + $input to $result + + Also fix the named 'directorargout' DIRECTOROUT typemaps for these languages which didn't + previously compile and add in $1, $2 etc expansion. + + *** POTENTIAL INCOMPATIBILITY *** + +2011-12-10: talby + [perl5] SWIG_error() now gets decorated with perl source file/line number. + [perl5] error handling now conforms to public XS api (fixes perl v5.14 issue). + +2011-12-10: wsfulton + [Android/Java] Fix directors to compile on Android. + + Added documentation and examples for Android. + +2011-12-08: vadz + Bug fix: Handle methods renamed or ignored in the base class correctly in the derived classes + (they could be sometimes mysteriously not renamed or ignored there before). + +2011-12-03: klickverbot + [D] Fix exception glue code for newer DMD 2 versions. + [D] Do not default to 32 bit glue code for DMD anymore. + [D] Use stdc.config.c_long/c_ulong to represent C long types. + +2011-12-01: szager + [python] Fixed bug 3447426: memory leak in vector.__getitem__. + +2011-11-30: wsfulton + [R] Remove C++ comments from generated C code. + +2011-11-27: olly + [Python] Fix some warnings when compiling generated wrappers with + certain GCC warning options (Debian bug #650246). + +2011-11-28: wsfulton + Fix #3433541 %typemap(in, numinputs=0) with 10+ arguments. + +2011-11-28: olly + [Perl] Fix warnings when compiling generated wrappers with certain + GCC warning options (Debian bug #436711). + +2011-11-28: olly + [PHP] Update keyword list to include keywords added in PHP releases up to 5.3. + +2011-11-25: wsfulton + [C#] Provide an easy way to override the default visibility for the proxy class pointer + constructors and getCPtr() method. The visibility is 'internal' by default and if multiple + SWIG modules are being used and compiled into different assemblies, then they need to be + 'public' in order to use the constructor or getCPtr() method from a different assembly. + Use the following macros to change the visibilities in the proxy and type wrapper class: + + SWIG_CSBODY_PROXY(public, public, SWIGTYPE) + SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE) + + [Java] Provide an easy way to override the default visibility for the proxy class pointer + constructors and getCPtr() method. The visibility is 'protected' by default and if multiple + SWIG modules are being used and compiled into different packages, then they need to be + 'public' in order to use the constructor or getCPtr() method from a different package. + Use the following macros to change the visibilities in the proxy and type wrapper class: + + SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) + SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE) + + The default for Java has changed from public to protected for the proxy classes. Use the + SWIG_JAVABODY_PROXY macro above to restore to the previous visibilities. + + *** POTENTIAL INCOMPATIBILITY *** + +2011-11-22: szager + [python] Bug 3440044: #ifdef out SWIG_Python_NonDynamicSetAttr if -builtin + isn't being used, to avoid unnecessary binary incompatibilities between + python installations. + +2011-11-17: wsfulton + Bug fix: Remove root directory from directory search list in Windows. + +2011-11-13: wsfulton + [Ruby] Apply patch #3421876 from Robin Stocker to fix #3416818 - same class name in + different namespaces confusion when using multiple modules. + +2011-11-11: wsfulton + Fix pcre-build.sh to work with non-compressed tarballs - problem reported by Adrian Blakely. + +2011-11-03: wsfulton + Expand special variables in typemap warnings, eg: + + %typemap(in, warning="1000:Test warning for 'in' typemap for $1_type $1_name") int "..." + +2011-11-01: wsfulton + Fix named output typemaps not being used when the symbol uses a qualifier and contains + a number, eg: + + %typemap(out) double ABC::m1 "..." + +2011-10-24: talby + [perl5] SF bug #3423119 - overload dispatch stack corruption fix. Better, but more research + is needed on a stable path for tail calls in XS. + + Also, fix for large long longs in 32 bit perl. + +2011-10-13: xavier98 + [octave] Allow Octave modules to be re-loaded after a "clear all". + +2011-09-19: wsfulton + Fix regression introduced in swig-2.0.1 reported by Teemu Ikonone leading to uncompilable code + when using typedef and function pointer references, for example: + + typedef int FN(const int &a, int b); + void *typedef_call1(FN *& precallback, FN * postcallback); + +2011-09-14: wsfulton + [Lua] Patch #3408012 from Raman Gopalan - add support for embedded Lua (eLua) + including options for targeting Lua Tiny RAM (LTR). + +2011-09-14: wsfulton + [C#] Add boost_intrusive_ptr.i library contribution from patch #3401571. + +2011-09-13: wsfulton + Add warnings for badly named destructors, eg: + + struct KStruct { + ~NOT_KStruct() {} + }; + + cpp_extend_destructors.i:92: Warning 521: Illegal destructor name ~NOT_KStruct. Ignored. + +2011-09-13: wsfulton + Fix %extend and destructors for templates. The destructor in %extend was not always wrapped, + for example: + + %extend FooT { + ~FooT() { delete $self; } // was not wrapped as expected + }; + template class FooT {}; + %template(FooTi) FooT; + +2011-09-13: wsfulton + Fix special variables such as "$decl" and "$fulldecl" in destructors to include the ~ character. + +2011-09-10: talby + [perl5] SF bug #1481958 - Improve range checking for integer types. + Enhance li_typemaps_runme.pl + +2011-09-08: wsfulton + Fix %extend on typedef classes in a namespace using the typedef name, for example: + namespace Space { + %extend CStruct { + ... + } + typedef struct tagCStruct { ... } CStruct; + } + +2011-08-31: xavier98 + [octave] patches from Karl Wette: improvements to module loading behavior; + added example of friend operator to operator example; fixed octave panic/crash in 3.0.5; + documentation improvements + +2011-08-30: szager + [python] Bug 3400486, fix error signalling for built-in constructors. + +2011-08-26: wsfulton + [Go] Fix file/line number display for "gotype" when using typemap debugging options + -tmsearch and -tmused. + +2011-08-26: wsfulton + [C#, D] Fix %callback which was generating uncompileable code. + +2011-08-25: wsfulton + Fix constructors in named typedef class declarations as reported by Gregory Bronner: + + typedef struct A { + A(){} // Constructor which was not accepted by SWIG + B(){} // NOT a constructor --illegal, but was accepted by SWIG + } B; + + For C code, the fix now results in the use of 'struct A *' instead of just 'B *' in + the generated code when wrapping members in A, but ultimately this does not matter, as + they are the same thing. + +2011-08-23: wsfulton + Fix %newobject when used in conjunction with %feature("ref") as reported by Jan Becker. The + code from the "ref" feature was not always being generated for the function specified by %newobject. + Documentation for "ref" and "unref" moved from Python to the C++ chapter. + +2011-08-22: szager + [python] Fixed memory leak with --builtin option (bug 3385089). + +2011-08-22: wsfulton + [Lua] SF patch #3394339 from Torsten Landschoff - new option -nomoduleglobal to disable installing + the module table into the global namespace. Require call also returns the module table instead + of a string. + +2011-08-09: xavier98 + Fix bug 3387394; Octave patches for 3.4.0 compatibility, etc. (from Karl Wette) + +2011-08-04: wsfulton + Add in $symname expansion for director methods. + +2011-07-29: olly + [PHP] Don't generate "return $r;" in cases where $r hasn't been set. + This was basically harmless, except it generated a PHP E_NOTICE if + the calling code had enabled them. + +2011-07-26: wsfulton + Fix scoping of forward class declarations nested within a class (for C++). Previously the symbol + was incorrectly put into the outer namespace, eg + + namespace std { + template struct map { + class iterator; + } + } + + iterator was scoped as std::iterator, but now it is correctly std::map::iterator; + + Also fixed is %template and template parameters that are a typedef when the template contains + default template parameters, eg: + + namespace Std { + template struct Map { + typedef Key key_type; + typedef T mapped_type; + } + } + tyepdef double DOUBLE; + %typemap(MM) Std::Map; + + All symbols within Map will be resolved correctly, eg key_type and mapped_type no matter if the + wrapped code uses Std::Map or std::Map or Std::Map + + Also fixes bug #3378145 - regression introduced in 2.0.4 - %template using traits. + +2011-07-20 szager + [python] Fix closure for tp_call slot. + +2011-07-16: wsfulton + [python] Fix director typemap using PyObject *. + +2011-07-13: szager + [python] SF patch #3365908 - Add all template parameters to map support code in std_map.i + +2011-07-13: szager + [python] Fix for bug 3324753: %rename member variables with -builtin. + +2011-07-01: wsfulton + Fix some scope and symbol lookup problems when template default parameters are being + used with typedef. For example: + + template struct Foo { + typedef XX X; + typedef TT T; + }; + template struct UsesFoo { + void x(typename Foo::T, typename Foo::X); + }; + + Also fixes use of std::vector::size_type for Python as reported by Aubrey Barnard. + +2011-06-23: olly + [PHP] Fix director code to work when PHP is built with ZTS enabled, + which is the standard configuration on Microsoft Windows. + +2011-06-21: mutandiz + [allegrocl] + - various small tweaks and bug fixes. + - Avoid name conflicts between smart pointer wrappers and the wrappers for + the actual class. + - Fix default typemaps for C bindings, which were incorrectly attempting to + call non-existent destructors on user-defined types. + - New feature, feature:aclmixins, for adding superclass to the foreign class + wrappers. + - Improve longlong typemaps. + +2011-06-19: wsfulton + Fix incorrect typemaps being used for a symbol within a templated type, eg: + A::value_type would incorrectly use a typemap for type A. + +2011-06-18: olly + [Tcl] Fix variable declarations in middle of blocks which isn't + permitted in C90 (issue probably introduced in 2.0.3 by patch #3224663). + Reported by Paul Obermeier in SF#3288586. + +2011-06-17: wsfulton + [Java] SF #3312505 - slightly easier to wrap char[] or char[ANY] with a Java byte[] + using arrays_java.i. + +2011-06-13: wsfulton + [Ruby, Octave] SF #3310528 Autodoc fixes similar to those described below for Python. + +2011-06-10: wsfulton + [Python] Few subtle bugfixes in autodoc documentation generation, + - Unnamed argument names fix for autodoc levels > 0. + - Display of template types fixed for autodoc levels > 1. + - Fix SF #3310528 - display of typedef structs for autodoc levels > 1. + - Add missing type for self for autodoc levels 1 and 3. + - autodoc levels 2 and 3 documented. + - Minor tweaks to autodoc style to conform with PEP8. + +2011-05-30: olly + [PHP] Fix handling of directors when -prefix is used. + +2011-05-24: olly + [PHP] Fix handling of methods of classes with a virtual base class (SF#3124665). + +Version 2.0.4 (21 May 2011) +=========================== + +2011-05-19: wsfulton + [Guile] Patch #3191625 fixing overloading of integer types. + +2011-05-19: wsfulton + [Perl] Patch #3260265 fixing overloading of non-primitive types and integers in + Perl 5.12 and later. + +2011-05-19: wsfulton + [Ruby] Fix %import where one of the imported files %include one of the STL include + files such as std_vector.i. + +2011-05-17: wsfulton + [Java] Apply #3289851 from Alan Harder to fix memory leak in directors when checking + for pending exceptions. + +2011-05-17: wsfulton + [Tcl] Apply #3300072 from Christian Delbaere to fix multiple module loading not + always sharing variables across modules. + +2011-05-16: xavier98 + [octave] Fix an incompatibility with never versions of Octave. Case on Octave + API >= 40 to handle rename of Octave_map to octave_map. + [octave] Add support for y.__rop__(x) operators when x.__op__(y) doesn't exist. + [octave] Allow global operators to be defined by SWIG-wrapped functions. + [octave] Fix several bugs around module namespaces; add -global, -noglobal, + -globals command line options to the module. + +2011-05-14: wsfulton + %varargs when used with a numeric argument used to create an additional argument + which was intended to provide a guaranteed sentinel value. This never worked and now + the additional argument is not generated. + +2011-05-13: wsfulton + [python] Additional fixes for python3.2 support. + +2011-05-07: szager + [python] Fixed PyGetSetDescr for python3.2. + +2011-05-05: wsfulton + [Lua, Python, Tcl] C/C++ prototypes shown in error message when calling an overloaded + method with incorrect arguments improved to show always show fully qualified name + and if a const method. + + Also fixed other Lua error messages in generated code which weren't consistently + using the fully qualified C++ name - requested by Gedalia Pasternak. + +2011-04-29: szager + Bug 2635919: Convenience method to convert std::map to a python dict. + +2011-04-29: szager + [Python] Fixed bug 2811549: return non-const iterators from STL + methods begin(), end(), rbegin(), rend(). + +2011-04-25: szager + [Python] Fixed bug 1498929: Access to member fields in map elements + +2011-04-23: klickverbot + [D] nspace: Correctly generate identifiers for base classes when + not in split proxy mode. + +2011-04-13: szager + Fixed bug 3286333: infinite recursion with mutual 'using namespace' clauses. + +2011-04-12: szager + Fixed bug 1163440: vararg typemaps. + +2011-04-12: szager + Fixed bug #3285386: parse error from 'operator T*&()'. Added operator_pointer_ref + test case to demonstrate. + +2011-04-11: szager + [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about + static initialization of struct members with pointers. + +2011-04-11: wsfulton + [Tcl] Apply patch #3284326 from Colin McDonald to fix some compiler warnings. + +2011-04-11: szager + [Python] Fixed PyVarObject_HEAD_INIT to eliminate VC++ compiler errors about + static initialization of struct members with pointers. + +2011-04-10: klickverbot + [D] Fixed wrapping of enums that are type char, for example: + enum { X = 'X'; } (this was already in 2.0.3 for C# and Java) + +2011-04-10: klickverbot + [D] nspace: Fixed referencing types in the root namespace when + not in split proxy mode. + +2011-04-09: szager + [Python] Applied patch #1932484: migrate PyCObject to PyCapsule. + +2011-04-09: szager + [Python] Added preprocessor guards for python functions PyUnicode_AsWideChar and + PySlice_GetIndices, which changed signatures in python3.2. + +2011-04-07: wsfulton + Fix wrapping of const array typedefs which were generating uncompileable code as + reported by Karl Wette. + +2011-04-03: szager + [Python] Fixed the behavior of %pythonnondynamic to conform to the spec in Lib/pyuserdir.swg. + +2011-04-03: szager + [Python] Merged in the szager-python-builtin branch, adding the -builtin feature + for python. The -builtin option may provide a significant performance gain + in python wrappers. For full details and limitations, refer to Doc/Manual/Python.html. + A small test suite designed to demonstrate the performance gain is in + Examples/python/performance. + +2011-04-01: wsfulton + Add in missing wrappers for friend functions for some target languages, mostly + the non-scripting languages like Java and C#. + +Version 2.0.3 (29 March 2011) +============================= + +2011-03-29: wsfulton + [R] Apply patch #3239076 from Marie White fixing strings for R >= 2.7.0 + +2011-03-29: wsfulton + [Tcl] Apply patch #3248280 from Christian Delbaere which adds better error messages when + the incorrect number or type of arguments are passed to overloaded methods. + +2011-03-29: wsfulton + [Tcl] Apply patch #3224663 from Christian Delbaere. + 1. Fix when function returns a NULL value, a "NULL" command will be created in the Tcl interpreter + and calling this command will cause a segmentation fault. + + 2. Previous implementation searches for class methods using a linear search causing performance issues + in wrappers for classes with many member functions. The patch adds a method hash table to classes and + changes method name lookup to use the hash table instead of doing a linear search. + +2011-03-26: wsfulton + [C#, Java] SF bug #3195112 - fix wrapping of enums that are type char, for example: + enum { X = 'X'; } + +2011-03-21: vadz + Allow setting PCRE_CFLAGS and PCRE_LIBS during configuration to override the values returned by + pcre-config, e.g. to allow using a static version of PCRE library. + +2011-03-17: wsfulton + [UTL] Add missing headers in generated STL wrappers to fix compilation with gcc-4.6. + +2011-03-17: wsfulton + Fix regression introduced in swig-2.0.2 where filenames with spaces were not found + when used with %include and %import. Reported by Shane Liesegang. + +2011-03-15: wsfulton + [UTL] Fix overloading when using const char[], problem reported by David Maxwell. + Similarly for char[ANY] and const char[ANY]. + +2011-03-15: wsfulton + [C#] Apply patch #3212624 fixing std::map Keys property. + +2011-03-14: olly + [PHP] Fix handling of overloaded methods/functions where some + return void and others don't - whether this worked or not depended + on the order they were encountered in (SF#3208299). + +2011-03-13: klickverbot + [D] Extended support for C++ namespaces (nspace feature). + +2011-03-12: olly + [PHP] Fix sharing of type information between multiple SWIG-wrapped + modules (SF#3202463). + +2011-03-09: wsfulton + [Python] Fix SF #3194294 - corner case bug when 'NULL' is used as the default value + for a primitive type parameter in a method declaration. + +2011-03-07: olly + [PHP] Don't use zend_error_noreturn() for cases where the function + returns void - now this issue can only matter if you have a function + or method which is directed and returns non-void. + +2011-03-06: olly + [PHP] Add casts to the typemaps for long long and unsigned long + long to avoid issues when they are used with shorter types via + %apply. + +2011-03-02: wsfulton + Templated smart pointers overloaded with both const and non const operator-> generated uncompilable + code when the pointee was a class with either public member variables or static methods. + Regression in 2.0.x reported as working in 1.3.40 by xantares on swig-user mailing list. + +Version 2.0.2 (20 February 2011) +================================ + +2011-02-19: wsfulton + [PHP] Add missing INPUT, OUTPUT and INOUT typemaps in the typemaps.i library + for primitive reference types as well as signed char * and bool *. + +2011-02-19: olly + [PHP] Address bug in PHP on some platforms/architectures which + results in zend_error_noreturn() not being available using + SWIG_ZEND_ERROR_NORETURN which defaults to zend_error_noreturn but + can be overridden when building the module by passing + -DSWIG_ZEND_ERROR_NORETURN=zend_error to the compiler. This may + result in compiler warnings, but should at least allow a module + to be built on those platforms/architectures (SF#3166423). + +2011-02-18: wsfulton + Fix #3184549 - vararg functions and function overloading when using the -fastdispatch option. + +2011-02-18: olly + [PHP] An overloaded method which can return an object or a + primitive type no longer causes SWIG to segfault. Reported by Paul + Colby in SF#3168531. + +2011-02-18: olly + [PHP] Fix invalid erase during iteration of std::map in generated + director code. Reported by Cory Bennett in SF#3175820. + +2011-02-17: wsfulton + Preprocessing now warns if extra tokens appear after #else and #end. + +2011-02-16: wsfulton + Fix #1653092 Preprocessor does not error out when #elif is missing an expression. + This and other cases of missing preprocessor expressions now result in an error. + +2011-02-14: wsfulton + [Ocaml] Apply patch #3151788 from Joel Reymont. Brings Ocaml support up to date + (ver 3.11 and 3.12), including std::string. + +2011-02-13: wsfulton + [Ruby] Apply patch #3176274 from James Masters - typecheck typemap for time_t. + +2011-02-13: wsfulton + Apply patch #3171793 from szager - protected director methods failing when -fvirtual is used. + +2011-02-13: wsfulton + Fix #1927852 - #include directives don't preprocess the file passed to it. The fix is for + #include with -importall or -includeall, %include and %import, for example: + #define FILENAME "abc.h" + %include FILENAME + +2011-02-12: wsfulton + Fix #1940536, overactive preprocessor which was expanding defined(...) outside of #if and #elif + preprocessor directives. + +2011-02-05: wsfulton + [MzScheme] SF #2942899 Add user supplied documentation to help getting started with MzScheme. + Update chapter name to MzScheme/Racket accounting for the rename of MzScheme to Racket. + +2011-02-05: wsfulton + [C#] SF #3085906 - Possible fix running test-suite on Mac OSX. + +2011-02-05: wsfulton + SF #3173367 Better information during configure about Boost prerequisite for running + the test-suite. + +2011-02-05: wsfulton + SF #3127633 Fix infinite loop in recursive typedef resolution. + +2011-02-04: wsfulton + [R] SF #3168676 Fix %rename not working for member variables and methods. + +2011-02-04: wsfulton + [clisp] SF #3148200 Fix segfault parsing nested unions. + +2011-02-01: wsfulton + [C#] Directors - a call to a method being defined in the base class, not + overridden in a subclass, but again overridden in a class derived from + the first subclass was not being dispatched correctly to the most derived class. + See director_alternating.i for an example. + +2011-02-01: wsfulton + [C#, Java] Any 'using' statements in the protected section of a class were previously + ignored with director protected (dirprot) mode. + +2011-01-30: wsfulton + Fix overloading with const pointer reference (SWIGTYPE *const&) parameters for a + number of scripting languages. + +2011-01-17: wsfulton + New warning for smart pointers if only some of the classes in the inheritance + chain are marked as smart pointer, eg, %shared_ptr should be used for all classes + in an inheritance hierarchy, so this new warning highlights code where this is + not the case. + + example.i:12: Warning 520: Base class 'A' of 'B' is not similarly marked as a smart pointer. + example.i:16: Warning 520: Derived class 'C' of 'B' is not similarly marked as a smart pointer. + +2011-01-14: wsfulton + Added some missing multi-argument typemaps: (char *STRING, size_t LENGTH) and + (char *STRING, int LENGTH). Documentation for this updated. Java patch from + Volker Grabsch. + +2011-01-11: iant + Require Go version 7077 or later. + +2010-12-30: klickverbot + [C#, D, Java] Check for collision of parameter names with target + language keywords when generating the director glue code. + + The situation in which the generated could would previously be + invalid is illustrated in the new 'director_keywords' test case. + +2010-12-23: wsfulton + [C#] Fix $csinput special variable not being expanded for csvarin typemaps + when used for global variables. Reported by Vadim Zeitlin. + +2010-12-14: wsfulton + Fix $basemangle expansion in array typemaps. For example if type is int *[3], + $basemangle expands to _p_int. + +2010-12-07: iant + Check that we are using a sufficiently new version of the + 6g or 8g Go compiler during configure time. If not, disable Go. + Minimum version is now 6707. + + *** POTENTIAL INCOMPATIBILITY *** + +2010-12-06: wsfulton + Fix #3127394 - use of network paths on Windows/MSys. + +2010-11-18: klickverbot + [D] Added the D language module. + +2010-11-12: vadz + Fix handling of multiple regex-using %renames attached to the same + declaration. For example, now + + %rename("%(regex/^Set(.*)/put\\1/)s") ""; + %rename("%(regex/^Get(.*)/get\\1/)s") ""; + + works as expected whereas before only the last anonymous rename was + taken into account. + +2010-10-17: drjoe + [R] Fix failure in overloaded functions which was breaking + QuantLib-SWIG + +2010-10-14: olly + [PHP] Allow compilation on non-conforming Microsoft C++ compilers + which don't accept: return function_returning_void(); + Reported by Frank Vanden Berghen on the SWIG mailing list. + +2010-10-12: wsfulton + Fix unary scope operator (::) (global scope) regression introduced in 2.0.0, reported by + Ben Walker. The mangled symbol names were incorrect, sometimes resulting in types being + incorrectly treated as opaque types. + + Also fixes #2958781 and some other type problems due to better typedef resolution, eg + std::vector::value_type didn't resolve to T * when it should have. The mangled type + was incorrectly SWIGTYPE_std__vectorT_Test_p_std__allocatorT_Test_p_t_t__value_type and now + it is correctly SWIGTYPE_p_Test. + +Version 2.0.1 (4 October 2010) +============================== + +2010-10-03: wsfulton + Apply patch #3066958 from Mikael Johansson to fix default smart pointer + handling when the smart pointer contains both a const and non-const operator->. + +2010-10-01: wsfulton + Add -pcreversion option to display PCRE version information. + +2010-10-01: olly + [Ruby] Avoid segfault when a method node has no parentNode + (SF#3034054). + +2010-10-01: olly + [Python] Allow reinitialisation to work with an embedded Python + interpreter (patch from Jim Carroll in SF#3075178). + +2010-09-28: wsfulton + [C#] Apply patch from Tomas Dirvanauskas for std::map wrappers to avoid + throwing exceptions with normal usage of iterators. + +2010-09-27: olly + [Python] Improve error message given when a parameter of the wrong + type is passed to an overloaded method (SF#3027355). + +2010-09-25: wsfulton + Apply SF patch #3075150 - Java directors using static variables in + named namespace. + +2010-09-24: wsfulton + More file and line error/warning reporting fixes where SWIG macros + are used within {} braces (where the preprocessor expands macros), + for example macros within %inline {...} and %fragment(...) {...} + and nested structs. + +2010-09-18: wsfulton + More file and line error/warning reporting fixes for various inherited + class problems. + +2010-09-15: wsfulton + A much improved debugging of SWIG source experience is now available and + documented in the "Debugging SWIG" section in the Doc/Devel/internals.html + file, including a swig.dbg support file for the gdb debugger. + +2010-09-11: wsfulton + Fix incorrect line number reporting in errors/warnings when a macro + definition ends with '/' and it is not the end of a C comment. + +2010-09-11: wsfulton + Fix incorrect line number reporting in errors/warnings after parsing + macro invocations with parameters given over more than one line. + +2010-09-10: wsfulton + Remove extraneous extra line in preprocessed output after including files + which would sometimes lead to error/warning messages two lines after the + end of the file. + +2010-09-10: wsfulton + Fix #2149523 - Incorrect line number reporting in errors after parsing macros + containing C++ comments. + +2010-09-08: olly + [PHP] Fix handling of OUTPUT typemaps (Patch from Ryan in SF#3058394). + +2010-09-03: wsfulton + Fix erroneous line numbers in error messages for macro expansions, for example, + the error message now points to instantiation of the macro, ie the last line here: + + #define MACRO2(a, b) + + #define MACRO1(NAME) MACRO2(NAME,2,3) + + MACRO1(abc) + +2010-09-02: wsfulton + Fix line numbers in error and warning messages for preprocessor messages within + %inline, for example: + + %inline %{ + #define FOOBAR 1 + #define FOOBAR "hi" + %} + +2010-09-02: wsfulton + Fix line numbers in error and warning messages which were cumulatively one + less than they should have been after parsing each %include/%import - bug + introduced in swig-1.3.32. Also fix line numbers in error and warning messages + when new line characters appear between the %include / %import statement and + the filename. + +2010-08-30: wsfulton + Fix line number and file name reporting for some macro preprocessor warnings. + The line number of the macro argument has been corrected and the line number + of the start of the macro instead of one past the end of the macro is used. + Some examples: + file.h:11: Error: Illegal macro argument name '..' + file.h:19: Error: Macro 'DUPLICATE' redefined, + file.h:15: Error: previous definition of 'DUPLICATE'. + file.h:25: Error: Variable-length macro argument must be last parameter + file.h:32: Error: Illegal character in macro argument name + file.i:37: Error: Macro 'SIT' expects 2 arguments + +2010-08-26: wsfulton + Fix __LINE__ and __FILE__ expansion reported by Camille Gillot. Mostly this + did not work at all. Also fixes SF #2822822. + +2010-08-17: wsfulton + [Perl] Fix corner case marshalling of doubles - errno was not being correctly + set before calling strtod - patch from Justin Vallon - SF Bug #3038936. + +2010-08-17: wsfulton + Fix make distclean when some of the more obscure languages are detected by + configure - fixes from Torsten Landschoff. + +2010-07-28: wsfulton + Restore configuring out of source for the test-suite since it broke in 1.3.37. + As previously, if running 'make check-test-suite' out of source, it needs to be + done by invoking configure with a relative path. Invoking configure with an + absolute path will not work. Running the full 'make check' still needs to be + done in the source tree. + +2010-07-16: wsfulton + Fix wrapping of function pointers and member function pointers when the function + returns by reference. + +2010-07-13: vadz + Removed support for the old experimental "rxspencer" encoder and + "[not]rxsmatch" in %rename (see the 01/16/2006 entry). The new and + officially supported "regex" encoder and "[not]regexmatch" checks + should be used instead (see the two previous entries). Please + replace "%(rxspencer:[pat][subst])s" with "%(regex:/pat/subst/)s" + when upgrading. Notice that you will also need to replace the back- + references of form "@1" with the more standard "\\1" and may need to + adjust your regular expressions syntax as the new regex encoder uses + Perl-compatible syntax and not (extended) POSIX syntax as the old one. + + *** POTENTIAL INCOMPATIBILITY *** + +2010-07-13: vadz + Add "regexmatch", "regextarget" and "notregexmatch" which can be + used to apply %rename directives to the declarations matching the + specified regular expression only. The first two can be used + interchangeably, both of the %renames below do the same thing: + + %rename("$ignore", regexmatch$name="Old$") ""; + %rename("$ignore", regextarget=1) "Old$"; + + (namely ignore the declarations having "Old" suffix). + + "notregexmatch" restricts the match to only the declarations which + do not match the regular expression, e.g. here is how to rename to + lower case versions all declarations except those consisting from + capital letters only: + + %rename("$(lowercase)s", notregexmatch$name="^[A-Z]+$") ""; + +2010-07-13: vadz + Add the new "regex" encoder that can be used in %rename, e.g. + + %rename("regex:/(\\w+)_(.*)/\\2/") ""; + + to remove any alphabetical prefix from all identifiers. The syntax + of the regular expressions is Perl-like and PCRE library + (http://www.pcre.org/) is used to implement this feature but notice + that backslashes need to be escaped as usual inside C strings. + + Original patch from Torsten Landschoff. + +2010-07-08: wsfulton + Fix #3024875 - shared_ptr of classes with non-public destructors. This also fixes + the "unref" feature when used on classes with non-public destructors. + +2010-06-17: ianlancetaylor + [Go] Add the Go language module. + +2010-06-10: wsfulton + [Lua] Fix SWIG_lua_isnilstring multiply defined when using multiple + modules and wrapping strings. Patch from 'Number Cruncher'. + +2010-06-10: olly + [PHP] Fix directors to correctly call a method with has a + different name in PHP to C++ (we were always using the C++ name + in this case). + +2010-06-03: wsfulton + Fix uncompileable code when %rename results in two enum items + with the same name. Reported by Vadim Zeitlin. + +Version 2.0.0 (2 June 2010) +=========================== + +2010-06-02: wsfulton + [C#] Fix SWIG_STD_VECTOR_ENHANCED macro used in std::vector to work with + types containing commas, for example: + + SWIG_STD_VECTOR_ENHANCED(std::pair< double, std::string >) + +2010-06-01: wsfulton + Add in std_shared_ptr.i for wrapping std::shared_ptr. Requires the %shared_ptr + macro like in the boost_shared_ptr.i library. std::tr1::shared_ptr can also be + wrapped if the following macro is defined: + + #define SWIG_SHARED_PTR_SUBNAMESPACE tr1 + %include + + shared_ptr is also documented in Library.html now. + +2010-05-27: wsfulton + Add the ability for $typemap special variable macros to call other $typemap + special variable macros, for example: + + %typemap(cstype) CC "CC" + %typemap(cstype) BB "$typemap(cstype, CC)" + %typemap(cstype) AA "$typemap(cstype, BB)" + void hah(AA aa); + + This also fixes C# std::vector containers of shared_ptr and %shared_ptr. + + Also added diagnostics for $typemap with -debug-tmsearch, for example, the + above displays additional diagnostic lines starting "Containing: ": + + example.i:34: Searching for a suitable 'cstype' typemap for: AA aa + Looking for: AA aa + Looking for: AA + Using: %typemap(cstype) AA + Containing: $typemap(cstype, BB) + example.i:31: Searching for a suitable 'cstype' typemap for: BB + Looking for: BB + Using: %typemap(cstype) BB + Containing: $typemap(cstype, CC) + example.i:29: Searching for a suitable 'cstype' typemap for: CC + Looking for: CC + Using: %typemap(cstype) CC + +2010-05-26: olly + Fix %attribute2ref not to produce a syntax error if the last + argument (AccessorMethod) is omitted. Patch from David Piepgras + in SF#2235756. + +2010-05-26: olly + [PHP] When using %throws or %catches, SWIG-generated PHP5 wrappers + now throw PHP Exception objects instead of giving a PHP error of + type E_ERROR. + + This change shouldn't cause incompatibility issues, since you can't + set an error handler for E_ERROR, so previously PHP would just exit + which also happens for unhandled exceptions. The benefit is you can + now catch them if you want to. + + Fixes SF#2545578 and SF#2955522. + +2010-05-25: olly + [PHP] Add missing directorin typemap for const std::string &. + Fixes SF#3006404 reported by t-Legiaw. + +2010-05-23: wsfulton + [C#] Fix #2957375 - SWIGStringHelper and SWIGExceptionHelper not always being + initialized before use in .NET 4 as the classes were not marked beforefieldinit. + A static constructor has been added to the intermediary class like this: + + %pragma(csharp) imclasscode=%{ + static $imclassname() { + } + %} + + If you had added your own custom static constructor to the intermediary class in + the same way as above, you will have to modify your approach to use static variable + initialization or define SWIG_CSHARP_NO_IMCLASS_STATIC_CONSTRUCTOR - See csharphead.swg. + + *** POTENTIAL INCOMPATIBILITY *** + +2010-05-23: wsfulton + Fix #2408232. Improve shared_ptr and intrusive_ptr wrappers for classes in an + inheritance hierarchy. No special treatment is needed for derived classes. + The proxy class also no longer needs to be specified, it is automatically + deduced. The following macros are deprecated: + SWIG_SHARED_PTR(PROXYCLASS, TYPE) + SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) + and have been replaced by + %shared_ptr(TYPE) + Similarly for intrusive_ptr wrappers, the following macro is deprecated: + SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE) + SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) + and have been replaced by + %intrusive_ptr(TYPE) + +2010-05-21: olly + [PHP] Stop generating a bogus line of code in certain constructors. + This was mostly harmless, but caused a PHP notice to be issued, if + enabled (SF#2985684). + +2010-05-18: wsfulton + [Java] Fix member pointers on 64 bit platforms. + +2010-05-14: wsfulton + Fix wrapping of C++ enum boolean values reported by Torsten Landschoff: + typedef enum { PLAY = true, STOP = false } play_state; + +2010-05-14: olly + [PHP] Fix wrapping of global variables which was producing + uncompilable code in some cases. + +2010-05-12: drjoe + [R] Add two more changes from Wil Nolan. Get garbage + collection to work. Implement newfree + +2010-05-09: drjoe + Fix bug reported by Wil Nolan change creation of string so + that R 2.7.0+ can use char hashes + +2010-05-07: wsfulton + Apply patch #2955146 from Sergey Satskiy to fix expressions containing divide by + operator in constructor initialization lists. + +2010-05-05: wsfulton + [R] Memory leak fix handling const std::string & inputs, reported by Will Nolan. + +2010-05-01: wsfulton + Typemap matching enhancement for non-default typemaps. Previously all + qualifiers were stripped in one step, now they are stripped one at a time + starting with the left most qualifier. For example, int const*const + is first stripped to int *const then int *. + + *** POTENTIAL INCOMPATIBILITY *** + +2010-04-25: bhy + [Python] Fix #2985655 - broken constructor renaming. + +2010-04-14: wsfulton + Typemap fragments are now official and documented in Typemaps.html. + +2010-04-09: wsfulton + [Ruby] Fix #2048064 and #2408020. + Apply Ubuntu patch to fix Ruby and std::vector wrappers with -minherit. + https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/522874 + +2010-04-09: wsfulton + [Mzscheme] Apply Ubuntu patch to fix std::map wrappers: + https://bugs.launchpad.net/ubuntu/+source/swig1.3/+bug/203876 + +2010-04-09: wsfulton + [Python] Apply patch #2952374 - fix directors and the -nortti option. + +2010-04-09: wsfulton + [Lua] Fix #2887254 and #2946032 - SWIG_Lua_typename using wrong stack index. + +2010-04-03: wsfulton + [Python] Fix exceptions being thrown with the -threads option based on patch from Arto Vuori. + Fixes bug #2818499. + +2010-04-03: wsfulton + Fix Makefile targets: distclean and maintainer-clean + +2010-04-02: wsfulton + [Lua] Fix char pointers, wchar_t pointers and char arrays so that nil can be passed as a + valid value. Bug reported by Gedalia Pasternak. + +2010-04-01: wsfulton + Numerous subtle typemap matching rule fixes when using the default type. The typemap + matching rules are to take a type and find the best default typemap (SWIGTYPE, SWIGTYPE* etc), + then look for the next best match by reducing the chosen default type. The type deduction + now follows C++ class template partial specialization matching rules. + + Below are the set of changes made showing the default type deduction + along with the old reduced type and the new version of the reduced type: + + SWIGTYPE const &[ANY] + new: SWIGTYPE const &[] + old: SWIGTYPE (&)[ANY] + + SWIGTYPE *const [ANY] + new: SWIGTYPE const [ANY] + old: SWIGTYPE *[ANY] + + SWIGTYPE const *const [ANY] + new: SWIGTYPE *const [ANY] + old: SWIGTYPE const *[ANY] + + SWIGTYPE const *const & + new: SWIGTYPE *const & + old: SWIGTYPE const *& + + SWIGTYPE *const * + new: SWIGTYPE const * + old: SWIGTYPE ** + + SWIGTYPE *const & + new: SWIGTYPE const & + old: SWIGTYPE *& + + Additionally, a const SWIGTYPE lookup is used now for any constant type. Some examples, where + T is some reduced type, eg int, struct Foo: + + T const + new: SWIGTYPE const + old: SWIGTYPE + + T *const + new: SWIGTYPE *const + old: SWIGTYPE * + + T const[] + new: SWIGTYPE const[] + old: SWIGTYPE[] + + enum T const + new: enum SWIGTYPE const + old: enum SWIGTYPE + + T (*const )[] + new: SWIGTYPE (*const )[] + old: SWIGTYPE (*)[] + + Reminder: the typemap matching rules can now be seen for any types being wrapped by using + either the -debug-tmsearch or -debug-tmused options. + + In practice this leads to some subtle matching rule changes and the majority of users + won't notice any changes, except in the prime area of motivation for this change: Improve + STL containers of const pointers and passing const pointers by reference. This is fixed + because many of the STL containers use a type 'T const&' as parameters and when T is + a const pointer, for example, 'K const*', then the full type is 'K const*const&'. This + means that the 'SWIGTYPE *const&' typemaps now match when T is either a non-const or + const pointer. Furthermore, some target languages incorrectly had 'SWIGTYPE *&' typemaps + when these should have been 'SWIGTYPE *const&'. These have been corrected (Java, C#, Lua, PHP). + + *** POTENTIAL INCOMPATIBILITY *** + +2010-03-13: wsfulton + [Java] Some very old deprecated pragma warnings are now errors. + +2010-03-13: wsfulton + Improve handling of file names and directories containing double/multiple path separators. + +2010-03-10: mutandiz (Mikel Bancroft) + [allegrocl] Use fully qualified symbol name of cl::identity in emit_defun(). + +2010-03-06: wsfulton + [Java] The intermediary JNI class modifiers are now public by default meaning these + intermediary low level functions are now accessible by default from outside any package + used. The proxy class pointer constructor and getCPtr() methods are also now public. + These are needed in order for the nspace option to work without any other mods. + The previous default of protected access can be restored using: + + SWIG_JAVABODY_METHODS(protected, protected, SWIGTYPE) + %pragma(java) jniclassclassmodifiers = "class" + +2010-03-06: wsfulton + [C#] Added the nspace feature for C#. Documentation for the nspace feature is now available. + +2010-03-04: wsfulton + Added the nspace feature. This adds some improved namespace support. Currently only Java + is supported for target languages, where C++ namespaces are automatically translated into + Java packages. The feature only applies to classes,struct,unions and enums declared within + a namespace. Methods and variables declared in namespaces still effectively have their + namespaces flattened. Example usage: + + %feature(nspace) Outer::Inner1::Color; + %feature(nspace) Outer::Inner2::Color; + + namespace Outer { + namespace Inner1 { + struct Color { + ... + }; + } + namespace Inner2 { + struct Color { + ... + }; + } + } + + For Java, the -package option is also required when using the nspace feature. Say + we use -package com.myco, the two classes can then be accessed as follows from Java: + + com.myco.Outer.Inner1.Color and com.myco.Outer.Inner2.Color. + +2010-02-27: wsfulton + [Python] Remove -dirvtable from the optimizations included by -O as it this option + currently leads to memory leaks as reported by Johan Blake. + +2010-02-27: wsfulton + License code changes: SWIG Source is GPL-v3 and library code license is now clearer + and is provided under a very permissive license. See http://www.swig.org/legal.html. + +2010-02-13: wsfulton + [Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'. + +2010-02-13: wsfulton + [Ruby] Apply patch from Patrick Bennett to fix RARRAY_LEN and RARRAY_PTR usage for Ruby 1.9.x + used in various STL wrappers. + +2010-02-13: wsfulton + [C#, Java] Fix incorrect multiply defined symbol name error when an enum item + and class name have the same name, as reported by Nathan Krieger. Example: + + class Vector {}; + namespace Text { + enum Preference { Vector }; + } + + This also fixes other incorrect corner case target language symbol name clashes. + +2010-02-11: wsfulton + Add the -debug-lsymbols option for displaying the target language layer symbols. + +2010-02-09: wsfulton + Fix -MM and -MMD options on Windows. They were not omitting files in the SWIG library as + they should be. + +2010-02-08: wsfulton + Fix #1807329 - When Makefile dependencies are being generated using the -M family of options + on Windows, the file paths have been corrected to use single backslashes rather than double + backslashes as path separators. + +2010-02-06: wsfulton + Fix #2918902 - language specific files not being generated in correct directory on + Windows when using forward slashes for -o, for example: + swig -python -c++ -o subdirectory/theinterface_wrap.cpp subdirectory/theinterface.i + +2010-02-05: wsfulton + Fix #2894405 - assertion when using -xmlout. + +2010-01-28: wsfulton + Fix typemap matching bug when a templated type has a typemap both specialized and not + specialized. For example: + + template struct XX { ... }; + %typemap(in) const XX & "..." + %typemap(in) const XX< int > & "..." + + resulted in the 2nd typemap being applied for all T in XX< T >. + +2010-01-22: wsfulton + Fix #2933129 - typemaps not being found when the unary scope operator (::) is used to denote + global scope, the typemap is now used in situations like this: + + struct X {}; + %typemap(in) const X & "..." + void m(const ::X &); + + and this: + + struct X {}; + %typemap(in) const ::X & "..." + void m(const X &); + +2010-01-20: wsfulton + Fix some unary scope operator (::) denoting global scope problems in the types generated + into the C++ layer. Previously the unary scope operator was dropped in the generated code + if the type had any sort of qualifier, for example when using pointers, references, like + ::foo*, ::foo&, bar< ::foo* >. + +2010-01-13: olly + [PHP] Add datetime to the list of PHP predefined classes (patch + from David Fletcher in SF#2931042). + +2010-01-11: wsfulton + Slight change to warning, error and diagnostic reporting. The warning number is no + longer shown within brackets. This is to help default parsing of warning messages by + other tools, vim on Unix in particular. + + Example original display using -Fstandard: + example.i:20: Warning(401): Nothing known about base class 'B'. Ignored. + New display: + example.i:20: Warning 401: Nothing known about base class 'B'. Ignored. + + Also subtle fix to -Fmicrosoft format adding in missing space. Example original display: + example.i(20): Warning(401): Nothing known about base class 'Base'. Ignored. + New display: + example.i(20) : Warning 401: Nothing known about base class 'Base'. Ignored. + +2010-01-10: wsfulton + Fix a few inconsistencies in reporting of file/line numberings including modifying + the overload warnings 509, 512, 516, 474, 475 to now be two line warnings. + +2010-01-10: wsfulton + Modify -debug-tags output to use standard file name/line reporting so that editors + can easily navigate to the appropriate lines. + Was typically: + . top . include . include (/usr/share/swig/temp/trunk/Lib/swig.swg:312) + . top . include . include . include (/usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39) + now: + /usr/share/swig/temp/trunk/Lib/swig.swg:312: . top . include . include + /usr/share/swig/temp/trunk/Lib/swigwarnings.swg:39: . top . include . include . include + +2010-01-03: wsfulton + Fix missing file/line numbers for typemap warnings and in output from the + -debug-tmsearch/-debug-tmused options. + +2010-01-03: wsfulton + Add typemaps used debugging option (-debug-tmused). When used each line displays + the typemap used for each type for which code is being generated including the file + and line number related to the type. This is effectively a condensed form of the + -debug-tmsearch option. Documented in Typemaps.html. + +2009-12-23: wsfulton + Fix for %javaexception and directors so that all the appropriate throws clauses + are generated. Problem reported by Peter Greenwood. + +2009-12-20: wsfulton + Add -debug-tmsearch option for debugging the typemap pattern matching rules. + Documented in Typemaps.html. + +2009-12-12: wsfulton + [Octave] Remove the -api option and use the new OCTAVE_API_VERSION_NUMBER + macro provided in the octave headers for determining the api version instead. + +2009-12-04: olly + [Ruby] Improve support for Ruby 1.9 under GCC. Addresses part of + SF#2859614. + +2009-12-04: olly + Fix handling of modulo operator (%) in constant expressions + (SF#2818562). + +2009-12-04: olly + [PHP] "empty" is a reserved word in PHP, so rename empty() method + on STL classes to "is_empty()" (previously this was automatically + renamed to "c_empty()"). + *** POTENTIAL INCOMPATIBILITY *** + +2009-12-03: olly + [PHP] Add typemaps for long long and unsigned long long, and for + pointer to method. + +2009-12-02: olly + [PHP] Fix warning and rename of reserved class name to be case + insensitive. + +2009-12-01: wsfulton + Revert support for %extend and memberin typemaps added in swig-1.3.39. The + memberin typemaps are ignored again for member variables within a %extend block. + Documentation inconsistency reported by Torsten Landschoff. + +2009-11-29: wsfulton + [Java, C#] Fix generated quoting when using %javaconst(1)/%csconst(1) for + static const char member variables. + + %javaconst(1) A; + %csconst(1) A; + struct X { + static const char A = 'A'; + }; + +2009-11-26: wsfulton + [Java, C#] Fix %javaconst(1)/%csconst(1) for static const member variables to + use the actual constant value if it is specified, rather than the C++ code to + access the member. + + %javaconst(1) EN; + %csconst(1) EN; + struct X { + static const int EN = 2; + }; + +2009-11-23: wsfulton + C++ nested typedef classes can now be handled too, for example: + struct Outer { + typedef Foo { } FooTypedef1, FooTypedef2; + }; + +2009-11-18: wsfulton + The wrappers for C nested structs are now generated in the same order as declared + in the parsed code. + +2009-11-18: wsfulton + Fix #491476 - multiple declarations of nested structs, for example: + struct Outer { + struct { + int val; + } inner1, inner2, *inner3, inner4[1]; + } outer; + +2009-11-17: wsfulton + Fix parsing of enum declaration and initialization, for example: + + enum ABC { + a, + b, + c + } A = a, *pC = &C, array[3] = {a, b, c}; + +2009-11-17: wsfulton + Fix parsing of struct declaration and initialization, for example: + + struct S { + int x; + } instance = { 10 }; + +2009-11-15: wsfulton + Fix #1960977 - Syntax error parsing derived nested class declaration and member + variable instance. + +2009-11-14: wsfulton + Fix #2310483 - function pointer typedef within extern "C" block. + +2009-11-13: wsfulton + Fix usage of nested template classes within templated classes so that compileable code + is generated. + +2009-11-13: olly + [php] Fix place where class prefix (as specified with -prefix) + wasn't being used. Patch from gverbruggen in SF#2892647. + +2009-11-12: wsfulton + Fix usage of nested template classes so that compileable code is generated - the nested + template class is now treated like a normal nested classes, that is, as an opaque type + unless the nestedworkaround feature is used. + +2009-11-12: wsfulton + Replace SWIGWARN_PARSE_NESTED_CLASS with SWIGWARN_PARSE_NAMED_NESTED_CLASS and + SWIGWARN_PARSE_UNNAMED_NESTED_CLASS for named and unnamed nested classes respectively. + + Named nested class ignored warnings can now be suppressed by name using %warnfilter, eg: + + %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner; + + but clearly unnamed nested classes cannot and the global suppression is still required, eg: + + #pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS + +2009-11-11: wsfulton + Added the nestedworkaround feature as a way to use the full functionality of a nested class + (C++ mode only). It removes the nested class from SWIG's type information so it is as if SWIG + had never parsed the nested class. The documented nested class workarounds using a global + fake class stopped working when SWIG treated the nested class as an opaque pointer, and + this feature reverts this behaviour. The documentation has been updated with details of how + to use and implement it, see the "Nested classes" section in SWIGPlus.html. + +2009-11-11: wsfulton + There were a number of C++ cases where nested classes/structs/unions were being handled + as if C code was being parsed which would oftentimes lead to uncompileable code as an + attempt was made to wrap the nested structs like it is documented for C code. Now all + nested structs/classes/unions are ignored in C++ mode, as was always documented. However, + there is an improvement as usage of nested structs/classes/unions is now always treated + as an opaque type by default, resulting in generated code that should always compile. + + *** POTENTIAL INCOMPATIBILITY *** + +2009-11-09: drjoe + Fix R for -fcompact and add std_map.i + +2009-11-08: wsfulton + Fix inconsistency for nested structs/unions/classes. Uncompileable code was being + generated when inner struct and union declarations were used as types within the + inner struct. The inner struct/union is now treated as a forward declaration making the + behaviour the same as an inner class. (C++ code), eg: + + struct Outer { + struct InnerStruct { int x; }; + InnerStruct* getInnerStruct(); + }; + +2009-11-08: wsfulton + Ignored nested class/struct warnings now display the name of the ignored class/struct. + +2009-11-07: wsfulton + Bug #1514681 - Fix nested template classes within a namespace generated uncompileable + code and introduced strange side effects to other wrapper code especially code + after the nested template class. Note that nested template classes are still ignored. + +2009-11-07: wsfulton + Add new debug options: + -debug-symtabs - Display symbol tables information + -debug-symbols - Display target language symbols in the symbol tables + -debug-csymbols - Display C symbols in the symbol tables + +2009-11-03: wsfulton + Fix some usage of unary scope operator (::) denoting global scope, for example: + + namespace AA { /* ... */ } + using namespace ::AA; + + and bug #1816802 - SwigValueWrapper should be used: + + struct CC { + CC(int); // no default constructor + }; + ::CC x(); + + and in template parameter specializations: + + struct S {}; + template struct X { void a() {}; }; + template <> struct X { void b() {}; }; + %template(MyTConcrete) X< ::S >; + + plus probably some other corner case usage of ::. + +2009-11-02: olly + [Python] Fix potential memory leak in initialisation code for the + generated module. + +2009-10-23: wsfulton + Fix seg fault when using a named nested template instantiation using %template(name) + within a class. A warning that these are not supported is now issued plus processing + continues as if no name was given. + +2009-10-20: wsfulton + [Python] Fix std::vector. This would previously compile, but not run correctly. + +2009-10-20: wsfulton + Fixed previously fairly poor template partial specialization and explicit + specialization support. Numerous bugs in this area have been fixed including: + + - Template argument deduction implemented for template type arguments, eg this now + works: + template class X {}; + template class X {}; + %template(X1) X; // Chooses T * specialization + + and more complex cases with multiple parameters and a mix of template argument + deduction and explicitly specialised parameters, eg: + template struct TwoParm { void a() {} }; + template struct TwoParm { void e() {} }; + %template(E) TwoParm; + + Note that the primary template must now be in scope, like in C++, when + an explicit or partial specialization is instantiated with %template. + + *** POTENTIAL INCOMPATIBILITY *** + +2009-09-14: wsfulton + [C#] Add %csattributes for adding C# attributes to enum values, see docs for example. + +2009-09-11: wsfulton + Fix memmove regression in cdata.i as reported by Adriaan Renting. + +2009-09-07: wsfulton + Fix constant expressions containing <= or >=. + +2009-09-02: wsfulton + The following operators in constant expressions now result in type bool for C++ + wrappers and remain as type int for C wrappers, as per each standard: + + && || == != < > <= >= (Actually the last 4 are still broken). For example: + + #define A 10 + #define B 10 + #define A_EQ_B A == B // now wrapped as type bool for C++ + #define A_AND_B A && B // now wrapped as type bool for C++ + +2009-09-02: wsfulton + Fix #2845746. true and false are now recognised keywords (only when wrapping C++). + Constants such as the following are now wrapped (as type bool): + #define FOO true + #define BAR FOO && false + +Version 1.3.40 (18 August 2009) +=============================== + +2009-08-17: olly + [Perl] Add "#undef do_exec" to our clean up of Perl global + namespace pollution. + +2009-08-17: olly + [PHP] Fix to wrap a resource returned by __get() in a PHP object (SF#2549217). + +2009-08-17: wsfulton + Fix #2797485 After doing a 'make clean', install fails if yodl2man or yodl2html + is not available. + +2009-08-16: wsfulton + [Octave] Caught exceptions display the type of the C++ exception instead of the + generic "c++-side threw an exception" message. + +2009-08-16: wsfulton + [Java] When %catches is used, fix so that any classes specified in the "throws" + attribute of the "throws" typemap are generated into the Java method's throws clause. + +2009-08-16: wsfulton + [C#] Fix exception handling when %catches is used, reported by Juan Manuel Alvarez. + +2009-08-15: wsfulton + Fix %template seg fault on some cases of overloading the templated method. + Bug reported by Jan Kupec. + +2009-08-15: wsfulton + [Ruby] Add numerous missing wrapped methods for std::vector specialization + as reported by Youssef Jones. + +2009-08-14: wsfulton + [Perl] Add SWIG_ConvertPtrAndOwn() method into the runtime for smart pointer + memory ownership control. shared_ptr support still to be added. Patch from + David Fletcher. + +2009-08-14: olly + [PHP] PHP5 now wraps static member variables as documented. + +2009-08-14: olly + [PHP] Update the PHP "class" example to work with PHP5 and use + modern wrapping features. + +2009-08-13: wsfulton + [PHP] std::vector wrappers overhaul. They no longer require the + specialize_std_vector() macro. Added wrappers for capacity() and reserve(). + +2009-08-13: wsfulton + [PHP] Add const reference typemaps. const reference primitive types are + now passed by value rather than pointer like the other target languages. + Fixes SF#2524029. + +2009-08-08: wsfulton + [Python] More user friendly AttributeError is raised when there are + no constructors generated for the proxy class in the event that the + class is abstract - the error message is now + "No constructor defined - class is abstract" whereas if there are no + public constructors for any other reason and the class is not abstract, + the message remains + "No constructor defined". + [tcl] Similarly for tcl when using -itcl. + +2009-08-04: olly + [PHP] Fix generated code to work with PHP 5.3. + +2009-08-04: vmiklos + [PHP] Various mathematical functions (which would conflict + with the built-in PHP ones) are now automatically handled by + adding a 'c_' prefix. + +2009-08-03: wsfulton + [C#] The std::vector implementation is improved and now uses $typemap such + that the proxy class for T no longer has to be specified in some macros + for correct C# compilation; the following macros are deprecated, where + CSTYPE was the C# type for the C++ class CTYPE: + + SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE) + usage should be removed altogether + + SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE) + should be replaced with: + SWIG_STD_VECTOR_ENHANCED(CTYPE) + + Some more details in csharp/std_vector.i + + *** POTENTIAL INCOMPATIBILITY *** + +2009-07-31: olly + [Python] Fix indentation so that we give a useful error if the + module can't be loaded. Patch from Gaetan Lehmann in SF#2829853. + +2009-07-29: wsfulton + Add $typemap(method, typelist) special variable macro. This allows + the contents of a typemap to be inserted within another typemap. + Fully documented in Typemaps.html. + +2009-07-29: vmiklos + [PHP] Static member variables are now prefixed with the + class name. This allows static member variables with the + same name in different classes. + +2009-07-29: olly + [Python] Add missing locks to std::map wrappers. Patch from + Paul Hampson in SF#2813836. + +2009-07-29: olly + [PHP] Fix memory leak in PHP OUTPUT typemaps. Reported by Hitoshi + Amano in SF#2826322. + +2009-07-29: olly + [PHP] Fix memory leak in PHP resource destructor for classes + without a destructor and non-class types. Patch from Hitoshi Amano + in SF#2825303. + +2009-07-28: olly + [PHP] Update warnings about clashes between identifiers and PHP + keywords and automatic renaming to work with the PHP5 class + wrappers. Fixes SF#1613679. + +2009-07-28: vmiklos + [PHP] If a member function is not public but it has a base + which is public, then now a warning is issued and the member + function will be public, as PHP requires this. + +2009-07-21: vmiklos + [PHP] Director support added. + +2009-07-15: olly + [Perl] Don't specify Perl prototype "()" for a constructor with a + different name to the class, as such constructors can still take + parameters. + +2009-07-12: xavier98 + [Octave] Add support for Octave 3.2 API + +2009-07-05: olly + [PHP] Update the list of PHP keywords - "cfunction" is no longer a + keyword in PHP5 and PHP 5.3 added "goto", "namespace", "__DIR__", + and "__NAMESPACE__". + +2009-07-03: olly + [Tcl] To complement USE_TCL_STUBS, add support for USE_TK_STUBS + and SWIG_TCL_STUBS_VERSION. Document all three in the Tcl chapter + of the manual. Based on patch from SF#2810380 by Christian + Gollwitzer. + +2009-07-02: vmiklos + [PHP] Added factory.i for PHP, see the li_factory testcase + for more info on how to use it. + +2009-07-02: wsfulton + Fix -Wallkw option as reported by Solomon Gibbs. + +2009-07-02: wsfulton + Fix syntax error when a nested struct contains a comment containing a * followed + eventually by a /. Regression from 1.3.37, reported by Solomon Gibbs. + +2009-07-01: vmiklos + [PHP] Unknown properties are no longer ignored in proxy + classes. + +2009-07-01: vmiklos + [PHP] Fixed %newobject behaviour, previously any method + marked with %newobject was handled as a constructor. + +2009-06-30: olly + [Ruby] Undefine close and connect macros defined by Ruby API + headers as we don't need them and they can clash with C++ methods + being wrapped. Patch from Vit Ondruch in SF#2814430. + +2009-06-26: olly + [Ruby] Fix to handle FIXNUM values greater than MAXINT passed for a + double parameter. + +2009-06-24: wsfulton + Fix wrapping methods with default arguments and the compactdefaultargs feature + where a class is passed by value and is assigned a default value. The SwigValueWrapper + template workaround for a missing default constructor is no longer used as the code + generated does not call the default constructor. + +2009-06-16: wsfulton + [Java,C#] Fix enum marshalling when %ignore is used on one of the enum items. + Incorrect enum values were being passed to the C++ layer or compilation errors resulted. + +2009-06-02: talby + [Perl] Resolved reference.i overload support problem + identified by John Potowsky. + +2009-05-26: wsfulton + [C#] Improved std::map wrappers based on patch from Yuval Baror. The C# proxy + now implements System.Collections.Generic.IDictionary<>. + + These std:map wrappers have a non-backwards compatible overhaul to make them + like a .NET IDictionary. Some method names have changed as following: + set -> setitem (use this[] property now) + get -> getitem (use this[] property now) + has_key -> ContainsKey + del -> Remove + clear -> Clear + + The following macros used for std::map wrappers are deprecated and will no longer work: + specialize_std_map_on_key + specialize_std_map_on_value + specialize_std_map_on_both + + *** POTENTIAL INCOMPATIBILITY *** + +2009-05-20: vmiklos + [PHP] Add the 'thisown' member to classes. The usage of it + is the same as the Python thisown one: it's 1 by default and + you can set it to 0 if you want to prevent freeing it. (For + example to prevent a double free.) + +2009-05-14: bhy + [Python] Fix the wrong pointer value returned by SwigPyObject_repr(). + +2009-05-13: mutandiz (Mikel Bancroft) + [allegrocl] Minor tweak when wrapping in -nocwrap mode. + +2009-05-11: wsfulton + [C#] Improved std::vector wrappers on the C# proxy side from Yuval Baror. These + implement IList<> instead of IEnumerable<> where possible. + +2009-04-29: wsfulton + [Java, C#] Add the 'notderived' attribute to the javabase and csbase typemaps. + When this attribute is set, the typemap will not apply to classes that are derived + from a C++ base class, eg + %typemap(csbase, notderived="1") SWIGTYPE "CommonBase" + +2009-04-29: olly + [Python] Don't attempt to acquire the GIL in situations where we + know that it will already be locked. This avoids some dead-locks + with mod_python (due to mod_python bugs which are apparently + unlikely to ever be fixed), and results in smaller wrappers which + run a little faster (in tests with Xapian on x86-64 Ubuntu 9.04, + the stripped wrapper library was 11% smaller and ran 2.7% faster). + +2009-04-21: wsfulton + [C#] Fix #2753469 - bool &OUTPUT and bool *OUTPUT typemaps initialisation. + +2009-04-09: wsfulton + Fix #2746858 - C macro expression using floating point numbers + +2009-03-30: olly + [PHP] The default out typemap for char[ANY] now returns the string up to a + zero byte, or the end of the array if there is no zero byte. This + is the same as Python does, and seems more generally useful than + the previous behaviour of returning the whole contents of the array + including any zero bytes. If you want the old behaviour, you can provide + your own typemap to do this: + + %typemap(out) char [ANY] + %{ + RETVAL_STRINGL($1, $1_dim0, 1); + %} + +Version 1.3.39 (21 March 2009) +============================== + +2009-03-19: bhy + [Python] Fix the memory leak related to Python 3 unicode and C char* conversion, + which can be shown in the following example before this fix: + + from li_cstring import * + i=0 + while True: + i += 1 + n = str(i)*10 + test3(n) + + This fix affected SWIG_AsCharPtrAndSize() so you cannot call this function with + a null alloc and non-null cptr argument in Python 3, otherwise a runtime error + will be raised. + +2009-03-18: wsfulton + [C#] std::vector wrapper improvements for .NET 2 and also providing the + necessary machinery to use the std::vector wrappers with more advanced features such + as LINQ - the C# proxy class now derives from IEnumerable<>. The default is now to + generate code requiring .NET 2 as a minimum, although the C# code can be compiled + for .NET 1 by defining the SWIG_DOTNET_1 C# preprocessor constant. See the + std_vector.i file for more details. + + *** POTENTIAL INCOMPATIBILITY *** + +2009-03-12: wsfulton + [Ruby] Fix #2676738 SWIG generated symbol name clashes. + +2009-03-01: bhy + [Python] Some fixes for Python 3.0.1 and higher support. In 3.0.1, the C API function + PyObject_Compare is removed, so PyObject_RichCompareBool is used for replacement. + Struct initilization of SwigPyObject and SwigPyObject_as_number changed to reflect + the drop of tp_compare and nb_long. + +2009-03-01: bhy + [Python] Fix SF#2583160. Now the importer in Python shadow wrapper take care of the + case that module already imported at other place. + +2009-02-28: bhy + [Python] Fix SF#2637352. Move struct declaration of SWIG_module in pyinit.swg before + the method calls, since some C compiler don't allow declaration in middle of function + body. + +2009-02-21: wsfulton + [Allegrocl] Fix seg fault wrapping some constant variable (%constant) types. + +2009-02-20: wsfulton + [CFFI] Fix seg faults when for %extend and using statements. + +2009-02-20: wsfulton + Fix SF #2605955: -co option which broke in 1.3.37. + +2009-02-20: wsfulton + New %insert("begin") section added. Also can be used as %begin. This is a new + code section reserved entirely for users and the code within the section is generated + at the top of the C/C++ wrapper file and so provides a means to put custom code + into the wrapper file before anything else that SWIG generates. + +2009-02-17: wsfulton + 'make clean-test-suite' will now run clean on ALL languages. Previously it only + ran the correctly configured languages. This way it is now possible to clean up + properly after running 'make partialcheck-test-suite'. + +2009-02-14: wsfulton + Extend attribute library support for structs/classes and the accessor functions use + pass/return by value semantics. Two new macros are available and usage is identical + to %attribute. These are %attributeval for structs/classes and %attributestring for + string classes, like std::string. See attribute.swg for more details. + +2009-02-13: wsfulton + Add support for %extend and memberin typemaps. Previously the memberin typemaps were + ignored for member variables within a %extend block. + +2009-02-12: wsfulton + Remove unnecessary temporary variable when wrapping return values that are references. + Example of generated code for wrapping: + + struct XYZ { + std::string& refReturn(); + }; + + used to be: + + std::string *result = 0 ; + ... + { + std::string &_result_ref = (arg1)->refReturn(); + result = (std::string *) &_result_ref; + } + + Now it is: + + std::string *result = 0 ; + ... + result = (std::string *) &(arg1)->refReturn(); + +2009-02-08: bhy + Change the SIZE mapped by %pybuffer_mutable_binary and %pybuffer_binary in pybuffer.i from + the length of the buffer to the number of items in the buffer. + +2009-02-08: wsfulton + Fix %feature not working for conversion operators, reported by Matt Sprague, for example: + %feature("cs:methodmodifiers") operator bool "protected"; + +2009-02-07: wsfulton + [MzScheme] Apply #2081967 configure changes for examples to build with recent PLT versions. + Also fixes Makefile errors building SWIG executable when mzscheme package is installed + (version 3.72 approx and later). + +2009-02-04: talby + [Perl] Fix SF#2564192 reported by David Kolovratnk. + SWIG_AsCharPtrAndSize() now handles "get" magic. + +Version 1.3.38 (31 January 2009) +================================ + +2009-01-31: bhy + [Python] Fix SF#2552488 reported by Gaetan Lehmann. Now %pythonprepend + and %pythonappend have correct indentation. + +2009-01-31: bhy + [Python] Fix SF#2552048 reported by Gaetan Lehmann. The parameter list + of static member function in generated proxy code should not have the + 'self' parameter. + +2009-01-29: wsfulton + Fix regression introduced in 1.3.37 where the default output directory + for target language specific files (in the absence of -outdir) was no + longer the same directory as the generated c/c++ file. + +2009-01-28: wsfulton + [Java, C#] Fix proxy class not being used when the global scope operator + was used for parameters passed by value. Reported by David Piepgrass. + +2009-01-15: wsfulton + [Perl] Fix seg fault when running with -v option, reported by John Ky. + +Version 1.3.37 (13 January 2009) +================================ + +2009-01-13: mgossage + [Lua] Added contract support for requiring that unsigned numbers are >=0 + Rewrote much of Examples/Lua/embed3. + Added a lot to the Lua documentation. + +2009-01-13: wsfulton + Fix compilation error when using directors on protected virtual overloaded + methods reported by Sam Hendley. + +2009-01-12: drjoe + [R] Fixed handling of integer arrays + +2009-01-10: drjoe + [R] Fix integer handling in r to deal correctly with signed + and unsigned issues + +2009-01-10: wsfulton + Patch #1992756 from Colin McDonald - %contract not working for classes + in namespace + +2009-01-05: olly + Mark SWIGPERL5, SWIGPHP5, and SWIGTCL8 as deprecated in the source + code and remove documentation of them. + +2008-12-30: wsfulton + Bug #2430756. All the languages now define a macro in the generated C/C++ + wrapper file indicating which language is being wrapped. The macro name is the + same as those defined when SWIG is run, eg SWIGJAVA, SWIGOCTAVE, SWIGCSHARP etc + and are listed in the "Conditional Compilation" section in the documentation. + +2008-12-23: wsfulton + [Java] Fix #2153773 - %nojavaexception was clearing the exception feature + instead of disabling it. Clearing checked Java exceptions also didn't work. + The new %clearjavaexception can be used for clearing the exception feature. + +2008-12-22: wsfulton + Fix #2432801 - Make SwigValueWrapper exception safe for when copy constructors + throw exceptions. + +2008-12-21: wsfulton + Apply patch #2440046 which fixes possible seg faults for member and global + variable char arrays when the strings are larger than the string array size. + +2008-12-20: wsfulton + The ccache compiler cache has been adapted to work with SWIG and + named ccache-swig. It now works with C/C++ compilers as well as SWIG + and can result in impressive speedups when used to recompile unchanged + code with either a C/C++ compiler or SWIG. Documentation is in CCache.html + or the installed ccache-swig man page. + +2008-12-12: wsfulton + Apply patch from Kalyanov Dmitry which fixes parsing of nested structs + containing comments. + +2008-12-12: wsfulton + Fix error message in some nested struct and %inline parsing error situations + such as unterminated strings and comments. + +2008-12-07: olly + [PHP] Fix warnings when compiling generated wrapper with GCC 4.3. + +2008-12-06: wsfulton + [PHP] Deprecate %pragma(php4). Please use %pragma(php) instead. + The following two warnings have been renamed: + WARN_PHP4_MULTIPLE_INHERITANCE -> WARN_PHP_MULTIPLE_INHERITANCE + WARN_PHP4_UNKNOWN_PRAGMA -> WARN_PHP_UNKNOWN_PRAGMA + + *** POTENTIAL INCOMPATIBILITY *** + +2008-12-04: bhy + [Python] Applied patch SF#2158938: all the SWIG symbol names started with Py + are changed, since they are inappropriate and discouraged in Python + documentation (from http://www.python.org/doc/2.5.2/api/includes.html): + + "All user visible names defined by Python.h (except those defined by + the included standard headers) have one of the prefixes "Py" or "_Py". + Names beginning with "_Py" are for internal use by the Python implementation + and should not be used by extension writers. Structure member names do + not have a reserved prefix. + + Important: user code should never define names that begin with "Py" or "_Py". + This confuses the reader, and jeopardizes the portability of the user + code to future Python versions, which may define additional names beginning + with one of these prefixes." + + Here is a brief list of what changed: + + PySwig* -> SwigPy* + PyObject_ptr -> SwigPtr_PyObject + PyObject_var -> SwigVar_PyObject + PySequence_Base, PySequence_Cont, PySequence_Ref -> + SwigPySequence_Base, SwigPySequence_Cont, SwigPySequence_Ref + PyMap* -> SwigPyMap* + + We provided a pyname_compat.i for backward compatibility. Users whose code having + these symbols and do not want to change it could simply include this file + at front of your code. A better solution is to run the converting tool on + your code, which has been put in SWIG's SVN trunk (Tools/pyname_patch.py) and + you can download it here: + https://swig.svn.sourceforge.net/svnroot/swig/trunk/Tools/pyname_patch.py + + *** POTENTIAL INCOMPATIBILITY *** + +2008-12-02: wsfulton + [Python] Apply patch #2143727 from Serge Monkewitz to fix importing base classes + when the package option is specified in %module and that module is %import'ed. + +2008-11-28: wsfulton + [UTL] Fix #2080497. Some incorrect acceptance of types in the STL, eg a double * element + passed into a vector constructor would be accepted, but the ensuing behaviour + was undefined. Now the type conversion correctly raises an exception. + +2008-11-24: wsfulton + Add -outcurrentdir option. This sets the default output directory to the current + directory instead of the path specified by the input file. This option enables + behaviour similar to c/c++ compilers. Note that this controls the output directory, + but only in the absence of the -o and/or -outdir options. + +2008-11-23: wsfulton + [ruby] Apply patch #2263850 to fix ruby/file.i ... rubyio.h filename change in + ruby 1.9. + +2008-11-23: wsfulton + Apply patch #2319790 from Johan Hake to fix shared_ptr usage in std::tr1 namespace. + +2008-11-21: wsfulton + The use of the include path to find the input file is now deprecated. + This makes the behaviour of SWIG the same as C/C++ compilers in preparation + for use with ccache. + +2008-11-16: wsfulton + Fix -nopreprocess option to: + - correctly report file names in warning and error messages. + - use the original input filename that created the preprocessed output when + determining the C++ wrapper file name (in the absence of -o). Previously + the name of the input file containing the preprocessed output was used. + +2008-11-11: wsfulton + [Java] Add patch #2152691 from MATSUURA Takanori which fixes compiles using the + Intel compiler + +2008-11-01: wsfulton + Add patch #2128249 from Anatoly Techtonik which corrects the C/C++ proxy + class being reported for Python docstrings when %rename is used. + +2008-11-01: wsfulton + Add the strip encoder patch from Anatoly Techtonik #2130016. This enables an + easy way to rename symbols by stripping a commonly used prefix in all the + function/struct names. It works in the same way as the other encoders, such as + title, lower, command etc outlined in CHANGES file dated 12/30/2005. Example + below will rename wxAnotherWidget to AnotherWidget and wxDoSomething to + DoSomething: + + %rename("%(strip:[wx])s") ""; + + struct wxAnotherWidget { + void wxDoSomething(); + }; + +2008-09-26: mutandiz + [allegrocl] + Lots of test-suite work. + - Fix ordering of wrapper output and %{ %} header output. + - Fix declarations of local vars in C wrappers. + - Fix declaration of defined constants in C wrappers. + - Fix declaration of EnumValues in C wrappers. + - add some const typemaps to allegrocl.swg + - add rename for operator bool() overloads. + +2008-09-25: olly + [PHP5] Fill in typemaps for SWIGTYPE and void * (SF#2095186). + +2008-09-22: mutandiz (Mikel Bancroft) + [allegrocl] + - Support wrapping of types whose definitions are not seen by + SWIG. They are treated as forward-referenced classes and if a + definition is not seen are treated as (* :void). + - Don't wrap the contents of unnamed namespaces. + - More code cleanup. Removed some extraneous warnings. + - start work on having the allegrocl mod pass the cpp test-suite. + +2008-09-19: olly + [PHP5] Add typemaps for long long and unsigned long long. + +2008-09-18: wsfulton + [C#] Added C# array typemaps provided by Antti Karanta. + The arrays provide a way to use MarshalAs(UnmanagedType.LPArray) + and pinning the array using 'fixed'. See arrays_csharp.i library file + for details. + +2008-09-18: wsfulton + Document the optional module attribute in the %import directive, + see Modules.html. Add a warning for Python wrappers when the + module name for an imported base class is missing, requiring the + module attribute to be added to %import, eg + + %import(module="FooModule") foo.h + +2008-09-18: olly + [PHP5] Change the default input typemap for char * to turn PHP + Null into C NULL (previously it was converted to an empty string). + The new behaviour is consistent with how the corresponding output + typemap works (SF#2025719). + + If you want to keep the old behaviour, add the following typemap + to your interface file (PHP's convert_to_string_ex() function does + the converting from PHP Null to an empty string): + + %typemap(in) char * { + convert_to_string_ex($input); + $1 = Z_STRVAL_PP($input); + } + +2008-09-18: olly + [PHP5] Fix extra code added to proxy class constructors in the case + where the only constructor takes no arguments. + +2008-09-18: olly + [PHP5] Fix wrapping of a renamed enumerated value of an enum class + member (SF#2095273). + +2008-09-17: mutandiz (Mikel Bancroft) + [allegrocl] + - Fix how forward reference typedefs are handled, so as not to conflict + with other legit typedefs. + - Don't (for now) perform an ffitype typemap lookup when trying to + when calling compose_foreign_type(). This is actually a useful thing + to do in certain cases, the test cases for which I can't currently + locate :/. It's breaking some wrapping behavior that is more commonly + seen, however. I'll readd in a more appropriate way when I can + recreate the needed test case, or a user complains (which means + they probably have a test case). + - document the -isolate command-line arg in the 'swig -help' output. + It was in the html docs, but not there. + - small amount of code cleanup, removed some unused code. + - some minor aesthetic changes. + +2008-09-12: bhy + [Python] Python 3.0 support branch merged into SWIG trunk. Thanks to + Google Summer of Code 2008 for supporting this project! By default + SWIG will generate interface files compatible with both Python 2.x + and 3.0. And there's also some Python 3 new features that can be + enabled by passing a "-py3" command line option to SWIG. These + features are: + + - Function annotation support + Also, the parameter list of proxy function will be generated, + even without the "-py3" option. However, the parameter list + will fallback to *args if the function (or method) is overloaded. + - Buffer interface support + - Abstract base class support + + For details of Python 3 support and these features, please see the + "Python 3 Support" section in the "SWIG and Python" chapter of the SWIG + documentation. + + The "-apply" command line option and support of generating codes + using apply() is removed. Since this is only required by very old + Python. + + This merge also patched SWIG's parser to solve a bug. By this patch, + SWIG features able to be correctly applied on C++ conversion operator, + such like this: + + %feature("shadow") *::operator bool %{ ... %} + +2008-09-02: richardb + [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-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: wsfulton + [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 1.3.36 (24 June 2008) +============================= + +06/24/2008: wsfulton + Remove deprecated -c commandline option (runtime library generation). + +06/24/2008: olly + [PHP] Fix assertion failure when handling %typemap(in,numinputs=0) + (testcase ignore_parameter). + +06/24/2008: olly + [PHP] Fix segfault when wrapping a non-class function marked with + %newobject (testcase char_strings). + +06/22/2008: wsfulton + [Java] Add a way to use AttachCurrentThreadAsDaemon instead of AttachCurrentThread + in director code. Define the SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON macro, see + Lib/java/director.swg. + +06/21/2008: wsfulton + [Ruby] Fix crashing in the STL wrappers (reject! and delete_if methods) + +06/19/2008: wsfulton + [Java, C#] C# and Java keywords will be renamed instead of just issuing a warning + and then generating uncompileable code. Warning 314 gives the new name when a + keyword is found. + +06/19/2008: wsfulton + [R] Keyword handling added. R Keywords will be renamed as necessary. + Warning 314 gives the new name when a keyword is found. + +06/17/2008: mgossage + [Lua] Added missing support for bool& and bool*. Added runtest for li_typemaps testcase. + (Bug #1938142) + +06/07/2008: bhy + Added test case keyword_rename, then made the keyword renaming works properly + by fixing Swig_name_make() for a incomplete condition checking. + +06/02/2008: wsfulton + [Java, C#] Fix enum wrappers when using -noproxy. + +05/30/2008: bhy + Added std::wstring into Lib/typemaps/primtypes.swg, since it is also a primitive + type in SWIG - fixed SF #1976978. + +05/29/2008: wsfulton + [Java, C#] Fix variable wrappers when using -noproxy. + +05/29/2008: bhy + [Python] Fixed a typo of %#ifdef in Lib/python/pycontainer.swg, which is related + to -extranative SWIG option - SF #1971977. + +05/20/2008: wsfulton + New partialcheck makefile targets for partial testing of the test-suite. These + just invoke SWIG, ie no compilation and no runtime testing. It can be faster + when developing by just doing a directory diff of the files SWIG generates + against those from a previous run. Example usage from the top level directory: + + make partialcheck-test-suite + make partialcheck-java-test-suite + + This change also encompasses more flexibility in running the test-suite, eg + it is possible to prefix the command line which runs any target language test + with a tool. See the RUNTOOL, COMPILETOOL and SWIGTOOL targets in the common.mk + file and makefiles in the test-suite directory. For example it is possible to + run the runtime tests through valgrind using: + + make check RUNTOOL="valgrind --leak-check=full" + + or invoke SWIG under valgrind using: + + make check SWIGTOOL="valgrind --tool=memcheck" + +05/19/2008: drjoe + [R] Fixed define that was breaking pre-2.7. Checked in + patch from Soren Sonnenburg that creates strings in + version independent way + +05/15/2008: wsfulton + [Java] Fix variable name clash in directors - SF #1963316 reported by Tristan. + +05/14/2008: wsfulton + Add an optimisation for functions that return objects by value, reducing + the number of copies of the object that are made. Implemented using an + optional attribute in the "out" typemap called "optimal". Details in + Typemaps.html. + +05/11/2008: olly + [PHP] Check for %feature("notabstract") when generating PHP5 class + wrapper. + +05/11/2008: wsfulton + Fix SF #1943608 - $self substitution in %contract, patch submitted by + Toon Verstraelen. + +05/09/2008: olly + [PHP] Fix char * typemaps to work when applied to signed char * and + unsigned char * (uncovered by testcase apply_strings). + +05/09/2008: wsfulton + Fix wrapping of char * member variables when using allprotected mode. + Bug reported by Warren Wang. + +05/09/2008: olly + [PHP] Fix bad PHP code generated when wrapping an enum in a + namespace (uncovered by testcase arrays_scope). + +05/09/2008: olly + [PHP] SWIG now runs the PHP testsuite using PHP5, not PHP4. PHP4 + is essentially obsolete now, so we care much more about solid PHP5 + support. + +05/07/2008: wsfulton + STL fixes when using %import rather than %include and the Solaris Workshop + compiler and the Roguewave STL. + +05/07/2008: wsfulton + Fix wrapping of overloaded protected methods when using allprotected mode. + Bug reported by Warren Wang. + +05/03/2008: wsfulton + Commit patch #1956607 to add -MT support from Richard Boulton. + This patch mirrors the gcc -MT option which allows one to change the default + Makefile target being generated when generating makefiles with the -M family + of options. For example: + + $ swig -java -MM -MT overiddenname -c++ example.i + overiddenname: \ + example.i \ + example.h + +04/30/2008: mgossage + [Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor) + which was unused and causing warning with g++ -Wall. + Removed other unused warning in typemaps.i and other places. + Added Examples/lua/embed3, and run tests a few test cases. + +04/24/2008: olly + [Python] Fix generated code for IBM's C++ compiler on AIX (patch + from Goeran Uddeborg in SF#1928048). + +04/24/2008: olly + Rename BSIZE in Examples/test-suite/arrays_scope.i to BBSIZE to + avoid a clash with BSIZE defined by headers on AIX with Perl + (reported in SF#1928048). + +04/20/2008: wsfulton + Add the ability to wrap all protected members when using directors. + Previously only the virtual methods were available to the target language. + Now all protected members, (static and non-static variables, non-virtual methods + and static methods) are wrapped when using the allprotected mode. The allprotected + mode is turned on in the module declaration: + + %module(directors="1", allprotected="1") modulename Version 1.3.35 (7 April 2008) ============================= @@ -60,7 +2599,7 @@ Version 1.3.35 (7 April 2008) 03/17/2008: olly Fix memory leak in SWIG's parser (based on patch from Russell - Bryant in SF#1914023).` + Bryant in SF#1914023). 03/12/2008: wsfulton Fix bug #1878285 - unnecessary cast for C struct creation wrappers. @@ -321,7 +2860,7 @@ Version 1.3.34 (27 February 2008) }; Version 1.3.33 (November 23, 2007) -================================= +================================== 11/21/2007: mikel [allegrocl] omit private slot type info in the classes/types @@ -1253,7 +3792,7 @@ Version 1.3.31 (November 20, 2006) [lua] update to typemap for object by value, to make it c89 compliant Version 1.3.30 (November 13, 2006) -================================= +================================== 11/12/2006: wsfulton [java] Remove DetachCurrentThread patch from 08/11/2006 - it causes segfaults @@ -5576,7 +8115,7 @@ Version 1.3.24 (December 14, 2004) compile with no errors, java shows some problems. Version 1.3.23 (November 11, 2004) -================================= +================================== 11/05/2004: wsfulton Patch #982753 from Fabrice Salvaire: Adds dependencies generation for @@ -7360,7 +9899,7 @@ Version 1.3.22 (September 4, 2004) When needed, use %inlcude std_string.i // 'char' strings - %inlcude std_wstring.i // 'wchar_t; strings + %inlcude std_wstring.i // 'wchar_t' strings 04/10/2004: mmatus (Marcelo Matus) @@ -7827,7 +10366,8 @@ Version 1.3.22 (September 4, 2004) exception instead. Version 1.3.21 (January 11, 2004) -================================== +================================= + 01/10/2004: cheetah (William Fulton) The output format for both warnings and errors can be selected for integration with your favourite IDE/editor. Editors and IDEs can usually @@ -9601,6 +12141,7 @@ Version 1.3.20 (December 17, 2003) Version 1.3.19 (March 28, 2003) =============================== + 03/28/2003: beazley Variety of minor bug fixes to the 1.3.18 release including: @@ -10187,6 +12728,7 @@ Version 1.3.18 (March 23, 2003) Version 1.3.17 (November 22, 2002) ================================== + 11/19/2002: beazley Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG. @@ -10542,6 +13084,7 @@ Version 1.3.16 (October 14, 2002) Version 1.3.15 (September 9, 2002) ================================== + 09/09/2002: beazley Fixed nasty runtime type checking bug with subtypes and inheritance and templates. @@ -12123,7 +14666,8 @@ Version 1.3.14 (August 12, 2002) with helper functions even if they aren't used. To fix this, a new fragment directive is available. For example: - %fragment("type_helper","header") %{ + (corrected typo in line below - 06/26/2008) + %fragment("type_header","header") %{ void some_helper_function() { ... } @@ -12233,6 +14777,7 @@ Version 1.3.14 (August 12, 2002) Version 1.3.13 (June 17, 2002) ============================== + 06/16/2002: beazley Fixed a bug with __FILE__ expansion in the preprocessor. On Windows, the backslash (\) is now converted to (\\) in the string literal @@ -15364,6 +17909,7 @@ Version 1.3.10 (December 10, 2001) Version 1.3.9 (September 25, 2001) ================================== + 9/25/2001: beazley Fixed parsing problem with type declarations like 'char ** const'. SWIG parsed this correctly, but the @@ -15376,6 +17922,7 @@ Version 1.3.9 (September 25, 2001) Version 1.3.8 (September 23, 2001) ================================== + 9/23/2001: beazley Included improved distutils setup.py file in the Tools directory (look for the setup.py.tmpl file). Contributed by @@ -16748,7 +19295,7 @@ Version 1.3 Alpha 5 and function bodies. Preprocessor bug. Version 1.3 Alpha 4 (September 4, 2000) -====================================== +======================================= 9/3/00 : ttn Added instructions for maintainers in Examples/README on how @@ -17834,6 +20381,7 @@ Version 1.3 Alpha 1 (February 11, 2000) Version 1.1 Patch 5 (February 5, 1998) ====================================== + 2/4/98 : Fixed a bug in the configure script when different package locations are specified (--with-tclincl, etc...). @@ -18086,6 +20634,7 @@ Version 1.1 Patch 3 (November 24, 1997) Version 1.1 Patch 2 (September 4, 1997) ======================================= + 9/4/97 : Fixed problem with handling of virtual functions that was introduced by some changes in the C++ module. @@ -19221,7 +21770,7 @@ This release should fix most, if not all, of those problems. it generated alot of unnecessary code). Version 1.1 Beta3 (January 9, 1997) -==================================== +=================================== Note : A *huge* number of changes related to ongoing modifications. @@ -19344,6 +21893,7 @@ Version 1.1 Beta1 (October 30, 1996) Version 1.0 Final (August 31, 1996) =================================== + 1. Fixed minor bug in C++ module 2. Fixed minor bug in pointer type-checker when using @@ -19427,7 +21977,7 @@ number of immediate problems : 3. A few minor fixes were made in the Makefile Version 1.0 Beta 3 (June 14, 1996) -=================================== +================================== There are lots of changes in this release : @@ -19517,6 +22067,7 @@ let me know. Version 1.0 Beta 2 (April 26, 1996) =================================== + This release is identical to Beta1 except a few minor bugs are fixed and the SWIG library has been updated to work with Tcl 7.5/Tk 4.1. A tcl7.5 examples directory is now included. @@ -19531,6 +22082,7 @@ A tcl7.5 examples directory is now included. Version 1.0 Beta 1 (April 10, 1996). ===================================== + This is the first "semi-official" release of SWIG. It has a number of substantial improvements over the Alpha release. These notes are in no particular order--hope I remembered everything.... diff --git a/CHANGES.current b/CHANGES.current index 27e9925d2..cb64a7937 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,106 +1,17 @@ -Version 1.3.36 (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. + +Version 2.0.6 (30 April 2012) ============================= -05/20/2008: wsfulton - New partialcheck makefile targets for partial testing of the test-suite. These - just invoke SWIG, ie no compilation and no runtime testing. It can be faster - when developing by just doing a directory diff of the files SWIG generates - against those from a previous run. Example usage from the top level directory: +2012-04-25: wsfulton + [Lua] Fix uninitialised variable in SWIGTYPE **OUTPUT typemaps as reported by Jim Anderson. - make partialcheck-test-suite - make partialcheck-java-test-suite +2012-04-28: wsfulton + [Python] Fix compilation errors when wrapping STL containers on Mac OSX and possibly other systems. - This change also encompasses more flexibility in running the test-suite, eg - it is possible to prefix the command line which runs any target language test - with a tool. See the RUNTOOL, COMPILETOOL and SWIGTOOL targets in the common.mk - file and makefiles in the test-suite directory. For example it is possible to - run the runtime tests through valgrind using: - - make check RUNTOOL="valgrind --leak-check=full" - - or invoke SWIG under valgrind using: - - make check SWIGTOOL="valgrind --tool=memcheck" - -05/19/2008: drjoe - [R] Fixed define that was breaking pre-2.7. Checked in - patch from Soren Sonnenburg that creates strings in - version independent way - -05/15/2008: wsfulton - [Java] Fix variable name clash in directors - SF #1963316 reported by Tristan. - -05/14/2008: wsfulton - Add an optimisation for functions that return objects by value, reducing - the number of copies of the object that are made. Implemented using an - optional attribute in the "out" typemap called "optimal". Details in - Typemaps.html. - -05/11/2008: olly - [PHP] Check for %feature("notabstract") when generating PHP5 class - wrapper. - -05/11/2008: wsfulton - Fix SF #1943608 - $self substitution in %contract, patch submitted by - Toon Verstraelen. - -05/09/2008: olly - [PHP] Fix char * typemaps to work when applied to signed char * and - unsigned char * (uncovered by testcase apply_strings). - -05/09/2008: wsfulton - Fix wrapping of char * member variables when using allprotected mode. - Bug reported by Warren Wang. - -05/09/2008: olly - [PHP] Fix bad PHP code generated when wrapping an enum in a - namespace (uncovered by testcase arrays_scope). - -05/09/2008: olly - [PHP] SWIG now runs the PHP testsuite using PHP5, not PHP4. PHP4 - is essentially obsolete now, so we care much more about solid PHP5 - support. - -05/07/2008: wsfulton - STL fixes when using %import rather than %include and the Solaris Workshop - compiler and the Roguewave STL. - -05/07/2008: wsfulton - Fix wrapping of overloaded protected methods when using allprotected mode. - Bug reported by Warren Wang. - -05/03/2008: wsfulton - Commit patch #1956607 to add -MT support from Richard Boulton. - This patch mirrors the gcc -MT option which allows one to change the default - Makefile target being generated when generating makefiles with the -M family - of options. For example: - - $ swig -java -MM -MT overiddenname -c++ example.i - overiddenname: \ - example.i \ - example.h - -04/30/2008: mgossage - [Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor) - which was unused and causing warning with g++ -Wall. - Removed other unused warning in typemaps.i and other places. - Added Examples/lua/embed3, and run tests a few test cases. - -04/24/2008: olly - [Python] Fix generated code for IBM's C++ compiler on AIX (patch - from Goeran Uddeborg in SF#1928048). - -04/24/2008: olly - Rename BSIZE in Examples/test-suite/arrays_scope.i to BBSIZE to - avoid a clash with BSIZE defined by headers on AIX with Perl - (reported in SF#1928048). - -04/20/2008: wsfulton - Add the ability to wrap all protected members when using directors. - Previously only the virtual methods were available to the target language. - Now all protected members, (static and non-static variables, non-virtual methods - and static methods) are wrapped when using the allprotected mode. The allprotected - mode is turned on in the module declaration: - - %module(directors="1", allprotected="1") modulename +2012-04-28: wsfulton + [Java] Patch 3521811 from Leo Davis - char **STRING_ARRAY typemaps fixed to handle + null pointers. diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 000000000..2fe0099b8 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,104 @@ +SWIG Copyright and Authors +-------------------------- + +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 + +Portions also copyrighted by: + Network Applied Communication Laboratory, Inc + Information-technology Promotion Agency, Japan + +Active SWIG Developers: + William Fulton (wsf@fultondesigns.co.uk) (SWIG core, Java, C#, Windows, Cygwin) + Olly Betts (olly@survex.com) (PHP) + Joseph Wang (joequant@gmail.com) (R) + Xavier Delacour (xavier.delacour@gmail.com) (Octave) + David Nadlinger (code@klickverbot.at) (D) + +Past SWIG developers and major contributors include: + Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) + Henning Thielemann (swig@henning-thielemann.de) (Modula3) + Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile, MzScheme) + Luigi Ballabio (luigi.ballabio@fastwebnet.it) (STL wrapping) + Mikel Bancroft (mikel@franz.com) (Allegro CL) + Surendra Singhi (efuzzyone@netscape.net) (CLISP, CFFI) + Marcelo Matus (mmatus@acms.arizona.edu) (SWIG core, Python, UTL[python,perl,tcl,ruby]) + Art Yerkes (ayerkes@speakeasy.net) (Ocaml) + Lyle Johnson (lyle@users.sourceforge.net) (Ruby) + Charlie Savage (cfis@interserv.com) (Ruby) + Thien-Thi Nguyen (ttn@glug.org) (build/test/misc) + Richard Palmer (richard@magicality.org) (PHP) + Sam Liddicott - Ananova Ltd (saml@liddicott.com) (PHP) + Tim Hockin - Sun Microsystems (thockin@sun.com) (PHP) + Kevin Ruland (PHP) + Shibukawa Yoshiki (Japanese Translation) + Jason Stewart (jason@openinformatics.com) (Perl5) + Loic Dachary (Perl5) + David Fletcher (Perl5) + Gary Holt (Perl5) + Masaki Fukushima (Ruby) + Scott Michel (scottm@cs.ucla.edu) (Java directors) + Tiger Feng (songyanf@cs.uchicago.edu) (SWIG core) + Mark Rose (mrose@stm.lbl.gov) (Directors) + Jonah Beckford (beckford@usermail.com) (CHICKEN) + Ahmon Dancy (dancy@franz.com) (Allegro CL) + Dirk Gerrits (Allegro CL) + Neil Cawse (C#) + Harco de Hilster (Java) + Alexey Dyachenko (dyachenko@fromru.com) (Tcl) + Bob Techentin (Tcl) + Martin Froehlich (Guile) + Marcio Luis Teixeira (Guile) + Duncan Temple Lang (R) + Miklos Vajna (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, + 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. + diff --git a/Doc/Devel/cmdopt.html b/Doc/Devel/cmdopt.html index c5f207c03..5e90d2aba 100644 --- a/Doc/Devel/cmdopt.html +++ b/Doc/Devel/cmdopt.html @@ -36,7 +36,7 @@ functions to mark whether or not a particular command line option was used. Thi

      Argument Marking

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

      diff --git a/Doc/Devel/engineering.html b/Doc/Devel/engineering.html index 5ccfb7858..2e78fbe35 100644 --- a/Doc/Devel/engineering.html +++ b/Doc/Devel/engineering.html @@ -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.

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

       /* -----------------------------------------------------------------------------
      - * 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[] = "$Id$";
       
       #include "swig.h"
       
      diff --git a/Doc/Devel/index.html b/Doc/Devel/index.html
      index 55c612ec3..4ddc63a76 100644
      --- a/Doc/Devel/index.html
      +++ b/Doc/Devel/index.html
      @@ -21,6 +21,7 @@ The following documentation describe the internal APIs used by SWIG.  These may
       
    • Parameter and Parameter list handling functions
    • Generic C/C++ Scanner interface
    • Wrapper objects. +
    • SWIG Runtime.

    diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html index ea36f844d..d24869d10 100644 --- a/Doc/Devel/internals.html +++ b/Doc/Devel/internals.html @@ -7,11 +7,6 @@

    SWIG Internals Manual

    -Thien-Thi Nguyen
    - -

    -David M. Beazley
    -

    @@ -42,11 +37,12 @@ David M. Beazley
  • 3. Types and Typemaps
  • 4. Parsing -
  • 5. Difference Between SWIG 1.1 and SWIG 1.3 -
  • 6. Plans for SWIG 2.0 -
  • 7. C/C++ Wrapper Support Functions -
  • 8. Symbol Naming Guidelines for Generated C/C++ Code -
  • 9. Debugging SWIG +
  • 5. C/C++ Wrapper Support Functions +
  • 6. Symbol Naming Guidelines for Generated C/C++ Code +
  • 7. Debugging SWIG + @@ -76,9 +72,8 @@ to code). Examples 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.] @@ -97,55 +92,35 @@ info. Source -SWIG source code is in this subdir tree. Directories marked w/ "(*)" -are used in building the swig executable. +The C and C++ source code for the swig executable is in this +subdir tree. - + + containers. - - - - - + - - + + - - - - + language has a .cxx and a .h file). - - + + - - - - - - - - - - + @@ -154,7 +129,7 @@ are used in building the swig executable. - + @@ -173,14 +148,14 @@ to look for code:
      -
    • Modules1.1/swigmain.cxx:main() is the program entry +
    • Modules/swigmain.cxx:main() is the program entry point. It parses the language-specifying command-line option (for example, -java), creating a new language-specific wrapping object (each language is a C++ class derived from base class Language). This object and the command-line is passed to SWIG_main(), whose return value is the program exit value. -
    • SWIG1.1/main.cxx:SWIG_main() is the "real" main. It +
    • Modules/main.cxx:SWIG_main() 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 -freeze, go into an infinite loop; otherwise return the error count.
    • The language-specific parse() (and all other -language-specific code) lives in Modules1.1/foo.{h,cxx} for +language-specific code) lives in Modules/foo.{h,cxx} for language Foo. Typically, FOO::parse() calls FOO::headers() and then the global function yyparse(), which uses the callbacks registered by SWIG_main() 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.
      • SwigType_str(SwigType *t, char *name).
        @@ -710,19 +684,7 @@ repeated calls without making any copies. [TODO] -

        5. Difference Between SWIG 1.1 and SWIG 1.3

        -
        - -[TODO] - - -

        6. Plans for SWIG 2.0

        -
        - -[TODO] - - -

        7. The C/C++ Wrapping Layer

        +

        5. The C/C++ Wrapping Layer

        Added: Dave Beazley (July 22, 2000) @@ -1001,8 +963,8 @@ for specifying local variable declarations and argument conversions. - -

        8. Symbol Naming Guidelines for Generated C/C++ Code

        +
        +

        6. Symbol Naming Guidelines for Generated C/C++ Code

        The C++ standard (ISO/IEC 14882:1998(E)) states:
        @@ -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. - -

        9. Debugging SWIG

        +
        +

        7. Debugging SWIG

        -Warning. Debugging SWIG is for the very patient. + +

        +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 SWIG Parse Tree Handling 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. +

        + +

        +The SWIG distribution comes with some additional support for the gdb debugger in the Tools/swig.gdb 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 swigprint and locswigprint user-defined commands are demonstrated below. +

        + +

        +More often than not, a parse tree node needs to be examined. +The session below displays the node n in one of the Java language module wrapper functions. +The swigprint method is used to show the symbol name (symname - a DOH String type) and the node (n - a DOH Hash type). +

        +
        +
        +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' : <Object 'VoidObj' at 0xb7cfa008>, 
        +  'sym:name' : Shape_x_set, 
        +  'view' : membervariableHandler, 
        +  'membervariableHandler:sym:name' : x, 
        +  'membervariableHandler:type' : double, 
        +  'membervariableHandler:parms' : <Object 'VoidObj' at 0xb7cfa008>, 
        +  'parentNode' : Hash(0xb7d2abc8) {..............................}, 
        +  'feature:java:enum' : typesafe, 
        +  'access' : public, 
        +  'parms' : Hash(0xb7cb9408) {......}, 
        +  'wrap:action' : if (arg1) (arg1)->x = arg2;, 
        +  'type' : void, 
        +  'memberset' : 1, 
        +  'sym:overname' : __SWIG_0, 
        +  'membervariableHandler:name' : x, 
        +}
        +
        +
        + +

        +Note that all the attributes in the Hash are shown, including the 'sym:name' attribute which was assigned to the symname variable. +

        + +

        +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 swigprint to expand to two Hash levels in order to view the contents of the collapsed 'nextSibling' Hash. +

        + +
        +
        +(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, 
        +}
        +
        +
        + +

        +The same Hash can also be displayed with file and line location information via the locswigprint command. +

        + +
        +
        +(gdb) locswigprint 0xb7cb9408
        +example.h:11: [Hash(0xb7cb9408) {
        +Hash(0xb7cb9408) {
        +  'name' : self, 
        +  'type' : p.Shape, 
        +  'self' : 1, 
        +  'nextSibling' : Hash(0xb7cb9498) {...}, 
        +  'hidden' : 1, 
        +  'nodeType' : parm, 
        +}]
        +
        +
        + +

        +Tip: Commands in gdb can be shortened with whatever makes them unique and can be command completed with the tab key. +Thus swigprint can usually be shortened to sw and locswigprint to loc. +The help for each command can also be obtained within the debugging session, for example, 'help swigprint'. +

        + +

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

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

        7.1 Debugging DOH Types The Hard Way

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

        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

      • String *s;
      • -
        -(String *)((DohBase *)s)->data +(struct String *)((DohBase *)s)->data
        The underlying char * string can be displayed with
        -((String *)((DohBase *)s)->data)->str +(*(struct String *)(((DohBase *)s)->data)).str

      • SwigType *t;
      • -
        -(String *)((DohBase *)t)->data +(struct String *)((DohBase *)t)->data
        The underlying char * string can be displayed with
        -((String *)((DohBase *)t)->data)->str +(*(struct String *)(((DohBase *)t)->data)).str

        -

      • String_or_char *sc;
      • +
      • const_String_or_char_ptr sc;
      • Either
        -((String *)((DohBase *)sc)->data)->str +(*(struct String *)(((DohBase *)sc)->data)).str
        or
        -(char *)sc +(char *)sc
        will work depending on whether the underlying type is really a String * or char *.

      -Copyright (C) 1999-2004 SWIG Development Team. +Copyright (C) 1999-2010 SWIG Development Team. diff --git a/Doc/Devel/scanner.html b/Doc/Devel/scanner.html index 272216475..65ef1d8e9 100644 --- a/Doc/Devel/scanner.html +++ b/Doc/Devel/scanner.html @@ -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 Scanner_token(). tokvalue is the integer token value to return and val 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.

      @@ -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. - - - - - diff --git a/Doc/Devel/tree.html b/Doc/Devel/tree.html index 64d9d197d..db3c6fee4 100644 --- a/Doc/Devel/tree.html +++ b/Doc/Devel/tree.html @@ -6,13 +6,6 @@

      SWIG Parse Tree Handling

      - -

      -David M. Beazley
      -dave-swig@dabeaz.com
      -December, 2006
      - -

      Introduction

      @@ -210,7 +203,33 @@ This function restores a node to the state it was in prior to the last Swig_

      Debugging Functions

      -The following functions are used to help debug SWIG parse trees. +

      +The following functions can be used to help debug any SWIG DOH object. +

      + +void Swig_print(DOH *object, int count = -1) + +
      +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<0). See Swig_set_max_hash_expand() to change default. +
      +
      +
      + +void Swig_print_with_location(DOH *object, int count = -1) + +
      +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<0). See Swig_set_max_hash_expand() to change default. +
      +
      +
      + + +

      +The following functions can be used to help debug SWIG parse trees. +

      void Swig_print_tags(Node *node, String_or_char *prefix) @@ -218,10 +237,10 @@ The following functions are used to help debug SWIG parse trees.

      Prints the tag-structure of the parse tree to standard output. node is the top-level parse tree node. prefix is a string prefix thats added to the start of each line. Normally, you would specify the empty string or NIL for prefix. -This function is called by the -dump_tags option to SWIG. +This function is called by the -debug-tags option to SWIG.
      -% 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,
       
       
      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 -dump_tree produces output generated by this function. +and other details.

      @@ -251,8 +270,8 @@ and other details. The command line option -dump_tree produces output

      Prints the same output as Swig_print_node() except that it also processes all of the siblings of node. This can -be used to dump the entire parse tree to standard output. Use the command line option -dump_tree 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 -debug-module +and -debug-top use this function to display the parse tree for a SWIG input file.
      diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html old mode 100755 new mode 100644 index 8981f52b5..5d00c4cd0 --- a/Doc/Manual/Allegrocl.html +++ b/Doc/Manual/Allegrocl.html @@ -8,13 +8,13 @@ -

      16 SWIG and Allegro Common Lisp

      +

      17 SWIG and Allegro Common Lisp

      • Basics @@ -135,10 +135,10 @@ be unhappy to see some enterprising folk use this work to add to it.

        -

        16.1 Basics

        +

        17.1 Basics

        -

        16.1.1 Running Swig

        +

        17.1.1 Running SWIG

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

        -

        16.1.2 Command Line Options

        +

        17.1.2 Command Line Options

        @@ -396,7 +396,7 @@ See Section 17.5 Identifier converter functions for more details.

        -

        16.1.3 Inserting user code into generated files

        +

        17.1.3 Inserting user code into generated files

        @@ -411,7 +411,7 @@ using the SWIG %insert(section) %{ ...code... %} directive:

         %module example
         
        -%insert("runtime") %{
        +%{
         #include "header.h"
         %}
         
        @@ -432,11 +432,11 @@ generated lisp interface file
         

      Note that the block %{ ... %} is effectively a shortcut for -%insert("runtime") %{ ... %}. +%insert("header") %{ ... %}.

      -

      16.2 Wrapping Overview

      +

      17.2 Wrapping Overview

      @@ -446,7 +446,7 @@ New users to SWIG are encouraged to read interested in generating an interface to C++.

      -

      16.2.1 Function Wrapping

      +

      17.2.1 Function Wrapping

      @@ -499,7 +499,7 @@ interested in generating an interface to C++.

      -

      16.2.2 Foreign Wrappers

      +

      17.2.2 Foreign Wrappers

      @@ -512,7 +512,7 @@ interested in generating an interface to C++. typemap.

      -

      16.2.3 FFI Wrappers

      +

      17.2.3 FFI Wrappers

      @@ -593,7 +593,7 @@ char *xxx(); ff:def-foreign-call's.

      -

      16.2.4 Non-overloaded Defuns

      +

      17.2.4 Non-overloaded Defuns

      @@ -606,7 +606,7 @@ char *xxx(); this function can be manipulated via the lout typemap.

      -

      16.2.5 Overloaded Defuns

      +

      17.2.5 Overloaded Defuns

      @@ -622,7 +622,7 @@ char *xxx(); can be manipulated via the lout typemap.

      -

      16.2.6 What about constant and variable access?

      +

      17.2.6 What about constant and variable access?

      @@ -635,7 +635,7 @@ char *xxx(); into the foreign module.

      -

      16.2.7 Object Wrapping

      +

      17.2.7 Object Wrapping

      @@ -657,7 +657,7 @@ char *xxx(); foreign function interface.

      -

      16.3 Wrapping Details

      +

      17.3 Wrapping Details

      @@ -665,7 +665,7 @@ char *xxx(); translated into lisp.

      -

      16.3.1 Namespaces

      +

      17.3.1 Namespaces

      @@ -742,7 +742,7 @@ namespace car { function such as (car '(1 2 3).

      -

      16.3.2 Constants

      +

      17.3.2 Constants

      @@ -803,7 +803,7 @@ namespace car { not use the -nocwrap command-line option.

      -

      16.3.3 Variables

      +

      17.3.3 Variables

      @@ -881,7 +881,7 @@ globalvar> (globalvar.nnn::glob_float) -

      16.3.4 Enumerations

      +

      17.3.4 Enumerations

      @@ -957,7 +957,7 @@ EXPORT const int ACL_ENUM___FOO3__SWIG_0 = FOO3; -

      16.3.5 Arrays

      +

      17.3.5 Arrays

      @@ -1105,10 +1105,10 @@ namespace BAR { -

      16.3.6 Classes and Structs and Unions (oh my!)

      +

      17.3.6 Classes and Structs and Unions (oh my!)

      -

      16.3.6.1 CLOS wrapping of

      +

      17.3.6.1 CLOS wrapping of

      @@ -1123,7 +1123,7 @@ namespace BAR { integer values.

      -

      16.3.6.2 CLOS Inheritance

      +

      17.3.6.2 CLOS Inheritance

      @@ -1136,7 +1136,7 @@ namespace BAR { parameter.

      -

      16.3.6.3 Member fields and functions

      +

      17.3.6.3 Member fields and functions

      @@ -1152,7 +1152,7 @@ namespace BAR { the interface does nothing for friend directives,

      -

      16.3.6.4 Why not directly access C++ classes using foreign types?

      +

      17.3.6.4 Why not directly access C++ classes using foreign types?

      @@ -1170,11 +1170,11 @@ namespace BAR { use the more robust wrapper functions.

      -

      16.3.7 Templates

      +

      17.3.7 Templates

      -

      16.3.7.1 Generating wrapper code for templates

      +

      17.3.7.1 Generating wrapper code for templates

      @@ -1187,7 +1187,7 @@ namespace BAR { directive.

      -

      16.3.7.2 Implicit Template instantiation

      +

      17.3.7.2 Implicit Template instantiation

      @@ -1197,7 +1197,7 @@ namespace BAR { class schema.

      -

      16.3.8 Typedef, Templates, and Synonym Types

      +

      17.3.8 Typedef, Templates, and Synonym Types

      @@ -1277,7 +1277,7 @@ synonym> -

      16.3.8.1 Choosing a primary type

      +

      17.3.8.1 Choosing a primary type

      @@ -1298,7 +1298,7 @@ synonym>

    -

    16.3.9 Function overloading/Parameter defaulting

    +

    17.3.9 Function overloading/Parameter defaulting

    @@ -1461,7 +1461,7 @@ overload> -

    16.3.10 Operator wrapping and Operator overloading

    +

    17.3.10 Operator wrapping and Operator overloading

    @@ -1607,7 +1607,7 @@ opoverload> -

    16.3.11 Varargs

    +

    17.3.11 Varargs

    @@ -1628,7 +1628,7 @@ opoverload> with other ways such functions can be wrapped.

    -

    16.3.12 C++ Exceptions

    +

    17.3.12 C++ Exceptions

    @@ -1640,7 +1640,7 @@ opoverload> implemented.

    -

    16.3.13 Pass by value, pass by reference

    +

    17.3.13 Pass by value, pass by reference

    @@ -1652,7 +1652,7 @@ opoverload> newly defined types.

    -

    16.4 Typemaps

    +

    17.4 Typemaps

    @@ -1663,7 +1663,7 @@ opoverload> on Typemaps for more information.

    -

    16.4.1 Code Generation in the C++ Wrapper

    +

    17.4.1 Code Generation in the C++ Wrapper

    @@ -1693,7 +1693,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.1.1 IN Typemap

    +

    17.4.1.1 IN Typemap

    @@ -1728,7 +1728,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.1.2 OUT Typemap

    +

    17.4.1.2 OUT Typemap

    @@ -1752,7 +1752,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.1.3 CTYPE Typemap

    +

    17.4.1.3 CTYPE Typemap

    @@ -1777,14 +1777,14 @@ return-val wrapper-name(parm0, parm1, ..., parmN)

    - 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 common typemaps here.

    -

    16.4.2 Code generation in Lisp wrappers

    +

    17.4.2 Code generation in Lisp wrappers

    @@ -1803,7 +1803,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) 16.3.1 Namespaces for details.

    -

    16.4.2.1 LIN Typemap

    +

    17.4.2.1 LIN Typemap

    @@ -1846,7 +1846,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.2.2 LOUT Typemap

    +

    17.4.2.2 LOUT Typemap

    @@ -1889,7 +1889,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.2.3 FFITYPE Typemap

    +

    17.4.2.3 FFITYPE Typemap

    @@ -1939,7 +1939,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.2.4 LISPTYPE Typemap

    +

    17.4.2.4 LISPTYPE Typemap

    @@ -1959,7 +1959,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.2.5 LISPCLASS Typemap

    +

    17.4.2.5 LISPCLASS Typemap

    @@ -1983,7 +1983,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.4.3 Modifying SWIG behavior using typemaps

    +

    17.4.3 Modifying SWIG behavior using typemaps

    @@ -2017,10 +2017,10 @@ return-val wrapper-name(parm0, parm1, ..., parmN) -

    16.5 Identifier Converter functions

    +

    17.5 Identifier Converter functions

    -

    16.5.1 Creating symbols in the lisp environment

    +

    17.5.1 Creating symbols in the lisp environment

    @@ -2041,11 +2041,11 @@ return-val wrapper-name(parm0, parm1, ..., parmN) of arguments.

    -

    16.5.2 Existing identifier-converter functions

    +

    17.5.2 Existing identifier-converter functions

    Two basic identifier routines have been defined. -

    16.5.2.1 identifier-convert-null

    +

    17.5.2.1 identifier-convert-null

    @@ -2054,7 +2054,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) strings, from which a symbol will be created.

    -

    16.5.2.2 identifier-convert-lispify

    +

    17.5.2.2 identifier-convert-lispify

    @@ -2063,7 +2063,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) same symbol transformations.

    -

    16.5.2.3 Default identifier to symbol conversions

    +

    17.5.2.3 Default identifier to symbol conversions

    @@ -2072,7 +2072,7 @@ return-val wrapper-name(parm0, parm1, ..., parmN) default naming conventions.

    -

    16.5.3 Defining your own identifier-converter

    +

    17.5.3 Defining your own identifier-converter

    @@ -2128,7 +2128,7 @@ indicating the number of arguments passed to the routine indicated by this identifier.

    -

    16.5.4 Instructing SWIG to use a particular identifier-converter

    +

    17.5.4 Instructing SWIG to use a particular identifier-converter

    diff --git a/Doc/Manual/Android.html b/Doc/Manual/Android.html new file mode 100644 index 000000000..443d77691 --- /dev/null +++ b/Doc/Manual/Android.html @@ -0,0 +1,749 @@ + + + +SWIG and Android + + + +

    18 SWIG and Android

    + + + + + + +

    +This chapter describes SWIG's support of Android. +

    + + + +

    18.1 Overview

    + + +

    +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 Java chapter applies to generating code for access from Android Java code. +This chapter contains a few Android specific notes and examples. +

    + +

    18.2 Android examples

    + + +

    18.2.1 Examples introduction

    + + +

    +The examples require the the Android SDK and Android NDK 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): +

    + +
    +
    +$ 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
    +
    +
    + +

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

    + +
    +
    +$ android list targets
    +
    +
    + +

    +The following examples are shipped with SWIG under the Examples/android directory and include a Makefile to build and install each example. +

    + +

    18.2.2 Simple C example

    + + +

    +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 SwigSimple in a subdirectory called simple using the commands below. +Adjust the --target id as mentioned earlier in the Examples introduction. +Managing Projects from the Command Line on the Android developer's site is a useful reference for these steps. +

    + +
    +
    +$ android create project --target 1 --name SwigSimple --path ./simple --activity SwigSimple --package org.swig.simple
    +$ cd simple
    +$ ant debug
    +
    +
    + +

    +Modify src/org/swig/simple/SwigSimple.java from the default to: +

    + +
    +
    +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
    +    }
    +}
    +
    +
    + +

    +The above simply adds a Run button and scrollable text view as the GUI aspects of the program. +The associated resources need to be created, modify res/layout/main.xml as follows: +

    + +
    +
    +<?xml version="1.0" encoding="utf-8"?>
    +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    +    android:orientation="vertical"
    +    android:layout_width="fill_parent"
    +    android:layout_height="fill_parent"
    +    >
    +<Button
    +    android:id="@+id/RunButton"  
    +    android:layout_width="wrap_content"  
    +    android:layout_height="wrap_content"  
    +    android:text="Run..."  
    +    android:onClick="onRunButtonClick"
    +    />
    +<ScrollView
    +    android:id="@+id/Scroller"
    +    android:layout_width="fill_parent"
    +    android:layout_height="fill_parent"
    +    >
    +<TextView
    +    android:id="@+id/OutputText"
    +    android:layout_width="wrap_content"
    +    android:layout_height="wrap_content"
    +    />
    +</ScrollView>
    +</LinearLayout>
    +
    +
    + +

    +Rebuild the project with your changes: +

    + +
    +
    +$ ant debug
    +
    +
    + +

    +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 Using hardware devices on the Android developer's site. +When complete your device should be listed in those attached, something like: +

    + +
    +
    +$ adb devices
    +List of devices attached 
    +A32-6DBE0001-9FF80000-015D62C3-02018028	device
    +
    +
    + +

    +This means you are now ready to install the application... +

    + +
    +
    +$ adb install bin/SwigSimple-debug.apk 
    +95 KB/s (4834 bytes in 0.049s)
    +	pkg: /data/local/tmp/SwigSimple-debug.apk
    +Success
    +
    +
    + +

    +The newly installed 'SwigSimple' app will be amongst all your other applications on the home screen. Run the app and it will show a Run button text box below it. +Press the Run button to see the simple text output. +

    + +

    +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: +

    + +
    +
    +$ adb uninstall org.swig.simple
    +Success
    +
    +
    + +

    +Now that you have a pure Java Android app working, let's add some JNI code generated from SWIG. +

    + +

    +First create a jni subdirectory and then create some C source code in jni/example.c: +

    + +
    +
    +/* 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 > 0) {
    +    g = x;
    +    x = y % x;
    +    y = g;
    +  }
    +  return g;
    +}
    +
    +
    + +

    +Create a SWIG interface file for this C code, jni/example.i: +

    + +
    +
    +/* File : example.i */
    +%module example
    +
    +%inline %{
    +extern int    gcd(int x, int y);
    +extern double Foo;
    +%}
    +
    +
    + +

    +Invoke SWIG as follows: +

    + +
    +
    +$ swig -java -package org.swig.simple -outdir src/org/swig/simple -o jni/example_wrap.c jni/example.i
    +
    +
    + +

    +SWIG generates the following files: +

    +
      +
    • src/org/swig/simple/exampleJNI.java
    • +
    • src/org/swig/simple/example.java
    • +
    • jni/example_wrap.c
    • +
    + +

    +Next we need to create a standard Android NDK build system file jni/Android.mk: +

    + +
    +
    +# 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)
    +
    +
    + +

    +See the Android NDK documentation 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: +

    + +
    +
    +$ ndk-build
    +Compile thumb  : example <= example_wrap.c
    +Compile thumb  : example <= example.c
    +SharedLibrary  : libexample.so
    +Install        : libexample.so => libs/armeabi/libexample.so
    +
    +
    + +

    +Now that the C JNI layer has been built, we can write Java code to call into the this layer. +Modify the nativeCall method in src/org/swig/simple/SwigSimple.java to call the JNI code as follows and add the static constructor to load the system library containing the compiled JNI C code: +

    + +
    +
    +    /** 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");
    +    }
    +
    +
    + +

    +Compile the Java code as usual, uninstall the old version of the app if still installed and re-install the new app: +

    + +
    +
    +$ ant debug
    +$ adb uninstall org.swig.simple
    +$ adb install bin/SwigSimple-debug.apk 
    +
    +
    + +

    +Run the app again and this time you will see the output pictured below, showing the result of calls into the C code: +

    + +
    Android screenshot of SwigSimple example
    + + +

    18.2.3 C++ class example

    + + +

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

    + +

    +First create an Android project called SwigClass in a subdirectory called class. +The steps below create and build a the JNI C++ app. +Adjust the --target id as mentioned earlier in the Examples introduction. +

    + +
    +
    +$ android create project --target 1 --name SwigClass --path ./class --activity SwigClass --package org.swig.classexample
    +$ cd class
    +
    +
    + +

    +Now create a jni subdirectory and then create a C++ header file jni/example.h which defines our +hierarchy of shape classes: +

    + +
    +
    +/* 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);
    +};
    +
    +
    + +

    +and create the implementation in the jni/example.cpp file: +

    + +
    +
    +/* 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;
    +}
    +
    +
    + +

    +Create a SWIG interface file for this C++ code in jni/example.i: +

    + +
    +
    +/* File : example.i */
    +%module example
    +
    +%{
    +#include "example.h"
    +%}
    +
    +/* Let's just grab the original header file here */
    +%include "example.h"
    +
    +
    + +

    +Invoke SWIG as follows, note that the -c++ option is required for C++ code: +

    + +
    +
    +$ swig -c++ -java -package org.swig.classexample -outdir src/org/swig/classexample -o jni/example_wrap.cpp jni/example.i
    +
    +
    + +

    +SWIG generates the following files: +

    +
      +
    • src/org/swig/classexample/Square.java
    • +
    • src/org/swig/classexample/exampleJNI.java
    • +
    • src/org/swig/classexample/example.java
    • +
    • src/org/swig/classexample/Circle.java
    • +
    • src/org/swig/classexample/Shape.java
    • +
    • jni/example_wrap.cpp
    • +
    + +

    +Next we need to create an Android NDK build system file for compiling the C++ code jni/Android.mk. +The -frtti compiler flag isn't strictly needed for this example, but is needed for any code that uses C++ RTTI: +

    + +
    +
    +# 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)
    +
    +
    + + +

    +A simple invocation of ndk-build will compile the .cpp files and generate a shared object/system library. Output will be similar to: +

    + +
    +
    +$ ndk-build
    +Compile++ thumb  : example <= example_wrap.cpp
    +Compile++ thumb  : example <= example.cpp
    +StaticLibrary  : libstdc++.a
    +SharedLibrary  : libexample.so
    +Install        : libexample.so => libs/armeabi/libexample.so
    +
    +
    + +

    +Now that the C JNI layer has been built, we can write Java code to call into this layer. +Modify src/org/swig/classexample/SwigClass.java from the default to: +

    + +
    +
    +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<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");
    +    }
    +}
    +
    +
    + +

    +Note the static constructor and the interesting JNI code is in the nativeCall method. +The remaining code deals with the GUI aspects which are identical to the previous C simple example. Modify res/layout/main.xml to contain the xml for the 'Run' button and scrollable text view: +

    + +
    +
    +<?xml version="1.0" encoding="utf-8"?>
    +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    +    android:orientation="vertical"
    +    android:layout_width="fill_parent"
    +    android:layout_height="fill_parent"
    +    >
    +<Button
    +    android:id="@+id/RunButton"  
    +    android:layout_width="wrap_content"  
    +    android:layout_height="wrap_content"  
    +    android:text="Run..."  
    +    android:onClick="onRunButtonClick"
    +    />
    +<ScrollView
    +    android:id="@+id/Scroller"
    +    android:layout_width="fill_parent"
    +    android:layout_height="fill_parent"
    +    >
    +<TextView
    +    android:id="@+id/OutputText"
    +    android:layout_width="wrap_content"
    +    android:layout_height="wrap_content"
    +    />
    +</ScrollView>
    +</LinearLayout>
    +
    +
    + + +

    +Compile the Java code as usual, uninstall the old version of the app if installed and re-install the new app: +

    + +
    +
    +$ ant debug
    +$ adb uninstall org.swig.classexample
    +$ adb install bin/SwigClass-debug.apk 
    +
    +
    + +

    +Run the app to see the result of calling the C++ code from Java: +

    + +
    Android screenshot of SwigClass example
    + + + + diff --git a/Doc/Manual/Arguments.html b/Doc/Manual/Arguments.html index af8780452..1ae9a6d2f 100644 --- a/Doc/Manual/Arguments.html +++ b/Doc/Manual/Arguments.html @@ -30,8 +30,6 @@ -Disclaimer: This chapter is under construction. -

    In Chapter 3, SWIG's treatment of basic datatypes and pointers was described. In particular, primitive types such as int 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); %} @@ -351,7 +349,7 @@ function like this in an interface file :

     %module example
    -%include typemaps.i
    +%include "typemaps.i"
     ...
     %{
     extern void negate(double *);
    diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
    index 97cb75409..b511dc126 100644
    --- a/Doc/Manual/CSharp.html
    +++ b/Doc/Manual/CSharp.html
    @@ -5,33 +5,42 @@
     
     
     
    -

    17 SWIG and C#

    +

    19 SWIG and C#

    @@ -39,7 +48,7 @@ -

    17.1 Introduction

    +

    19.1 Introduction

    @@ -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 -Mixed DLL Loading Problem. -Swig C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using -Mono and Portable.NET. +Mixed DLL Loading Problem. +SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using +Mono and Portable.NET.

    @@ -59,7 +68,7 @@ The Microsoft Developer Network (MSDN) h Monodoc, available from the Mono project, has a very useful section titled Interop with native libraries.

    -

    17.2 Differences to the Java module

    +

    19.2 Differences to the Java module

    @@ -93,6 +102,12 @@ namespace com.bloggs.widget { ... }

    +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. + + +
  • +The nspace feature 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 nspace feature, the -namespace option is not mandatory for C#.
  • @@ -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 %javaexception. -In fact, throwing C# exceptions works quite differently, see C# Exceptions> below. +In fact, throwing C# exceptions works quite differently, see C# Exceptions below.
  • @@ -156,6 +171,14 @@ javadestruct_derived -> csdestruct_derived
  • +
  • +

    Typemap macros:

    +
    +SWIG_JAVABODY_PROXY         -> SWIG_CSBODY_PROXY
    +SWIG_JAVABODY_TYPEWRAPPER   -> SWIG_CSBODY_TYPEWRAPPER
    +
    +
  • +
  • Additional typemaps:

    @@ -194,6 +217,7 @@ jniclassinterfaces -> imclassinterfaces $javaclassname -> $csclassname $&javaclassname -> $&csclassname $*javaclassname -> $*csclassname +$javaclazzname -> $csclazzname $javainput -> $csinput $jnicall -> $imcall @@ -201,7 +225,12 @@ $jnicall -> $imcall
  • -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 constructor helper function 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 Date marshalling example and Date marshalling of properties example 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 constructor helper function 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# using or fixed block is started. +Note that 'pre', 'post', 'terminator' and 'cshin' attributes are not used for marshalling the property set. +Please see the Date marshalling example and Date marshalling of properties example for further understanding of these "csin" applicable attributes.

  • @@ -237,7 +266,9 @@ public static extern IntPtr function(string jarg1);

    Support for type attributes. The 'imtype' and 'cstype' typemaps can have an optional inattributes and outattributes typemap attribute. -There are C# attributes and typemap attributes, don't get confused!! +The 'imtype' typemap can also have an optional directorinattributes and directoroutattributes +typemap attribute which attaches to director delegates, an implementation detail of directors, see directors implementation. +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# MarshalAs 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.

    + +

    +The directorinattributes and directoroutattributes typemap attribute are attached to the delegates in the director class, for example, the SwigDelegateBase_0 +

    +
  • -Support for attaching C# attributes to wrapped methods and variables. -This is done using the %csattributes feature, see %feature directives. +Support for attaching C# attributes to wrapped methods, variables and enum values. +This is done using the %csattributes feature, see %feature directives. Note that C# attributes are attached to proxy classes and enums using the csattributes typemap. For example, imagine we have a custom attribute class, ThreadSafeAttribute, 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.

    + +

    +An example for attaching attributes to the enum and enum values is shown below. +

    + +
    +
    +%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 };
    +%}
    +
    +
    + +

    +which will result in the following C# enum: +

    + +
    +
    +[System.ComponentModel.Description("Colours")]
    +public enum Couleur {
    +  [System.ComponentModel.Description("Red")]
    +  Rouge,
    +  Orange,
    +  [System.ComponentModel.Description("Green")]
    +  Vert
    +}
    +
    +
  • @@ -350,7 +418,7 @@ This feature is useful for some obscure cases where SWIG might get the virtu
  • - +

    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 imclassname is used to achieve this: @@ -385,7 +453,7 @@ if specified, otherwise it is equivalent to the $module special variable.

    $imclassname
    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 %module directive. +unless the imclassname attribute is specified in the %module directive.

    @@ -397,7 +465,296 @@ Windows users can also get the examples working using a Cygwin or MinGW 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. -

    17.3 C# Exceptions

    +

    19.3 Void pointers

    + + +

    +By default SWIG treats void * as any other pointer and hence marshalls it as a type wrapper class called SWIGTYPE_p_void. +If you want to marshall with the .NET System.IntPtr type instead, there is a simple set of named typemaps called +void *VOID_INT_PTR that can be used. +They can be applied like any other named typemaps: +

    + + +
    +
    +%apply void *VOID_INT_PTR { void * }
    +void * f(void *v);
    +
    +
    + +

    19.4 C# Arrays

    + + +

    +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 SWIGTYPE_p_int when wrapping the C type int [] or int *. +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. +

    + +

    19.4.1 The SWIG C arrays library

    + + +

    +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 carrays.i library section. +Please refer to this section for details, but for convenience, the C# usage for the two examples outlined there is shown below. +

    + +

    +For the %array_functions example, the equivalent usage would be: +

    + +
    +
    +SWIGTYPE_p_double a = example.new_doubleArray(10);  // Create an array
    +for (int i=0; i<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
    +
    +
    + +

    +and for the %array_class example, the equivalent usage would be: +

    + +
    +
    +doubleArray c = new doubleArray(10);    // Create double[10]
    +for (int i=0; i<10; i++)
    +  c.setitem(i, 2*i);                    // Assign values
    +example.print_array(c.cast());          // Pass to C
    +
    +
    + + +

    19.4.2 Managed arrays using P/Invoke default array marshalling

    + + +

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

    + +

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

    + +

    +For more information on the subject, see the +Default Marshaling for Arrays article +on MSDN. +

    + + +

    +The P/Invoke default marshalling is supported by the arrays_csharp.i library via the INPUT, OUTPUT and INOUT typemaps. +Let's look at some example usage. Consider the following C function: +

    +
    +
    +void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
    +
    +
    + +

    +We can now instruct SWIG to use the default marshalling typemaps by +

    + +
    +
    +%include "arrays_csharp.i"
    +
    +%apply int INPUT[]  {int *sourceArray}
    +%apply int OUTPUT[] {int *targetArray}
    +
    +
    + +

    +As a result, we get the following method in the module class: +

    + +
    +
    +public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
    +    examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
    +}
    +
    +
    + +

    +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: +

    + +
    +
    +[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
    +public static extern void myArrayCopy([In, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, 
    +                                      [Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2,
    +                                       int jarg3);
    +
    +
    + +

    +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: +

    + +
    +
    +void myArraySwap(int *array1, int *array2, int nitems);
    +
    +
    + +

    +Now, we can instruct SWIG to wrap this by +

    + +
    +
    +%include "arrays_csharp.i"
    +
    +%apply int INOUT[] {int *array1}
    +%apply int INOUT[] {int *array2}
    +
    +
    + +

    +This results in the module class method +

    + +
    +
    +  public static void myArraySwap(int[] array1, int[] array2, int nitems) {
    +    examplePINVOKE.myArraySwap(array1, array2, nitems);
    +  }
    +
    +
    + +

    +and intermediary class method +

    + +
    +
    +  [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);
    +
    +
    + + +

    19.4.3 Managed arrays using pinning

    + + +

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

    + +

    +For more information, see the fixed statement in the C# language reference. +

    + + +

    +Now let's look at an example using pinning, thus avoiding the CLR making copies +of the arrays passed as parameters. The arrays_csharp.i library file again provides the required support via the FIXED typemaps. +Let's use the same function from the previous section: +

    + +
    +
    +void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
    +
    +
    + +

    +We now need to declare the module class method unsafe, as we are using pointers: +

    + +
    +
    +%csmethodmodifiers myArrayCopy "public unsafe";
    + 
    +
    + +

    +Apply the appropriate typemaps to the array parameters: +

    + +
    +
    +%include "arrays_csharp.i"
    +
    +%apply int FIXED[] {int *sourceArray}
    +%apply int FIXED[] {int *targetArray}
    +
    +
    + +

    +Notice that there is no need for separate in, out or inout typemaps as is the +case when using P/Invoke default marshalling. +

    + +

    +As a result, we get the following method in the module class: +

    + +
    +
    +  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);
    +    }
    +    }
    +    }
    +  }
    +
    +
    + +

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

    + +

    +Also the intermediary class method looks a little different from the default marshalling +example - the method is expecting an IntPtr as the parameter type. +

    + +
    +
    +[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
    +public static extern void myArrayCopy(IntPtr jarg1, IntPtr jarg2, int jarg3);
    +
    +
    + + + +

    19.5 C# Exceptions

    @@ -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 Exception specifications. -The Exception handling with %exception section details the %exception feature. +The Exception handling with %exception section details the %exception 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.

    @@ -494,7 +851,7 @@ set so should only be used when a C# exception is not created.

    -

    17.3.1 C# exception example using "check" typemap

    +

    19.5.1 C# exception example using "check" typemap

    @@ -668,7 +1025,7 @@ without setting the canthrow attribute you will get a warning message s

    -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.
     
    @@ -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 SWIG_CSharpSetPendingException.

    -

    17.3.2 C# exception example using %exception

    +

    19.5.2 C# exception example using %exception

    Let's consider a similar, but more common example that throws a C++ exception from within a wrapped function. -We can use %exception as mentioned in Exception handling with %exception. +We can use %exception as mentioned in Exception handling with %exception.

    @@ -741,7 +1098,7 @@ The managed code generated does check for the pending exception as mentioned ear
    -

    17.3.3 C# exception example using exception specifications

    +

    19.5.3 C# exception example using exception specifications

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

    -

    17.3.4 Custom C# ApplicationException example

    +

    19.5.4 Custom C# ApplicationException example

    @@ -932,7 +1289,7 @@ try { -

    17.4 C# Directors

    +

    19.6 C# Directors

    @@ -942,10 +1299,10 @@ Essentially, it enables unmanaged C++ code to call back into managed code for vi

    The following sections provide information on the C# director implementation and contain most of the information required to use the C# directors. -However, the Java directors section should also be read in order to gain more insight into directors. +However, the Java directors section should also be read in order to gain more insight into directors.

    -

    17.4.1 Directors example

    +

    19.6.1 Directors example

    @@ -1066,7 +1423,7 @@ CSharpDerived - UIntMethod(123) -

    17.4.2 Directors implementation

    +

    19.6.2 Directors implementation

    @@ -1252,7 +1609,7 @@ void SwigDirector_Base::BaseBoolMethod(Base const &b, bool flag) { -

    17.4.3 Director caveats

    +

    19.6.3 Director caveats

    @@ -1300,7 +1657,42 @@ However, a call from C# to CSharpDefaults.DefaultMethod() will of cours should pass the call on to CSharpDefaults.DefaultMethod(int)using the C++ default value, as shown above.

    -

    17.5 C# Typemap examples

    +

    19.7 Multiples modules

    + + +

    +When using multiple modules 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 +getCPtr() and pointer constructor generated from the csbody typemaps needs changing. +The default visibility is internal but it needs to be public for access from a different assembly. +Just changing 'internal' to 'public' in the typemap achieves this. +Two macros are available in csharp.swg 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 csbody 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: +

    + +
    +
    +  SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
    +  SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
    +
    +
    + +

    +Alternatively, instead of exposing these as public, consider +using the [assembly:InternalsVisibleTo("Name")] 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 [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] attribute +if you don't want users to easily stumble upon these so called 'internal workings' of the wrappers. +

    + +

    19.8 C# Typemap examples

    This section includes a few examples of typemaps. For more examples, you @@ -1308,12 +1700,12 @@ might look at the files "csharp.swg" and "typemaps.i" in the SWIG library. -

    17.5.1 Memory management when returning references to member variables

    +

    19.8.1 Memory management when returning references to member variables

    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 Java equivalent. +The example is a direct equivalent to this Java equivalent.

    @@ -1432,11 +1824,11 @@ public class Bike : IDisposable { Note the addReference call.

    -

    17.5.2 Memory management for objects passed to the C++ layer

    +

    19.8.2 Memory management for objects passed to the C++ layer

    -The example is a direct equivalent to this Java equivalent. +The example is a direct equivalent to this Java equivalent. 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. -

    17.5.3 Date marshalling using the csin typemap and associated attributes

    +

    19.8.3 Date marshalling using the csin typemap and associated attributes

    -The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. +The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. This example demonstrates how a C++ date class, say CDate, can be mapped onto the standard .NET date class, System.DateTime 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 Java Date marshalling example. +The example is an equivalent to the Java Date marshalling example. The idea is that the System.DateTime is used wherever the C++ API uses a CDate. Let's assume the code being wrapped is as follows:

    @@ -1567,6 +1959,7 @@ Let's assume the code being wrapped is as follows:
     class CDate {
     public:
    +  CDate();
       CDate(int year, int month, int day);
       int getYear();
       int getMonth();
    @@ -1649,8 +2042,8 @@ The typemaps to achieve this are shown below.
     
     %typemap(cstype) const CDate& "System.DateTime"
     %typemap(csin, 
    -         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);")
    -         const CDate &
    +         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);"
    +        ) const CDate &
              "$csclassname.getCPtr(temp$csinput)"
     
     %typemap(cstype) CDate& "out System.DateTime"
    @@ -1658,7 +2051,8 @@ The typemaps to achieve this are shown below.
              pre="    CDate temp$csinput = new CDate();", 
              post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
                   " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
    -         cshin="out $csinput") CDate &
    +         cshin="out $csinput"
    +        ) CDate &
              "$csclassname.getCPtr(temp$csinput)"
     
     
    @@ -1763,7 +2157,8 @@ will be possible with the following CDate * typemaps pre=" 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);", - cshin="ref $csinput") CDate * + cshin="ref $csinput" + ) CDate * "$csclassname.getCPtr(temp$csinput)"
    @@ -1780,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); } } ... @@ -1788,7 +2184,52 @@ public class example { -

    17.5.4 A date example demonstrating marshalling of C# properties

    +

    +The following typemap is the same as the previous but demonstrates how a using block can be used for the temporary variable. +The only change to the previous typemap is the introduction of the 'terminator' attribute to terminate the using block. +The subtractYears method is nearly identical to the above addYears method. +

    + +
    +
    +%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)"
    +
    +void subtractYears(CDate *pDate, int years) {
    +  *pDate = CDate(pDate->getYear() - years, pDate->getMonth(), pDate->getDay());
    +}
    +
    +
    + +

    +The resulting generated code shows the termination of the using block: +

    + +
    +
    +public class example {
    +  public static void subtractYears(ref System.DateTime pDate, int years) {
    +    using (CDate temppDate = new CDate(pDate.Year, pDate.Month, pDate.Day)) {
    +    try {
    +      examplePINVOKE.subtractYears(CDate.getCPtr(temppDate), years);
    +    } finally {
    +      pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(),
    +                                  0, 0, 0);
    +    }
    +    } // terminate temppDate using block
    +  }
    +  ...
    +}
    +
    +
    + +

    19.8.4 A date example demonstrating marshalling of C# properties

    @@ -1827,7 +2268,8 @@ The typemap type required is thus CDate *. Given that the previous sect pre=" 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);", - cshin="ref $csinput") CDate * + cshin="ref $csinput" + ) CDate * "$csclassname.getCPtr(temp$csinput)" %typemap(csvarin, excode=SWIGEXCODE2) CDate * %{ @@ -1888,7 +2330,7 @@ Some points to note: -

    17.5.5 Turning wrapped classes into partial classes

    +

    19.8.5 Turning wrapped classes into partial classes

    @@ -1988,7 +2430,7 @@ demonstrating that the class contains methods calling both unmanaged code - The following example is an alternative approach to adding managed code to the generated proxy class.

    -

    17.5.6 Extending proxy classes with additional C# code

    +

    19.8.6 Extending proxy classes with additional C# code

    @@ -2027,6 +2469,38 @@ public class ExtendMe : IDisposable { +

    19.8.7 Underlying type for enums

    + + +

    +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 csbase 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: +

    + +
    +
    +%typemap(csbase) BigNumbers "uint"
    +%inline %{
    +  enum BigNumbers { big=0x80000000, bigger };
    +%}
    +
    +
    + +

    +The generated enum will then use the given underlying type and compile correctly: +

    + +
    +
    +public enum BigNumbers : uint {
    +  big = 0x80000000,
    +  bigger
    +}
    +
    +
    + diff --git a/Doc/Manual/Chicken.html b/Doc/Manual/Chicken.html index bd1b3d94b..4e43b9b90 100644 --- a/Doc/Manual/Chicken.html +++ b/Doc/Manual/Chicken.html @@ -8,7 +8,7 @@ -

    18 SWIG and Chicken

    +

    20 SWIG and Chicken

      @@ -35,7 +35,7 @@
    • Typemaps
    • Pointers
    • Unsupported features and known problems
        @@ -72,7 +72,7 @@

        -

        18.1 Preliminaries

        +

        20.1 Preliminaries

        @@ -80,17 +80,16 @@ relies on some recent additions to CHICKEN, which are only present in releases of CHICKEN with version number greater than or equal to 1.89. - To use a chicken version between 1.40 and 1.89, see the Garbage collection + To use a chicken version between 1.40 and 1.89, see the Garbage collection section below.

        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.

        -

        18.1.1 Running SWIG in C mode

        +

        20.1.1 Running SWIG in C mode

        @@ -123,7 +122,7 @@ object files and linked into your project.

        -

        18.1.2 Running SWIG in C++ mode

        +

        20.1.2 Running SWIG in C++ mode

        @@ -152,10 +151,10 @@ object files and linked into your project.

        -

        18.2 Code Generation

        +

        20.2 Code Generation

        -

        18.2.1 Naming Conventions

        +

        20.2.1 Naming Conventions

        @@ -171,7 +170,7 @@ %rename SWIG directive in the SWIG interface file.

        -

        18.2.2 Modules

        +

        20.2.2 Modules

        @@ -193,7 +192,7 @@ (uses modulename)) CHICKEN Scheme form.

        -

        18.2.3 Constants and Variables

        +

        20.2.3 Constants and Variables

        @@ -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 (set! MYCONSTANT1 (MYCONSTANT1)). See - Features and the %feature directive + Features and the %feature directive for info on how to apply the %feature.

        -

        18.2.4 Functions

        +

        20.2.4 Functions

        @@ -249,12 +248,12 @@ parameters). The return values can then be accessed with (call-with-values).

        -

        18.2.5 Exceptions

        +

        20.2.5 Exceptions

        The SWIG chicken module has support for exceptions thrown from C or C++ code to be caught in scheme. - See Exception handling with %exception + See Exception handling with %exception for more information about declaring exceptions in the interface file.

        @@ -263,7 +262,7 @@ inside the %exception blocks. SWIG_exception will throw a list consisting of the code (as an integer) and the message. Both of these will throw an exception using (abort), which can be handled by (handle-exceptions). See - Chicken manual on Exceptions + the Chicken manual on Exceptions and SFRI-12. Since the exception values are thrown directly, if (condition-case) is used to catch an exception the exception will come through in the val () case.

        @@ -291,7 +290,7 @@
    -

    18.3 TinyCLOS

    +

    20.3 TinyCLOS

    @@ -334,7 +333,7 @@

    -

    18.4 Linkage

    +

    20.4 Linkage

    @@ -355,7 +354,7 @@

    -

    18.4.1 Static binary or shared library linked at compile time

    +

    20.4.1 Static binary or shared library linked at compile time

    We can easily use csc to build a static binary.

    @@ -396,7 +395,7 @@ in which case the test script does not need to be linked with example.so. The t be run with csi.

    -

    18.4.2 Building chicken extension libraries

    +

    20.4.2 Building chicken extension libraries

    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

    This library can then be loaded by scheme code with the (require 'modname) function. -See -Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.

    +See the +Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.

    Another alternative is to run SWIG normally and create a scheme file that contains (declare (uses modname)) and then compile that file into the shared library as well. For example, inside the mod_load.scm file,

    @@ -454,7 +453,7 @@ distributed and used by anyone, even if SWIG is not installed.

    See the Examples/chicken/egg directory in the SWIG source for an example that builds two eggs, one using the first method and one using the second method.

    -

    18.4.3 Linking multiple SWIG modules with TinyCLOS

    +

    20.4.3 Linking multiple SWIG modules with TinyCLOS

    Linking together multiple modules that share type information using the %import @@ -478,7 +477,7 @@ with (declare (uses ...)). To create an extension library or an egg, just create a module_load.scm file that (declare (uses ...)) all the modules.

    -

    18.5 Typemaps

    +

    20.5 Typemaps

    @@ -487,7 +486,7 @@ all the modules.

    Lib/chicken/chicken.swg.

    -

    18.6 Pointers

    +

    20.6 Pointers

    @@ -520,7 +519,7 @@ all the modules.

    type. flags is either zero or SWIG_POINTER_DISOWN (see below).

    -

    18.6.1 Garbage collection

    +

    20.6.1 Garbage collection

    If the owner flag passed to SWIG_NewPointerObj is 1, NewPointerObj will add a @@ -531,12 +530,12 @@ all the modules.

    be garbage collected, SWIG will automatically set the owner flag to 1. For other functions, the %newobject directive must be specified for functions whose return values should be garbage collected. See - Object ownership and %newobject for more information. + Object ownership and %newobject for more information.

    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 DISOWN input typemap. - After applying this typemap (see the Typemaps chapter for more information on how to apply typemaps), + After applying this typemap (see the Typemaps chapter 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 SWIG_POINTER_DISOWN flag to SWIG_ConvertPtr. Warning: Since the lifetime of the object is now controlled by the underlying code, the object might @@ -551,7 +550,7 @@ all the modules.

    must be called manually.

    -

    18.7 Unsupported features and known problems

    +

    20.7 Unsupported features and known problems

    -

    18.7.1 TinyCLOS problems with Chicken version <= 1.92

    +

    20.7.1 TinyCLOS problems with Chicken version <= 1.92

    In Chicken versions equal to or below 1.92, TinyCLOS has a limitation such that generic methods do not properly work on methods diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 5c7a18eaf..4af66298c 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -5,7 +5,7 @@ SWIG Users Manual -

    SWIG Users Manual

    +

    SWIG Users Manual

    @@ -15,13 +15,12 @@

  • Running SWIG @@ -162,7 +167,7 @@
  • Character strings and structures
  • Array members
  • Structure data members -
  • C constructors and destructors +
  • C constructors and destructors
  • Adding member functions to C structures
  • Nested structures
  • Other things to note about structure wrapping @@ -223,21 +228,25 @@
  • Wrapping overloaded operators
  • Class extension
  • Templates -
  • Namespaces +
  • Namespaces +
  • Renaming templated types in namespaces
  • Exception specifications
  • Exception handling with %catches
  • Pointers to Members -
  • Smart pointers and operator->() +
  • Smart pointers and operator->() +
  • C++ reference counted objects - ref/unref feature
  • Using declarations and inheritance
  • Nested classes -
  • A brief rant about const-correctness +
  • A brief rant about const-correctness
  • Where to go for more information @@ -254,8 +263,11 @@
  • Macro Expansion
  • SWIG Macros
  • C99 and GNU Extensions +
  • Preprocessing and delimiters +
  • Preprocessor and Typemaps
  • Viewing preprocessor output
  • The #error and #warning directives @@ -272,7 +284,7 @@
  • C Arrays and Pointers @@ -285,9 +297,10 @@
  • STL/C++ Library
  • Utility Libraries
  • Typemap specifications -
  • Pattern matching rules +
  • Pattern matching rules
  • Code generation rules
  • Common typemap methods -
  • Typemaps for multiple languages +
  • Typemaps for multiple target languages
  • Optimal code generation when returning by value -
  • Multi-argument typemaps -
  • The run-time type checker +
  • Multi-argument typemaps +
  • Typemap warnings +
  • Typemap fragments + +
  • The run-time type checker
  • Typemaps and overloading
  • More about %apply and %clear -
  • Reducing wrapper code size
  • Passing data between typemaps +
  • C++ "this" pointer
  • Where to go for more information? @@ -400,7 +426,7 @@ @@ -474,7 +500,7 @@
  • C/C++ Parser (300-399)
  • Types and typemaps (400-499)
  • Code generation (500-599) -
  • Language module specific (800-899) +
  • Language module specific (700-899)
  • User defined (900-999)
  • History @@ -487,9 +513,10 @@ -

    16 SWIG and Allegro Common Lisp

    +

    16 Using SWIG with ccache - ccache-swig(1) manpage

    + + + + + +

    17 SWIG and Allegro Common Lisp

    -

    17 SWIG and C#

    +

    18 SWIG and Android

    -

    18 SWIG and Chicken

    +

    19 SWIG and C#

    + + + + + +

    20 SWIG and Chicken

    @@ -642,7 +720,7 @@
  • Typemaps
  • Pointers
  • Unsupported features and known problems -

    23 SWIG and Modula-3

    +

    27 SWIG and Modula-3

    -

    24 SWIG and MzScheme

    +

    28 SWIG and MzScheme/Racket

    -

    25 SWIG and Ocaml

    +

    29 SWIG and Ocaml

    @@ -995,7 +1156,7 @@
    -

    26 SWIG and Octave

    +

    30 SWIG and Octave

    @@ -1003,6 +1164,7 @@
  • Preliminaries
  • Running SWIG @@ -1030,7 +1192,7 @@ -

    27 SWIG and Perl5

    +

    31 SWIG and Perl5

    @@ -1065,7 +1227,7 @@
  • Modules and packages
  • Input and output parameters -
  • Exception handling +
  • Exception handling
  • Remapping datatypes with typemaps
  • Typemap Examples
  • PHP Pragmas, Startup and Shutdown code +
  • Cross language polymorphism + -

    29 SWIG and Pike

    +

    33 SWIG and Pike

    @@ -1152,7 +1323,7 @@
    -

    30 SWIG and Python

    +

    34 SWIG and Python

    @@ -1185,15 +1356,20 @@
  • C++ namespaces
  • C++ templates
  • C++ Smart Pointers -
  • C++ Reference Counted Objects (ref/unref) +
  • C++ reference counted objects
  • Further details on the Python class interface -
  • Cross language polymorphism +
  • Cross language polymorphism
  • Typemaps
  • Python Packages +
  • Python 3 Support + -

    31 SWIG and Ruby

    +

    35 SWIG and R

    + + + + + +

    36 SWIG and Ruby

    @@ -1285,7 +1482,7 @@
  • C++ namespaces
  • C++ templates
  • C++ Standard Template Library (STL) -
  • C++ STL Functors +
  • C++ STL Functors
  • C++ STL Iterators
  • C++ Smart Pointers
  • Cross-Language Polymorphism @@ -1369,7 +1566,7 @@
  • Advanced Topics @@ -1386,7 +1583,7 @@ -

    32 SWIG and Tcl

    +

    37 SWIG and Tcl

    @@ -1447,27 +1644,12 @@ +
  • Tcl/Tk Stubs -

    33 SWIG and R

    - - - - - -

    34 Extending SWIG to support new languages

    +

    38 Extending SWIG to support new languages

    @@ -1510,25 +1692,27 @@
  • Writing a Language Module -
  • Typemaps - +
  • Debugging Options
  • Guide to parse tree nodes +
  • Further Development Information diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html index e9d70e39a..b98fbfc88 100644 --- a/Doc/Manual/Customization.html +++ b/Doc/Manual/Customization.html @@ -10,7 +10,7 @@ @@ -45,7 +45,7 @@ of exception handling is presented. Then, a more general-purpose customization mechanism known as "features" is described.

    -

    11.1 Exception handling with %exception

    +

    11.1 Exception handling with %exception

    @@ -53,6 +53,21 @@ The %exception directive allows you to define a general purpose excepti handler. For example, you can specify the following:

    +
    +%exception {
    +    try {
    +        $action
    +    }
    +    catch (RangeError) {
    +        ... handle error ...
    +    }
    +}
    +
    + +

    +How the exception is handled depends on the target language, for example, Python: +

    +
     %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;
         }
     }
     
    @@ -68,7 +83,7 @@ handler. For example, you can specify the following:

    When defined, the code enclosed in braces is inserted directly into the low-level wrapper functions. The special variable $action is one of a few -%exception special variable +%exception special variables 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 %exception @@ -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 %exception follow the same rules as for %rename described in the section on -Ambiguity resolution and renaming. +Ambiguity resolution and renaming. For example, if you wanted to define an exception handler for a specific class, you might write this:

    @@ -567,7 +582,7 @@ it can be used elsewhere in SWIG. This includes typemaps and helper functions.

    -

    11.2 Object ownership and %newobject

    +

    11.2 Object ownership and %newobject

    @@ -689,6 +704,11 @@ depends on the target language on implementing the 'disown' mechanism properly.

    +

    +The use of %newobject is also integrated with reference counting and is covered in the +C++ reference counted objects section. +

    +

    Compatibility note: Previous versions of SWIG had a special %new directive. However, unlike %newobject, 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.

    -

    11.3 Features and the %feature directive

    +

    11.3 Features and the %feature directive

    @@ -758,9 +778,9 @@ involving %feature:

    -The name matching rules outlined in the Ambiguity resolution and renaming +The name matching rules outlined in the Ambiguity resolution and renaming section applies to all %feature directives. -In fact the the %rename directive is just a special form of %feature. +In fact the %rename directive is just a special form of %feature. 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, MyExceptionClass is the name of the Java clas

    -Further details can be obtained from the Java exception handling section. +Further details can be obtained from the Java exception handling section.

    11.3.2 Feature flags

    @@ -1019,6 +1039,20 @@ but this will: +

    +SWIG provides macros for disabling and clearing features. Many of these can be found in the swig.swg 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: +

    + +
    +
    +#define %exception      %feature("except")
    +#define %noexception    %feature("except","0")
    +#define %clearexception %feature("except","")
    +
    +
    +

    11.3.4 Features and default arguments

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

    -

    11.3.5 Feature example

    +

    11.3.5 Feature example

    diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html new file mode 100644 index 000000000..43fa69196 --- /dev/null +++ b/Doc/Manual/D.html @@ -0,0 +1,454 @@ + + + +SWIG and D + + + + +

    21 SWIG and D

    + + + + + + +

    21.1 Introduction

    + + +

    From the D Programming Language web site: 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. As such, it is not very surprising that D is able to directly interface with C libraries. Why would a SWIG module for D be needed then in the first place?

    + +

    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 \0-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.

    + +

    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 extern(C++) has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases.

    + +

    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 C# (and also on Java, since the C# module was in turn forked from it).

    + + +

    21.2 Command line invocation

    + + +

    To activate the D module, pass the -d 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:

    + +
    +
    -d2
    +
    +

    By default, SWIG generates code for D1/Tango. Use the -d2 flag to target D2/Phobos instead.

    +
    + +
    -splitproxy
    +
    +

    By default, SWIG generates two D modules: the proxy module, named like the source module (either specified via the %module directive or via the module command line switch), which contains all the proxy classes, functions, enums, etc., and the intermediary module (named like the proxy module, but suffixed with _im), which contains all the extern(C) function declarations and other private parts only used internally by the proxy module.

    +

    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.

    +
    + +
    -package <pkg>
    +
    +

    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.

    +
    + +
    -wrapperlibrary <wl>
    +
    +

    The code SWIG generates to dynamically load the C/C++ wrapper layer looks for a library called $module_wrap by default. With this switch, you can override the name of the file the wrapper code loads at runtime (the lib prefix and the suffix for shared libraries are appended automatically, depending on the OS).

    +

    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.

    +
    +
    + + +

    21.3 Typemaps

    + + +

    21.3.1 C# <-> D name comparison

    + + +

    If you already know the SWIG C# module, you might find the following name comparison table useful:

    + +
    + ctype                  <->  ctype
    + imtype                 <->  imtype
    + cstype                 <->  dtype
    + csin                   <->  din
    + csout                  <->  dout
    + csdirectorin           <->  ddirectorin
    + csdirectorout          <->  ddirectorout
    + csinterfaces           <->  dinterfaces
    + csinterfaces_derived   <->  dinterfaces_derived
    + csbase                 <->  dbase
    + csclassmodifiers       <->  dclassmodifiers
    + cscode                 <->  dcode
    + csimports              <->  dimports
    + csbody                 <->  dbody
    + csfinalize             <->  ddestructor
    + csdestruct             <->  ddispose
    + csdestruct_derived     <->  ddispose_derived
    +
    + + +

    21.3.2 ctype, imtype, dtype

    + + +

    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.

    + +

    The ctype typemap is used to determine the types to use in the C wrapper functions. The types from the imtype typemap are used in the extern(C) declarations of these functions in the intermediary D module. The dtype typemap contains the D types used in the D proxy module/class.

    + + +

    21.3.3 in, out, directorin, directorout

    + + +

    Used for converting between the types for C/C++ and D when generating the code for the wrapper functions (on the C++ side).

    + +

    The code from the in typemap is used to convert arguments to the C wrapper function to the type used in the wrapped code (ctype->original C++ type), the out typemap is utilized to convert values from the wrapped code to wrapper function return types (original C++ type->ctype).

    + +

    The directorin typemap is used to convert parameters to the type used in the D director callback function, its return value is processed by directorout (see below).

    + + +

    21.3.4 din, dout, ddirectorin, ddirectorout

    + + +

    Typemaps for code generation in D proxy and type wrapper classes.

    + +

    The din 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 $dinput macro is replaced). To inject further parameter processing code before or after the call to the intermediary layer, the pre, post and terminator attributes can be used (please refer to the C# date marshalling example for more information on these).

    + +

    The dout 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 $excode special variable in dout typemaps is replaced by the excode typemap attribute code if the method can throw any exceptions from unmanaged code, otherwise by nothing (the $imcall and $owner macros are replaced).

    + +

    The code from the ddirectorin and ddirectorout 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 ddirectorin, the proxy class method return value is converted to the type the C++ code expects via the ddirectorout typemap (the $dcall and $winput macros are replaced).

    + +

    The full chain of type conversions when a director callback is invoked looks like this:

    + +
    +      type              CPPClass::method(type a)
    +        ↑                       ↓
    +   <directorout>          <directorin>
    +        ↑                       ↓
    +      ctype             methodCallback(ctype a)           C++
    + :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
    +      imtype            methodCallback(imtype a)           D
    +        ↑                       ↓
    +  <ddirectorout>          <ddirectorin>
    +        ↑                       ↓
    +      dtype             DClass.method(dtype a)
    + + +

    21.3.5 typecheck typemaps

    + + +

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

    + + +

    21.3.6 Code injection typemaps

    + + +

    These typemaps are used for generating the skeleton of proxy classes for C++ types.

    + +

    By overriding dbase, dinterfaces or dinterfaces_derived, the inheritance chain of the generated proxy class for a type can be modified. dclassmodifiers allows you to add any custom modifiers around the class keyword.

    + +

    Using dcode and dimports, 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.

    + +

    dconstructor, ddestructor, ddispose and ddispose_derived are used to generate the class constructor, destructor and dispose() method, respectively. The auxiliary code for handling the pointer to the C++ object is stored in dbody and dbody_derived. You can override them for specific types.

    + + +

    21.3.7 Special variable macros

    + + +

    The standard SWIG special variables are available for use within typemaps as described in the Typemaps documentation, for example $1, $input, $result etc.

    + +

    When generating D wrappers, a few additional macros are available:

    +
    +
    $dclassname (C#: $csclassname)
    +
    +

    This special variable works similar to $n_type 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, SWIGTYPE_p_p_SomeCppClass is generated when wrapping SomeCppClass **.

    +

    There are two other variants available, $&dclassname and $*dclassname. The former adds a level of indirection, while the latter removes one. For instance, when wrapping Foo **, $*dclassname would be replaced by the proxy class name corresponding to Foo *.

    +
    + +
    $dclazzname (C#: $csclazzname)
    +
    +

    This special variable expands the fully qualified C++ class into the package name, if used by the nspace feature, and the proxy class name, mangled for use as a function name. For example, Namespace1::Namespace2::Klass is expanded into Namespace1_Namespace2_Klass_.

    +

    This special variable might be useful for calling certain functions in the wrapper layer (e.g. upcast wrappers) which are mangled like this.

    +
    + +
    $null
    +

    In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either 0 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 (return $null;).

    + +
    $dinput (C#: $csinput)
    +
    +

    This variable is used in din typemaps and is replaced by the expression which is to be passed to C/C++.

    +

    For example, this input

    +
    +%typemap(din) SomeClass * "SomeClass.getCPointer($dinput)"
    +
    +%inline %{
    +  class SomeClass {};
    +  void foo(SomeClass *arg);
    +%}
    +

    leads to the following D proxy code being generated:

    +
    +void foo(SomeClass arg) {
    +  example_im.foo(SomeClass.getCPointer(arg));
    +}
    + +
    $imcall and $owner (C#: $imcall)
    +
    +

    These variables are used in dout typemaps. $imcall contains the call to the intermediary module which provides the value to be used, and $owner 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 %newobject).

    +

    Consider the following example:

    +
    +%typemap(dout) SomeClass * {
    +  return new SomeClass($imcall, $owner);
    +}
    +
    +%inline %{
    +  class SomeClass;
    +  SomeClass *foo();
    +
    +  %newobject bar();
    +  SomeClass *bar();
    +%}
    +

    The code generated for foo() and bar() looks like this:

    +
    +SomeClass foo() {
    +  return new SomeClass(example_im.foo(), false);
    +}
    +
    +SomeClass bar() {
    +  return new SomeClass(example_im.bar(), true);
    +}
    +
    +
    + +
    $dcall and $winput (C#: $cscall, $iminput)
    +

    These variables are used in the director-specific typemaps ddirectorin and ddirectorout. They are more or less the reverse of the $imcall and $dinput macros: $dcall contains the invocation of the D proxy method of which the return value is to be passed back to C++, $winput contains the parameter value from C++.

    + +
    $excode
    +

    This variable is used in dout and dconstructor typemaps and is filled with the contents of the excode typemap attribute if an exception could be thrown from the C++ side. See the C# documentation for details.

    + +
    $dbaseclass
    +

    Currently for internal use only, it contains the D name of the C++ base class (if any) inside proxy classes.

    + +
    $directorconnect
    +
    +

    This macro is only valid inside the dconstructor typemap and contains the value of the dconstructor typemap attribute if the currently wrapped class has directors enabled.

    +

    This is how the default dconstructor typemap looks like (you usually do not want to specify a custom one):

    +
    +%typemap(dconstructor, excode=SWIGEXCODE,
    +         directorconnect="\n  swigDirectorConnect();") SWIGTYPE {
    +  this($imcall, true);$excode$directorconnect
    +}
    +
    +
    + +
    $importtype(SomeDType)
    +
    +

    This macro is used in the dimports typemap if a dependency on another D type generated by SWIG is added by a custom typemap.

    +

    Consider the following code snippet:

    +
    +%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
    +
    +

    This causes SWIG to add AnInterface and AnotherInterface to the base class list of SomeClass:

    +
    +class SomeClass : AnInterface, AnotherInterface {
    +  ...
    +}
    +
    +

    For this to work, AnInterface and AnotherInterface 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 dimports typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.

    +

    The $importtype macro helps you to elegantly solve this problem:

    +
    +%typemap(dimports) RemoteMpe %{
    +$importtype(AnInterface)
    +$importtype(AnotherInterface)
    +%}
    +
    +

    If SWIG is in split proxy mode, it expands to an import statement for the specified type, to nothing if not.

    +
    + +
    $module
    +

    Expands to the name of the main proxy D module.

    + +
    $imdmodule
    +

    Contains the fully qualified name of the intermediary D module.

    +
    + + +

    21.4 %features

    + + +

    The D module defines a number of directives which modify the SWIG features set globally or for a specific declaration:

    + + +
    +
    %dmanifestconst and %dconstvalue(value)
    +
    +

    Out of the box, SWIG generates accessor methods for C #defines and C++ constants. The %dmanifestconst directive enables wrapping these constants as D manifest constants (const in D1, enum in D2).

    +

    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 %dconstvalue directive, passing the new value as parameter.

    +

    For enums, again %dconstvalue can be used to override the value of an enum item if the initializer should not compile in D.

    +
    + +
    %dmethodmodifiers
    +
    +

    This directive can be used to override the modifiers for a proxy function. For instance, you could make a public C++ member function private in D like this:

    +
    +%dmethodmodifiers A::foo "private";
    +
    +%inline %{
    +struct A {
    +  void foo();
    +};
    +%}
    +
    +
    +
    + + +

    21.5 Pragmas

    + + +

    There are a few SWIG pragmas specific to the D module, which you can use to influence the D code SWIG generates:

    + +
    +
    %pragma(d) imdmodulecode
    +

    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.

    + +
    %pragma(d) imdmoduleimports
    +

    Additional code to be emitted to the imports section of the intermediary D module (the $importtype macro can be used here). You probably want to use this in conjunction with the imdmodulecode pragma.

    + +
    %pragma(d) proxydmodulecode
    +

    Just like proxydmodulecode, the argument is copied to the proxy D module (if SWIG is in split proxy mode and/or the nspace feature is used, it is emitted to the main proxy D module only).

    + +
    %pragma(d) globalproxyimports
    +
    +

    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 all proxy modules if in split proxy mode), you can use the globalproxyimports directive.

    +

    For example:

    +
    +%typemap(din) char[] "($dinput ? tango.stdc.stringz.toStringz($dinput) : null)"
    +%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
    +
    +
    + +
    %pragma(d) wrapperloadercode
    +
    +

    The D code for loading the wrapper library (it is copied to the intermediary D module). The $wrapperloaderbindcode variable is replaced by the list of commands for binding the functions from the wrapper library to the symbols in the intermediary D module.

    +

    Each time this pragma is specified, the previous value is overwritten.

    +
    + +
    %pragma(d) wrapperloaderbindcommand
    +
    +

    The D command to use for binding the wrapper functions from the C/C++ library to the symbols in the intermediary D module. The $function variable contains the name of the D function in the wrap module, the $symbol variable is replaced by the name of the symbol in the library.

    +

    Each time this pragma is specified, the previous value is overwritten.

    +
    +
    + + +

    21.6 D Exceptions

    + + +

    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.

    + +

    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 throw(...) exception specification).

    + +

    As this feature is implemented in exactly the same way it is for C#, please see the C# documentation for a more detailed explanation.

    + + +

    21.7 D Directors

    + + +

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

    + +

    There is no D specific documentation yet, but the way the feature is implemented is very similar to how it is done in Java and C#. +

    + + +

    21.8 Other features

    + + +

    21.8.1 Extended namespace support (nspace)

    + + +

    By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the nspace 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, free variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.

    + + +

    21.8.2 Native pointer support

    + + +

    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 primitive type below.

    + +

    Central to this custom pointer handling scheme are two typemap attributes: the cprimitive attribute on the dtype typemap and the nativepointer attribute on all the typemaps which influence the D side of the code (dtype, din, dout, ...). When a D typemap is looked up, the following happens behind the scenes:

    + +

    First, the matching typemap is determined by the usual typemap lookup rules. Then, it is checked if the result has the nativepointer attribute set. If it is present, it means that its value should replace the typemap value if and only if 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.

    + +

    To determine if a type should be considered primitive, the cprimitive attribute on its dtype attribute is used. For example, the dtype typemap for float has cprimitive="1", so the code from the nativepointer attribute is taken into account e.g. for float ** or the function pointer float (*)(float *).

    + + +

    21.8.3 Operator overloading

    + + +

    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:

    + +

    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.

    + +

    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 && and ||, but also !, and prefix increment/decrement operators in D1 resp. their postfix pendants in D2.

    + +

    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, [], in combination with assignments - while operator [] in C++ simply returns a reference which is then written to, D resorts to a separate opIndexAssign method -, or implicit casting (which was introduced in D2 via alias this). Despite the lack of automatic support, manually handling these cases should be perfectly possible.

    + + +

    21.8.4 Running the test-suite

    + + +

    As with any other language, the SWIG test-suite can be built for D using the *-d-test-suite targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional D_VERSION variable, e.g. make check-d-test-suite D_VERSION=2.

    + +

    Note: If you want to use GDC on Linux or another platform which requires you to link libdl for dynamically loading the shared library, you might have to add -ldl manually to the d_compile target in Examples/Makefile, because GDC does not currently honor the pragma(lib,...) statement.

    + + +

    21.9 D Typemap examples

    + + +

    There are no D-specific typemap examples yet. However, with the above name comparison table, you should be able to get an idea what can be done by looking at the corresponding C# section.

    + + + +

    21.10 Work in progress and planned features

    + + +

    There are a couple of features which are not implemented yet, but would be very useful and might be added in the near future:

    + +
      +
    • Static linking: 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.
    • +
    • C array handling: 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.
    • +
    + +

    Some generated code might also be a bit rough around the edges, particularly in the following areas:

    + +
      +
    • Memory management: 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.
    • +
    • D2 support: 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 could be issues concerning const-correctness etc.
    • +
    + + + + + diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index 588912b68..c3b2740f4 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -6,7 +6,7 @@ -

    34 Extending SWIG to support new languages

    +

    38 Extending SWIG to support new languages

    -

    34.1 Introduction

    +

    38.1 Introduction

    @@ -89,7 +91,7 @@ Also, this chapter is not meant to be a hand-holding tutorial. As a starting po you should probably look at one of SWIG's existing modules.

    -

    34.2 Prerequisites

    +

    38.2 Prerequisites

    @@ -119,7 +121,7 @@ obvious, but almost all SWIG directives as well as the low-level generation of wrapper code are driven by C++ datatypes.

    -

    34.3 The Big Picture

    +

    38.3 The Big Picture

    @@ -156,7 +158,7 @@ role in making the system work. For example, both typemaps and declaration anno based on pattern matching and interact heavily with the underlying type system.

    -

    34.4 Execution Model

    +

    38.4 Execution Model

    @@ -201,7 +203,7 @@ latter stage of compilation. The next few sections briefly describe some of these stages.

    -

    34.4.1 Preprocessing

    +

    38.4.1 Preprocessing

    @@ -232,10 +234,11 @@ of swig.swg looks like this: ... /* Code insertion directives such as %wrapper %{ ... %} */ -#define %init %insert("init") -#define %wrapper %insert("wrapper") -#define %header %insert("header") +#define %begin %insert("begin") #define %runtime %insert("runtime") +#define %header %insert("header") +#define %wrapper %insert("wrapper") +#define %init %insert("init") /* Access control directives */ @@ -281,7 +284,7 @@ been expanded as well as everything else that goes into the low-level construction of the wrapper code.

    -

    34.4.2 Parsing

    +

    38.4.2 Parsing

    @@ -382,7 +385,7 @@ returning a foo and taking types a and b as arguments).

    -

    34.4.3 Parse Trees

    +

    38.4.3 Parse Trees

    @@ -448,7 +451,8 @@ of the output.

    The contents of each parse tree node consist of a collection of attribute/value pairs. Internally, the nodes are simply represented by hash tables. A display of -the entire parse-tree structure can be obtained using swig -dump_tree. +the entire parse-tree structure can be obtained using swig -debug-top <n>, where n is +the stage being processed. There are a number of other parse tree display options, for example, swig -debug-module <n> will avoid displaying system parse information and only display the parse tree pertaining to the user's module at stage n of processing. @@ -636,7 +640,7 @@ $ swig -c++ -python -debug-module 4 example.i -

    34.4.4 Attribute namespaces

    +

    38.4.4 Attribute namespaces

    @@ -655,7 +659,7 @@ that matches the name of the target language. For example, python:foo perl:foo.

    -

    34.4.5 Symbol Tables

    +

    38.4.5 Symbol Tables

    @@ -746,7 +750,7 @@ example.i:5. Previous declaration is foo_i(int ) -

    34.4.6 The %feature directive

    +

    38.4.6 The %feature directive

    @@ -802,7 +806,7 @@ For example, the exception code above is simply stored without any modifications.

    -

    34.4.7 Code Generation

    +

    38.4.7 Code Generation

    @@ -924,7 +928,7 @@ public : The role of these functions is described shortly.

    -

    34.4.8 SWIG and XML

    +

    38.4.8 SWIG and XML

    @@ -937,7 +941,7 @@ internal data structures, it may be useful to keep XML in the back of your mind as a model.

    -

    34.5 Primitive Data Structures

    +

    38.5 Primitive Data Structures

    @@ -983,7 +987,7 @@ typedef Hash Typetab; -

    34.5.1 Strings

    +

    38.5.1 Strings

    @@ -1023,7 +1027,7 @@ Deletes s.

    -int Len(String_or_char *s) +int Len(const String_or_char *s)

    @@ -1031,7 +1035,7 @@ Returns the length of the string.

    -char *Char(String_or_char *s) +char *Char(const String_or_char *s)

    @@ -1039,7 +1043,7 @@ Returns a pointer to the first character in a string.

    -void Append(String *s, String_or_char *t) +void Append(String *s, const String_or_char *t)

    @@ -1047,7 +1051,7 @@ Appends t to the end of string s.

    -void Insert(String *s, int pos, String_or_char *t) +void Insert(String *s, int pos, const String_or_char *t)

    @@ -1124,7 +1128,7 @@ Returns the number of replacements made (if any).
    -

    34.5.2 Hashes

    +

    38.5.2 Hashes

    @@ -1160,7 +1164,7 @@ Returns the number of items in h.

    -Object *Getattr(Hash *h, String_or_char *key) +Object *Getattr(Hash *h, const String_or_char *key)

    @@ -1169,7 +1173,7 @@ a simple char * string. Returns NULL if not found.

    -int Setattr(Hash *h, String_or_char *key, Object_or_char *val) +int Setattr(Hash *h, const String_or_char *key, const Object_or_char *val)

    @@ -1183,7 +1187,7 @@ of val. Returns 1 if this operation replaced an existing hash entry,

    -int Delattr(Hash *h, String_or_char *key) +int Delattr(Hash *h, const String_or_char *key)

    @@ -1201,7 +1205,7 @@ Returns the list of hash table keys.
    -

    34.5.3 Lists

    +

    38.5.3 Lists

    @@ -1247,7 +1251,7 @@ negative, the first item is returned.

    -int *Setitem(List *x, int n, Object_or_char *val) +int *Setitem(List *x, int n, const Object_or_char *val)

    @@ -1269,7 +1273,7 @@ for n.

    -void Append(List *x, Object_or_char *t) +void Append(List *x, const Object_or_char *t)

    @@ -1279,7 +1283,7 @@ used to create a String object.

    -void Insert(String *s, int pos, Object_or_char *t) +void Insert(String *s, int pos, const Object_or_char *t)

    @@ -1290,7 +1294,7 @@ If t is not a standard object, it is assumed to be a char * and is used to create a String object.
    -

    34.5.4 Common operations

    +

    38.5.4 Common operations

    The following operations are applicable to all datatypes. @@ -1345,7 +1349,7 @@ objects and report errors. Gets the line number associated with x. -

    34.5.5 Iterating over Lists and Hashes

    +

    38.5.5 Iterating over Lists and Hashes

    To iterate over the elements of a list or a hash table, the following functions are used: @@ -1390,7 +1394,7 @@ for (j = First(j); j.item; j= Next(j)) { -

    34.5.6 I/O

    +

    38.5.6 I/O

    Special I/O functions are used for all internal I/O. These operations @@ -1477,13 +1481,14 @@ Same as the C tell() function.

    -File *NewFile(const char *filename, const char *mode) +File *NewFile(const char *filename, const char *mode, List *newfiles)

    Create a File object using the fopen() library call. This file differs from FILE * in that it can be placed in the standard -SWIG containers (lists, hashes, etc.). +SWIG containers (lists, hashes, etc.). The filename is added to the +newfiles list if newfiles is non-zero and the file was created successfully.

    @@ -1526,7 +1531,7 @@ Similarly, the preprocessor and parser all operate on string-files. -

    34.6 Navigating and manipulating parse trees

    +

    38.6 Navigating and manipulating parse trees

    Parse trees are built as collections of hash tables. Each node is a hash table in which @@ -1660,7 +1665,7 @@ Deletes a node from the parse tree. Deletion reconnects siblings and properly u the parent so that sibling nodes are unaffected. -

    34.7 Working with attributes

    +

    38.7 Working with attributes

    @@ -1777,7 +1782,7 @@ the attribute is optional. Swig_restore() must always be called after function. -

    34.8 Type system

    +

    38.8 Type system

    @@ -1786,7 +1791,7 @@ pointers, references, and pointers to members. A detailed discussion of type theory is impossible here. However, let's cover the highlights.

    -

    34.8.1 String encoding of types

    +

    38.8.1 String encoding of types

    @@ -1887,7 +1892,7 @@ make the final type, the two parts are just joined together using string concatenation.

    -

    34.8.2 Type construction

    +

    38.8.2 Type construction

    @@ -1920,7 +1925,7 @@ Adds a reference to ty.

    -void SwigType_add_array(SwigType *ty, String_or_char *dim) +void SwigType_add_array(SwigType *ty, const String_or_char *size)

    @@ -1960,7 +1965,7 @@ Sets nth array dimensions of ty to rep.

    -void SwigType_add_qualifier(SwigType *ty, String_or_char *q) +void SwigType_add_qualifier(SwigType *ty, const String_or_char *q)

    @@ -1969,7 +1974,7 @@ Adds a type qualifier q to ty. q is typically

    -void SwigType_add_memberpointer(SwigType *ty, String_or_char *cls) +void SwigType_add_memberpointer(SwigType *ty, const String_or_char *cls)

    @@ -2056,7 +2061,7 @@ Returns the prefix of a type. For example, if ty is ty is unmodified.
    -

    34.8.3 Type tests

    +

    38.8.3 Type tests

    @@ -2143,7 +2148,7 @@ Checks if ty is a varargs type. Checks if ty is a templatized type. -

    34.8.4 Typedef and inheritance

    +

    38.8.4 Typedef and inheritance

    @@ -2245,7 +2250,7 @@ Fully reduces ty according to typedef rules. Resulting datatype will consist only of primitive typenames. -

    34.8.5 Lvalues

    +

    38.8.5 Lvalues

    @@ -2282,7 +2287,7 @@ Literal y; // type = 'Literal', ltype='p.char' -

    34.8.6 Output functions

    +

    38.8.6 Output functions

    @@ -2290,7 +2295,7 @@ The following functions produce strings that are suitable for output.

    -String *SwigType_str(SwigType *ty, String_or_char *id = 0) +String *SwigType_str(SwigType *ty, const String_or_char *id = 0)

    @@ -2301,7 +2306,7 @@ used to convert string-encoded types back into a form that is valid C syntax.

    -String *SwigType_lstr(SwigType *ty, String_or_char *id = 0) +String *SwigType_lstr(SwigType *ty, const String_or_char *id = 0)

    @@ -2310,7 +2315,7 @@ is generated from the type's lvalue (as generated from SwigType_ltype).

    -String *SwigType_lcaststr(SwigType *ty, String_or_char *id = 0) +String *SwigType_lcaststr(SwigType *ty, const String_or_char *id = 0)

    @@ -2321,7 +2326,7 @@ this function produces the string "(char *) foo".

    -String *SwigType_rcaststr(SwigType *ty, String_or_char *id = 0) +String *SwigType_rcaststr(SwigType *ty, const String_or_char *id = 0)

    @@ -2344,7 +2349,7 @@ SWIG, but is most commonly associated with type-descriptor objects that appear in wrappers (e.g., SWIGTYPE_p_double).
    -

    34.9 Parameters

    +

    38.9 Parameters

    @@ -2443,7 +2448,7 @@ included. Used to emit prototypes. Returns the number of required (non-optional) arguments in p. -

    34.10 Writing a Language Module

    +

    38.10 Writing a Language Module

    @@ -2458,7 +2463,7 @@ describes the creation of a minimal Python module. You should be able to extra this to other languages.

    -

    34.10.1 Execution model

    +

    38.10.1 Execution model

    @@ -2468,7 +2473,7 @@ the parsing of command line options, all aspects of code generation are controll different methods of the Language that must be defined by your module.

    -

    34.10.2 Starting out

    +

    38.10.2 Starting out

    @@ -2576,7 +2581,7 @@ that activates your module. For example, swig -python foo.i. The messages from your new module should appear.

    -

    34.10.3 Command line options

    +

    38.10.3 Command line options

    @@ -2599,24 +2604,24 @@ void Language::main(int argc, char *argv[]) { } else { Swig_arg_error(); } - } else if (strcmp(argv[i],"-globals") == 0) { - if (argv[i+1]) { - global_name = NewString(argv[i+1]); - Swig_mark_arg(i); - Swig_mark_arg(i+1); - i++; - } else { - Swig_arg_error(); - } - } else if ( (strcmp(argv[i],"-proxy") == 0)) { - proxy_flag = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-keyword") == 0) { - use_kw = 1; - Swig_mark_arg(i); - } else if (strcmp(argv[i],"-help") == 0) { - fputs(usage,stderr); - } + } else if (strcmp(argv[i],"-globals") == 0) { + if (argv[i+1]) { + global_name = NewString(argv[i+1]); + Swig_mark_arg(i); + Swig_mark_arg(i+1); + i++; + } else { + Swig_arg_error(); + } + } else if ( (strcmp(argv[i],"-proxy") == 0)) { + proxy_flag = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-keyword") == 0) { + use_kw = 1; + Swig_mark_arg(i); + } else if (strcmp(argv[i],"-help") == 0) { + fputs(usage,stderr); + } ... } } @@ -2635,7 +2640,7 @@ to mark the option as valid. If you forget to do this, SWIG will terminate wit unrecognized command line option error.

    -

    34.10.4 Configuration and preprocessing

    +

    38.10.4 Configuration and preprocessing

    @@ -2684,7 +2689,7 @@ an implementation file python.cxx and a configuration file python.swg.

    -

    34.10.5 Entry point to code generation

    +

    38.10.5 Entry point to code generation

    @@ -2742,22 +2747,23 @@ int Python::top(Node *n) { -

    34.10.6 Module I/O and wrapper skeleton

    +

    38.10.6 Module I/O and wrapper skeleton

    -Within SWIG wrappers, there are four main sections. These are (in order) +Within SWIG wrappers, there are five main sections. These are (in order)

      -
    • runtime: This section has most of the common SWIG runtime code -
    • header: This section holds declarations and inclusions from the .i file -
    • wrapper: This section holds all the wrappering code +
    • begin: This section is a placeholder for users to put code at the beginning of the C/C++ wrapper file. +
    • runtime: This section has most of the common SWIG runtime code. +
    • header: This section holds declarations and inclusions from the .i file. +
    • wrapper: This section holds all the wrappering code.
    • init: This section holds the module initalisation function -(the entry point for the interpreter) +(the entry point for the interpreter).

    Different parts of the SWIG code will fill different sections, @@ -2774,6 +2780,7 @@ such as: class PYTHON : public Language { protected: /* General DOH objects used for holding the strings */ + File *f_begin; File *f_runtime; File *f_header; File *f_wrappers; @@ -2789,22 +2796,25 @@ int Python::top(Node *n) { ... /* Initialize I/O */ - f_runtime = NewFile(outfile, "w"); - if (!f_runtime) { + f_begin = NewFile(outfile, "w", SWIG_output_files()); + if (!f_begin) { FileErrorDisplay(outfile); SWIG_exit(EXIT_FAILURE); } + f_runtime = NewString(""); f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("begin", f_begin); Swig_register_filebyname("header", f_header); Swig_register_filebyname("wrapper", f_wrappers); Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("init", f_init); /* Output module initialization code */ + Swig_banner(f_begin); ... /* Emit code for children */ @@ -2812,16 +2822,18 @@ int Python::top(Node *n) { ... /* Write all to the file */ - Dump(f_header, f_runtime); - Dump(f_wrappers, f_runtime); - Wrapper_pretty_print(f_init, f_runtime); + Dump(f_runtime, f_begin); + Dump(f_header, f_begin); + Dump(f_wrappers, f_begin); + Wrapper_pretty_print(f_init, f_begin); /* Cleanup files */ + Delete(f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); - Close(f_runtime); - Delete(f_runtime); + Close(f_begin); + Delete(f_begin); return SWIG_OK; } @@ -2884,7 +2896,7 @@ functionWrapper : void Shape_y_set(Shape *self,double y) -

    34.10.7 Low-level code generators

    +

    38.10.7 Low-level code generators

    @@ -3038,13 +3050,13 @@ but without the typemaps, there is still work to do.

    -

    34.10.8 Configuration files

    +

    38.10.8 Configuration files

    -At the time of this writing, SWIG supports nearly a dozen languages, +At the time of this writing, SWIG supports nearly twenty languages, which means that for continued sanity in maintaining the configuration files, the language modules need to follow some conventions. These are outlined here along with the admission that, yes it is ok to violate @@ -3079,8 +3091,6 @@ The nickname is used in four places:

  • - -
    DOH (*)
    DOH C library providing memory allocation, file access and generic - containers. Result: libdoh.a
    Experiment[TODO]
    Include (*)
    Include Configuration .h files
    LParseParser (lex / yacc) files and support [why not (*)?!]
    CParseParser (lex / yacc) files and support
    Modules[TODO]
    Modules1.1 (*) Language-specific callbacks that does actual code generation (each - language has a .cxx and a .h file). Result: libmodules11.a
    Preprocessor (*)SWIG-specialized C/C++ preprocessor. Result: libcpp.a
    PreprocessorSWIG-specialized C/C++ preprocessor.
    SWIG1.1 (*)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.
    SWIG1.3[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.
    Swig (*)This directory contains the new ANSI C core of the system +
    SwigThis directory contains the ANSI C core of the system and contains generic functions related to types, file handling, scanning, and so forth.
    ToolsLibtool support and the mkdist.py script.The mkdist.py script and other tools.
    Win
    usagetransform
    "skip" tag(none)
    Examples/ subdir name(none)
    Examples/GIFPlot/ subdir namecapitalize (upcase first letter)
    Examples/test-suite/ subdir name(none)
    @@ -3113,7 +3123,7 @@ entirely upcased.

    At the end of the new section is the place to put the aforementioned -nickname kludges (should they be needed). See Perl5 and Php4 for +nickname kludges (should they be needed). See Perl5 for examples of what to do. [If this is still unclear after you've read the code, ping me and I'll expand on this further. --ttn]

    @@ -3148,8 +3158,8 @@ skip-qux = $(skip-qux99)

    Lastly, you need to modify each of check-aliveness, -check-examples, check-test-suite, -check-gifplot (all targets) and lib-languages (var). +check-examples, check-test-suite +and lib-languages (var). Use the nickname for these, not the alias. Note that you can do this even before you have any tests or examples set up; the Makefile rules do some sanity checking and skip around @@ -3164,10 +3174,6 @@ and look to the existing languages for examples.

    Do cp ../python/check.list . and modify to taste. One subdir per line. -
    Examples/GIFPlot/Qux99/check.list -
    Do cp ../Python/check.list . and modify to taste. -One subdir per line. -
    Lib/qux99/extra-install.list
    If you add your language to the top-level Makefile.in var lib-languages, then make install will install @@ -3188,7 +3194,7 @@ politely displays the ignoring language message. -

    34.10.9 Runtime support

    +

    38.10.9 Runtime support

    @@ -3197,7 +3203,7 @@ Discuss the kinds of functions typically needed for SWIG runtime support (e.g. the SWIG files that implement those functions.

    -

    34.10.10 Standard library files

    +

    38.10.10 Standard library files

    @@ -3216,7 +3222,7 @@ The following are the minimum that are usually supported: Please copy these and modify for any new language.

    -

    34.10.11 Examples and test cases

    +

    38.10.11 User examples

    @@ -3241,11 +3247,256 @@ These can be found, for example for Python, in

    By default, all of the examples are built and run when the user types make check. To ensure that your examples are automatically run -during this process, see the section on configuration +during this process, see the section on configuration files.

    -

    34.10.12 Documentation

    +

    38.10.12 Test driven development and the test-suite

    + + +

    +A test driven development approach is central to the improvement and development of SWIG. +Most modifications to SWIG are accompanied by additional regression tests and checking all +tests to ensure that no regressions have been introduced. +

    + +

    +The regression testing is carried out by the SWIG test-suite. +The test-suite consists of numerous testcase interface files in the Examples/test-suite directory +as well as target language specific runtime tests in the Examples/test-suite/[lang] directory. +When a testcase is run, it will execute the following steps for each testcase: +

    + +
      +
    1. Execute SWIG passing it the testcase interface file.
    2. +
    3. Compile the resulting generated C/C++ code with either the C or C++ compiler into object files.
    4. +
    5. Link the object files into a dynamic library (dll/shared object).
    6. +
    7. Compile any generated and any runtime test target language code with the target language compiler, if the target language supports compilation. This step thus does not apply to the interpreted languages.
    8. +
    9. Execute a runtime test if one exists.
    10. +
    + +

    +For example, the ret_by_value testcase consists of two components. +The first component is the Examples/test-suite/ret_by_value.i interface file. +The name of the SWIG module must always be the name of the testcase, so the ret_by_value.i interface file thus begins with: +

    + +
    +
    +%module ret_by_value
    +
    +
    + +

    +The testcase code will then follow the module declaration, +usually within a %inline %{ ... %} section for the majority of the tests. +

    + +

    +The second component is the optional runtime tests. +Any runtime tests are named using the following convention: [testcase]_runme.[ext], +where [testcase] is the testcase name and [ext] is the normal extension for the target language file. +In this case, the Java and Python target languages implement a runtime test, so their files are respectively, +Examples/test-suite/java/ret_by_value_runme.java and +Examples/test-suite/python/ret_by_value_runme.py. +

    + +

    +The goal of the test-suite is to test as much as possible in a silent manner. +This way any SWIG or compiler errors or warnings are easily visible. +Should there be any warnings, changes must be made to either fix them (preferably) or suppress them. +Compilation or runtime errors result in a testcase failure and will be immediately visible. +It is therefore essential that the runtime tests are written in a manner that displays nothing to stdout/stderr on success +but error/exception out with an error message on stderr on failure. +

    + +

    38.10.12.1 Running the test-suite

    + + +

    +In order for the test-suite to work for a particular target language, the language must be correctly detected +and configured during the configure stage so that the correct Makefiles are generated. +Most development occurs on Linux, so usually it is a matter of installing the development packages for the target language +and simply configuring as outlined earlier. +

    + +

    +If when running the test-suite commands that follow, you get a message that the test was skipped, it indicates that the +configure stage is missing information in order to compile and run everything for that language. +

    + +

    +The test-suite can be run in a number of ways. +The first group of commands are for running multiple testcases in one run and should be executed in the top level directory. +To run the entire test-suite (can take a long time): +

    + +
    +make -k check-test-suite
    +
    + +

    +To run the test-suite just for target language [lang], replace [lang] with one of csharp, java, perl5, python, ruby, tcl etc: +

    + +
    +make check-[lang]-test-suite
    +
    + +

    +Note that if a runtime test is available, a message "(with run test)" is displayed when run. For example: +

    + +
    +$ make check-python-test-suite
    +checking python test-suite
    +checking testcase argcargvtest (with run test) under python
    +checking testcase python_autodoc under python
    +checking testcase python_append (with run test) under python
    +checking testcase callback (with run test) under python
    +
    + +

    +The files generated on a previous run can be deleted using the clean targets, either the whole test-suite or for a particular language: +

    + +
    +make clean-test-suite
    +make clean-[lang]-test-suite
    +
    + +

    +The test-suite can be run in a partialcheck mode where just SWIG is executed, that is, the compile, +link and running of the testcases is not performed. +Note that the partialcheck does not require the target language to be correctly configured and detected and unlike the other test-suite make targets, is never skipped. Once again, either all the languages can be executed or just a chosen language: +

    + +
    +make partialcheck-test-suite
    +make partialcheck-[lang]-test-suite
    +
    + +

    +If your computer has more than one CPU, you are strongly advised to use parallel make to speed up the execution speed. +This can be done with any of the make targets that execute more than one testcase. +For example, a dual core processor can efficiently use 2 parallel jobs: +

    + +
    +make -j2 check-test-suite
    +make -j2 check-python-test-suite
    +make -j2 partialcheck-java-test-suite
    +
    + +

    +The second group of commands are for running individual testcases and should be executed in the appropriate +target language directory, Examples/test-suite/[lang]. +Testcases can contain either C or C++ code and when one is written, a decision must be made as to which of these input +languages is to be used. +Replace [testcase] in the commands below with the name of the testcase. +

    + +

    +For a C language testcase, add the testcase under the C_TEST_CASES list in Examples/test-suite/common.mk and +execute individually as: +

    +
    +make -s [testcase].ctest
    +
    + +

    +For a C++ language testcase, add the testcase under the CPP_TEST_CASES list in Examples/test-suite/common.mk and +execute individually as: +

    +
    +make -s [testcase].cpptest
    +
    + +

    +A third category of tests are C++ language testcases testing multiple modules (the %import directive). +These require more than one shared library (dll/shared object) to be built and so are separated out from the normal C++ testcases. +Add the testcase under the MULTI_CPP_TEST_CASES list in Examples/test-suite/common.mk and +execute individually as: +

    +
    +make -s [testcase].multicpptest
    +
    + +

    +To delete the generated files, execute: +

    +
    +make -s [testcase].clean
    +
    + +

    +If you would like to see the exact commands being executed, drop the -s option: +

    +
    +make [testcase].ctest
    +make [testcase].cpptest
    +make [testcase].multicpptest
    +
    + +

    +Some real examples of each: +

    +
    +make -s ret_by_value.clean
    +make -s ret_by_value.ctest
    +make -s bools.cpptest
    +make -s imports.multicpptest
    +
    + +

    +Advanced usage of the test-suite facilitates running tools on some of the five stages. +The make variables SWIGTOOL and RUNTOOL are used to specify a tool to respectively, invoke SWIG +and the execution of the runtime test. +You are advised to view the Examples/test-suite/common.mk file for details but for a short summary, +the classic usage is to use Valgrind for memory checking. +For example, checking for memory leaks when running the runtime test in the target language interpreter: +

    + +
    +make ret_by_value.ctest RUNTOOL="valgrind --leak-check=full"
    +
    + +

    +This will probably make more sense if you look at the output of the above as it will show the exact commands being executed. +SWIG can be analyzed for bad memory accesses using: +

    + +
    +make ret_by_value.ctest SWIGTOOL="valgrind --tool=memcheck --trace-children=yes"
    +
    + +

    +A debugger can also be invoked easily on an individual test, for example gdb: +

    + +
    +make ret_by_value.ctest RUNTOOL="gdb --args"
    +
    + +

    +SWIG reads the SWIG_FEATURES environment variable to obtain options in addition to those passed on the command line. +This is particularly useful as the entire test-suite or a particular testcase can be run customized by using additional +arguments, for example the -O optimization flag can be added in, as shown below for the bash shell: +

    + +
    +env SWIG_FEATURES=-O make check-python-test-suite
    +
    + +

    +The syntax for setting environment variables varies from one shell to the next, but it also works as shown in the example below, where some typemap debugging is added in: +

    + +
    +make ret_by_value.ctest SWIG_FEATURES="-debug-tmsearch"
    +
    + +

    38.10.13 Documentation

    @@ -3277,7 +3528,7 @@ Some topics that you'll want to be sure to address include: if available. -

    34.10.13 Prerequisites for adding a new language module to the SWIG distribution

    +

    38.10.14 Prerequisites for adding a new language module to the SWIG distribution

    @@ -3334,7 +3585,7 @@ should be added should there be an area not already covered by the existing tests.

    -

    34.10.14 Coding style guidelines

    +

    38.10.15 Coding style guidelines

    @@ -3358,13 +3609,34 @@ The generated C/C++ code should also follow this style as close as possible. How should be avoided as unlike the SWIG developers, users will never have consistent tab settings.

    -

    34.11 Typemaps

    +

    38.11 Debugging Options

    -

    34.11.1 Proxy classes

    +

    +There are various command line options which can aid debugging a SWIG interface as well as debugging the development of a language module. These are as follows: +

    +
    +-debug-classes    - Display information about the classes found in the interface
    +-debug-module <n> - Display module parse tree at stages 1-4, <n> is a csv list of stages
    +-debug-symtabs    - Display symbol tables information
    +-debug-symbols    - Display target language symbols in the symbol tables
    +-debug-csymbols   - Display C symbols in the symbol tables
    +-debug-lsymbols   - Display target language layer symbols
    +-debug-tags       - Display information about the tags found in the interface
    +-debug-template   - Display information for debugging templates
    +-debug-top <n>    - Display entire parse tree at stages 1-4, <n> is a csv list of stages
    +-debug-typedef    - Display information about the types and typedefs in the interface
    +-debug-typemap    - Display information for debugging typemaps
    +-debug-tmsearch   - Display typemap search debugging information
    +-debug-tmused     - Display typemaps used debugging information
    +
    -

    34.12 Guide to parse tree nodes

    +

    +The complete list of command line options for SWIG are available by running swig -help. +

    + +

    38.12 Guide to parse tree nodes

    @@ -3772,6 +4044,13 @@ extern "X" { ... } declaration.

  • +

    38.13 Further Development Information

    + + +

    +There is further documentation available on the internals of SWIG, API documentation and debugging information. +This is shipped with SWIG in the Doc/Devel directory. +

    diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html new file mode 100644 index 000000000..8abeada81 --- /dev/null +++ b/Doc/Manual/Go.html @@ -0,0 +1,635 @@ + + + +SWIG and Go + + + +

    22 SWIG and Go

    + + + + + + +

    +This chapter describes SWIG's support of Go. For more information on +the Go programming language +see golang.org. +

    + +

    22.1 Overview

    + + +

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

    + +

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

    + +

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

    + +

    22.2 Running SWIG with Go

    + + +

    +To generate Go code, use the -go option with SWIG. By +default SWIG will generate code for the gc compilers. To generate +code for gccgo, you should also use the -gccgo option. +

    + +

    22.2.1 Additional Commandline Options

    + + +

    +These are the command line options for SWIG's GO module. They can +also be seen by using: +

    + +
    +swig -go -help
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Go specific options
    -gccgoGenerate code for gccgo. The default is to generate code for + 6g/8g/5g.
    -gccgo-46Generate 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.
    -no-gccgo-46Turn off -gccgo-46, whether set by default or earlier + on the command line. +
    -package <name>Set the name of the Go package to <name>. The default + package name is the SWIG module name.
    -soname %lt;name%gt;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 -soname option passed to the linker.
    -go-prefix <prefix>When generating code for gccgo, set the prefix to use. This + corresponds to the -fgo-prefix option to gccgo.
    -long-type-size <s>Set the size for the C/C++ type long. This controls + whether long is converted to the Go type int32 + or int64. The <s> argument should be 32 or 64.
    + +

    22.2.2 Go Output Files

    + + +

    When generating Go code, SWIG will generate the following + files:

    + +
      +
    • +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. +
    • +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. +
    • +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. +
    • +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. +
    + +

    +A typical command sequence would look like this: +

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

    22.3 A tour of basic C/C++ wrapping

    + + +

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

    + +

    22.3.1 Go Package Name

    + + +

    +All Go source code lives in a package. The name of this package will +default to the name of the module from SWIG's %module +directive. You may override this by using SWIG's -package +command line option. +

    + +

    22.3.2 Go Names

    + + +

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

    + +

    +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 Get or Set will be prepended. +For example, if the C/C++ variable is called var, then SWIG +will define the functions GetVar and SetVar. If a +variable is declared as const, or if +SWIG's +%immutable directive is used for the variable, then only +the getter will be defined. +

    + +

    +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 New +followed by that name, and the destructor will be +named Delete followed by that name. +

    + +

    22.3.3 Go Constants

    + + +

    +C/C++ constants created via #define or the %constant +directive become Go constants, declared with a const +declaration. + +

    22.3.4 Go Enumerations

    + + +

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

    + +

    22.3.5 Go Classes

    + + +

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

    + +

    +For a C++ class ClassName, 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 ClassName. SWIG will define a +function NewClassName which will take any constructor +arguments and return a value of the interface +type ClassName. SWIG will also define a +destructor DeleteClassName. +

    + +

    +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 val.MethodName syntax. Public members of the C++ class +will be given getter and setter functions defined as methods of the +class. +

    + +

    +SWIG will represent static methods of C++ classes as ordinary Go +functions. SWIG will use names like ClassNameMethodName. +SWIG will give static members getter and setter functions with names +like GetClassName_VarName. +

    + +

    +Given a value of the interface type, Go code can retrieve the pointer +to the C++ type by calling the Swigcptr method. This will +return a value of type SwigcptrClassName, which is just a +name for uintptr. 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 reinterpret_cast. This should only be used for very +special cases, such as where C++ would use a dynamic_cast. +

    + +

    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:

    +
    +
    +class MyClass {
    +  int MyMethod();
    +  static MyClass *MyFactoryFunction();
    +};
    +
    +
    +
    +

    You will get go code that looks like this:

    +
    +
    +type MyClass interface {
    +  Swigcptr() uintptr
    +  SwigIsMyClass()
    +  MyMethod() int
    +}
    +
    +MyClassMyFactoryFunction() MyClass {
    +  // swig magic here
    +}
    +
    +
    +

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

    + +

    22.3.5.1 Go Class Inheritance

    + + +

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

    + +

    22.3.6 Go Templates

    + + +

    +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 %template directive. + +

    22.3.7 Go Director Classes

    + + +

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

    + +

    +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 NewDirectorClassName, +where ClassName is the name of the C++ class. That will +return a value of type ClassName. +

    + +

    +For example: +

    + +
    +
    +type GoClass struct { }
    +func (p *GoClass) VirtualFunction() { }
    +func MakeClass() ClassName {
    +	return NewDirectorClassName(&GoClass{})
    +}
    +
    +
    + +

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

    + +

    22.3.8 Default Go primitive type mappings

    + + +

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

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    C/C++ typeGo type
    boolbool
    charbyte
    signed charint8
    unsigned charbyte
    shortint16
    unsigned shortuint16
    intint
    unsigned intuint
    longint32 or int64, depending on -long-type-size
    unsigned longuint32 or uint64, depending on -long-type-size
    long longint64
    unsigned long longuint64
    floatfloat32
    doublefloat64
    char *
    char []
    string
    + +

    +Note that SWIG wraps the C char type as a character. Pointers +and arrays of this type are wrapped as strings. The signed +char type can be used if you want to treat char 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. +

    + +

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

    + +

    22.3.9 Output arguments

    + + +

    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.

    + +

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

    +
    +
    +double modf(double x, double *ip);
    +
    +
    +

    You could wrap it with SWIG as follows:

    +
    +
    +%include <typemaps.i>
    +double modf(double x, double *OUTPUT);
    +
    +
    +

    or you can use the %apply directive:

    +
    +
    +%include <typemaps.i>
    +%apply double *OUTPUT { double *ip };
    +double modf(double x, double *ip);
    +
    +
    +

    In Go you would use it like this:

    +
    +
    +ptr := []float64{0.0}
    +fraction := modulename.Modf(5.0, ptr)
    +
    +
    +

    Since this is ugly, you may want to wrap the swig-generated API with +some additional functions written in go that +hide the ugly details.

    + +

    There are no char *OUTPUT typemaps. However you can +apply the signed char * typemaps instead:

    +
    +
    +%include <typemaps.i>
    +%apply signed char *OUTPUT {char *output};
    +void f(char *output);
    +
    +
    + +

    22.3.10 Adding additional go code

    + + +

    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 %insert(go_wrapper), like this:

    +
    +
    +%include <typemaps.i>
    +// 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
    +}
    +
    +%}
    +
    +
    + +

    For classes, since swig generates an interface, you can add additional +methods by defining another interface that includes the swig-generated +interface. For example,

    +
    +
    +%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
    +}
    +
    +%}
    +
    +
    +

    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.

    + +

    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.

    + + diff --git a/Doc/Manual/Guile.html b/Doc/Manual/Guile.html index 20ab716e4..6f1300492 100644 --- a/Doc/Manual/Guile.html +++ b/Doc/Manual/Guile.html @@ -8,7 +8,7 @@ -

    19 SWIG and Guile

    +

    23 SWIG and Guile

      @@ -47,7 +47,7 @@

      This section details guile-specific support in SWIG. -

      19.1 Meaning of "Module"

      +

      23.1 Meaning of "Module"

      @@ -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". -

      19.2 Using the SCM or GH Guile API

      +

      23.2 Using the SCM or GH Guile API

      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.

      The GH interface to guile is deprecated. Read more about why in the -Guile manual. +Guile manual. 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.

      -

      19.3 Linkage

      +

      23.3 Linkage

      @@ -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 linkage. -

      19.3.1 Simple Linkage

      +

      23.3.1 Simple Linkage

      @@ -206,7 +206,7 @@ placed between the define-module form and the SWIG_init via a preprocessor define to avoid symbol clashes. For this case, however, passive linkage is available. -

      19.3.2 Passive Linkage

      +

      23.3.2 Passive Linkage

      Passive linkage is just like simple linkage, but it generates an @@ -216,7 +216,7 @@ package name (see below).

      You should use passive linkage rather than simple linkage when you are using multiple modules. -

      19.3.3 Native Guile Module Linkage

      +

      23.3.3 Native Guile Module Linkage

      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:

    -

    19.3.4 Old Auto-Loading Guile Module Linkage

    +

    23.3.4 Old Auto-Loading Guile Module Linkage

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

    19.3.5 Hobbit4D Linkage

    +

    23.3.5 Hobbit4D Linkage

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

    -

    19.4 Underscore Folding

    +

    23.4 Underscore Folding

    @@ -320,7 +320,7 @@ complained so far. %rename to specify the Guile name of the wrapped functions and variables (see CHANGES). -

    19.5 Typemaps

    +

    23.5 Typemaps

    @@ -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 -Features and the %feature directive +Features and the %feature directive for info on how to apply the %feature.

    -

    19.6 Representation of pointers as smobs

    +

    23.6 Representation of pointers as smobs

    @@ -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 SWIG_ConvertPtr(), passing a pointer to a struct representing the expected pointer type. See also -The run-time type checker. +The run-time type checker. If the Scheme object passed was not a SWIG smob representing a compatible pointer, a wrong-type-arg exception is raised. -

    19.6.1 GH Smobs

    +

    23.6.1 GH Smobs

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

    -

    19.6.2 SCM Smobs

    +

    23.6.2 SCM Smobs

    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.

    -

    19.6.3 Garbage Collection

    +

    23.6.3 Garbage Collection

    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 +is exactly like described in Object ownership and %newobject in the SWIG manual. All typemaps use an $owner var, and the guile module replaces $owner with 0 or 1 depending on feature:new.

    -

    19.7 Exception Handling

    +

    23.7 Exception Handling

    @@ -517,7 +517,7 @@ mapping: The default when not specified here is to use "swig-error". See Lib/exception.i for details. -

    19.8 Procedure documentation

    +

    23.8 Procedure documentation

    If invoked with the command-line option -procdoc @@ -553,7 +553,7 @@ like this: typemap argument doc. See Lib/guile/typemaps.i for details. -

    19.9 Procedures with setters

    +

    23.9 Procedures with setters

    For global variables, SWIG creates a single wrapper procedure @@ -581,7 +581,7 @@ struct members, the procedures (struct-member-get pointer) and (struct-member-set pointer value) are not generated. -

    19.10 GOOPS Proxy Classes

    +

    23.10 GOOPS Proxy Classes

    SWIG can also generate classes and generic functions for use with @@ -730,7 +730,7 @@ Notice that <Foo> is used before it is defined. The fix is to just put th %import "foo.h" before the %inline block.

    -

    19.10.1 Naming Issues

    +

    23.10.1 Naming Issues

    As you can see in the example above, there are potential naming conflicts. The default exported @@ -767,9 +767,7 @@ guile-modules. For example,

    (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:))) -

    TODO: Renaming class name prefixes?

    - -

    19.10.2 Linking

    +

    23.10.2 Linking

    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 Module-primitive.scm (with primitive replaced with whatever is given with the -primsuffix argument. The code to load the .so library should be located in the %scheme directive, which will then be added to the scmstub file. -Swig will automatically generate the line (use-modules (Package Module-primitive)) +SWIG will automatically generate the line (use-modules (Package Module-primitive)) into the GOOPS guile-module. So if Module-primitive.scm is on the autoload path for guile, the %goops directive can be empty. Otherwise, the %goops directive should contain whatever code is needed to load the Module-primitive.scm file into guile.

    @@ -848,7 +846,7 @@ Produces the following code at the top of the generated GOOPS guile-module
  • Module Linkage: This is very similar to passive linkage with a scmstub file. -Swig will also automatically generate the line (use-modules +SWIG will also automatically generate the line (use-modules (Package Module-primitive)) into the GOOPS guile-module. Again the %goops directive should contain whatever code is needed to get that module loaded into guile.

    diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html index 491204d1d..a8d15a5c2 100644 --- a/Doc/Manual/Introduction.html +++ b/Doc/Manual/Introduction.html @@ -37,7 +37,7 @@

    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.

    2.2 Why use SWIG?

    @@ -194,9 +195,9 @@ extern int my_mod(int n, int m);

    The interface file contains ANSI C function prototypes and variable declarations. The %module directive defines the name of the -module that will be created by SWIG. The %{,%} 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 %{ %} block +provides a location for inserting additional code, such as C header +files or additional C declarations, into the generated C wrapper code.

    2.3.2 The swig command

    @@ -334,7 +335,7 @@ major features include:

    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.

    @@ -365,20 +366,20 @@ possible to support different types of interfaces depending on the application.

    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.

    If you are using the GNU Autotools -(Autoconf/ -Automake/ -Libtool) +(Autoconf/ +Automake/ +Libtool) to configure SWIG use in your project, the SWIG Autoconf macros can be used. -The primary macro is ac_pkg_swig, see -http://www.gnu.org/software/ac-archive/htmldoc/ac_pkg_swig.html. -The ac_python_devel macro is also helpful for generating Python extensions. See the -Autoconf Macro Archive +The primary macro is ax_pkg_swig, see +http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig. +The ax_python_devel macro is also helpful for generating Python extensions. See the +Autoconf Archive for further information on this and other Autoconf macros.

    @@ -414,7 +415,8 @@ SWIG_LINK_LIBRARIES(example ${PYTHON_LIBRARIES})

    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.

    2.7 Hands off code generation

    diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index 88963caf5..76e147be5 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -5,142 +5,144 @@ -

    20 SWIG and Java

    +

    24 SWIG and Java

    @@ -153,7 +155,7 @@ It covers most SWIG features, but certain low-level details are covered in less

    -

    20.1 Overview

    +

    24.1 Overview

    @@ -165,7 +167,7 @@ SWIG wraps C/C++ code using Java proxy classes and is very useful if you want to If only one or two JNI functions are needed then using SWIG may be overkill. SWIG enables a Java program to easily call into C/C++ code from Java. Historically, SWIG was not able to generate any code to call into Java code from C++. -However, SWIG now supports full cross language polymorphism and code is generated to call up from C++ to Java when wrapping C++ virtual methods. +However, SWIG now supports full cross language polymorphism and code is generated to call up from C++ to Java when wrapping C++ virtual methods via the director feature.

    @@ -180,7 +182,7 @@ However, the "SWIG Basics" chapter will be a useful

    This chapter starts with a few practicalities on running SWIG and compiling the generated code. If you are looking for the minimum amount to read, have a look at the sections up to and including the -tour of basic C/C++ wrapping section which explains how to call the various C/C++ code constructs from Java. +tour of basic C/C++ wrapping section which explains how to call the various C/C++ code constructs from Java. Following this section are details of the C/C++ code and Java classes that SWIG generates. Due to the complexities of C and C++ there are different ways in which C/C++ code could be wrapped and called from Java. SWIG is a powerful tool and the rest of the chapter details how the default code wrapping can be tailored. @@ -188,7 +190,7 @@ Various customisation tips and techniques using SWIG directives are covered. The latter sections cover the advanced techniques of using typemaps for complete control of the wrapping process.

    -

    20.2 Preliminaries

    +

    24.2 Preliminaries

    @@ -204,7 +206,11 @@ Run make -k check from the SWIG root directory after installing SWIG on The Java module requires your system to support shared libraries and dynamic loading. This is the commonly used method to load JNI code so your system will more than likely support this.

    -

    20.2.1 Running SWIG

    +

    +Android uses Java JNI and also works with SWIG. Please read the Android chapter in conjunction with this one if you are targeting Android. +

    + +

    24.2.1 Running SWIG

    @@ -249,7 +255,13 @@ rest of your C/C++ application. The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. -It is also possible to change the output directory that the Java files are generated into using -outdir. +It is also possible to change the output directory that the Java files are generated into using -outdir. +

    + +

    +The module name, specified with %module, determines the name of various generated classes as discussed later. +Note that the module name does not define a Java package and by default, the generated Java classes do not have a Java package. +The -package option described below can specify a Java package name to use.

    @@ -257,7 +269,7 @@ The following sections have further practical examples and details on how you mi compiling and using the generated files.

    -

    20.2.2 Additional Commandline Options

    +

    24.2.2 Additional Commandline Options

    @@ -294,7 +306,7 @@ swig -java -help Their use will become clearer by the time you have finished reading this section on SWIG and Java.

    -

    20.2.3 Getting the right header files

    +

    24.2.3 Getting the right header files

    @@ -309,7 +321,7 @@ They are usually in directories like this:

    The exact location may vary on your machine, but the above locations are typical.

    -

    20.2.4 Compiling a dynamic module

    +

    24.2.4 Compiling a dynamic module

    @@ -337,26 +349,26 @@ is a useful reference for compiling on different platforms.

    Important
    If you are going to use optimisations turned on with gcc (for example -O2), ensure you also compile with -fno-strict-aliasing. The GCC optimisations have become -more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the C/C++ to Java typemaps section for more details. +more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on. See the C/C++ to Java typemaps section for more details.

    The name of the shared library output file is important. -If the name of your SWIG module is "example", the name of the corresponding shared library file should be "libexample.so" (or equivalent depending on your machine, see Dynamic linking problems for more information). +If the name of your SWIG module is "example", the name of the corresponding shared library file should be "libexample.so" (or equivalent depending on your machine, see Dynamic linking problems for more information). The name of the module is specified using the %module directive or -module command line option.

    -

    20.2.5 Using your module

    +

    24.2.5 Using your module

    To load your shared native library module in Java, simply use Java's System.loadLibrary method in a Java class:

    -// main.java
    +// runme.java
     
    -public class main {
    +public class runme {
       static {
    -    System.loadLibrary("example");
    +    System.loadLibrary("example");
       }
     
       public static void main(String argv[]) {
    @@ -371,7 +383,7 @@ Compile all the Java files and run:
     
     
     $ javac *.java
    -$ java main
    +$ java runme
     24
     $
     
    @@ -380,7 +392,7 @@ $ If it doesn't work have a look at the following section which discusses problems loading the shared library.

    -

    20.2.6 Dynamic linking problems

    +

    24.2.6 Dynamic linking problems

    @@ -393,12 +405,12 @@ You may get an exception similar to this:

    -$ java main
    +$ java runme
     Exception in thread "main" java.lang.UnsatisfiedLinkError: no example in java.library.path
             at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312)
             at java.lang.Runtime.loadLibrary0(Runtime.java:749)
             at java.lang.System.loadLibrary(System.java:820)
    -        at main.<clinit>(main.java:5)
    +        at runme.<clinit>(runme.java:5)
     

    @@ -425,7 +437,7 @@ The following exception is indicative of this:

    -$ java main
    +$ java runme
     Exception in thread "main" java.lang.UnsatisfiedLinkError: libexample.so: undefined
     symbol: fact
             at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    @@ -433,13 +445,26 @@ symbol: fact
             at java.lang.ClassLoader.loadLibrary(ClassLoader.java, Compiled Code)
             at java.lang.Runtime.loadLibrary0(Runtime.java, Compiled Code)
             at java.lang.System.loadLibrary(System.java, Compiled Code)
    -        at main.<clinit>(main.java:5)
    +        at runme.<clinit>(runme.java:5)
     $
     

    This error usually indicates that you forgot to include some object files or libraries in the linking of the native library file. Make sure you compile both the SWIG wrapper file and the code you are wrapping into the native library file. +If you forget to compile and link in the SWIG wrapper file into your native library file, you will get a message similar to the following: +

    + +
    +$ java runme
    +Exception in thread "main" java.lang.UnsatisfiedLinkError: exampleJNI.gcd(II)I
    +	at exampleJNI.gcd(Native Method)
    +	at example.gcd(example.java:12)
    +	at runme.main(runme.java:18)
    +
    + +

    +where gcd is the missing JNI function that SWIG generated into the wrapper file. Also make sure you pass all of the required libraries to the linker. The java -verbose:jni commandline switch is also a great way to get more information on unresolved symbols. One last piece of advice is to beware of the common faux pas of having more than one native library version in your path. @@ -454,7 +479,7 @@ The following section also contains some C++ specific linking problems and solut

    -

    20.2.7 Compilation problems and compiling with C++

    +

    24.2.7 Compilation problems and compiling with C++

    @@ -507,7 +532,7 @@ Finally make sure the version of JDK header files matches the version of Java th

    -

    20.2.8 Building on Windows

    +

    24.2.8 Building on Windows

    @@ -516,7 +541,7 @@ You will want to produce a DLL that can be loaded by the Java Virtual Machine. This section covers the process of using SWIG with Microsoft Visual C++ 6 although the procedure may be similar with other compilers. In order for everything to work, you will need to have a JDK installed on your machine in order to read the JNI header files.

    -

    20.2.8.1 Running SWIG from Visual Studio

    +

    24.2.8.1 Running SWIG from Visual Studio

    @@ -552,10 +577,10 @@ When doing a build, any changes made to the interface file will result in SWIG b

    The Java classes that SWIG output should also be compiled into .class files. To run the native code in the DLL (example.dll), make sure that it is in your path then run your Java program which uses it, as described in the previous section. -If the library fails to load have a look at Dynamic linking problems. +If the library fails to load have a look at Dynamic linking problems.

    -

    20.2.8.2 Using NMAKE

    +

    24.2.8.2 Using NMAKE

    @@ -614,7 +639,7 @@ Of course you may want to make changes for it to work for C++ by adding in the -

    -

    20.3 A tour of basic C/C++ wrapping

    +

    24.3 A tour of basic C/C++ wrapping

    @@ -624,7 +649,7 @@ variables are wrapped with JavaBean type getters and setters and so forth. This section briefly covers the essential aspects of this wrapping.

    -

    20.3.1 Modules, packages and generated Java classes

    +

    24.3.1 Modules, packages and generated Java classes

    @@ -656,9 +681,11 @@ This is often combined with the -outdir to specify a package directory swig -java -package com.bloggs.swig -outdir com/bloggs/swig example.i

    +

    SWIG won't create the directory, so make sure it exists beforehand. +

    -

    20.3.2 Functions

    +

    24.3.2 Functions

    @@ -692,7 +719,7 @@ System.out.println(example.fact(4)); -

    20.3.3 Global variables

    +

    24.3.3 Global variables

    @@ -779,7 +806,7 @@ extern char *path; // Read-only (due to %immutable) -

    20.3.4 Constants

    +

    24.3.4 Constants

    @@ -815,7 +842,7 @@ public interface exampleConstants { Note that SWIG has inferred the C type and used an appropriate Java type that will fit the range of all possible values for the C type. By default SWIG generates runtime constants. They are not compiler constants that can, for example, be used in a switch statement. This can be changed by using the %javaconst(flag) directive. It works like all -the other %feature directives. The default is %javaconst(0). +the other %feature directives. The default is %javaconst(0). It is possible to initialize all wrapped constants from pure Java code by placing a %javaconst(1) before SWIG parses the constants. Putting it at the top of your interface file would ensure this. Here is an example: @@ -919,7 +946,7 @@ Or if you decide this practice isn't so bad and your own class implements ex

    -

    20.3.5 Enumerations

    +

    24.3.5 Enumerations

    @@ -933,7 +960,7 @@ The final two approaches use simple integers for each enum item. Before looking at the various approaches for wrapping named C/C++ enums, anonymous enums are considered.

    -

    20.3.5.1 Anonymous enums

    +

    24.3.5.1 Anonymous enums

    @@ -996,7 +1023,7 @@ As in the case of constants, you can access them through either the module class

    -

    20.3.5.2 Typesafe enums

    +

    24.3.5.2 Typesafe enums

    @@ -1031,7 +1058,7 @@ public final class Beverage {

    -See Typesafe enum classes to see the omitted support methods. +See Typesafe enum classes to see the omitted support methods. Note that the enum item with an initializer (LAGER) is initialized with the enum value obtained via a JNI call. However, as with anonymous enums and constants, use of the %javaconst directive is strongly recommended to change this behaviour:

    @@ -1072,10 +1099,11 @@ C++ enums defined within a C++ class are generated into a static final inner Jav

    -Typesafe enums have their advantages over using plain integers in that they they can be used in a typesafe manner. +Typesafe enums have their advantages over using plain integers in that they can be used in a typesafe manner. However, there are limitations. For example, they cannot be used in switch statements and serialization is an issue. Please look at the following references for further information: + http://java.sun.com/developer/Books/shiftintojava/page1.html#replaceenums Replace Enums with Classes in Effective Java Programming on the Sun website, Create enumerated constants in Java JavaWorld article, Java Tip 133: More on typesafe enums and @@ -1089,7 +1117,7 @@ When upgrading to JDK 1.5 or later, proper Java enums could be used instead, wit The following section details proper Java enum generation.

    -

    20.3.5.3 Proper Java enums

    +

    24.3.5.3 Proper Java enums

    @@ -1130,19 +1158,19 @@ public enum Beverage {

    -See Proper Java enum classes to see the omitted support methods. +See Proper Java enum classes to see the omitted support methods. The generated Java enum has numerous additional methods to support enums with initializers, such as LAGER above. Note that as with the typesafe enum pattern, enum items with initializers are by default initialized with the enum value obtained via a JNI call. However, this is not the case above as we have used the recommended %javaconst(1) to avoid the JNI call. -The %javaconstvalue(value) directive covered in the Constants section can also be used for proper Java enums. +The %javaconstvalue(value) directive covered in the Constants section can also be used for proper Java enums.

    The additional support methods need not be generated if none of the enum items have initializers and this is covered later in the -Simpler Java enums for enums without initializers section. +Simpler Java enums for enums without initializers section.

    -

    20.3.5.4 Type unsafe enums

    +

    24.3.5.4 Type unsafe enums

    @@ -1180,7 +1208,7 @@ public final class Beverage {

    As is the case previously, the default is %javaconst(0) as not all C/C++ values will compile as Java code. However, again it is recommended to add in a %javaconst(1) directive. -and the %javaconstvalue(value) directive covered in the Constants section can also be used for type unsafe enums. +and the %javaconstvalue(value) directive covered in the Constants section can also be used for type unsafe enums. Note that global enums are generated into a Java class within whatever package you are using. C++ enums defined within a C++ class are generated into a static final inner Java class within the Java proxy class.

    @@ -1190,7 +1218,7 @@ Note that unlike typesafe enums, this approach requires users to mostly use diff Thus the upgrade path to proper enums provided in JDK 1.5 is more painful.

    -

    20.3.5.5 Simple enums

    +

    24.3.5.5 Simple enums

    @@ -1199,7 +1227,7 @@ Each enum item is also wrapped as a static final integer. However, these integers are not generated into a class named after the C/C++ enum. Instead, global enums are generated into the constants interface. Also, enums defined in a C++ class have their enum items generated directly into the Java proxy class rather than an inner class within the Java proxy class. -In fact, this approach is effectively wrapping the enums as if they were anonymous enums and the resulting code is as per anonymous enums. +In fact, this approach is effectively wrapping the enums as if they were anonymous enums and the resulting code is as per anonymous enums. The implementation is in the "enumsimple.swg" file.

    @@ -1209,7 +1237,7 @@ SWIG-1.3.21 and earlier versions wrapped all enums using this approach. The type unsafe approach is preferable to this one and this simple approach is only included for backwards compatibility with these earlier versions of SWIG.

    -

    20.3.6 Pointers

    +

    24.3.6 Pointers

    @@ -1297,7 +1325,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return a NULL pointer if the conversion can't be performed.

    -

    20.3.7 Structures

    +

    24.3.7 Structures

    @@ -1406,8 +1434,8 @@ to by b.x. In this example, 16 integers would be copied. Like C, SWI no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation fault or access violation. The default wrapping makes it hard to set or get just one element of the array and so array access from Java is somewhat limited. -This can be changed easily though by using the approach outlined later in the Wrapping C arrays with Java arrays and -Unbounded C Arrays sections. +This can be changed easily though by using the approach outlined later in the Wrapping C arrays with Java arrays and +Unbounded C Arrays sections.

    @@ -1465,7 +1493,7 @@ x.setA(3); // Modify x.a - this is the same as b.f.a -

    20.3.8 C++ classes

    +

    24.3.8 C++ classes

    @@ -1528,7 +1556,7 @@ int bar = Spam.getBar(); -

    20.3.9 C++ inheritance

    +

    24.3.9 C++ inheritance

    @@ -1589,7 +1617,7 @@ Note that Java does not support multiple inheritance so any multiple inheritance A warning is given when multiple inheritance is detected and only the first base class is used.

    -

    20.3.10 Pointers, references, arrays and pass by value

    +

    24.3.10 Pointers, references, arrays and pass by value

    @@ -1644,7 +1672,7 @@ to hold the result and a pointer is returned (Java will release this memory when the returned object's finalizer is run by the garbage collector).

    -

    20.3.10.1 Null pointers

    +

    24.3.10.1 Null pointers

    @@ -1668,7 +1696,7 @@ For spam1 and spam4 above the Java null gets translat The converse also occurs, that is, NULL pointers are translated into null Java objects when returned from a C/C++ function.

    -

    20.3.11 C++ overloaded functions

    +

    24.3.11 C++ overloaded functions

    @@ -1752,7 +1780,7 @@ If declarations such as these appear, you will get a warning message like this:

    -example.i:12: Warning(515): Overloaded method spam(unsigned short) ignored.
    +example.i:12: Warning 515: Overloaded method spam(unsigned short) ignored.
     Method spam(int) at example.i:11 used.
     
    @@ -1783,7 +1811,7 @@ void spam(unsigned short); // Ignored -

    20.3.12 C++ default arguments

    +

    24.3.12 C++ default arguments

    @@ -1826,11 +1854,13 @@ Further details on default arguments and how to restore this approach are given

    -

    20.3.13 C++ namespaces

    +

    24.3.13 C++ namespaces

    -SWIG is aware of C++ namespaces, but namespace names do not appear in +SWIG is aware of named C++ namespaces and they can be mapped to Java packages, however, +the default wrapping flattens the namespaces, effectively ignoring them. +So by default, the namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

    @@ -1886,7 +1916,30 @@ symbols separate, consider wrapping them as separate SWIG modules. Each SWIG module can be placed into a separate package.

    -

    20.3.14 C++ templates

    +

    +The default behaviour described above can be improved via the nspace feature. +Note that it only works for classes, structs, unions and enums declared within a named C++ namespace. +When the nspace feature is used, the C++ namespaces are converted into Java packages of the same name. +Proxy classes are thus declared within a package and this proxy makes numerous calls to the JNI intermediary class which is declared in the unnamed package by default. +As Java does not support types declared in a named package accessing types declared in an unnamed package, the -package commandline option described earlier must be used to provide a parent package. +So if SWIG is run using the -package com.myco option, a wrapped class, MyWorld::Material::Color, can then be accessed as com.myco.MyWorld.Material.Color. If you don't specify a package, you will get the following error message: +

    + +
    +
    +example.i:16: Error: The nspace feature used on 'MyWorld::Material::Color' is not supported unless
    +a package is specified
    +with -package - Java does not support types declared in a named package accessing types declared
    +in an unnamed package.
    +
    +
    + +

    +If the resulting use of the nspace feature and hence packages results in a proxy class in one package deriving or using a proxy class from another package, +you will need to open up the visibility for the pointer constructor and getCPtr method from the default 'protected' to 'public' with the SWIG_JAVABODY_PROXY macro. See Java code typemaps. +

    + +

    24.3.14 C++ templates

    @@ -1935,7 +1988,7 @@ Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter.

    -

    20.3.15 C++ Smart Pointers

    +

    24.3.15 C++ Smart Pointers

    @@ -2019,7 +2072,7 @@ Foo f = p.__deref__(); // Returns underlying Foo * -

    20.4 Further details on the generated Java classes

    +

    24.4 Further details on the generated Java classes

    @@ -2034,7 +2087,7 @@ Finally enum classes are covered. First, the crucial intermediary JNI class is considered.

    -

    20.4.1 The intermediary JNI class

    +

    24.4.1 The intermediary JNI class

    @@ -2121,7 +2174,7 @@ class exampleJNI {

    This class contains the complete Java - C/C++ interface so all function calls go via this class. -As this class acts as a go-between for all JNI calls to C/C++ code from the Java proxy classes, type wrapper classes and module class, it is known as the intermediary JNI class. +As this class acts as a go-between for all JNI calls to C/C++ code from the Java proxy classes, type wrapper classes and module class, it is known as the intermediary JNI class.

    @@ -2130,14 +2183,14 @@ This approach leads to minimal JNI code which makes for better performance as JN SWIG favours generating Java code over JNI code as Java code is compiled into byte code and avoids the costly string operations needed in JNI code. This approach has a downside though as the proxy class might get collected before the native method has completed. You might notice above that there is an additional parameters with a underscore postfix, eg jarg1_. -These are added in order to prevent premature garbage collection when marshalling proxy classes. +These are added in order to prevent premature garbage collection when marshalling proxy classes.

    The functions in the intermediary JNI class cannot be accessed outside of its package. Access to them is gained through the module class for globals otherwise the appropriate proxy class.

    - +

    The name of the intermediary JNI class can be changed from its default, that is, the module name with JNI appended after it. The module directive attribute jniclassname is used to achieve this: @@ -2154,7 +2207,7 @@ If name is the same as modulename then the module class name g from modulename to modulenameModule.

    -

    20.4.1.1 The intermediary JNI class pragmas

    +

    24.4.1.1 The intermediary JNI class pragmas

    @@ -2220,20 +2273,20 @@ The jniclasscode pragma is quite useful for adding in a static block fo

    Pragmas will take either "" or %{ %} as delimiters. -For example, let's change the intermediary JNI class access to public. +For example, let's change the intermediary JNI class access to just the default package-private access.

    -%pragma(java) jniclassclassmodifiers="public class"
    +%pragma(java) jniclassclassmodifiers="class"
     

    -All the methods in the intermediary JNI class will then be callable outside of the package as the method modifiers are public by default. +All the methods in the intermediary JNI class will then not be callable outside of the package as the method modifiers have been changed from public access to default access. This is useful if you want to prevent users calling these low level functions.

    -

    20.4.2 The Java module class

    +

    24.4.2 The Java module class

    @@ -2264,7 +2317,7 @@ example.egg(new Foo()); The primary reason for having the module class wrapping the calls in the intermediary JNI class is to implement static type checking. In this case only a Foo can be passed to the egg function, whereas any long can be passed to the egg function in the intermediary JNI class.

    -

    20.4.2.1 The Java module class pragmas

    +

    24.4.2.1 The Java module class pragmas

    @@ -2311,16 +2364,16 @@ The pragma code appears in the generated module class like this:

    -See The intermediary JNI class pragmas section for further details on using pragmas. +See The intermediary JNI class pragmas section for further details on using pragmas.

    -

    20.4.3 Java proxy classes

    +

    24.4.3 Java proxy classes

    A Java proxy class is generated for each structure, union or C++ class that is wrapped. -Proxy classes have also been called peer classes. +Proxy classes have also been called peer classes. The default proxy class for our previous example looks like this:

    @@ -2391,7 +2444,7 @@ int y = f.spam(5, new Foo()); -

    20.4.3.1 Memory management

    +

    24.4.3.1 Memory management

    @@ -2485,7 +2538,7 @@ you're lucky, you will only get a segmentation fault. To work around this, the ownership flag of o needs changing to false. The ownership flag is a private member variable of the proxy class so this is not possible without some customization of the proxy class. This can be achieved by using a typemap to customise the proxy class with pure Java code as detailed later in the section on -Java typemaps. +Java typemaps.

    @@ -2547,13 +2600,13 @@ Obj obj = Factory.createObj(); // obj.swigCMemOwn = true; Some memory management issues are quite tricky to fix and may only be noticeable after using for a long time. One such issue is premature garbage collection of an object created from Java and resultant usage from C++ code. The section on typemap examples cover two such scenarios, -Memory management for objects passed to the C++ layer +Memory management for objects passed to the C++ layer and -Memory management when returning references to member variables +Memory management when returning references to member variables

    -

    20.4.3.2 Inheritance

    +

    24.4.3.2 Inheritance

    @@ -2665,11 +2718,11 @@ This is a necessity as C++ compilers are free to implement pointers in the inher It is of course possible to extend Base using your own Java classes. If Derived is provided by the C++ code, you could for example add in a pure Java class Extended derived from Base. There is a caveat and that is any C++ code will not know about your pure Java class Extended so this type of derivation is restricted. -However, true cross language polymorphism can be achieved using the directors feature. +However, true cross language polymorphism can be achieved using the directors feature.

    -

    20.4.3.3 Proxy classes and garbage collection

    +

    24.4.3.3 Proxy classes and garbage collection

    @@ -2702,7 +2755,7 @@ Call the System.runFinalizersOnExit(true) or Runtime.getRuntime().r This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.

    In many cases you will be lucky and find that it works, but it is not to be advocated. -Have a look at Sun's Java web site and search for runFinalizersOnExit. +Have a look at Java web site and search for runFinalizersOnExit.

  • @@ -2718,7 +2771,7 @@ You can encourage the garbage collector to call the finalizers, for example, add }

    Although this usually works, the documentation doesn't guarantee that runFinalization() will actually call the finalizers. -As the the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.

    +As the shutdown hook is guaranteed you could also make a JNI call to clean up any resources that are being tracked by the C/C++ code.

  • @@ -2743,7 +2796,7 @@ The SWIG generated code ensures that the memory is not deleted twice, in the eve

    Write your own object manager in Java. You could derive all SWIG classes from a single base class which could track which objects have had their finalizers run, then call the rest of them on program termination. -The section on Java typemaps details how to specify a pure Java base class. +The section on Java typemaps details how to specify a pure Java base class.

  • @@ -2752,7 +2805,7 @@ The section on Java typemaps details how to specify See the How to Handle Java Finalization's Memory-Retention Issues article for alternative approaches to managing memory by avoiding finalizers altogether.

    -

    20.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling

    +

    24.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling

    @@ -2856,8 +2909,12 @@ and therefore there is no possibility of premature garbage collection. In practi

    The premature garbage collection prevention parameter for proxy classes is generated by default whenever proxy classes are passed by value, reference or with a pointer. -The additional parameters do impose a slight performance overhead and the parameter generation can be suppressed globally with the -nopgcpp commandline option. -More selective suppression is possible with the 'nopgcpp' attribute in the "jtype" Java typemap. +The implementation for this extra parameter generation requires the "jtype" typemap to contain long and the "jstype" typemap to contain the name of a proxy class. +

    + +

    +The additional parameter does impose a slight performance overhead and the parameter generation can be suppressed globally with the -nopgcpp commandline option. +More selective suppression is possible with the 'nopgcpp' attribute in the "jtype" Java typemap. The attribute is a flag and so should be set to "1" to enable the suppression, or it can be omitted or set to "0" to disable. For example:

    @@ -2870,7 +2927,7 @@ For example: Compatibility note: The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.

    -

    20.4.3.5 Single threaded applications and thread safety

    +

    24.4.3.5 Single threaded applications and thread safety

    @@ -2958,7 +3015,7 @@ for (int i=0; i<100000; i++) { -

    20.4.4 Type wrapper classes

    +

    24.4.4 Type wrapper classes

    @@ -2987,7 +3044,7 @@ public class SWIGTYPE_p_int { The methods do not have public access, so by default it is impossible to do anything with objects of this class other than pass them around. The methods in the class are part of the inner workings of SWIG. If you need to mess around with pointers you will have to use some typemaps specific to the Java module to achieve this. -The section on Java typemaps details how to modify the generated code. +The section on Java typemaps details how to modify the generated code.

    @@ -3045,16 +3102,16 @@ public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... } -

    20.4.5 Enum classes

    +

    24.4.5 Enum classes

    SWIG can generate three types of enum classes. -The Enumerations section discussed these but omitted all the details. +The Enumerations section discussed these but omitted all the details. The following sub-sections detail the various types of enum classes that can be generated.

    -

    20.4.5.1 Typesafe enum classes

    +

    24.4.5.1 Typesafe enum classes

    @@ -3138,7 +3195,7 @@ The swigValue method is used for marshalling in the other direction. The toString method is overridden so that the enum name is available.

    -

    20.4.5.2 Proper Java enum classes

    +

    24.4.5.2 Proper Java enum classes

    @@ -3213,10 +3270,10 @@ The next variable is in the SwigNext inner class rather than i Marshalling between Java enums and the C/C++ enum integer value is handled via the swigToEnum and swigValue methods. All the constructors and methods in the Java enum are required just to handle C/C++ enums with initializers. These needn't be generated if the enum being wrapped does not have any initializers and the -Simpler Java enums for enums without initializers section describes how typemaps can be used to achieve this. +Simpler Java enums for enums without initializers section describes how typemaps can be used to achieve this.

    -

    20.4.5.3 Type unsafe enum classes

    +

    24.4.5.3 Type unsafe enum classes

    @@ -3247,7 +3304,7 @@ public final class Beverage { -

    20.5 Cross language polymorphism using directors

    +

    24.5 Cross language polymorphism using directors

    @@ -3269,7 +3326,7 @@ The upshot is that C++ classes can be extended in Java and from C++ these extens Neither C++ code nor Java code needs to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions transparently takes care of all the cross-language method routing.

    -

    20.5.1 Enabling directors

    +

    24.5.1 Enabling directors

    @@ -3340,7 +3397,7 @@ public: -

    20.5.2 Director classes

    +

    24.5.2 Director classes

    @@ -3367,7 +3424,7 @@ If the correct implementation is in Java, the Java API is used to call the metho

    -

    20.5.3 Overhead and code bloat

    +

    24.5.3 Overhead and code bloat

    @@ -3385,7 +3442,7 @@ This situation can be optimized by selectively enabling director methods (using

    -

    20.5.4 Simple directors example

    +

    24.5.4 Simple directors example

    @@ -3413,7 +3470,7 @@ void callup(DirectorBase *director) {

    The following DirectorDerived Java class is derived from the Java proxy class DirectorBase and overrides upcall_method(). When C++ code invokes upcall_method(), the SWIG-generated C++ code redirects the call via JNI to the Java DirectorDerived subclass. -Naturally, the SWIG generated C++ code and the generated Java intermediate class marshal and convert arguments between C++ and Java when needed. +Naturally, the SWIG generated C++ code and the generated Java intermediary class marshal and convert arguments between C++ and Java when needed.

    @@ -3450,7 +3507,27 @@ DirectorDerived::upcall_method() invoked.
    -

    20.6 Accessing protected members

    +

    24.5.5 Director threading issues

    + + +

    +Depending on your operating system and version of Java and how you are using threads, you might find the JVM hangs on exit. +There are a couple of solutions to try out. The preferred solution requires jdk-1.4 and later and uses AttachCurrentThreadAsDaemon instead of AttachCurrentThread whenever a call into the JVM is required. This can be enabled by defining the SWIG_JAVA_ATTACH_CURRENT_THREAD_AS_DAEMON macro when compiling the C++ wrapper code. For older JVMs define SWIG_JAVA_NO_DETACH_CURRENT_THREAD instead, to avoid the DetachCurrentThread call but this will result in a memory leak instead. For further details inspect the source code in the java/director.swg library file. +

    + +

    +Macros can be defined on the commandline when compiling your C++ code, or alternatively added to the C++ wrapper file as shown below: +

    + +
    +
    +%insert("runtime") %{
    +#define SWIG_JAVA_NO_DETACH_CURRENT_THREAD
    +%}
    +
    +
    + +

    24.6 Accessing protected members

    @@ -3546,7 +3623,7 @@ class MyProtectedBase extends ProtectedBase -

    20.7 Common customization features

    +

    24.7 Common customization features

    @@ -3558,7 +3635,7 @@ be awkward. This section describes some common SWIG features that are used to improve the interface to existing C/C++ code.

    -

    20.7.1 C/C++ helper functions

    +

    24.7.1 C/C++ helper functions

    @@ -3624,7 +3701,7 @@ hard to implement. It is possible to improve on this using Java code, typemaps, customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.

    -

    20.7.2 Class extension with %extend

    +

    24.7.2 Class extension with %extend

    @@ -3687,14 +3764,14 @@ Vector(2,3,4) in any way---the extensions only show up in the Java interface.

    -

    20.7.3 Exception handling with %exception and %javaexception

    +

    24.7.3 Exception handling with %exception and %javaexception

    If a C or C++ function throws an error, you may want to convert that error into a Java exception. To do this, you can use the %exception directive. The %exception directive simply lets you rewrite part of the generated wrapper code to include an error check. -It is detailed in full in the Exception handling with %exception section. +It is detailed in full in the Exception handling with %exception section.

    @@ -3735,7 +3812,7 @@ will produce a familiar looking Java exception: Exception in thread "main" java.lang.OutOfMemoryError: Not enough memory at exampleJNI.malloc(Native Method) at example.malloc(example.java:16) - at main.main(main.java:112) + at runme.main(runme.java:112) @@ -3764,7 +3841,7 @@ The $action is a SWIG special variable and is replaced by the C/C++ f The return $null; handles all native method return types, namely those that have a void return and those that do not. This is useful for typemaps that will be used in native method returning all return types. See the section on -Java special variables for further explanation. +Java special variables for further explanation.

    @@ -3795,7 +3872,9 @@ public: In the example above, java.lang.Exception is a checked exception class and so ought to be declared in the throws clause of getitem. Classes can be specified for adding to the throws clause using %javaexception(classes) instead of %exception, where classes is a string containing one or more comma separated Java classes. -The %nojavaexception feature is the equivalent to %noexception and clears previously declared exception handlers. +The %clearjavaexception feature is the equivalent to %clearexception and clears previously declared exception handlers. +The %nojavaexception feature is the equivalent to %noexception and disables the exception handler. +See Clearing features for the difference on disabling and clearing features.

    @@ -3835,16 +3914,16 @@ public class FooClass {

    The examples above first use the C JNI calling syntax then the C++ JNI calling syntax. The C++ calling syntax will not compile as C and also vice versa. -It is however possible to write JNI calls which will compile under both C and C++ and is covered in the Typemaps for both C and C++ compilation section. +It is however possible to write JNI calls which will compile under both C and C++ and is covered in the Typemaps for both C and C++ compilation section.

    The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter. -The typemap example Handling C++ exception specifications as Java exceptions provides further exception handling capabilities. +The typemap example Handling C++ exception specifications as Java exceptions provides further exception handling capabilities.

    -

    20.7.4 Method access with %javamethodmodifiers

    +

    24.7.4 Method access with %javamethodmodifiers

    @@ -3870,7 +3949,7 @@ protected static void protect_me() {

    -

    20.8 Tips and techniques

    +

    24.8 Tips and techniques

    @@ -3880,7 +3959,7 @@ strings and arrays. This chapter discusses the common techniques for solving these problems.

    -

    20.8.1 Input and output parameters using primitive pointers and references

    +

    24.8.1 Input and output parameters using primitive pointers and references

    @@ -4054,7 +4133,7 @@ void foo(Bar *OUTPUT); will not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

    -

    20.8.2 Simple pointers

    +

    24.8.2 Simple pointers

    @@ -4120,7 +4199,7 @@ System.out.println("3 + 4 = " + result); See the SWIG Library chapter for further details.

    -

    20.8.3 Wrapping C arrays with Java arrays

    +

    24.8.3 Wrapping C arrays with Java arrays

    @@ -4187,7 +4266,7 @@ Please be aware that the typemaps in this library are not efficient as all the e There is an alternative approach using the SWIG array library and this is covered in the next section.

    -

    20.8.4 Unbounded C Arrays

    +

    24.8.4 Unbounded C Arrays

    @@ -4332,7 +4411,51 @@ well suited for applications in which you need to create buffers, package binary data, etc.

    -

    20.8.5 Overriding new and delete to allocate from Java heap

    +

    24.8.5 Binary data vs Strings

    + + +

    +By default SWIG handles char * as a string but there is a handy multi-argument typemap available as mentioned in Passing binary data. +The following simple example demonstrates using a byte array instead of passing the default string type and length to the wrapped function. +

    + + +
    +
    +%apply (char *STRING, size_t LENGTH) { (const char data[], size_t len) }
    +%inline %{
    +void binaryChar1(const char data[], size_t len) {
    +  printf("len: %d data: ", len);
    +  for (size_t i=0; i<len; ++i)
    +    printf("%x ", data[i]);
    +  printf("\n");
    +}
    +%}
    +
    +
    + +

    +Calling from Java requires just the byte array to be passed in as the multi-argument typemap being applied reduces the number of arguments in the target language to one, from the original two: +

    + +
    +
    +byte[] data = "hi\0jk".getBytes();
    +example.binaryChar1(data);     
    +
    +
    + +

    +resulting in the output +

    + +
    +$ java runme
    +len: 5 data: 68 69 0 6a 6b
    +
    + + +

    24.8.6 Overriding new and delete to allocate from Java heap

    @@ -4449,13 +4572,13 @@ model and use these functions in place of malloc and free in your own code.

    -

    20.9 Java typemaps

    +

    24.9 Java typemaps

    This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the %typemap directive. -You are advised to be familiar with the the material in the "Typemaps" chapter. +You are advised to be familiar with the material in the "Typemaps" chapter. While not absolutely essential knowledge, this section assumes some familiarity with the Java Native Interface (JNI). JNI documentation can be consulted either online at Sun's Java web site or from a good JNI book. The following two books are recommended:

    @@ -4470,7 +4593,7 @@ Before proceeding, it should be stressed that typemaps are not a required part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the generated code. -

    20.9.1 Default primitive type mappings

    +

    24.9.1 Default primitive type mappings

    @@ -4622,7 +4745,7 @@ However, the mappings allow the full range of values for each C type from Java.

    -

    20.9.2 Default typemaps for non-primitive types

    +

    24.9.2 Default typemaps for non-primitive types

    @@ -4637,7 +4760,7 @@ So in summary, the C/C++ pointer to non-primitive types is cast into the 64 bit The Java type is either the proxy class or type wrapper class.

    -

    20.9.3 Sixty four bit JVMs

    +

    24.9.3 Sixty four bit JVMs

    @@ -4650,7 +4773,7 @@ Unfortunately it won't of course hold true for JNI code.

    -

    20.9.4 What is a typemap?

    +

    24.9.4 What is a typemap?

    @@ -4773,7 +4896,7 @@ int c = example.count('e',"Hello World"); -

    20.9.5 Typemaps for mapping C/C++ types to Java types

    +

    24.9.5 Typemaps for mapping C/C++ types to Java types

    @@ -4827,7 +4950,7 @@ The most important of these implement the mapping of C/C++ types to Java types: These are Java code typemaps which transform the type used in the Java intermediary JNI class (as specified in the "jtype" typemap) to the Java type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap). This typemap provides the conversion for the parameters in the director methods when calling up from C++ to Java. - See Director typemaps. + See Director typemaps. @@ -4836,7 +4959,7 @@ The most important of these implement the mapping of C/C++ types to Java types: These are Java code typemaps which transform the type used in the Java module class, proxy classes and type wrapper classes (as specified in the "jstype" typemap) to the type used in the Java intermediary JNI class (as specified in the "jtype" typemap). This typemap provides the conversion for the return type in the director methods when returning from the C++ to Java upcall. - See Director typemaps. + See Director typemaps. @@ -4844,7 +4967,7 @@ The most important of these implement the mapping of C/C++ types to Java types: Conversion from C++ type to jni type for director methods. These are C++ typemaps which convert the parameters used in the C++ director method to the appropriate JNI intermediary type. The conversion is done in JNI code prior to calling the Java function from the JNI code. - See Director typemaps. + See Director typemaps. @@ -4852,7 +4975,7 @@ The most important of these implement the mapping of C/C++ types to Java types: Conversion from jni type to C++ type for director methods. These are C++ typemaps which convert the JNI return type used in the C++ director method to the appropriate C++ return type. The conversion is done in JNI code after calling the Java function from the JNI code. - See Director typemaps. + See Director typemaps. @@ -4930,12 +5053,12 @@ SWIGEXPORT jlong JNICALL Java_exampleJNI_FooBar(JNIEnv *jenv, jclass jcls,

    If you are using gcc as your C compiler, you might get a "dereferencing type-punned pointer will break strict-aliasing rules" warning about this. -Please see Compiling a dynamic module to avoid runtime problems with these strict aliasing rules. +Please see Compiling a dynamic module to avoid runtime problems with these strict aliasing rules.

    The default code generated by SWIG for the Java module comes from the typemaps in the "java.swg" library file which implements the -Default primitive type mappings and +Default primitive type mappings and Default typemaps for non-primitive types covered earlier. There are other type mapping typemaps in the Java library. These are listed below: @@ -5033,7 +5156,7 @@ These are listed below: -

    20.9.6 Java typemap attributes

    +

    24.9.6 Java typemap attributes

    @@ -5043,7 +5166,7 @@ There are a few additional typemap attributes that the Java module supports.

    The first of these is the 'throws' attribute. The throws attribute is optional and specified after the typemap name and contains one or more comma separated classes for adding to the throws clause for any methods that use that typemap. -It is analogous to the %javaexception feature's throws attribute. +It is analogous to the %javaexception feature's throws attribute.

    @@ -5055,7 +5178,7 @@ It is analogous to the %javaexception feature'

    The attribute is necessary for supporting Java checked exceptions and can be added to just about any typemap. The list of typemaps include all the C/C++ (JNI) typemaps in the "Typemaps" chapter and the -Java specific typemaps listed in the previous section, barring +Java specific typemaps listed in the previous section, barring the "jni", "jtype" and "jstype" typemaps as they could never contain code to throw an exception.

    @@ -5063,23 +5186,23 @@ the "jni", "jtype" and "jstype" typemaps as they could never contain code to thr The throws clause is generated for the proxy method as well as the JNI method in the JNI intermediary class. If a method uses more than one typemap and each of those typemaps have classes specified in the throws clause, the union of the exception classes is added to the throws clause ensuring there are no duplicate classes. -See the NaN exception example for further usage. +See the NaN exception example for further usage.

    -The "jtype" typemap has the optional 'nopgcpp' attribute which can be used to suppress the generation of the premature garbage collection prevention parameter. +The "jtype" typemap has the optional 'nopgcpp' attribute which can be used to suppress the generation of the premature garbage collection prevention parameter.

    -The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' attributes. These are used for generating code before and after the JNI call in the proxy class or module class. The 'pre' attribute contains code that is generated before the JNI call and the 'post' attribute contains code generated after the JNI call. The 'pgcppname' attribute is used to change the premature garbage collection prevention parameter name passed to the JNI function. This is sometimes needed when the 'pre' typemap creates a temporary variable which is then passed to the JNI function. +The "javain" typemap has the optional 'pre', 'post' and 'pgcppname' attributes. These are used for generating code before and after the JNI call in the proxy class or module class. The 'pre' attribute contains code that is generated before the JNI call and the 'post' attribute contains code generated after the JNI call. The 'pgcppname' attribute is used to change the premature garbage collection prevention parameter name passed to the JNI function. This is sometimes needed when the 'pre' typemap creates a temporary variable which is then passed to the JNI function.

    - -Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a this call. In Java the this call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a Date marshalling example showing 'pre', 'post' and 'pgcppname' attributes in action. + +Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a this call. In Java the this call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a Date marshalling example showing 'pre', 'post' and 'pgcppname' attributes in action.

    -

    20.9.7 Java special variables

    +

    24.9.7 Java special variables

    @@ -5102,6 +5225,14 @@ If the type does not have an associated proxy class, it expands to the type wrap SWIGTYPE_p_unsigned_short is generated when wrapping unsigned short *.

    +

    +$javaclazzname
    +This special variable works like $javaclassname, but expands the fully qualified C++ class into the package name, +if used by the nspace feature, and the proxy class name, mangled for use as a function name. +For example, Namespace1::Namespace2::Klass is expanded into Namespace1_Namespace2_Klass_. +This special variable is usually used for making calls to a function in the intermediary JNI class, as they are mangled with this prefix. +

    +

    $null
    Used in input typemaps to return early from JNI functions that have either void or a non-void return type. Example: @@ -5208,7 +5339,7 @@ can be wrapped with the Java equivalent, that is, static inner proxy classes.

    $jniinput, $javacall and $packagepath
    -These special variables are used in the directors typemaps. See Director specific typemaps for details. +These special variables are used in the directors typemaps. See Director specific typemaps for details.

    @@ -5219,10 +5350,10 @@ This special variable expands to the module name, as specified by %module $imclassname
    This special variable expands to the intermediary class name. Usually this is the same as '$moduleJNI', -unless the jniclassname attribute is specified in the %module directive. +unless the jniclassname attribute is specified in the %module directive.

    -

    20.9.8 Typemaps for both C and C++ compilation

    +

    24.9.8 Typemaps for both C and C++ compilation

    @@ -5259,7 +5390,7 @@ If you do not intend your code to be targeting both C and C++ then your typemaps

    -

    20.9.9 Java code typemaps

    +

    24.9.9 Java code typemaps

    @@ -5275,6 +5406,9 @@ base (extends) for Java class: empty default Note that this typemap accepts a replace attribute as an optional flag. When set to "1", it will replace/override any C++ base classes that might have been parsed. If this flag is not specified and there are C++ base classes, then a multiple inheritance warning is issued and the code in the typemap is ignored. +The typemap also accepts a notderived attribute as an optional flag. When set to "1", it will not apply to classes that +are derived from a C++ base. +When used with the SWIGTYPE type, it is useful for giving a common base for all proxy classes, that is, providing a base class that sits in between all proxy classes and the Java base class Object for example: %typemap(javabase, notderived="1") SWIGTYPE "CommonBase".

    %typemap(javabody)

    @@ -5328,7 +5462,7 @@ import statements for Java class: empty default

    %typemap(javainterfaces)

    -interfaces (extends) for Java class: empty default +interfaces (implements) for Java class: empty default

    %typemap(javafinalize)

    @@ -5397,9 +5531,9 @@ The "javaimports" typemap is ignored if the enum class is wrapped by an inner Ja

    The defaults can be overridden to tailor these classes. -Here is an example which will change the getCPtr method and constructor from the default protected access to public access. -This has a practical application if you are invoking SWIG more than once and generating the wrapped classes into different packages in each invocation. -If the classes in one package are using the classes in another package, then these methods need to be public. +Here is an example which will change the getCPtr method and constructor from the default public access to protected access. +If the classes in one package are not using the classes in another package, then these methods need not be public and removing access to these low level implementation details, is a good thing. +If you are invoking SWIG more than once and generating the wrapped classes into different packages in each invocation, then you cannot do this as you will then have different packages.

    @@ -5408,12 +5542,12 @@ If the classes in one package are using the classes in another package, then the private long swigCPtr; protected boolean swigCMemOwn; - public $javaclassname(long cPtr, boolean cMemoryOwn) { + protected $javaclassname(long cPtr, boolean cMemoryOwn) { swigCMemOwn = cMemoryOwn; swigCPtr = cPtr; } - public static long getCPtr($javaclassname obj) { + protected static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } %} @@ -5421,7 +5555,7 @@ If the classes in one package are using the classes in another package, then the

    -The typemap code is the same that is in "java.swg", barring the two method modifiers. +The typemap code is the same that is in "java.swg", barring the last two method modifiers. Note that SWIGTYPE will target all proxy classes, but not the type wrapper classes. Also the above typemap is only used for proxy classes that are potential base classes. To target proxy classes that are derived from a wrapped class as well, the "javabody_derived" typemap should also be overridden. @@ -5436,7 +5570,7 @@ For the typemap to be used in all type wrapper classes, all the different types %typemap(javabody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ private long swigCPtr; - public $javaclassname(long cPtr, boolean bFutureUse) { + protected $javaclassname(long cPtr, boolean bFutureUse) { swigCPtr = cPtr; } @@ -5444,7 +5578,7 @@ For the typemap to be used in all type wrapper classes, all the different types swigCPtr = 0; } - public static long getCPtr($javaclassname obj) { + protected static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } %} @@ -5455,7 +5589,30 @@ For the typemap to be used in all type wrapper classes, all the different types Again this is the same that is in "java.swg", barring the method modifier for getCPtr.

    -

    20.9.10 Director specific typemaps

    +

    +When using multiple modules or the nspace feature it is common to invoke SWIG with a different -package +command line option for each module. +However, by default the generated code may not compile if +generated classes in one package use generated classes in another package. +The visibility of the +getCPtr() and pointer constructor generated from the javabody typemaps needs changing. +The default visibility is protected but it needs to be public for access from a different package. +Just changing 'protected' to 'public' in the typemap achieves this. +Two macros are available in java.swg 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 javabody 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: +

    + +
    +
    +  SWIG_JAVABODY_PROXY(public, public, SWIGTYPE)
    +  SWIG_JAVABODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
    +
    +
    + +

    24.9.10 Director specific typemaps

    @@ -5481,7 +5638,7 @@ For example, integers are converted as follows:

    $input is the SWIG name of the JNI temporary variable passed to Java in the upcall. The descriptor="I" will put an I into the JNI field descriptor that identifies the Java method that will be called from C++. -For more about JNI field descriptors and their importance, refer to the JNI documentation mentioned earlier. +For more about JNI field descriptors and their importance, refer to the JNI documentation mentioned earlier. A typemap for C character strings is:

    @@ -5680,7 +5837,7 @@ The basic strategy here is to provide a default package typemap for the majority -

    20.10 Typemap Examples

    +

    24.10 Typemap Examples

    @@ -5690,11 +5847,11 @@ the SWIG library.

    -

    20.10.1 Simpler Java enums for enums without initializers

    +

    24.10.1 Simpler Java enums for enums without initializers

    -The default Proper Java enums approach to wrapping enums is somewhat verbose. +The default Proper Java enums approach to wrapping enums is somewhat verbose. This is to handle all possible C/C++ enums, in particular enums with initializers. The generated code can be simplified if the enum being wrapped does not have any initializers.

    @@ -5769,7 +5926,7 @@ This would be done by using the original versions of these typemaps in "enums.sw

    -

    20.10.2 Handling C++ exception specifications as Java exceptions

    +

    24.10.2 Handling C++ exception specifications as Java exceptions

    @@ -5837,7 +5994,7 @@ If, however, we wanted to throw a checked exception, say java.io.IOException

    -Note that this typemap uses the 'throws' typemap attribute to ensure a throws clause is generated. +Note that this typemap uses the 'throws' typemap attribute to ensure a throws clause is generated. The generated proxy method then specifies the checked exception by containing java.io.IOException in the throws clause:

    @@ -5894,7 +6051,7 @@ We could alternatively have used %rename to rename what() into

    -

    20.10.3 NaN Exception - exception handling for a particular type

    +

    24.10.3 NaN Exception - exception handling for a particular type

    @@ -5994,13 +6151,13 @@ public class example {

    -See the Date marshalling example for an example using further "javain" typemap attributes. +See the Date marshalling example for an example using further "javain" typemap attributes.

    If we decide that what we actually want is a checked exception instead of a runtime exception, we can change this easily enough. The proxy method that uses float as an input, must then add the exception class to the throws clause. -SWIG can handle this as it supports the 'throws' typemap attribute for specifying classes for the throws clause. +SWIG can handle this as it supports the 'throws' typemap attribute for specifying classes for the throws clause. Thus we can modify the pragma and the typemap for the throws clause:

    @@ -6049,7 +6206,7 @@ If we were a martyr to the JNI cause, we could replace the succinct code within If we had, we would have put it in the "in" typemap which, like all JNI and Java typemaps, also supports the 'throws' attribute.

    -

    20.10.4 Converting Java String arrays to char **

    +

    24.10.4 Converting Java String arrays to char **

    @@ -6143,13 +6300,13 @@ When this module is compiled, our wrapped C functions can be used by the followi

    -// File main.java
    +// File runme.java
     
    -public class main {
    +public class runme {
     
       static {
         try {
    -     System.loadLibrary("example");
    +      System.loadLibrary("example");
         } catch (UnsatisfiedLinkError e) {
           System.err.println("Native code library failed to load. " + e);
           System.exit(1);
    @@ -6171,7 +6328,7 @@ When compiled and run we get:
     

    -$ java main
    +$ java runme
     argv[0] = Cat
     argv[1] = Dog
     argv[2] = Cow
    @@ -6193,7 +6350,7 @@ Lastly the "jni", "jtype" and "jstype" typemaps are also required to specify
     what Java types to use.
     

    -

    20.10.5 Expanding a Java object to multiple arguments

    +

    24.10.5 Expanding a Java object to multiple arguments

    @@ -6275,7 +6432,7 @@ example.foo(new String[]{"red", "green", "blue", "white"});

    -

    20.10.6 Using typemaps to return arguments

    +

    24.10.6 Using typemaps to return arguments

    @@ -6362,13 +6519,13 @@ The following Java program demonstrates this:

    -// File: main.java
    +// File: runme.java
     
    -public class main {
    +public class runme {
     
       static {
         try {
    -      System.loadLibrary("example");
    +      System.loadLibrary("example");
         } catch (UnsatisfiedLinkError e) {
           System.err.println("Native code library failed to load. " + e);
           System.exit(1);
    @@ -6389,11 +6546,11 @@ When compiled and run we get:
     

    -$ java main
    +$ java runme
     1 12.0  340.0
     
    -

    20.10.7 Adding Java downcasts to polymorphic return types

    +

    24.10.7 Adding Java downcasts to polymorphic return types

    @@ -6449,7 +6606,7 @@ We get:

     Ambulance started
     java.lang.ClassCastException
    -        at main.main(main.java:16)
    +        at runme.main(runme.java:16)
     

    @@ -6599,7 +6756,7 @@ SWIG usually generates code which constructs the proxy classes using Java code a Note that the JNI code above uses a number of string lookups to call a constructor, whereas this would not occur using byte compiled Java code.

    -

    20.10.8 Adding an equals method to the Java classes

    +

    24.10.8 Adding an equals method to the Java classes

    @@ -6643,7 +6800,7 @@ System.out.println("foo1? " + foo1.equals(foo2));

    -

    20.10.9 Void pointers and a common Java base class

    +

    24.10.9 Void pointers and a common Java base class

    @@ -6702,7 +6859,7 @@ This example contains some useful functionality which you may want in your code.

  • It also has a function which effectively implements a cast from the type of the proxy/type wrapper class to a void pointer. This is necessary for passing a proxy class or a type wrapper class to a function that takes a void pointer. -

    20.10.10 Struct pointer to pointer

    +

    24.10.10 Struct pointer to pointer

    @@ -6882,7 +7039,7 @@ The C functional interface has been completely morphed into an object-oriented i the Butler class would behave much like any pure Java class and feel more natural to Java users.

    -

    20.10.11 Memory management when returning references to member variables

    +

    24.10.11 Memory management when returning references to member variables

    @@ -7005,7 +7162,7 @@ public class Bike { Note the addReference call.

    -

    20.10.12 Memory management for objects passed to the C++ layer

    +

    24.10.12 Memory management for objects passed to the C++ layer

    @@ -7121,11 +7278,11 @@ The 'javacode' typemap simply adds in the specified code into the Java proxy cla

  • -

    20.10.13 Date marshalling using the javain typemap and associated attributes

    +

    24.10.13 Date marshalling using the javain typemap and associated attributes

    -The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. +The NaN Exception example is a simple example of the "javain" typemap and its 'pre' attribute. This example demonstrates how a C++ date class, say CDate, can be mapped onto the standard Java date class, java.util.GregorianCalendar by using the 'pre', 'post' and 'pgcppname' attributes of the "javain" typemap. The idea is that the GregorianCalendar is used wherever the C++ API uses a CDate. @@ -7292,13 +7449,13 @@ A few things to note: more local variables with the same name would be generated.

  • The use of the "javain" typemap causes a constructor helper function (SwigConstructAction) to be generated. This allows Java code to be called before the JNI call and is required as the Java compiler won't compile code inserted before the 'this' call. -
  • The 'pgcppname' attribute is used to modify the object being passed as the premature garbage collection prevention parameter (the 2nd and 4th parameters in the JNI calls). +
  • The 'pgcppname' attribute is used to modify the object being passed as the premature garbage collection prevention parameter (the 2nd and 4th parameters in the JNI calls). -

    20.11 Living with Java Directors

    +

    24.11 Living with Java Directors

    @@ -7479,10 +7636,10 @@ public abstract class UserVisibleFoo extends Foo {

  • -

    20.12 Odds and ends

    +

    24.12 Odds and ends

    -

    20.12.1 JavaDoc comments

    +

    24.12.1 JavaDoc comments

    @@ -7538,7 +7695,7 @@ public class Barmy { -

    20.12.2 Functional interface without proxy classes

    +

    24.12.2 Functional interface without proxy classes

    @@ -7599,7 +7756,7 @@ All destructors have to be called manually for example the delete_Foo(foo) -

    20.12.3 Using your own JNI functions

    +

    24.12.3 Using your own JNI functions

    @@ -7649,7 +7806,7 @@ This directive is only really useful if you want to mix your own hand crafted JN

    -

    20.12.4 Performance concerns and hints

    +

    24.12.4 Performance concerns and hints

    @@ -7670,7 +7827,7 @@ However, you will have to be careful about memory management and make sure that This method normally calls the C++ destructor or free() for C code.

    -

    20.12.5 Debugging

    +

    24.12.5 Debugging

    @@ -7692,7 +7849,7 @@ The -verbose:jni and -verbose:gc are also useful options for monitoring code beh

    -

    20.13 Examples

    +

    24.13 Java Examples

    diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index 586e1ecab..dcec21c90 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -14,7 +14,7 @@

  • C Arrays and Pointers @@ -27,9 +27,10 @@
  • STL/C++ Library
  • Utility Libraries
      @@ -316,7 +317,7 @@ In this example, the function int_to_uint() would be used to cast type Note: When working with simple pointers, typemaps can often be used to provide more seamless operation.

      -

      8.2.2 carrays.i

      +

      8.2.2 carrays.i

      @@ -419,7 +420,9 @@ delete_doubleArray(a) # Destroy array +

      %array_class(type,name) +

      @@ -665,7 +668,7 @@ in order for this to work.

      -char *cdata(void *ptr, int nbytes) +const char *cdata(void *ptr, size_t nbytes)

      @@ -674,13 +677,17 @@ pointer.

      -void memmove(void *ptr, char *s) +void memmove(void *ptr, const char *s)

      Copies all of the string data in s into the memory pointed to by -ptr. The string may contain embedded NULL bytes. The length of -the string is implicitly determined in the underlying wrapper code. +ptr. The string may contain embedded NULL bytes. +This is actually a wrapper to the standard C library memmove function, which is +declared as +void memmove(void *ptr, const void *src, size_t n). +The src and length n parameters are +extracted from the language specific string s in the underlying wrapper code.

      @@ -821,20 +828,20 @@ If you have a function that expects binary data,

      -int parity(char *str, int len, int initial);
      +size_t parity(char *str, size_t len, size_t initial);
       

      -you can wrap the parameters (char *str, int len) as a single +you can wrap the parameters (char *str, size_t len) as a single argument using a typemap. Just do this:

      -%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);
       
      @@ -851,6 +858,7 @@ Now, in the target language, you can use binary string data like this:

      In the wrapper function, the passed string will be expanded to a pointer and length parameter. +The (char *STRING, int LENGTH) multi-argument typemap is also available in addition to (char *STRING, size_t LENGTH).

      8.3.3 Using %newobject to release memory

      @@ -888,7 +896,10 @@ char *foo();

      -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 char * so that the memory is released, +however, you may need to provide your own "newfree" typemap for other types. +See Object ownership and %newobject for more details.

      8.3.4 cstring.i

      @@ -1378,6 +1389,7 @@ The following table shows which C++ classes are supported and the equivalent SWI std::set set std_set.i std::string string std_string.i std::vector vector std_vector.i + std::shared_ptr shared_ptr std_shared_ptr.i @@ -1387,7 +1399,7 @@ Please look for the library files in the appropriate language library directory.

      -

      8.4.1 std_string.i

      +

      8.4.1 std::string

      @@ -1471,16 +1483,11 @@ void foo(string s, const String &t); // std_string typemaps still applie -

      -Note: The std_string library is incompatible with Perl on some platforms. -We're looking into it. -

      - -

      8.4.2 std_vector.i

      +

      8.4.2 std::vector

      -The std_vector.i library provides support for the C++ vector class in the STL. +The std_vector.i library provides support for the C++ std::vector class in the STL. Using this library involves the use of the %template directive. All you need to do is to instantiate different versions of vector for the types that you want to use. For example:

      @@ -1655,11 +1662,6 @@ if you want to make their head explode. details and the public API exposed to the interpreter vary.

      -

      -Note: std_vector.i was written by Luigi "The Amazing" Ballabio. -

      - -

      8.4.3 STL exceptions

      @@ -1710,6 +1712,164 @@ The %exception directive can be used by placing the following code befo Any thrown STL exceptions will then be gracefully handled instead of causing a crash.

      +

      8.4.4 shared_ptr smart pointer

      + + +

      +Some target languages have support for handling the widely used boost::shared_ptr smart pointer. +This smart pointer is also available as std::tr1::shared_ptr before it becomes fully standardized as std::shared_ptr. +The boost_shared_ptr.i library provides support for boost::shared_ptr and std_shared_ptr.i provides support for std::shared_ptr, but if the following macro is defined as shown, it can be used for std::tr1::shared_ptr: +

      + +
      +
      +#define SWIG_SHARED_PTR_SUBNAMESPACE tr1
      +%include <std_shared_ptr.i>
      +
      +
      + +

      +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 %shared_ptr(T) macro, +where T is the underlying pointer type equating to usage shared_ptr<T>. +The type T must be non-primitive. +A simple example demonstrates usage: +

      + +
      +
      +%module example
      +%include <boost_shared_ptr.i>
      +%shared_ptr(IntValue)
      +
      +%inline %{
      +#include <boost/shared_ptr.hpp>
      +
      +struct IntValue {
      +  int value;
      +  IntValue(int v) : value(v) {}
      +};
      +
      +static int extractValue(const IntValue &t) {
      +  return t.value;
      +}
      +
      +static int extractValueSmart(boost::shared_ptr<IntValue> t) {
      +  return t->value;
      +}
      +%}
      +
      +
      + +

      +Note that the %shared_ptr(IntValue) declaration occurs after the inclusion of the boost_shared_ptr.i +library which provides the macro and, very importantly, before any usage or declaration of the type, IntValue. +The %shared_ptr 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 shared_ptr 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: +

      + +
      +
      +IntValue iv = new IntValue(1234);
      +int val1 = example.extractValue(iv);
      +int val2 = example.extractValueSmart(iv);
      +System.out.println(val1 + " " + val2);
      +
      +
      + +

      +This shared_ptr library works quite differently to SWIG's normal, but somewhat limited, +smart pointer handling. +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 %shared_ptr 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 must be wrapped as a shared_ptr too. +In other words all classes in an inheritance hierarchy must all be used with the %shared_ptr macro. +For example the following code can be used with the base class shown earlier: +

      + +
      +
      +%shared_ptr(DerivedIntValue)
      +%inline %{
      +struct DerivedIntValue : IntValue {
      +  DerivedIntValue(int value) : IntValue(value) {}
      +  ...
      +};
      +%}
      +
      +
      + +

      +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++: +

      + +
      +
      +DerivedIntValue div = new DerivedIntValue(5678);
      +int val3 = example.extractValue(div);
      +int val4 = example.extractValueSmart(div);
      +
      +
      + +

      +If the %shared_ptr 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: +

      + +
      +
      +%include "boost_shared_ptr.i"
      +%shared_ptr(Parent);
      +
      +%inline %{
      +  #include <boost/shared_ptr.hpp>
      +  struct GrandParent {
      +    virtual ~GrandParent() {}
      +  };
      +
      +  struct Parent : GrandParent {
      +    virtual ~Parent() {}
      +  };
      +
      +  struct Child : Parent {
      +    virtual ~Child() {}
      +  };
      +%}
      +
      +
      + +

      +warns about the missing smart pointer information: +

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

      +Adding the missing %shared_ptr macros will fix this: +

      + +
      +
      +%include "boost_shared_ptr.i"
      +%shared_ptr(GrandParent);
      +%shared_ptr(Parent);
      +%shared_ptr(Child);
      +
      +... as before ...
      +
      +

      8.5 Utility Libraries

      diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html index ca2d0414e..01ff3a3ec 100644 --- a/Doc/Manual/Lisp.html +++ b/Doc/Manual/Lisp.html @@ -6,7 +6,7 @@ -

      21 SWIG and Common Lisp

      +

      25 SWIG and Common Lisp

        @@ -41,16 +41,16 @@ Lisp, Common Foreign Function Interface(CFFI), CLisp and UFFI foreign function interfaces.

        -

        21.1 Allegro Common Lisp

        +

        25.1 Allegro Common Lisp

        Allegro Common Lisp support in SWIG has been updated to include support for both C and C++. You can read about the interface - here + here

        -

        21.2 Common Foreign Function Interface(CFFI)

        +

        25.2 Common Foreign Function Interface(CFFI)

        @@ -77,7 +77,7 @@ swig -cffi -module module-name file-name files and the various things which you can do with them.

        -

        21.2.1 Additional Commandline Options

        +

        25.2.1 Additional Commandline Options

        @@ -96,14 +96,14 @@ swig -cffi -help -generate-typedef -If this option is given then defctype will be used to generate +If this option is given then defctype will be used to generate
        shortcuts according to the typedefs in the input. -[no]cwrap -Turn on or turn off generation of an intermediate C file when +Turn on or turn off generation of an intermediate C file when
        creating a C interface. By default this is only done for C++ code. @@ -118,7 +118,7 @@ swig -cffi -help -

        21.2.2 Generating CFFI bindings

        +

        25.2.2 Generating CFFI bindings

        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 feature directive. + href="Customization.html#Customization_features">feature directive. 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 intern_function ensures that all C names are
      -

      21.2.3 Generating CFFI bindings for C++ code

      +

      25.2.3 Generating CFFI bindings for C++ code

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

      21.2.4 Inserting user code into generated files

      +

      25.2.4 Inserting user code into generated files

      @@ -583,7 +583,7 @@ using the SWIG %insert(section) %{ ...code... %} directive:

       %module example
       
      -%insert("runtime") %{
      +%{
       #include "header.h"
       %}
       
      @@ -604,11 +604,11 @@ generated lisp interface file:
       

    Note that the block %{ ... %} is effectively a shortcut for -%insert("runtime") %{ ... %}. +%insert("header") %{ ... %}.

    -

    21.3 CLISP

    +

    25.3 CLISP

    @@ -638,7 +638,7 @@ swig -clisp -module module-name file-name interface file for the CLISP module. The CLISP module tries to produce code which is both human readable and easily modifyable.

    -

    21.3.1 Additional Commandline Options

    +

    25.3.1 Additional Commandline Options

    @@ -671,7 +671,7 @@ and global variables will be created otherwise only definitions for
    -

    21.3.2 Details on CLISP bindings

    +

    25.3.2 Details on CLISP bindings

    @@ -795,7 +795,7 @@ struct bar { -

    21.4 UFFI

    +

    25.4 UFFI

    diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html index 4ebf02349..ec32c4449 100644 --- a/Doc/Manual/Lua.html +++ b/Doc/Manual/Lua.html @@ -6,13 +6,14 @@ -

    22 SWIG and Lua

    +

    26 SWIG and Lua

    @@ -50,15 +67,20 @@

    -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 really tiny language, less than 6000 lines of code, which compiles to <100 kilobytes of binary code. It can be found at http://www.lua.org +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++). It's also a really tiny language, less than 6000 lines of code, which compiles to <100 kilobytes of binary code. It can be found at http://www.lua.org

    -

    22.1 Preliminaries

    +

    +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: http://www.eluaproject.net +

    + +

    26.1 Preliminaries

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

    -

    22.2 Running SWIG

    + +

    26.2 Running SWIG

    @@ -88,9 +110,58 @@ $ swig -c++ -lua example.i This creates a C/C++ source file example_wrap.c or example_wrap.cxx. 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 to create an extension module.

    -The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrappered module will export one function "int luaopen_example(lua_State* L)" which must be called to register the module with the Lua interpreter. The name "luaopen_example" depends upon the name of the module. +The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrapped module will export one function "int luaopen_example(lua_State* L)" which must be called to register the module with the Lua interpreter. The name "luaopen_example" depends upon the name of the module.

    -

    22.2.1 Compiling and Linking and Interpreter

    +

    +To build an eLua module, run SWIG using -lua and add either -elua or -eluac. +

    +
    +$ swig -lua -elua example.i
    +
    +

    +or +

    +
    +$ swig -lua -eluac example.i
    +
    +

    +The -elua 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 -eluac 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 -eluac. To access any value from eLua, one must directly call the wrapper function associated with that value. +

    + +

    26.2.1 Additional command line options

    + + +

    +The following table list the additional commandline options available for the Lua module. They can also be seen by using: +

    + +
    +swig -lua -help 
    +
    + + + + + + + + + + + + + + + + + + + + + +
    Lua specific options
    -eluaGenerates LTR compatible wrappers for smaller devices running elua.
    -eluacLTR compatible wrappers in "crass compress" mode for elua.
    -nomoduleglobalDo not register the module name as a global variable but return the module table from calls to require.
    + +

    26.2.2 Compiling and Linking and Interpreter

    @@ -114,7 +185,7 @@ int main(int argc,char* argv[]) } L=lua_open(); luaopen_base(L); // load basic libs (eg. print) - luaopen_example(L); // load the wrappered module + luaopen_example(L); // load the wrapped module if (luaL_loadfile(L,argv[1])==0) // load and run the file lua_pcall(L,0,0,0); else @@ -136,8 +207,32 @@ $ 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 +

    +For eLua, the source must be built along with the wrappers generated by SWIG. Make sure the eLua source files platform_conf.h and auxmods.h are updated with the entries of your new module. Please note: "mod" is the module name. +

    +
    +/* 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 )\
    +  ....
    +
    -

    22.2.2 Compiling a dynamic module

    +
    +/* Sample auxmods.h */
    +#define AUXLIB_PIO       "pio"
    +LUALIB_API int ( luaopen_pio )(lua_State *L );
    +
    +#define AUXLIB_MOD       "mod"
    +LUALIB_API int ( luaopen_mod )(lua_State *L );
    +....
    +
    +

    +More information on building and configuring eLua can be found here: http://www.eluaproject.net/doc/v0.8/en_building.html +

    + +

    26.2.3 Compiling a dynamic module

    @@ -150,7 +245,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

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

     require("example")
    @@ -161,7 +256,7 @@ For those using Lua 5.0.x, you will also need an interpreter with the loadlib fu
     
     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
     

    @@ -182,10 +277,10 @@ print(a,b,c)

    Note: for Lua 5.0:
    -The loadlib() function is in the global namespace, not in package. So its just loadlib(). +The loadlib() function is in the global namespace, not in a package. So it's just loadlib().

    -if 'a' is a function, this its all working fine, all you need to do is call it +if 'a' is a function, this is all working fine, all you need to do is call it

       a()
    @@ -194,7 +289,7 @@ if 'a' is a function, this its all working fine, all you need to do is call it
     to load your library which will add a table 'example' with all the functions added.
     

    -If it doesn't work, look at the error messages, in particular mesage 'b'
    +If it doesn't work, look at the error messages, in particular message 'b'
    The specified module could not be found.
    Means that is cannot find the module, check your the location and spelling of the module.
    The specified procedure could not be found.
    @@ -205,7 +300,7 @@ Is quite obvious (Go back and consult the Lua documents on how to enable loadlib -

    22.2.3 Using your module

    +

    26.2.4 Using your module

    @@ -223,19 +318,19 @@ $ ./my_lua >

    -

    22.3 A tour of basic C/C++ wrapping

    +

    26.3 A tour of basic C/C++ wrapping

    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.

    -

    22.3.1 Modules

    +

    26.3.1 Modules

    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.

    -

    22.3.2 Functions

    +

    26.3.2 Functions

    @@ -273,7 +368,7 @@ It is also possible to rename the module with an assignment. 24 -

    22.3.3 Global variables

    +

    26.3.3 Global variables

    @@ -299,7 +394,7 @@ SWIG will effectively generate two functions example.Foo_set() and 4 5

    -Its is therefore not possible to 'move' the global variable into the global namespace as it is with functions. It is however, possible to rename the module with an assignment, to make it more convenient. +It is therefore not possible to 'move' the global variable into the global namespace as it is with functions. It is however, possible to rename the module with an assignment, to make it more convenient.

     > e=example
    @@ -310,7 +405,7 @@ Its is therefore not possible to 'move' the global variable into the global name
     4
     

    -If a variable is marked with the %immutable directive then any attempts to set this variable will cause an Lua error. Given a global variable: +If a variable is marked with the %immutable directive then any attempts to set this variable will cause a Lua error. Given a global variable:

    %module example
    @@ -319,7 +414,7 @@ extern double Foo;
     %mutable;
     

    -SWIG will allow the the reading of Foo but when a set attempt is made, an error function will be called. +SWIG will allow the reading of Foo but when a set attempt is made, an error function will be called.

     > print(e.Foo) -- reading works ok
    @@ -346,8 +441,22 @@ nil
     > print(example.PI)
     3.142
     
    +

    +If you have used the -eluac 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 -elua) +

    +
    +> -- Applicable only with -eluac. (num is defined)
    +> print(example.num_get())
    +20
    +> example.num_set(50) -- new value added
    +> print(example.num_get())
    +50
    +
    +

    +In general, functions of the form "variable_get()" and "variable_set()" are automatically generated by SWIG for use with -eluac. +

    -

    22.3.4 Constants and enums

    +

    26.3.4 Constants and enums

    @@ -370,7 +479,18 @@ example.SUNDAY=0

    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.

    -

    22.3.5 Pointers

    +

    +If you're using eLua and have used -elua or -eluac to generate your wrapper, macro constants and enums should be accessed through a rotable called "const". 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. +

    +
    +> print(example.ICONST)
    +10
    +> print(example.const.SUNDAY)
    +0
    +> print(example.const.SCONST)
    +Hello World
    +
    +

    26.3.5 Pointers

    @@ -391,13 +511,13 @@ When wrapped, you will be able to use the functions in a natural way from Lua. F > example.fclose(f)

    -Unlike many scripting languages, Lua has had support for pointers to C/C++ object built in for a long time. They are called 'userdata'. Unlike many other SWIG versions which use some kind of encoded character string, all objects will be represented as a userdata. The SWIG-Lua bindings provides a special function swig_type(), which if given a userdata object will return the type of object pointed to as a string (assuming it was a SWIG wrappered object). +Unlike many scripting languages, Lua has had support for pointers to C/C++ object built in for a long time. They are called 'userdata'. Unlike many other SWIG versions which use some kind of encoded character string, all objects will be represented as a userdata. The SWIG-Lua bindings provides a special function swig_type(), which if given a userdata object will return the type of object pointed to as a string (assuming it was a SWIG wrapped object).

     > print(f)
     userdata: 003FDA80
     > print(swig_type(f))
    -FILE * -- its a FILE*
    +FILE * -- it's a FILE*
     

    Lua enforces the integrity of its userdata, so it is virtually impossible to corrupt the data. But as the user of the pointer, you are responsible for freeing it, or closing any resources associated with it (just as you would in a C program). This does not apply so strictly to classes & structs (see below). One final note: if a function returns a NULL pointer, this is not encoded as a userdata, but as a Lua nil. @@ -408,7 +528,7 @@ Lua enforces the integrity of its userdata, so it is virtually impossible to cor nil -

    22.3.6 Structures

    +

    26.3.6 Structures

    @@ -441,10 +561,10 @@ If you print out the value of p in the above example, you will see something lik userdata: 003FA320

    -Like the pointer in the previous section, this is held as a userdata. However, additional features have been added to make this more usable. SWIG effectivly creates some accessor/mutator functions to get and set the data. These functions will be added to the userdata's metatable. This provides the natural access to the member variables that were shown above (see end of the document for full details). +Like the pointer in the previous section, this is held as a userdata. However, additional features have been added to make this more usable. SWIG effectively creates some accessor/mutator functions to get and set the data. These functions will be added to the userdata's metatable. This provides the natural access to the member variables that were shown above (see end of the document for full details).

    -const members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutable's, setting attempts will be cause an error. For example: +const members of a structure are read-only. Data members can also be forced to be read-only using the immutable directive. As with other immutables, setting attempts will be cause an error. For example:

    struct Foo {
        ...
    @@ -493,8 +613,26 @@ Because the pointer points inside the structure, you can modify the contents and
     > x = b.f
     > x.a = 3                 -- Modifies the same structure
     
    +

    +For eLua with the -eluac option, structure manipulation has to be performed with specific structure functions generated by SWIG. Let's say you have the following structure definition: +

    +
    struct data {
    +   int x, y;
    +   double z;
    +};
     
    -

    22.3.7 C++ classes

    +> --From eLua +> a = example.new_data() +> example.data_x_set(a, 10) +> example.data_y_set(a, 20) +> print(example.data_x_get(a), example.data_y_get(a)) +10 20 +
    +

    +In general, functions of the form "new_struct()", "struct_member_get()", "struct_member_set()" and "free_struct()" are automatically generated by SWIG for each structure defined in C. (Please note: This doesn't apply for modules generated with the -elua option) +

    + +

    26.3.7 C++ classes

    @@ -526,7 +664,7 @@ Stout >

    -(Note: for calling methods of a class, you use class:method(args), not class.method(args), its an easy mistake to make. However for data attributes it is class.attribute) +(Note: for calling methods of a class, you use class:method(args), not class.method(args), it's an easy mistake to make. However for data attributes it is class.attribute)

    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 +673,6 @@ Class data members are accessed in the same manner as C structures. Static class public: static void foo(); static int bar; - };

    @@ -550,12 +687,12 @@ In Lua, the static members can be accessed as follows: It is not (currently) possible to access static members of an instance:

    -> s=example.Spam()      -- s is a Spam instance
    +> s=example.Spam()              -- s is a Spam instance
     > s.foo()                       -- Spam::foo() via an instance
                                     -- does NOT work
     
    -

    22.3.8 C++ inheritance

    +

    26.3.8 C++ inheritance

    @@ -580,7 +717,7 @@ then the function spam() accepts a Foo pointer or a pointer to any clas

    It is safe to use multiple inheritance with SWIG.

    -

    22.3.9 Pointers, references, values, and arrays

    +

    26.3.9 Pointers, references, values, and arrays

    @@ -611,7 +748,7 @@ Foo spam7();

    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.

    -

    22.3.10 C++ overloaded functions

    +

    26.3.10 C++ overloaded functions

    @@ -669,8 +806,8 @@ void foo(Bar &b); If declarations such as these appear, you will get a warning message like this:

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

    To fix this, you either need to ignore or rename one of the methods. For example: @@ -697,7 +834,7 @@ Please refer to the "SWIG and C++" chapter for more information about overloadin

    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.

    -

    22.3.11 C++ operators

    +

    26.3.11 C++ operators

    @@ -809,7 +946,7 @@ It is also possible to overload the operator[], but currently this cann }; -

    22.3.12 Class extension with %extend

    +

    26.3.12 Class extension with %extend

    @@ -864,7 +1001,32 @@ true

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

    -

    22.3.13 C++ templates

    + +

    26.3.13 Using %newobject to release memory

    + + +

    If you have a function that allocates memory like this,

    +
    +
    char *foo() {
    +   char *result = (char *) malloc(...);
    +   ...
    +   return result;
    +}
    +
    +
    +

    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.

    +

    To fix the memory leak, use the %newobject directive.

    +
    +
    %newobject foo;
    +...
    +char *foo();
    +
    +
    +

    This will release the allocated memory.

    + +

    26.3.14 C++ templates

    @@ -899,7 +1061,7 @@ In Lua:

    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.

    -

    22.3.14 C++ Smart Pointers

    +

    26.3.15 C++ Smart Pointers

    @@ -951,7 +1113,7 @@ If you ever need to access the underlying pointer returned by operator->( > f = p:__deref__() -- Returns underlying Foo * -

    22.3.15 C++ Exceptions

    +

    26.3.16 C++ Exceptions

    @@ -970,13 +1132,13 @@ SWIG will automatically convert this to a Lua error.

    -> message()
    +> message()
     I died.
     stack traceback:
             [C]: in function 'message'
             stdin:1: in main chunk
             [C]: ?
    ->
    +>
     

    @@ -985,13 +1147,13 @@ Using xpcall will allow you to obtain additional debug information (such as a st

    -> 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)
    +> 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)
     false   I died.
    -> ok,res=xpcall(a,debug.traceback)  -- call the function
    -> print(ok,res)
    +> ok,res=xpcall(a,debug.traceback)  -- call the function
    +> print(ok,res)
     false   I died.
     stack traceback:
             [C]: in function 'message'
    @@ -1003,11 +1165,12 @@ stack traceback:
     

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

    +

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

    @@ -1021,27 +1184,23 @@ void throw_A() throw(A*) { }

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

    -> throw_A()
    +> throw_A()
     object exception:A *
     stack traceback:
             [C]: in function 'unknown'
             stdin:1: in main chunk
             [C]: ?
    ->
    +>
     

    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.

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

    -

    If you have your own class which you want output as a string you will need to add a typemap something like this:

    @@ -1052,8 +1211,8 @@ If you have your own class which you want output as a string you will need to ad
     %}
     

    -If you wish your exception to be returned to the interpreter, it must firstly be copyable. Then you must have and additional -%apply 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 +%apply statement, to tell SWIG to return a copy of this object to the interpreter. For example:

     %apply SWIGTYPE EXCEPTION_BY_VAL {Exc}; // tell SWIG to return Exc by value to interpreter
    @@ -1076,33 +1235,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).
     

    -> ok,res=pcall(throw_exc)
    -> print(ok)
    +> ok,res=pcall(throw_exc)
    +> print(ok)
     false
    -> print(res)
    +> print(res)
     userdata: 0003D880
    -> print(res.code,res.msg)
    +> print(res.code,res.msg)
     42      Hosed
    ->
    +>
     

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

    All of this code assumes that your C++ code uses exception specification (which a lot doesn't). If it doesn't consult the "Exception handling with %catches" section -and the "Exception handling with %exception" section, for more details on how to +and the "Exception handling with %exception" section, for more details on how to add exception specification to functions or globally (respectively).

    -

    22.3.16 Writing your own custom wrappers

    +

    26.4 Typemaps

    + + +

    This section explains what typemaps are and how to use 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

    + +

    26.4.1 What is a typemap?

    + + +

    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:

    + +
    %module example
    +
    +%typemap(in) int {
    +	$1 = (int) lua_tonumber(L,$input);
    +	printf("Received an integer : %d\n",$1);
    +}
    +%inline %{
    +extern int fact(int n);
    +%}
    +
    + +

    Note: you shouldn't use this typemap, as SWIG already has a typemap for this task. This is purely for example.

    + +

    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.

    + +

    When this example is compiled into a Lua module, it operates as follows:

    + +
    > require "example"
    +> print(example.fact(6))
    +Received an integer : 6
    +720
    +
    + +

    26.4.2 Using typemaps

    + + +

    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.

    + +

    However for more complex functions which use input/output parameters or arrays, you will need to make use of <typemaps.i>, which contains typemaps for these situations. For example, consider these functions:

    + +
    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;
    +}
    +
    + +

    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.

    + +

    One means would be to rename the argument name to help SWIG, eg void add(int x, int y, int *OUTPUT), however it is easier to use the %apply to achieve the same result, as shown below.

    + +
    %include <typemaps.i>
    +%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);
    +
    + +

    When wrapped, it gives the following results:

    + +
    > require "example"
    +> print(example.add(1,2))
    +3
    +> print(demo.sub(1,2))
    +-1
    +> a,b=1,2
    +> c,d=demo.swap(a,b)
    +> print(a,b,c,d)
    +1       2       2       1
    +
    + +

    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.

    + +

    Note: C++ references must be handled exactly the same way. However SWIG will automatically wrap a const int& as an input parameter (since that it obviously input).

    + +

    26.4.3 Typemaps and arrays

    + + +

    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.

    + +

    Given the functions:

    +
    extern void sort_int(int* arr, int len);
    +extern void sort_double(double* arr, int len);
    +
    + +

    There are basically two ways that SWIG can deal with this. The first way, uses the <carrays.i> library +to create an array in C/C++ then this can be filled within Lua and passed into the function. It works, but it's a bit tedious. +More details can be found in the carrays.i documentation.

    + +

    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 <typemaps.i> file there are typemaps ready written to perform this task. To use them is again a matter of using %appy in the correct manner.

    + +

    The wrapper file below, shows both the use of carrays as well as the use of the typemap to wrap arrays.

    + +
    // using the C-array
    +%include <carrays.i>
    +// 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 <typemaps.i>
    +%apply (double *INOUT,int) {(double* arr,int len)};
    +
    +extern void sort_double(double* arr, int len); // the function to wrap
    +
    + +

    Once wrapped, the functions can both be called, though with different ease of use:

    + +
    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
    +
    + +

    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 %luacode directive is good for this. See SWIG\Examples\lua\arrays for an example of this.

    + +

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

    + +

    Note: SWIG also can support arrays of pointers in a similar manner.

    + +

    26.4.4 Typemaps and pointer-pointer functions

    + + +

    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:

    + +
    struct iMath;    // some structure
    +int Create_Math(iMath** pptr); // its creator (assume it mallocs)
    +
    + +

    Which would be used with the following C code:

    + +
    iMath* ptr;
    +int ok;
    +ok=Create_Math(&ptr);
    +// do things with ptr
    +//...
    +free(ptr); // dispose of iMath
    +
    + +

    SWIG has a ready written typemap to deal with such a kind of function in <typemaps.i>. 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:

    + +
    %include <typemaps.i>
    +%apply SWIGTYPE** OUTPUT{iMath **pptr }; // tell SWIG it's an output
    +
    +struct iMath;    // some structure
    +int Create_Math(iMath** pptr); // its creator (assume it mallocs)
    +
    + +

    The usage is as follows:

    + +
    ok,ptr=Create_Math() -- ptr is an iMath* which is returned with the int (ok)
    +ptr=nil -- the iMath* will be GC'ed as normal
    +
    + +

    26.5 Writing typemaps

    + + +

    This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the %typemap directive. This is an advanced topic that assumes familiarity with the Lua C API as well as the material in the "Typemaps" chapter.

    + +

    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.

    + +

    Before proceeding, you should read the previous section on using typemaps, and look at the existing 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 an idea to base your work on).

    + +

    26.5.1 Typemaps you can write

    + + +

    There are many different types of typemap that can be written, the full list can be found in the "Typemaps" chapter. However the following are the most commonly used ones.

    + +
      +
    • in this is for input arguments to functions
    • +
    • out this is for return types from functions
    • +
    • argout this is for a function argument which is actually returning something
    • +
    • typecheck 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).
    • +
    + +

    26.5.2 SWIG's Lua-C API

    + + +

    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.

    + +

    int SWIG_ConvertPtr(lua_State* L,int index,void** ptr,swig_type_info *type,int flags);

    + +
    +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.
    +The returns a value which can be checked with the macro SWIG_IsOK() +
    + +

    void SWIG_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type,int own);

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

    void* SWIG_MustGetPtr(lua_State* L,int index,swig_type_info *type,int flags,int argnum,const char* func_name);

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

    SWIG_fail

    + +
    +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.
    +A common use for this code is:
    +if (!SWIG_IsOK(SWIG_ConvertPtr( .....)){
    + lua_pushstring(L,"something bad happened");
    + SWIG_fail;
    +}
    + +

    SWIG_fail_arg(char* func_name,int argnum,char* type)

    + +
    +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 +
    +"Error in func_name (arg argnum), expected 'type' got 'whatever the type was'"
    +
    + +

    SWIG_fail_ptr(const char* fn_name,int argnum,swig_type_info* type);

    + +
    +Similar to SWIG_fail_arg, except that it will display the swig_type_info information instead.
    + +

    26.6 Customization of your Bindings

    -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 %native directive as follows: +This section covers adding of some small extra bits to your module to add the last finishing touches. +

    + + + +

    26.6.1 Writing your own custom wrappers

    + + +

    +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 %native directive as follows:

    %native(my_func) int native_function(lua_State*L);  // registers native_function() with SWIG
     ...
    @@ -1114,14 +1537,14 @@ int native_function(lua_State*L) // my native code
     %}
     

    -The %native directive in the above example, tells SWIG that there is a function int native_function(lua_State*L); which is to be added into the module under the name 'my_func'. 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 %native directive in the above example, tells SWIG that there is a function int native_function(lua_State*L); which is to be added into the module under the name 'my_func'. 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.

    -

    22.3.17 Adding additional Lua code

    +

    26.6.2 Adding additional Lua code

    -As well as adding additional C/C++ code, its also possible to add your own Lua code to the module as well. +As well as adding additional C/C++ code, it's also possible to add your own Lua code to the module as well. This code is executed once all other initialisation, including the %init code has been called.

    @@ -1146,7 +1569,7 @@ module name added.

    Should there be an error in the Lua code, this will not stop loading of the module. -The default behaviour of SWIG is to print a error message to stderr and then continue. +The default behaviour of SWIG is to print an error message to stderr and then continue. It is possible to change this behaviour by using a #define SWIG_DOSTRING_FAIL(STR) to define a different behaviour should the code fail.

    @@ -1155,18 +1578,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.

    -

    22.4 Details on the Lua binding

    +

    26.7 Details on the Lua binding

    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.

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

    -

    22.4.1 Binding global data into the module.

    +

    26.7.1 Binding global data into the module.

    @@ -1226,14 +1649,14 @@ end

    That way when you call 'a=example.Foo', 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 'example.Foo=10', 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)'.

    -

    22.4.2 Userdata and Metatables

    +

    26.7.2 Userdata and Metatables

    As mentioned earlier, classes and structures, are all held as pointer, using the Lua 'userdata' structure. This structure is actually a pointer to a C structure 'swig_lua_userdata', which contains the pointer to the data, a pointer to the swig_type_info (an internal SWIG struct) and a flag which marks if the object is to be disposed of when the interpreter no longer needs it. The actual accessing of the object is done via the metatable attached to this userdata.

    -The metatable is a Lua 5.0 feature (which is also why SWIG cannot wrap Lua 4.0). Its a table which holds a list of functions, operators and attributes. This is what gives the userdata the feeling that it is a real object and not just a hunk of memory. +The metatable is a Lua 5.0 feature (which is also why SWIG cannot wrap Lua 4.0). It's a table which holds a list of functions, operators and attributes. This is what gives the userdata the feeling that it is a real object and not just a hunk of memory.

    Given a class @@ -1250,10 +1673,10 @@ public: };

    -SWIG will create a module excpp, with all the various function inside. However to allow the intuitive use of the userdata is also creates up a set of metatables. As seen in the above section on global variables, use of the metatables allows for wrappers to be used intuitively. To save effort, the code creates one metatable per class and stores it inside Lua's registry. Then when an new object is instantiated, the metatable is found in the registry and the userdata associated to the metatable. Currently derived classes make a complete copy of the base classes table and then add on their own additional function. +SWIG will create a module excpp, with all the various functions inside. However to allow the intuitive use of the userdata, SWIG also creates up a set of metatables. As seen in the above section on global variables, use of the metatables allows for wrappers to be used intuitively. To save effort, the code creates one metatable per class and stores it inside Lua's registry. Then when a new object is instantiated, the metatable is found in the registry and the userdata associated with the metatable. Currently, derived classes make a complete copy of the base class' table and then add on their own additional functions.

    -Some of the internals can be seen by looking at a classes metatable. +Some of the internals can be seen by looking at the metatable of a class:

     > p=excpp.Point()
    @@ -1270,7 +1693,7 @@ __index function: 003FB698
     .fn     table: 003FB528
     

    -The '.type' attribute is the name of the class. The '.get' and '.set' tables work in a similar manner to the modules, the main difference is the '.fn' table which also holds all the member functions. (The '__gc' function is the classes destructor function) +The '.type' attribute is the name of the class. The '.get' and '.set' tables work in a similar manner to the modules, the main difference is the '.fn' table which also holds all the member functions. (The '__gc' function is the class' destructor function)

    The Lua equivalent of the code for enabling functions looks a little like this @@ -1284,7 +1707,7 @@ function __index(obj,name) local f=g[name] -- looks for the get_attribute function -- calls it & returns the value if type(f)=="function" then return f() end - -- ok, so it not an attribute, maybe its a function + -- ok, so it not an attribute, maybe it's a function local fn=m['.fn'] -- gets the function table if not fn then return nil end local f=fn[name] -- looks for the function @@ -1301,22 +1724,22 @@ So when 'p:Print()' is called, the __index looks on the object metatable for a ' In theory, you can play with this usertable & 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.

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

    -Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__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. +Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the class' 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.

    -

    22.4.3 Memory management

    +

    26.7.3 Memory management

    -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 collectgarbage()). 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 & 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 collectgarbage()). 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 & 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.

    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.

    -It is also currently not possible to change the ownership flag on the data (unlike most other scripting languages, Lua does not permit access to the data from within the interpreter) +It is also currently not possible to change the ownership flag on the data (unlike most other scripting languages, Lua does not permit access to the data from within the interpreter).

    diff --git a/Doc/Manual/Makefile b/Doc/Manual/Makefile index 1923c2c48..42149ba3a 100644 --- a/Doc/Manual/Makefile +++ b/Doc/Manual/Makefile @@ -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 diff --git a/Doc/Manual/Modula3.html b/Doc/Manual/Modula3.html index ff70fc143..065313fa2 100644 --- a/Doc/Manual/Modula3.html +++ b/Doc/Manual/Modula3.html @@ -5,42 +5,39 @@ -

    23 SWIG and Modula-3

    +

    27 SWIG and Modula-3

    @@ -49,24 +46,29 @@

    This chapter describes SWIG's support of -Modula-3. +Modula-3. You should be familiar with the basics of SWIG, especially -typemaps. +typemaps.

    -

    23.1 Overview

    +

    27.1 Overview

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

    + +

    +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:

      @@ -78,130 +80,34 @@ PLPlot
    1. FFTW - . +
    - -

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

    - - -

    23.1.1 Why not scripting ?

    +

    27.1.1 Motivation

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

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

    - -

    23.1.2 Why Modula-3 ?

    - - -

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

    -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 UNSAFE modules. +SWIG converts C headers to Modula-3 interfaces for you, and using typemaps +you can pass TEXTs or open arrays, and convert error return codes +into exceptions.

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

    - - -

    23.1.3 Why C / C++ ?

    - - -

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

    - -

    23.1.4 Why SWIG ?

    - - -

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

    - -

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

    - -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 typedefs and consts -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 good SWIG interfaces -is very costly and it will only amortise -when considering evolving libraries. -

    - - -

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

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

    - -

    23.2 Conception

    +

    27.2 Conception

    -

    23.2.1 Interfaces to C libraries

    +

    27.2.1 Interfaces to C libraries

    -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 -modula3.swg +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 (%typemap).

    -

    23.2.2 Interfaces to C++ libraries

    +

    27.2.2 Interfaces to C++ libraries

    @@ -417,7 +296,7 @@ with a C interface.

    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:

    @@ -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 -Java and -Python. +Java and +Python.
  • How to manage storage with the garbage collector of Modula-3? Support for - + %newobject and %typemap(newfree) isn't implemented, yet. What's about resources that are managed by the garbage collector @@ -494,7 +373,7 @@ as far as I know.
  • How to turn C++ exceptions into Modula-3 exceptions? There's also no support for - + %exception, yet.
  • @@ -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.

    -

    23.3 Preliminaries

    +

    27.3 Preliminaries

    -

    23.3.1 Compilers

    +

    27.3.1 Compilers

    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 -modula3.swg +but the modula3.swg library file may do so. For testing examples I use Critical Mass cm3.

    -

    23.3.2 Additional Commandline Options

    +

    27.3.2 Additional Commandline Options

    @@ -599,10 +477,10 @@ Instead generate templates for some basic typemaps.

    -

    23.4 Modula-3 typemaps

    +

    27.4 Modula-3 typemaps

    -

    23.4.1 Inputs and outputs

    +

    27.4.1 Inputs and outputs

    @@ -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 -modula3.swg -. +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: -

    23.4.2 Subranges, Enumerations, Sets

    +

    27.4.2 Subranges, Enumerations, Sets

    @@ -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 -example. +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.

    -

    23.4.3 Objects

    +

    27.4.3 Objects

    Declarations of C++ classes are mapped to OBJECT types while it is tried to retain the access hierarchy "public - protected - private" using partial revelation. -Though the -implementation +Though the example in +Examples/modula3/class/example.i is not really useful, yet.

    -

    23.4.4 Imports

    +

    27.4.4 Imports

    @@ -903,9 +779,7 @@ Unqualified import is not supported.

    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 -modula3.swg -. +for the modula3.swg typemap library. For a monolithic module you might be better off if you add the imports directly:

    @@ -918,7 +792,7 @@ IMPORT M3toC; -

    23.4.5 Exceptions

    +

    27.4.5 Exceptions

    @@ -942,7 +816,7 @@ you should declare %typemap("m3wrapinconv:throws") blah * %{OSError.E%}.

    -

    23.4.6 Example

    +

    27.4.6 Example

    @@ -989,10 +863,10 @@ where almost everything is generated by a typemap: -

    23.5 More hints to the generator

    +

    27.5 More hints to the generator

    -

    23.5.1 Features

    +

    27.5.1 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 - -generateconstoption. + -generateconstoption. In future it may be generalized to other kind of values such as strings.
    -

    23.5.2 Pragmas

    +

    27.5.2 Pragmas

    @@ -1052,14 +926,14 @@ where almost everything is generated by a typemap:
    -

    23.6 Remarks

    +

    27.6 Remarks

    • The Modula-3 part of SWIG doesn't try to generate nicely formatted code. -Use m3pp to postprocess the Modula files, -it does a very good job here. +If you need to read the generated code, use m3pp to postprocess the +Modula files.
    diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html index 8971324fb..70b0f1181 100644 --- a/Doc/Manual/Modules.html +++ b/Doc/Manual/Modules.html @@ -10,9 +10,10 @@
      +
    • Modules Introduction
    • Basics
    • The SWIG runtime code -
    • External access to the runtime +
    • External access to the runtime
    • A word of caution about static libraries
    • References
    • Reducing the wrapper file size @@ -22,11 +23,49 @@ +

      15.1 Modules Introduction

      + + +

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

      + +

      +The module name can be supplied in one of two ways. +The first is to specify it with the special %module +directive. This directive must appear at the beginning of the interface file. +The general form of this directive is: +

      + +
      +%module(option1="value1",option2="value2",...) modulename
      +
      + +

      +where the modulename is mandatory and the options add one or more optional additional features. +Typically no options are specified, for example: +

      + +
      +%module mymodule
      +
      + +

      +The second way to specify the module name is with the -module command line option, for example -module mymodule. +If the module name is supplied on the command line, it overrides the name specified by the +%module directive. +

      +

      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.

      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.

      -

      15.1 Basics

      +

      15.2 Basics

      @@ -50,43 +90,93 @@ scripting language runtime as you would do for the single module case.

      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:

      -%module base
      -
      -%inline %{
      +// File: base.h
       class base {
       public:
      -       int foo(void);
      +  int foo();
       };
      -%}
       
        -
      -%module derived
       
      -%import "base.i"
      +
      +// File: base_module.i
      +%module base_module
      +
      +%{
      +#include "base.h"
      +%}
      +%include "base.h"
      +
      +  + +
      +// File: derived_module.i
      +%module derived_module
      +
      +%import "base_module.i"
       
       %inline %{
       class derived : public base {
       public:
      -       int bar(void);
      +  int bar();
       };
       %}
       
      -

      To create the wrapper properly, module derived needs to know the -base class and that it's interface is covered in another module. The -line %import "base.i" lets SWIG know exactly that. The common mistake here is -to %import the .h file instead of the .i, 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.

      +

      To create the wrapper properly, module derived_module needs to know about the +base class and that its interface is covered in another module. The +line %import "base_module.i" lets SWIG know exactly that. Oftentimes +the .h file is passed to %import instead of the .i, +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: +

      -

      15.2 The SWIG runtime code

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

      +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 module attribute in the %import directive. +The derived_module.i file shown above could be replaced with the following: + +

      +// File: derived_module.i
      +%module derived_module
      +
      +%import(module="base_module") "base.h"
      +
      +%inline %{
      +class derived : public base {
      +public:
      +  int bar();
      +};
      +
      + +

      +Note that "base_module" is the module name and is the same as that specified in %module +in base_module.i as well as the %import in derived_module.i. +

      + +

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

      + +

      15.3 The SWIG runtime code

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

      -

      15.3 External access to the runtime

      +

      15.4 External access to the runtime

      -

      As described in The run-time type checker, +

      As described in The run-time type checker, the functions SWIG_TypeQuery, SWIG_NewPointerObj, and others sometimes need to be called. Calling these functions from a typemap is supported, since the typemap code is embedded into the _wrap.c 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.

      -

      15.4 A word of caution about static libraries

      +

      15.5 A word of caution about static libraries

      @@ -200,7 +290,7 @@ into it. This is very often NOT 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.

      -

      15.5 References

      +

      15.6 References

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

      -

      15.6 Reducing the wrapper file size

      +

      15.7 Reducing the wrapper file size

      diff --git a/Doc/Manual/Mzscheme.html b/Doc/Manual/Mzscheme.html index 699168322..3b49a2974 100644 --- a/Doc/Manual/Mzscheme.html +++ b/Doc/Manual/Mzscheme.html @@ -2,17 +2,19 @@ -SWIG and MzScheme +SWIG and MzScheme/Racket -

      24 SWIG and MzScheme

      +

      28 SWIG and MzScheme/Racket

      @@ -20,9 +22,9 @@

      -This section contains information on SWIG's support of MzScheme. +This section contains information on SWIG's support of Racket, formally known as MzScheme. -

      24.1 Creating native MzScheme structures

      +

      28.1 Creating native structures

      @@ -63,8 +65,116 @@ Then in scheme, you can use regular struct access procedures like

      +

      28.2 Simple example

      + +

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

      + +

      +C header file: +

      + +
      +
      +// example.h
      +int fact(int n);
      +
      +
      + +

      +C source code: +

      + +
      +
      +// File: example.c
      +#include "example.h"
      +
      +int fact(int n) {
      +  if (n < 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);
      +  }
      +}
      +
      +
      + +

      +SWIG interface file: +

      + +
      +
      +/* File: example.i */
      +%module example
      +
      +%{
      +#include "example.h"
      +%}
      +
      +int fact(int n);
      +
      +
      + +

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

      + +
      +
      +% 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->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.
      +> (require "example.ss")
      +> (fact 5)
      +120
      +> ^D
      +% echo 'It works!'
      +
      +
      + + +

      +Some points of interest: +

      +
        +
      • This is on a 64-bit machine, so we have to include the -m32 option when building the object file +
      • 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). +
      • 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). +
      • 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"). +
      • 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. +
      + +

      28.3 External documentation

      + + +

      +See the C API for more description of using the mechanism for adding extensions. The main documentation is here. +

      + +

      +Tip: mzc's --vv option is very useful for debugging the inevitable library problems you'll encounter.

      diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html index 79ede443f..ba8aa5fa9 100644 --- a/Doc/Manual/Ocaml.html +++ b/Doc/Manual/Ocaml.html @@ -6,7 +6,7 @@ -

      25 SWIG and Ocaml

      +

      29 SWIG and Ocaml

        @@ -80,7 +80,7 @@ If you're not familiar with the Objective Caml language, you can visit The Ocaml Website.

        -

        25.1 Preliminaries

        +

        29.1 Preliminaries

        @@ -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 Dl package + href="http://download.camlcity.org/download/">Dl package . 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.

        -

        25.1.1 Running SWIG

        +

        29.1.1 Running SWIG

        @@ -122,7 +122,7 @@ you will compile the file example_wrap.c with ocamlc or the resulting .ml and .mli files as well, and do the final link with -custom (not needed for native link).

        -

        25.1.2 Compiling the code

        +

        29.1.2 Compiling the code

        @@ -158,7 +158,7 @@ the user more freedom with respect to custom typing.

      -

      25.1.3 The camlp4 module

      +

      29.1.3 The camlp4 module

      @@ -234,7 +234,7 @@ let b = C_string (getenv "PATH") -

      25.1.4 Using your module

      +

      29.1.4 Using your module

      @@ -248,7 +248,7 @@ When linking any ocaml bytecode with your module, use the -custom option is not needed when you build native code.

      -

      25.1.5 Compilation problems and compiling with C++

      +

      29.1.5 Compilation problems and compiling with C++

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

      -

      25.2 The low-level Ocaml/C interface

      +

      29.2 The low-level Ocaml/C interface

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

      -

      25.2.1 The generated module

      +

      29.2.1 The generated module

      @@ -394,7 +394,7 @@ it describes the output SWIG will generate for class definitions. -

      25.2.2 Enums

      +

      29.2.2 Enums

      @@ -457,7 +457,7 @@ val x : Enum_test.c_obj = C_enum `a

    -

    25.2.2.1 Enum typing in Ocaml

    +

    29.2.2.1 Enum typing in Ocaml

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

    -

    25.2.3 Arrays

    +

    29.2.3 Arrays

    -

    25.2.3.1 Simple types of bounded arrays

    +

    29.2.3.1 Simple types of bounded arrays

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

    -

    25.2.3.2 Complex and unbounded arrays

    +

    29.2.3.2 Complex and unbounded arrays

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

    -

    25.2.3.3 Using an object

    +

    29.2.3.3 Using an object

    @@ -521,7 +521,7 @@ Consider writing an object when the ending condition of your array is complex, such as using a required sentinel, etc.

    -

    25.2.3.4 Example typemap for a function taking float * and int

    +

    29.2.3.4 Example typemap for a function taking float * and int

    @@ -572,7 +572,7 @@ void printfloats( float *tab, int len ); -

    25.2.4 C++ Classes

    +

    29.2.4 C++ Classes

    @@ -615,7 +615,7 @@ the underlying pointer, so using create_[x]_from_ptr alters the returned value for the same object.

    -

    25.2.4.1 STL vector and string Example

    +

    29.2.4.1 STL vector and string Example

    @@ -634,13 +634,13 @@ length. Instead, use multiple returns, as in the argout_ref example. #include "example.h" %} -%include stl.i +%include <stl.i> namespace std { %template(StringVector) std::vector < string >; }; -%include example.h +%include "example.h" This example is in Examples/ocaml/stl @@ -695,7 +695,7 @@ baz # -

    25.2.4.2 C++ Class Example

    +

    29.2.4.2 C++ Class Example

    @@ -725,7 +725,7 @@ public: }; -

    25.2.4.3 Compiling the example

    +

    29.2.4.3 Compiling the example

    @@ -743,7 +743,7 @@ bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
       -L$QTPATH/lib -cclib -lqt
     
    -

    25.2.4.4 Sample Session

    +

    29.2.4.4 Sample Session

    @@ -770,10 +770,10 @@ Assuming you have a working installation of QT, you will see a window
     containing the string "hi" in a button.  
     

    -

    25.2.5 Director Classes

    +

    29.2.5 Director Classes

    -

    25.2.5.1 Director Introduction

    +

    29.2.5.1 Director Introduction

    @@ -800,7 +800,7 @@ class foo { };

    -

    25.2.5.2 Overriding Methods in Ocaml

    +

    29.2.5.2 Overriding Methods in Ocaml

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

    -

    25.2.5.3 Director Usage Example

    +

    29.2.5.3 Director Usage Example

    @@ -887,7 +887,7 @@ in a more effortless style in ocaml, while leaving the "engine" part of the program in C++.

    -

    25.2.5.4 Creating director objects

    +

    29.2.5.4 Creating director objects

    @@ -928,7 +928,7 @@ object from causing a core dump, as long as the object is destroyed properly.

    -

    25.2.5.5 Typemaps for directors, directorin, directorout, directorargout

    +

    29.2.5.5 Typemaps for directors, directorin, directorout, directorargout

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

    -

    25.2.5.6 directorin typemap

    +

    29.2.5.6 directorin typemap

    @@ -950,7 +950,7 @@ code receives when you are called. In general, a simple directorin typ can use the same body as a simple out typemap.

    -

    25.2.5.7 directorout typemap

    +

    29.2.5.7 directorout typemap

    @@ -961,7 +961,7 @@ for the same type, except when there are special requirements for object ownership, etc.

    -

    25.2.5.8 directorargout typemap

    +

    29.2.5.8 directorargout typemap

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

    -

    25.2.6 Exceptions

    +

    29.2.6 Exceptions

    diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html index 97e1be17c..3229299d5 100644 --- a/Doc/Manual/Octave.html +++ b/Doc/Manual/Octave.html @@ -8,13 +8,14 @@ -

    26 SWIG and Octave

    +

    30 SWIG and Octave

    • Preliminaries
    • Running SWIG @@ -46,7 +47,7 @@

      Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB. -More information can be found at www.octave.org. +More information can be found at Octave web site.

      @@ -54,21 +55,26 @@ More information can be found at 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).

      -

      26.1 Preliminaries

      +

      30.1 Preliminaries

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

      -

      26.2 Running SWIG

      +

      +As of SWIG 2.0.5, the Octave module should work with Octave versions 3.0.5, 3.2.4, and 3.4.0. +

      + +

      30.2 Running SWIG

      -Let's start with a very simple SWIG interface file: +Let's start with a very simple SWIG interface file, example.i:

      -
      %module example
      +
      +%module example
       %{
       #include "example.h"
       %}
      @@ -76,20 +82,49 @@ int gcd(int x, int y);
       extern double Foo; 

      -To build an Octave module, run SWIG using the -octave option. The -c++ 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 -octave option:

      -
      $ swig -octave -c++ example.i 
      +
      $ swig -octave -o example_wrap.cpp example.i 

      -This creates a C/C++ source file example_wrap.cxx. 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 -c++ option is also required when wrapping C++ code:

      + +
      $ swig -octave -c++ -o example_wrap.cpp example.i 
      +

      -The swig command line has a number of options you can use, like to redirect it's output. Use swig --help to learn about these. +This creates a C++ source file example_wrap.cpp. 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.

      -

      26.2.1 Compiling a dynamic module

      +

      30.2.1 Command-line options

      + + +

      +The swig command line has a number of options you can use, like to redirect its output. Use swig -help to learn about these. +Options specific to the Octave module are: +

      + +
      +
      $ swig -octave -help
      +...
      +Octave Options (available with -octave)
      +     -global       - Load all symbols into the global namespace [default]
      +     -globals name - Set name 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 str - Prefix str for global operator functions [default: 'op_']
      +
      + +

      +The -global and -noglobal options determine whether the Octave module will load all symbols into the global namespace in addition to the global namespace. +The -globals 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 -opprefix options sets the prefix of the names of global/friend operator functions. +

      + +

      30.2.2 Compiling a dynamic module

      @@ -98,8 +133,8 @@ Building an oct file is usually done with the mkoctfile command (either within O

      -$ 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
       

      @@ -116,7 +151,7 @@ $ mkoctfile example_wrap.cxx example.c

      octave:1> example
      -

      26.2.2 Using your module

      +

      30.2.3 Using your module

      @@ -134,10 +169,10 @@ octave:4> example.cvar.Foo=4; octave:5> example.cvar.Foo ans = 4

      -

      26.3 A tour of basic C/C++ wrapping

      +

      30.3 A tour of basic C/C++ wrapping

      -

      26.3.1 Modules

      +

      30.3.1 Modules

      @@ -149,37 +184,73 @@ When Octave is asked to invoke example, it will try to find the .m or .

      -Giving this function a parameter "global" will cause it to load all symbols into the global namespace in addition to the example namespace. For example: +An Octave module takes three options, -global, -noglobal, and -globals, which behave the same as the corresponding swig command-line options. +Here are some example usages:

      -
      $ octave -q
      -octave:1> example("global")
      -octave:2> gcd(4,6)
      +    
      +octave:1> example -help
      +usage: example [-global|-noglobal] [-globals <name>]
      +octave:2> example -global
      +octave:3> gcd(4,6)
       ans =  2
      -octave:3> cvar.Foo
      +octave:4> cvar.Foo
       ans =  3
      -octave:4> cvar.Foo=4;
      -octave:5> cvar.Foo
      -ans =  4 
      +octave:5> cvar.Foo=4;
      +octave:6> cvar.Foo
      +ans =  4
       
      +
      +
      +octave:1> example -noglobal
      +octave:2> gcd(6,9)
      +ans =  3
      +octave:3> cvar.Foo
      +error: `cvar' undefined near line 3 column 1
      +octave:3> example.cvar.Foo
      +ans =  3
      +
      +
      +
      +octave:1> example -globals mycvar
      +octave:2> cvar.Foo
      +error: `cvar' undefined near line 2 column 1
      +octave:2> mycvar.Foo
      +ans =  3
      +
      +

      - It is also possible to rename the module namespace with an assignment, as in:
      -

      octave:1> example;
      +     It is also possible to rename the module / global variables namespaces with an assignment, as in: 
      +
      +octave:1> example
       octave:2> c=example;
       octave:3> c.gcd(10,4)
      -ans =  2 
      - -

      -All global variables are put into the cvar namespace object. This is accessible either as my_module.cvar, or just cvar (if the module is imported into the global namespace). -

      -

      -One can also rename it by simple assignment, e.g., -

      -
      -octave:1> some_vars = cvar;
      +ans =  2
      +octave:4> some_vars = cvar;
      +octave:5> some_vars.Foo
      +ans =  3
       
      -

      26.3.2 Functions

      +

      +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: +

      + +
      +octave:1> function l = my_lcm(a,b)
      +> example
      +> l = abs(a*b)/example.gcd(a,b);
      +> endfunction
      +octave:2> my_lcm(4,6)
      +ans =  12
      +octave:3> example.gcd(4,6)
      +error: can't perform indexing operations for <unknown type> type
      +octave:3> example;
      +octave:4> example.gcd(4,6)
      +ans =  2
      +
      + +

      30.3.2 Functions

      @@ -196,7 +267,7 @@ int fact(int n);

      octave:1> example.fact(4)
       24 
      -

      26.3.3 Global variables

      +

      30.3.3 Global variables

      @@ -231,7 +302,7 @@ extern double Foo;

      - SWIG will allow the the reading of Foo but when a set attempt is made, an error function will be called. + SWIG will allow the reading of Foo but when a set attempt is made, an error function will be called.

      octave:1> example
      @@ -249,7 +320,7 @@ octave:2> example.PI=3.142;
       octave:3> example.PI
       ans =  3.1420 
      -

      26.3.4 Constants and enums

      +

      30.3.4 Constants and enums

      @@ -271,7 +342,7 @@ example.SCONST="Hello World" example.SUNDAY=0 ....

    -

    26.3.5 Pointers

    +

    30.3.5 Pointers

    @@ -318,7 +389,7 @@ octave:2> 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 -

    26.3.6 Structures and C++ classes

    +

    30.3.6 Structures and C++ classes

    @@ -453,7 +524,7 @@ ans = 1 Depending on the ownership setting of a swig_ref, it may call C++ destructors when its reference count goes to zero. See the section on memory management below for details.

    -

    26.3.7 C++ inheritance

    +

    30.3.7 C++ inheritance

    @@ -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 swig_ref.

    -

    26.3.8 C++ overloaded functions

    +

    30.3.8 C++ overloaded functions

    @@ -472,7 +543,7 @@ The dispatch function selects which overload to call (if any) based on the passe typecheck typemaps are used to analyze each argument, as well as assign precedence. See the chapter on typemaps for details.

    -

    26.3.9 C++ operators

    +

    30.3.9 C++ operators

    @@ -572,7 +643,11 @@ On the C++ side, the default mappings are as follows: %rename(__brace) *::operator[]; -

    26.3.10 Class extension with %extend

    +

    +Octave can also utilise friend (i.e. non-member) operators with a simple %rename: see the example in the Examples/octave/operator directory. +

    + +

    30.3.10 Class extension with %extend

    @@ -602,7 +677,7 @@ octave:3> printf("%s\n",a); octave:4> a.__str() 4 -

    26.3.11 C++ templates

    +

    30.3.11 C++ templates

    @@ -679,14 +754,14 @@ ans = -

    26.3.12 C++ Smart Pointers

    +

    30.3.12 C++ Smart Pointers

    C++ smart pointers are fully supported as in other modules.

    -

    26.3.13 Directors (calling Octave from C++ code)

    +

    30.3.13 Directors (calling Octave from C++ code)

    @@ -747,7 +822,8 @@ Note that you have to enable directors via the %feature directive (see other mod subclass() will accept any number of C++ bases or other subclass()'ed objects, (string,octave_value) pairs, and function_handles. 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.,

    -octave:1> B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',@(self) do_stuff())
    +octave:1> B=@(some_var=2) subclass(A(),'some_var',some_var,@some_func,'another_func',
    +@(self) do_stuff())
     

    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 -

    26.3.14 Threads

    +

    30.3.14 Threads

    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.

    -

    26.3.15 Memory management

    +

    30.3.15 Memory management

    @@ -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/subclass()'ing).

    -

    26.3.16 STL support

    +

    30.3.16 STL support

    -This is some skeleton support for various STL containers. +Various STL library files are provided for wrapping STL containers.

    -

    26.3.17 Matrix typemaps

    +

    30.3.17 Matrix typemaps

    diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html index b7cdaf0e5..0a4b61bd5 100644 --- a/Doc/Manual/Perl5.html +++ b/Doc/Manual/Perl5.html @@ -6,7 +6,7 @@ -

    27 SWIG and Perl5

    +

    31 SWIG and Perl5

  • Input and output parameters -
  • Exception handling +
  • Exception handling
  • Remapping datatypes with typemaps
  • Typemap Examples
      -
    • Converting a Perl5 array to a char ** -
    • Return values +
    • Converting a Perl5 array to a char ** +
    • Return values
    • Returning values from arguments
    • Accessing array structure members
    • Turning Perl references into C pointers @@ -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.

      -

      27.1 Overview

      +

      31.1 Overview

      @@ -108,12 +108,12 @@ described. Advanced customization features, typemaps, and other options are found near the end of the chapter.

      -

      27.2 Preliminaries

      +

      31.2 Preliminaries

      -To build a Perl5 module, run Swig using the -perl option as -follows : +To build a Perl5 module, run SWIG using the -perl option as +follows:

      @@ -133,11 +133,11 @@ To build the module, you will need to compile the file
       example_wrap.c and link it with the rest of your program.
       

      -

      27.2.1 Getting the right header files

      +

      31.2.1 Getting the right header files

      -In order to compile, SWIG extensions need the following Perl5 header files :

      +In order to compile, SWIG extensions need the following Perl5 header files:

       #include "Extern.h"
      @@ -149,23 +149,23 @@ In order to compile, SWIG extensions need the following Perl5 header files :

      These are typically located in a directory like this

      -/usr/lib/perl5/5.00503/i386-linux/CORE
      +/usr/lib/perl/5.14/CORE
       

      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:

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

      27.2.2 Compiling a dynamic module

      +

      31.2.2 Compiling a dynamic module

      @@ -176,9 +176,9 @@ using commands like this (shown for Linux):

       $ 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
       

      @@ -198,13 +198,13 @@ the target should be named `example.so', `example.sl', or the appropriate dynamic module name on your system.

      -

      27.2.3 Building a dynamic module with MakeMaker

      +

      31.2.3 Building a dynamic module with MakeMaker

      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 :

      +script such as the following:

       # File : Makefile.PL
      @@ -218,12 +218,12 @@ WriteMakefile(
       

      -Now, to build a module, simply follow these steps :

      +Now, to build a module, simply follow these steps:

      -% perl Makefile.PL
      -% make
      -% make install
      +$ perl Makefile.PL
      +$ make
      +$ make install
       

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

      -

      27.2.4 Building a static version of Perl

      +

      31.2.4 Building a static version of Perl

      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 :

      +extension, you first need to invoke SWIG as follows:

      -% swig -perl -static example.i
      +$ swig -perl -static example.i
       

      @@ -253,7 +253,7 @@ By default SWIG includes code for dynamic loading, but the Next, you will need to supply a main() function that initializes your extension and starts the Perl interpreter. While, this may sound daunting, SWIG can do this for you automatically as -follows :

      +follows:

       %module example
      @@ -264,14 +264,14 @@ extern int fact(int);
       %}
       
       // Include code for rebuilding Perl
      -%include perlmain.i
      +%include <perlmain.i>
       

      -The same thing can be accomplished by running SWIG as follows :

      +The same thing can be accomplished by running SWIG as follows:

      -% swig -perl -static -lperlmain.i example.i
      +$ swig -perl -static -lperlmain.i example.i
       

      @@ -290,7 +290,7 @@ for a dynamic module, but change the link line to something like this:

      -% 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
       
      @@ -301,7 +301,7 @@ added to it. Depending on your machine, you may need to link with additional libraries such as -lsocket, -lnsl, -ldl, etc.

      -

      27.2.5 Using the module

      +

      31.2.5 Using the module

      @@ -323,9 +323,7 @@ A common error received by first-time users is the following:

       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.
       
      @@ -363,7 +361,7 @@ Another common error is the following:
       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:
       
       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).
       

      -

      27.2.6 Compilation problems and compiling with C++

      +

      31.2.6 Compilation problems and compiling with C++

      @@ -472,10 +470,10 @@ compiler. For example:

      -% 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
      +$ 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
      +$ g++ -shared example.o example_wrap.o -o example.so
       

      @@ -485,10 +483,10 @@ Solaris, you often need to add an extra library -lCrun like this:

      -% 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 -lCrun
      +$ 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 -lCrun
       

      @@ -503,7 +501,7 @@ it needs to be. So you should compile the wrapper like:

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

      @@ -511,7 +509,7 @@ it needs to be. So you should compile the wrapper like:

      -% perl -e 'use Config; print $Config{ccflags};'
      +$ perl -e 'use Config; print "$Config{ccflags}\n";'
       

      @@ -519,8 +517,8 @@ So you could also compile the wrapper like

      -% 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}'`
       

      @@ -568,8 +566,8 @@ can behave strangely when working with multiple modules.

      It should be noted that you may get a lot of error messages -about the `bool' datatype when compiling a C++ Perl module. If -you experience this problem, you can try the following :

      +about the 'bool' datatype when compiling a C++ Perl module. If +you experience this problem, you can try the following:

      • Use -DHAS_BOOL 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 swig-user mailing list.

        -

        27.2.7 Compiling for 64-bit platforms

        +

        31.2.7 Compiling for 64-bit platforms

        @@ -626,7 +624,7 @@ also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

        -

        27.3 Building Perl Extensions under Windows

        +

        31.3 Building Perl Extensions under Windows

        @@ -637,13 +635,13 @@ section assumes you are using SWIG with Microsoft Visual C++ although the procedure may be similar with other compilers.

        -

        27.3.1 Running SWIG from Developer Studio

        +

        31.3.1 Running SWIG from Developer Studio

        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 :

        +roughly requires these steps:

        • Open up a new workspace and use the AppWizard to select a DLL @@ -651,7 +649,7 @@ project.
        • 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. example_wrap.c). Note : If using C++, choose a +(ie. example_wrap.c). Note: If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. 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:

          @@ -700,7 +698,7 @@ print "$a\n";
           
           
          -

          27.3.2 Using other compilers

          +

          31.3.2 Using other compilers

          @@ -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 Windows chapter.

          -

          27.4 The low-level interface

          +

          31.4 The low-level interface

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

          -

          27.4.1 Functions

          +

          31.4.1 Functions

          @@ -741,7 +739,7 @@ use example; $a = &example::fact(2);

      -

      27.4.2 Global variables

      +

      31.4.2 Global variables

      @@ -758,7 +756,7 @@ double Spam;

      -is accessed as follows :

      +is accessed as follows:

       use example;
      @@ -811,11 +809,11 @@ extern char *path;       // Declared later in the input
       
      -

      27.4.3 Constants

      +

      31.4.3 Constants

      -Constants are wrapped as read-only Perl variables. For example: +By default, constants are wrapped as read-only Perl variables. For example:

      @@ -838,14 +836,27 @@ $example::FOO = 2; # Error
      -

      27.4.4 Pointers

      +

      +Alternatively, if you use swig's -const 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: +

      + +
      +
      +use example;
      +print example::FOO,"\n";
      +
      +
      + +

      31.4.4 Pointers

      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 :

      +is. That is, if you have a C declaration like this:

       Matrix *new_Matrix(int n, int m);
      @@ -867,7 +878,7 @@ generated.

      To check to see if a value is the NULL pointer, use the -defined() command :

      +defined() command:

       if (defined($ptr)) {
      @@ -879,7 +890,7 @@ if (defined($ptr)) {
       

      -To create a NULL pointer, you should pass the undef value to +To create a NULL pointer, you should pass the undef value to a function.

      @@ -889,9 +900,9 @@ pointer that SWIG wrapper functions return. Suppose that $a and $b are two references that point to the same C object. In general, $a and $b will be different--since they are different references. Thus, it is a mistake to check the equality -of $a and $b to check the equality of two C +of $a and $b 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:

      @@ -947,7 +958,7 @@ as XS and xsubpp.  Given the advancement of the SWIG typesystem and the
       SWIG and XS, this is no longer supported.
       

      -

      27.4.5 Structures

      +

      31.4.5 Structures

      @@ -1081,12 +1092,12 @@ void Bar_f_set(Bar *b, Foo *val) {

      -

      27.4.6 C++ classes

      +

      31.4.6 C++ classes

      C++ classes are wrapped by building a set of low level accessor functions. -Consider the following class : +Consider the following class:

      @@ -1104,7 +1115,7 @@ static void print(List *l);
       

      -When wrapped by SWIG, the following functions are created : +When wrapped by SWIG, the following functions are created:

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

      -

      27.4.7 C++ classes and type-checking

      +

      31.4.7 C++ classes and type-checking

      @@ -1182,7 +1193,7 @@ If necessary, the type-checker also adjusts the value of the pointer (as is nece multiple inheritance is used).

      -

      27.4.8 C++ overloaded functions

      +

      31.4.8 C++ overloaded functions

      @@ -1226,7 +1237,7 @@ example::Spam_foo_d($s,3.14); Please refer to the "SWIG Basics" chapter for more information.

      -

      27.4.9 Operators

      +

      31.4.9 Operators

      @@ -1253,17 +1264,17 @@ The following C++ operators are currently supported by the Perl module:

    • operator or
    -

    27.4.10 Modules and packages

    +

    31.4.10 Modules and packages

    When you create a SWIG extension, everything gets placed into a single Perl module. The name of the module is determined by the -%module directive. To use the module, do the following : +%module directive. To use the module, do the following:

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

    27.5 Input and output parameters

    +

    31.5 Input and output parameters

    @@ -1543,7 +1554,7 @@ example:

     %module example
    -%include typemaps.i
    +%include "typemaps.i"
     
     void add(int x, int y, int *REFERENCE);
     
    @@ -1567,7 +1578,7 @@ print "$c\n"; Note: The REFERENCE feature is only currently supported for numeric types (integers and floating point).

    -

    27.6 Exception handling

    +

    31.6 Exception handling

    @@ -1575,7 +1586,7 @@ The SWIG %exception 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:

    @@ -1732,7 +1743,7 @@ This is still supported, but it is deprecated.  The newer %exception di
     functionality, but it has additional capabilities that make it more powerful.
     

    -

    27.7 Remapping datatypes with typemaps

    +

    31.7 Remapping datatypes with typemaps

    @@ -1749,7 +1760,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Perl interface.

    -

    27.7.1 A simple typemap example

    +

    31.7.1 A simple typemap example

    @@ -1783,7 +1794,7 @@ The $input variable is the input object (usually a SV *).

    -When this example is used in Perl5, it will operate as follows : +When this example is used in Perl5, it will operate as follows:

    @@ -1792,7 +1803,7 @@ $n = example::fact(6);
     print "$n\n";
     ...
     
    -Output :
    +Output:
     Received an integer : 6
     720
     
    @@ -1853,7 +1864,7 @@ example::count("e","Hello World");
    -

    27.7.2 Perl5 typemaps

    +

    31.7.2 Perl5 typemaps

    @@ -1958,7 +1969,7 @@ Return of C++ member data (all languages). Check value of input parameter.

    -

    27.7.3 Typemap variables

    +

    31.7.3 Typemap variables

    @@ -2029,7 +2040,7 @@ properly assigned. The Perl name of the wrapper function being created.

    -

    27.7.4 Useful functions

    +

    31.7.4 Useful functions

    @@ -2098,7 +2109,7 @@ int sv_isa(SV *, char *0;

  • -

    27.8 Typemap Examples

    +

    31.8 Typemap Examples

    @@ -2107,7 +2118,7 @@ might look at the files "perl5.swg" and "typemaps.i" in the SWIG library.

    -

    27.8.1 Converting a Perl5 array to a char **

    +

    31.8.1 Converting a Perl5 array to a char **

    @@ -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() {

    When this module is compiled, the wrapped C functions can be used in a -Perl script as follows : +Perl script as follows:

    @@ -2199,7 +2210,7 @@ print @$b,"\n";                                  # Print it out
     
    -

    27.8.2 Return values

    +

    31.8.2 Return values

    @@ -2214,7 +2225,7 @@ number of output values.

    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 EXTEND() macro as in : +can be done using the EXTEND() macro as in:

    @@ -2228,7 +2239,7 @@ can be done using the EXTEND() macro as in :
     }
     
    -

    27.8.3 Returning values from arguments

    +

    31.8.3 Returning values from arguments

    @@ -2273,7 +2284,7 @@ int multout(double a, double b, double *OUTPUT, double *OUTPUT);

    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:

    @@ -2282,11 +2293,11 @@ print "multout(7,13) = @r\n";
     ($x,$y) = multout(7,13);
     
    -

    27.8.4 Accessing array structure members

    +

    31.8.4 Accessing array structure members

    -Consider the following data structure : +Consider the following data structure:

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

    -

    27.8.5 Turning Perl references into C pointers

    +

    31.8.5 Turning Perl references into C pointers

    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:

    @@ -2361,7 +2372,7 @@ void add(double a, double b, double *c) {
     

    -A common misinterpretation of this function is the following Perl script : +A common misinterpretation of this function is the following Perl script:

    @@ -2398,7 +2409,7 @@ To make this work with a reference, you can use a typemap such as this:
     

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

    @@ -2410,7 +2421,7 @@ print "$c\n";
     
     
    -

    27.8.6 Pointer handling

    +

    31.8.6 Pointer handling

    @@ -2489,7 +2500,7 @@ For example:

    -

    27.9 Proxy classes

    +

    31.9 Proxy classes

    @@ -2505,7 +2516,7 @@ to the underlying code. This section describes the implementation details of the proxy interface.

    -

    27.9.1 Preliminaries

    +

    31.9.1 Preliminaries

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

    -

    27.9.2 Structure and class wrappers

    +

    31.9.2 Structure and class wrappers

    -Suppose you have the following SWIG interface file : +Suppose you have the following SWIG interface file:

    @@ -2653,13 +2664,13 @@ $v->DESTROY();
     
     
    -

    27.9.3 Object Ownership

    +

    31.9.3 Object Ownership

    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:

    @@ -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:
     

    @@ -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 %OWNER hash.  This is
    -done using the DISOWN method.
    +done using the DISOWN method.
     

    @@ -2740,11 +2751,11 @@ counting, garbage collection, or advanced features one might find in
     sophisticated languages.
     

    -

    27.9.4 Nested Objects

    +

    31.9.4 Nested Objects

    -Suppose that we have a new object that looks like this : +Suppose that we have a new object that looks like this:

    @@ -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 %BLESSEDMEMBERS hash which would
    -look like this (along with some supporting code) :
    +look like this (along with some supporting code):
     

    @@ -2783,7 +2794,7 @@ unmodified.
     

    -This implementation allows us to operate on nested structures as follows : +This implementation allows us to operate on nested structures as follows:

    @@ -2793,12 +2804,12 @@ $p->{f}->{x} = 0.0;
     %${$p->{v}} = ( x=>0, y=>0, z=>0);         
     
    -

    27.9.5 Proxy Functions

    +

    31.9.5 Proxy Functions

    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:

    @@ -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:
     

    @@ -2827,13 +2838,13 @@ This function replaces the original function, but operates in an
     identical manner.
     

    -

    27.9.6 Inheritance

    +

    31.9.6 Inheritance

    Simple C++ inheritance is handled using the Perl @ISA array in each class package. For example, if you have the following -interface file : +interface file:

    @@ -2868,7 +2879,7 @@ public:
     

    -The resulting, Perl wrapper class will create the following code : +The resulting, Perl wrapper class will create the following code:

    @@ -2903,12 +2914,12 @@ particular, inheritance of data members is extremely tricky (and I'm
     not even sure if it really works).
     

    -

    27.9.7 Modifying the proxy methods

    +

    31.9.7 Modifying the proxy methods

    It is possible to override the SWIG generated proxy/shadow methods, using %feature("shadow"). -It works like all the other %feature directives. +It works like all the other %feature directives. Here is a simple example showing how to add some Perl debug code to the constructor:

    @@ -2931,7 +2942,7 @@ public: };
    -

    27.10 Adding additional Perl code

    +

    31.10 Adding additional Perl code

    diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index 6b654fde5..19ace7192 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -7,14 +7,13 @@ -

    28 SWIG and PHP

    +

    32 SWIG and PHP

    @@ -40,24 +49,27 @@

    -Caution: This chapter (and module!) is still under construction +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. +

    + +

    +Currently any PHP5 release should work, but we don't regularly test with +PHP < 5.3.

    In this chapter, we discuss SWIG's support of PHP. The PHP module -was extensively rewritten in release 1.3.26, and although it is -significantly more functional, it still does not implement all the -features available in some of the other languages. +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 now supports most +of the features available in some of the other languages.

    -The examples and test cases have been developed with PHP4. Release -1.3.30 added support for generating PHP5 class wrappers for C++ -libraries. -

    - -

    -In order to use this module, you will need to have a copy of the PHP4 or PHP5 +In order to use this module, you will need to have a copy of the PHP5 include files to compile the SWIG generated files. If you installed PHP from a binary package, you may need to install a "php-dev" or "php-devel" package for these to be installed. You can find out where these files are @@ -67,7 +79,7 @@ your extension into php directly, you will need the complete PHP source tree available.

    -

    28.1 Generating PHP Extensions

    +

    32.1 Generating PHP Extensions

    @@ -88,19 +100,20 @@ you wish to statically link the extension into the php interpreter. The third file, example.php can be included by PHP scripts. It attempts to dynamically load the extension and contains extra php code specified -in the interface file. If wrapping C++ code for PHP5, it will +in the interface file. If wrapping C++ code with PHP classes, it will also contain PHP5 class wrappers.

    -Swig can generate PHP extensions from C++ libraries as well when +SWIG can generate PHP extensions from C++ libraries as well when given the -c++ option. The support for C++ is discussed in more detail in section 27.2.6.

    The usual (and recommended) way is to build the extension as a separate -dynamically loaded module. You can then specify that this be loaded +dynamically loaded module (which is supported by all modern operating +systems). You can then specify that this be loaded automatically in php.ini or load it explicitly for any script which needs it.

    @@ -110,17 +123,16 @@ It is also possible to rebuild PHP from source so that your module is statically linked into the php executable/library. This is a lot more work, and also requires a full rebuild of PHP to update your module, and it doesn't play nicely with package system. We don't recommend -this approach, but if you really want to do this, the -phpfull -command line argument to swig may be of use - see below for details. +this approach, or provide explicit support for it.

    -

    28.1.1 Building a loadable extension

    +

    32.1.1 Building a loadable extension

    To build your module as a dynamically loadable extension, use compilation commands like these (if you aren't using GCC, the commands will be different, -and there may be so variation between platforms - these commands should at +and there may be some variation between platforms - these commands should at least work for Linux though):

    @@ -129,135 +141,7 @@ least work for Linux though): gcc -shared example_wrap.o -o example.so
    -

    -There is a deprecated -make command line argument to swig which will -generate an additional file makefile which can usually build the -extension (at least on some UNIX platforms), but the Makefile generated isn't -very flexible, and the commands required are trivial so it is simpler to just -add them to your Makefile or other build system directly. We recommend that -you don't use -make and it's likely to be removed at some point. -

    - -

    28.1.2 Building extensions into PHP

    - - -

    -Note that we don't recommend this approach - it's cleaner and simpler to -use dynamically loadable modules, which are supported by all modern OSes. -Support for this may be discontinued entirely in the future. -

    - -

    -It is possible to rebuild PHP itself with your module statically linked -in. To do this, you can use the -phpfull command line option to -swig. Using this option will generate three additional files. The first -extra file, config.m4 contains the m4 and shell code needed to -enable the extension as part of the PHP build process. The second -extra file, Makefile.in contains the information needed to -build the final Makefile after substitutions. The third and final -extra file, CREDITS should contain the credits for the -extension. -

    - -

    -To build with phpize, after you have run swig you will need to run the -'phpize' command (installed as part of php) in the same -directory. This re-creates the php build environment in that -directory. It also creates a configure file which includes the shell -code from the config.m4 that was generated by SWIG, this configure -script will accept a command line argument to enable the extension to -be run (by default the command line argument is --enable-modulename, -however you can edit the config.m4 file before running phpize to -accept --with-modulename. You can also add extra tests in config.m4 to -check that a correct library version is installed or correct header -files are included, etc, but you must edit this file before running -phpize.) You can also get SWIG to generate simple extra tests for -libraries and header files for you. -

    - -
    -	swig -php -phpfull
    -
    - -

    -If you depend on source files not generated by SWIG, before generating -the configure file, you may need to edit the Makefile.in -file. This contains the names of the source files to compile (just the -wrapper file by default) and any additional libraries needed to be -linked in. If there are extra C files to compile, you will need to add -them to the Makefile.in, or add the names of libraries if they are -needed. In simple cases SWIG is pretty good at generating a complete -Makefile.in and config.m4 which need no further editing. -

    - -

    -You then run the configure script with the command line argument needed -to enable the extension. Then run make, which builds the extension. -The extension object file will be left in the modules sub directory, you can -move it to wherever it is convenient to call from your php script. -

    - -

    -When using -phpfull, swig also accepts the following -additional optional arguments: -

    -
      -
    • -withincs "<incs>" Adds include files to the config.m4 file. -
    • -withlibs "<libs>" Links with the specified libraries. -
    • -withc "<files>" Compiles and links the additional specified C files. -
    • -withcxx "<files>" Compiles and links the additional specified C++ files. -
    - -

    -After running swig with the -phpfull switch, you will be left with a shockingly -similar set of files to the previous build process. However you will then need -to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension (e.g. mkdir php-4.0.6/ext/modulename). -

    - -

    -After moving the files into this directory, you will need to run the 'buildall' -script in the php source directory. This rebuilds the configure script -and includes the extra command line arguments from the module you have added. -

    - -

    -Before running the generated configure file, you may need to edit the -Makefile.in. This contains the names of the source files to compile ( -just the wrapper file by default) and any additional libraries needed to -link in. If there are extra C files to compile you will need to add them -to the Makefile, or add the names of libraries if they are needed. -In most cases Makefile.in will be complete, especially if you -make use of -withlibs and -withincs -

    - -
    -	swig -php -phpfull -withlibs "xapian omquery" --withincs "om.h"
    -
    - -

    -Will include in the config.m4 and Makefile.in search for -libxapian.a or libxapian.so and search for -libomquery.a or libomquery.so as well as a -search for om.h. -

    - -

    -You then need to run the configure command and pass the necessary command -line arguments to enable your module (by default this is --enable-modulename, -but this can be changed by editing the config.m4 file in the modules directory -before running the buildall script. In addition, extra tests can be added to -the config.m4 file to ensure the correct libraries and header files are -installed.) -

    - -

    -Once configure has completed, you can run make to build php. If this all -compiles correctly, you should end up with a php executable/library -which contains your new module. You can test it with a php script which -does not have the 'dl' command as used above. -

    - -

    28.1.3 Using PHP Extensions

    +

    32.1.2 Using PHP Extensions

    @@ -288,21 +172,22 @@ attempts to do the dl() call for you: include("example.php");

    -

    28.2 Basic PHP interface

    +

    32.2 Basic PHP interface

    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 %rename them. +other symbols unless care is taken to %rename them. At present +SWIG doesn't have support for the namespace feature added in PHP 5.3.

    -

    28.2.1 Constants

    +

    32.2.1 Constants

    -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 %constant SWIG directive. These will then be available from your PHP script as a PHP constant, (i.e. no dollar sign is needed to @@ -319,7 +204,7 @@ access them.) For example, with a swig interface file like this,

    -you can access the constants in your php script like this, +you can access the constants in your PHP script like this,

    @@ -333,9 +218,16 @@ echo "E = " . E . "\n";
     

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

    + +

    +For example,

    @@ -363,67 +255,12 @@ if(EASY_TO_MISPEL) {
     

    -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!

    -

    -The second 'feature' is that although constants are case sensitive (by -default), you cannot declare a constant twice with alternative -cases. E.g., -

    - -
    -
    -%module example
    -
    -#define TEST	Hello
    -#define Test	World
    -
    -
    - -

    -accessed from PHP, -

    - -
    -
    -include("example.php");
    -
    -echo TEST, Test;
    -
    -
    - -

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

    - -

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

    - -

    28.2.2 Global Variables

    +

    32.2.2 Global Variables

    @@ -472,7 +309,7 @@ undefined. At this time SWIG does not support custom accessor methods.

    -

    28.2.3 Functions

    +

    32.2.3 Functions

    @@ -525,7 +362,7 @@ print $s; # The value of $s was not changed. --> -

    28.2.4 Overloading

    +

    32.2.4 Overloading

    @@ -533,13 +370,13 @@ Although PHP does not support overloading functions natively, swig will generate dispatch functions which will use %typecheck typemaps to allow overloading. This dispatch function's operation and precedence is described in Wrapping +href="SWIGPlus.html#SWIGPlus_overloaded_methods">Wrapping Overloaded Functions and Methods.

    -

    28.2.5 Pointers and References

    +

    32.2.5 Pointers and References

    @@ -605,7 +442,7 @@ One can include cpointer.i to generate PHP wrappers to int

     %module example
    -%include cpointer.i
    +%include "cpointer.i"
     %pointer_functions(int,intp)
     
     void add( int *in1, int *in2, int *result);
    @@ -639,7 +476,7 @@ parameter names as appropriate.
     
     
     %module example
    -%include typemaps.i
    +%include "typemaps.i"
     
     void add( int *INPUT, int *INPUT, int *OUTPUT);
     
    @@ -671,7 +508,7 @@ named typemap REFERENCE.
     
     
     %module example
    -%include phppointers.i
    +%include "phppointers.i"
     
     void add( int *REF, int *REF, int *REF);
     
    @@ -713,24 +550,15 @@ PHP in a number of ways: by using unset on an existing
     variable, or assigning NULL to a variable.
     

    -

    28.2.6 Structures and C++ classes

    +

    32.2.6 Structures and C++ classes

    -SWIG defaults to wrapping C++ structs and classes with PHP classes. This -requires SWIG to generate different code for PHP4 and PHP5, so you must -specify which you want using -php4 or -php5 (currently --php generates PHP4 class wrappers for compatibility with -SWIG 1.3.29 and earlier, but this may change in the future). -

    - -

    -PHP4 classes are implemented entirely using the Zend C API so -no additional php code is generated. For PHP5, a PHP wrapper -class is generated which calls a set of flat functions wrapping the C++ class. -In many cases the PHP4 and PHP5 wrappers will behave the same way, -but the PHP5 ones make use of better PHP5's better OO functionality -where appropriate. +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.

    @@ -754,7 +582,7 @@ struct Complex {

    -Would be used in the following way from either PHP4 or PHP5: +Would be used in the following way from PHP5:

    @@ -783,7 +611,7 @@ Would be used in the following way from either PHP4 or PHP5:
     Member variables and methods are accessed using the -> operator.
     

    -

    28.2.6.1 Using -noproxy

    +

    32.2.6.1 Using -noproxy

    @@ -809,7 +637,7 @@ Complex_im_set($obj,$d); Complex_im_get($obj);

    -

    28.2.6.2 Constructors and Destructors

    +

    32.2.6.2 Constructors and Destructors

    @@ -850,13 +678,13 @@ the programmer can either reassign the variable or call unset($v)

    -

    28.2.6.3 Static Member Variables

    +

    32.2.6.3 Static Member Variables

    -Static member variables are not supported in PHP4, and it does not -appear to be possible to intercept accesses to static member variables -in PHP5. Therefore, static member variables are +Static member variables in C++ are not wrapped as such in PHP +as it does not appear to be possible to intercept accesses to such variables. +Therefore, static member variables are wrapped using a class function with the same name, which returns the current value of the class variable. For example

    @@ -893,7 +721,7 @@ Ko::threats(10); echo "There has now been " . Ko::threats() . " threats\n";
    -

    28.2.6.4 Static Member Functions

    +

    32.2.6.4 Static Member Functions

    @@ -915,15 +743,9 @@ Ko::threats();

    -

    28.2.7 PHP Pragmas, Startup and Shutdown code

    +

    32.2.7 PHP Pragmas, Startup and Shutdown code

    -

    -Note: Currently pragmas for PHP need to be specified using -%pragma(php4) but also apply for PHP5! This is just a historical -oddity because SWIG's PHP support predates PHP5. -

    -

    To place PHP code in the generated "example.php" file one can use the code pragma. The code is inserted after loading the shared @@ -932,7 +754,7 @@ object.

     %module example
    -%pragma(php4) code="
    +%pragma(php) code="
     # This code is inserted into example.php
     echo \"example.php execution\\n\";
     "
    @@ -954,7 +776,7 @@ the example.php file.
     
     
     %module example
    -%pragma(php4) code="
    +%pragma(php) code="
     include \"include.php\";
     "
     %pragma(php) include="include.php"   // equivalent.
    @@ -968,7 +790,7 @@ phpinfo() function.
     
     
     %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\");
    @@ -994,7 +816,7 @@ either %init or %minit.
     
     

    To insert code into the PHP_MSHUTDOWN_FUNCTION, one can use -either %init or %minit. +either %shutdown or %mshutdown.

    @@ -1005,8 +827,384 @@ either %init or %minit.
     

    -The %rinit and %rshutdown statements insert code -into the request init and shutdown code respectively. +The %rinit and %rshutdown statements are very similar but insert code +into the request init (PHP_RINIT_FUNCTION) and request shutdown (PHP_RSHUTDOWN_FUNCTION) code respectively. +

    + +

    32.3 Cross language polymorphism

    + + +

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

    + +

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

    + +

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

    + +

    32.3.1 Enabling directors

    + + +

    +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: +

    + +
    +
    +%module(directors="1") modulename
    +
    +
    + +

    +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: +

    + +
    +
    +// 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; 
    +
    +
    + +

    +You can use the %feature("nodirector") directive to turn off +directors for specific classes or methods. So for example, +

    + +
    +
    +%feature("director") Foo;
    +%feature("nodirector") Foo::bar;
    +
    +
    + +

    +will generate directors for all virtual methods of class Foo except +bar(). +

    + +

    +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()): +

    + +
    +
    +%feature("director") Foo;
    +class Foo {
    +public:
    +    Foo(int foo);
    +    virtual void one();
    +    virtual void two();
    +};
    +
    +class Bar: public Foo {
    +public:
    +    virtual void three();
    +};
    +
    +
    + +

    +then at the PHP side you can define +

    + +
    +
    +require("mymodule.php");
    +
    +class MyFoo extends Foo {
    +  function one() {
    +     print "one from php\n";
    +  }
    +}
    +
    +
    + + +

    32.3.2 Director classes

    + + + + + +

    +For each class that has directors enabled, SWIG generates a new class +that derives from both the class in question and a special +Swig::Director 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. +

    + +

    +For simplicity let's ignore the Swig::Director 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. +

    + +

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

    + +

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

    + +

    +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 ->_cPtr. This is exactly what happens without directors +and is true even if directors are enabled for the particular class in +question. When a class derived 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. +

    + +

    32.3.3 Ownership and object destruction

    + + +

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

    + +

    +This relationship can be reversed by calling the special +->thisown property of the proxy class. After setting this +property to 0, 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. +

    + +

    +Here is an example: +

    + +
    +
    +class Foo {
    +public:
    +    ...
    +};
    +class FooContainer {
    +public:
    +    void addFoo(Foo *);
    +    ...
    +};
    +
    +
    + +
    + +
    +
    +$c = new FooContainer();
    +$a = new Foo();
    +$a->thisown = 0;
    +$c->addFoo($a);
    +
    +
    + +

    +In this example, we are assuming that FooContainer will take care of +deleting all the Foo pointers it contains at some point. +

    + +

    32.3.4 Exception unrolling

    + + +

    +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: +

    + +
    +
    +%feature("director:except") {
    +    if ($error == FAILURE) {
    +        throw Swig::DirectorMethodException();
    +    }
    +}
    +
    +
    + +

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

    + +

    +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 +director:except handler shown above. Here is an example of a +suitable exception handler: +

    + +
    +
    +%exception {
    +    try { $action }
    +    catch (Swig::DirectorException &e) { SWIG_fail; }
    +}
    +
    +
    + +

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

    + +

    32.3.5 Overhead and code bloat

    + + +

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

    + +

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

    + +

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

    + +

    32.3.6 Typemaps

    + + +

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

    + + +

    32.3.7 Miscellaneous

    + + +

    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.

    diff --git a/Doc/Manual/Pike.html b/Doc/Manual/Pike.html index 3e39d4062..8c1eb2d36 100644 --- a/Doc/Manual/Pike.html +++ b/Doc/Manual/Pike.html @@ -6,7 +6,7 @@ -

    29 SWIG and Pike

    +

    33 SWIG and Pike

      @@ -46,10 +46,10 @@ least, make sure you read the "SWIG Basics" chapter.

      -

      29.1 Preliminaries

      +

      33.1 Preliminaries

      -

      29.1.1 Running SWIG

      +

      33.1.1 Running SWIG

      @@ -94,7 +94,7 @@ can use the -o option:

      $ swig -pike -o pseudonym.c example.i
      -

      29.1.2 Getting the right header files

      +

      33.1.2 Getting the right header files

      @@ -114,7 +114,7 @@ You're looking for files with the names global.h, program.h and so on.

      -

      29.1.3 Using your module

      +

      33.1.3 Using your module

      @@ -129,10 +129,10 @@ Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend) (1) Result: 24

    -

    29.2 Basic C/C++ Mapping

    +

    33.2 Basic C/C++ Mapping

    -

    29.2.1 Modules

    +

    33.2.1 Modules

    @@ -143,7 +143,7 @@ concerned), SWIG's %module directive doesn't really have any significance.

    -

    29.2.2 Functions

    +

    33.2.2 Functions

    @@ -168,11 +168,11 @@ exactly as you'd expect it to: (1) Result: 24

    -

    29.2.3 Global variables

    +

    33.2.3 Global variables

    -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

    @@ -197,7 +197,7 @@ will result in two functions, Foo_get() and Foo_set(): (3) Result: 3.141590
    -

    29.2.4 Constants and enumerated types

    +

    33.2.4 Constants and enumerated types

    @@ -205,7 +205,7 @@ Enumerated types in C/C++ declarations are wrapped as Pike constants, not as Pike enums.

    -

    29.2.5 Constructors and Destructors

    +

    33.2.5 Constructors and Destructors

    @@ -213,7 +213,7 @@ Constructors are wrapped as create() methods, and destructors are wrapped as destroy() methods, for Pike classes.

    -

    29.2.6 Static Members

    +

    33.2.6 Static Members

    diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html index 630657a9a..2d0aa093e 100644 --- a/Doc/Manual/Preface.html +++ b/Doc/Manual/Preface.html @@ -11,13 +11,12 @@

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

    1.2 Special Introduction for Version 1.3

    +

    1.2 SWIG Versions

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

    -

    1.3 SWIG Versions

    - - -

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

    - -

    1.4 SWIG resources

    +

    1.3 SWIG resources

    @@ -106,7 +93,7 @@ SWIG along with information about beta releases and future work.

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

    @@ -115,7 +102,7 @@ about this can be obtained at:
    -

    1.5 Prerequisites

    +

    1.4 Prerequisites

    @@ -132,7 +119,7 @@ writing a normal C program.

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

    1.6 Organization of this manual

    +

    1.5 Organization of this manual

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

    -

    1.7 How to avoid reading the manual

    +

    1.6 How to avoid reading the manual

    @@ -165,24 +151,19 @@ The SWIG distribution also comes with a large directory of examples that illustrate different topics.

    -

    1.8 Backwards Compatibility

    +

    1.7 Backwards compatibility

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

    - -

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

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

    -

    1.9 Credits

    +

    1.8 Credits

    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ö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 +Donating to SWIG 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.

    -

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

    1.10 Bug reports

    +

    1.9 Bug reports

    diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index a454c8124..8fcbe9206 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -16,8 +16,11 @@

  • Macro Expansion
  • SWIG Macros
  • C99 and GNU Extensions +
  • Preprocessing and delimiters +
  • Preprocessor and Typemaps
  • Viewing preprocessor output
  • The #error and #warning directives @@ -81,7 +84,7 @@ Such information generally includes type declarations (e.g., typedef) a C++ classes that might be used as base-classes for class declarations in the interface. The use of %import is also important when SWIG is used to generate extensions as a collection of related modules. This is an advanced topic and is described -in a later chapter. +in later in the Working with Modules chapter.

    @@ -102,12 +105,13 @@ by SWIG when it is parsing the interface:

     SWIG                            Always defined when SWIG is processing a file
     SWIGIMPORTED                    Defined when SWIG is importing a file with %import
    -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 +119,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
     
    @@ -307,7 +309,14 @@ interface building. However, they are used internally to implement a number of SWIG directives and are provided to make SWIG more compatible with C99 code.

    -

    7.7 Preprocessing and %{ ... %} & " ... " delimiters

    +

    7.7 Preprocessing and delimiters

    + + +

    +The preprocessor handles { }, " " and %{ %} delimiters differently. +

    + +

    7.7.1 Preprocessing and %{ ... %} & " ... " delimiters

    @@ -332,7 +341,7 @@ the contents of the %{ ... %} block are copied without modification to the output (including all preprocessor directives).

    -

    7.8 Preprocessing and { ... } delimiters

    +

    7.7.2 Preprocessing and { ... } delimiters

    @@ -374,11 +383,11 @@ to actually go into the wrapper file, prefix the preprocessor directives with % and leave the preprocessor directive in the code.

    -

    7.9 Preprocessor and Typemaps

    +

    7.8 Preprocessor and Typemaps

    -Typemaps support a special attribute called noblock where the { ... } delimiters can be used, +Typemaps support a special attribute called noblock 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 is run through the preprocessor. For example:

    @@ -445,7 +454,7 @@ would generate
  • -

    7.10 Viewing preprocessor output

    +

    7.9 Viewing preprocessor output

    @@ -455,7 +464,7 @@ Instead the results after the preprocessor has run are displayed. This might be useful as an aid to debugging and viewing the results of macro expansions.

    -

    7.11 The #error and #warning directives

    +

    7.10 The #error and #warning directives

    diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index 62b72fabf..a9a9bc44e 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -6,7 +6,7 @@ -

    30 SWIG and Python

    +

    34 SWIG and Python

    @@ -113,9 +123,9 @@

    This chapter describes SWIG's support of Python. SWIG is compatible -with most recent Python versions including Python 2.2 as well as older -versions dating back to Python 1.5.2. For the best results, consider using Python -2.0 or newer. +with most recent Python versions including Python 3.0 and Python 2.6, +as well as older versions dating back to Python 2.0. For the best results, +consider using Python 2.3 or newer.

    @@ -125,7 +135,7 @@ very least, make sure you read the "SWIG Basics" chapter.

    -

    30.1 Overview

    +

    34.1 Overview

    @@ -152,10 +162,10 @@ described followed by a discussion of low-level implementation details.

    -

    30.2 Preliminaries

    +

    34.2 Preliminaries

    -

    30.2.1 Running SWIG

    +

    34.2.1 Running SWIG

    @@ -253,13 +263,13 @@ The following sections have further practical examples and details on how you might go about compiling and using the generated files.

    -

    30.2.2 Using distutils

    +

    34.2.2 Using distutils

    The preferred approach to building an extension module for python is to compile it with distutils, which comes with all recent versions of python -(Distutils Docs). +(Distutils Docs).

    @@ -333,7 +343,7 @@ python that you run the command with. Taking apart the command line: setup.py is the tradition)

  • build_ext -- telling distutils to build extensions
  • --inplace -- this tells distutils to put the extension lib in the current dir. - Other wise, it will put it inside a build hierarchy, and you'd have to move it to use it. + Otherwise, it will put it inside a build hierarchy, and you'd have to move it to use it.

    @@ -345,7 +355,7 @@ This same approach works on all platforms if the appropriate compiler is install can even build extensions to the standard Windows Python using MingGW)

    -

    30.2.3 Hand compiling a dynamic module

    +

    34.2.3 Hand compiling a dynamic module

    @@ -357,8 +367,8 @@ program using commands like this (shown for Linux):

     $ swig -python example.i
    -$ gcc -c -fPIC example.c
    -$ gcc -c -fPIC example_wrap.c -I/usr/local/include/python2.0
    +$ gcc -O2 -fPIC -c example.c
    +$ gcc -O2 -fPIC -c example_wrap.c -I/usr/local/include/python2.5
     $ gcc -shared example.o example_wrap.o -o _example.so
     
    @@ -393,7 +403,7 @@ module actually consists of two files; socket.py and

    -

    30.2.4 Static linking

    +

    34.2.4 Static linking

    @@ -427,7 +437,7 @@ extern int mod(int, int); extern double My_variable; %} -%include embed.i // Include code for a static version of Python +%include "embed.i" // Include code for a static version of Python

  • @@ -472,7 +482,7 @@ If using static linking, you might want to rely on a different approach (perhaps using distutils).

    -

    30.2.5 Using your module

    +

    34.2.5 Using your module

    @@ -629,7 +639,7 @@ system configuration (this requires root access and you will need to read the man pages).

    -

    30.2.6 Compilation of C++ extensions

    +

    34.2.6 Compilation of C++ extensions

    @@ -648,26 +658,19 @@ compiler. For example:

     $ swig -c++ -python example.i
    -$ g++ -c example.cxx
    -$ g++ -c example_wrap.cxx -I/usr/local/include/python2.0
    +$ g++ -O2 -fPIC -c example.cxx
    +$ g++ -O2 -fPIC -c example_wrap.cxx -I/usr/local/include/python2.5
     $ g++ -shared example.o example_wrap.o -o _example.so
     

    -On some platforms, you could also need to generate -position-independent code (PIC), by using a compiler option such as -fPIC. -Notably, the x86_64 (Opteron and EM64T) platform requires it, and when -using the GNU Compiler Suite, you will need to modify the previous example -as follows: +The -fPIC option tells GCC to generate position-independent code (PIC) +which is required for most architectures (it's not vital on x86, but +still a good idea as it allows code pages from the library to be shared between +processes). Other compilers may need a different option specified instead of +-fPIC.

    -
    -$ swig -c++ -python example.i
    -$ g++ -fPIC -c example.cxx
    -$ g++ -fPIC -c example_wrap.cxx -I/usr/local/include/python2.0
    -$ g++ -shared example.o example_wrap.o -o _example.so
    -
    -

    In addition to this, you may need to include additional library files to make it work. For example, if you are using the Sun C++ compiler on @@ -677,7 +680,7 @@ Solaris, you often need to add an extra library -lCrun like this:

     $ swig -c++ -python example.i
     $ CC -c example.cxx
    -$ CC -c example_wrap.cxx -I/usr/local/include/python2.0
    +$ CC -c example_wrap.cxx -I/usr/local/include/python2.5
     $ CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun
     
    @@ -728,7 +731,7 @@ erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM.

    -

    30.2.7 Compiling for 64-bit platforms

    +

    34.2.7 Compiling for 64-bit platforms

    @@ -765,7 +768,7 @@ and -m64 allow you to choose the desired binary format for your python extension.

    -

    30.2.8 Building Python Extensions under Windows

    +

    34.2.8 Building Python Extensions under Windows

    @@ -874,7 +877,7 @@ SWIG Wiki.

    -

    30.3 A tour of basic C/C++ wrapping

    +

    34.3 A tour of basic C/C++ wrapping

    @@ -883,7 +886,7 @@ to your C/C++ code. Functions are wrapped as functions, classes are wrapped as This section briefly covers the essential aspects of this wrapping.

    -

    30.3.1 Modules

    +

    34.3.1 Modules

    @@ -896,7 +899,7 @@ module name, make sure you don't use the same name as a built-in Python command or standard module name.

    -

    30.3.2 Functions

    +

    34.3.2 Functions

    @@ -920,7 +923,7 @@ like you think it does: >>>

    -

    30.3.3 Global variables

    +

    34.3.3 Global variables

    @@ -1058,7 +1061,7 @@ that starts with a leading underscore. SWIG does not create cvar if there are no global variables in a module.

    -

    30.3.4 Constants and enums

    +

    34.3.4 Constants and enums

    @@ -1098,7 +1101,7 @@ other object. Unfortunately, there is no easy way for SWIG to generate code that prevents this. You will just have to be careful.

    -

    30.3.5 Pointers

    +

    34.3.5 Pointers

    @@ -1138,7 +1141,7 @@ simply represented as opaque values using an especial python container object:

     >>> print f
    -<Swig Object at _08a71808_p_FILE>
    +<Swig Object of type 'FILE *' at 0xb7d6f470>
     

    @@ -1148,7 +1151,7 @@ dereference the pointer from Python. Of course, that isn't much of a concern in

    -In older versions of Swig (1.3.22 or older), pointers were represented +In older versions of SWIG (1.3.22 or older), pointers were represented using a plain string object. If you have an old package that still requires that representation, or you just feel nostalgic, you can always retrieve it by casting the pointer object to a string: @@ -1172,7 +1175,7 @@ integer:

    However, the inverse operation is not possible, i.e., you can't build -a Swig pointer object from a raw integer value. +a SWIG pointer object from a raw integer value.

    @@ -1239,7 +1242,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

    -

    30.3.6 Structures

    +

    34.3.6 Structures

    @@ -1286,7 +1289,7 @@ something like this:

    This object is actually a Python instance that has been wrapped around a pointer to the low-level C structure. This instance doesn't actually do anything--it just serves as a proxy. -The pointer to the C object can be found in the the .this +The pointer to the C object can be found in the .this attribute. For example:

    @@ -1428,7 +1431,7 @@ everything works just like you would expect. For example: -

    30.3.7 C++ classes

    +

    34.3.7 C++ classes

    @@ -1517,7 +1520,7 @@ they are accessed through cvar like this: -

    30.3.8 C++ inheritance

    +

    34.3.8 C++ inheritance

    @@ -1572,7 +1575,7 @@ then the function spam() accepts Foo * or a pointer to any cla It is safe to use multiple inheritance with SWIG.

    -

    30.3.9 Pointers, references, values, and arrays

    +

    34.3.9 Pointers, references, values, and arrays

    @@ -1633,7 +1636,7 @@ treated as a returning value, and it will follow the same allocation/deallocation process.

    -

    30.3.10 C++ overloaded functions

    +

    34.3.10 C++ overloaded functions

    @@ -1714,8 +1717,8 @@ If declarations such as these appear, you will get a warning message like this:

    -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).
     
    @@ -1756,7 +1759,7 @@ first declaration takes precedence. Please refer to the "SWIG and C++" chapter for more information about overloading.

    -

    30.3.11 C++ operators

    +

    34.3.11 C++ operators

    @@ -1845,7 +1848,7 @@ Also, be aware that certain operators don't map cleanly to Python. For instance overloaded assignment operators don't map to Python semantics and will be ignored.

    -

    30.3.12 C++ namespaces

    +

    34.3.12 C++ namespaces

    @@ -1912,7 +1915,7 @@ utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

    -

    30.3.13 C++ templates

    +

    34.3.13 C++ templates

    @@ -1966,7 +1969,7 @@ Some more complicated examples will appear later.

    -

    30.3.14 C++ Smart Pointers

    +

    34.3.14 C++ Smart Pointers

    @@ -2050,170 +2053,16 @@ simply use the __deref__() method. For example: - -

    30.3.15 C++ Reference Counted Objects (ref/unref)

    +

    34.3.15 C++ reference counted objects

    -Another usual idiom in C++ is the use of reference counted -objects. Consider for example: - -

    -
    -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->ref(); 
    -  }
    -
    -  ~B() { 
    -    a->unref(); 
    -  }
    -};
    -
    -int main() {
    -  A *a  = new A();
    -  a->ref();           // 'a' is ref here
    -
    -  B *b1 = new B(a);   // 'a' is ref here
    -  if (1 + 1 == 2) {
    -    B *b2 = new B(a); // 'a' is ref here
    -    delete b2;        // 'a' is unref, but not deleted   
    -  }
    -
    -  delete b1;          // 'a' is unref, but not deleted   
    -  a->unref();         // 'a' is unref and deleted
    -}
    -
    -
    - -

    -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 an Reference Counted -Object 'RCObj', which implements the ref/unref idiom. -

    - -

    -To tell SWIG that 'RCObj' and all its derived classes are reference -counted objects, you use the "ref" and "unref" features, or -%ref and %unref directives (since 1.3.28). For example: +The C++ reference counted objects section contains +Python examples of memory management using referencing counting.

    -
    -
    -%module example
    -...
    -
    -%feature("ref")   RCObj "$this->ref();"
    -%feature("unref") RCObj "$this->unref();"
    -
    -%include "rcobj.h"
    -%include "A.h"
    -...
    -
    -
    - -or, using the directive form: - - -
    -
    -%module example
    -...
    -
    -%ref   RCObj "$this->ref();"
    -%unref RCObj "$this->unref();"
    -
    -%include "rcobj.h"
    -%include "A.h"
    -...
    -
    -
    - - - -

    -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 shadow object instance, respectively. -

    - -

    -In the python side, the use of a reference counted object is not -different than any other regular instance: -

    - -
    -
    -def create_A():
    -  a = A()         # SWIG ref 'a' (new object is passed to python)
    -  b1 = B(a)       # C++  ref 'a'
    -  if 1 + 1 == 2:
    -     b2 = B(a)    # C++ ref 'a'
    -  return a        # 'b1' and 'b2' are released, C++ unref 'a' twice
    -
    -a = create_A()   
    -exit              # 'a' is released, SWIG unref 'a'
    -
    -
    - -

    -Note that the user doesn't explicitly need to call 'a->ref()' nor 'a->unref()' -(as neither 'delete a'). Instead, SWIG take cares of executing the "ref" -and "unref" codes as needed. If the user doesn't specify the -"ref/unref" features, SWIG will produce a code equivalent to define -them as: -

    - -
    -
    -%feature("ref")   ""
    -%feature("unref") "delete $this;"
    -
    -
    - -

    -In other words, SWIG will not do anything special when a new object -is passed to python, and it will always 'delete' the object when -python releases the proxy instance. -

    - - -

    30.4 Further details on the Python class interface

    +

    34.4 Further details on the Python class interface

    @@ -2226,7 +2075,17 @@ of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

    -

    30.4.1 Proxy classes

    +

    New in SWIG version 2.0.4: +The use of Python proxy classes has performance implications that may be +unacceptable for a high-performance library. The new -builtin +option instructs SWIG to forego the use of proxy classes, and instead +create wrapped types as new built-in Python types. When this option is used, +the following section ("Proxy classes") does not apply. Details on the use of +the -builtin option are in the Built-in Types +section. +

    + +

    34.4.1 Proxy classes

    @@ -2315,9 +2174,325 @@ you can attach new Python methods to the class and you can even inherit from it by Python built-in types until Python 2.2).

    -

    30.4.2 Memory management

    +

    34.4.2 Built-in Types

    +

    +The -builtin option provides a significant performance improvement +in the wrapped code. To understand the difference between proxy classes +and built-in types, let's take a look at what a wrapped object looks like +under both circumstances. +

    + +

    When proxy classes are used, each wrapped object in python is an instance +of a pure python class. As a reminder, here is what the __init__ method looks +like in a proxy class: +

    + +
    +
    +class Foo(object):
    +     def __init__(self):
    +         self.this = _example.new_Foo()
    +         self.thisown = 1
    +
    +
    + +

    When a Foo instance is created, the call to _example.new_Foo() +creates a new C++ Foo instance; wraps that C++ instance inside an instance of +a python built-in type called SwigPyObject; and stores the SwigPyObject +instance in the 'this' field of the python Foo object. Did you get all that? So, the +python Foo object is composed of three parts:

    + +
      +
    • The python Foo instance, which contains...
    • +
    • ... an instance of struct SwigPyObject, which contains...
    • +
    • ... a C++ Foo instance
    • +
    + +

    When -builtin is used, the pure python layer is stripped off. Each +wrapped class is turned into a new python built-in type which inherits from +SwigPyObject, and SwigPyObject instances are returned directly +from the wrapped methods. For more information about python built-in extensions, +please refer to the python documentation:

    + +

    http://docs.python.org/extending/newtypes.html

    + +

    34.4.2.1 Limitations

    + + +

    Use of the -builtin option implies a couple of limitations: +

      +
    • python version support:

      +
        +
      • Versions 2.5 and up are fully supported
      • +
      • Versions 2.3 and 2.4 are mostly supported; there are problems with director classes and/or sub-classing a wrapped type in python.
      • +
      • Versions older than 2.3 are not supported.
      • +
      +
    • +
    • Some legacy syntax is no longer supported; in particular:

      +
        +
      • The functional interface is no longer exposed. For example, you may no longer call Whizzo.new_CrunchyFrog(). Instead, you must use Whizzo.CrunchyFrog().
      • +
      • Static member variables are no longer accessed through the 'cvar' field (e.g., Dances.cvar.FishSlap). + They are instead accessed in the idiomatic way (Dances.FishSlap).
      • +
      +
    • +
    • Wrapped types may not be raised as python exceptions. Here's why: the python internals expect that all sub-classes of Exception will have this struct layout:

      + +
      +
      +typedef struct {
      +    PyObject_HEAD
      +    PyObject *dict;
      +    PyObject *args;
      +    PyObject *message;
      +} PyBaseExceptionObject;
      +
      +
      + +

      But swig-generated wrappers expect that all swig-wrapped classes will have this struct layout:

      + +
      +
      +typedef struct {
      +    PyObject_HEAD
      +    void *ptr;
      +    swig_type_info *ty;
      +    int own;
      +    PyObject *next;
      +    PyObject *dict;
      +} SwigPyObject;
      +
      +
      + +

      There are workarounds for this. For example, if you wrap this class: + +

      +
      +class MyException {
      +public:
      +    MyException (const char *msg_);
      +    ~MyException ();
      +
      +    const char *what () const;
      +
      +private:
      +    char *msg;
      +};
      +
      +
      + +

      ... you can define this python class, which may be raised as an exception:

      + +
      +
      +class MyPyException (Exception) :
      +    def __init__(self, msg, *args) :
      +        Exception.__init__(self, *args)
      +        self.myexc = MyException(msg)
      +    def what (self) :
      +        return self.myexc.what()
      +
      +
      +
    • +
    • Reverse binary operators (e.g., __radd__) are not supported.

      +

      To illustrate this point, if you have a wrapped class called MyString, +and you want to use instances of MyString interchangeably with native python +strings, you can define an 'operator+ (const char*)' method :

      + +
      +
      +class MyString {
      +public:
      +    MyString (const char *init);
      +    MyString operator+ (const char *other) const;
      +    ...
      +};
      +
      +
      + +

      +SWIG will automatically create an operator overload in python that will allow this: +

      + +
      +
      +from MyModule import MyString
      +
      +mystr = MyString("No one expects")
      +episode = mystr + " the Spanish Inquisition"
      +
      +
      + +

      +This works because the first operand (mystr) defines a way +to add a native string to itself. However, the following will not work: +

      + +
      +
      +from MyModule import MyString
      +
      +mystr = MyString("Parrot")
      +episode = "Dead " + mystr
      +
      +
      + +

      +The above code fails, because the first operand -- a native python string -- +doesn't know how to add an instance of MyString to itself. +

      +
    • + +
    • If you have multiple SWIG modules that share type information (more info), +the -builtin option requiress a bit of extra discipline to ensure that base classes are initialized before derived classes. Specifically:

      +
        +
      • There must be an unambiguous dependency graph for the modules.

      • +
      • Module dependencies must be explicitly stated with %import statements in the SWIG interface file.

        +
      + +

      As an example, suppose module A has this interface in A.i :

      + +
      +%module "A";
      +
      +class Base {
      +...
      +};
      +
      + +

      If you want to wrap another module containing a class that inherits from A, this is how it would look :

      + +
      +%module "B";
      +
      +%import "A.i"
      +
      +class Derived : public Base {
      +...
      +};
      +
      + +

      The import "A.i" statement is required, because module B depends on module A.

      + +

      As long as you obey these requirements, your python code may import the modules in any order :

      + +
      +import B
      +import A
      +
      +assert(issubclass(B.Derived, A.Base))
      +
      +
    • +
    + +

    34.4.2.2 Operator overloads -- use them!

    + + +

    The entire justification for the -builtin option is improved +performance. To that end, the best way to squeeze maximum performance out +of your wrappers is to use operator overloads. +Named method dispatch is slow in python, even when compared to other scripting languages. +However, python built-in types have a large number of "slots", +analogous to C++ operator overloads, which allow you to short-circuit named method dispatch +for certain common operations. +

    + +

    By default, SWIG will translate most C++ arithmetic operator overloads into python +slot entries. For example, suppose you have this class: + +

    +
    +class Twit {
    +public:
    +    Twit operator+ (const Twit& twit) const;
    +
    +    // Forward to operator+
    +    Twit add (const Twit& twit) const
    +    { return *this + twit; }
    +};
    +
    +
    + +

    SWIG will automatically register operator+ as a python slot operator for addition. You may write python code like this:

    + +
    +
    +from MyModule import Twit
    +
    +nigel = Twit()
    +emily = Twit()
    +percival = nigel + emily
    +percival = nigel.add(emily)
    +
    +
    + +

    The last two lines of the python code are equivalent, +but the line that uses the '+' operator is much faster. +

    + +

    In-place operators (e.g., operator+=) and comparison operators +(operator==, operator<, etc.) are also converted to python +slot operators. For a complete list of C++ operators that are +automatically converted to python slot operators, refer to the file +python/pyopers.swig in the SWIG library. +

    + +

    There are other very useful python slots that you +may explicitly define using %feature directives. For example, +suppose you want to use instances of a wrapped class as keys in a native python +dict. That will work as long as you define a hash function for +instances of your class, and use it to define the python tp_hash +slot: +

    + +
    +
    +%feature("python:slot", "tp_hash", functype="hashfunc") Cheese::cheeseHashFunc;
    +
    +class Cheese {
    +public:
    +    Cheese (const char *name);
    +    long cheeseHashFunc () const;
    +};
    +
    +
    + +

    This will allow you to write python code like this:

    + +
    +
    +from my MyPackage import Cheese
    +
    +inventory = {
    +    Cheese("cheddar") : 0,
    +    Cheese("gouda") : 0,
    +    Cheese("camembert") : 0
    +}
    +
    +
    + +

    Because you defined the tp_hash slot, Cheese objects may +be used as hash keys; and when the cheeseHashFunc method is invoked +by a python dict, it will not go through named method dispatch. +A more detailed discussion about %feature("python:slot") can be found +in the file python/pyopers.swig in the SWIG library. +You can read about all of the available python slots here:

    + +

    http://docs.python.org/c-api/typeobj.html

    + +

    You may override (almost) all of the slots defined in the PyTypeObject, +PyNumberMethods, PyMappingMethods, PySequenceMethods, and PyBufferProcs +structs. +

    + + +

    34.4.3 Memory management

    + + +

    NOTE: Although this section refers to proxy objects, everything here also applies +when the -builtin option is used.

    +

    Associated with proxy object, is an ownership flag .thisown The value of this flag determines who is responsible for deleting the underlying C++ object. If set to 1, @@ -2507,7 +2682,7 @@ It is also possible to deal with situations like this using typemaps--an advanced topic discussed later.

    -

    30.4.3 Python 2.2 and classic classes

    +

    34.4.4 Python 2.2 and classic classes

    @@ -2517,7 +2692,7 @@ in Python-2.2, an entirely new type of class system was introduced. This new-style class system offers many enhancements including static member functions, properties (managed attributes), and class methods. Details about all of these changes can be found on www.python.org and is not repeated here. +href="http://www.python.org">www.python.org and is not repeated here.

    @@ -2544,7 +2719,7 @@ class itself. In Python-2.1 and earlier, they have to be accessed as a global function or through an instance (see the earlier section).

    -

    30.5 Cross language polymorphism

    +

    34.5 Cross language polymorphism

    @@ -2578,7 +2753,7 @@ proxy classes, director classes, and C wrapper functions takes care of all the cross-language method routing transparently.

    -

    30.5.1 Enabling directors

    +

    34.5.1 Enabling directors

    @@ -2671,7 +2846,7 @@ class MyFoo(mymodule.Foo): -

    30.5.2 Director classes

    +

    34.5.2 Director classes

    @@ -2753,7 +2928,7 @@ so there is no need for the extra overhead involved with routing the calls through Python.

    -

    30.5.3 Ownership and object destruction

    +

    34.5.3 Ownership and object destruction

    @@ -2805,12 +2980,12 @@ public:

     >>> c = FooContainer()
    ->>> a = Foo().__disown()__
    +>>> a = Foo().__disown__()
     >>> c.addFoo(a)
     >>> b = Foo()
    ->>> b = b.__disown()__
    +>>> b = b.__disown__()
     >>> c.addFoo(b)
    ->>> c.addFoo(Foo().__disown()__)
    +>>> c.addFoo(Foo().__disown__())
     
    @@ -2820,7 +2995,7 @@ deleting all the Foo pointers it contains at some point. Note that no hard references to the Foo objects remain in Python.

    -

    30.5.4 Exception unrolling

    +

    34.5.4 Exception unrolling

    @@ -2879,7 +3054,7 @@ Swig::DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns.

    -

    30.5.5 Overhead and code bloat

    +

    34.5.5 Overhead and code bloat

    @@ -2913,7 +3088,7 @@ directive) for only those methods that are likely to be extended in Python.

    -

    30.5.6 Typemaps

    +

    34.5.6 Typemaps

    @@ -2927,7 +3102,7 @@ need to be supported.

    -

    30.5.7 Miscellaneous

    +

    34.5.7 Miscellaneous

    @@ -2974,7 +3149,7 @@ methods that return const references.

    -

    30.6 Common customization features

    +

    34.6 Common customization features

    @@ -2987,7 +3162,7 @@ This section describes some common SWIG features that are used to improve your the interface to an extension module.

    -

    30.6.1 C/C++ helper functions

    +

    34.6.1 C/C++ helper functions

    @@ -3068,7 +3243,7 @@ hard to implement. It is possible to clean this up using Python code, typemaps, customization features as covered in later sections.

    -

    30.6.2 Adding additional Python code

    +

    34.6.2 Adding additional Python code

    @@ -3124,7 +3299,7 @@ customization features.

    Sometimes you may want to replace or modify the wrapper function that SWIG creates in the proxy .py file. The Python module -in SWIG provides some features that enable you do do this. First, to +in SWIG provides some features that enable you to do this. First, to entirely replace a proxy function you can use %feature("shadow"). For example:

    @@ -3217,7 +3392,7 @@ public: -

    30.6.3 Class extension with %extend

    +

    34.6.3 Class extension with %extend

    @@ -3306,7 +3481,7 @@ Vector(12,14,16) in any way---the extensions only show up in the Python interface.

    -

    30.6.4 Exception handling with %exception

    +

    34.6.4 Exception handling with %exception

    @@ -3432,7 +3607,7 @@ The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter.

    -

    30.7 Tips and techniques

    +

    34.7 Tips and techniques

    @@ -3442,7 +3617,7 @@ strings, binary data, and arrays. This chapter discusses the common techniques solving these problems.

    -

    30.7.1 Input and output parameters

    +

    34.7.1 Input and output parameters

    @@ -3655,7 +3830,7 @@ void foo(Bar *OUTPUT); may not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

    -

    30.7.2 Simple pointers

    +

    34.7.2 Simple pointers

    @@ -3724,7 +3899,7 @@ If you replace %pointer_functions() by %pointer_class(type,name)SWIG Library chapter for further details.

    -

    30.7.3 Unbounded C Arrays

    +

    34.7.3 Unbounded C Arrays

    @@ -3786,7 +3961,7 @@ well suited for applications in which you need to create buffers, package binary data, etc.

    -

    30.7.4 String handling

    +

    34.7.4 String handling

    @@ -3855,16 +4030,7 @@ If you need to return binary data, you might use the also be used to extra binary data from arbitrary pointers.

    -

    30.7.5 Arrays

    - - -

    30.7.6 String arrays

    - - -

    30.7.7 STL wrappers

    - - -

    30.8 Typemaps

    +

    34.8 Typemaps

    @@ -3881,7 +4047,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status.

    -

    30.8.1 What is a typemap?

    +

    34.8.1 What is a typemap?

    @@ -3997,7 +4163,7 @@ parameter is omitted): -

    30.8.2 Python typemaps

    +

    34.8.2 Python typemaps

    @@ -4038,7 +4204,7 @@ a look at the SWIG library version 1.3.20 or so.

    -

    30.8.3 Typemap variables

    +

    34.8.3 Typemap variables

    @@ -4109,7 +4275,7 @@ properly assigned. The Python name of the wrapper function being created. -

    30.8.4 Useful Python Functions

    +

    34.8.4 Useful Python Functions

    @@ -4237,7 +4403,7 @@ write me -

    30.9 Typemap Examples

    +

    34.9 Typemap Examples

    @@ -4246,7 +4412,7 @@ might look at the files "python.swg" and "typemaps.i" in the SWIG library.

    -

    30.9.1 Converting Python list to a char **

    +

    34.9.1 Converting Python list to a char **

    @@ -4326,7 +4492,7 @@ memory allocation is used to allocate memory for the array, the the C function.

    -

    30.9.2 Expanding a Python object into multiple arguments

    +

    34.9.2 Expanding a Python object into multiple arguments

    @@ -4405,7 +4571,7 @@ to supply the argument count. This is automatically set by the typemap code. F -

    30.9.3 Using typemaps to return arguments

    +

    34.9.3 Using typemaps to return arguments

    @@ -4494,7 +4660,7 @@ function can now be used as follows: >>> -

    30.9.4 Mapping Python tuples into small arrays

    +

    34.9.4 Mapping Python tuples into small arrays

    @@ -4543,7 +4709,7 @@ array, such an approach would not be recommended for huge arrays, but for small structures, this approach works fine.

    -

    30.9.5 Mapping sequences to C arrays

    +

    34.9.5 Mapping sequences to C arrays

    @@ -4624,7 +4790,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { %} %typemap(in) double [ANY](double temp[$1_dim0]) { - if (!convert_darray($input,temp,$1_dim0))) { + if (!convert_darray($input,temp,$1_dim0)) { return NULL; } $1 = &temp[0]; @@ -4632,7 +4798,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { -

    30.9.6 Pointer handling

    +

    34.9.6 Pointer handling

    @@ -4729,7 +4895,7 @@ class object (if applicable). -

    30.10 Docstring Features

    +

    34.10 Docstring Features

    @@ -4757,7 +4923,7 @@ of your users much simpler.

    -

    30.10.1 Module docstring

    +

    34.10.1 Module docstring

    @@ -4791,7 +4957,7 @@ layout of controls on a panel, etc. to be loaded from an XML file." -

    30.10.2 %feature("autodoc")

    +

    34.10.2 %feature("autodoc")

    @@ -4815,14 +4981,15 @@ introspection, then life is good once more. which when attached to a node in the parse tree will cause a docstring to be generated that includes the name of the function, parameter names, default values if any, and return type if any. There are also -three options for autodoc controlled by the value given to the -feature, described below. +four levels for autodoc controlled by the value given to the +feature, %feature("autodoc", "level"). +The four values for level are covered in the following sub-sections. -

    30.10.2.1 %feature("autodoc", "0")

    +

    34.10.2.1 %feature("autodoc", "0")

    -When the "0" option is given then the types of the parameters will +When level "0" is used then the types of the parameters will not be included in the autodoc string. For example, given this function prototype:

    @@ -4847,18 +5014,19 @@ def function_name(*args, **kwargs): -

    30.10.2.2 %feature("autodoc", "1")

    +

    34.10.2.2 %feature("autodoc", "1")

    -When the "1" option is used then the parameter types will be +When level "1" is used then the parameter types will be used in the autodoc string. In addition, an attempt is made to simplify the type name such that it makes more sense to the Python -user. Pointer, reference and const info is removed, -%rename's are evaluated, etc. (This is not always -successful, but works most of the time. See the next section for what -to do when it doesn't.) Given the example above, then turning on the -parameter types with the "1" option will result in Python code like +user. Pointer, reference and const info is removed if the associated type +is has an associated Python type (%rename's are thus shown correctly). +This works most of the time, otherwise a C/C++ type will be used. +See the next section for the "docstring" feature for tweaking the docstrings to your liking. +Given the example above, then turning on the +parameter types with level "1" will result in Python code like this:

    @@ -4871,8 +5039,92 @@ def function_name(*args, **kwargs): +

    34.10.2.3 %feature("autodoc", "2")

    -

    30.10.2.3 %feature("autodoc", "docstring")

    + +

    +Level "2" results in the function prototype as per level "0". In addition, a line of +documentation is generated for each parameter. Using the previous example, the generated +code will be: +

    + +
    +
    +def function_name(*args, **kwargs):
    +    """
    +    function_name(x, y, foo=None, bar=None) -> bool
    +
    +    Parameters:
    +        x: int
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +    ...
    +
    +
    + +

    +Note that the documentation for each parameter is sourced from the "doc" typemap which by default shows the +C/C++ type rather than the simplified Python type name described earlier for level "1". +Typemaps can of course change the output for any particular type, for example the int x parameter: +

    + +
    +
    +%feature("autodoc", "2");
    +%typemap("doc") int x "$1_name (C++ type: $1_type) -- Input $1_name dimension"
    +bool function_name(int x, int y, Foo* foo=NULL, Bar* bar=NULL);
    +
    +
    + +

    +resulting in +

    + +
    +
    +def function_name(*args, **kwargs):
    +  """
    +    function_name(x, y, foo=None, bar=None) -> bool
    +
    +    Parameters:
    +        x (C++ type: int) -- Input x dimension
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +
    +
    + +

    34.10.2.4 %feature("autodoc", "3")

    + + +

    +Level "3" results in the function prototype as per level "1" but also contains the same additional line of documentation for each parameter as per level "2". Using our earlier example again, the generated code will be: +

    + +
    +
    +def function_name(*args, **kwargs):
    +    """
    +    function_name(int x, int y, Foo foo=None, Bar bar=None) -> bool
    +
    +    Parameters:
    +        x: int
    +        y: int
    +        foo: Foo *
    +        bar: Bar *
    +
    +    """
    +    ...
    +
    +
    + + +

    34.10.2.5 %feature("autodoc", "docstring")

    @@ -4891,7 +5143,7 @@ void GetPosition(int* OUTPUT, int* OUTPUT); -

    30.10.3 %feature("docstring")

    +

    34.10.3 %feature("docstring")

    @@ -4923,13 +5175,13 @@ with more than one line. -

    30.11 Python Packages

    +

    34.11 Python Packages

    Using the package option of the %module directive allows you to specify what Python package that the module will be -living in when installed. +living in when installed.

    @@ -4950,6 +5202,258 @@ and also in base class declarations, etc. if the package name is different than its own.

    +

    34.12 Python 3 Support

    + + +

    +SWIG is able to support Python 3.0. The wrapper code generated by +SWIG can be compiled with both Python 2.x or 3.0. Further more, by +passing the -py3 command line option to SWIG, wrapper code +with some Python 3 specific features can be generated (see below +subsections for details of these features). The -py3 option also +disables some incompatible features for Python 3, such as +-classic. + +

    +There is a list of known-to-be-broken features in Python 3: +

    +
      +
    • No more support for FILE* typemaps, because PyFile_AsFile has been dropped + in Python 3.
    • +
    • The -apply command line option is removed and generating + code using apply() is no longer supported.
    • +
    + +

    +The following are Python 3.0 new features that are currently supported by +SWIG. +

    + +

    34.12.1 Function annotation

    + + +

    +The -py3 option will enable function annotation support. When used +SWIG is able to generate proxy method definitions like this: +

    + +
    +  def foo(self, bar : "int"=0) -> "void" : ...
    +
    + +

    +Also, even if without passing SWIG the -py3 option, the parameter list +still could be generated: +

    + +
    +  def foo(self, bar=0): ...
    +
    + +

    +But for overloaded function or method, the parameter list would fallback to +*args or self, *args, and **kwargs may be append +depend on whether you enabled the keyword argument. This fallback is due to +all overloaded functions share the same function in SWIG generated proxy class. +

    + +

    +For detailed usage of function annotation, see +PEP 3107. +

    + +

    34.12.2 Buffer interface

    + + +

    +Buffer protocols were revised in Python 3. SWIG also gains a series of +new typemaps to support buffer interfaces. These typemap macros are +defined in pybuffer.i, which must be included in order to use them. +By using these typemaps, your wrapped function will be able to +accept any Python object that exposes a suitable buffer interface. +

    + +

    +For example, the get_path() function puts the path string +into the memory pointed to by its argument: +

    + +
    +void get_path(char *s);
    +
    + +

    +Then you can write a typemap like this: (the following example is +applied to both Python 3.0 and 2.6, since the bytearray type +is backported to 2.6. +

    + + +
    +%include <pybuffer.i>
    +%pybuffer_mutable_string(char *str);
    +void get_path(char *s);
    +
    + +

    +And then on the Python side the wrapped get_path could be used in this +way: +

    + +
    +>>> p = bytearray(10)
    +>>> get_path(p)
    +>>> print(p)
    +bytearray(b'/Foo/Bar/\x00')
    +
    + +

    +The macros defined in pybuffer.i are similar to those in +cstring.i: +

    + +

    +%pybuffer_mutable_binary(parm, size_parm) +

    + +
    + +

    +The macro can be used to generate a typemap which maps a buffer of an +object to a pointer provided by parm and a size argument +provided by size_parm. For example: +

    + +
    +%pybuffer_mutable_binary(char *str, size_t size);
    +...
    +int snprintf(char *str, size_t size, const char *format, ...);
    +
    + +

    +In Python: +

    + +
    +>>> buf = bytearray(6)
    +>>> snprintf(buf, "Hello world!")
    +>>> print(buf)
    +bytearray(b'Hello\x00')
    +>>> 
    +
    + +
    + +

    +%pybuffer_mutable_string(parm) +

    + +
    + +

    +This typemap macro requires the buffer to be a zero terminated string, +and maps the pointer of the buffer to parm. For example: +

    + +
    +%pybuffer_mutable_string(char *str);
    +...
    +size_t make_upper(char *str);
    +
    + +

    +In Python: +

    + +
    +>>> buf = bytearray(b'foo\x00')
    +>>> make_upper(buf)
    +>>> print(buf)
    +bytearray(b'FOO\x00')
    +>>>
    +
    + +

    +Both %pybuffer_mutable_binary and %pybuffer_mutable_string +require the provided buffer to be mutable, eg. they can accept a +bytearray type but can't accept an immutable byte +type. +

    + +
    + +

    +%pybuffer_binary(parm, size_parm) +

    + +
    + +

    +This macro maps an object's buffer to a pointer parm and a +size size_parm. It is similar to +%pybuffer_mutable_binary, except the +%pybuffer_binary an accept both mutable and immutable +buffers. As a result, the wrapped function should not modify the buffer. +

    + +
    + +

    +%pybuffer_string(parm) +

    + +
    + +

    +This macro maps an object's buffer as a string pointer parm. +It is similar to %pybuffer_mutable_string but the buffer +could be both mutable and immutable. And your function should not +modify the buffer. +

    + +
    + + +

    34.12.3 Abstract base classes

    + + +

    +By including pyabc.i and using the -py3 command +line option when calling SWIG, the proxy classes of the STL containers +will automatically gain an appropriate abstract base class. For +example, the following SWIG interface: +

    + +
    +%include <pyabc.i>
    +%include <std_map.i>
    +%include <std_list.i>
    +
    +namespace std {
    +  %template(Mapii) map<int, int>;
    +  %template(IntList) list<int>;
    +}
    +
    + +

    +will generate a Python proxy class Mapii inheriting from +collections.MutableMap and a proxy class IntList +inheriting from collections.MutableSequence. +

    + +

    +pyabc.i also provides a macro %pythonabc that could be +used to define an abstract base class for your own C++ class: +

    + +
    +%pythonabc(MySet, collections.MutableSet);
    +
    + +

    +For details of abstract base class, please see +PEP 3119. +

    diff --git a/Doc/Manual/R.html b/Doc/Manual/R.html index 3b37d53a0..ceea32146 100644 --- a/Doc/Manual/R.html +++ b/Doc/Manual/R.html @@ -6,7 +6,7 @@ -

    33 SWIG and R

    +

    35 SWIG and R

      @@ -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++.

      -

      33.1 Bugs

      +

      35.1 Bugs

      @@ -45,7 +45,7 @@ Currently the following features are not implemented or broken:

    • C Array wrappings
    -

    33.2 Using R and SWIG

    +

    35.2 Using R and SWIG

    @@ -56,28 +56,48 @@ example.c is the name of the file with the functions in them

     swig -r example.i
    -PKG_LIBS="example.c" R CMD SHLIB example_wrap.c
    +R CMD SHLIB example_wrap.c example.c
     

    -The corresponding comments for C++ mode are +The corresponding options for C++ mode are

     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
     

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

    +
    +
    +swig -c++ -r -o example_wrap.cpp example.i
    +R CMD SHLIB -o example.so example_wrap.cpp example.cpp
    +
    +
    + +

    +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: +

    + +
    +
    +swig -c++ -r -o example_wrap.cpp example.i
    +PKG_LIBS="example.cxx" R CMD SHLIB -o example example_wrap.cpp
    +
    +
    +

    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

    -

    33.3 Precompiling large R files

    +

    35.3 Precompiling large R files

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

    33.4 General policy

    +

    35.4 General policy

    @@ -126,7 +146,7 @@ wrapping over the underlying functions and rely on the R type system to provide R syntax.

    -

    33.5 Language conventions

    +

    35.5 Language conventions

    @@ -135,7 +155,7 @@ and [ are overloaded to allow for R syntax (one based indices and slices)

    -

    33.6 C++ classes

    +

    35.6 C++ classes

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

    -

    33.7 Enumerations

    +

    35.7 Enumerations

    diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 9cd83d494..69005c731 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -1,32 +1,13 @@ - - - - - - - - - - - - - - SWIG and Ruby + - - - - - - -

    31 SWIG and Ruby

    +

    36 SWIG and Ruby

  • Advanced Topics @@ -167,7 +148,7 @@ -

    31.1 Preliminaries

    +

    36.1 Preliminaries

    SWIG 1.3 is known to work with Ruby versions 1.6 and later. @@ -190,7 +171,7 @@ of Ruby.

    -

    31.1.1 Running SWIG

    +

    36.1.1 Running SWIG

    To build a Ruby module, run SWIG using the -ruby @@ -244,7 +225,7 @@ to compile this file and link it with the rest of your program.

    -

    31.1.2 Getting the right header files

    +

    36.1.2 Getting the right header files

    In order to compile the wrapper code, the compiler needs the ruby.h @@ -255,7 +236,9 @@ header file. This file is usually contained in a directory such as

    -
    /usr/lib/ruby/1.8/x86_64-linux-gnu/ruby.h
    /usr/local/lib/ruby/1.6/i686-linux/ruby.h
    +
    /usr/lib/ruby/1.8/x86_64-linux-gnu/ruby.h
    +/usr/local/lib/ruby/1.6/i686-linux/ruby.h
    +
    @@ -276,7 +259,10 @@ installed, you can run Ruby to find out. For example:

    -
    $ ruby -e 'puts $:.join("\n")'
    /usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby/1.6/i686-linux
    /usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6 /usr/local/lib/ruby/1.6/i686-linux .
    +
    $ ruby -e 'puts $:.join("\n")'
    +/usr/local/lib/ruby/site_ruby/1.6 /usr/local/lib/ruby/site_ruby/1.6/i686-linux
    +/usr/local/lib/ruby/site_ruby /usr/local/lib/ruby/1.6 /usr/local/lib/ruby/1.6/i686-linux .
    +
    @@ -288,7 +274,7 @@ installed, you can run Ruby to find out. For example:

    -

    31.1.3 Compiling a dynamic module

    +

    36.1.3 Compiling a dynamic module

    Ruby extension modules are typically compiled into shared @@ -324,16 +310,7 @@ looks like the following:

    - - - -
    require 'mkmf'
    create_makefile('example')
    - - - - -
    @@ -401,7 +378,12 @@ can add this:

    -
    open("Makefile", "a") { |mf|
    puts <<EOM
    # Your make rules go here
    EOM
    }
    +
    open("Makefile", "a") { |mf|
    + puts <<EOM
    + # Your make rules go here
    + EOM
    +}
    +
    @@ -424,7 +406,10 @@ operating system would look something like this:

    -
    $ swig -ruby example.i
    $ gcc -c example.c
    $ gcc -c example_wrap.c -I/usr/local/lib/ruby/1.6/i686-linux
    $ gcc -shared example.o example_wrap.o -o example.so +
    $ swig -ruby example.i
    +$ gcc -c example.c
    +$ gcc -c example_wrap.c -I/usr/local/lib/ruby/1.6/i686-linux 
    +$ gcc -shared example.o example_wrap.o -o example.so
     
    @@ -443,7 +428,7 @@ manual pages for your compiler and linker to determine the correct set of options. You might also check the SWIG Wiki for additional information.

    -

    31.1.4 Using your module

    +

    36.1.4 Using your module

    Ruby module names must be capitalized, @@ -456,7 +441,12 @@ module is imported by requiring the etc feature:

    -
    # The feature name begins with a lowercase letter...
    require 'etc'

    # ... but the module name begins with an uppercase letter
    puts "Your login name: #{Etc.getlogin}"
    +
    # The feature name begins with a lowercase letter...
    +require 'etc'
    +
    +# ... but the module name begins with an uppercase letter
    +puts "Your login name: #{Etc.getlogin}"
    +
    @@ -498,7 +488,7 @@ begins with:

    -

    31.1.5 Static linking

    +

    36.1.5 Static linking

    An alternative approach to dynamic linking is to rebuild the @@ -519,7 +509,7 @@ finally rebuilding Ruby.

    -

    31.1.6 Compilation of C++ extensions

    +

    36.1.6 Compilation of C++ extensions

    On most machines, C++ extension modules should be linked @@ -571,7 +561,7 @@ extension, e.g.

    -

    31.2 Building Ruby Extensions under Windows 95/NT

    +

    36.2 Building Ruby Extensions under Windows 95/NT

    Building a SWIG extension to Ruby under Windows 95/NT is @@ -610,7 +600,7 @@ files.

    -

    31.2.1 Running SWIG from Developer Studio

    +

    36.2.1 Running SWIG from Developer Studio

    If you are developing your application within Microsoft @@ -752,7 +742,7 @@ directory, then run the Ruby script from the DOS/Command prompt:

    -

    31.3 The Ruby-to-C/C++ Mapping

    +

    36.3 The Ruby-to-C/C++ Mapping

    This section describes the basics of how SWIG maps C or C++ @@ -762,7 +752,7 @@ declarations in your SWIG interface files to Ruby constructs.

    -

    31.3.1 Modules

    +

    36.3.1 Modules

    The SWIG %module directive specifies @@ -931,7 +921,7 @@ Ruby's built-in names.

    -

    31.3.2 Functions

    +

    36.3.2 Functions

    Global functions are wrapped as Ruby module methods. For @@ -994,7 +984,7 @@ module that can be used like so:

    -

    31.3.3 Variable Linking

    +

    36.3.3 Variable Linking

    C/C++ global variables are wrapped as a pair of singleton @@ -1094,7 +1084,7 @@ effect until it is explicitly disabled using %mutable. -

    31.3.4 Constants

    +

    36.3.4 Constants

    C/C++ constants are wrapped as module constants initialized @@ -1138,7 +1128,7 @@ constant values, e.g.

    -

    31.3.5 Pointers

    +

    36.3.5 Pointers

    "Opaque" pointers to arbitrary C/C++ types (i.e. types that @@ -1190,7 +1180,7 @@ the Ruby nil object.

    -

    31.3.6 Structures

    +

    36.3.6 Structures

    C/C++ structs are wrapped as Ruby classes, with accessor @@ -1317,7 +1307,7 @@ this code:

    If you want to set an array member, you will need to supply a -"memberin" typemap described in the section on typemaps. +"memberin" typemap described in the section on typemaps. As a special case, SWIG does generate code to set array members of type char (allowing you to store a Ruby string in the structure).

    @@ -1365,7 +1355,7 @@ pointers. For example,

    -

    31.3.7 C++ classes

    +

    36.3.7 C++ classes

    Like structs, C++ classes are wrapped by creating a new Ruby @@ -1451,7 +1441,7 @@ class.

  • -

    31.3.8 C++ Inheritance

    +

    36.3.8 C++ Inheritance

    The SWIG type-checker is fully aware of C++ inheritance. @@ -1559,7 +1549,7 @@ you'll see a warning message like:

    -
    example.i:5: Warning(802): Warning for Derived: Base Base2 ignored.
    Multiple inheritance is not supported in Ruby.
    +
    example.i:5: Warning 802: Warning for Derived: Base Base2 ignored.
    Multiple inheritance is not supported in Ruby.
    @@ -1682,7 +1672,7 @@ Typing").

    -

    31.3.9 C++ Overloaded Functions

    +

    36.3.9 C++ Overloaded Functions

    C++ overloaded functions, methods, and constructors are @@ -1810,7 +1800,11 @@ message like this:

    -
    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).
    +
    +
    @@ -1878,7 +1872,7 @@ and C++" chapter for more information about overloading.

    -

    31.3.10 C++ Operators

    +

    36.3.10 C++ Operators

    For the most part, overloaded operators are handled @@ -1952,14 +1946,14 @@ example:

    More details about wrapping C++ operators into Ruby operators -is discussed in the section +is discussed in the section on operator overloading.

    -

    31.3.11 C++ namespaces

    +

    36.3.11 C++ namespaces

    SWIG is aware of C++ namespaces, but namespace names do not @@ -2035,7 +2029,7 @@ identical symbol names, well, then you get what you deserve.

    -

    31.3.12 C++ templates

    +

    36.3.12 C++ templates

    C++ templates don't present a huge problem for SWIG. However, @@ -2079,7 +2073,7 @@ directive. For example:

    -

    31.3.13 C++ Standard Template Library (STL)

    +

    36.3.13 C++ Standard Template Library (STL)

    On a related note, the standard SWIG library contains a @@ -2332,7 +2326,7 @@ chapter.

    -

    31.3.14 C++ STL Functors

    +

    36.3.14 C++ STL Functors

    Some containers in the STL allow you to modify their default @@ -2393,7 +2387,7 @@ intset;
    -%include std_set.i
    +%include <std_set.i>
    @@ -2532,7 +2526,7 @@ b
    -

    31.3.15 C++ STL Iterators

    +

    36.3.15 C++ STL Iterators

    The STL is well known for the use of iterators.  There @@ -2729,7 +2723,7 @@ i
    ->> [3, 4, 5 ]

    +>> [3, 4, 5 ]
    @@ -2743,7 +2737,7 @@ i
    -

    31.3.16 C++ Smart Pointers

    +

    36.3.16 C++ Smart Pointers

    In certain C++ programs, it is common to use classes that @@ -2868,12 +2862,12 @@ method. For example:

    -

    31.3.17 Cross-Language Polymorphism

    +

    36.3.17 Cross-Language Polymorphism

    SWIG's Ruby module supports cross-language polymorphism (a.k.a. the "directors" feature) similar to that for SWIG's Python -module. Rather than duplicate the information presented in the Python chapter, this +module. Rather than duplicate the information presented in the Python chapter, this section just notes the differences that you need to be aware of when using this feature with Ruby.

    @@ -2881,7 +2875,7 @@ using this feature with Ruby.

    -

    31.3.17.1 Exception Unrolling

    +

    36.3.17.1 Exception Unrolling

    Whenever a C++ director class routes one of its virtual @@ -2919,7 +2913,7 @@ caught here and a C++ exception is raised in its place.

    -

    31.4 Naming

    +

    36.4 Naming

    Ruby has several common naming conventions. Constants are @@ -3015,7 +3009,7 @@ planned to become the default option in future releases.

    -

    31.4.1 Defining Aliases

    +

    36.4.1 Defining Aliases

    It's a fairly common practice in the Ruby built-ins and @@ -3107,7 +3101,7 @@ Features") for more details).

    -

    31.4.2 Predicate Methods

    +

    36.4.2 Predicate Methods

    Ruby methods that return a boolean value and end in a @@ -3196,7 +3190,7 @@ Features") for more details).

    -

    31.4.3 Bang Methods

    +

    36.4.3 Bang Methods

    Ruby methods that modify an object in-place and end in an @@ -3260,7 +3254,7 @@ Features") for more details).

    -

    31.4.4 Getters and Setters

    +

    36.4.4 Getters and Setters

    Often times a C++ library will expose properties through @@ -3330,7 +3324,7 @@ methods to be exposed in Ruby as value and value=. -

    31.5 Input and output parameters

    +

    36.5 Input and output parameters

    A common problem in some C programs is handling parameters @@ -3581,10 +3575,10 @@ of %apply

    -

    31.6 Exception handling

    +

    36.6 Exception handling

    -

    31.6.1 Using the %exception directive

    +

    36.6.1 Using the %exception directive

    The SWIG %exception directive can be @@ -3679,7 +3673,7 @@ Features for more examples.

    -

    31.6.2 Handling Ruby Blocks

    +

    36.6.2 Handling Ruby Blocks

    One of the highlights of Ruby and most of its standard library @@ -3860,7 +3854,7 @@ RUBY_YIELD_SELF );

    For more information on typemaps, see Typemaps.

    -

    31.6.3 Raising exceptions

    +

    36.6.3 Raising exceptions

    There are three ways to raise exceptions from C++ code to @@ -4621,7 +4615,7 @@ the built-in Ruby exception types.

    -

    31.6.4 Exception classes

    +

    36.6.4 Exception classes

    Starting with SWIG 1.3.28, the Ruby module supports the %exceptionclass @@ -4679,7 +4673,7 @@ providing for a more natural integration between C++ code and Ruby code.

    -

    31.7 Typemaps

    +

    36.7 Typemaps

    This section describes how you can modify SWIG's default @@ -4702,7 +4696,7 @@ of the primitive C-Ruby interface.

    -

    31.7.1 What is a typemap?

    +

    36.7.1 What is a typemap?

    A typemap is nothing more than a code generation rule that is @@ -4964,7 +4958,7 @@ to be used as follows (notice how the length parameter is omitted):

    -

    31.7.2 Typemap scope

    +

    36.7.2 Typemap scope

    Once defined, a typemap remains in effect for all of the @@ -5012,7 +5006,7 @@ where the class itself is defined. For example:

    -

    31.7.3 Copying a typemap

    +

    36.7.3 Copying a typemap

    A typemap is copied by using assignment. For example:

    @@ -5114,7 +5108,7 @@ rules as for -

    31.7.4 Deleting a typemap

    +

    36.7.4 Deleting a typemap

    A typemap can be deleted by simply defining no code. For @@ -5166,7 +5160,7 @@ typemaps immediately after the clear operation.

    -

    31.7.5 Placement of typemaps

    +

    36.7.5 Placement of typemaps

    Typemap declarations can be declared in the global scope, @@ -5250,7 +5244,7 @@ string -

    31.7.6 Ruby typemaps

    +

    36.7.6 Ruby typemaps

    The following list details all of the typemap methods that @@ -5260,7 +5254,7 @@ can be used by the Ruby module:

    -

    31.7.6.1  "in" typemap

    +

    36.7.6.1  "in" typemap

    Converts Ruby objects to input @@ -5503,7 +5497,7 @@ arguments to be specified. For example:

    -

    31.7.6.2 "typecheck" typemap

    +

    36.7.6.2 "typecheck" typemap

    The "typecheck" typemap is used to support overloaded @@ -5544,7 +5538,7 @@ on "Typemaps and Overloading."

    -

    31.7.6.3  "out" typemap

    +

    36.7.6.3  "out" typemap

    Converts return value of a C function @@ -5776,7 +5770,7 @@ version of the C datatype matched by the typemap. -

    31.7.6.4 "arginit" typemap

    +

    36.7.6.4 "arginit" typemap

    The "arginit" typemap is used to set the initial value of a @@ -5801,7 +5795,7 @@ applications. For example:

    -

    31.7.6.5 "default" typemap

    +

    36.7.6.5 "default" typemap

    The "default" typemap is used to turn an argument into a @@ -5843,7 +5837,7 @@ default argument wrapping.

    -

    31.7.6.6 "check" typemap

    +

    36.7.6.6 "check" typemap

    The "check" typemap is used to supply value checking code @@ -5867,7 +5861,7 @@ arguments have been converted. For example:

    -

    31.7.6.7 "argout" typemap

    +

    36.7.6.7 "argout" typemap

    The "argout" typemap is used to return values from arguments. @@ -6025,7 +6019,7 @@ some function like SWIG_Ruby_AppendOutput.

    -

    31.7.6.8 "freearg" typemap

    +

    36.7.6.8 "freearg" typemap

    The "freearg" typemap is used to cleanup argument data. It is @@ -6061,7 +6055,7 @@ abort prematurely.

    -

    31.7.6.9 "newfree" typemap

    +

    36.7.6.9 "newfree" typemap

    The "newfree" typemap is used in conjunction with the %newobject @@ -6085,14 +6079,14 @@ a function. For example:

    -

    See Object +

    See Object ownership and %newobject for further details.

    -

    31.7.6.10 "memberin" typemap

    +

    36.7.6.10 "memberin" typemap

    The "memberin" typemap is used to copy data from an @@ -6125,7 +6119,7 @@ other objects.

    -

    31.7.6.11 "varin" typemap

    +

    36.7.6.11 "varin" typemap

    The "varin" typemap is used to convert objects in the target @@ -6136,7 +6130,7 @@ This is implementation specific.

    -

    31.7.6.12 "varout" typemap

    +

    36.7.6.12 "varout" typemap

    The "varout" typemap is used to convert a C/C++ object to an @@ -6147,7 +6141,7 @@ This is implementation specific.

    -

    31.7.6.13 "throws" typemap

    +

    36.7.6.13 "throws" typemap

    The "throws" typemap is only used when SWIG parses a C++ @@ -6206,7 +6200,7 @@ handling with %exception section.

    -

    31.7.6.14 directorin typemap

    +

    36.7.6.14 directorin typemap

    Converts C++ objects in director @@ -6460,7 +6454,7 @@ referring to the class itself. -

    31.7.6.15 directorout typemap

    +

    36.7.6.15 directorout typemap

    Converts Ruby objects in director @@ -6523,49 +6517,16 @@ typemap.

    - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - + @@ -6720,7 +6681,7 @@ exception.
    -

    31.7.6.16 directorargout typemap

    +

    36.7.6.16 directorargout typemap

    Output argument processing in director @@ -6769,80 +6730,21 @@ $result = output_helper( $result, NUM2INT($1) );

    - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - + - - - - - @@ -6960,7 +6862,7 @@ referring to the instance of the class itself -

    31.7.6.17 ret typemap

    +

    36.7.6.17 ret typemap

    Cleanup of function return values @@ -6970,7 +6872,7 @@ referring to the instance of the class itself -

    31.7.6.18 globalin typemap

    +

    36.7.6.18 globalin typemap

    Setting of C global variables @@ -6980,7 +6882,7 @@ referring to the instance of the class itself -

    31.7.7 Typemap variables

    +

    36.7.7 Typemap variables

    @@ -7090,14 +6992,14 @@ being created. -

    31.7.8 Useful Functions

    +

    36.7.8 Useful Functions

    When you write a typemap, you usually have to work directly with Ruby objects. The following functions may prove to be useful. -(These functions plus many more can be found in Programming -Ruby, by David Thomas and Andrew Hunt.) 

    -

    In addition, we list equivalent functions that Swig defines, which +(These functions plus many more can be found in Programming +Ruby book, by David Thomas and Andrew Hunt.) 

    +

    In addition, we list equivalent functions that SWIG defines, which provide a language neutral conversion (these functions are defined for each swig language supported).  If you are trying to create a swig file that will work under multiple languages, it is recommended you @@ -7114,7 +7016,7 @@ across multiple languages.

    -

    31.7.8.1 C Datatypes to Ruby Objects

    +

    36.7.8.1 C Datatypes to Ruby Objects

    @@ -7123,7 +7025,7 @@ across multiple languages.

    - + @@ -7170,7 +7072,7 @@ SWIG_From_float(float) -

    31.7.8.2 Ruby Objects to C Datatypes

    +

    36.7.8.2 Ruby Objects to C Datatypes

    Here, while the Ruby versions return the value directly, the SWIG @@ -7259,7 +7161,7 @@ Ruby_Format_TypeError( "$1_name", "$1_type","$symname", $argnum, $input -

    31.7.8.3 Macros for VALUE

    +

    36.7.8.3 Macros for VALUE

    RSTRING_LEN(str)

    @@ -7322,7 +7224,7 @@ Ruby_Format_TypeError( "$1_name", "$1_type","$symname", $argnum, $input -

    31.7.8.4 Exceptions

    +

    36.7.8.4 Exceptions

    void rb_raise(VALUE exception, const char *fmt, @@ -7489,7 +7391,7 @@ arguments are interpreted as with printf(). -

    31.7.8.5 Iterators

    +

    36.7.8.5 Iterators

    void rb_iter_break()

    @@ -7591,7 +7493,7 @@ VALUE), VALUE value)

    -

    31.7.9 Typemap Examples

    +

    36.7.9 Typemap Examples

    This section includes a few examples of typemaps. For more @@ -7602,7 +7504,7 @@ directory.

    -

    31.7.10 Converting a Ruby array to a char **

    +

    36.7.10 Converting a Ruby array to a char **

    A common problem in many C programs is the processing of @@ -7657,7 +7559,7 @@ after the execution of the C function.

    -

    31.7.11 Collecting arguments in a hash

    +

    36.7.11 Collecting arguments in a hash

    Ruby's solution to the "keyword arguments" capability of some @@ -7936,7 +7838,7 @@ directory of the SWIG distribution.

    -

    31.7.12 Pointer handling

    +

    36.7.12 Pointer handling

    Occasionally, it might be necessary to convert pointer values @@ -8035,7 +7937,7 @@ For example:

    -

    31.7.12.1 Ruby Datatype Wrapping

    +

    36.7.12.1 Ruby Datatype Wrapping

    VALUE Data_Wrap_Struct(VALUE class, void @@ -8086,7 +7988,7 @@ and assigns that pointer to ptr. -

    31.7.13 Example: STL Vector to Ruby Array

    +

    36.7.13 Example: STL Vector to Ruby Array

    Another use for macros and type maps is to create a Ruby array @@ -8195,7 +8097,7 @@ the C++ Standard Template Library.
    -

    31.8 Docstring Features

    +

    36.8 Docstring Features

    @@ -8256,7 +8158,7 @@ generate ri documentation from a c wrap file, you could do:

    -

    31.8.1 Module docstring

    +

    36.8.1 Module docstring

    @@ -8307,7 +8209,7 @@ macro. For example: -

    31.8.2 %feature("autodoc")

    +

    36.8.2 %feature("autodoc")

    Since SWIG does know everything about the function it wraps, @@ -8336,7 +8238,7 @@ feature, described below. -

    31.8.2.1 %feature("autodoc", "0")

    +

    36.8.2.1 %feature("autodoc", "0")

    @@ -8384,7 +8286,7 @@ Then Ruby code like this will be generated: -

    31.8.2.2 %feature("autodoc", "1")

    +

    36.8.2.2 %feature("autodoc", "1")

    @@ -8416,7 +8318,7 @@ this: -

    31.8.2.3 %feature("autodoc", "2")

    +

    36.8.2.3 %feature("autodoc", "2")

    @@ -8432,7 +8334,7 @@ this: -

    31.8.2.4 %feature("autodoc", "3")

    +

    36.8.2.4 %feature("autodoc", "3")

    @@ -8460,7 +8362,7 @@ this: -

    31.8.2.5 %feature("autodoc", "docstring")

    +

    36.8.2.5 %feature("autodoc", "docstring")

    @@ -8488,7 +8390,7 @@ generated string. For example: -

    31.8.3 %feature("docstring")

    +

    36.8.3 %feature("docstring")

    @@ -8503,10 +8405,10 @@ docstring and they are output together.

    -

    31.9 Advanced Topics

    +

    36.9 Advanced Topics

    -

    31.9.1 Operator overloading

    +

    36.9.1 Operator overloading

    SWIG allows operator overloading with, by using the %extend @@ -9523,10 +9425,10 @@ parses the expression a != b as !(a == b). -

    31.9.2 Creating Multi-Module Packages

    +

    36.9.2 Creating Multi-Module Packages

    -

    The chapter on Working +

    The chapter on Working with Modules discusses the basics of creating multi-module extensions with SWIG, and in particular the considerations for sharing runtime type information among the different modules.

    @@ -9704,7 +9606,7 @@ initialized:

    -

    31.9.3 Specifying Mixin Modules

    +

    36.9.3 Specifying Mixin Modules

    The Ruby language doesn't support multiple inheritance, but @@ -9802,7 +9704,7 @@ Features") for more details).

    -

    31.10 Memory Management

    +

    36.10 Memory Management

    One of the most common issues in generating SWIG bindings for @@ -9849,7 +9751,7 @@ understanding of how the underlying library manages memory.

    -

    31.10.1 Mark and Sweep Garbage Collector

    +

    36.10.1 Mark and Sweep Garbage Collector

    Ruby uses a mark and sweep garbage collector. When the garbage @@ -9897,7 +9799,7 @@ this memory.

    -

    31.10.2 Object Ownership

    +

    36.10.2 Object Ownership

    As described above, memory management depends on clearly @@ -10046,7 +9948,7 @@ above. For example:

    In this case, the default SWIG behavior for calling member functions is incorrect. The Ruby object should assume ownership of the returned object. This can be done by using the %newobject directive. -See +See Object ownership and %newobject for more information.

    @@ -10094,7 +9996,38 @@ classes is:

    -
    /* File RubyOwnershipExample.i */

    %module RubyOwnershipExample

    %{
    #include "RubyOwnershipExample.h"
    %}

    class Foo
    {
    public:
    Foo();
    ~Foo();
    };

    class Bar
    {
    Foo *foo_;
    public:
    Bar();
    ~Bar();
    Foo* get_foo();

    %newobject get_new_foo;
    Foo* get_new_foo();

    %apply SWIGTYPE *DISOWN {Foo *foo};
    void set_foo(Foo *foo);
    %clear Foo *foo;
    };

    +
    /* File RubyOwnershipExample.i */
    +
    +%module RubyOwnershipExample
    +
    +%{
    +#include "RubyOwnershipExample.h"
    +%}
    +
    +class Foo
    +{
    +public:
    + Foo();
    + ~Foo();
    +};
    +
    +class Bar
    +{
    + Foo *foo_;
    +public:
    + Bar();
    + ~Bar();
    + Foo* get_foo();
    +
    + %newobject get_new_foo;
    + Foo* get_new_foo();
    +
    + %apply SWIGTYPE *DISOWN {Foo *foo};
    + void set_foo(Foo *foo);
    + %clear Foo *foo;
    +};
    +
    +
    @@ -10124,7 +10057,7 @@ classes is:

    -

    31.10.3 Object Tracking

    +

    36.10.3 Object Tracking

    The remaining parts of this section will use the class library @@ -10161,7 +10094,35 @@ class library models a zoo and the animals it contains.

    -
    $ irb
    irb(main):001:0> require 'example'
    => true

    irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2be3820>

    irb(main):004:0> tiger1.get_name()
    => "tiger1"

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be0a60>

    irb(main):006:0> zoo.add_animal(tiger)
    => nil

    irb(main):007:0> zoo.get_num_animals()
    => 1

    irb(main):007:0> tiger2 = zoo.remove_animal(0)
    => #<Example::Animal:0x2bd4a18>

    irb(main):008:0> tiger2.get_name()
    => "tiger1"

    irb(main):009:0> tiger1.equal?(tiger2)
    => false

    +
    $ irb
    +irb(main):001:0> require 'example'
    +=> true
    +
    +irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    +=> #<Example::Animal:0x2be3820>
    +
    +irb(main):004:0> tiger1.get_name()
    +=> "tiger1"
    +
    +irb(main):003:0> zoo = Example::Zoo.new()
    +=> #<Example::Zoo:0x2be0a60>
    +
    +irb(main):006:0> zoo.add_animal(tiger)
    +=> nil
    +
    +irb(main):007:0> zoo.get_num_animals()
    +=> 1
    +
    +irb(main):007:0> tiger2 = zoo.remove_animal(0)
    +=> #<Example::Animal:0x2bd4a18>
    +
    +irb(main):008:0> tiger2.get_name()
    +=> "tiger1"
    +
    +irb(main):009:0> tiger1.equal?(tiger2)
    +=> false
    +
    +
    @@ -10188,7 +10149,16 @@ the same underlying C++ object. This can cause problems. For example:
    -
    irb(main):010:0> tiger1 = nil
    => nil

    irb(main):011:0> GC.start
    => nil

    irb(main):012:0> tiger2.get_name()
    (irb):12: [BUG] Segmentation fault

    +
    irb(main):010:0> tiger1 = nil
    +=> nil
    +
    +irb(main):011:0> GC.start
    +=> nil
    +
    +irb(main):012:0> tiger2.get_name()
    +(irb):12: [BUG] Segmentation fault
    +
    +
    @@ -10200,7 +10170,7 @@ the same underlying C++ object. This can cause problems. For example:
    -

    After the the garbage collector runs, as a result of our call +

    After the garbage collector runs, as a result of our call to GC.start, callingtiger2.get_name() causes a segmentation fault. The problem is that when tiger1 is garbage collected, it frees the underlying C++ object. Thus, when tiger2 @@ -10247,7 +10217,7 @@ class-by-class basis if needed. To fix the example above:

    -
    %module example

    %{
    #include "example.h"
    %}

    /* Tell SWIG that create_animal creates a new object */
    %newobject Zoo::create_animal;

    /* Tell SWIG to keep track of mappings between C/C++ structs/classes. */
    %trackobjects;

    %include "example.h"
    +
    %module example

    %{
    #include "example.h"
    %}

    /* Tell SWIG that create_animal creates a new object */
    %newobject Zoo::create_animal;

    /* Tell SWIG to keep track of mappings between C/C++ structs/classes. */
    %trackobjects;

    %include "example.h"
    @@ -10278,7 +10248,7 @@ class-by-class basis if needed. To fix the example above:

    -
    $ irb
    irb(main):001:0> require 'example'
    => true

    irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2be37d8>

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be0a18>

    irb(main):004:0> zoo.add_animal(tiger1)
    => nil

    irb(main):006:0> tiger2 = zoo.remove_animal(0)
    => #<Example::Animal:0x2be37d8>

    irb(main):007:0> tiger1.equal?(tiger2)
    => true

    irb(main):008:0> tiger1 = nil
    => nil

    irb(main):009:0> GC.start
    => nil

    irb(main):010:0> tiger.get_name()
    => "tiger1"
    irb(main):011:0>

    +
    $ irb
    irb(main):001:0> require 'example'
    => true

    irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2be37d8>

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be0a18>

    irb(main):004:0> zoo.add_animal(tiger1)
    => nil

    irb(main):006:0> tiger2 = zoo.remove_animal(0)
    => #<Example::Animal:0x2be37d8>

    irb(main):007:0> tiger1.equal?(tiger2)
    => true

    irb(main):008:0> tiger1 = nil
    => nil

    irb(main):009:0> GC.start
    => nil

    irb(main):010:0> tiger.get_name()
    => "tiger1"
    irb(main):011:0>

    @@ -10338,7 +10308,7 @@ methods.

    -

    31.10.4 Mark Functions

    +

    36.10.4 Mark Functions

    With a bit more testing, we see that our class library still @@ -10355,7 +10325,7 @@ has problems. For example:

    -
    $ irb
    irb(main):001:0> require 'example'
    => true

    irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2bea6a8>

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be7960>

    irb(main):004:0> zoo.add_animal(tiger1)
    => nil

    irb(main):007:0> tiger1 = nil
    => nil

    irb(main):007:0> GC.start
    => nil

    irb(main):005:0> tiger2 = zoo.get_animal(0)
    (irb):12: [BUG] Segmentation fault
    +
    $ irb
    irb(main):001:0> require 'example'
    => true

    irb(main):002:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2bea6a8>

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be7960>

    irb(main):004:0> zoo.add_animal(tiger1)
    => nil

    irb(main):007:0> tiger1 = nil
    => nil

    irb(main):007:0> GC.start
    => nil

    irb(main):005:0> tiger2 = zoo.get_animal(0)
    (irb):12: [BUG] Segmentation fault
    @@ -10403,7 +10373,7 @@ implementation is:

    -
    %module example

    %{
    #include "example.h"
    %}

    /* Keep track of mappings between C/C++ structs/classes
    and Ruby objects so we can implement a mark function. */
    %trackobjects;

    /* Specify the mark function */
    %markfunc Zoo "mark_Zoo";

    %include "example.h"

    %header %{

    static void mark_Zoo(void* ptr) {
    Zoo* zoo = (Zoo*) ptr;

    /* Loop over each object and tell the garbage collector
    that we are holding a reference to them. */
    int count = zoo->get_num_animals();

    for(int i = 0; i < count; ++i) {
    Animal* animal = zoo->get_animal(i);
    VALUE object = SWIG_RubyInstanceFor(animal);

    if (object != Qnil) {
    rb_gc_mark(object);
    }
    }
    }
    %}

    +
    %module example

    %{
    #include "example.h"
    %}

    /* Keep track of mappings between C/C++ structs/classes
    and Ruby objects so we can implement a mark function. */
    %trackobjects;

    /* Specify the mark function */
    %markfunc Zoo "mark_Zoo";

    %include "example.h"

    %header %{

    static void mark_Zoo(void* ptr) {
    Zoo* zoo = (Zoo*) ptr;

    /* Loop over each object and tell the garbage collector
    that we are holding a reference to them. */
    int count = zoo->get_num_animals();

    for(int i = 0; i < count; ++i) {
    Animal* animal = zoo->get_animal(i);
    VALUE object = SWIG_RubyInstanceFor(animal);

    if (object != Qnil) {
    rb_gc_mark(object);
    }
    }
    }
    %}

    @@ -10432,7 +10402,7 @@ test suite.

    -
    $ irb
    irb(main):002:0> tiger1=Example::Animal.new("tiger1")
    => #<Example::Animal:0x2be3bf8>

    irb(main):003:0> Example::Zoo.new()
    => #<Example::Zoo:0x2be1780>

    irb(main):004:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2bde9c0>

    irb(main):005:0> zoo.add_animal(tiger1)
    => nil

    irb(main):009:0> tiger1 = nil
    => nil

    irb(main):010:0> GC.start
    => nil
    irb(main):014:0> tiger2 = zoo.get_animal(0)
    => #<Example::Animal:0x2be3bf8>

    irb(main):015:0> tiger2.get_name()
    => "tiger1"
    irb(main):016:0>

    +
    $ irb
    irb(main):002:0> tiger1=Example::Animal.new("tiger1")
    => #<Example::Animal:0x2be3bf8>

    irb(main):003:0> Example::Zoo.new()
    => #<Example::Zoo:0x2be1780>

    irb(main):004:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2bde9c0>

    irb(main):005:0> zoo.add_animal(tiger1)
    => nil

    irb(main):009:0> tiger1 = nil
    => nil

    irb(main):010:0> GC.start
    => nil
    irb(main):014:0> tiger2 = zoo.get_animal(0)
    => #<Example::Animal:0x2be3bf8>

    irb(main):015:0> tiger2.get_name()
    => "tiger1"
    irb(main):016:0>

    @@ -10456,7 +10426,7 @@ test suite.

    -

    31.10.5 Free Functions

    +

    36.10.5 Free Functions

    By default, SWIG creates a "free" function that is called when @@ -10508,14 +10478,22 @@ directive, let's slightly change our example. Assume that the zoo object is responsible for freeing animal that it contains. This means that the Zoo::add_animal function should be marked with a DISOWN typemap -and the destructor should be updated as below::

    +and the destructor should be updated as below:

    -
    Zoo::~Zoo() {
    IterType iter = this->animals.begin();
    IterType end = this->animals.end();

    for(iter; iter != end; ++iter) {
    Animal* animal = *iter;
    delete animal;
    }
    }
    +
    Zoo::~Zoo() {
    + IterType iter = this->animals.begin();
    + IterType end = this->animals.end();
    +
    + for(iter; iter != end; ++iter) {
    + Animal* animal = *iter;
    + delete animal;
    + }
    +}
    @@ -10534,7 +10512,29 @@ and the destructor should be updated as below::

    -
    $irb
    irb(main):002:0> require 'example'
    => true

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be0fe8>

    irb(main):005:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2bda760>

    irb(main):006:0> zoo.add_animal(tiger1)
    => nil

    irb(main):007:0> zoo = nil
    => nil

    irb(main):008:0> GC.start
    => nil

    irb(main):009:0> tiger1.get_name()
    (irb):12: [BUG] Segmentation fault

    +
    $irb
    +irb(main):002:0> require 'example'
    +=> true
    +
    +irb(main):003:0> zoo = Example::Zoo.new()
    +=> #<Example::Zoo:0x2be0fe8>
    +
    +irb(main):005:0> tiger1 = Example::Animal.new("tiger1")
    +=> #<Example::Animal:0x2bda760>
    +
    +irb(main):006:0> zoo.add_animal(tiger1)
    +=> nil
    +
    +irb(main):007:0> zoo = nil
    +=> nil
    +
    +irb(main):008:0> GC.start
    +=> nil
    +
    +irb(main):009:0> tiger1.get_name()
    +(irb):12: [BUG] Segmentation fault
    +
    +
    @@ -10567,7 +10567,49 @@ existing Ruby object to the destroyed C++ object and raise an exception.
    -
    %module example

    %{
    #include "example.h"
    %}

    /* Specify that ownership is transferred to the zoo
    when calling add_animal */
    %apply SWIGTYPE *DISOWN { Animal* animal };

    /* Track objects */
    %trackobjects;

    /* Specify the mark function */
    %freefunc Zoo "free_Zoo";

    %include "example.h"

    %header %{
    static void free_Zoo(void* ptr) {
    Zoo* zoo = (Zoo*) ptr;

    /* Loop over each animal */
    int count = zoo->get_num_animals();

    for(int i = 0; i < count; ++i) {
    /* Get an animal */
    Animal* animal = zoo->get_animal(i);

    /* Unlink the Ruby object from the C++ object */
    SWIG_RubyUnlinkObjects(animal);

    /* Now remove the tracking for this animal */
    SWIG_RubyRemoveTracking(animal);
    }

    /* Now call SWIG_RemoveMapping for the zoo */
    SWIG_RemoveMapping(ptr);

    /* Now free the zoo which will free the animals it contains */
    delete zoo;
    }
    %}
    +
    %module example
    +
    +%{
    +#include "example.h"
    +%}
    +
    +/* Specify that ownership is transferred to the zoo
    +	when calling add_animal */
    +%apply SWIGTYPE *DISOWN { Animal* animal };
    +
    +/* Track objects */
    +%trackobjects;
    +
    +/* Specify the mark function */
    +%freefunc Zoo "free_Zoo";
    +
    +%include "example.h"
    +
    +%header %{
    + static void free_Zoo(void* ptr) {
    + Zoo* zoo = (Zoo*) ptr;
    +
    + /* Loop over each animal */
    + int count = zoo->get_num_animals();
    +
    + for(int i = 0; i < count; ++i) {
    + /* Get an animal */
    + Animal* animal = zoo->get_animal(i);
    +
    + /* Unlink the Ruby object from the C++ object */
    + SWIG_RubyUnlinkObjects(animal);
    +
    + /* Now remove the tracking for this animal */
    + SWIG_RubyRemoveTracking(animal);
    + }
    +
    + /* Now call SWIG_RubyRemoveTracking for the zoo */
    + SWIG_RubyRemoveTracking(ptr);
    + 
    + /* Now free the zoo which will free the animals it contains */
    + delete zoo;
    + }
    +%} 
    @@ -10586,7 +10628,30 @@ existing Ruby object to the destroyed C++ object and raise an exception.
    -
    $irb
    irb(main):002:0> require 'example'
    => true

    irb(main):003:0> zoo = Example::Zoo.new()
    => #<Example::Zoo:0x2be0fe8>

    irb(main):005:0> tiger1 = Example::Animal.new("tiger1")
    => #<Example::Animal:0x2bda760>

    irb(main):006:0> zoo.add_animal(tiger1)
    => nil

    irb(main):007:0> zoo = nil
    => nil

    irb(main):008:0> GC.start
    => nil

    irb(main):009:0> tiger1.get_name()
    RuntimeError: This Animal * already released
    from (irb):10:in `get_name'
    from (irb):10
    irb(main):011:0>
    +
    $irb
    +irb(main):002:0> require 'example'
    +=> true
    +
    +irb(main):003:0> zoo = Example::Zoo.new()
    +=> #<Example::Zoo:0x2be0fe8>
    +
    +irb(main):005:0> tiger1 = Example::Animal.new("tiger1")
    +=> #<Example::Animal:0x2bda760>
    +
    +irb(main):006:0> zoo.add_animal(tiger1)
    +=> nil
    +
    +irb(main):007:0> zoo = nil
    +=> nil
    +
    +irb(main):008:0> GC.start
    +=> nil
    +
    +irb(main):009:0> tiger1.get_name()
    +RuntimeError: This Animal * already released
    + from (irb):10:in `get_name'
    + from (irb):10
    +irb(main):011:0>
    @@ -10611,7 +10676,7 @@ been freed, and thus raises a runtime exception.

    -

    31.10.6 Embedded Ruby and the C++ Stack

    +

    36.10.6 Embedded Ruby and the C++ Stack

    As has been said, the Ruby GC runs and marks objects before @@ -10645,7 +10710,7 @@ initialization a normal Ruby interpreter will call the ruby_init() function which in turn will call a function called Init_stack or similar.  This function will store a pointer to the location where -the stack points at at that point in time.

    +the stack points at that point in time.

    diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index c22d81c07..58a3c8e55 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -13,7 +13,7 @@
  • Running SWIG @@ -53,7 +59,7 @@
  • Character strings and structures
  • Array members
  • Structure data members -
  • C constructors and destructors +
  • C constructors and destructors
  • Adding member functions to C structures
  • Nested structures
  • Other things to note about structure wrapping @@ -92,7 +98,7 @@ chapters.

    -To run SWIG, use the swig command with options options and a filename like this: +To run SWIG, use the swig command with options and a filename like this:

    @@ -113,6 +119,7 @@ can be obtained by typing swig -help or 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 swig -help or 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 swig -help or swig
     -lfile                Include a SWIG library file.
     -module name          Set the name of the SWIG module
     -o outfile            Name of output file
    +-outcurrentdir	      Set default output dir to current dir instead of input file's path
     -outdir dir           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);
     ...
     

    -The name of the module is supplied using the special %module -directive (or the -module 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 -%module directive. +The module name is supplied using the special %module +directive. Modules are described further in the Modules Introduction section.

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

    -

    5.1.2 SWIG Output

    +

    5.1.2 SWIG Output

    @@ -224,7 +227,7 @@ The C/C++ output file created by SWIG often contains everything that is needed to construct a extension module for the target scripting language. SWIG is not a stub compiler nor is it usually necessary to edit the output file (and if you look at the output, -you probably won't want to). To build the final extension module, the +you probably won't want to). To build the final extension module, the SWIG output file is compiled and linked with the rest of your C/C++ program to create a shared library.

    @@ -232,7 +235,7 @@ program to create a shared library.

    Many target languages will also generate proxy class files in the target language. The default output directory for these language -specific files is the same directory as the generated C/C++ file. This can +specific files is the same directory as the generated C/C++ file. This can be modified using the -outdir option. For example:

    @@ -247,6 +250,17 @@ cppfiles/example_wrap.cpp pyfiles/example.py
  • +

    +If the -outcurrentdir option is used (without -o) +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 -o and +-outcurrentdir are used together, -outcurrentdir 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 -outdir. +

    +

    5.1.3 Comments

    @@ -324,10 +338,13 @@ currently supported:

      -
    • Non-conventional type declarations. +
    • +

      +Non-conventional type declarations. For example, SWIG does not support declarations such as the following (even though this is legal C): +

       /* Non-conventional placement of storage specifier (extern) */
      @@ -349,15 +366,19 @@ if you're feeling particularly obfuscated, you can certainly break SWIG (althoug
       

    • -
    • 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: +
    • +

      +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 +

      -/* 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) {
       
    • -
    • 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. +
    • +

      +Certain advanced features of C++ such as nested classes +are not yet fully supported. Please see the C++ Nested classes section +for more information. +

    @@ -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

    defines a constant because PI 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

    +
    +
    +#define F_CONST (double) 5            // A floating pointer constant with cast
    +
    +
    +

    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 e can change---it's only the value being pointed to that is read-only.

    +

    +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 const-correctness +for more information. +

    +

    Compatibility Note: One reason for changing SWIG to handle const declarations as read-only variables is that there are @@ -1590,7 +1626,7 @@ double y; // Read-write

    The %mutable and %immutable directives are actually -%feature directives defined like this: +%feature directives defined like this:

    @@ -1633,6 +1669,9 @@ generate a warning message.   Simply change the directives to %immutable;5.4.7 Renaming and ignoring declarations
     
     
    +

    5.4.7.1 Simple renaming of specific identifiers

    + +

    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 :

    // 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:
     %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 *);
     ...
     
    @@ -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.

    -

    -More powerful variants of %rename and %ignore directives can be used to help -wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the -Ambiguity resolution and renaming section in the C++ chapter. -

    -

    Compatibility note: Older versions of SWIG provided a special %name directive for renaming declarations. For example: @@ -1724,7 +1758,7 @@ For example:

    -%name(output) extern void print(char *);
    +%name(output) extern void print(const char *);
     
    @@ -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.

    +

    5.4.7.2 Advanced renaming support

    + + +

    +While writing %rename 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: +

    + +
    +
    +%rename("myprefix_%s") ""; // print -> myprefix_print
    +
    +
    + +

    +This also shows that the argument of %rename doesn't have to be a +literal string but can be a printf()-like format string. In the +simplest form, "%s" 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 +do_something_long() as more Java-like doSomethingLong() you +can use the "lowercamelcase" extended format specifier like this: +

    + +
    +
    +%rename("%(lowercamelcase)s") ""; // foo_bar -> fooBar; FooBar -> fooBar
    +
    +
    + +

    +Some functions can be parametrized, for example the "strip" 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: +

    +
    +
    +%rename("%(strip:[wx])s") ""; // wxHello -> Hello; FooBar -> FooBar
    +
    +
    + +

    +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: +

    +
    $symname Name of -function/method being wrapped$inputRuby object being sent to the function
    $symname Name of function/method being wrapped
    $1...n Argument being -sent to the functionArgument being sent to the function
    $resultResult that the -director function returnsResult that the director function returns
    $inputRuby object being sent to the function
    $symnamename of the -function/method being wrappedname of the function/method being wrapped
    $1...nArgument being -sent to the functionArgument being sent to the function
    RUBYSwigSWIG
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FunctionReturnsExample (in/out)
    uppercase or upperUpper case version of the string.PrintPRINT
    lowercase or lowerLower case version of the string.Printprint
    titleString with first letter capitalized and the rest in lower case.printPrint
    firstuppercaseString with the first letter capitalized and the rest unchanged.printItPrintIt
    firstlowercaseString with the first letter in lower case and the rest unchanged.PrintItprintIt
    camelcase or ctitleString with capitalized first letter and any letter following an + underscore (which are removed in the process) and rest in lower case.print_itPrintIt
    lowercamelcase or lctitleString with every letter following an underscore (which is removed in + the process) capitalized and rest, including the first letter, in lower + case.print_itprintIt
    undercase or utitleLower 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 camelcase.PrintItprint_it
    schemifyString with all underscores replaced with dashes, resulting in more + Lispers/Schemers-pleasing name.print_itprint-it
    strip:[prefix]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. %rename("strip:[wx]")wxPrintPrint
    regex:/pattern/subst/String after (Perl-like) regex substitution operation. This function + allows to apply arbitrary regular expressions to the identifier names. The + pattern part is a regular expression in Perl syntax (as supported + by the Perl Compatible Regular Expressions (PCRE)) + library and the subst string + can contain back-references introduced by '\' or, as backslashes need + to be escaped in C strings, rather by "\\". For example, to remove + any alphabetic prefix before an underscore you could use the following directive: + %rename("regex:/(\\w+)_(.*)/\\2/")Prefix_PrintPrint
    command:cmdOutput of an external command cmd 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 cmd is not enclosed in + square brackets but must be terminated with a triple '<' sign, + e.g. %rename("command:tr -d aeiou <<<") + (nonsensical example removing all vowels)PrintPrnt
    + +

    +The most general function of all of the above ones (not counting +command which is even more powerful in principle but which should +generally be avoided because of performance considerations) is the +regex one. Here are some more examples of its use: +

    + +
    +
    +// Strip the wx prefix from all identifiers except those starting with wxEVT
    +%rename("%(regex:/wx(?!EVT)(.*)/\\1/)s") ""; // wxSomeWidget -> SomeWidget
    +                                             // wxEVT_PAINT -> 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 -> Red
    +
    +// Remove all "Set/Get" prefixes.
    +%rename("%(regex:/^(Set|Get)(.*)/\\2/)s") ""; // SetValue -> Value
    +                                              // GetValue -> Value
    +
    +
    + +

    +As before, everything that was said above about %rename also applies to +%ignore. 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 +"$ignore" value. So the following snippets +

    + +
    +
    +%ignore print;
    +
    +
    + +

    +and +

    + +
    +
    +%rename("$ignore") print;
    +
    +
    + +

    +are exactly equivalent and %rename can be used to selectively ignore +multiple declarations using the previously described matching possibilities. +

    + +

    5.4.7.3 Limiting global renaming rules

    + + +

    +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 +%rename can be limited using subsequent match parameters. +They can be applied to any of the attributes associated by SWIG with the +declarations appearing in its input. For example: +

    +
    +
    +%rename("foo", match$name="bar") "";
    +
    +
    +

    +can be used to achieve the same effect as the simpler +

    +
    +
    +%rename("foo") bar;
    +
    +
    +

    +and so is not very interesting on its own. However match can also be +applied to the declaration type, for example match="class" restricts +the match to class declarations only (in C++) and match="enumitem" +restricts it to the enum elements. SWIG also provides convenience macros for +such match expressions, for example +

    +
    +
    +%rename("%(title)s", %$isenumitem) "";
    +
    +
    +

    +will capitalize the names of all the enum elements but not change the case of +the other declarations. Similarly, %$isclass, %$isfunction, +%$isconstructor, %$isunion, %$istemplate, +and %$isvariable can be used. Many other checks are possible and this +documentation is not exhaustive, see the "%rename predicates" section in +swig.swg for the full list of supported match expressions. +

    + +

    +In addition to literally matching some string with match you can +also use regexmatch or notregexmatch to match a string +against a regular expression. For example, to ignore all functions having +"Old" as a suffix you could use +

    +
    +
    +%rename("$ignore", regexmatch$name="Old$") "";
    +
    +
    +

    +For simple cases like this, specifying the regular expression for the +declaration name directly can be preferable and can also be done using +regextarget: +

    +
    +
    +%rename("$ignore", regextarget=1) "Old$";
    +
    +
    + +

    +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 fullname attribute: +

    + +
    +
    +%rename("$ignore", regextarget=1, fullname=1) "NameSpace::ClassName::.*Old$";
    +
    +
    + +

    +As for notregexmatch, 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: +

    +
    +
    +%rename("$(lower)s", notregexmatch$name="^[A-Z]+$") "";
    +
    +
    + +

    +Finally, variants of %rename and %ignore directives can be used to help +wrap C++ overloaded functions and methods or C++ methods which use default arguments. This is described in the +Ambiguity resolution and renaming section in the C++ chapter. +

    + + +

    5.4.7.4 Ignoring everything then wrapping a few selected symbols

    + + +

    +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, myheader.h +which has many classes in it and just the one class called Star is wanted within this header, +the following approach could be taken: +

    + +
    +
    +%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"
    +
    +
    + +

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

    + +
    +
    +%rename($ignore, %$isclass) ""; // Only ignore all classes
    +%rename("%s") Star; // Unignore 'Star'
    +%include "myheader.h"
    +
    +
    + +

    5.4.8 Default/optional arguments

    @@ -1896,13 +2261,13 @@ normally, just use the original function name such as add().

    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 ADD, SUB, and MUL:

     /* 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);
     

    -A format string of "%(lower)s" converts all characters to lower-case. +A format string of "%(lowercase)s" converts all characters to lower case. A string of "%(title)s" capitalizes the first character and converts the rest to lower case.

    @@ -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 Typemaps chapter for more about typemaps +and individual target language chapters for more on callbacks and the 'director' feature.

    5.5 Structures and unions

    @@ -2219,13 +2585,13 @@ void Foo_w_set(FOO *f, WORD value) {

    -Compatibility Note: SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes -to pointers. Starting in SWIG-1.3.12, this transformation only occurs if a datatype is known to be a structure, -class, or union. This is unlikely to break existing code. However, if you need to tell SWIG that an undeclared +Compatibility Note: SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes +to pointers. Starting in SWIG-1.3.12, this transformation only occurs if a datatype is known to be a structure, +class, or union. This is unlikely to break existing code. However, if you need to tell SWIG that an undeclared datatype is really a struct, simply use a forward struct declaration such as "struct Foo;".

    -

    5.5.5 C constructors and destructors

    +

    5.5.5 C constructors and destructors

    @@ -2282,7 +2648,7 @@ struct Bar { // Default constructor generated. Since ignoring the implicit or default destructors most of the times produce memory leaks, SWIG will always try to generate them. If needed, however, you can selectively disable the generation of the -default/implicit destructor by using %nodefaultdtor +default/implicit destructor by using %nodefaultdtor

    @@ -2350,7 +2716,7 @@ You can make a Vector 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 Vector look a lot like a class by writing a SWIG interfa

    Note the usage of the $self 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 as if the constructor declaration +had a return value, a Vector * in this case.

    @@ -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->x*v->x+v->y*v->y+v->z*v->z); + return (const double) sqrt(v->x*v->x+v->y*v->y+v->z*v->z); } %} @@ -2486,41 +2856,53 @@ of the object.

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

    -struct Person {
    -   char name[50];
    -   ...
    -}
    +typedef struct {
    +  char name[50];
    +  ...
    +} Person;
     

    -By default, the name 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 name was always upper case, you can rewrite +the interface as follows to ensure this occurs whenever a name is read or written to:

    -struct Person {
    -    %extend {
    -       char *name;
    -    }
    -...
    +typedef struct {
    +  %extend {
    +    char name[50];
    +  }
    +  ...
    +} Person;
    +
    +%{
    +#include <string.h>
    +#include <ctype.h>
    +
    +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->name;
    +  make_upper(p->name);
    +  return p->name;
     }
    +
     void Person_name_set(Person *p, char *val) {
    -   strncpy(p->name,val,50);
    +  strncpy(p->name,val,50);
    +  make_upper(p->name);
     }
     %}
     
    @@ -2530,7 +2912,7 @@ void Person_name_set(Person *p, char *val) { Finally, it should be stressed that even though %extend 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).

    @@ -2613,10 +2995,16 @@ $o->{intRep}->{ivalue} = 7 # Change value of o.intRep.ivalue

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

    + +

    +Finally, note that nesting is handled differently in C++ mode, +see Nested classes. +

    5.5.8 Other things to note about structure wrapping

    @@ -2694,12 +3082,17 @@ output of SWIG is structured first.

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

      +
    • Begin section.
      +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. +
    • +
    • Runtime code.
      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.

      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:

      +%begin %{
      +   ... code in begin section ...
      +%}
      +
       %runtime %{
          ... code in runtime section ...
       %}
      @@ -2751,10 +3149,12 @@ of the following code insertion directives:
       
       

      The bare %{ ... %} directive is a shortcut that is the same as -%header %{ ... %}. +%header %{ ... %}.

      +The %begin 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 %include directive to process an entire C source/header file. -

    • Make sure everything in the interface file uses ANSI C/C++syntax. +
    • Make sure everything in the interface file uses ANSI C/C++ syntax.
    • Make sure all necessary `typedef' 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.
    • If your program has a main() function, you may need to rename it (read on). @@ -2927,16 +3333,21 @@ extern void dump(FILE *f);

      Of course, in this case, our header file is pretty simple so we could -have made an interface file like this as well:

      +use a simpler approach and use an interface file like this:

       /* File : interface.i */
       %module mymodule
      -%include header.h
      +%{
      +#include "header.h"
      +%}
      +%include "header.h"
       

      -Naturally, your mileage may vary.

      +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 %include and #include statements like this is one of the most common approaches to interface file design due to lower maintenance overhead. +

      5.7.3 Why use separate interface files?

      diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index faf0b254c..b4baca6ae 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -42,21 +42,25 @@
    • Wrapping overloaded operators
    • Class extension
    • Templates -
    • Namespaces +
    • Namespaces +
    • Renaming templated types in namespaces
    • Exception specifications
    • Exception handling with %catches
    • Pointers to Members -
    • Smart pointers and operator->() +
    • Smart pointers and operator->() +
    • C++ reference counted objects - ref/unref feature
    • Using declarations and inheritance
    • Nested classes -
    • A brief rant about const-correctness +
    • A brief rant about const-correctness
    • Where to go for more information
    @@ -1125,7 +1129,7 @@ For example if a method has ten default arguments, then eleven wrapper methods a

    Please see the Features and default arguments section for more information on using %feature with functions with default arguments. -The Ambiguity resolution and renaming section +The Ambiguity resolution and renaming section also deals with using %rename and %ignore 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 typecheck typemap. See the Typemaps and overloading section for details or otherwise @@ -1153,8 +1157,9 @@ public:

    -This is great for reducing the size of the wrappers, but the caveat is it does not work for the strongly typed languages -which don't have optional arguments in the language, such as C# and Java. +This is great for reducing the size of the wrappers, but the caveat is it does not work for the statically typed languages, +such as C# and Java, +which don't have optional arguments in the language, Another restriction of this feature is that it cannot handle default arguments that are not public. The following example illustrates this:

    @@ -1615,7 +1620,7 @@ warning message like this:
    -example.i:18: Warning(401): Nothing known about base class 'Foo'. Ignored.
    +example.i:18: Warning 401: Nothing known about base class 'Foo'. Ignored.
     
    @@ -2030,7 +2035,8 @@ Therefore, when SWIG encounters this situation, it may generate a warning messag
    -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).
     
    @@ -2040,7 +2046,8 @@ or for statically typed languages like Java:
    -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.
     
    @@ -2090,7 +2097,7 @@ When wrapping an overloaded function, there is a chance that you will get an err
    -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').
     
    @@ -2121,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.

    -

    6.15.3 Ambiguity resolution and renaming

    +

    6.15.3 Ambiguity resolution and renaming

    @@ -3245,22 +3252,39 @@ public:

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

    -template<class T1, class T2> class Foo<T1, T2 *> { };
    +template<class T1, class T2> class Foo { };                     // (1) primary template
    +template<>                   class Foo<double *, int *> { };    // (2) explicit specialization
    +template<class T1, class T2> class Foo<T1, T2 *> { };           // (3) partial specialization
     

    -SWIG isn't able to match it properly for instantiations like Foo<int *, int *>. -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:

    +
    +
    +Foo<double *, int *>     // explicit specialization matching (2)
    +
    +
    + +

    +SWIG implements template argument deduction so that the following partial specialization examples work just like they would with a C++ compiler: +

    + +
    +
    +Foo<int *, int *>        // partial specialization matching (3)
    +Foo<int *, const int *>  // partial specialization matching (3)
    +Foo<int *, int **>       // partial specialization matching (3)
    +
    +
    +

    Member function templates are supported. The underlying principle is the same as for normal templates--SWIG can't create a wrapper unless you provide @@ -3333,7 +3357,7 @@ public:

    In this case, the %extend directive is not needed, and -%template does the exactly same job, i.e., it adds two new +%template does exactly the same job, i.e., it adds two new methods to the Foo class.

    @@ -3470,7 +3494,7 @@ instead:

    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.

    @@ -3627,12 +3651,16 @@ as the class name. For example: Similar changes apply to typemaps and other customization features.

    -

    6.19 Namespaces

    +

    6.19 Namespaces

    -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 +nspace feature, 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 @@ -3816,7 +3844,7 @@ When this conflict occurs, you will get an error message that resembles this:

    -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'
     
    @@ -4072,6 +4100,87 @@ with any namespace awareness. In the future, language modules may or may not p more advanced namespace support.

    +

    6.19.1 The nspace feature for namespaces

    + + +

    +Some target languages provide support for the nspace feature. +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. +

    + +

    +The feature is demonstrated below for C# using the following example: +

    + +
    +
    +%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 {
    +    ...
    +    };
    +  }
    +}
    +
    +
    + +

    +Without the nspace feature directives above or %rename, you would get the following warning resulting in just one of the Color classes being available for use from the target language: +

    + +
    +
    +example.i:9: Error: 'Color' is multiply defined in the generated target language module.
    +example.i:5: Error: Previous declaration of 'Color'
    +
    +
    + +

    +With the nspace feature the two Color classes are wrapped into the equivalent C# namespaces. +A fully qualified constructor call of each these two types in C# is then: +

    + +
    +
    +MyWorld.Material.Color materialColor = new MyWorld.Material.Color();
    +MyWorld.Wrapping.Color wrappingColor = new MyWorld.Wrapping.Color();
    +
    +
    + +

    +Note that the nspace 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. +

    + +
    +
    +namespace MyWorld {
    +  namespace Material {
    +    int quantity;
    +    void dispatch();
    +  }
    +  namespace Wrapping {
    +    int quantity;
    +    void dispatch();
    +  }
    +}
    +
    +
    + +

    +Compatibility Note: The nspace feature was first introduced in SWIG-2.0.0. +

    +

    6.20 Renaming templated types in namespaces

    @@ -4084,8 +4193,9 @@ In the example below, the generic template type is used to rename to bbb
    -%rename(bbb) Space::ABC::aaa(T t);                       // will match but with lower precedence than ccc
    -%rename(ccc) Space::ABC<Space::XYZ>::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<Space::XYZ>::aaa(Space::XYZ t);// will match but with higher precedence
    +                                                             // than bbb
     
     namespace Space {
       class XYZ {};
    @@ -4106,9 +4216,9 @@ Below shows how %rename can be placed inside a namespace.
     
     namespace Space {
    -  %rename(bbb) ABC::aaa(T t);                       // will match but with lower precedence than ccc
    -  %rename(ccc) ABC<Space::XYZ>::aaa(Space::XYZ t);  // will match but with higher precedence than bbb
    -  %rename(ddd) ABC<Space::XYZ>::aaa(XYZ t);         // will not match
    +  %rename(bbb) ABC::aaa(T t);                     // will match but with lower precedence than ccc
    +  %rename(ccc) ABC<Space::XYZ>::aaa(Space::XYZ t);// will match but with higher precedence than bbb
    +  %rename(ddd) ABC<Space::XYZ>::aaa(XYZ t);       // will not match
     }
     
     namespace Space {
    @@ -4130,11 +4240,11 @@ The following example shows how %rename can be placed within %extend.
     
     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<Space::XYZ> {
    -    %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
       }
     }
     
    @@ -4196,7 +4306,7 @@ is outlined in the "throws" typemap s
     

    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 "Exception handling with %exception" section for details. +Consult the "Exception handling with %exception" section for details. The next section details a way of simulating an exception specification or replacing an existing one.

    @@ -4300,7 +4410,7 @@ when checking types. However, no such support is currently provided for member pointers.

    -

    6.24 Smart pointers and operator->()

    +

    6.24 Smart pointers and operator->()

    @@ -4509,8 +4619,179 @@ p = f.__deref__() # Raw pointer from operator-> Note: Smart pointer support was first added in SWIG-1.3.14.

    +

    6.25 C++ reference counted objects - ref/unref feature

    -

    6.25 Using declarations and inheritance

    + +

    +Another similar idiom in C++ is the use of reference counted objects. Consider for example: + +

    +
    +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->ref(); 
    +  }
    +
    +  ~B() { 
    +    a->unref(); 
    +  }
    +};
    +
    +int main() {
    +  A *a  = new A();       // (count: 0)
    +  a->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->unref();         // 'a' unref and deleted (count: 0)
    +}
    +
    +
    + +

    +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 Reference Counted + Object 'RCObj', which implements the ref/unref idiom. +

    + +

    +To tell SWIG that 'RCObj' and all its derived classes are reference +counted objects, use the "ref" and "unref" features. +These are also available as %refobject and %unrefobject, respectively. +For example: +

    + + +
    +
    +%module example
    +...
    +
    +%feature("ref")   RCObj "$this->ref();"
    +%feature("unref") RCObj "$this->unref();"
    +
    +%include "rcobj.h"
    +%include "A.h"
    +...
    +
    +
    + +

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

    + +

    +On the python side, the use of a reference counted object is no +different to any other regular instance: +

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

    +Note that the user doesn't explicitly need to call 'a->ref()' nor 'a->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: +

    + +
    +
    +%feature("ref")   ""
    +%feature("unref") "delete $this;"
    +
    +
    + +

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

    + +

    +The %newobject feature 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: +

    + +
    +
    +%newobject AFactory;
    +A *AFactory() {
    +  return new A();
    +}
    +
    +
    + +

    +The AFactory function now acts much like a call to the A constructor with respect to memory handling: +

    + +
    +
    +a = AFactory()    # SWIG ref 'a' due to %newobject (count: 1)
    +exit              # 'a' is released, SWIG unref 'a' called in the destructor wrapper (count: 0)
    +
    +
    + + + +

    6.26 Using declarations and inheritance

    @@ -4673,41 +4954,54 @@ public:

    -

    6.26 Nested classes

    +

    6.27 Nested classes

    -There is limited support for nested structs and unions when wrapping C code, see Nested structures 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 Nested structures 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.

    -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 Outer class which contains a nested class Inner. +The easiest thing to do is turn a blind eye to the warning that SWIG generates, or simply suppress it:

    -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& inner);
    +  ...
     };
     

    -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 Outer class which contains a nested class Inner: +Note that if Inner 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 getInner() method above, the returned value can then be passed around, such as passed into the +useInner() method. +

    + +

    +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 Outer class in a header file:

    @@ -4720,14 +5014,18 @@ public: int var; Inner(int v = 0) : var(v) {} }; - void method(Inner inner); + Inner getInner(); + void useInner(const Inner& inner); };

    -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 nestedworkaround +feature flag 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.

    @@ -4735,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 { @@ -4746,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; %} -

    -The downside to this approach is having to maintain two definitions of Inner, 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 Inner, +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.

    -

    6.27 A brief rant about const-correctness

    +

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

    + +
    +
    +// File outer.h
    +class Outer {
    +public:
    +#ifndef SWIG
    +  class Inner {
    +    public:
    +      ...
    +  };
    +#endif
    +  ...
    +};
    +
    +
    + +

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

    + +

    +Compatibility Note: SWIG-1.3.40 and earlier versions did not have the nestedworkaround feature +and the generated code resulting from parsing nested classes did not always compile. +Nested class warnings could also not be suppressed using %warnfilter. +

    + + +

    6.28 A brief rant about const-correctness

    @@ -4822,7 +5156,7 @@ using another tool if maintaining constness is the most important part of your project.

    -

    6.28 Where to go for more information

    +

    6.29 Where to go for more information

    diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index b7b4798e7..1151de1d5 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -1,23 +1,15 @@ -SWIG-1.3 Documentation +SWIG-2.0 Documentation -

    SWIG-1.3 Development Documentation

    +

    SWIG-2.0 Documentation

    -Last update : SWIG-1.3.36 (in progress) +Last update : SWIG-2.0.6 (30 April 2012)

    Sections

    -

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

    -

    SWIG Core Documentation

    Language Module Documentation

    @@ -66,20 +62,5 @@ to help!).
  • Extending SWIG
  • -

    Documentation that has not yet been updated

    - -

    -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 -SWIG Basics 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 Typemaps -chapter above if you are using this feature. -

    - - - diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index e837a5b17..f55a7f139 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -6,7 +6,7 @@ -

    32 SWIG and Tcl

    +

    37 SWIG and Tcl

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

    -

    32.1 Preliminaries

    +

    37.1 Preliminaries

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

    -

    32.1.1 Getting the right header files

    +

    37.1.1 Getting the right header files

    @@ -126,7 +127,7 @@ this is the case, you should probably make a symbolic link so that tcl.h -

    32.1.2 Compiling a dynamic module

    +

    37.1.2 Compiling a dynamic module

    @@ -161,7 +162,7 @@ The name of the module is specified using the %module directive or the -module command line option.

    -

    32.1.3 Static linking

    +

    37.1.3 Static linking

    @@ -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 @@ -227,7 +228,7 @@ minimal in most situations (and quite frankly not worth the extra hassle in the opinion of this author).

    -

    32.1.4 Using your module

    +

    37.1.4 Using your module

    @@ -355,7 +356,7 @@ to the default system configuration (this requires root access and you will need the man pages).

    -

    32.1.5 Compilation of C++ extensions

    +

    37.1.5 Compilation of C++ extensions

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

    -

    32.1.6 Compiling for 64-bit platforms

    +

    37.1.6 Compiling for 64-bit platforms

    @@ -465,7 +466,7 @@ also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

    -

    32.1.7 Setting a package prefix

    +

    37.1.7 Setting a package prefix

    @@ -484,7 +485,7 @@ option will append the prefix to the name when creating a command and call it "Foo_bar".

    -

    32.1.8 Using namespaces

    +

    37.1.8 Using namespaces

    @@ -506,7 +507,7 @@ When the -namespace option is used, objects in the module are always accessed with the namespace name such as Foo::bar.

    -

    32.2 Building Tcl/Tk Extensions under Windows 95/NT

    +

    37.2 Building Tcl/Tk Extensions under Windows 95/NT

    @@ -517,7 +518,7 @@ covers the process of using SWIG with Microsoft Visual C++. although the procedure may be similar with other compilers.

    -

    32.2.1 Running SWIG from Developer Studio

    +

    37.2.1 Running SWIG from Developer Studio

    @@ -575,7 +576,7 @@ MSDOS > tclsh80 % -

    32.2.2 Using NMAKE

    +

    37.2.2 Using NMAKE

    @@ -638,7 +639,7 @@ to get you started. With a little practice, you'll be making lots of Tcl extensions.

    -

    32.3 A tour of basic C/C++ wrapping

    +

    37.3 A tour of basic C/C++ wrapping

    @@ -649,7 +650,7 @@ classes. This section briefly covers the essential aspects of this wrapping.

    -

    32.3.1 Modules

    +

    37.3.1 Modules

    @@ -683,7 +684,7 @@ To fix this, supply an extra argument to load like this: -

    32.3.2 Functions

    +

    37.3.2 Functions

    @@ -708,7 +709,7 @@ like you think it does: % -

    32.3.3 Global variables

    +

    37.3.3 Global variables

    @@ -788,7 +789,7 @@ extern char *path; // Read-only (due to %immutable) -

    32.3.4 Constants and enums

    +

    37.3.4 Constants and enums

    @@ -872,7 +873,7 @@ When an identifier name is given, it is used to perform an implicit hash-table l conversion. This allows the global statement to be omitted.

    -

    32.3.5 Pointers

    +

    37.3.5 Pointers

    @@ -968,7 +969,7 @@ C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

    -

    32.3.6 Structures

    +

    37.3.6 Structures

    @@ -1250,7 +1251,7 @@ Note: Tcl only destroys the underlying object if it has ownership. See the memory management section that appears shortly.

    -

    32.3.7 C++ classes

    +

    37.3.7 C++ classes

    @@ -1317,7 +1318,7 @@ In Tcl, the static member is accessed as follows: -

    32.3.8 C++ inheritance

    +

    37.3.8 C++ inheritance

    @@ -1366,7 +1367,7 @@ For instance: It is safe to use multiple inheritance with SWIG.

    -

    32.3.9 Pointers, references, values, and arrays

    +

    37.3.9 Pointers, references, values, and arrays

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

    -

    32.3.10 C++ overloaded functions

    +

    37.3.10 C++ overloaded functions

    @@ -1501,8 +1502,8 @@ If declarations such as these appear, you will get a warning message like this:

    -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).
     
    @@ -1543,7 +1544,7 @@ first declaration takes precedence. Please refer to the "SWIG and C++" chapter for more information about overloading.

    -

    32.3.11 C++ operators

    +

    37.3.11 C++ operators

    @@ -1645,7 +1646,7 @@ There are ways to make this operator appear as part of the class using the % Keep reading.

    -

    32.3.12 C++ namespaces

    +

    37.3.12 C++ namespaces

    @@ -1709,7 +1710,7 @@ utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

    -

    32.3.13 C++ templates

    +

    37.3.13 C++ templates

    @@ -1761,7 +1762,7 @@ More details can be found in the SWIG and C++ -

    32.3.14 C++ Smart Pointers

    +

    37.3.14 C++ Smart Pointers

    @@ -1845,7 +1846,7 @@ simply use the __deref__() method. For example: -

    32.4 Further details on the Tcl class interface

    +

    37.4 Further details on the Tcl class interface

    @@ -1858,7 +1859,7 @@ of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

    -

    32.4.1 Proxy classes

    +

    37.4.1 Proxy classes

    @@ -1923,7 +1924,7 @@ function. This allows objects to be encapsulated objects that look a lot like as shown in the last section.

    -

    32.4.2 Memory management

    +

    37.4.2 Memory management

    @@ -2111,7 +2112,7 @@ typemaps--an advanced topic discussed later.

    -

    32.5 Input and output parameters

    +

    37.5 Input and output parameters

    @@ -2299,7 +2300,7 @@ set c [lindex $dim 1] -

    32.6 Exception handling

    +

    37.6 Exception handling

    @@ -2433,7 +2434,7 @@ Since SWIG's exception handling is user-definable, you are not limited to C++ ex See the chapter on "Customization Features" for more examples.

    -

    32.7 Typemaps

    +

    37.7 Typemaps

    @@ -2450,7 +2451,7 @@ Typemaps are only used if you want to change some aspect of the primitive C-Tcl interface.

    -

    32.7.1 What is a typemap?

    +

    37.7.1 What is a typemap?

    @@ -2567,7 +2568,7 @@ parameter is omitted): -

    32.7.2 Tcl typemaps

    +

    37.7.2 Tcl typemaps

    @@ -2705,7 +2706,7 @@ Initialize an argument to a value before any conversions occur. Examples of these methods will appear shortly.

    -

    32.7.3 Typemap variables

    +

    37.7.3 Typemap variables

    @@ -2776,7 +2777,7 @@ properly assigned. The Tcl name of the wrapper function being created. -

    32.7.4 Converting a Tcl list to a char **

    +

    37.7.4 Converting a Tcl list to a char **

    @@ -2822,7 +2823,7 @@ int print_args(char **argv) { return i; } %} -%include tclsh.i +%include "tclsh.i" @@ -2838,7 +2839,7 @@ argv[2] = Larry 3 -

    32.7.5 Returning values in arguments

    +

    37.7.5 Returning values in arguments

    @@ -2880,7 +2881,7 @@ result, a Tcl function using these typemaps will work like this : % -

    32.7.6 Useful functions

    +

    37.7.6 Useful functions

    @@ -2957,7 +2958,7 @@ int Tcl_IsShared(Tcl_Obj *obj); -

    32.7.7 Standard typemaps

    +

    37.7.7 Standard typemaps

    @@ -3041,7 +3042,7 @@ work) -

    32.7.8 Pointer handling

    +

    37.7.8 Pointer handling

    @@ -3117,7 +3118,7 @@ For example: -

    32.8 Turning a SWIG module into a Tcl Package.

    +

    37.8 Turning a SWIG module into a Tcl Package.

    @@ -3189,7 +3190,7 @@ As a final note, most SWIG examples do not yet use the to use the load command instead.

    -

    32.9 Building new kinds of Tcl interfaces (in Tcl)

    +

    37.9 Building new kinds of Tcl interfaces (in Tcl)

    @@ -3288,7 +3289,7 @@ danger of blowing something up (although it is easily accomplished with an out of bounds array access).

    -

    32.9.1 Proxy classes

    +

    37.9.1 Proxy classes

    @@ -3409,5 +3410,27 @@ short, but clever Tcl script can be combined with SWIG to do many interesting things.

    +

    37.10 Tcl/Tk Stubs

    + + +

    +For background information about the Tcl Stubs feature, see +http://www.tcl.tk/doc/howto/stubs.html. +

    + +

    +As of SWIG 1.3.10, the generated C/C++ wrapper will use the Tcl Stubs +feature if compiled with -DUSE_TCL_STUBS. +

    + +

    +As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs +feature if compiled with -DUSE_TK_STUBS. Also, you can override +the minimum version to support which is passed to Tcl_InitStubs() +and Tk_InitStubs() with -DSWIG_TCL_STUBS_VERSION="8.3" +or the version being compiled with using +-DSWIG_TCL_STUBS_VERSION=TCL_VERSION. +

    + diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index e07f9f87e..b3b0bc7a9 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -18,29 +18,36 @@
  • Reusing typemaps
  • What can be done with typemaps?
  • What can't be done with typemaps? +
  • Similarities to Aspect Oriented Programming
  • The rest of this chapter
  • Typemap specifications -
  • Pattern matching rules +
  • Pattern matching rules
  • Code generation rules
  • Common typemap methods -
  • Typemaps for multiple languages +
  • Typemaps for multiple target languages
  • Optimal code generation when returning by value -
  • Multi-argument typemaps -
  • The run-time type checker +
  • Multi-argument typemaps +
  • Typemap warnings +
  • Typemap fragments + +
  • The run-time type checker
  • Typemaps and overloading
  • More about %apply and %clear -
  • Reducing wrapper code size
  • Passing data between typemaps +
  • C++ "this" pointer
  • Where to go for more information? @@ -82,10 +95,6 @@ -

    -Disclaimer: This chapter is under construction! -

    -

    10.1 Introduction

    @@ -108,7 +117,7 @@ chapter with only a vague idea of what SWIG already does by default.

    One of the most important problems in wrapper code generation is the -conversion of datatypes between programming languages. Specifically, +conversion or marshalling of datatypes between programming languages. Specifically, for every C/C++ declaration, SWIG must somehow generate wrapper code that allows values to be passed back and forth between languages. Since every programming language represents data differently, this is @@ -224,14 +233,17 @@ At first glance, this code will look a little confusing. However, there is really not much to it. The first typemap (the "in" typemap) is used to convert a value from the target language to C. The second typemap (the "out" typemap) is used to convert in the other -direction. The content of each typemap is a small fragment of C code -that is inserted directly into the SWIG generated wrapper functions. Within -this code, a number of special variables prefixed with a $ are expanded. These are -really just placeholders for C variables that are generated in the course +direction. The content of each typemap is a small fragment of code +that is inserted directly into the SWIG generated wrapper functions. +The code is usually C or C++ code which will be generated into the C/C++ wrapper functions. +Note that this isn't always the case as some target language modules allow target language +code within the typemaps which gets generated into target language specific files. +Within this code, a number of special variables prefixed with a $ are expanded. These are +really just placeholders for C/C++ variables that are generated in the course of creating the wrapper function. In this case, $input refers to an -input object that needs to be converted to C and $result +input object that needs to be converted to C/C++ and $result refers to an object that is going to be returned by a wrapper -function. $1 refers to a C variable that has the same type as +function. $1 refers to a C/C++ variable that has the same type as specified in the typemap declaration (an int in this example).

    @@ -574,14 +586,14 @@ suppose you had a declaration like this,
    -Foo *make_Foo();
    +Foo *make_Foo(int n);
     

    -and you wanted to tell SWIG that make_Foo() returned a newly +and you wanted to tell SWIG that make_Foo(int n) returned a newly allocated object (for the purposes of providing better memory -management). Clearly, this property of make_Foo() is +management). Clearly, this property of make_Foo(int n) is not a property that would be associated with the datatype Foo * by itself. Therefore, a completely different SWIG customization mechanism (%feature) is used for this purpose. Consult the -

    10.1.7 The rest of this chapter

    +

    10.1.7 Similarities to Aspect Oriented Programming

    + + +

    +SWIG has parallels to Aspect Oriented Software Development (AOP). +The AOP terminology with respect to SWIG typemaps can be viewed as follows: +

    +
      +
    • Cross-cutting concerns: The cross-cutting concerns are the modularization of the functionality that the typemaps implement, which is primarily marshalling of types from/to the target language and C/C++. +
    • Advice: The typemap body contains code which is executed whenever the marshalling is required. +
    • Pointcut: The pointcuts are the positions in the wrapper code that the typemap code is generated into. +
    • Aspect: Aspects are the combination of the pointcut and the advice, hence each typemap is an aspect. +
    +

    +SWIG can also be viewed as has having a second set of aspects based around %feature. +Features such as %exception are also cross-cutting concerns as they encapsulate code that can be used to add logging or exception handling to any function. +

    + +

    10.1.8 The rest of this chapter

    @@ -654,7 +684,7 @@ of "The C Programming Language" by Kernighan and Ritchie or This section describes the behavior of the %typemap directive itself.

    -

    10.2.1 Defining a typemap

    +

    10.2.1 Defining a typemap

    @@ -675,8 +705,9 @@ these methods is described later.

    -modifiers is an optional comma separated list of name="value" values. These -are sometimes to attach extra information to a typemap and is often target-language dependent. +modifiers is an optional comma separated list of name="value" values. +These are sometimes to attach extra information to a typemap and is often target-language dependent. +They are also known as typemap attributes.

    @@ -702,7 +733,7 @@ variables (parms). The purpose of these variables will be explained shortly.

    code specifies the code used in the typemap. -Usually this is C/C++ code, but in the strongly typed target languages, such as Java and C#, this can contain target language code for certain typemaps. +Usually this is C/C++ code, but in the statically typed target languages, such as Java and C#, this can contain target language code for certain typemaps. It can take any one of the following forms:

    @@ -984,14 +1015,15 @@ types (std::string and Foo::string).

    It should be noted that for scoping to work, SWIG has to know that string is a typename defined -within a particular namespace. In this example, this is done using the class declaration class string. +within a particular namespace. In this example, this is done using the forward class declaration class string.

    -

    10.3 Pattern matching rules

    +

    10.3 Pattern matching rules

    -The section describes the pattern matching rules by which C datatypes are associated with typemaps. +The section describes the pattern matching rules by which C/C++ datatypes are associated with typemaps. +The matching rules can be observed in practice by using the debugging options also described.

    10.3.1 Basic matching rules

    @@ -1006,18 +1038,21 @@ is used.
    • Typemaps that exactly match TYPE and NAME.
    • Typemaps that exactly match TYPE only. +
    • If TYPE is a C++ template of type T< TPARMS >, where TPARMS are the template parameters, + the type is stripped of the template parameters and the following checks are then made: +
        +
      • Typemaps that exactly match T and NAME. +
      • Typemaps that exactly match T only. +

    -If TYPE includes qualifiers (const, volatile, etc.), they are stripped and the following -checks are made: +If TYPE includes qualifiers (const, volatile, etc.), each qualifier is stripped one at a time to form a new stripped type +and the matching rules above are repeated on the stripped type. +The left-most qualifier is stripped first, resulting in the right-most (or top-level) qualifier being stripped last. +For example int const*const is first stripped to int *const then int *.

    -
      -
    • Typemaps that match the stripped TYPE and NAME. -
    • Typemaps that match the stripped TYPE only. -
    -

    If TYPE is an array. The following transformation is made:

    @@ -1044,8 +1079,8 @@ To find a typemap for the argument const char *s, SWIG will search for
     const char *s           Exact type and name match
     const char *            Exact type match
    -char *s                 Type and name match (stripped qualifiers)
    -char *                  Type match (stripped qualifiers)
    +char *s                 Type and name match (qualifier stripped)
    +char *                  Type match (qualifier stripped)
     
    @@ -1076,16 +1111,21 @@ shows how some of the basic rules are applied: ... typemap 5 } -void A(int *x); // int *x rule (typemap 1) -void B(int *y); // int * rule (typemap 2) -void C(const int *x); // int *x rule (typemap 1) -void D(const int *z); // int * rule (typemap 3) -void E(int x[4]); // int [4] rule (typemap 4) -void F(int x[1000]); // int [ANY] rule (typemap 5) +void A(int *x); // int *x rule (typemap 1) +void B(int *y); // int * rule (typemap 2) +void C(const int *x); // int *x rule (typemap 1) +void D(const int *z); // const int *z rule (typemap 3) +void E(int x[4]); // int [4] rule (typemap 4) +void F(int x[1000]); // int [ANY] rule (typemap 5) -

    10.3.2 Typedef reductions

    +

    +Compatibility note: SWIG-2.0.0 introduced stripping the qualifiers one step at a time. Prior versions +stripped all qualifiers in one step. +

    + +

    10.3.2 Typedef reductions matching

    @@ -1240,58 +1280,97 @@ is rather esoteric--there's little practical reason to write a typemap quite lik to confuse your coworkers even more.

    -

    10.3.3 Default typemaps

    - -

    -Most SWIG language modules use typemaps to define the default behavior of the C primitive types. This -is entirely straightforward. For example, a set of typemaps are written like this: +As a point of clarification, it is worth emphasizing that typedef matching is a typedef reduction process only, that is, SWIG does not search for every single possible typedef. +Given a type in a declaration, it will only reduce the type, it won't build it up looking for typedefs. +For example, given the type Struct, the typemap below will not be used for the aStruct parameter, +because Struct is fully reduced:

    -%typemap(in) int   "convert an int";
    -%typemap(in) short "convert a short";
    -%typemap(in) float "convert a float";
    +struct Struct {...};
    +typedef Struct StructTypedef;
    +
    +%typemap(in) StructTypedef { 
    +  ...
    +}
    +
    +void go(Struct aStruct);
    +
    +
    + +

    10.3.3 Default typemap matching rules

    + + +

    +If the basic pattern matching rules result in no match being made, even after typedef reductions, +the default typemap matching rules are used to look for a suitable typemap match. +These rules match a generic typemap based on the reserved SWIGTYPE base type. +For example pointers will use SWIGTYPE * and references will use SWIGTYPE &. +More precisely, the rules are based on the C++ class template partial specialization matching rules used +by C++ compilers when looking for an appropriate partial template specialization. +This means that a match is chosen from the most specialized set of generic typemap types available. For example, +when looking for a match to int const *, the rules will prefer to match SWIGTYPE const * +if available before matching SWIGTYPE *, before matching SWIGTYPE. +

    + +

    +Most SWIG language modules use typemaps to define the default behavior of the C primitive types. This +is entirely straightforward. For example, a set of typemaps for primitives marshalled by value or +const reference are written like this: +

    + +
    +
    +%typemap(in) int           "... convert to int ...";
    +%typemap(in) short         "... convert to short ...";
    +%typemap(in) float         "... convert to float ...";
    +...
    +%typemap(in) const int &   "... convert ...";
    +%typemap(in) const short & "... convert ...";
    +%typemap(in) const float & "... convert ...";
     ...
     

    Since typemap matching follows all typedef declarations, any sort of type that is -mapped to a primitive type through typedef will be picked up by one of these primitive typemaps. +mapped to a primitive type by value or const reference through typedef will be picked +up by one of these primitive typemaps. +Most language modules also define typemaps for char pointers and char arrays to handle strings, +so these non-default types will also be used in preference as the basic typemap matching rules +provide a better match than the default typemap matching rules.

    -The default behavior for pointers, arrays, references, and other kinds of types are handled by -specifying rules for variations of the reserved SWIGTYPE type. For example: +Below is a list of the typical default types supplied by language modules, showing what the "in" typemap would look like:

    -%typemap(in) SWIGTYPE *            { ... default pointer handling ...         }
    -%typemap(in) SWIGTYPE &            { ... default reference handling ...       }
    -%typemap(in) SWIGTYPE []           { ... default array handling ...           }
    -%typemap(in) enum SWIGTYPE         { ... default handling for enum values ... }
    -%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...  } 
    +%typemap(in) SWIGTYPE &            { ... default reference handling ...                       };
    +%typemap(in) SWIGTYPE *            { ... default pointer handling ...                         };
    +%typemap(in) SWIGTYPE *const       { ... default pointer const handling ...                   };
    +%typemap(in) SWIGTYPE *const&      { ... default pointer const reference handling ...         };
    +%typemap(in) SWIGTYPE[ANY]         { ... 1D fixed size arrays handlling ...                   };
    +%typemap(in) SWIGTYPE []           { ... unknown sized array handling ...                     };
    +%typemap(in) enum SWIGTYPE         { ... default handling for enum values ...                 };
    +%typemap(in) const enum SWIGTYPE & { ... default handling for const enum reference values ... };
    +%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...                  };
    +%typemap(in) SWIGTYPE              { ... simple default handling ...                          };
     

    -These rules match any kind of pointer, reference, or array--even when -multiple levels of indirection or multiple array dimensions are used. -Therefore, if you wanted to change SWIG's default handling for all -types of pointers, you would simply redefine the rule for SWIGTYPE -*. -

    - -

    -Finally, the following typemap rule is used to match against simple types that don't match any other rules: +If you wanted to change SWIG's default handling for +simple pointers, you would simply redefine the rule for SWIGTYPE *. +Note, the simple default typemap rule is used to match against simple types that don't match any other rules:

    -%typemap(in) SWIGTYPE   { ... handle an unknown type ... }
    +%typemap(in) SWIGTYPE              { ... simple default handling ...                          } 
     
    @@ -1310,7 +1389,7 @@ double dot_product(Vector a, Vector b);

    The Vector type will usually just get matched against SWIGTYPE. The default implementation of SWIGTYPE is -to convert the value into pointers (as described in chapter 3). +to convert the value into pointers (as described in this earlier section).

    @@ -1322,34 +1401,7 @@ objects into strings instead of converting them to pointers.

    -The best way to explore the default typemaps is to look at the ones -already defined for a particular language module. Typemaps -definitions are usually found in the SWIG library in a file such as -python.swg, tcl8.swg, etc. -

    - -

    10.3.4 Mixed default typemaps

    - - -

    -The default typemaps described above can be mixed with const and with each other. -For example the SWIGTYPE * typemap is for default pointer handling, but if a const SWIGTYPE * typemap -is defined it will be used instead for constant pointers. Some further examples follow: -

    - -
    -
    -%typemap(in) enum SWIGTYPE &        { ... enum references ...                       }
    -%typemap(in) const enum SWIGTYPE &  { ... const enum references ...                 }
    -%typemap(in) SWIGTYPE *&            { ... pointers passed by reference ...          }
    -%typemap(in) SWIGTYPE * const &     { ... constant pointers passed by reference ... }
    -%typemap(in) SWIGTYPE[ANY][ANY]     { ... 2D arrays ...                             }
    -
    -
    - -

    -Note that the the typedef reduction described earlier is also used with these mixed default typemaps. -For example, say the following typemaps are defined and SWIG is looking for the best match for the enum shown below: +Let's consider an example where the following typemaps are defined and SWIG is looking for the best match for the enum shown below:

    @@ -1368,16 +1420,25 @@ const Hello &hi;

    The typemap at the top of the list will be chosen, not because it is defined first, but because it is the closest match for the type being wrapped. If any of the typemaps in the above list were not defined, then the next one on the list would have precedence. -In other words the typemap chosen is the closest explicit match.

    -Compatibility note: The mixed default typemaps were introduced in SWIG-1.3.23, but were not used much in this version. -Expect to see them being used more and more within the various libraries in later versions of SWIG. +The best way to explore the default typemaps is to look at the ones +already defined for a particular language module. Typemap +definitions are usually found in the SWIG library in a file such as +java.swg, csharp.swg etc. +However, for many of the target languages the typemaps are hidden behind complicated macros, +so the best way to view the default typemaps, or any typemaps for that matter, +is to look at the preprocessed output by running swig -E on any interface file. +Finally the best way to view the typemap matching rules in action is via the debugging typemap pattern matching options covered later on.

    +

    +Compatibility note: The default typemap matching rules were modified in SWIG-2.0.0 from a slightly +simpler scheme to match the current C++ class template partial specialization matching rules. +

    -

    10.3.5 Multi-arguments typemaps

    +

    10.3.4 Multi-arguments typemaps

    @@ -1407,6 +1468,378 @@ but all subsequent arguments must match exactly.

    +

    10.3.5 Matching rules compared to C++ templates

    + + +

    +For those intimately familiar with C++ templates, a comparison of the typemap matching rules and template type deduction is interesting. +The two areas considered are firstly the default typemaps and their similarities to partial template specialization and secondly, non-default typemaps and their similarities to full template specialization. +

    + +

    +For default (SWIGTYPE) typemaps the rules are inspired by C++ class template +partial specialization. For example, given partial specialization for T const& : +

    + +
    +
    +template <typename T> struct X             { void a(); };
    +template <typename T> struct X< T const& > { void b(); };
    +
    +
    + +

    +The full (unspecialized) template is matched with most types, such as: +

    + +
    +
    +X< int & >            x1;  x1.a();
    +
    +
    + +

    +and the following all match the T const& partial specialization: +

    + +
    +
    +X< int *const& >      x2;  x2.b();
    +X< int const*const& > x3;  x3.b();
    +X< int const& >       x4;  x4.b();
    +
    +
    + +

    +Now, given just these two default typemaps, where T is analogous to SWIGTYPE: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) SWIGTYPE const& { ... }
    +
    +
    + +

    +The generic default typemap SWIGTYPE is used with most types, such as +

    + +
    +
    +int &
    +
    +
    + +

    +and the following all match the SWIGTYPE const& typemap, just like the partial template matching: +

    + +
    +
    +int *const&
    +int const*const&
    +int const&
    +
    +
    + +

    +Note that the template and typemap matching rules are not identical for all default typemaps though, for example, with arrays. +

    + +

    +For non-default typemaps, one might expect SWIG to follow the fully specialized template rules. +This is nearly the case, but not quite. +Consider a very similar example to the earlier partially specialized template but this time there is a fully specialized template: +

    + +
    +
    +template <typename T> struct Y       { void a(); };
    +template <> struct Y< int const & >  { void b(); };
    +
    +
    + +

    +Only the one type matches the specialized template exactly: +

    + +
    +
    +Y< int & >             y1;  y1.a();
    +Y< int *const& >       y2;  y2.a();
    +Y< int const *const& > y3;  y3.a();
    +Y< int const& >        y4;  y4.b(); // fully specialized match
    +
    +
    + +

    +Given typemaps with the same types used for the template declared above, where T is again analogous to SWIGTYPE: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) int const&      { ... }
    +
    +
    + +

    +The comparison between non-default typemaps and fully specialized single parameter templates turns out to be the same, as just the one type will match the non-default typemap: +

    + +
    +
    +int &
    +int *const&
    +int const*const&
    +int const&        // matches non-default typemap int const&
    +
    +
    + +

    +However, if a non-const type is used instead: +

    + +
    +
    +%typemap(...) SWIGTYPE        { ... }
    +%typemap(...) int &           { ... }
    +
    +
    + +

    +then there is a clear difference to template matching as both the const and non-const types match the typemap: +

    + +
    +
    +int &             // matches non-default typemap int &
    +int *const&
    +int const*const&
    +int const&        // matches non-default typemap int &
    +
    +
    + +

    +There are other subtle differences such as typedef handling, but at least it should be clear that the typemap matching rules +are similar to those for specialized template handling. +

    + + +

    10.3.6 Debugging typemap pattern matching

    + + +

    +There are two useful debug command line options available for debugging typemaps, -debug-tmsearch and -debug-tmused. +

    + +

    +The -debug-tmsearch option is a verbose option for debugging typemap searches. +This can be very useful for watching the pattern matching process in action and for debugging which typemaps are used. +The option displays all the typemaps and types that are looked for until a successful pattern match is made. +As the display includes searches for each and every type needed for wrapping, the amount of information displayed can be large. +Normally you would manually search through the displayed information for the particular type that you are interested in. +

    + +

    +For example, consider some of the code used in the Typedef reductions section already covered: +

    + +
    +
    +typedef int Integer;
    +typedef Integer Row4[4];
    +void foo(Row4 rows[10]);
    +
    +
    + +

    +A sample of the debugging output is shown below for the "in" typemap: +

    + +
    +
    +swig -perl -debug-tmsearch example.i
    +...
    +example.h:3: Searching for a suitable 'in' typemap for: Row4 rows[10]
    +  Looking for: Row4 rows[10]
    +  Looking for: Row4 [10]
    +  Looking for: Row4 rows[ANY]
    +  Looking for: Row4 [ANY]
    +  Looking for: Integer rows[10][4]
    +  Looking for: Integer [10][4]
    +  Looking for: Integer rows[ANY][ANY]
    +  Looking for: Integer [ANY][ANY]
    +  Looking for: int rows[10][4]
    +  Looking for: int [10][4]
    +  Looking for: int rows[ANY][ANY]
    +  Looking for: int [ANY][ANY]
    +  Looking for: SWIGTYPE rows[ANY][ANY]
    +  Looking for: SWIGTYPE [ANY][ANY]
    +  Looking for: SWIGTYPE rows[ANY][]
    +  Looking for: SWIGTYPE [ANY][]
    +  Looking for: SWIGTYPE *rows[ANY]
    +  Looking for: SWIGTYPE *[ANY]
    +  Looking for: SWIGTYPE rows[ANY]
    +  Looking for: SWIGTYPE [ANY]
    +  Looking for: SWIGTYPE rows[]
    +  Looking for: SWIGTYPE []
    +  Using: %typemap(in) SWIGTYPE []
    +...
    +
    +
    + +

    +showing that the best default match supplied by SWIG is the SWIGTYPE [] typemap. +As the example shows, the successful match displays the used typemap source including typemap method, type and optional name in one of these simplified formats: +

    + +
      +
    • Using: %typemap(method) type name +
    • Using: %typemap(method) type name = type2 name2 +
    • Using: %apply type2 name2 { type name } +
    + +

    +This information might meet your debugging needs, however, you might want to analyze further. +If you next invoke SWIG with the -E option to display the preprocessed output, and search for the particular typemap used, +you'll find the full typemap contents (example shown below for Python): +

    + +
    +
    +%typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
    +  res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown |  0 );
    +  if (!SWIG_IsOK(res)) { 
    +    SWIG_exception_fail(SWIG_ArgError(res), "in method '" "$symname" "', argument "
    +                       "$argnum"" of type '" "$type""'"); 
    +  } 
    +  $1 = ($ltype)(argp);
    +}
    +
    +
    + +

    +The generated code for the foo wrapper will then contain the snippets of the typemap with the special variables expanded. +The rest of this chapter will need reading though to fully understand all of this, however, the relevant parts of the generated code for the above typemap can be seen below: +

    + +
    +
    +SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
    +...
    +  void *argp1 = 0 ;
    +  int res1 = 0 ;
    +...
    +  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_a_4__int, 0 |  0 );
    +  if (!SWIG_IsOK(res1)) {
    +    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "foo" "', argument "
    +                       "1"" of type '" "int [10][4]""'"); 
    +  } 
    +  arg1 = (int (*)[4])(argp1);
    +...
    +}
    +
    +
    + +

    +Searches for multi-argument typemaps are not mentioned unless a matching multi-argument typemap does actually exist. +For example, the output for the code in the earlier multi-arguments section is as follows: +

    + +
    +
    +...
    +example.h:39: Searching for a suitable 'in' typemap for: char *buffer
    +  Looking for: char *buffer
    +  Multi-argument typemap found...
    +  Using: %typemap(in) (char *buffer,int len)
    +...
    +
    +
    + +

    +The second option for debugging is -debug-tmused and this displays the typemaps used. +This option is a less verbose version of the -debug-tmsearch option as it only displays each successfully found typemap on a separate single line. +The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used in the same simplified format output by the -debug-tmsearch option. +Below is the output for the example code at the start of this section on debugging. +

    + +
    +
    +$ swig -perl -debug-tmused example.i
    +example.h:3: Typemap for Row4 rows[10] (in) : %typemap(in) SWIGTYPE []
    +example.h:3: Typemap for Row4 rows[10] (typecheck) : %typemap(typecheck) SWIGTYPE *
    +example.h:3: Typemap for Row4 rows[10] (freearg) : %typemap(freearg) SWIGTYPE []
    +example.h:3: Typemap for void foo (out) : %typemap(out) void
    +
    +
    + +

    +Now, consider the following interface file: +

    + +
    +
    +%module example
    +
    +%{
    +void set_value(const char* val) {}
    +%}
    +
    +%typemap(check) char *NON_NULL {
    +  if (!$1) {
    +    /* ... error handling ... */
    +  }
    +}
    +
    +// use default pointer handling instead of strings
    +%apply SWIGTYPE * { const char* val, const char* another_value }
    +
    +%typemap(check) const char* val = char* NON_NULL;
    +
    +%typemap(arginit, noblock=1) const char* val {
    +   $1 = "";
    +}
    +
    +void set_value(const char* val);
    +
    +
    +
    + +

    +and the output debug: +

    + +
    +
    +swig -perl5 -debug-tmused example.i
    +example.i:21: Typemap for char const *val (arginit) : %typemap(arginit) char const *val
    +example.i:21: Typemap for char const *val (in) : %apply SWIGTYPE * { char const *val }
    +example.i:21: Typemap for char const *val (typecheck) : %apply SWIGTYPE * { char const *val }
    +example.i:21: Typemap for char const *val (check) : %typemap(check) char const *val = char *NON_NULL
    +example.i:21: Typemap for char const *val (freearg) : %apply SWIGTYPE * { char const *val }
    +example.i:21: Typemap for void set_value (out) : %typemap(out) void
    +
    +
    + +

    +The following observations about what is displayed can be noted (the same applies for -debug-tmsearch): +

    +
      +
    • +The relevant typemap is shown, but for typemap copying, the appropriate %typemap or %apply is displayed, for example, the "check" and "in" typemaps. +
    • +
    • +The typemap modifiers are not shown, eg the noblock=1 modifier in the "arginit" typemap. +
    • +
    • +The exact %apply statement might look different to what is in the actual code. For example, the const char* another_value is not shown as it is not relevant here. +Also the types may be displayed slightly differently - char const * and not const char*. +
    • +
    +

    10.4 Code generation rules

    @@ -1481,12 +1914,16 @@ Occasionally, typemap code will be specified using a few alternative forms. For %typemap(in) int %{ $1 = PyInt_AsLong($input); %} +%typemap(in, noblock=1) int { +$1 = PyInt_AsLong($input); +}

    -These two forms are mainly used for cosmetics--the specified code is not enclosed inside +These three forms are mainly used for cosmetics--the specified code is not enclosed inside a block scope when it is emitted. This sometimes results in a less complicated looking wrapper function. +Note that only the third of the three typemaps have the typemap code passed through the SWIG preprocessor.

    10.4.2 Declaring new local variables

    @@ -1615,7 +2052,7 @@ wrap_foo() {

    Some typemaps do not recognize local variables (or they may simply not -apply). At this time, only typemaps that apply to argument conversion support this. +apply). At this time, only typemaps that apply to argument conversion support this (input typemaps such as the "in" typemap).

    @@ -1645,6 +2082,7 @@ each type must have its own local variable declaration.

    Within all typemaps, the following special variables are expanded. +This is by no means a complete list as some target languages have additional special variables which are documented in the language specific chapters.

    @@ -1891,6 +2329,86 @@ Another approach, which only works for arrays is to use the $1_basetype +

    10.4.4 Special variable macros

    + + +

    +Special variable macros are like macro functions in that they take one or more input arguments +which are used for the macro expansion. +They look like macro/function calls but use the special variable $ prefix to the macro name. +Note that unlike normal macros, the expansion is not done by the preprocessor, +it is done during the SWIG parsing/compilation stages. +The following special variable macros are available across all language modules. +

    + +

    10.4.4.1 $descriptor(type)

    + + +

    +This macro expands into the type descriptor structure for any C/C++ type specified in type. +It behaves like the $1_descriptor special variable described above except that the type to expand is +taken from the macro argument rather than inferred from the typemap type. +For example, $descriptor(std::vector<int> *) will expand into SWIGTYPE_p_std__vectorT_int_t. +This macro is mostly used in the scripting target languages and is demonstrated later in the Run-time type checker usage section. +

    + +

    10.4.4.2 $typemap(method, typepattern)

    + + +

    +This macro uses the pattern matching rules described earlier to lookup and +then substitute the special variable macro with the code in the matched typemap. +The typemap to search for is specified by the arguments, where method is the typemap method name and +typepattern is a type pattern as per the %typemap specification in the Defining a typemap section. +

    + +

    +The special variables within the matched typemap are expanded into those for the matched typemap type, +not the typemap within which the macro is called. +In practice, there is little use for this macro in the scripting target languages. +It is mostly used in the target languages that are statically typed as a way to obtain the target language type given the C/C++ type and more commonly only when the C++ type is a template parameter. +

    + +

    +The example below is for C# only and uses some typemap method names documented in the C# chapter, but it shows some of the possible syntax variations. +

    + +
    +
    +%typemap(cstype) unsigned long    "uint"
    +%typemap(cstype) unsigned long bb "bool"
    +%typemap(cscode) BarClass %{
    +  void foo($typemap(cstype, unsigned long aa) var1,
    +           $typemap(cstype, unsigned long bb) var2,
    +           $typemap(cstype, (unsigned long bb)) var3,
    +           $typemap(cstype, unsigned long) var4)
    +  {
    +    // do something
    +  }
    +%}
    +
    +
    + +

    +The result is the following expansion +

    + +
    +
    +%typemap(cstype) unsigned long    "uint"
    +%typemap(cstype) unsigned long bb "bool"
    +%typemap(cscode) BarClass %{
    +  void foo(uint var1,
    +           bool var2,
    +           bool var3,
    +           uint var4)
    +  {
    +    // do something
    +  }
    +%}
    +
    +
    +

    10.5 Common typemap methods

    @@ -1933,7 +2451,7 @@ to implement customized conversions.

    In addition, the "in" typemap allows the number of converted arguments to be -specified. For example: +specified. The numinputs attributes facilitates this. For example:

    @@ -1946,7 +2464,12 @@ specified. For example:

    -At this time, only zero or one arguments may be converted. +At this time, only zero or one arguments may be converted. +When numinputs is set to 0, the argument is effectively ignored and cannot be supplied from the target language. +The argument is still required when making the C/C++ call and the above typemap +shows the value used is instead obtained from a locally declared variable called temp. +Usually numinputs is not specified, whereupon the default value is 1, that is, there is a one to one mapping of the number of arguments when used from the target language to the C/C++ call. +Multi-argument typemaps provide a similar concept where the number of arguments mapped from the target language to C/C++ can be changed for multiple adjacent C/C++ arguments.

    @@ -1977,7 +2500,7 @@ the input argument is the correct type.

    If you define new "in" typemaps and your program uses overloaded methods, you should also define a collection of -"typecheck" typemaps. More details about this follow in a later section on "Typemaps and Overloading." +"typecheck" typemaps. More details about this follow in the Typemaps and overloading section.

    10.5.3 "out" typemap

    @@ -2125,7 +2648,7 @@ return values are often appended to return value of the function.

    -See the typemaps.i library for examples. +See the typemaps.i library file for examples.

    10.5.8 "freearg" typemap

    @@ -2187,7 +2710,7 @@ string *foo();

    -See Object ownership and %newobject for further details. +See Object ownership and %newobject for further details.

    10.5.10 "memberin" typemap

    @@ -2271,7 +2794,7 @@ catch(char const *_e) {

    Note that if your methods do not have an exception specification yet they do throw exceptions, SWIG cannot know how to deal with them. -For a neat way to handle these, see the Exception handling with %exception section. +For a neat way to handle these, see the Exception handling with %exception section.

    10.6 Some typemap examples

    @@ -2450,9 +2973,8 @@ You may even get a warning message like this:

    -swig -python  example.i
    -Generating wrappers for Python
    -example.i:10.  Warning. Array member value will be read-only.
    +$ swig -python  example.i
    +example.i:10: Warning 462: Unable to set variable of type float [4].
     

    @@ -2549,7 +3071,7 @@ useless and has since been eliminated. To return structure members, simply use One particularly interesting application of typemaps is the implementation of argument constraints. This can be done with the "check" typemap. When used, this allows you to provide code for -checking the values of function arguments. For example :

    +checking the values of function arguments. For example:

     %module math
    @@ -2572,7 +3094,7 @@ your program terminated with an error message.

    This kind of checking can be particularly useful when working with -pointers. For example :

    +pointers. For example:

     %typemap(check) Vector * {
    @@ -2590,16 +3112,12 @@ a NULL pointer. As a result, SWIG can often prevent a potential
     segmentation faults or other run-time problems by raising an exception
     rather than blindly passing values to the underlying C/C++ program.

    -

    -Note: A more advanced constraint checking system is in development. Stay tuned. -

    - -

    10.7 Typemaps for multiple languages

    +

    10.7 Typemaps for multiple target languages

    The code within typemaps is usually language dependent, -however, many languages support the same typemaps. +however, many target languages support the same typemaps. In order to distinguish typemaps across different languages, the preprocessor should be used. For example, the "in" typemap for Perl and Ruby could be written as:

    @@ -2630,8 +3148,9 @@ The example above also shows a common approach of issuing a warning for an as ye

    The "out" typemap is the main typemap for return types. This typemap supports an optional attribute flag called "optimal", which is for reducing -temporary variables and the amount of generated code. -It only really makes a difference when returning objects by value and it cannot always be used, +temporary variables and the amount of generated code, thereby giving the compiler the opportunity to +use return value optimization for generating faster executing code. +It only really makes a difference when returning objects by value and has some limitations on usage, as explained later on.

    @@ -2669,7 +3188,7 @@ struct XX {

    -The "out" typemap shown is the default typemap for C# when returning by objects by value. +The "out" typemap shown is the default typemap for C# when returning objects by value. When making a call to XX::create() from C#, the output is as follows:

    @@ -2689,7 +3208,7 @@ XX(const XX &) Note that three objects are being created as well as an assignment. Wouldn't it be great if the XX::create() method was the only time a constructor was called? As the method returns by value, this is asking a lot and the code that SWIG generates by default -makes it impossible for the compiler to make this type of optimisation. +makes it impossible for the compiler to use return value optimisation (RVO). However, this is where the "optimal" attribute in the "out" typemap can help out. If the typemap code is kept the same and just the "optimal" attribute specified like this:

    @@ -2748,7 +3267,7 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {

    The major difference is the result temporary variable holding the value returned from XX::create() is no longer generated and instead the copy constructor call is made directly from the value returned by XX::create(). -With modern compiler optimisations turned on, the copy is not actually done, in fact the object is never created +With modern compilers implementing RVO, the copy is not actually done, in fact the object is never created on the stack in XX::create() at all, it is simply created directly on the heap. In the first instance, the $1 special variable in the typemap is expanded into result. In the second instance, $1 is expanded into XX::create() and this is essentially @@ -2756,9 +3275,9 @@ what the "optimal" attribute is telling SWIG to do.

    -This kind of optimisation is not turned on by default as it has a number of restrictions. +The "optimal" attribute optimisation is not turned on by default as it has a number of restrictions. Firstly, some code cannot be condensed into a simple call for passing into the copy constructor. -One common occurrence is when %exception is used. +One common occurrence is when %exception is used. Consider adding the following %exception to the example:

    @@ -2780,8 +3299,9 @@ SWIG can detect when the "optimal" attribute cannot be used and will ignore it a
    -example.i:28: Warning(474): Method XX::create() usage of the optimal attribute in the out 
    -typemap at example.i:14 ignored as the following cannot be used to generate optimal code: 
    +example.i:28: Warning 474: Method XX::create() usage of the optimal attribute ignored
    +example.i:14: Warning 474: in the out typemap as the following cannot be used to generate
    +optimal code: 
     try {
       result = XX::create();
     } catch(const std::exception &e) {
    @@ -2791,7 +3311,7 @@ try {
     

    -It should be clear that the above code cannot be used as the argument to the copy constructor call, ie for the $1 substitution. +It should be clear that the above code cannot be used as the argument to the copy constructor call, that is, for the $1 substitution.

    @@ -2802,8 +3322,8 @@ In fact SWIG attempts to detect this and will issue a warning something like:

    -example.i:21: Warning(475): Multiple calls to XX::create() might be generated due to 
    -optimal attribute usage in the out typemap at example.i:7.
    +example.i:21: Warning 475: Multiple calls to XX::create() might be generated due to
    +example.i:7: Warning 475: optimal attribute usage in the out typemap.
     
    @@ -2811,7 +3331,7 @@ optimal attribute usage in the out typemap at example.i:7. However, it doesn't always get it right, for example when $1 is within some commented out code.

    -

    10.9 Multi-argument typemaps

    +

    10.9 Multi-argument typemaps

    @@ -2842,14 +3362,14 @@ list of strings like this:

    To do this, you not only need to map a list of strings to char *argv[], but the value of int argc is implicitly determined by the length of the list. Using only simple -typemaps, this type of conversion is possible, but extremely painful. Therefore, SWIG1.3 -introduces the notion of multi-argument typemaps. +typemaps, this type of conversion is possible, but extremely painful. +Multi-argument typemaps help in this situation.

    A multi-argument typemap is a conversion rule that specifies how to -convert a single object in the target language to set of -consecutive function arguments in C/C++. For example, the following multi-argument +convert a single object in the target language to a set of +consecutive function arguments in C/C++. For example, the following multi-argument maps perform the conversion described for the above example:

    @@ -3073,10 +3593,353 @@ this, you could write a multi-argument typemap like this: This kind of technique can be used to hook into scripting-language matrix packages such as Numeric Python. However, it should also be stressed that some care is in order. For example, when crossing languages you may need to worry about issues such as row-major vs. column-major -ordering (and perform conversions if needed). +ordering (and perform conversions if needed). Note that multi-argument typemaps cannot deal +with non-consecutive C/C++ arguments; a workaround such as a helper function re-ordering +the arguments to make them consecutive will need to be written.

    -

    10.10 The run-time type checker

    +

    10.10 Typemap warnings

    + + +

    +Warnings can be added to typemaps so that SWIG generates a warning message whenever the typemap is used. +See the information in the issuing warnings section. +

    + + +

    10.11 Typemap fragments

    + + +

    +The primary purpose of fragments is to reduce code bloat that repeated use of typemap code can lead to. +Fragments are snippets of code that can be thought of as code dependencies of a typemap. +If a fragment is used by more than one typemap, then the snippet of code within the fragment is only generated once. +Code bloat is typically reduced by moving typemap code into a support function +and then placing the support function into a fragment. +

    + +

    +For example, if you have a very long typemap +

    + +
    +
    +%typemap(in) MyClass * {
    +  MyClass *value = 0;
    +
    +  ... many lines of marshalling code  ...
    +
    +  $result = value;
    +}
    +
    +
    + +

    +the same marshalling code is often repeated in several typemaps, such as "in", "varin", "directorout", etc. +SWIG copies the code for each argument that requires the typemap code, easily leading to code bloat +in the generated code. +To eliminate this, define a fragment that includes the common marshalling code: +

    + +
    +
    +%fragment("AsMyClass", "header") {
    +  MyClass *AsMyClass(PyObject *obj) {
    +    MyClass *value = 0;
    +
    +    ... many lines of marshalling code  ...
    +
    +    return value;
    +  }
    +}
    +
    +%typemap(in, fragment="AsMyClass") MyClass * {
    +  $result = AsMyClass($input);
    +}
    +
    +%typemap(varin, fragment="AsMyClass") MyClass * {
    +  $result = AsMyClass($input);
    +}
    +
    +
    + +

    +When the "in" or "varin" typemaps for MyClass are required, the +contents of the fragment called "AsMyClass" is added to the "header" section within the generated code, and then the +typemap code is emitted. Hence, the method AsMyClass will be +generated into the wrapper code before any typemap code that calls it. +

    + +

    +To define a fragment you need a fragment name, a section name for generating the fragment code into, and the code itself. +See Code insertion blocks for a full list of section names. +Usually the section name used is "header". Different delimiters can be used: +

    + +
    +
    +%fragment("my_name", "header") %{ ... %}
    +%fragment("my_name", "header") { ... }
    +%fragment("my_name", "header") " ... "
    +
    +
    + +

    +and these follow the usual preprocessing rules mentioned in the +Preprocessing delimiters +section. +The following are some rules and guidelines for using fragments: +

    + +
      +
    1. +

      +A fragment is added to the wrapping code only once. When using the MyClass * typemaps above and wrapping the method: +

      + +
      +
      +void foo(MyClass *a, MyClass *b);
      +
      +
      + +

      +the generated code will look something like: +

      + +
      +
      +MyClass *AsMyClass(PyObject *obj) {
      +  ...
      +}
      +
      +void _wrap_foo(...) {
      +  ....
      +  arg1 = AsMyClass(obj1);
      +  arg2 = AsMyClass(obj2);
      +  ...
      +  foo(arg1, arg2);
      +}
      +
      +
      + +

      +even as there is duplicated typemap code to process both a and +b, the AsMyClass method will be defined only once. +

      + +
    2. +

      +A fragment should only be defined once. If there is more than +one definition, the first definition is the one used. +All other definitions are silently ignored. For example, if you have +

      + + +
      +
      +%fragment("AsMyClass", "header") { ...definition 1... }
      +....
      +%fragment("AsMyClass", "header") { ...definition 2... }
      +
      +
      + +

      +only the first definition is used. In this way +you can override the default fragments in a SWIG library by defining your fragment before the library %include. +Note that this behavior is the opposite to typemaps, where the last typemap defined/applied prevails. +Fragments follow the first-in-first-out convention since they are intended to be global, +while typemaps are intended to be locally specialized. +

      + +
    3. +

      +Fragment names cannot contain commas. +

      + + +
    4. +

      +A fragment can use one or more additional fragments, for example: +

      + +
      +
      +%fragment("<limits.h>", "header") {
      +  %#include <limits.h>
      +}
      +
      +
      +%fragment("AsMyClass", "header", fragment="<limits.h>") {
      +  MyClass *AsMyClass(PyObject *obj) {
      +    MyClass *value = 0;
      +
      +    ... some marshalling code  ...
      +
      +    if  (ival < CHAR_MIN /*defined in <limits.h>*/) {
      +       ...
      +    } else {
      +       ...
      +    }
      +    ...
      +    return value;
      +  }
      +}
      +
      +
      + +

      +in this case, when the "AsMyClass" fragment is emitted, it also +triggers the inclusion of the "<limits.h>" fragment. +

      + +
    5. +

      +A fragment can have dependencies on a number of other fragments, for example: +

      + +
      +
      +%fragment("bigfragment", "header", fragment="frag1", fragment="frag2", fragment="frag3") "";
      +
      +
      + +

      +When the "bigfragment" is used, the three dependent fragments "frag1", +"frag2" and "frag3" are also pulled in. Note that as "bigframent" is +empty (the empty string - ""), it does not add any code itself, but merely triggers the +inclusion of the other fragments. +

      + +
    6. +

      +A typemap can also use more than one fragment, but since the +syntax is different, you need to specify the dependent fragments in a comma separated +list. Consider: +

      + +
      +
      +%typemap(in, fragment="frag1,frag2,frag3") {...}
      +
      +
      + +

      +which is equivalent to: +

      + +
      +
      +%typemap(in, fragment="bigfragment") {...}
      +
      +
      + +

      +when used with the "bigfragment" defined above. +

      + +
    7. +

      +Finally, you can force the inclusion of a fragment at any point in the generated code as follows: +

      + +
      +
      +%fragment("bigfragment");
      +
      +
      + +

      +which is very useful inside a template class, for example. +

      +
    + +

    +Most readers will probably want to skip the next two sub-sections on advanced +fragment usage unless a desire to really get to grips +with some powerful but tricky macro and fragment usage that is used in parts of the SWIG typemap library. +

    + +

    10.11.1 Fragment type specialization

    + + +

    +Fragments can be type specialized. The syntax is as follows: +

    + +
    +
    +%fragment("name", "header") { ...a type independent fragment... }
    +%fragment("name"{type}, "header") { ...a type dependent fragment...  }
    +
    +
    + +

    +where type is a C/C++ type. Like typemaps, fragments can also be used inside templates, for example: +

    + +
    +
    +template <class T>
    +struct A {
    +  %fragment("incode"{A<T>}, "header") {
    +    ... 'incode' specialized fragment ...
    +  }
    +
    +  %typemap(in, fragment="incode"{A<T>}) {
    +     ... here we use the 'type specialized' fragment "incode"{A<T>} ...
    +  }
    +};
    +
    +
    + +

    10.11.2 Fragments and automatic typemap specialization

    + + +

    +Since fragments can be type specialized, they can be elegantly used +to specialize typemaps. For example, if you have something like: +

    + +
    +
    +%fragment("incode"{float}, "header") {
    +  float in_method_float(PyObject *obj) {
    +    ...
    +  }
    +}
    +
    +%fragment("incode"{long}, "header") {
    +  float in_method_long(PyObject *obj) {
    +    ...
    +  }
    +}
    +
    +// %my_typemaps macro definition
    +%define %my_typemaps(Type) 
    +%typemap(in, fragment="incode"{Type}) Type {
    +  value = in_method_##Type(obj);
    +}
    +%enddef
    +
    +%my_typemaps(float);
    +%my_typemaps(long);
    +
    +
    + +

    +then the proper "incode"{float} or "incode"{long} fragment will be used, +and the in_method_float and in_method_long methods will be called whenever +the float or long types are used as input parameters. +

    + +

    +This feature is used a lot in the typemaps shipped in the SWIG library for some scripting languages. +The interested (or very brave) reader can take a look at the fragments.swg file shipped with SWIG to see this in action. +

    + + +

    10.12 The run-time type checker

    @@ -3102,13 +3965,13 @@ language modules.

  • Modules can be unloaded from the type system.
  • -

    10.10.1 Implementation

    +

    10.12.1 Implementation

    The run-time type checker is used by many, but not all, of SWIG's supported target languages. The run-time type checker features -are not required and are thus not used for strongly typed languages such as Java and C#. +are not required and are thus not used for statically typed languages such as Java and C#. The scripting and scheme based languages rely on it and it forms a critical part of SWIG's operation for these languages.

    @@ -3288,12 +4151,12 @@ structures rather than creating new ones. These swig_module_info structures are chained together in a circularly linked list.

    -

    10.10.2 Usage

    +

    10.12.2 Usage

    This section covers how to use these functions from typemaps. To learn how to call these functions from external files (not the generated _wrap.c file), see -the External access to the run-time system +the External access to the run-time system section.

    When pointers are converted in a typemap, the typemap code often looks @@ -3328,8 +4191,8 @@ type tables and improves efficiency.

    Occasionally, you might need to write a typemap that needs to convert -pointers of other types. To handle this, a special macro substitution -$descriptor(type) can be used to generate the SWIG type +pointers of other types. To handle this, the special variable macro +$descriptor(type) covered earlier can be used to generate the SWIG type descriptor name for any C datatype. For example:

    @@ -3376,17 +4239,19 @@ interface file.

    Further details about the run-time type checking can be found in the documentation for individual language modules. Reading the source code may also help. The file -Lib/swigrun.swg in the SWIG library contains all of the source code for +Lib/swigrun.swg in the SWIG library contains all of the source of the generated code for type-checking. This code is also included in every generated wrapped file so you probably just look at the output of SWIG to get a better sense for how types are managed.

    -

    10.11 Typemaps and overloading

    +

    10.13 Typemaps and overloading

    -In many target languages, SWIG fully supports C++ overloaded methods and functions. For example, +This section does not apply to the statically typed languages like Java and C#, where overloading +of the types is handled much like C++ by generating overloaded methods in the target language. +In many of the other target languages, SWIG still fully supports C++ overloaded methods and functions. For example, if you have a collection of functions like this:

    @@ -3691,7 +4556,7 @@ Subsequent "in" typemaps would then perform more extensive type-checking. -

    10.12 More about %apply and %clear

    +

    10.14 More about %apply and %clear

    @@ -3776,88 +4641,8 @@ example: -

    10.13 Reducing wrapper code size

    - -

    -Since the code supplied to a typemap is inlined directly into wrapper functions, typemaps can result -in a tremendous amount of code bloat. For example, consider this typemap for an array: -

    - -
    -
    -%typemap(in) float [ANY] {
    -  int i;
    -  if (!PySequence_Check($input)) {
    -    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    -    return NULL;
    -  }
    -  if (PySequence_Length($input) != $1_dim0) {
    -    PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected $1_dim0 elements");
    -    return NULL;
    -  }
    -  $1 = (float) malloc($1_dim0*sizeof(float));
    -  for (i = 0; i < $1_dim0; i++) {
    -    PyObject *o = PySequence_GetItem($input,i);
    -    if (PyNumber_Check(o)) {
    -      $1[i] = (float) PyFloat_AsDouble(o);
    -    } else {
    -      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");      
    -      free(result);
    -      return NULL;
    -    }
    -  }
    -}
    -
    -
    - -

    -If you had a large interface with hundreds of functions all accepting -array parameters, this typemap would be replicated -repeatedly--generating a huge amount of code. A better approach might -be to consolidate some of the typemap into a function. For example: -

    - -
    -
    -%{
    -/* Define a helper function */
    -static float *
    -convert_float_array(PyObject *input, int size) {
    -  int i;
    -  float *result;
    -  if (!PySequence_Check(input)) {
    -    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    -    return NULL;
    -  }
    -  if (PySequence_Length(input) != size) {
    -    PyErr_SetString(PyExc_ValueError,"Size mismatch. ");
    -    return NULL;
    -  }
    -  result = (float) malloc(size*sizeof(float));
    -  for (i = 0; i < size; i++) {
    -    PyObject *o = PySequence_GetItem(input,i);
    -    if (PyNumber_Check(o)) {
    -      result[i] = (float) PyFloat_AsDouble(o);
    -    } else {
    -      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");
    -      free(result);       
    -      return NULL;
    -    }
    -  }
    -  return result;
    -}
    -%}
    -
    -%typemap(in) float [ANY] {
    -    $1 = convert_float_array($input, $1_dim0);
    -    if (!$1) return NULL;
    -}
    -%}
    -
    -
    - -

    10.14 Passing data between typemaps

    +

    10.15 Passing data between typemaps

    @@ -3894,7 +4679,67 @@ sure that the typemaps sharing information have exactly the same types and names

    -

    10.15 Where to go for more information?

    +

    10.16 C++ "this" pointer

    + + +

    +All the rules discussed for typemaps apply to C++ as well as C. +However in addition C++ passes an extra parameter into every +non-static class method -- the this pointer. Occasionally it can be +useful to apply a typemap to this pointer (for example to check +and make sure this is non-null before deferencing). +Actually, C also has an the equivalent of the this pointer which is used +when accessing variables in a C struct. +

    +

    +In order to customise the this pointer handling, target a variable named self in your typemaps. +self is the name SWIG uses to refer to the extra parameter in wrapped functions. +

    +

    +For example, if wrapping for Java generation: +

    + +
    +
    +%typemap(check) SWIGTYPE *self %{
    +if (!$1) {
    +  SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException,
    +    "invalid native object; delete() likely already called");
    +  return $null;
    +}
    +%}
    +
    +
    + +

    +In the above case, the $1 variable is expanded into the argument +name that SWIG is using as the this pointer. + +SWIG will then insert the check code before the actual C++ class method +is called, and will raise an exception rather than crash +the Java virtual machine. + +The generated code will look something like: +

    + +
    +
    +  if (!arg1) {
    +    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException,
    +      "invalid native object; delete() likely already called");
    +    return ;
    +  }
    +  (arg1)->wrappedFunction(...);
    +
    +
    + +

    +Note that if you have a parameter named self then it +will also match the typemap. One work around is to create an interface file that wraps +the method, but gives the argument a name other than self. +

    + +

    10.17 Where to go for more information?

    @@ -3908,6 +4753,7 @@ numerous examples. You should look at these files to get a feel for how to define typemaps of your own. Some of the language modules support additional typemaps and further information is available in the individual chapters for each target language. +There you may also find more hands-on practical examples.

    diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html index f40a1ff1f..c27db603d 100644 --- a/Doc/Manual/Varargs.html +++ b/Doc/Manual/Varargs.html @@ -270,21 +270,37 @@ traceprintf(arg1, NULL);

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

     >>> traceprintf("Hello World")
     >>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
    +>>> traceprintf("Your result is 90%%.")
     

    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:

    +
    +
    +>>> traceprintf("Your result is 90%.\n")  # unpredictable behaviour
    +>>> traceprintf("Your result is 90%%.\n") # good
    +
    +
    + +

    +Read on for further solutions. +

    + +

    13.4 Argument replacement using %varargs

    @@ -315,33 +331,82 @@ int open(const char *path, int oflags, int mode = 0);

    In this case, %varargs 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, %varargs can also +If the arguments to a varargs function are of uniform type, %varargs can also accept a numerical argument count as follows:

    -%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, ...);
     

    -This would wrap execlp() as a function that accepted up to 10 optional arguments. +and is effectively seen as: +

    + +
    +
    +int execlp(const char *path, const char *arg, 
    +           char *str1 = NULL, 
    +           char *str2 = NULL, 
    +           char *str3 = NULL);
    +
    +
    + +

    +This would wrap execlp() as a function that accepted up to 3 optional arguments. Depending on the application, this may be more than enough for practical purposes.

    -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 %varargs directive. +The handling of default arguments can be changed via the +compactdefaultargs feature. If this feature is used, for example +

    + +
    +
    +%feature("compactdefaultargs") execlp;
    +%varargs(3, char *str = NULL) execlp;
    +...
    +int execlp(const char *path, const char *arg, ...);
    +
    +
    + +

    +a call from the target language which does not provide the maximum number of arguments, such as, +execlp("a", "b", "c") +will generate C code which includes the missing default values, that is, execlp("a", "b", "c", NULL, NULL). +If compactdefaultargs is not used, then the generated code will be +execlp("a", "b", "c"). 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 compactdefaultargs it is possible to guarantee the NULL sentinel is passed through the, +numinputs=0 'in' typemap attribute, naming the last parameter. +For example, +

    + +
    +
    +%feature("compactdefaultargs") execlp;
    +%varargs(3, char *str = NULL) execlp;
    +%typemap(in, numinputs=0) char *str3 ""
    +...
    +int execlp(const char *path, const char *arg, ...);
    +
    +
    + +

    +Note that str3 is the name of the last argument, as we have used %vargars with 3. +Now execlp("a", "b", "c", "d", "e") 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 NULL.

    +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 printf(). Providing general purpose wrappers to such functions presents special problems (covered shortly). @@ -445,23 +510,36 @@ like this:

     %typemap(in) (...)(char *args[10]) {
    -    int i;
    -    int argc;
    -    for (i = 0; i < 10; i++) args[i] = 0;
    -    argc = PyTuple_Size(varargs);
    -    if (argc > 10) {
    -       PyErr_SetString(PyExc_ValueError,"Too many arguments");
    +  int i;
    +  int argc;
    +  for (i = 0; i < 10; i++) args[i] = 0;
    +  argc = PyTuple_Size(varargs);
    +  if (argc > 10) {
    +    PyErr_SetString(PyExc_ValueError, "Too many arguments");
    +    return NULL;
    +  }
    +  for (i = 0; i < argc; i++) {
    +    PyObject *pyobj = PyTuple_GetItem(varargs, i);
    +    char *str = 0;
    +%#if PY_VERSION_HEX>=0x03000000
    +    PyObject *pystr;
    +    if (!PyUnicode_Check(pyobj)) {
    +       PyErr_SetString(PyExc_ValueError, "Expected a string");
            return NULL;
         }
    -    for (i = 0; i < 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;
     }
     
    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 39d5d3f01..2a3ce560d 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -25,7 +25,7 @@
  • C/C++ Parser (300-399)
  • Types and typemaps (400-499)
  • Code generation (500-599) -
  • Language module specific (800-899) +
  • Language module specific (700-899)
  • User defined (900-999)
  • History @@ -44,8 +44,8 @@ During compilation, SWIG may generate a variety of warning messages. For exampl
    -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)
     
    @@ -102,7 +102,7 @@ int foo(double); // Silently ignored.

    The %warnfilter directive has the same semantics as other declaration modifiers like %rename, %ignore and %feature, see the -%feature directive section. For example, if you wanted to +%feature directive section. For example, if you wanted to suppress a warning for a method in a class hierarchy, you could do this:

    @@ -257,16 +257,23 @@ Warning messages can be associated with typemaps using the
    -%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 * {
        ...
     }
     

    -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 special variables will be expanded as appropriate, for example:

    +
    +
    +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
    +
    +
    +

    14.5 Symbolic symbols

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

    14.9 Warning number reference

    @@ -373,7 +380,7 @@ example.i(4): Syntax error in input.
  • 117. Deprecated %new directive.
  • 118. Deprecated %typemap(except).
  • 119. Deprecated %typemap(ignore). -
  • 120. Deprecated command line option (-c). +
  • 120. Deprecated command line option (-runtime, -noruntime).
  • 121. Deprecated %name directive. @@ -381,8 +388,12 @@ example.i(4): Syntax error in input.
      -
    • 201. Unable to find 'filename'. -
    • 202. Could not evaluate 'expr'. +
    • 201. Unable to find filename. +
    • 202. Could not evaluate expression expr. +
    • 203. Both includeall and importall are defined: using includeall. +
    • 204. CPP #warning, "warning". +
    • 205. CPP #error, "error". +
    • 206. Unexpected tokens after #directive directive.

    14.9.3 C/C++ Parser (300-399)

    @@ -399,18 +410,20 @@ example.i(4): Syntax error in input.
  • 308. Namespace alias 'name' not allowed here. Assuming 'name'
  • 309. [private | protected] inheritance ignored.
  • 310. Template 'name' was already wrapped as 'name' (ignored) -
  • 311. Template partial specialization not supported. -
  • 312. Nested classes not currently supported (ignored). +
  • 312. Unnamed nested class not currently supported (ignored).
  • 313. Unrecognized extern type "name" (ignored).
  • 314. 'identifier' is a lang keyword.
  • 315. Nothing known about 'identifier'.
  • 316. Repeated %module directive.
  • 317. Specialization of non-template 'name'. -
  • 318. Instantiation of template name is ambiguous. Using templ at file:line +
  • 318. Instantiation of template 'name' is ambiguous, instantiation templ used, instantiation templ ignored.
  • 319. No access specifier given for base class name (ignored).
  • 320. Explicit template instantiation ignored.
  • 321. identifier conflicts with a built-in name.
  • 322. Redundant redeclaration of 'name'. +
  • 323. Recursive scope inheritance of 'name'. +
  • 324. Named nested template instantiations not supported. Processing as if no name was given to %template(). +
  • 325. Nested class not currently supported (name ignored).
  • 350. operator new ignored.
  • 351. operator delete ignored.
  • 352. operator+ ignored. @@ -482,8 +495,8 @@ example.i(4): Syntax error in input.
  • 469. No or improper directorin typemap defined for type
  • 470. Thread/reentrant unsafe wrapping, consider returning by value instead.
  • 471. Unable to use return type type in director method -
  • 474. Method method usage of the optimal attribute in the out typemap at file:line ignored as the following cannot be used to generate optimal code: code -
  • 475. Multiple calls to method might be generated due to optimal attribute usage in the out typemap at file:line. +
  • 474. Method method usage of the optimal attribute ignored in the out typemap as the following cannot be used to generate optimal code: code +
  • 475. Multiple calls to method might be generated due to optimal attribute usage in the out typemap. @@ -492,28 +505,30 @@ example.i(4): Syntax error in input.
      -
    • 501. Overloaded declaration ignored. decl -
    • 502. Overloaded constructor ignored. decl +
    • 501. Overloaded declaration ignored. decl. Previous declaration is decl. +
    • 502. Overloaded constructor ignored. decl. Previous declaration is decl.
    • 503. Can't wrap 'identifier' unless renamed to a valid identifier. -
    • 504. Function name must have a return type. +
    • 504. Function name must have a return type. Ignored.
    • 505. Variable length arguments discarded.
    • 506. Can't wrap varargs with keyword arguments enabled.
    • 507. Adding native function name not supported (ignored). -
    • 508. Declaration of 'name' shadows declaration accessible via operator->() at file:line. -
    • 509. Overloaded declaration is shadowed by declaration at file:line. +
    • 508. Declaration of 'name' shadows declaration accessible via operator->(), previous declaration of'declaration'. +
    • 509. Overloaded method declaration effectively ignored, as it is shadowed by declaration.
    • 510. Friend function 'name' ignored.
    • 511. Can't use keyword arguments with overloaded functions. -
    • 512. Overloaded declaration const ignored. Non-const method at file:line used. +
    • 512. Overloaded method declaration ignored, using non-const method declaration instead.
    • 513. Can't generate wrappers for unnamed struct/class.
    • 514.
    • 515. -
    • 516. Overloaded method declaration ignored. Method declaration at file:line used. +
    • 516. Overloaded method declaration ignored, using declaration instead.
    • 517.
    • 518. Portability warning: File file1 will be overwritten by file2 on case insensitive filesystems such as Windows' FAT32 and NTFS unless the class/module name is renamed.
    • 519. %template() contains no name. Template method ignored: declaration +
    • 520. Base/Derived class 'classname1' of 'classname2' is not similarly marked as a smart pointer. +
    • 521. Illegal destructor name name. Ignored.
    -

    14.9.6 Language module specific (800-899)

    +

    14.9.6 Language module specific (700-899)

      @@ -558,7 +573,7 @@ example.i(4): Syntax error in input.
      -
    • 870. Warning for classname: Base baseclass ignored. Multiple inheritance is not supported in Php4. (Php). +
    • 870. Warning for classname: Base baseclass ignored. Multiple inheritance is not supported in PHP.
    • 871. Unrecognized pragma pragma. (Php).
    diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html index 8a718ffad..6349f355a 100644 --- a/Doc/Manual/Windows.html +++ b/Doc/Manual/Windows.html @@ -67,7 +67,7 @@ SWIG does not come with the usual Windows type installation program, however it

    -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 Building swig.exe on Windows.

    @@ -78,7 +78,7 @@ If you want to build your own swig.exe have a look at MinGW download page - or MinGW SourceForge download page. + or MinGW SourceForge download page. 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.