From b75c60620535f1716873fd26c5205b0379fae237 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 17 Aug 2009 23:07:16 +0000 Subject: [PATCH 001/146] Fix for r11557 rename of max to maximum git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11628 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/lua/overload_template_fast_runme.lua | 4 ++-- Examples/test-suite/octave/overload_template_fast_runme.m | 4 ++-- Examples/test-suite/python/overload_template_fast_runme.py | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Examples/test-suite/lua/overload_template_fast_runme.lua b/Examples/test-suite/lua/overload_template_fast_runme.lua index 97078f34d..6663cb0b5 100644 --- a/Examples/test-suite/lua/overload_template_fast_runme.lua +++ b/Examples/test-suite/lua/overload_template_fast_runme.lua @@ -2,12 +2,12 @@ require("import") -- the import fn import("overload_template_fast") -- import code for k,v in pairs(overload_template_fast) do _G[k]=v end -- move to global --- lua has only one numeric type, so max(int,int) and max(double,double) are the same +-- lua has only one numeric type, so maximum(int,int) and maximum(double,double) are the same -- whichever one was wrapper first will be used (which is int) f = foo() -a = max(3,4) +a = maximum(3,4) -- mix 1 assert(mix1("hi") == 101) diff --git a/Examples/test-suite/octave/overload_template_fast_runme.m b/Examples/test-suite/octave/overload_template_fast_runme.m index 346af7242..f99ce8642 100644 --- a/Examples/test-suite/octave/overload_template_fast_runme.m +++ b/Examples/test-suite/octave/overload_template_fast_runme.m @@ -5,8 +5,8 @@ overload_template_fast f = foo(); -a = max(3,4); -b = max(3.4,5.2); +a = maximum(3,4); +b = maximum(3.4,5.2); # mix 1 if (mix1("hi") != 101) diff --git a/Examples/test-suite/python/overload_template_fast_runme.py b/Examples/test-suite/python/overload_template_fast_runme.py index a8d271d27..d47f7d14d 100644 --- a/Examples/test-suite/python/overload_template_fast_runme.py +++ b/Examples/test-suite/python/overload_template_fast_runme.py @@ -1,8 +1,8 @@ from overload_template_fast import * f = foo() -a = max(3,4) -b = max(3.4,5.2) +a = maximum(3,4) +b = maximum(3.4,5.2) # mix 1 if (mix1("hi") != 101): From d2fe155495de7b6f857a66734ae71dfa93981678 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 17 Aug 2009 23:12:54 +0000 Subject: [PATCH 002/146] warning fix git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11629 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/special_variable_macros.i | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/special_variable_macros.i b/Examples/test-suite/special_variable_macros.i index 3f0cd724a..f27bbd619 100644 --- a/Examples/test-suite/special_variable_macros.i +++ b/Examples/test-suite/special_variable_macros.i @@ -88,7 +88,7 @@ const char * testMary(Name *mary) { %{ /*%typemap(in) (Name *multiname, int num) start */ temp_name = $*1_ltype("multiname num"); - temp_count = strlen(temp_name.getNamePtr()->getName()); + temp_count = (int)strlen(temp_name.getNamePtr()->getName()); (void)$input; $1 = temp_name.getNamePtr(); $2 = temp_count + 100; @@ -103,7 +103,7 @@ $typemap(in, (Name *multiname, int num)) %inline %{ const char * testJim(Name *jim, int count) { - if (count != strlen(jim->getNamePtr()->getName()) + 100) + if (count != (int)strlen(jim->getNamePtr()->getName()) + 100) return "size check failed"; else return jim->getName(); From 96cd19f86b6510238c5051e31862d369496e8037 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 00:16:11 +0000 Subject: [PATCH 003/146] Remove C# 3.0 requirement to run test git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11630 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/csharp/li_std_vector_runme.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/csharp/li_std_vector_runme.cs b/Examples/test-suite/csharp/li_std_vector_runme.cs index a2da91e15..617116d5a 100644 --- a/Examples/test-suite/csharp/li_std_vector_runme.cs +++ b/Examples/test-suite/csharp/li_std_vector_runme.cs @@ -158,7 +158,8 @@ public class li_std_vector_runme { } catch (ArgumentNullException) { } { - myDoubleVector = new DoubleVector() { 123.4, 567.8, 901.2 }; + // Collection initializer test, requires C# 3.0 +// myDoubleVector = new DoubleVector() { 123.4, 567.8, 901.2 }; } // IndexOf() test @@ -542,8 +543,8 @@ public class li_std_vector_runme { // Dispose() { - using (StructVector vs = new StructVector() { new Struct(0.0), new Struct(11.1) } ) - using (DoubleVector vd = new DoubleVector() { 0.0, 11.1 } ) { + using (StructVector vs = new StructVector( new Struct[] { new Struct(0.0), new Struct(11.1) } ) ) + using (DoubleVector vd = new DoubleVector( new double[] { 0.0, 11.1 } ) ) { } } From 6a5a5f69a14d08e9741e2f6a88dc681e45db9b7f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 01:26:56 +0000 Subject: [PATCH 004/146] Complete summary for 1.3.40 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11631 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 6ee379786..634ec1b4d 100644 --- a/README +++ b/README @@ -95,6 +95,10 @@ What's New? SWIG-1.3.40 summary: - SWIG now supports directors for PHP. - PHP support improved in general. +- Octave 3.2 support added. +- Various bug fixes/enhancements for Allegrocl C#, Java, Octave, Perl, + Python, Ruby and Tcl. +- Other generic fixes and minor new features. SWIG-1.3.39 summary: - Some new small feature enhancements. From 2d27a4296bc7774e595e2975a30317ebcea43054 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 13:41:22 +0000 Subject: [PATCH 005/146] fix warnings git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11632 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/li_reference.i | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Examples/test-suite/li_reference.i b/Examples/test-suite/li_reference.i index d021e807f..f16fdbeaa 100644 --- a/Examples/test-suite/li_reference.i +++ b/Examples/test-suite/li_reference.i @@ -10,43 +10,43 @@ void RDouble(double &REFERENCE, int t = 0) { ToVal = REFERENCE; REFERENCE = FrVal + t; } void PFloat(float *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (float)(FrVal + t); } void RFloat(float &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (float)(FrVal + t); } void PInt(int *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (int)(FrVal + t); } void RInt(int &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (int)(FrVal + t); } void PShort(short *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (short)(FrVal + t); } void RShort(short &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (short)(FrVal + t); } void PLong(long *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (long)(FrVal + t); } void RLong(long &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (long)(FrVal + t); } void PUInt(unsigned int *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (unsigned int)(FrVal + t); } void RUInt(unsigned int &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (unsigned int)(FrVal + t); } void PUShort(unsigned short *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (unsigned short)(FrVal + t); } void RUShort(unsigned short &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (unsigned short)(FrVal + t); } void PULong(unsigned long *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (unsigned long)(FrVal + t); } void RULong(unsigned long &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (unsigned long)(FrVal + t); } void PUChar(unsigned char *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (unsigned char)(FrVal + t); } void RUChar(unsigned char &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (unsigned char)(FrVal + t); } void PChar(signed char *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (signed char)(FrVal + t); } void RChar(signed char &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (signed char)(FrVal + t); } void PBool(bool *REFERENCE, int t = 0) - { ToVal = *REFERENCE; *REFERENCE = FrVal + t; } + { ToVal = *REFERENCE; *REFERENCE = (FrVal + t) ? true : false; } void RBool(bool &REFERENCE, int t = 0) - { ToVal = REFERENCE; REFERENCE = FrVal + t; } + { ToVal = REFERENCE; REFERENCE = (FrVal + t) ? true : false; } %} From 3c604b402dce9d1febf1de672d33ffe950139c8a Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 18 Aug 2009 13:47:27 +0000 Subject: [PATCH 006/146] PHP: remove unneeded ctor from the director_extend testcase git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11633 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/php/director_extend_runme.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Examples/test-suite/php/director_extend_runme.php b/Examples/test-suite/php/director_extend_runme.php index f282df17d..f283aefbe 100644 --- a/Examples/test-suite/php/director_extend_runme.php +++ b/Examples/test-suite/php/director_extend_runme.php @@ -11,11 +11,6 @@ check::classes(array(SpObject)); check::globals(array()); class MyObject extends SpObject{ - function __construct() { - parent::__construct(); - return; - } - function getFoo() { return 123; } From 4be26aa11d967501c8a5f6de65555c46d7fab387 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 14:02:22 +0000 Subject: [PATCH 007/146] Clear up confusion that typemaps can contain C/C++ as well as target language code git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11634 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Sections.html | 2 +- Doc/Manual/Typemaps.html | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index 789efc129..e39633e38 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -6,7 +6,7 @@

SWIG-1.3 Development Documentation

-Last update : SWIG-1.3.40 (in progress) +Last update : SWIG-1.3.40 (18 August 2009)

Sections

diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 226b4ef3e..bf31b30b9 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -230,14 +230,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).

@@ -4060,6 +4063,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.

From 66e281e7f0a5cade4a4f671133b3c86fc40006d3 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 14:04:06 +0000 Subject: [PATCH 008/146] add 1.3.40 release date git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11635 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- ANNOUNCE | 2 +- CHANGES.current | 4 ++-- README | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 9ef41142a..64e195d04 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,4 +1,4 @@ -*** ANNOUNCE: SWIG 1.3.40 (in progress) *** +*** ANNOUNCE: SWIG 1.3.40 (18 August 2009) *** http://www.swig.org diff --git a/CHANGES.current b/CHANGES.current index 1021106f1..e41f17d65 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,5 +1,5 @@ -Version 1.3.40 (in progress) -============================ +Version 1.3.40 (18 August 2009) +=============================== 2009-08-17: olly [Perl] Add "#undef do_exec" to our clean up of Perl global diff --git a/README b/README index 634ec1b4d..dbf438f51 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ SWIG (Simplified Wrapper and Interface Generator) -Version: 1.3.40 (in progress) +Version: 1.3.40 (18 August 2009) Tagline: SWIG is a compiler that integrates C and C++ with languages including Perl, Python, Tcl, Ruby, PHP, Java, Ocaml, Lua, @@ -96,7 +96,7 @@ SWIG-1.3.40 summary: - SWIG now supports directors for PHP. - PHP support improved in general. - Octave 3.2 support added. -- Various bug fixes/enhancements for Allegrocl C#, Java, Octave, Perl, +- Various bug fixes/enhancements for Allegrocl, C#, Java, Octave, Perl, Python, Ruby and Tcl. - Other generic fixes and minor new features. From f0fb2f38518674b973bb97552b89ec84e94c003e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 14:08:50 +0000 Subject: [PATCH 009/146] Remove 'under construction' notes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11636 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Arguments.html | 2 -- Doc/Manual/Php.html | 4 ---- Doc/Manual/Typemaps.html | 4 ---- 3 files changed, 10 deletions(-) diff --git a/Doc/Manual/Arguments.html b/Doc/Manual/Arguments.html index 911e8548e..8ab51faf6 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 diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index 7bf158918..de745e135 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -48,10 +48,6 @@ -

-Caution: This chapter (and module!) is still under construction -

-

SWIG supports generating wrappers for PHP5. Support for PHP4 has been removed as of SWIG 1.3.37. The PHP developers are no longer making new PHP4 releases, diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index bf31b30b9..da4fdadc9 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -88,10 +88,6 @@ -

-Disclaimer: This chapter is under construction! -

-

10.1 Introduction

From fc52ca3b80434eee001745e93c07cbf0fb7095cf Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 18 Aug 2009 16:23:23 +0000 Subject: [PATCH 010/146] PHP: handle -prefix when checking if a class has been subclassed or not git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11637 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index bae922e90..eee4d1fcc 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1636,7 +1636,7 @@ public: } else { Node *parent = Swig_methodclass(n); String *classname = Swig_class_name(parent); - Printf(output, "\t\tif (get_class($this) === '%s') {\n", classname); + Printf(output, "\t\tif (get_class($this) === '%s%s') {\n", prefix, classname); Printf(output, "\t\t\t$_this = null;\n"); Printf(output, "\t\t} else {\n"); Printf(output, "\t\t\t$_this = $this;\n"); From 2d78a12b873468c7d5f9529e79e445d82351a892 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 18 Aug 2009 23:30:59 +0000 Subject: [PATCH 011/146] changes required for new SourceForge file release process git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11645 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/mkrelease.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/Tools/mkrelease.py b/Tools/mkrelease.py index edf3b07fe..b719c470e 100755 --- a/Tools/mkrelease.py +++ b/Tools/mkrelease.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # This script builds the SWIG source tarball, creates the Windows executable and the Windows zip package -# and uploads them both to SF ready for release +# and uploads them both to SF ready for release. Also uploaded are the release notes. import sys import string import os @@ -30,10 +30,20 @@ os.system("python ./mkdist.py " + version) and failed("") print "Build Windows package" os.system("./mkwindows.sh " + version) and failed("") -print "Uploading to Sourceforge" -os.system("rsync --archive --verbose -P --times -e ssh swig-" + version + ".tar.gz " + username + "@frs.sourceforge.net:uploads/") and failed("") -os.system("rsync --archive --verbose -P --times -e ssh swigwin-" + version + ".zip " + username + "@frs.sourceforge.net:uploads/") and failed("") +print "Uploading to SourceForge" + +swig_dir_sf = username + ",swig@frs.sourceforge.net:/home/frs/project/s/sw/swig/swig/swig-" + version + "/" +swigwin_dir_sf = username + ",swig@frs.sourceforge.net:/home/frs/project/s/sw/swig/swigwin/swigwin-" + version + "/" + +release_notes_file = "release-notes-" + version + ".txt" +os.system("rm -f " + release_notes_file) +os.system("cat swig-" + version + "/README " + "swig-" + version + "/CHANGES.current > " + release_notes_file) + +os.system("rsync --archive --verbose -P --times -e ssh " + "swig-" + version + ".tar.gz " + release_notes_file + " " + swig_dir_sf) and failed("") +os.system("rsync --archive --verbose -P --times -e ssh " + "swigwin-" + version + ".zip " + swigwin_dir_sf) and failed("") os.system("svn copy -m \"rel-" + version + "\" https://swig.svn.sourceforge.net/svnroot/swig/trunk https://swig.svn.sourceforge.net/svnroot/swig/tags/rel-" + version + "/") print "Finished" + +print "Now log in to SourceForge and set the operating system and link the release notes to each of the tarball and zip file in the File Manager." From 4835720f5a63a822292e66aa0fb308a6ac1144f9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 19 Aug 2009 00:11:29 +0000 Subject: [PATCH 012/146] bump version to 1.3.41 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11647 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- ANNOUNCE | 10 +- CHANGES | 258 +++++++++++++++++++++++++++++++++++++++ CHANGES.current | 258 +-------------------------------------- Doc/Manual/Sections.html | 2 +- README | 2 +- configure.in | 2 +- 6 files changed, 268 insertions(+), 264 deletions(-) diff --git a/ANNOUNCE b/ANNOUNCE index 64e195d04..770df1b20 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,10 +1,10 @@ -*** ANNOUNCE: SWIG 1.3.40 (18 August 2009) *** +*** ANNOUNCE: SWIG 1.3.41 (in progress) *** http://www.swig.org -We're pleased to announce SWIG-1.3.40, the latest installment in the -SWIG development effort. SWIG-1.3.40 includes a number of bug fixes +We're pleased to announce SWIG-1.3.41, the latest installment in the +SWIG development effort. SWIG-1.3.41 includes a number of bug fixes and enhancements. What is SWIG? @@ -24,11 +24,11 @@ Availability: ------------- The release is available for download on Sourceforge at - http://prdownloads.sourceforge.net/swig/swig-1.3.40.tar.gz + http://prdownloads.sourceforge.net/swig/swig-1.3.41.tar.gz A Windows version is also available at - http://prdownloads.sourceforge.net/swig/swigwin-1.3.40.zip + http://prdownloads.sourceforge.net/swig/swigwin-1.3.41.zip Please report problems with this release to the swig-dev mailing list, details at http://www.swig.org/mail.html. diff --git a/CHANGES b/CHANGES index d9426512b..8360207c2 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,264 @@ SWIG (Simplified Wrapper and Interface Generator) See CHANGES.current for current version. +Version 1.3.40 (in progress) +=============================== + +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) ============================== diff --git a/CHANGES.current b/CHANGES.current index e41f17d65..99cade363 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,257 +1,3 @@ -Version 1.3.40 (18 August 2009) -=============================== +Version 1.3.41 (in progress) +============================ -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); - %} diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index e39633e38..b98661c0d 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -6,7 +6,7 @@

SWIG-1.3 Development Documentation

-Last update : SWIG-1.3.40 (18 August 2009) +Last update : SWIG-1.3.41 (in progress)

Sections

diff --git a/README b/README index dbf438f51..4af2da56f 100644 --- a/README +++ b/README @@ -1,6 +1,6 @@ SWIG (Simplified Wrapper and Interface Generator) -Version: 1.3.40 (18 August 2009) +Version: 1.3.41 (in progress) Tagline: SWIG is a compiler that integrates C and C++ with languages including Perl, Python, Tcl, Ruby, PHP, Java, Ocaml, Lua, diff --git a/configure.in b/configure.in index 4edc8e1ae..96c3d18b0 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. dnl The macros which aren't shipped with the autotools are stored in the dnl Tools/config directory in .m4 files. -AC_INIT([swig],[1.3.40],[http://www.swig.org]) +AC_INIT([swig],[1.3.41],[http://www.swig.org]) AC_PREREQ(2.58) AC_CONFIG_SRCDIR([Source/Swig/swig.h]) AC_CONFIG_AUX_DIR([Tools/config]) From a90d30b4fda91ce28cb0d5b5afe3fb54382a4621 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 19 Aug 2009 00:14:15 +0000 Subject: [PATCH 013/146] mention CHANGES.current in README file git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11648 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- README | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README b/README index 4af2da56f..2101925fe 100644 --- a/README +++ b/README @@ -64,7 +64,7 @@ Major contributors include: Past contributors include: James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran Kovuk, Oleg Tolmatcev, Tal Shalif, Lluis Padro, Chris Seatory, Igor Bely, Robin Dunn - (See CHANGES for a more complete list). + (See CHANGES and CHANGES.current for a more complete list). Portions also copyrighted by companies/corporations; Network Applied Communication Laboratory, Inc @@ -376,8 +376,10 @@ well advised to read this. Release Notes ============= -Please see the CHANGES files for a detailed list of bug fixes and -new features. A summary of the changes is included in this README file. +Please see the CHANGES.current file for a detailed list of bug fixes and +new features for the current release. The CHANGES file contains bug fixes +and new features for older versions. A summary of the changes is included +in this README file. Windows Installation ==================== From 9584c00eaa7c3c16009e4f2173aa079d1f2a97fa Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 19 Aug 2009 00:23:38 +0000 Subject: [PATCH 014/146] Fix release date for 1.3.40 for last commit git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11649 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 8360207c2..509484e2f 100644 --- a/CHANGES +++ b/CHANGES @@ -2,7 +2,7 @@ SWIG (Simplified Wrapper and Interface Generator) See CHANGES.current for current version. -Version 1.3.40 (in progress) +Version 1.3.40 (18 August 2009) =============================== 2009-08-17: olly From 2c6fedd1d2df236fe4f4eebb5b16b10a73aeb41e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 20 Aug 2009 22:53:17 +0000 Subject: [PATCH 015/146] fix make distclean git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11657 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 19d37dc3b..111d7d878 100644 --- a/Makefile.in +++ b/Makefile.in @@ -388,7 +388,7 @@ maintainer-clean: clean-libfiles DISTCLEAN-DEAD = config.status config.log config.cache swig.spec Makefile mkmf.log libtool -distclean: distclean-objects clean-examples clean-gifplot distclean-test-suite clean-docs distclean-dead distclean-ccache +distclean: clean-docs distclean-objects clean-examples clean-gifplot distclean-test-suite distclean-dead distclean-ccache distclean-objects: distclean-source From 9d6e826bd8d76e43a9d00cbd446c7e3949514c82 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 20 Aug 2009 23:21:07 +0000 Subject: [PATCH 016/146] Test std::map in all languages git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11658 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 1 + Examples/test-suite/octave/Makefile.in | 1 - Examples/test-suite/python/Makefile.in | 1 - Examples/test-suite/ruby/Makefile.in | 1 - 4 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 492378b16..4c469ded0 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -409,6 +409,7 @@ CPP_STD_TEST_CASES += \ li_std_combinations \ li_std_deque \ li_std_except \ + li_std_map \ li_std_pair \ li_std_string \ li_std_vector \ diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index 70de84adc..a9a7649ec 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -17,7 +17,6 @@ CPP_TEST_CASES += \ CPP_TEST_BROKEN += \ implicittest \ li_implicit \ - li_std_map \ li_std_set \ li_std_stream diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 274d53f1d..4938ddc27 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -49,7 +49,6 @@ CPP_TEST_CASES += \ li_implicit \ li_std_vectora \ li_std_vector_extra \ - li_std_map \ li_std_multimap \ li_std_pair_extra \ li_std_set \ diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index dc8751da1..27996616e 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -14,7 +14,6 @@ CPP_TEST_CASES = \ li_cstring \ li_factory \ li_std_functors \ - li_std_map \ li_std_multimap \ li_std_pair_lang_object \ li_std_queue \ From b56cd0b0f671b3c367abe2216ac53c82b933d3ea Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 20 Aug 2009 23:55:25 +0000 Subject: [PATCH 017/146] remove unused directory creation git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11660 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CCache/Makefile.in | 1 - 1 file changed, 1 deletion(-) diff --git a/CCache/Makefile.in b/CCache/Makefile.in index 29cf8db1b..2f4decfff 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -37,7 +37,6 @@ $(PACKAGE_NAME).1: ccache.yo -yodl2man -o $(PACKAGE_NAME).1 ccache.yo web/ccache-man.html: ccache.yo - mkdir -p man yodl2html -o web/ccache-man.html ccache.yo install: $(PACKAGE_NAME)$(EXEEXT) $(PACKAGE_NAME).1 From 1be8bd5d8eee68bfe2806cc0efbbbaf86409af6f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 21 Aug 2009 00:00:23 +0000 Subject: [PATCH 018/146] tidy up distclean git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11662 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CCache/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CCache/Makefile.in b/CCache/Makefile.in index 2f4decfff..f885e72ae 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -63,7 +63,7 @@ test: test.sh check: test distclean: clean distclean-docs - /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status configure config.h + /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status configure config.h.in ccache_swig_config.h # FIXME: To fix this, test.sh needs to be able to take ccache from the # installed prefix, not from the source dir. From 3932d02a2a74984ac016692cd34efbf7952060ea Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 21 Aug 2009 00:25:11 +0000 Subject: [PATCH 019/146] fix SWIG naming convention git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11663 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Allegrocl.html | 4 ++-- Doc/Manual/CSharp.html | 2 +- Doc/Manual/Contents.html | 2 +- Doc/Manual/Guile.html | 4 ++-- Doc/Manual/Perl5.html | 2 +- Doc/Manual/Php.html | 2 +- Doc/Manual/Python.html | 6 +++--- Doc/Manual/Ruby.html | 4 ++-- Doc/Manual/SWIGPlus.html | 2 +- Examples/java/pointer/index.html | 2 +- Examples/perl5/pointer/index.html | 2 +- Examples/python/pointer/index.html | 2 +- Examples/ruby/pointer/index.html | 2 +- Examples/tcl/pointer/index.html | 2 +- Lib/lua/luarun.swg | 2 +- Lib/php/director.swg | 4 ++-- Lib/python/director.swg | 10 +++++----- Lib/ruby/director.swg | 10 +++++----- Lib/tcl/typemaps.i | 4 ++-- Lib/typemaps/fragments.swg | 6 +++--- Lib/typemaps/swigmacros.swg | 6 +++--- Source/Modules/modula3.cxx | 2 +- Source/Preprocessor/cpp.c | 4 ++-- 23 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html index cc950db7c..cf70f6c27 100644 --- a/Doc/Manual/Allegrocl.html +++ b/Doc/Manual/Allegrocl.html @@ -14,7 +14,7 @@
  • Basics @@ -138,7 +138,7 @@ to it.

    17.1 Basics

    -

    17.1.1 Running Swig

    +

    17.1.1 Running SWIG

    diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index f747fc213..f092d188a 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -55,7 +55,7 @@ The PInvoke interface has been chosen over Microsoft's Managed C++ interface as 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 +SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using Mono and Portable.NET.

    diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 0e7ebf464..85b1ab5f5 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -537,7 +537,7 @@
    • Basics diff --git a/Doc/Manual/Guile.html b/Doc/Manual/Guile.html index cf7e8da2c..61b5ba7d6 100644 --- a/Doc/Manual/Guile.html +++ b/Doc/Manual/Guile.html @@ -814,7 +814,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 +848,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/Perl5.html b/Doc/Manual/Perl5.html index 8f74bd1de..40500dc5a 100644 --- a/Doc/Manual/Perl5.html +++ b/Doc/Manual/Perl5.html @@ -112,7 +112,7 @@ options are found near the end of the chapter.

      -To build a Perl5 module, run Swig using the -perl option as +To build a Perl5 module, run SWIG using the -perl option as follows :

      diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html index de745e135..b9dcb83c5 100644 --- a/Doc/Manual/Php.html +++ b/Doc/Manual/Php.html @@ -101,7 +101,7 @@ 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.

      diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index 8b359bda9..a739543df 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -1137,7 +1137,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>
       

      @@ -1147,7 +1147,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: @@ -1171,7 +1171,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.

      diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 98fa315d0..643a6daec 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -7097,7 +7097,7 @@ being created. 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 +

      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 @@ -7123,7 +7123,7 @@ across multiple languages.

      RUBY - Swig + SWIG diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index ef7487ff8..f3befa54b 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -3471,7 +3471,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.

      diff --git a/Examples/java/pointer/index.html b/Examples/java/pointer/index.html index e20fe3328..5c93d4d58 100644 --- a/Examples/java/pointer/index.html +++ b/Examples/java/pointer/index.html @@ -143,7 +143,7 @@ extraction. diff --git a/Examples/perl5/pointer/index.html b/Examples/perl5/pointer/index.html index 6f9fd397d..94467bc36 100644 --- a/Examples/perl5/pointer/index.html +++ b/Examples/perl5/pointer/index.html @@ -144,7 +144,7 @@ extraction. diff --git a/Examples/python/pointer/index.html b/Examples/python/pointer/index.html index ceef30566..b99c8fe4c 100644 --- a/Examples/python/pointer/index.html +++ b/Examples/python/pointer/index.html @@ -144,7 +144,7 @@ extraction. diff --git a/Examples/ruby/pointer/index.html b/Examples/ruby/pointer/index.html index 2b9c40b35..c9d5b9c32 100644 --- a/Examples/ruby/pointer/index.html +++ b/Examples/ruby/pointer/index.html @@ -144,7 +144,7 @@ extraction. diff --git a/Examples/tcl/pointer/index.html b/Examples/tcl/pointer/index.html index 874088a72..407380240 100644 --- a/Examples/tcl/pointer/index.html +++ b/Examples/tcl/pointer/index.html @@ -144,7 +144,7 @@ extraction. diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 32e1b1617..9bb45d577 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -79,7 +79,7 @@ typedef struct { /* this is the struct for wrapping arbitary packed binary data (currently it is only used for member function pointers) the data ordering is similar to swig_lua_userdata, but it is currently not possible -to tell the two structures apart within Swig, other than by looking at the type +to tell the two structures apart within SWIG, other than by looking at the type */ typedef struct { swig_type_info *type; diff --git a/Lib/php/director.swg b/Lib/php/director.swg index 6a9d4df3c..b28f6dbd9 100644 --- a/Lib/php/director.swg +++ b/Lib/php/director.swg @@ -168,7 +168,7 @@ namespace Swig { { public: DirectorPureVirtualException(const char* msg) - : DirectorException(E_ERROR, "Swig director pure virtual method called", msg) + : DirectorException(E_ERROR, "SWIG director pure virtual method called", msg) { } @@ -182,7 +182,7 @@ namespace Swig { { public: DirectorMethodException(const char* msg = "") - : DirectorException(E_ERROR, "Swig director method error", msg) + : DirectorException(E_ERROR, "SWIG director method error", msg) { } diff --git a/Lib/python/director.swg b/Lib/python/director.swg index ba9144539..f3855babe 100644 --- a/Lib/python/director.swg +++ b/Lib/python/director.swg @@ -237,7 +237,7 @@ namespace Swig { try { throw; } catch (DirectorException& e) { - std::cerr << "Swig Director exception caught:" << std::endl + std::cerr << "SWIG Director exception caught:" << std::endl << e.getMessage() << std::endl; } catch (std::exception& e) { std::cerr << "std::exception caught: "<< e.what() << std::endl; @@ -276,12 +276,12 @@ namespace Swig { class DirectorTypeMismatchException : public Swig::DirectorException { public: DirectorTypeMismatchException(PyObject *error, const char* msg="") - : Swig::DirectorException(error, "Swig director type mismatch", msg) + : Swig::DirectorException(error, "SWIG director type mismatch", msg) { } DirectorTypeMismatchException(const char* msg="") - : Swig::DirectorException(PyExc_TypeError, "Swig director type mismatch", msg) + : Swig::DirectorException(PyExc_TypeError, "SWIG director type mismatch", msg) { } @@ -300,7 +300,7 @@ namespace Swig { class DirectorMethodException : public Swig::DirectorException { public: DirectorMethodException(const char* msg = "") - : DirectorException(PyExc_RuntimeError, "Swig director method error.", msg) + : DirectorException(PyExc_RuntimeError, "SWIG director method error.", msg) { } @@ -315,7 +315,7 @@ namespace Swig { { public: DirectorPureVirtualException(const char* msg = "") - : DirectorException(PyExc_RuntimeError, "Swig director pure virtual method called", msg) + : DirectorException(PyExc_RuntimeError, "SWIG director pure virtual method called", msg) { } diff --git a/Lib/ruby/director.swg b/Lib/ruby/director.swg index 9a6371ad9..76969cadc 100644 --- a/Lib/ruby/director.swg +++ b/Lib/ruby/director.swg @@ -176,7 +176,7 @@ namespace Swig { try { throw; } catch (DirectorException& e) { - std::cerr << "Swig Director exception caught:" << std::endl + std::cerr << "SWIG Director exception caught:" << std::endl << e.getMessage() << std::endl; } catch (std::exception& e) { std::cerr << "std::exception caught: "<< e.what() << std::endl; @@ -212,12 +212,12 @@ namespace Swig { class DirectorTypeMismatchException : public Swig::DirectorException { public: DirectorTypeMismatchException(VALUE error, const char *msg="") - : Swig::DirectorException(error, "Swig director type mismatch", msg) + : Swig::DirectorException(error, "SWIG director type mismatch", msg) { } DirectorTypeMismatchException(const char *msg="") - : Swig::DirectorException(rb_eTypeError, "Swig director type mismatch", msg) + : Swig::DirectorException(rb_eTypeError, "SWIG director type mismatch", msg) { } @@ -238,7 +238,7 @@ namespace Swig { } DirectorMethodException(const char* msg = "") - : Swig::DirectorException(rb_eRuntimeError, "Swig director method error.", msg) { + : Swig::DirectorException(rb_eRuntimeError, "SWIG director method error.", msg) { } static void raise(VALUE error) @@ -252,7 +252,7 @@ namespace Swig { { public: DirectorPureVirtualException(const char* msg = "") - : DirectorException(rb_eRuntimeError, "Swig director pure virtual method called", msg) + : DirectorException(rb_eRuntimeError, "SWIG director pure virtual method called", msg) { } diff --git a/Lib/tcl/typemaps.i b/Lib/tcl/typemaps.i index 7c9e04a8b..2a8f1064a 100644 --- a/Lib/tcl/typemaps.i +++ b/Lib/tcl/typemaps.i @@ -4,8 +4,8 @@ * * typemaps.i * - * Swig typemap library for Tcl8. This file contains various sorts - * of typemaps for modifying Swig's code generation. + * SWIG typemap library for Tcl8. This file contains various sorts + * of typemaps for modifying SWIG's code generation. * ----------------------------------------------------------------------------- */ #if !defined(SWIG_USE_OLD_TYPEMAPS) diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg index 6d3e20223..ef6a346cc 100644 --- a/Lib/typemaps/fragments.swg +++ b/Lib/typemaps/fragments.swg @@ -444,15 +444,15 @@ SWIG_AsVal_dec(Type)(SWIG_Object obj, Type *val) %define %ensure_fragment(Fragment) %fragment(`Fragment`,"header") { -%#error "Swig language implementation must provide the Fragment fragment" +%#error "SWIG language implementation must provide the Fragment fragment" } %enddef %define %ensure_type_fragments(Type) %fragment(SWIG_From_frag(Type),"header") { -%#error "Swig language implementation must provide a SWIG_From_frag(Type) fragment" +%#error "SWIG language implementation must provide a SWIG_From_frag(Type) fragment" } %fragment(SWIG_AsVal_frag(Type),"header") { -%#error "Swig language implementation must provide a SWIG_AsVal_frag(Type) fragment" +%#error "SWIG language implementation must provide a SWIG_AsVal_frag(Type) fragment" } %enddef diff --git a/Lib/typemaps/swigmacros.swg b/Lib/typemaps/swigmacros.swg index 928f4ec0c..e95e7af92 100644 --- a/Lib/typemaps/swigmacros.swg +++ b/Lib/typemaps/swigmacros.swg @@ -20,7 +20,7 @@ Casting Operations: ------------------- - Swig provides the following casting macros, which implement the + SWIG provides the following casting macros, which implement the corresponding C++ casting operations: %const_cast(a, Type) const_cast(a) @@ -173,7 +173,7 @@ nocppval #endif /* __cplusplus */ /* ----------------------------------------------------------------------------- - * Swig names and mangling + * SWIG names and mangling * ----------------------------------------------------------------------------- */ #define %mangle(Type...) #@Type @@ -210,7 +210,7 @@ nocppval %define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef /* ----------------------------------------------------------------------------- - * Swig flags + * SWIG flags * ----------------------------------------------------------------------------- */ /* diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx index b14dddd22..7440d906a 100644 --- a/Source/Modules/modula3.cxx +++ b/Source/Modules/modula3.cxx @@ -81,7 +81,7 @@ char cvsroot_modula3_cxx[] = "$Id$"; that assign special purposes to the array types. - Can one interpret $n_basetype as the identifier matched with SWIGTYPE ? - Swig's odds: + SWIG's odds: - arguments of type (Node *) for SWIG functions should be most often better (const Node *): Swig_symbol_qualified, Getattr, nodeType, parentNode diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c index 81646171a..7958b4e09 100644 --- a/Source/Preprocessor/cpp.c +++ b/Source/Preprocessor/cpp.c @@ -1648,7 +1648,7 @@ String *Preprocessor_parse(String *s) { state = 0; break; - /* Swig directives */ + /* SWIG directives */ case 100: /* %{,%} block */ if (c == '{') { @@ -1713,7 +1713,7 @@ String *Preprocessor_parse(String *s) { case 110: if (!isidchar(c)) { Ungetc(c, s); - /* Look for common Swig directives */ + /* Look for common SWIG directives */ if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport) || Equal(decl, kpp_dextern)) { /* Got some kind of file inclusion directive */ if (allow) { From 415d2b6fe923b30ab526d6ed3a69cf78290643b7 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sat, 29 Aug 2009 06:53:25 +0000 Subject: [PATCH 020/146] [Perl] Remove bogus assertion (patch from David Fletcher). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11671 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 2 ++ Lib/perl5/perlrun.swg | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index 99cade363..8414f06c9 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,3 +1,5 @@ Version 1.3.41 (in progress) ============================ +2009-08-29: olly + [Perl] Remove bogus assertion (patch from David Fletcher). diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg index be788f540..94bc5e48c 100644 --- a/Lib/perl5/perlrun.swg +++ b/Lib/perl5/perlrun.swg @@ -293,7 +293,6 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_ int newmemory = 0; *ptr = SWIG_TypeCast(tc,voidptr,&newmemory); if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); if (own) *own = *own | SWIG_CAST_NEW_MEMORY; } From 6edbe9cdc2b59d327d28f983be1724dc87a8791a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 29 Aug 2009 10:09:01 +0000 Subject: [PATCH 021/146] extra white space helps disambiguate the expression which some compilers/tools complain about - patch from David Fletcher git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11672 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/perl5/perlrun.swg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg index 94bc5e48c..983633355 100644 --- a/Lib/perl5/perlrun.swg +++ b/Lib/perl5/perlrun.swg @@ -310,7 +310,7 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_ */ SV *obj = sv; HV *stash = SvSTASH(SvRV(obj)); - GV *gv = *(GV**) hv_fetch(stash, "OWNER", 5, TRUE); + GV *gv = *(GV**)hv_fetch(stash, "OWNER", 5, TRUE); if (isGV(gv)) { HV *hv = GvHVn(gv); /* @@ -341,7 +341,7 @@ SWIG_Perl_MakePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, swig_type_info *t, i stash=SvSTASH(SvRV(obj)); if (flags & SWIG_POINTER_OWN) { HV *hv; - GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE); + GV *gv = *(GV**)hv_fetch(stash, "OWNER", 5, TRUE); if (!isGV(gv)) gv_init(gv, stash, "OWNER", 5, FALSE); hv=GvHVn(gv); From 7908bb2dc3e21bb3d27b24cfdee2683d3fcd3deb Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 29 Aug 2009 10:41:06 +0000 Subject: [PATCH 022/146] Add information about the SWIG test-suite git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11673 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Contents.html | 8 +- Doc/Manual/Extending.html | 239 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 237 insertions(+), 10 deletions(-) diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 85b1ab5f5..d6feb934f 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -1581,7 +1581,7 @@
    • Writing a Language Module
      • Execution model -
      • Starting out +
      • Starting out
      • Command line options
      • Configuration and preprocessing
      • Entry point to code generation @@ -1590,7 +1590,11 @@
      • Configuration files
      • Runtime support
      • Standard library files -
      • Examples and test cases +
      • User examples +
      • Test driven development and the test-suite +
      • Documentation
      • Prerequisites for adding a new language module to the SWIG distribution
      • Coding style guidelines diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index 0ebaeaa04..c56647450 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -48,7 +48,7 @@
      • Writing a Language Module
        • Execution model -
        • Starting out +
        • Starting out
        • Command line options
        • Configuration and preprocessing
        • Entry point to code generation @@ -57,7 +57,11 @@
        • Configuration files
        • Runtime support
        • Standard library files -
        • Examples and test cases +
        • User examples +
        • Test driven development and the test-suite +
        • Documentation
        • Prerequisites for adding a new language module to the SWIG distribution
        • Coding style guidelines @@ -2471,7 +2475,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.

          -

          35.10.2 Starting out

          +

          35.10.2 Starting out

          @@ -3053,7 +3057,7 @@ but without the typemaps, there is still work to do.

          -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 @@ -3225,7 +3229,7 @@ The following are the minimum that are usually supported: Please copy these and modify for any new language.

          -

          35.10.11 Examples and test cases

          +

          35.10.11 User examples

          @@ -3254,7 +3258,226 @@ during this process, see the section on configuration files.

          -

          35.10.12 Documentation

          +

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

          + +

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

          35.10.13 Documentation

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

        -

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

        +

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

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

        -

        35.10.14 Coding style guidelines

        +

        35.10.15 Coding style guidelines

        From 968eb8287a0cb0c622291653d6b495d79c92e207 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Sep 2009 17:30:17 +0000 Subject: [PATCH 023/146] correction to SWIGTOOL usage git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11675 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 4c469ded0..f98067c5d 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -28,12 +28,14 @@ # The 'clean' target cleans up. # # Note that the RUNTOOL, COMPILETOOL and SWIGTOOL variables can be used -# for # invoking tools for the runtime tests and target language +# for invoking tools for the runtime tests and target language # compiler (eg javac) respectively. For example, valgrind can be used # for memory checking of the runtime tests using: -# make RUNTOOL="valgrind --leak-check-full" +# make RUNTOOL="valgrind --leak-check=full" # and valgrind can be used when invoking SWIG using: -# make SWIGTOOL="valgrind --tool=memcheck" +# make SWIGTOOL="valgrind --tool=memcheck --trace-children=yes" +# Note: trace-children needed because of preinst-swig shell wrapper +# to the swig executable. # # The variables below can be overridden after including this makefile ####################################################################### From d841f7a66c465a43aa3f849c5f4d75da89b2971e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 2 Sep 2009 20:49:55 +0000 Subject: [PATCH 024/146] fix overloading of jboolean with other JNI types at the c++ level for some platforms (64bit Linux) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11676 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/java/java_jnitypes_runme.java | 2 +- Examples/test-suite/java_jnitypes.i | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/java/java_jnitypes_runme.java b/Examples/test-suite/java/java_jnitypes_runme.java index 40395cef1..3e9d9e4c5 100644 --- a/Examples/test-suite/java/java_jnitypes_runme.java +++ b/Examples/test-suite/java/java_jnitypes_runme.java @@ -28,7 +28,7 @@ public class java_jnitypes_runme { double doubleArray[] = new double[] {10.0, 20.0}; Test objectArray[] = new Test[] {new Test(), test}; - if (java_jnitypes.jnifunc(true) != true) testFailed("jboolean"); + if (java_jnitypes.jnifunc_bool(true) != true) testFailed("jboolean"); if (java_jnitypes.jnifunc('A') != 'A') testFailed("jchar"); if (java_jnitypes.jnifunc((byte)100) != (byte)100) testFailed("jbyte"); if (java_jnitypes.jnifunc((short)100) != (short)100) testFailed("jshort"); diff --git a/Examples/test-suite/java_jnitypes.i b/Examples/test-suite/java_jnitypes.i index bc405793d..90970d1b2 100644 --- a/Examples/test-suite/java_jnitypes.i +++ b/Examples/test-suite/java_jnitypes.i @@ -5,7 +5,7 @@ %inline %{ -jboolean jnifunc(jboolean in) { return in; } +jboolean jnifunc_bool(jboolean in) { return in; } /* some JVM implementations won't allow overloading of the jboolean type with some of the others on the c++ level */ jchar jnifunc(jchar in) { return in; } jbyte jnifunc(jbyte in) { return in; } jshort jnifunc(jshort in) { return in; } From 7c6aca2ebc2c55cb9c7e25d8201e5b4bdb0907b2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 2 Sep 2009 22:33:04 +0000 Subject: [PATCH 025/146] true and false supported in constant expressions (C++ only). && || == != < > <= >= operators now return type bool (C++ only) and type int for C as per C/C++ standards. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11677 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 17 ++++ Examples/test-suite/common.mk | 2 + .../csharp/preproc_constants_c_runme.cs | 68 +++++++++++++++ .../csharp/preproc_constants_runme.cs | 67 +++++++++++++++ Examples/test-suite/preproc_constants.i | 82 +++++++++++++++++++ Examples/test-suite/preproc_constants_c.i | 6 ++ Source/CParse/cscanner.c | 8 +- Source/CParse/parser.y | 19 +++-- Source/Swig/scanner.c | 21 +++-- Source/Swig/swigscan.h | 1 + 10 files changed, 276 insertions(+), 15 deletions(-) create mode 100644 Examples/test-suite/csharp/preproc_constants_c_runme.cs create mode 100644 Examples/test-suite/csharp/preproc_constants_runme.cs create mode 100644 Examples/test-suite/preproc_constants.i create mode 100644 Examples/test-suite/preproc_constants_c.i diff --git a/CHANGES.current b/CHANGES.current index 8414f06c9..26f1434e1 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,5 +1,22 @@ Version 1.3.41 (in progress) ============================ +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 + 2009-08-29: olly [Perl] Remove bogus assertion (patch from David Fletcher). diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index f98067c5d..4bbf74525 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -257,6 +257,7 @@ CPP_TEST_CASES += \ overload_template \ overload_template_fast \ pointer_reference \ + preproc_constants \ primitive_ref \ private_assign \ protected_rename \ @@ -456,6 +457,7 @@ C_TEST_CASES += \ overload_extend \ overload_extendc \ preproc \ + preproc_constants_c \ ret_by_value \ simple_array \ sizeof_pointer \ diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs new file mode 100644 index 000000000..71cf697f7 --- /dev/null +++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs @@ -0,0 +1,68 @@ +using System; +using System.Reflection; +using preproc_constants_cNamespace; + +// Same as preproc_constants_c.i testcase, but bool types are int instead +public class runme { + static void Main() { + assert( typeof(int) == preproc_constants_c.CONST_INT1.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_INT2.GetType() ); + assert( typeof(uint) == preproc_constants_c.CONST_UINT1.GetType() ); + assert( typeof(uint) == preproc_constants_c.CONST_UINT2.GetType() ); + assert( typeof(uint) == preproc_constants_c.CONST_UINT3.GetType() ); + assert( typeof(uint) == preproc_constants_c.CONST_UINT4.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_LONG1.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_LONG2.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_LONG3.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_LONG4.GetType() ); + assert( typeof(long) == preproc_constants_c.CONST_LLONG1.GetType() ); + assert( typeof(long) == preproc_constants_c.CONST_LLONG2.GetType() ); + assert( typeof(long) == preproc_constants_c.CONST_LLONG3.GetType() ); + assert( typeof(long) == preproc_constants_c.CONST_LLONG4.GetType() ); + assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG1.GetType() ); + assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG2.GetType() ); + assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG3.GetType() ); + assert( typeof(ulong) == preproc_constants_c.CONST_ULLONG4.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE1.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE2.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE3.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE4.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE5.GetType() ); + assert( typeof(double) == preproc_constants_c.CONST_DOUBLE6.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_BOOL1.GetType() ); + assert( typeof(int) == preproc_constants_c.CONST_BOOL2.GetType() ); + assert( typeof(char) == preproc_constants_c.CONST_CHAR.GetType() ); + assert( typeof(string) == preproc_constants_c.CONST_STRING1.GetType() ); + assert( typeof(string) == preproc_constants_c.CONST_STRING2.GetType() ); + + assert( typeof(int) == preproc_constants_c.INT_AND_BOOL.GetType() ); +// assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() ); + assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() ); + assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() ); + assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() ); + assert( typeof(uint) == preproc_constants_c.INT_AND_ULONG.GetType() ); + assert( typeof(long) == preproc_constants_c.INT_AND_LLONG.GetType() ); + assert( typeof(ulong) == preproc_constants_c.INT_AND_ULLONG.GetType() ); + assert( typeof(int ) == preproc_constants_c.BOOL_AND_BOOL.GetType() ); + + assert( typeof(int) == preproc_constants_c.EXPR_MULTIPLY.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_DIVIDE.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_PLUS.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_EQUALITY.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_AND.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_XOR.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_OR.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_LAND.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_LOR.GetType() ); + assert( typeof(double) == preproc_constants_c.EXPR_CONDITIONAL.GetType() ); + + } + static void assert(bool assertion) { + if (!assertion) + throw new ApplicationException("test failed"); + } +} diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs new file mode 100644 index 000000000..b2c6c62ae --- /dev/null +++ b/Examples/test-suite/csharp/preproc_constants_runme.cs @@ -0,0 +1,67 @@ +using System; +using System.Reflection; +using preproc_constantsNamespace; + +public class runme { + static void Main() { + assert( typeof(int) == preproc_constants.CONST_INT1.GetType() ); + assert( typeof(int) == preproc_constants.CONST_INT2.GetType() ); + assert( typeof(uint) == preproc_constants.CONST_UINT1.GetType() ); + assert( typeof(uint) == preproc_constants.CONST_UINT2.GetType() ); + assert( typeof(uint) == preproc_constants.CONST_UINT3.GetType() ); + assert( typeof(uint) == preproc_constants.CONST_UINT4.GetType() ); + assert( typeof(int) == preproc_constants.CONST_LONG1.GetType() ); + assert( typeof(int) == preproc_constants.CONST_LONG2.GetType() ); + assert( typeof(int) == preproc_constants.CONST_LONG3.GetType() ); + assert( typeof(int) == preproc_constants.CONST_LONG4.GetType() ); + assert( typeof(long) == preproc_constants.CONST_LLONG1.GetType() ); + assert( typeof(long) == preproc_constants.CONST_LLONG2.GetType() ); + assert( typeof(long) == preproc_constants.CONST_LLONG3.GetType() ); + assert( typeof(long) == preproc_constants.CONST_LLONG4.GetType() ); + assert( typeof(ulong) == preproc_constants.CONST_ULLONG1.GetType() ); + assert( typeof(ulong) == preproc_constants.CONST_ULLONG2.GetType() ); + assert( typeof(ulong) == preproc_constants.CONST_ULLONG3.GetType() ); + assert( typeof(ulong) == preproc_constants.CONST_ULLONG4.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE1.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE2.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE3.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE4.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE5.GetType() ); + assert( typeof(double) == preproc_constants.CONST_DOUBLE6.GetType() ); + assert( typeof(bool) == preproc_constants.CONST_BOOL1.GetType() ); + assert( typeof(bool) == preproc_constants.CONST_BOOL2.GetType() ); + assert( typeof(char) == preproc_constants.CONST_CHAR.GetType() ); + assert( typeof(string) == preproc_constants.CONST_STRING1.GetType() ); + assert( typeof(string) == preproc_constants.CONST_STRING2.GetType() ); + + assert( typeof(int) == preproc_constants.INT_AND_BOOL.GetType() ); +// assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() ); + assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() ); + assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() ); + assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() ); + assert( typeof(uint) == preproc_constants.INT_AND_ULONG.GetType() ); + assert( typeof(long) == preproc_constants.INT_AND_LLONG.GetType() ); + assert( typeof(ulong) == preproc_constants.INT_AND_ULLONG.GetType() ); + assert( typeof(int ) == preproc_constants.BOOL_AND_BOOL.GetType() ); + + assert( typeof(int) == preproc_constants.EXPR_MULTIPLY.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_DIVIDE.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_PLUS.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_EQUALITY.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_AND.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_XOR.GetType() ); + assert( typeof(int) == preproc_constants.EXPR_OR.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_LAND.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_LOR.GetType() ); + assert( typeof(double) == preproc_constants.EXPR_CONDITIONAL.GetType() ); + + } + static void assert(bool assertion) { + if (!assertion) + throw new ApplicationException("test failed"); + } +} diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i new file mode 100644 index 000000000..b759d8a75 --- /dev/null +++ b/Examples/test-suite/preproc_constants.i @@ -0,0 +1,82 @@ +%module preproc_constants + +// Note: C types are slightly different to C++ types as (a && b) is int in C and bool in C++ + +// Simple constants +#define CONST_INT1 10 +#define CONST_INT2 0xFF + +#define CONST_UINT1 10u +#define CONST_UINT2 10U +#define CONST_UINT3 0xFFu +#define CONST_UINT4 0xFFU + +#define CONST_LONG1 10l +#define CONST_LONG2 10L +#define CONST_LONG3 0xFFl +#define CONST_LONG4 0xFFL + +#define CONST_LLONG1 10LL +#define CONST_LLONG2 10ll +#define CONST_LLONG3 0xFFll +#define CONST_LLONG4 0xFFLL + +#define CONST_ULLONG1 10ull +#define CONST_ULLONG2 10ULL +#define CONST_ULLONG3 0xFFull +#define CONST_ULLONG4 0xFFULL + +#define CONST_DOUBLE1 10e1 +#define CONST_DOUBLE2 10E1 +#define CONST_DOUBLE3 12.3 +#define CONST_DOUBLE4 12. +#define CONST_DOUBLE5 12.3f +#define CONST_DOUBLE6 12.3F + +#define CONST_BOOL1 true +#define CONST_BOOL2 false + +#define CONST_CHAR 'x' +#define CONST_STRING1 "const string" +#define CONST_STRING2 "const" " string" + +// Expressions - runtime tests check the type for any necessary type promotions of the expressions + +#define INT_AND_BOOL 0xFF & true +//#define INT_AND_CHAR 0xFF & 'A' /* FIXME compile error */ +#define INT_AND_INT 0xFF & 2 +#define INT_AND_UINT 0xFF & 2u +#define INT_AND_LONG 0xFF & 2l +#define INT_AND_ULONG 0xFF & 2ul +#define INT_AND_LLONG 0xFF & 2ll +#define INT_AND_ULLONG 0xFF & 2ull + +#define BOOL_AND_BOOL true & true // Note integral promotion to type int +//#define CHAR_AND_CHAR 'A' & 'B' // Note integral promotion to type int +/* FIXME ABOVE */ + + +#define EXPR_MULTIPLY 0xFF * 2 +#define EXPR_DIVIDE 0xFF / 2 +//FIXME #define EXPR_MOD 0xFF % 2 + +#define EXPR_PLUS 0xFF + 2 +#define EXPR_MINUS 0xFF + 2 + +#define EXPR_LSHIFT 0xFF << 2 +#define EXPR_RSHIFT 0xFF >> 2 +/* FIXME +#define EXPR_LT 0xFF < 255 +#define EXPR_GT 0xFF > 255 +#define EXPR_LTE 0xFF <= 255 +#define EXPR_LGE 0xFF >= 255 +*/ +#define EXPR_INEQUALITY 0xFF != 255 +#define EXPR_EQUALITY 0xFF == 255 +#define EXPR_AND 0xFF & 1 +#define EXPR_XOR 0xFF ^ 1 +#define EXPR_OR 0xFF | 1 +#define EXPR_LAND 0xFF && 1 +#define EXPR_LOR 0xFF || 1 +#define EXPR_CONDITIONAL true ? 2 : 2.2 + diff --git a/Examples/test-suite/preproc_constants_c.i b/Examples/test-suite/preproc_constants_c.i new file mode 100644 index 000000000..e27d1f508 --- /dev/null +++ b/Examples/test-suite/preproc_constants_c.i @@ -0,0 +1,6 @@ +%module preproc_constants_c + +%define true 1 %enddef +%define false 0 %enddef + +%include "preproc_constants.i" diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index 8734c7d0e..b5c485f5d 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -257,7 +257,7 @@ void skip_decl(void) { * Lexical scanner. * ------------------------------------------------------------------------- */ -int yylook(void) { +static int yylook(void) { int tok = 0; @@ -410,6 +410,9 @@ int yylook(void) { case SWIG_TOKEN_FLOAT: return NUM_FLOAT; + case SWIG_TOKEN_BOOL: + return NUM_BOOL; + case SWIG_TOKEN_POUND: Scanner_skip_line(scan); yylval.id = Swig_copy_string(Char(Scanner_text(scan))); @@ -525,6 +528,7 @@ int yylex(void) { case NUM_UNSIGNED: case NUM_LONGLONG: case NUM_ULONGLONG: + case NUM_BOOL: if (l == NUM_INT) yylval.dtype.type = T_INT; if (l == NUM_FLOAT) @@ -539,6 +543,8 @@ int yylex(void) { yylval.dtype.type = T_LONGLONG; if (l == NUM_ULONGLONG) yylval.dtype.type = T_ULONGLONG; + if (l == NUM_BOOL) + yylval.dtype.type = T_BOOL; yylval.dtype.val = NewString(Scanner_text(scan)); yylval.dtype.bitfield = 0; yylval.dtype.throws = 0; diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 7c33e5459..88e6a2005 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1486,7 +1486,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %token STRING %token INCLUDE IMPORT INSERT %token CHARCONST -%token NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG +%token NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL %token TYPEDEF %token TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64 %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD @@ -5547,6 +5547,7 @@ exprnum : NUM_INT { $$ = $1; } | NUM_ULONG { $$ = $1; } | NUM_LONGLONG { $$ = $1; } | NUM_ULONGLONG { $$ = $1; } + | NUM_BOOL { $$ = $1; } ; exprcompound : expr PLUS expr { @@ -5591,28 +5592,28 @@ exprcompound : expr PLUS expr { } | expr LAND expr { $$.val = NewStringf("%s&&%s",$1.val,$3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LOR expr { $$.val = NewStringf("%s||%s",$1.val,$3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr EQUALTO expr { $$.val = NewStringf("%s==%s",$1.val,$3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr NOTEQUALTO expr { $$.val = NewStringf("%s!=%s",$1.val,$3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these. | expr GREATERTHAN expr { $$.val = NewStringf("%s SWIG_LT %s", $1.val, $3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LESSTHAN expr { $$.val = NewStringf("%s SWIG_GT %s", $1.val, $3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } */ | expr GREATERTHANOREQUALTO expr { @@ -5620,11 +5621,11 @@ exprcompound : expr PLUS expr { * loop somewhere in the type system. Just workaround for now * - SWIG_GE is defined in swiglabels.swg. */ $$.val = NewStringf("%s SWIG_GE %s", $1.val, $3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LESSTHANOREQUALTO expr { $$.val = NewStringf("%s SWIG_LE %s", $1.val, $3.val); - $$.type = T_INT; + $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { $$.val = NewStringf("%s?%s:%s", $1.val, $3.val, $5.val); diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c index 3de794fdc..507c8c748 100644 --- a/Source/Swig/scanner.c +++ b/Source/Swig/scanner.c @@ -16,7 +16,8 @@ char cvsroot_scanner_c[] = "$Id$"; #include extern String *cparse_file; -extern int cparse_start_line; +extern int cparse_cplusplus; +extern int cparse_start_line; struct Scanner { String *text; /* Current token value */ @@ -730,15 +731,25 @@ static int look(Scanner * s) { break; case 7: /* Identifier */ if ((c = nextchar(s)) == 0) - return SWIG_TOKEN_ID; - if (isalnum(c) || (c == '_') || (c == '$')) { + state = 71; + else if (isalnum(c) || (c == '_') || (c == '$')) { state = 7; } else { retract(s, 1); - return SWIG_TOKEN_ID; + state = 71; } break; + case 71: /* Identifier or true/false */ + if (cparse_cplusplus) { + if (Strcmp(s->text, "true") == 0) + return SWIG_TOKEN_BOOL; + else if (Strcmp(s->text, "false") == 0) + return SWIG_TOKEN_BOOL; + } + return SWIG_TOKEN_ID; + break; + case 75: /* Special identifier $ */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_DOLLAR; @@ -747,7 +758,7 @@ static int look(Scanner * s) { } else { retract(s,1); if (Len(s->text) == 1) return SWIG_TOKEN_DOLLAR; - return SWIG_TOKEN_ID; + state = 71; } break; diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h index 3403098df..2adf7b2be 100644 --- a/Source/Swig/swigscan.h +++ b/Source/Swig/swigscan.h @@ -64,6 +64,7 @@ extern void Scanner_freeze_line(Scanner *s, int val); #define SWIG_TOKEN_ULONGLONG 29 /* 314ULL */ #define SWIG_TOKEN_QUESTION 30 /* ? */ #define SWIG_TOKEN_COMMENT 31 /* C or C++ comment */ +#define SWIG_TOKEN_BOOL 32 /* true or false */ #define SWIG_TOKEN_ILLEGAL 99 #define SWIG_TOKEN_ERROR -1 From 49935ee9524db96e00f7125834956c1fd83927cb Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 2 Sep 2009 22:35:55 +0000 Subject: [PATCH 026/146] Fix director exception testcase since exception message recently changed slightly git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11678 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/python/director_exception_runme.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/test-suite/python/director_exception_runme.py b/Examples/test-suite/python/director_exception_runme.py index ef7a044f1..82be1289b 100644 --- a/Examples/test-suite/python/director_exception_runme.py +++ b/Examples/test-suite/python/director_exception_runme.py @@ -43,7 +43,7 @@ b = launder(a) try: b.pong() except TypeError, e: - if str(e) == "Swig director type mismatch in output value of type 'std::string'": + if str(e) == "SWIG director type mismatch in output value of type 'std::string'": ok = 1 else: print "Unexpected error message: %s" % str(e) From fddbb30848a8c9fc12a9739d436371f1cc5c08ee Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Sep 2009 11:31:39 +0000 Subject: [PATCH 027/146] Revert removal of assertion. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11680 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 2 -- Lib/perl5/perlrun.swg | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 26f1434e1..6e7e6ba1a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -18,5 +18,3 @@ Version 1.3.41 (in progress) #define FOO true #define BAR FOO && false -2009-08-29: olly - [Perl] Remove bogus assertion (patch from David Fletcher). diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg index 983633355..b506c3af9 100644 --- a/Lib/perl5/perlrun.swg +++ b/Lib/perl5/perlrun.swg @@ -293,6 +293,7 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_ int newmemory = 0; *ptr = SWIG_TypeCast(tc,voidptr,&newmemory); if (newmemory == SWIG_CAST_NEW_MEMORY) { + assert(own); if (own) *own = *own | SWIG_CAST_NEW_MEMORY; } From 719cfe68bf161cf65a529da3138d3a12a3907304 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 7 Sep 2009 06:17:40 +0000 Subject: [PATCH 028/146] add some useful info for assert around SWIG_CAST_NEW_MEMORY git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11686 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/perl5/perlrun.swg | 2 +- Lib/python/pyrun.swg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg index b506c3af9..ecb1f5cd2 100644 --- a/Lib/perl5/perlrun.swg +++ b/Lib/perl5/perlrun.swg @@ -293,7 +293,7 @@ SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_ int newmemory = 0; *ptr = SWIG_TypeCast(tc,voidptr,&newmemory); if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); + assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ if (own) *own = *own | SWIG_CAST_NEW_MEMORY; } diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg index 21fddb610..c0d30ee45 100644 --- a/Lib/python/pyrun.swg +++ b/Lib/python/pyrun.swg @@ -1089,7 +1089,7 @@ SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int int newmemory = 0; *ptr = SWIG_TypeCast(tc,vptr,&newmemory); if (newmemory == SWIG_CAST_NEW_MEMORY) { - assert(own); + assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */ if (own) *own = *own | SWIG_CAST_NEW_MEMORY; } From 2726424a7f4479682858f56fe54640d42a856a1c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 11 Sep 2009 18:47:05 +0000 Subject: [PATCH 029/146] Fix constant expressions containing <= or >= git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11687 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 +++ Doc/Manual/Library.html | 4 ++-- Examples/test-suite/csharp/preproc_constants_c_runme.cs | 2 ++ Examples/test-suite/csharp/preproc_constants_runme.cs | 2 ++ Examples/test-suite/preproc_constants.i | 4 ++-- Source/CParse/parser.y | 4 ++-- 6 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 6e7e6ba1a..5db53b965 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +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: diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index 7293f31fe..eaebbede5 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -667,7 +667,7 @@ in order for this to work.

        -char *cdata(void *ptr, int nbytes) +const char *cdata(void *ptr, size_t nbytes)

        @@ -676,7 +676,7 @@ pointer.

        -void memmove(void *ptr, char *s) +void memmove(void *ptr, const char *s)

        diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs index 71cf697f7..76c684d85 100644 --- a/Examples/test-suite/csharp/preproc_constants_c_runme.cs +++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs @@ -51,6 +51,8 @@ public class runme { assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() ); + assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_EQUALITY.GetType() ); assert( typeof(int) == preproc_constants_c.EXPR_AND.GetType() ); diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs index b2c6c62ae..9fae5914a 100644 --- a/Examples/test-suite/csharp/preproc_constants_runme.cs +++ b/Examples/test-suite/csharp/preproc_constants_runme.cs @@ -50,6 +50,8 @@ public class runme { assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() ); assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() ); assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() ); + assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() ); assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() ); assert( typeof(bool) == preproc_constants.EXPR_EQUALITY.GetType() ); assert( typeof(int) == preproc_constants.EXPR_AND.GetType() ); diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i index b759d8a75..771f3db1b 100644 --- a/Examples/test-suite/preproc_constants.i +++ b/Examples/test-suite/preproc_constants.i @@ -68,9 +68,9 @@ /* FIXME #define EXPR_LT 0xFF < 255 #define EXPR_GT 0xFF > 255 -#define EXPR_LTE 0xFF <= 255 -#define EXPR_LGE 0xFF >= 255 */ +#define EXPR_LTE 0xFF <= 255 +#define EXPR_GTE 0xFF >= 255 #define EXPR_INEQUALITY 0xFF != 255 #define EXPR_EQUALITY 0xFF == 255 #define EXPR_AND 0xFF & 1 diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 88e6a2005..99453b2fd 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -5620,11 +5620,11 @@ exprcompound : expr PLUS expr { /* Putting >= in the expression literally causes an infinite * loop somewhere in the type system. Just workaround for now * - SWIG_GE is defined in swiglabels.swg. */ - $$.val = NewStringf("%s SWIG_GE %s", $1.val, $3.val); + $$.val = NewStringf("%s >= %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LESSTHANOREQUALTO expr { - $$.val = NewStringf("%s SWIG_LE %s", $1.val, $3.val); + $$.val = NewStringf("%s <= %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK { From a2229a45fc62cc6f6e0d6fa03819183c85f392b1 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 11 Sep 2009 18:53:14 +0000 Subject: [PATCH 030/146] Fix memmove regression git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11688 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 +++ Examples/test-suite/li_cdata.i | 2 +- Examples/test-suite/python/li_cdata_runme.py | 10 ++++++++++ Lib/cdata.i | 3 ++- Lib/typemaps/cdata.swg | 5 +++-- 5 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 Examples/test-suite/python/li_cdata_runme.py diff --git a/CHANGES.current b/CHANGES.current index 5db53b965..d86107ca2 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +2009-09-11: wsfulton + Fix memmove regression in cdata.i as reported by Adriaan Renting. + 2009-09-07: wsfulton Fix constant expressions containing <= or >=. diff --git a/Examples/test-suite/li_cdata.i b/Examples/test-suite/li_cdata.i index 6ce006d3b..2180af96e 100644 --- a/Examples/test-suite/li_cdata.i +++ b/Examples/test-suite/li_cdata.i @@ -5,4 +5,4 @@ %cdata(int); %cdata(double); - +void *malloc(size_t size); diff --git a/Examples/test-suite/python/li_cdata_runme.py b/Examples/test-suite/python/li_cdata_runme.py new file mode 100644 index 000000000..061ca6f68 --- /dev/null +++ b/Examples/test-suite/python/li_cdata_runme.py @@ -0,0 +1,10 @@ + +from li_cdata import * + +s = "ABC abc" +m = malloc(256) +memmove(m, s) +ss = cdata(m, 7) +if ss != "ABC abc": + raise "failed" + diff --git a/Lib/cdata.i b/Lib/cdata.i index 67601f737..b970b1d5d 100644 --- a/Lib/cdata.i +++ b/Lib/cdata.i @@ -79,5 +79,6 @@ SWIGCDATA cdata_##NAME(TYPE *ptr, int nelements); %cdata(void); -/* Memory move function */ +/* Memory move function. Due to multi-argument typemaps this appears to be wrapped as +void memmove(void *data, const char *s); */ void memmove(void *data, const void *indata, int inlen); diff --git a/Lib/typemaps/cdata.swg b/Lib/typemaps/cdata.swg index 32b3f5a77..cab53d31e 100644 --- a/Lib/typemaps/cdata.swg +++ b/Lib/typemaps/cdata.swg @@ -21,7 +21,7 @@ typedef struct SWIGCDATA { %typemap(out,noblock=1,fragment="SWIG_FromCharPtrAndSize") SWIGCDATA { %set_output(SWIG_FromCharPtrAndSize($1.data,$1.len)); } -%typemap(in) (const void *indata, int inlen) = (char *STRING, int SIZE); +%typemap(in) (const void *indata, size_t inlen) = (char *STRING, size_t SIZE); /* ----------------------------------------------------------------------------- @@ -70,7 +70,8 @@ SWIGCDATA cdata_##NAME(TYPE *ptr, size_t nelements = 1); %cdata(void); -/* Memory move function */ +/* Memory move function. Due to multi-argument typemaps this appears to be wrapped as +void memmove(void *data, const char *s); */ void memmove(void *data, const void *indata, size_t inlen); From 7df94f65e59c54c6ecca72269163a42eb3239f2f Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Sat, 12 Sep 2009 08:23:55 +0000 Subject: [PATCH 031/146] Clean-up remnants of SWIG_GE, etc workaround which is no longer used. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11689 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 99453b2fd..cc795bd4f 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -5608,18 +5608,15 @@ exprcompound : expr PLUS expr { } /* Sadly this causes 2 reduce-reduce conflicts with templates. FIXME resolve these. | expr GREATERTHAN expr { - $$.val = NewStringf("%s SWIG_LT %s", $1.val, $3.val); + $$.val = NewStringf("%s < %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } | expr LESSTHAN expr { - $$.val = NewStringf("%s SWIG_GT %s", $1.val, $3.val); + $$.val = NewStringf("%s > %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } */ | expr GREATERTHANOREQUALTO expr { - /* Putting >= in the expression literally causes an infinite - * loop somewhere in the type system. Just workaround for now - * - SWIG_GE is defined in swiglabels.swg. */ $$.val = NewStringf("%s >= %s", $1.val, $3.val); $$.type = cparse_cplusplus ? T_BOOL : T_INT; } From 4ebb9b0db23127b42dbb39209f16c9d3263b3b21 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 13 Sep 2009 20:20:11 +0000 Subject: [PATCH 032/146] minor rewrite of enum value handling git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11690 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 4 ++-- Source/Modules/csharp.cxx | 30 ++++++++++++++++-------------- Source/Modules/java.cxx | 23 ++++++++++++----------- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index cc795bd4f..8876384b1 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3127,8 +3127,8 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI { if (unnamedinstance) { SwigType *cty = NewString("enum "); Setattr($$,"type",cty); - Setattr($$,"unnamedinstance","1"); - Setattr(n,"unnamedinstance","1"); + SetFlag($$,"unnamedinstance"); + SetFlag(n,"unnamedinstance"); Delete(cty); } if ($8) { diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index b5444d4b4..7c0114928 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1211,6 +1211,9 @@ public: String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); String *name = Getattr(n, "name"); + Node *parent = parentNode(n); + int unnamedinstance = GetFlag(parent, "unnamedinstance"); + String *parent_name = Getattr(parent, "name"); String *tmpValue; // Strange hack from parent method @@ -1222,9 +1225,9 @@ public: Setattr(n, "value", tmpValue); { - EnumFeature enum_feature = decodeEnumFeature(parentNode(n)); + EnumFeature enum_feature = decodeEnumFeature(parent); - if ((enum_feature == ProperEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) { + if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { // Wrap (non-anonymous) C/C++ enum with a proper C# enum // Emit the enum item. if (!GetFlag(n, "firstenumitem")) @@ -1241,21 +1244,16 @@ public: } } else { // Wrap C/C++ enums with constant integers or use the typesafe enum pattern - const String *parent_name = Getattr(parentNode(n), "name"); - String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int"); + String *type = Getattr(n, "type"); /* should be int unless explicitly specified in a C++0x enum class */ + SwigType *typemap_lookup_type = parent_name ? parent_name : type; const String *tm = typemapLookup(n, "cstype", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF); + String *return_type = Copy(tm); - Delete(typemap_lookup_type); - typemap_lookup_type = NULL; - - // The %csconst feature determines how the constant value is obtained - int const_feature_flag = GetFlag(n, "feature:cs:const"); - const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) { - // Wrap (non-anonymouse) enum using the typesafe enum pattern + if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) { + // Wrap (non-anonymous) enum using the typesafe enum pattern if (Getattr(n, "enumvalue")) { String *value = enumValue(n); Printf(enum_code, " %s static readonly %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value); @@ -1267,6 +1265,10 @@ public: // Simple integer constants // Note these are always generated for anonymous enums, no matter what enum_feature is specified // Code generated is the same for SimpleEnum and TypeunsafeEnum -> the class it is generated into is determined later + + // The %csconst feature determines how the constant value is obtained + int const_feature_flag = GetFlag(n, "feature:cs:const"); + const char *const_readonly = const_feature_flag ? "const" : "static readonly"; String *value = enumValue(n); Printf(enum_code, " %s %s %s %s = %s;\n", methodmods, const_readonly, return_type, symname, value); @@ -1275,9 +1277,9 @@ public: } // Add the enum value to the comma separated list being constructed in the enum declaration. - String *enumvalues = Getattr(parentNode(n), "enumvalues"); + String *enumvalues = Getattr(parent, "enumvalues"); if (!enumvalues) - Setattr(parentNode(n), "enumvalues", Copy(symname)); + Setattr(parent, "enumvalues", Copy(symname)); else Printv(enumvalues, ", ", symname, NIL); } diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 9af6fc214..fd6c768c9 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1267,6 +1267,9 @@ public: String *symname = Getattr(n, "sym:name"); String *value = Getattr(n, "value"); String *name = Getattr(n, "name"); + Node *parent = parentNode(n); + int unnamedinstance = GetFlag(parent, "unnamedinstance"); + String *parent_name = Getattr(parent, "name"); String *tmpValue; // Strange hack from parent method @@ -1278,9 +1281,9 @@ public: Setattr(n, "value", tmpValue); { - EnumFeature enum_feature = decodeEnumFeature(parentNode(n)); + EnumFeature enum_feature = decodeEnumFeature(parent); - if ((enum_feature == ProperEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) { + if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { // Wrap (non-anonymous) C/C++ enum with a proper Java enum // Emit the enum item. if (!GetFlag(n, "firstenumitem")) @@ -1293,18 +1296,16 @@ public: } } else { // Wrap C/C++ enums with constant integers or use the typesafe enum pattern - const String *parent_name = Getattr(parentNode(n), "name"); - String *typemap_lookup_type = parent_name ? Copy(parent_name) : NewString("int"); + String *type = Getattr(n, "type"); /* should be int unless explicitly specified in a C++0x enum class */ + SwigType *typemap_lookup_type = parent_name ? parent_name : type; const String *tm = typemapLookup(n, "jstype", typemap_lookup_type, WARN_JAVA_TYPEMAP_JSTYPE_UNDEF); - String *return_type = Copy(tm); - Delete(typemap_lookup_type); - typemap_lookup_type = NULL; + String *return_type = Copy(tm); const String *methodmods = Getattr(n, "feature:java:methodmodifiers"); methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); - if ((enum_feature == TypesafeEnum) && Getattr(parentNode(n), "sym:name") && !Getattr(parentNode(n), "unnamedinstance")) { - // Wrap (non-anonymouse) enum using the typesafe enum pattern + if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) { + // Wrap (non-anonymous) enum using the typesafe enum pattern if (Getattr(n, "enumvalue")) { String *value = enumValue(n); Printf(enum_code, " %s final static %s %s = new %s(\"%s\", %s);\n", methodmods, return_type, symname, return_type, symname, value); @@ -1323,9 +1324,9 @@ public: } // Add the enum value to the comma separated list being constructed in the enum declaration. - String *enumvalues = Getattr(parentNode(n), "enumvalues"); + String *enumvalues = Getattr(parent, "enumvalues"); if (!enumvalues) - Setattr(parentNode(n), "enumvalues", Copy(symname)); + Setattr(parent, "enumvalues", Copy(symname)); else Printv(enumvalues, ", ", symname, NIL); } From 5eeab68e21a8b68c5025ab791a6ac2f7d28000ff Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 14 Sep 2009 19:37:55 +0000 Subject: [PATCH 033/146] Add %csattributes for adding C# attributes to enum values, see docs for example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11691 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 +++ .../csharp/csharp_attributes_runme.cs | 19 +++++++++++++++++++ Examples/test-suite/csharp_attributes.i | 4 ++++ Source/Modules/csharp.cxx | 8 ++++++++ 4 files changed, 34 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index d86107ca2..1f6de8059 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/csharp/csharp_attributes_runme.cs b/Examples/test-suite/csharp/csharp_attributes_runme.cs index 7dc9d7c87..3f4ea179a 100644 --- a/Examples/test-suite/csharp/csharp_attributes_runme.cs +++ b/Examples/test-suite/csharp/csharp_attributes_runme.cs @@ -1,5 +1,6 @@ using System; using System.Reflection; +using System.ComponentModel; using csharp_attributesNamespace; public class runme @@ -171,6 +172,24 @@ public class runme if (Attribute.GetCustomAttribute(member, typeof(Eurostar2Attribute)) == null) throw new Exception("No attribute for " + member.Name); } + // Enum value attributes + Type walesType = typeof(MoreStations.Wales); + { + MemberInfo member = (MemberInfo)walesType.GetMember("Cardiff")[0]; + DescriptionAttribute attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(System.ComponentModel.DescriptionAttribute)); + if (attribute == null) + throw new Exception("No attribute for " + member.Name); + if (attribute.Description != "Cardiff city station") + throw new Exception("Incorrect attribute value for " + member.Name); + } + { + MemberInfo member = (MemberInfo)walesType.GetMember("Swansea")[0]; + DescriptionAttribute attribute = (DescriptionAttribute)Attribute.GetCustomAttribute(member, typeof(System.ComponentModel.DescriptionAttribute)); + if (attribute == null) + throw new Exception("No attribute for " + member.Name); + if (attribute.Description != "Swansea city station") + throw new Exception("Incorrect attribute value for " + member.Name); + } // Enum csattribute typemap { Type cymrutype = typeof(Cymru); diff --git a/Examples/test-suite/csharp_attributes.i b/Examples/test-suite/csharp_attributes.i index 101e89732..e74f7422d 100644 --- a/Examples/test-suite/csharp_attributes.i +++ b/Examples/test-suite/csharp_attributes.i @@ -15,6 +15,8 @@ public: int GlobalFunction(int myInt) { return myInt; } %} +//%include "enumsimple.swg" +//%include "enumtypesafe.swg" // Test the attributes feature %csattributes MoreStations::MoreStations() "[InterCity1]" @@ -25,6 +27,8 @@ int GlobalFunction(int myInt) { return myInt; } %csattributes Wales "[InterCity6]" %csattributes Paddington() "[InterCity7]" %csattributes DidcotParkway "[InterCity8]" +%csattributes MoreStations::Cardiff "[System.ComponentModel.Description(\"Cardiff city station\")]" +%csattributes Swansea "[System.ComponentModel.Description(\"Swansea city station\")]" %typemap(csattributes) MoreStations "[Eurostar1]" %typemap(csattributes) MoreStations::Wales "[Eurostar2]" diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 7c0114928..a752fb933 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1226,12 +1226,17 @@ public: { EnumFeature enum_feature = decodeEnumFeature(parent); + const String *csattributes = Getattr(n, "feature:cs:attributes"); if ((enum_feature == ProperEnum) && parent_name && !unnamedinstance) { // Wrap (non-anonymous) C/C++ enum with a proper C# enum // Emit the enum item. if (!GetFlag(n, "firstenumitem")) Printf(enum_code, ",\n"); + + if (csattributes) + Printf(enum_code, " %s\n", csattributes); + Printf(enum_code, " %s", symname); // Check for the %csconstvalue feature @@ -1252,6 +1257,9 @@ public: const String *methodmods = Getattr(n, "feature:cs:methodmodifiers"); methodmods = methodmods ? methodmods : (is_public(n) ? public_string : protected_string); + if (csattributes) + Printf(enum_code, " %s\n", csattributes); + if ((enum_feature == TypesafeEnum) && parent_name && !unnamedinstance) { // Wrap (non-anonymous) enum using the typesafe enum pattern if (Getattr(n, "enumvalue")) { From 272ed9fc29e670648ad2e0e6dda4f7a69b22cd03 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Tue, 15 Sep 2009 01:27:17 +0000 Subject: [PATCH 034/146] require -fPIC in compile line git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11692 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 16f3cfbe2..561f7cc29 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -1124,11 +1124,11 @@ RRSRC = $(INTERFACE:.i=.R) r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) - +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) ) + +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o -fPIC $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) ) r_cpp: $(CXXSRCS) $(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH) - +( PKG_LIBS="$(CXXSRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) ) + +( PKG_LIBS="$(CXXSRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) ) r_clean: rm -f *_wrap* *~ .~* From 15070e6d8fb55b308ca0035fb77f1ffb55ec34c3 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 15 Sep 2009 21:26:57 +0000 Subject: [PATCH 035/146] Add %csattributes for adding C# attributes to enum values. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11693 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/CSharp.html | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index f092d188a..be0dcf658 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -297,7 +297,7 @@ Note that all these different C# attributes can be combined so that a method has

      • -Support for attaching C# attributes to wrapped methods and variables. +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. @@ -344,6 +344,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
        +}
        +
        +
      • From 123f4931cd9efd04f5375553a05cbeeb086b58aa Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 Oct 2009 18:16:09 +0000 Subject: [PATCH 036/146] document directorinattributes and directoroutattributes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11696 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/CSharp.html | 9 ++++++++- .../test-suite/csharp/csharp_attributes_runme.cs | 8 ++++++++ Examples/test-suite/csharp_attributes.i | 12 +++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index be0dcf658..a4bb9e2d1 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -249,7 +249,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: @@ -293,6 +295,11 @@ 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 +

        +
      • diff --git a/Examples/test-suite/csharp/csharp_attributes_runme.cs b/Examples/test-suite/csharp/csharp_attributes_runme.cs index 3f4ea179a..4cdced80d 100644 --- a/Examples/test-suite/csharp/csharp_attributes_runme.cs +++ b/Examples/test-suite/csharp/csharp_attributes_runme.cs @@ -198,6 +198,8 @@ public class runme if (tgv == null) throw new Exception("No attribute for Cymru"); } + + // No runtime test for directorinattributes and directoroutattributes } } @@ -256,3 +258,9 @@ public class ThreadSafeAttribute : Attribute { public ThreadSafeAttribute() {} } +[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] +public class DirectorIntegerOutAttribute : Attribute {} + +[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] +public class DirectorIntegerInAttribute : Attribute {} + diff --git a/Examples/test-suite/csharp_attributes.i b/Examples/test-suite/csharp_attributes.i index e74f7422d..bca595d9a 100644 --- a/Examples/test-suite/csharp_attributes.i +++ b/Examples/test-suite/csharp_attributes.i @@ -1,4 +1,4 @@ -%module csharp_attributes +%module(directors="1") csharp_attributes // Test the inattributes and outattributes typemaps %typemap(cstype, outattributes="[IntOut]", inattributes="[IntIn]") int "int" @@ -50,3 +50,13 @@ enum Cymru { Llanelli }; double MoreStations::WestonSuperMare = 0.0; %} +// Test directorinattributes and directoroutattributes +%typemap(imtype, directoroutattributes="[DirectorIntegerOut]", directorinattributes="[DirectorIntegerIn]") int "int" +%feature("director") YetMoreStations; + +%inline %{ +struct YetMoreStations { + virtual int Slough(int x) {} + virtual ~YetMoreStations() {} +}; +%} From 4b2ced5095ea8ee40d9d13d36c939374d820e52b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 17:50:36 +0000 Subject: [PATCH 037/146] Fix partial specialization and explicit specialization lookup git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11703 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 21 + Examples/test-suite/common.mk | 2 + ...template_partial_specialization_runme.java | 59 ++ ..._partial_specialization_typedef_runme.java | 59 ++ .../template_partial_specialization.i | 134 +++++ .../template_partial_specialization_typedef.i | 130 +++++ Source/CParse/parser.y | 19 +- Source/CParse/templ.c | 512 +++++++++++++----- 8 files changed, 784 insertions(+), 152 deletions(-) create mode 100644 Examples/test-suite/java/template_partial_specialization_runme.java create mode 100644 Examples/test-suite/java/template_partial_specialization_typedef_runme.java create mode 100644 Examples/test-suite/template_partial_specialization.i create mode 100644 Examples/test-suite/template_partial_specialization_typedef.i diff --git a/CHANGES.current b/CHANGES.current index 1f6de8059..16d5c6c28 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,27 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 4bbf74525..a47f821ef 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -339,6 +339,8 @@ CPP_TEST_CASES += \ template_ns_inherit \ template_ns_scope \ template_partial_arg \ + template_partial_specialization \ + template_partial_specialization_typedef \ template_qualifier \ template_qualifier \ template_ref_type \ diff --git a/Examples/test-suite/java/template_partial_specialization_runme.java b/Examples/test-suite/java/template_partial_specialization_runme.java new file mode 100644 index 000000000..ef8c4e80e --- /dev/null +++ b/Examples/test-suite/java/template_partial_specialization_runme.java @@ -0,0 +1,59 @@ +import template_partial_specialization.*; + +public class template_partial_specialization_runme { + + static { + try { + System.loadLibrary("template_partial_specialization"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + // One parameter tests + new A().a(); + new B().b(); + new C().c(); + new D().d(); + new E().e(); + + new F().f(); + new G().g(); + new H().h(); + + new I().i(); + new J().j(); + new K().k(); + new L().l(); + + new BB().b(); + new BBB().b(); + new BBBB().b(); + new BBBBB().b(); + + new B1().b(); + new B2().b(); + new B3().b(); + new B4().b(); + + // Two parameter tests + new A_().a(); + new B_().b(); + new C_().c(); + new D_().d(); + new E_().e(); + new F_().f(); + new G_().g(); + + new C1_().c(); + new C2_().c(); + new C3_().c(); + new C4_().c(); + new B1_().b(); + new E1_().e(); + new E2_().e(); + } +} + diff --git a/Examples/test-suite/java/template_partial_specialization_typedef_runme.java b/Examples/test-suite/java/template_partial_specialization_typedef_runme.java new file mode 100644 index 000000000..6ae95eb6a --- /dev/null +++ b/Examples/test-suite/java/template_partial_specialization_typedef_runme.java @@ -0,0 +1,59 @@ +import template_partial_specialization_typedef.*; + +public class template_partial_specialization_typedef_runme { + + static { + try { + System.loadLibrary("template_partial_specialization_typedef"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + // One parameter tests + new A().a(); + new B().b(); + new C().c(); + new D().d(); + new E().e(); + + new F().f(); + new G().g(); + new H().h(); + + new I().i(); + new J().j(); + new K().k(); + new L().l(); + + new BB().b(); + new BBB().b(); + new BBBB().b(); + new BBBBB().b(); + + new B1().b(); + new B2().b(); + new B3().b(); + new B4().b(); + + // Two parameter tests + new A_().a(); + new B_().b(); + new C_().c(); + new D_().d(); + new E_().e(); + new F_().f(); + new G_().g(); + + new C1_().c(); + new C2_().c(); + new C3_().c(); + new C4_().c(); + new B1_().b(); + new E1_().e(); + new E2_().e(); + } +} + diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i new file mode 100644 index 000000000..e59ae7e5a --- /dev/null +++ b/Examples/test-suite/template_partial_specialization.i @@ -0,0 +1,134 @@ +%module template_partial_specialization + +%inline %{ +namespace One { + template struct OneParm { void a() {} }; + template struct OneParm { void b() {} }; + template struct OneParm { void c() {} }; + template struct OneParm { void d() {} }; + template struct OneParm { void e() {} }; + + template <> struct OneParm { void f() {} }; + template <> struct OneParm { void g() {} }; + template <> struct OneParm { void h() {} }; + + template <> struct OneParm { void i() {} }; + template <> struct OneParm { void j() {} }; + template <> struct OneParm { void k() {} }; + template <> struct OneParm { void l() {} }; +} +%} + +// partial specializations +%template(A) One::OneParm; +%template(B) One::OneParm; +%template(C) One::OneParm; +%template(D) One::OneParm; +%template(E) One::OneParm; + +// explicit specializations +%template(F) One::OneParm; +%template(G) One::OneParm; +%template(H) One::OneParm; + +// %template scope explicit specializations +namespace ONE { + %template(I) One::OneParm; + %template(J) ::One::OneParm; +} +%template(K) ::One::OneParm; +namespace One { + %template(L) OneParm; +} + +// %template scope partial specializations +namespace ONE { + %template(BB) One::OneParm; + %template(BBB) ::One::OneParm; +} +%template(BBBB) ::One::OneParm; +namespace One { + %template(BBBBB) OneParm; +} + +// non-exact match +%template(B1) One::OneParm; +%template(B2) One::OneParm; +%template(B3) One::OneParm; +%template(B4) One::OneParm; + + +// Two parameter specialization tests +%inline %{ +struct Concrete {}; +namespace Two { + template struct TwoParm { void a() {} }; + template struct TwoParm { void b() {} }; + template struct TwoParm { void c() {} }; + template struct TwoParm { void d() {} }; + template struct TwoParm { void e() {} }; + template struct TwoParm { void f() {} }; + template <> struct TwoParm { void g() {} }; +} +%} + +namespace Two { + %template(A_) TwoParm; + %template(B_) TwoParm; + %template(C_) TwoParm; + %template(D_) TwoParm; + %template(E_) TwoParm; + %template(F_) TwoParm; + %template(G_) TwoParm; + + %template(C1_) TwoParm; + %template(C2_) TwoParm; +} + +%template(C3_) Two::TwoParm; +%template(C4_) ::Two::TwoParm; +%template(B1_) ::Two::TwoParm; +%template(E1_) Two::TwoParm; +%template(E2_) Two::TwoParm; + +#if 0 +// TODO fix: +%inline %{ +//namespace S { + template struct X { void a() {} }; + template struct X { void b() {} }; +// template<> struct X { void c() {} }; +//} +%} + +#if 0 +struct AA { // crashes +#else +namespace AA { // thinks X is in AA namespace + %template(X2) X; +}; +#endif +#endif + +#if 0 +namespace Space { +} +template struct Vector { +#ifdef SWIG + %template() Space::VectorHelper; +#endif + void gook(T i) {} + void geeko(double d) {} + void geeky(int d) {} +}; +/* +template struct Vector { +}; +*/ +//} +%} + +%template(VectorIntPtr) Space::Vector; // should fail as Vector is in global namespace +// is this a regression - no fails in 1.3.40 too +// Note problem is removed by removing empty Space namespace!! +#endif diff --git a/Examples/test-suite/template_partial_specialization_typedef.i b/Examples/test-suite/template_partial_specialization_typedef.i new file mode 100644 index 000000000..6fdbf99aa --- /dev/null +++ b/Examples/test-suite/template_partial_specialization_typedef.i @@ -0,0 +1,130 @@ +// This testcase is almost identical to template_partial_specialization but uses typedefs for %template + +%module template_partial_specialization_typedef + +%inline %{ +namespace TypeDef { + typedef double Double; + typedef int * IntPtr; + typedef double * DoublePtr; + typedef double & DoubleRef; + typedef const double & ConstDoubleRef; + typedef double * const & DoublePtrConstRef; + + typedef int Int; + typedef int * const & IntPtrConstRef; + typedef int ** IntPtrPtr; + typedef float Float; + typedef float * FloatPtr; + typedef float ** FloatPtrPtr; + typedef float *** FloatPtrPtrPtr; + + typedef bool * BoolPtr; + typedef char * CharPtr; + typedef short * ShortPtr; + typedef long * LongPtr; + typedef unsigned int ** UnsignedIntPtrPtr; + typedef unsigned int *** UnsignedIntPtrPtrPtr; + typedef const unsigned int ** ConstUnsignedIntPtr; + typedef const unsigned int *** ConstUnsignedIntPtrPtr; +} +namespace One { + template struct OneParm { void a() {} }; + template struct OneParm { void b() {} }; + template struct OneParm { void c() {} }; + template struct OneParm { void d() {} }; + template struct OneParm { void e() {} }; + + template <> struct OneParm { void f() {} }; + template <> struct OneParm { void g() {} }; + template <> struct OneParm { void h() {} }; + + template <> struct OneParm { void i() {} }; + template <> struct OneParm { void j() {} }; + template <> struct OneParm { void k() {} }; + template <> struct OneParm { void l() {} }; +} +%} + +// partial specializations +%template(A) One::OneParm; +%template(B) One::OneParm; +%template(C) One::OneParm; +%template(D) One::OneParm; +%template(E) One::OneParm; + +// explicit specializations +%template(F) One::OneParm; +%template(G) One::OneParm; +%template(H) One::OneParm; + +// %template scope explicit specializations +namespace ONE { + %template(I) One::OneParm; + %template(J) ::One::OneParm; +} +%template(K) ::One::OneParm; +namespace One { + %template(L) OneParm; +} + +// %template scope partial specializations +namespace ONE { + %template(BB) One::OneParm; + %template(BBB) ::One::OneParm; +} +%template(BBBB) ::One::OneParm; +namespace One { + %template(BBBBB) OneParm; +} + +// non-exact match +%template(B1) One::OneParm; +%template(B2) One::OneParm; +%template(B3) One::OneParm; +%template(B4) One::OneParm; + + +// Two parameter specialization tests +%inline %{ +struct Concrete {}; +namespace Two { + template struct TwoParm { void a() {} }; + template struct TwoParm { void b() {} }; + template struct TwoParm { void c() {} }; + template struct TwoParm { void d() {} }; + template struct TwoParm { void e() {} }; + template struct TwoParm { void f() {} }; + template <> struct TwoParm { void g() {} }; +} +%} + +%inline %{ +namespace TypeDef { + typedef const double * ConstDoublePtr; + typedef const int * ConstIntPtr; + typedef int * IntPtr; + typedef Concrete * ConcretePtr; + typedef const Concrete * ConstConcretePtr; + typedef void * VoidPtr; +} +%} +namespace Two { + %template(A_) TwoParm; + %template(B_) TwoParm; + %template(C_) TwoParm; + %template(D_) TwoParm; + %template(E_) TwoParm; + %template(F_) TwoParm; + %template(G_) TwoParm; + + %template(C1_) TwoParm; + %template(C2_) TwoParm; +} + +%template(C3_) Two::TwoParm; +%template(C4_) ::Two::TwoParm; +%template(B1_) ::Two::TwoParm; +%template(E1_) Two::TwoParm; +%template(E2_) Two::TwoParm; + diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 8876384b1..29aff3d10 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3759,6 +3759,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Parm *p = $3; String *fname = NewString(Getattr($$,"name")); String *ffname = 0; + ParmList *partialparms = 0; char tmp[32]; int i, ilen; @@ -3780,12 +3781,21 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para /* Patch argument names with typedef */ { Iterator tt; + Parm *parm_current = 0; List *tparms = SwigType_parmlist(fname); ffname = SwigType_templateprefix(fname); Append(ffname,"<("); for (tt = First(tparms); tt.item; ) { SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0); SwigType *ttr = Swig_symbol_type_qualify(rtt,0); + + Parm *newp = NewParm(ttr, 0); + if (partialparms) + set_nextSibling(partialparms, newp); + else + partialparms = newp; + parm_current = newp; + Append(ffname,ttr); tt = Next(tt); if (tt.item) Putc(',',ffname); @@ -3796,6 +3806,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Append(ffname,")>"); } { + Node *new_partial = NewHash(); String *partials = Getattr(tempn,"partials"); if (!partials) { partials = NewList(); @@ -3803,7 +3814,9 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Delete(partials); } /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */ - Append(partials,ffname); + Setattr(new_partial, "partialparms", partialparms); + Setattr(new_partial, "templcsymname", ffname); + Append(partials, new_partial); } Setattr($$,"partialargs",ffname); Swig_symbol_cadd(ffname,$$); @@ -3812,8 +3825,8 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Delete(tlist); Delete(targs); } else { - /* Need to resolve exact specialization name */ - /* add default args from generic template */ + /* An explicit template specialization */ + /* add default args from primary (unspecialized) template */ String *ty = Swig_symbol_template_deftype(tname,0); String *fname = Swig_symbol_type_qualify(ty,0); Swig_symbol_cadd(fname,$$); diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 14886605f..1f1620094 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -422,6 +422,70 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab return 0; } +typedef enum { ExactNoMatch = -2, PartiallySpecializedNoMatch = -1, PartiallySpecializedMatch = 1, ExactMatch = 2 } EMatch; + +/* ----------------------------------------------------------------------------- + * does_parm_match() + * + * Template argument deduction - check if a template type matches a partially specialized + * template parameter type. Reduce 'partial_parm_type' to see if it matches 'type'. + * + * type - template parameter type to match against + * partial_parm_type - partially specialized template type - a possible match + * partial_parm_type_base - base type of partial_parm_type + * tscope - template scope + * specialization_priority - (output) contains a value indicating how good the match is + * (higher is better) only set if return is set to PartiallySpecializedMatch or ExactMatch. + * ----------------------------------------------------------------------------- */ + +static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const char *partial_parm_type_base, Symtab *tscope, int *specialization_priority) { + static const int EXACT_MATCH_PRIORITY = 99999; /* a number bigger than the length of any conceivable type */ + int matches; + int substitutions; + EMatch match; + SwigType *ty = Swig_symbol_typedef_reduce(type, tscope); + String *base = SwigType_base(ty); + SwigType *t = Copy(partial_parm_type); + substitutions = Replaceid(t, partial_parm_type_base, base); /* eg: Replaceid("p.$1", "$1", "int") returns t="p.int" */ + matches = Equal(ty, t); + *specialization_priority = -1; + if (substitutions == 1) { + /* we have a non-explicit specialized parameter (in partial_parm_type) because a substitution for $1, $2... etc has taken place */ + SwigType *tt = Copy(partial_parm_type); + int len; + /* + check for match to partial specialization type, for example, all of the following could match the type in the %template: + template struct XX {}; + template struct XX {}; // r.$1 + template struct XX {}; // r.q(const).$1 + template struct XX {}; // r.q(const).p.$1 + %template(XXX) XX; // r.q(const).p.int + + where type="r.q(const).p.int" will match either of tt="r.$1", tt="r.q(const)" tt="r.q(const).p" + */ + Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */ + len = Len(tt); + if (Strncmp(tt, ty, len) == 0) { + match = PartiallySpecializedMatch; + *specialization_priority = len; + } else { + match = PartiallySpecializedNoMatch; + } + Delete(tt); + } else { + match = matches ? ExactMatch : ExactNoMatch; + if (matches) + *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */ + } + /* + Printf(stdout, " does_parm_match %2d %5d [%s] [%s]\n", match, *specialization_priority, type, partial_parm_type); + */ + Delete(t); + Delete(base); + Delete(ty); + return match; +} + /* ----------------------------------------------------------------------------- * template_locate() * @@ -429,175 +493,321 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab * ----------------------------------------------------------------------------- */ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { - Node *n; - String *tname, *rname = 0; + Node *n = 0; + String *tname = 0, *rname = 0; Node *templ; - List *mpartials = 0; + Symtab *primary_scope = 0; + List *possiblepartials = 0; Parm *p; - Parm *parms; + Parm *parms = 0; Parm *targs; ParmList *expandedparms; + int *priorities_matrix = 0; + int max_possible_partials = 0; + int posslen = 0; - tname = Copy(name); - parms = CopyParmList(tparms); - - /* Search for generic template */ + /* Search for primary (unspecialized) template */ templ = Swig_symbol_clookup(name, 0); - /* Add default values from generic template */ - if (templ) { - Symtab *tsdecl = Getattr(templ, "sym:symtab"); + if (template_debug) { + tname = Copy(name); + SwigType_add_template(tname, tparms); + Printf(stdout, "\n%s:%d: template_debug: Searching for match to: '%s'\n", cparse_file, cparse_line, tname); + Delete(tname); + tname = 0; + } + if (templ) { + tname = Copy(name); + parms = CopyParmList(tparms); + + /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */ + primary_scope = Getattr(templ, "sym:symtab"); + + /* Add default values from primary template */ targs = Getattr(templ, "templateparms"); - expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, tsdecl); - } else { - expandedparms = parms; - } + expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope); - - /* reduce the typedef */ - p = expandedparms; - while (p) { - SwigType *ty = Getattr(p, "type"); - if (ty) { - SwigType *nt = Swig_symbol_type_qualify(ty, tscope); - Setattr(p, "type", nt); - Delete(nt); - } - p = nextSibling(p); - } - - SwigType_add_template(tname, expandedparms); - - if (template_debug) { - Printf(stdout, "\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); - } - - /* Search for an exact specialization. - Example: template<> class name { ... } */ - { - if (template_debug) { - Printf(stdout, " searching: '%s' (exact specialization)\n", tname); - } - n = Swig_symbol_clookup_local(tname, 0); - if (!n) { - SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); - if (!Equal(rname, tname)) { - if (template_debug) { - Printf(stdout, " searching: '%s' (exact specialization)\n", rname); - } - n = Swig_symbol_clookup_local(rname, 0); + /* reduce the typedef */ + p = expandedparms; + while (p) { + SwigType *ty = Getattr(p, "type"); + if (ty) { + SwigType *nt = Swig_symbol_type_qualify(ty, tscope); + Setattr(p, "type", nt); + Delete(nt); } - Delete(rname); + p = nextSibling(p); } - if (n) { - Node *tn; - String *nodeType = nodeType(n); - if (Equal(nodeType, "template")) - goto success; - tn = Getattr(n, "template"); - if (tn) { - n = tn; - goto success; /* Previously wrapped by a template return that */ + SwigType_add_template(tname, expandedparms); + + /* Search for an explicit (exact) specialization. Example: template<> class name { ... } */ + { + if (template_debug) { + Printf(stdout, " searching for : '%s' (explicit specialization)\n", tname); } - Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); - Delete(tname); - Delete(parms); - return 0; /* Found a match, but it's not a template of any kind. */ - } - } - - /* Search for partial specialization. - Example: template class name { ... } */ - - /* Generate reduced template name (stripped of extraneous pointers, etc.) */ - - rname = NewStringf("%s<(", name); - p = parms; - while (p) { - String *t; - t = Getattr(p, "type"); - if (!t) - t = Getattr(p, "value"); - if (t) { - String *ty = Swig_symbol_typedef_reduce(t, tscope); - String *tb = SwigType_base(ty); - String *td = SwigType_default(ty); - Replaceid(td, "enum SWIGTYPE", tb); - Replaceid(td, "SWIGTYPE", tb); - Append(rname, td); - Delete(tb); - Delete(ty); - Delete(td); - } - p = nextSibling(p); - if (p) { - Append(rname, ","); - } - } - Append(rname, ")>"); - - mpartials = NewList(); - if (templ) { - /* First, we search using an exact type prototype */ - Parm *p; - char tmp[32]; - int i; - List *partials; - String *ss; - Iterator pi; - - partials = Getattr(templ, "partials"); - if (partials) { - for (pi = First(partials); pi.item; pi = Next(pi)) { - ss = Copy(pi.item); - p = parms; - i = 1; - while (p) { - String *t, *tn; - sprintf(tmp, "$%d", i); - t = Getattr(p, "type"); - if (!t) - t = Getattr(p, "value"); - if (t) { - String *ty = Swig_symbol_typedef_reduce(t, tscope); - tn = SwigType_base(ty); - Replaceid(ss, tmp, tn); - Delete(tn); - Delete(ty); + n = Swig_symbol_clookup_local(tname, primary_scope); + if (!n) { + SwigType *rname = Swig_symbol_typedef_reduce(tname, tscope); + if (!Equal(rname, tname)) { + if (template_debug) { + Printf(stdout, " searching for : '%s' (explicit specialization with typedef reduction)\n", rname); } - i++; - p = nextSibling(p); + n = Swig_symbol_clookup_local(rname, primary_scope); } - if (template_debug) { - Printf(stdout, " searching: '%s' (partial specialization - %s)\n", ss, pi.item); - } - if ((Equal(ss, tname)) || (Equal(ss, rname))) { - Append(mpartials, pi.item); - } - Delete(ss); + Delete(rname); } - } - } - - if (template_debug) { - Printf(stdout, " Matched partials: %s\n", mpartials); - } - - if (Len(mpartials)) { - String *s = Getitem(mpartials, 0); - n = Swig_symbol_clookup_local(s, 0); - if (Len(mpartials) > 1) { if (n) { - Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); - Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n, "name"))); + Node *tn; + String *nodeType = nodeType(n); + if (Equal(nodeType, "template")) { + if (template_debug) { + Printf(stdout, " explicit specialization found: '%s'\n", Getattr(n, "name")); + } + goto success; + } + tn = Getattr(n, "template"); + if (tn) { + if (template_debug) { + Printf(stdout, " previous instantiation found: '%s'\n", Getattr(n, "name")); + } + n = tn; + goto success; /* Previously wrapped by a template instantiation */ + } + Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); + Delete(tname); + Delete(parms); + return 0; /* Found a match, but it's not a template of any kind. */ } } + + /* Search for partial specializations. + * Example: template class name { ... } + + * There are 3 types of template arguments: + * (1) Template type arguments + * (2) Template non type arguments + * (3) Template template arguments + * only (1) is really supported for partial specializations + */ + + /* Generate reduced template name (stripped of extraneous pointers, etc.) */ + rname = NewStringf("%s<(", name); + p = parms; + while (p) { + String *t; + t = Getattr(p, "type"); + if (!t) + t = Getattr(p, "value"); + if (t) { + String *tyr = Swig_symbol_typedef_reduce(t, tscope); + String *ty = SwigType_strip_qualifiers(tyr); + String *tb = SwigType_base(ty); + String *td = SwigType_default(ty); + Replaceid(td, "enum SWIGTYPE", tb); + Replaceid(td, "SWIGTYPE", tb); + Append(rname, td); + Delete(tb); + Delete(td); + Delete(ty); + Delete(tyr); + } + p = nextSibling(p); + if (p) { + Append(rname, ","); + } + } + Append(rname, ")>"); + + /* Rank each template parameter against the desired template parameters then build a matrix of best matches */ + possiblepartials = NewList(); + { + char tmp[32]; + List *partials; + + partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */ + if (partials) { + Iterator pi; + int parms_len = ParmList_len(parms); + int *priorities_row; + max_possible_partials = Len(partials); + priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */ + priorities_row = priorities_matrix; + for (pi = First(partials); pi.item; pi = Next(pi)) { + Parm *p = parms; + int all_parameters_match = 1; + int i = 1; + Parm *partialparms = Getattr(pi.item, "partialparms"); + Parm *pp = partialparms; + String *templcsymname = Getattr(pi.item, "templcsymname"); + if (template_debug) { + Printf(stdout, " checking match: '%s' (partial specialization)\n", templcsymname); + } + if (ParmList_len(partialparms) == parms_len) { + while (p && pp) { + SwigType *t; + sprintf(tmp, "$%d", i); + t = Getattr(p, "type"); + if (!t) + t = Getattr(p, "value"); + if (t) { + EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1); + if (match < (int)PartiallySpecializedMatch) { + all_parameters_match = 0; + break; + } + } + i++; + p = nextSibling(p); + pp = nextSibling(pp); + } + if (all_parameters_match) { + Append(possiblepartials, pi.item); + priorities_row += parms_len; + } + } + } + } + } + + posslen = Len(possiblepartials); + if (template_debug) { + int i; + if (posslen == 0) + Printf(stdout, " matched partials: NONE\n"); + else if (posslen == 1) + Printf(stdout, " chosen partial: '%s'\n", Getattr(Getitem(possiblepartials, 0), "templcsymname")); + else { + Printf(stdout, " possibly matched partials:\n"); + for (i = 0; i < posslen; i++) { + Printf(stdout, " '%s'\n", Getattr(Getitem(possiblepartials, i), "templcsymname")); + } + } + } + + if (posslen > 1) { + /* Now go through all the possibly matched partial specialization templates and look for a non-ambiguous match. + * Exact matches rank the highest and deduced parameters are ranked by how much they are reduced, eg looking for + * a match to const int *, the following rank (highest to lowest): + * const int * (exact match) + * const T * + * T * + * T + * + * An ambiguous example when attempting to match as either specialization could match: %template() X; + * template X class {}; // primary template + * template X class {}; // specialization (1) + * template X class {}; // specialization (2) + */ + if (template_debug) { + int row, col; + int parms_len = ParmList_len(parms); + Printf(stdout, " parameter priorities matrix (%d parms):\n", parms_len); + for (row = 0; row < posslen; row++) { + int *priorities_row = priorities_matrix + row*parms_len; + Printf(stdout, " "); + for (col = 0; col < parms_len; col++) { + Printf(stdout, "%5d ", priorities_row[col]); + } + Printf(stdout, "\n"); + } + } + { + int row, col; + int parms_len = ParmList_len(parms); + /* Printf(stdout, " parameter priorities inverse matrix (%d parms):\n", parms_len); */ + for (col = 0; col < parms_len; col++) { + int *priorities_col = priorities_matrix + col; + int maxpriority = -1; + /* + Printf(stdout, "max_possible_partials: %d col:%d\n", max_possible_partials, col); + Printf(stdout, " "); + */ + /* determine the highest rank for this nth parameter */ + for (row = 0; row < posslen; row++) { + int *element_ptr = priorities_col + row*parms_len; + int priority = *element_ptr; + if (priority > maxpriority) + maxpriority = priority; + /* Printf(stdout, "%5d ", priority); */ + } + /* Printf(stdout, "\n"); */ + /* flag all the parameters which equal the highest rank */ + for (row = 0; row < posslen; row++) { + int *element_ptr = priorities_col + row*parms_len; + int priority = *element_ptr; + *element_ptr = (priority >= maxpriority) ? 1 : 0; + } + } + } + { + int row, col; + int parms_len = ParmList_len(parms); + Iterator pi = First(possiblepartials); + Node *chosenpartials = NewList(); + if (template_debug) + Printf(stdout, " priority flags matrix:\n"); + for (row = 0; row < posslen; row++) { + int *priorities_row = priorities_matrix + row*parms_len; + int highest_count = 0; /* count of highest priority parameters */ + for (col = 0; col < parms_len; col++) { + highest_count += priorities_row[col]; + } + if (template_debug) { + Printf(stdout, " "); + for (col = 0; col < parms_len; col++) { + Printf(stdout, "%5d ", priorities_row[col]); + } + Printf(stdout, "\n"); + } + if (highest_count == parms_len) { + Append(chosenpartials, pi.item); + } + pi = Next(pi); + } + if (Len(chosenpartials) > 0) { + /* one or more best match found */ + Delete(possiblepartials); + possiblepartials = chosenpartials; + posslen = Len(possiblepartials); + } else { + /* no best match found */ + Delete(chosenpartials); + } + } + } + + if (posslen > 0) { + String *s = Getattr(Getitem(possiblepartials, 0), "templcsymname"); + n = Swig_symbol_clookup_local(s, primary_scope); + if (posslen > 1) { + int i; + if (n) { + Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, cparse_file, cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); + Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(n), Getline(n), " instantiation '%s' used,\n", SwigType_namestr(Getattr(n, "name"))); + } + for (i = 1; i < posslen; i++) { + String *templcsymname = Getattr(Getitem(possiblepartials, i), "templcsymname"); + Node *ignored_node = Swig_symbol_clookup_local(templcsymname, primary_scope); + Swig_warning(WARN_PARSE_TEMPLATE_AMBIG, Getfile(ignored_node), Getline(ignored_node), " instantiation '%s' ignored.\n", SwigType_namestr(Getattr(ignored_node, "name"))); + } + } + } + + if (!n) { + if (template_debug) { + Printf(stdout, " chosen primary template: '%s'\n", Getattr(templ, "name")); + } + n = templ; + } + } else { + if (template_debug) { + Printf(stdout, " primary template not found\n"); + } + /* Give up if primary (unspecialized) template not found as specializations will only exist if there is a primary template */ + n = 0; } - if (!n) { - n = templ; - } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } else if (n) { @@ -610,12 +820,16 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { success: Delete(tname); Delete(rname); - Delete(mpartials); + Delete(possiblepartials); if ((template_debug) && (n)) { + /* Printf(stdout, "Node: %p\n", n); Swig_print_node(n); + */ + Printf(stdout, " chosen template:'%s'\n", Getattr(n, "name")); } Delete(parms); + free(priorities_matrix); return n; } From 132376badea420005bc40ac35dd8145417f1641c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 18:22:16 +0000 Subject: [PATCH 038/146] Fix std::vector of const pointers git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11704 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 ++ Examples/test-suite/li_std_vector_extra.i | 5 ++- Examples/test-suite/li_std_vector_ptr.i | 1 + .../python/li_std_vector_extra_runme.py | 20 ++++++++++ Lib/std/std_vector.i | 40 +++++++++++++++++++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 16d5c6c28..0c8e39ed2 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +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: diff --git a/Examples/test-suite/li_std_vector_extra.i b/Examples/test-suite/li_std_vector_extra.i index 9c2497f7c..114de3f11 100644 --- a/Examples/test-suite/li_std_vector_extra.i +++ b/Examples/test-suite/li_std_vector_extra.i @@ -125,15 +125,16 @@ std::vector vecStr(std::vector v) { %inline %{ int *makeIntPtr(int v) { return new int(v); } + const short *makeConstShortPtr(int v) { return new short(v); } double *makeDoublePtr(double v) { return new double(v); } int extractInt(int *p) { return *p; } + short extractConstShort(const short *p) { return *p; } %} %template(pyvector) std::vector; namespace std { - %template(ConstShortVector) vector; -// %template(ConstIntVector) vector; // interferes with vector... see new testcase li_std_vector_ptr + %template(ConstShortPtrVector) vector; } %inline %{ diff --git a/Examples/test-suite/li_std_vector_ptr.i b/Examples/test-suite/li_std_vector_ptr.i index 688cbdd54..292c9d700 100644 --- a/Examples/test-suite/li_std_vector_ptr.i +++ b/Examples/test-suite/li_std_vector_ptr.i @@ -1,3 +1,4 @@ +// Bug 2359417 %module li_std_vector_ptr %include "std_vector.i" diff --git a/Examples/test-suite/python/li_std_vector_extra_runme.py b/Examples/test-suite/python/li_std_vector_extra_runme.py index 776eacfb3..8900d7298 100644 --- a/Examples/test-suite/python/li_std_vector_extra_runme.py +++ b/Examples/test-suite/python/li_std_vector_extra_runme.py @@ -154,3 +154,23 @@ if extractInt(vi[0]) != 11: if extractInt(vi[1]) != 22: raise RuntimeError +# vector const pointer checks +csp = makeConstShortPtr(111) + +error = 0 +try: + vcs = ConstShortPtrVector((csp, dp)) # check vector does not accept double * element + error = 1 +except: + pass + +if error: + raise RuntimeError + +vcs = ConstShortPtrVector((csp, makeConstShortPtr(222))) +if extractConstShort(vcs[0]) != 111: + raise RuntimeError + +if extractConstShort(vcs[1]) != 222: + raise RuntimeError + diff --git a/Lib/std/std_vector.i b/Lib/std/std_vector.i index ab1435b31..b0bb714d4 100644 --- a/Lib/std/std_vector.i +++ b/Lib/std/std_vector.i @@ -134,6 +134,46 @@ namespace std { %std_vector_methods_val(vector); }; + // *** + // const pointer specialization + // *** + template + class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef const _Tp * value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type reference; + typedef value_type const_reference; + typedef _Alloc allocator_type; + + %traits_swigtype(_Tp); + + %fragment(SWIG_Traits_frag(std::vector), "header", + fragment=SWIG_Traits_frag(_Tp), + fragment="StdVectorTraits") { + namespace swig { + template <> struct traits > { + typedef value_category category; + static const char* type_name() { + return "std::vector"; + } + }; + } + } + + %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector); + +#ifdef %swig_vector_methods_val + // Add swig/language extra methods + %swig_vector_methods_val(std::vector); +#endif + + %std_vector_methods_val(vector); + }; + // *** // *** // bool specialization From fd222c5e66add5f3b40c0b3e10191096be22a746 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 20:30:22 +0000 Subject: [PATCH 039/146] Reference the Swig_print_* family of functions in the debugging section git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11705 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Devel/internals.html | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html index ea36f844d..d27ec12fa 100644 --- a/Doc/Devel/internals.html +++ b/Doc/Devel/internals.html @@ -1095,6 +1095,10 @@ Either
      +

      +Please also read the Debugging Functions section in SWIG Parse Tree Handling for the Swig_print_node(), Swig_print_tree() and Swig_print_tags() functions for displaying node contents. It is often easier to place a few calls to these functions in code of interest and recompile than use the debugger. +

      +
      Copyright (C) 1999-2004 SWIG Development Team. From 9062890aa6ecc9c2cc95d03063cf54b644cc0c20 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 20:54:19 +0000 Subject: [PATCH 040/146] update deprecated dump_tags, dump_tree, dump_module options git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11706 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Devel/tree.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/Devel/tree.html b/Doc/Devel/tree.html index 64d9d197d..43ad191f6 100644 --- a/Doc/Devel/tree.html +++ b/Doc/Devel/tree.html @@ -218,10 +218,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 +243,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 +251,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.
      From bd3fddb28cd70f943fe91df3be4b2b2e843550b8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 22:18:43 +0000 Subject: [PATCH 041/146] Add reference to the Doc/Devel documentation. Add debugging options git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11708 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Contents.html | 6 ++---- Doc/Manual/Extending.html | 32 ++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index d6feb934f..108106035 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -1599,11 +1599,9 @@
    • Prerequisites for adding a new language module to the SWIG distribution
    • Coding style guidelines
    -
  • Typemaps - +
  • Debugging Options
  • Guide to parse tree nodes +
  • Further Development Information
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index c56647450..111644e7f 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -66,11 +66,9 @@
  • Prerequisites for adding a new language module to the SWIG distribution
  • Coding style guidelines -
  • Typemaps - +
  • Debugging Options
  • Guide to parse tree nodes +
  • Further Development Information @@ -3590,11 +3588,26 @@ 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.

    -

    35.11 Typemaps

    +

    35.11 Debugging Options

    -

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

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

    35.12 Guide to parse tree nodes

    @@ -4004,6 +4017,13 @@ extern "X" { ... } declaration. +

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

    From f825fba4f7392a1654de8fdce894d03a80671c7d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Oct 2009 23:21:28 +0000 Subject: [PATCH 042/146] fix partial specialization with many parameters git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11709 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../template_partial_specialization.i | 18 ++++++++++++++++++ Source/CParse/parser.y | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i index e59ae7e5a..76bfa00fc 100644 --- a/Examples/test-suite/template_partial_specialization.i +++ b/Examples/test-suite/template_partial_specialization.i @@ -91,6 +91,24 @@ namespace Two { %template(E1_) Two::TwoParm; %template(E2_) Two::TwoParm; + +// Many template parameters +%inline %{ +template struct FiveParm { void a() {} }; +template struct FiveParm { void b() {} }; +%} + +%template(FiveParm1) FiveParm; + +%inline %{ +template struct ThreeParm; +template struct ThreeParm { void a1() {} }; +template struct ThreeParm { void a2() {} }; +template struct ThreeParm { void a3() {} }; +%} + +%template(ThreeParmInt) ThreeParm; + #if 0 // TODO fix: %inline %{ diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 29aff3d10..eeda3b0ea 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3791,7 +3791,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_para Parm *newp = NewParm(ttr, 0); if (partialparms) - set_nextSibling(partialparms, newp); + set_nextSibling(parm_current, newp); else partialparms = newp; parm_current = newp; From 678abc58fb3e89b6f94230db3470881bd7e1cf3d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Oct 2009 05:41:33 +0000 Subject: [PATCH 043/146] Fix seg fault when using a named template instantiation using %template(name) within a class git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11711 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 5 ++++ Doc/Manual/Warnings.html | 2 ++ Examples/test-suite/common.mk | 1 + .../java/template_nested_typemaps_runme.java | 27 +++++++++++++++++++ .../test-suite/template_nested_typemaps.i | 24 +++++++++++++++++ Source/Include/swigwarn.h | 1 + 6 files changed, 60 insertions(+) create mode 100644 Examples/test-suite/java/template_nested_typemaps_runme.java create mode 100644 Examples/test-suite/template_nested_typemaps.i diff --git a/CHANGES.current b/CHANGES.current index 0c8e39ed2..b8565d9cd 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,11 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 95af1ec6b..df05478a6 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -411,6 +411,8 @@ example.i(4): Syntax error in input.
  • 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().
  • 350. operator new ignored.
  • 351. operator delete ignored.
  • 352. operator+ ignored. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index a47f821ef..7bc5a9fa0 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -330,6 +330,7 @@ CPP_TEST_CASES += \ template_inherit_abstract \ template_int_const \ template_methods \ + template_nested_typemaps \ template_ns \ template_ns2 \ template_ns3 \ diff --git a/Examples/test-suite/java/template_nested_typemaps_runme.java b/Examples/test-suite/java/template_nested_typemaps_runme.java new file mode 100644 index 000000000..8e2354a8b --- /dev/null +++ b/Examples/test-suite/java/template_nested_typemaps_runme.java @@ -0,0 +1,27 @@ +import template_nested_typemaps.*; + +public class template_nested_typemaps_runme { + + static { + try { + System.loadLibrary("template_nested_typemaps"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + BreezeString b = new BreezeString(); + { + int v = 88; + short vTypemap = -99; + if (b.methodInt1(v) != v) throw new RuntimeException("failed"); + if (b.methodInt2(v) != vTypemap) throw new RuntimeException("failed"); + + if (template_nested_typemaps.globalInt1(v) != v) throw new RuntimeException("failed"); + if (template_nested_typemaps.globalInt2(v) != v) throw new RuntimeException("failed"); + } + } +} + diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i new file mode 100644 index 000000000..273b4b0cf --- /dev/null +++ b/Examples/test-suite/template_nested_typemaps.i @@ -0,0 +1,24 @@ +%module template_nested_typemaps + +template struct Typemap { + %typemap(in) T { + $1 = -99; + } +}; + +%inline %{ +int globalInt1(int s) { return s; } + +template struct Breeze { + int methodInt1(int s) { return s; } +#if defined(SWIG) + %template() Typemap; +#endif + int methodInt2(int s) { return s; } // only this method should pick up the typemap within Typemap + void takeIt(T t) {} +}; + +int globalInt2(int s) { return s; } +%} + +%template(BreezeString) Breeze; diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index e8fa159af..6c54c55bd 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -84,6 +84,7 @@ #define WARN_PARSE_BUILTIN_NAME 321 #define WARN_PARSE_REDUNDANT 322 #define WARN_PARSE_REC_INHERITANCE 323 +#define WARN_PARSE_NESTED_TEMPLATE 324 #define WARN_IGNORE_OPERATOR_NEW 350 /* new */ #define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ From 16b8caa3ded254fce8955166cb1d2d36173635a8 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Oct 2009 05:59:13 +0000 Subject: [PATCH 044/146] Fix seg fault when two or more %template() declarations were made within a class git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11712 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../java/template_nested_typemaps_runme.java | 10 ++++++++++ Examples/test-suite/template_nested_typemaps.i | 15 +++++++++++++++ .../template_partial_specialization.i | 4 ---- Source/CParse/parser.y | 17 ++++++++++++----- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Examples/test-suite/java/template_nested_typemaps_runme.java b/Examples/test-suite/java/template_nested_typemaps_runme.java index 8e2354a8b..3bd8aa1df 100644 --- a/Examples/test-suite/java/template_nested_typemaps_runme.java +++ b/Examples/test-suite/java/template_nested_typemaps_runme.java @@ -22,6 +22,16 @@ public class template_nested_typemaps_runme { if (template_nested_typemaps.globalInt1(v) != v) throw new RuntimeException("failed"); if (template_nested_typemaps.globalInt2(v) != v) throw new RuntimeException("failed"); } + + { + short v = 88; + short vTypemap = -77; + if (b.methodShort1(v) != v) throw new RuntimeException("failed"); + if (b.methodShort2(v) != vTypemap) throw new RuntimeException("failed"); + + if (template_nested_typemaps.globalShort1(v) != v) throw new RuntimeException("failed"); + if (template_nested_typemaps.globalShort2(v) != v) throw new RuntimeException("failed"); + } } } diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i index 273b4b0cf..8ed02eaea 100644 --- a/Examples/test-suite/template_nested_typemaps.i +++ b/Examples/test-suite/template_nested_typemaps.i @@ -1,3 +1,5 @@ +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_TEMPLATE + %module template_nested_typemaps template struct Typemap { @@ -5,9 +7,15 @@ template struct Typemap { $1 = -99; } }; +template <> struct Typemap { + %typemap(in) short { + $1 = -77; + } +}; %inline %{ int globalInt1(int s) { return s; } +short globalShort1(short s) { return s; } template struct Breeze { int methodInt1(int s) { return s; } @@ -16,9 +24,16 @@ template struct Breeze { #endif int methodInt2(int s) { return s; } // only this method should pick up the typemap within Typemap void takeIt(T t) {} + + short methodShort1(short s) { return s; } +#if defined(SWIG) + %template(TypemapShort) Typemap; // should issue warning SWIGWARN_PARSE_NESTED_TEMPLATE +#endif + short methodShort2(short s) { return s; } // only this method should pick up the typemap within Typemap - note specialization }; int globalInt2(int s) { return s; } +short globalShort2(short s) { return s; } %} %template(BreezeString) Breeze; diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i index 76bfa00fc..a81bc47a5 100644 --- a/Examples/test-suite/template_partial_specialization.i +++ b/Examples/test-suite/template_partial_specialization.i @@ -119,14 +119,10 @@ template struct ThreeParm { void a3( //} %} -#if 0 -struct AA { // crashes -#else namespace AA { // thinks X is in AA namespace %template(X2) X; }; #endif -#endif #if 0 namespace Space { diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index eeda3b0ea..4d4401572 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -535,6 +535,8 @@ static void add_symbols_copy(Node *n) { add_oldname = Getattr(n,"sym:name"); if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { + int old_inclass = -1; + Node *old_current_class = 0; if (add_oldname) { DohIncref(add_oldname); /* Disable this, it prevents %rename to work with templates */ @@ -564,7 +566,9 @@ static void add_symbols_copy(Node *n) { Namespaceprefix = Swig_symbol_qualifiedscopename(0); } if (strcmp(cnodeType,"class") == 0) { + old_inclass = inclass; inclass = 1; + old_current_class = current_class; current_class = n; if (Strcmp(Getattr(n,"kind"),"class") == 0) { cplus_mode = CPLUS_PRIVATE; @@ -591,8 +595,8 @@ static void add_symbols_copy(Node *n) { add_oldname = 0; } if (strcmp(cnodeType,"class") == 0) { - inclass = 0; - current_class = 0; + inclass = old_inclass; + current_class = old_current_class; } } else { if (strcmp(cnodeType,"extend") == 0) { @@ -2752,7 +2756,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va } else { Setattr(templnode,"sym:typename","1"); } - if ($3) { + if ($3 && !inclass) { /* Comment this out for 1.3.28. We need to re-enable it later but first we need to @@ -2770,8 +2774,11 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va Swig_cparse_template_expand(templnode,nname,temparms,tscope); Setattr(templnode,"sym:name",nname); Delete(nname); - Setattr(templnode,"feature:onlychildren", - "typemap,typemapitem,typemapcopy,typedef,types,fragment"); + Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment"); + + if ($3) { + Swig_warning(WARN_PARSE_NESTED_TEMPLATE, cparse_file, cparse_line, "Named nested template instantiations not supported. Processing as if no name was given to %%template().\n"); + } } Delattr(templnode,"templatetype"); Setattr(templnode,"template",nn); From 6fc2ce82ea774f042237fbc96098380e70c70a61 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 23 Oct 2009 06:48:38 +0000 Subject: [PATCH 045/146] Document improved template explicit specialization and partial specialization git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11713 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/SWIGPlus.html | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index f3befa54b..f318af6a3 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -3246,22 +3246,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 From 283fd3c7ec13662f36653480996a32d357b20482 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 24 Oct 2009 21:58:06 +0000 Subject: [PATCH 046/146] minor improvement to testcase git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11715 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../java/template_nested_typemaps_runme.java | 2 ++ Examples/test-suite/template_nested_typemaps.i | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/java/template_nested_typemaps_runme.java b/Examples/test-suite/java/template_nested_typemaps_runme.java index 3bd8aa1df..443faca4f 100644 --- a/Examples/test-suite/java/template_nested_typemaps_runme.java +++ b/Examples/test-suite/java/template_nested_typemaps_runme.java @@ -21,6 +21,7 @@ public class template_nested_typemaps_runme { if (template_nested_typemaps.globalInt1(v) != v) throw new RuntimeException("failed"); if (template_nested_typemaps.globalInt2(v) != v) throw new RuntimeException("failed"); + if (template_nested_typemaps.globalInt3(v) != vTypemap) throw new RuntimeException("failed"); } { @@ -31,6 +32,7 @@ public class template_nested_typemaps_runme { if (template_nested_typemaps.globalShort1(v) != v) throw new RuntimeException("failed"); if (template_nested_typemaps.globalShort2(v) != v) throw new RuntimeException("failed"); + if (template_nested_typemaps.globalShort3(v) != vTypemap) throw new RuntimeException("failed"); } } } diff --git a/Examples/test-suite/template_nested_typemaps.i b/Examples/test-suite/template_nested_typemaps.i index 8ed02eaea..54f5bc503 100644 --- a/Examples/test-suite/template_nested_typemaps.i +++ b/Examples/test-suite/template_nested_typemaps.i @@ -2,12 +2,14 @@ %module template_nested_typemaps +// Testing that the typemaps invoked within a class via %template are picked up by appropriate methods + template struct Typemap { %typemap(in) T { $1 = -99; } }; -template <> struct Typemap { +template <> struct Typemap { // Note explicit specialization %typemap(in) short { $1 = -77; } @@ -22,14 +24,14 @@ template struct Breeze { #if defined(SWIG) %template() Typemap; #endif - int methodInt2(int s) { return s; } // only this method should pick up the typemap within Typemap + int methodInt2(int s) { return s; } // should pick up the typemap within Typemap void takeIt(T t) {} short methodShort1(short s) { return s; } #if defined(SWIG) %template(TypemapShort) Typemap; // should issue warning SWIGWARN_PARSE_NESTED_TEMPLATE #endif - short methodShort2(short s) { return s; } // only this method should pick up the typemap within Typemap - note specialization + short methodShort2(short s) { return s; } // should pick up the typemap within Typemap }; int globalInt2(int s) { return s; } @@ -37,3 +39,9 @@ short globalShort2(short s) { return s; } %} %template(BreezeString) Breeze; + +%inline %{ +int globalInt3(int s) { return s; } // should pick up the typemap within Typemap +short globalShort3(short s) { return s; } // should pick up the typemap within Typemap +%} + From 70e8072612c4f1229b11047fca8f2141dd664ba5 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 2 Nov 2009 06:31:45 +0000 Subject: [PATCH 047/146] [Python] Fix potential memory leak in initialisation code for the generated module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11717 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Lib/python/pyinit.swg | 18 +++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index b8565d9cd..692c0522c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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 diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg index 058934b04..5af8d2491 100644 --- a/Lib/python/pyinit.swg +++ b/Lib/python/pyinit.swg @@ -279,15 +279,15 @@ SWIG_Python_FixMethods(PyMethodDef *methods, } } if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { + void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; + if (ptr) { + size_t shift = (ci->ptype) - types; + swig_type_info *ty = types_initial[shift]; + size_t ldoc = (c - methods[i].ml_doc); + size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; + char *ndoc = (char*)malloc(ldoc + lptr + 10); + if (ndoc) { + char *buff = ndoc; strncpy(buff, methods[i].ml_doc, ldoc); buff += ldoc; strncpy(buff, "swig_ptr: ", 10); From da1fc3ab8f30e097f17a056db023b099b383c68c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 3 Nov 2009 19:14:37 +0000 Subject: [PATCH 048/146] Fix some usage of global scope operator :: git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11719 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 22 +++++++++++++++++++ .../template_partial_specialization.i | 2 ++ Examples/test-suite/using_namespace.i | 11 ++++++++++ Examples/test-suite/valuewrapper_const.i | 6 +++++ Source/Swig/symbol.c | 8 +++++++ 5 files changed, 49 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 692c0522c..0f5f6be84 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,28 @@ Version 1.3.41 (in progress) ============================ +2009-11-03: wsfulton + Fix some usage of global scope operator, 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. diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i index a81bc47a5..8781fbbda 100644 --- a/Examples/test-suite/template_partial_specialization.i +++ b/Examples/test-suite/template_partial_specialization.i @@ -69,6 +69,7 @@ namespace Two { template struct TwoParm { void e() {} }; template struct TwoParm { void f() {} }; template <> struct TwoParm { void g() {} }; + template <> struct TwoParm { void h() {} }; } %} @@ -90,6 +91,7 @@ namespace Two { %template(B1_) ::Two::TwoParm; %template(E1_) Two::TwoParm; %template(E2_) Two::TwoParm; +%template(H_) Two::TwoParm< ::Concrete, ::Concrete * >; // Many template parameters diff --git a/Examples/test-suite/using_namespace.i b/Examples/test-suite/using_namespace.i index 799c7cfb5..ce02e9a87 100644 --- a/Examples/test-suite/using_namespace.i +++ b/Examples/test-suite/using_namespace.i @@ -74,3 +74,14 @@ struct X { }; } + +%inline %{ +namespace SpaceMan { + typedef double SpaceManDouble; +} +using namespace ::SpaceMan; // global namespace prefix + +SpaceManDouble useSpaceMan(SpaceManDouble s) { return s; } + +%} + diff --git a/Examples/test-suite/valuewrapper_const.i b/Examples/test-suite/valuewrapper_const.i index db1c807c8..3091df30e 100644 --- a/Examples/test-suite/valuewrapper_const.i +++ b/Examples/test-suite/valuewrapper_const.i @@ -24,6 +24,12 @@ public: const B GetBconst() const { return b; } + ::B GetBGlobalQualifier() { + return b; + } + const ::B GetBconstGlobalGlobalQualifier() const { + return b; + } }; %} diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index 055af854f..3f9ce86af 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -998,6 +998,8 @@ Node *Swig_symbol_clookup(const_String_or_char_ptr name, Symtab *n) { String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); + } else { + s = symbol_lookup(nname, global_scope, 0); } Delete(nname); } else { @@ -1070,6 +1072,8 @@ Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (* String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); + } else { + s = symbol_lookup(nname, global_scope, checkfunc); } Delete(nname); } else { @@ -1134,6 +1138,8 @@ Node *Swig_symbol_clookup_local(const_String_or_char_ptr name, Symtab *n) { String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, 0); + } else { + s = symbol_lookup(nname, global_scope, 0); } Delete(nname); } else { @@ -1182,6 +1188,8 @@ Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, String *nname = NewString(cname + 2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname, global_scope, 0, 0, checkfunc); + } else { + s = symbol_lookup(nname, global_scope, checkfunc); } Delete(nname); } else { From 57fff12d5f8e67be14218e3a1ed57e2291cc5c6b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 3 Nov 2009 19:52:12 +0000 Subject: [PATCH 049/146] Fix seg fault for some template parameters which have no type, just a default value git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11720 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 3 +++ Source/Swig/parms.c | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 4d4401572..b8691ab9c 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -2644,6 +2644,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va n = Swig_cparse_template_locate($5,$7,tscope); /* Patch the argument types to respect namespaces */ +Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7)); p = $7; while (p) { SwigType *value = Getattr(p,"value"); @@ -2669,6 +2670,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va p = nextSibling(p); } +Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7)); /* Look for the template */ { @@ -2746,6 +2748,7 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va def_supplied = 1; } } +Printf(stdout, " p tempar patching: %s\n", ParmList_str_defaultargs(temparms)); templnode = copy_node(nn); /* We need to set the node name based on name used to instantiate */ diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index 9b58f5fcb..6b0863ee4 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -114,6 +114,14 @@ int ParmList_len(ParmList *p) { return i; } +/* --------------------------------------------------------------------- + * get_empty_type() + * ---------------------------------------------------------------------- */ + +static SwigType *get_empty_type() { + return NewStringEmpty(); +} + /* --------------------------------------------------------------------- * ParmList_str() * @@ -123,7 +131,8 @@ int ParmList_len(ParmList *p) { String *ParmList_str(ParmList *p) { String *out = NewStringEmpty(); while (p) { - String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name")); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); Append(out, pstr); p = nextSibling(p); if (p) { @@ -144,7 +153,8 @@ String *ParmList_str_defaultargs(ParmList *p) { String *out = NewStringEmpty(); while (p) { String *value = Getattr(p, "value"); - String *pstr = SwigType_str(Getattr(p, "type"), Getattr(p, "name")); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), Getattr(p, "name")); Append(out, pstr); if (value) { Printf(out, "=%s", value); @@ -167,7 +177,8 @@ String *ParmList_str_defaultargs(ParmList *p) { String *ParmList_protostr(ParmList *p) { String *out = NewStringEmpty(); while (p) { - String *pstr = SwigType_str(Getattr(p, "type"), 0); + String *type = Getattr(p, "type"); + String *pstr = SwigType_str(type ? type : get_empty_type(), 0); Append(out, pstr); p = nextSibling(p); if (p) { From dbe46033ee68af08508f84ddb08ba264cc8878ea Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 3 Nov 2009 19:57:35 +0000 Subject: [PATCH 050/146] remove debug in last commit git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11721 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index b8691ab9c..4d4401572 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -2644,7 +2644,6 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va n = Swig_cparse_template_locate($5,$7,tscope); /* Patch the argument types to respect namespaces */ -Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7)); p = $7; while (p) { SwigType *value = Getattr(p,"value"); @@ -2670,7 +2669,6 @@ Printf(stdout, " p before patching: %s\n", ParmList_str_defaultargs($7)); p = nextSibling(p); } -Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7)); /* Look for the template */ { @@ -2748,7 +2746,6 @@ Printf(stdout, " p after patching: %s\n", ParmList_str_defaultargs($7)); def_supplied = 1; } } -Printf(stdout, " p tempar patching: %s\n", ParmList_str_defaultargs(temparms)); templnode = copy_node(nn); /* We need to set the node name based on name used to instantiate */ From e351dfceaf5b1869fcda492c427149577056e1fe Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Wed, 4 Nov 2009 03:48:17 +0000 Subject: [PATCH 051/146] first pass at making fcompact work with R git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11722 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/r/rtype.swg | 16 ++++++++-------- Source/Modules/r.cxx | 34 +++++++++++++++++----------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg index d388d1eae..04441c03f 100644 --- a/Lib/r/rtype.swg +++ b/Lib/r/rtype.swg @@ -100,30 +100,30 @@ long *, long &, long[ANY] - "$input = as.integer($input) "; + "$input = as.integer($input); "; %typemap(scoercein) char *, string, std::string, string &, std::string & -%{ $input = as($input, "character") %} +%{ $input = as($input, "character"); %} %typemap(scoerceout) enum SWIGTYPE - %{ $result = enumFromInteger($result, "$R_class") %} + %{ $result = enumFromInteger($result, "$R_class"); %} %typemap(scoerceout) enum SWIGTYPE & - %{ $result = enumFromInteger($result, "$R_class") %} + %{ $result = enumFromInteger($result, "$R_class"); %} %typemap(scoerceout) enum SWIGTYPE * - %{ $result = enumToInteger($result, "$R_class") %} + %{ $result = enumToInteger($result, "$R_class"); %} %typemap(scoerceout) SWIGTYPE - %{ class($result) <- "$&R_class" %} + %{ class($result) <- "$&R_class"; %} %typemap(scoerceout) SWIGTYPE & - %{ class($result) <- "$R_class" %} + %{ class($result) <- "$R_class"; %} %typemap(scoerceout) SWIGTYPE * - %{ class($result) <- "$R_class" %} + %{ class($result) <- "$R_class"; %} /* Override the SWIGTYPE * above. */ %typemap(scoerceout) char, diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index c48e2e266..e142c3bee 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1101,7 +1101,7 @@ int R::OutputMemberReferenceMethod(String *className, int isSet, Delete(pitem); } Delete(itemList); - Printf(f->code, ")\n"); + Printf(f->code, ");\n"); if (!isSet && varaccessor > 0) { Printf(f->code, "%svaccessors = c(", tab8); @@ -1117,7 +1117,7 @@ int R::OutputMemberReferenceMethod(String *className, int isSet, Printf(f->code, "'%s'%s", item, vcount < varaccessor ? ", " : ""); } } - Printf(f->code, ")\n"); + Printf(f->code, ");\n"); } @@ -1129,24 +1129,24 @@ int R::OutputMemberReferenceMethod(String *className, int isSet, "stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className, ": fields are \", paste(names(accessorFuns), sep = \", \")", ")", "\n}\n", NIL); */ - Printv(f->code, tab8, - "idx = pmatch(name, names(accessorFuns))\n", + Printv(f->code, ";", tab8, + "idx = pmatch(name, names(accessorFuns));\n", tab8, "if(is.na(idx)) \n", tab8, tab4, NIL); - Printf(f->code, "return(callNextMethod(x, name%s))\n", + Printf(f->code, "return(callNextMethod(x, name%s));\n", isSet ? ", value" : ""); - Printv(f->code, tab8, "f = accessorFuns[[idx]]\n", NIL); + Printv(f->code, tab8, "f = accessorFuns[[idx]];\n", NIL); if(isSet) { - Printv(f->code, tab8, "f(x, value)\n", NIL); - Printv(f->code, tab8, "x\n", NIL); // make certain to return the S value. + Printv(f->code, tab8, "f(x, value);\n", NIL); + Printv(f->code, tab8, "x;\n", NIL); // make certain to return the S value. } else { - Printv(f->code, tab8, "formals(f)[[1]] = x\n", NIL); + Printv(f->code, tab8, "formals(f)[[1]] = x;\n", NIL); if (varaccessor) { Printv(f->code, tab8, - "if (is.na(match(name, vaccessors))) f else f(x)\n", NIL); + "if (is.na(match(name, vaccessors))) f else f(x);\n", NIL); } else { - Printv(f->code, tab8, "f\n", NIL); + Printv(f->code, tab8, "f;\n", NIL); } } Printf(f->code, "}\n"); @@ -1157,15 +1157,15 @@ int R::OutputMemberReferenceMethod(String *className, int isSet, isSet ? "<-" : "", getRClassName(className)); Wrapper_print(f, out); - Printf(out, ")\n"); + Printf(out, ");\n"); if(isSet) { Printf(out, "setMethod('[[<-', c('_p%s', 'character'),", getRClassName(className)); - Insert(f->code, 2, "name = i\n"); + Insert(f->code, 2, "name = i;\n"); Printf(attr->code, "%s", f->code); Wrapper_print(attr, out); - Printf(out, ")\n"); + Printf(out, ");\n"); } DelWrapper(attr); @@ -2090,10 +2090,10 @@ int R::functionWrapper(Node *n) { } - Printv(sfun->code, (Len(tm) ? "ans = " : ""), ".Call('", wname, - "', ", sargs, "PACKAGE='", Rpackage, "')\n", NIL); + Printv(sfun->code, ";", (Len(tm) ? "ans = " : ""), ".Call('", wname, + "', ", sargs, "PACKAGE='", Rpackage, "');\n", NIL); if(Len(tm)) - Printf(sfun->code, "%s\n\nans\n", tm); + Printf(sfun->code, "%s\n\nans;\n", tm); if (destructor) Printv(f->code, "R_ClearExternalPtr(self);\n", NIL); From 9683047b9a5f6975f2470858a311de9f885a2db7 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Wed, 4 Nov 2009 03:50:09 +0000 Subject: [PATCH 052/146] move fPIC location to be in front of -o git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11723 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 561f7cc29..3516d6f28 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -1124,7 +1124,7 @@ RRSRC = $(INTERFACE:.i=.R) r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) - +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o -fPIC $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) ) + +( PKG_LIBS="$(SRCS)" PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -fPIC -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) ) r_cpp: $(CXXSRCS) $(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH) From 64d1b6f0c650ac7a84e182cee4cc965271131f76 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 4 Nov 2009 22:49:39 +0000 Subject: [PATCH 053/146] Add -debug-symtabs and -debug-qsymtabs options for debugging symbol tables git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11724 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 +++++ Doc/Manual/Extending.html | 2 ++ Source/CParse/parser.y | 14 +++------- Source/Modules/main.cxx | 18 +++++++++++++ Source/Swig/swig.h | 3 +++ Source/Swig/symbol.c | 56 +++++++++++++++++++++++++++------------ 6 files changed, 72 insertions(+), 27 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 0f5f6be84..b577367db 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 1.3.41 (in progress) ============================ +2009-11-04: wsfulton + Add new debug options: + -debug-symtabs - Display symbol tables information + -debug-qsymtabs - Display symbol tables summary information using fully + qualified names + 2009-11-03: wsfulton Fix some usage of global scope operator, for example: diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html index 111644e7f..11578db97 100644 --- a/Doc/Manual/Extending.html +++ b/Doc/Manual/Extending.html @@ -3598,6 +3598,8 @@ There are various command line options which can aid debugging a SWIG interface

     -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-qsymtabs   - Display symbol tables summary information using fully qualified names
     -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
    diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
    index 4d4401572..954b7af77 100644
    --- a/Source/CParse/parser.y
    +++ b/Source/CParse/parser.y
    @@ -817,14 +817,8 @@ static List *make_inherit_list(String *clsname, List *names) {
     
     /* If the class name is qualified.  We need to create or lookup namespace entries */
     
    -static Symtab *get_global_scope() {
    -  Symtab *symtab = Swig_symbol_current();
    -  Node   *pn = parentNode(symtab);
    -  while (pn) {
    -    symtab = pn;
    -    pn = parentNode(symtab);
    -    if (!pn) break;
    -  }
    +static Symtab *set_scope_to_global() {
    +  Symtab *symtab = Swig_symbol_global_scope();
       Swig_symbol_setscope(symtab);
       return symtab;
     }
    @@ -869,11 +863,11 @@ static String *resolve_node_scope(String *cname) {
           String *nprefix = NewString(Char(prefix)+2);
           Delete(prefix);
           prefix= nprefix;
    -      gscope = get_global_scope();
    +      gscope = set_scope_to_global();
         }    
         if (!prefix || (Len(prefix) == 0)) {
           /* Use the global scope, but we need to add a 'global' namespace.  */
    -      if (!gscope) gscope = get_global_scope();
    +      if (!gscope) gscope = set_scope_to_global();
           /* note that this namespace is not the "unnamed" one,
     	 and we don't use Setattr(nscope,"name", ""),
     	 because the unnamed namespace is private */
    diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
    index c824db6f9..30e8eb18a 100644
    --- a/Source/Modules/main.cxx
    +++ b/Source/Modules/main.cxx
    @@ -62,6 +62,8 @@ static const char *usage1 = (const char *) "\
          -copyright      - Display copyright notices\n\
          -debug-classes  - Display information about the classes found in the interface\n\
          -debug-module - Display module parse tree at stages 1-4,  is a csv list of stages\n\
    +     -debug-symtabs  - Display symbol tables information\n\
    +     -debug-qsymtabs - Display symbol tables summary information using fully qualified names\n\
          -debug-tags     - Display information about the tags found in the interface\n\
          -debug-template - Display information for debugging templates\n\
          -debug-top   - Display entire parse tree at stages 1-4,  is a csv list of stages\n\
    @@ -162,6 +164,8 @@ static int no_cpp = 0;
     static char *outfile_name = 0;
     static char *outfile_name_h = 0;
     static int tm_debug = 0;
    +static int dump_symtabs = 0;
    +static int dump_qsymtabs = 0;
     static int dump_tags = 0;
     static int dump_module = 0;
     static int dump_top = 0;
    @@ -716,6 +720,12 @@ void SWIG_getoptions(int argc, char *argv[]) {
           } else if (strncmp(argv[i], "-w", 2) == 0) {
     	Swig_mark_arg(i);
     	Swig_warnfilter(argv[i] + 2, 1);
    +      } else if (strcmp(argv[i], "-debug-symtabs") == 0) {
    +	dump_symtabs = 1;
    +	Swig_mark_arg(i);
    +      } else if (strcmp(argv[i], "-debug-qsymtabs") == 0) {
    +	dump_qsymtabs = 1;
    +	Swig_mark_arg(i);
           } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
     	dump_tags = 1;
     	Swig_mark_arg(i);
    @@ -1145,6 +1155,14 @@ int SWIG_main(int argc, char *argv[], Language *l) {
           SwigType_print_scope(0);
         }
     
    +    if (dump_symtabs) {
    +      Swig_symbol_tables_print(Swig_symbol_global_scope());
    +    }
    +
    +    if (dump_qsymtabs) {
    +      Swig_symbol_tables_summary_print();
    +    }
    +
         if (dump_tags) {
           Swig_print_tags(top, 0);
         }
    diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
    index a5f13bd77..e415493a0 100644
    --- a/Source/Swig/swig.h
    +++ b/Source/Swig/swig.h
    @@ -200,6 +200,8 @@ extern "C" {
     
     /* --- Symbol table module --- */
     
    +  extern void Swig_symbol_tables_print(Symtab *symtab);
    +  extern void Swig_symbol_tables_summary_print(void);
       extern void Swig_symbol_init(void);
       extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
       extern String *Swig_symbol_getscopename(void);
    @@ -207,6 +209,7 @@ extern "C" {
       extern Symtab *Swig_symbol_newscope(void);
       extern Symtab *Swig_symbol_setscope(Symtab *);
       extern Symtab *Swig_symbol_getscope(const_String_or_char_ptr symname);
    +  extern Symtab *Swig_symbol_global_scope(void);
       extern Symtab *Swig_symbol_current(void);
       extern Symtab *Swig_symbol_popscope(void);
       extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
    diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
    index 3f9ce86af..a13361aa8 100644
    --- a/Source/Swig/symbol.c
    +++ b/Source/Swig/symbol.c
    @@ -175,20 +175,32 @@ static Hash *global_scope = 0;	/* Global scope */
     /* common attribute keys, to avoid calling find_key all the times */
     
     
    +/* -----------------------------------------------------------------------------
    + * Swig_symbol_tables_print()
    + *
    + * Debug display of symbol tables
    + * ----------------------------------------------------------------------------- */
     
    -#if 0
    -void Swig_symbol_dump_symtable() {
    -  Printf(stdout, "DUMPING SYMTABLE start =======================================\n");
    -  {
    -    Hash *cst = Getattr(current_symtab, "csymtab");
    -    Swig_print_tree(cst);
    -    /*
    -       Swig_print_tree(Getattr(cst, "NumSpace"));
    -     */
    -  }
    -  Printf(stdout, "DUMPING SYMTABLE end   =======================================\n");
    +void Swig_symbol_tables_print(Symtab *symtab) {
    +  if (!symtab)
    +    symtab = current_symtab;
    +
    +  Printf(stdout, "SYMBOL TABLES start  =======================================\n");
    +  Swig_print_tree(symtab);
    +  Printf(stdout, "SYMBOL TABLES finish =======================================\n");
    +}
    +
    +/* -----------------------------------------------------------------------------
    + * Swig_symbol_tables_summary_print()
    + *
    + * Debug summary display of all symbol tables by fully-qualified name 
    + * ----------------------------------------------------------------------------- */
    +
    +void Swig_symbol_tables_summary_print(void) {
    +  Printf(stdout, "SYMBOL TABLES SUMMARY start  =======================================\n");
    +  Swig_print_node(symtabs);
    +  Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
     }
    -#endif
     
     /* -----------------------------------------------------------------------------
      * Swig_symbol_init()
    @@ -196,7 +208,7 @@ void Swig_symbol_dump_symtable() {
      * Create a new symbol table object
      * ----------------------------------------------------------------------------- */
     
    -void Swig_symbol_init() {
    +void Swig_symbol_init(void) {
     
       current = NewHash();
       current_symtab = NewHash();
    @@ -240,7 +252,7 @@ void Swig_symbol_setscopename(const_String_or_char_ptr name) {
      * Get the C scopename of the current symbol table
      * ----------------------------------------------------------------------------- */
     
    -String *Swig_symbol_getscopename() {
    +String *Swig_symbol_getscopename(void) {
       return Getattr(current_symtab, "name");
     }
     
    @@ -295,7 +307,7 @@ String *Swig_symbol_qualifiedscopename(Symtab *symtab) {
      * Create a new scope.  Returns the newly created scope.
      * ----------------------------------------------------------------------------- */
     
    -Symtab *Swig_symbol_newscope() {
    +Symtab *Swig_symbol_newscope(void) {
       Hash *n;
       Hash *hsyms, *h;
     
    @@ -346,7 +358,7 @@ Symtab *Swig_symbol_setscope(Symtab *sym) {
      * scope to the parent scope.
      * ----------------------------------------------------------------------------- */
     
    -Symtab *Swig_symbol_popscope() {
    +Symtab *Swig_symbol_popscope(void) {
       Hash *h = current_symtab;
       current_symtab = Getattr(current_symtab, "parentNode");
       assert(current_symtab);
    @@ -357,13 +369,23 @@ Symtab *Swig_symbol_popscope() {
       return h;
     }
     
    +/* -----------------------------------------------------------------------------
    + * Swig_symbol_global_scope()
    + *
    + * Return the symbol table for the global scope.
    + * ----------------------------------------------------------------------------- */
    +
    +Symtab *Swig_symbol_global_scope(void) {
    +  return global_scope;
    +}
    +
     /* -----------------------------------------------------------------------------
      * Swig_symbol_current()
      *
      * Return the current symbol table.
      * ----------------------------------------------------------------------------- */
     
    -Symtab *Swig_symbol_current() {
    +Symtab *Swig_symbol_current(void) {
       return current_symtab;
     }
     
    
    From deba0e9285e15396c84314bbdb18bc44d99ef30c Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 7 Nov 2009 20:44:20 +0000
    Subject: [PATCH 054/146] re-organise symbol debugging options - add in
     -debug-symbols and -debug-csymbols, and remove -debug-qsymtab
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11726 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     CHANGES.current           |  8 +++---
     Doc/Manual/Extending.html | 39 ++++++++++++++-------------
     Source/Modules/main.cxx   | 24 ++++++++++++-----
     Source/Swig/swig.h        |  6 +++--
     Source/Swig/symbol.c      | 56 ++++++++++++++++++++++++++++++++++++---
     5 files changed, 97 insertions(+), 36 deletions(-)
    
    diff --git a/CHANGES.current b/CHANGES.current
    index b577367db..67d9f9aa1 100644
    --- a/CHANGES.current
    +++ b/CHANGES.current
    @@ -1,11 +1,11 @@
     Version 1.3.41 (in progress)
     ============================
     
    -2009-11-04: wsfulton
    +2009-11-07: wsfulton
     	    Add new debug options:
    -             -debug-symtabs  - Display symbol tables information
    -             -debug-qsymtabs - Display symbol tables summary information using fully
    -                               qualified names
    +              -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 global scope operator, for example:
    diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
    index 11578db97..040eb65c7 100644
    --- a/Doc/Manual/Extending.html
    +++ b/Doc/Manual/Extending.html
    @@ -2604,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);
    +          }
               ...
           }
       }
    @@ -3599,7 +3599,8 @@ There are various command line options which can aid debugging a SWIG interface
     -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-qsymtabs   - Display symbol tables summary information using fully qualified names
    +-debug-symbols    - Display target language symbols in the symbol tables
    +-debug-csymbols   - Display C symbols in the symbol tables
     -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
    diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
    index 30e8eb18a..30d12f26b 100644
    --- a/Source/Modules/main.cxx
    +++ b/Source/Modules/main.cxx
    @@ -63,7 +63,8 @@ static const char *usage1 = (const char *) "\
          -debug-classes  - Display information about the classes found in the interface\n\
          -debug-module - Display module parse tree at stages 1-4,  is a csv list of stages\n\
          -debug-symtabs  - Display symbol tables information\n\
    -     -debug-qsymtabs - Display symbol tables summary information using fully qualified names\n\
    +     -debug-symbols  - Display target language symbols in the symbol tables\n\
    +     -debug-csymbols - Display C symbols in the symbol tables\n\
          -debug-tags     - Display information about the tags found in the interface\n\
          -debug-template - Display information for debugging templates\n\
          -debug-top   - Display entire parse tree at stages 1-4,  is a csv list of stages\n\
    @@ -165,7 +166,8 @@ static char *outfile_name = 0;
     static char *outfile_name_h = 0;
     static int tm_debug = 0;
     static int dump_symtabs = 0;
    -static int dump_qsymtabs = 0;
    +static int dump_symbols = 0;
    +static int dump_csymbols = 0;
     static int dump_tags = 0;
     static int dump_module = 0;
     static int dump_top = 0;
    @@ -723,8 +725,11 @@ void SWIG_getoptions(int argc, char *argv[]) {
           } else if (strcmp(argv[i], "-debug-symtabs") == 0) {
     	dump_symtabs = 1;
     	Swig_mark_arg(i);
    -      } else if (strcmp(argv[i], "-debug-qsymtabs") == 0) {
    -	dump_qsymtabs = 1;
    +      } else if (strcmp(argv[i], "-debug-symbols") == 0) {
    +	dump_symbols = 1;
    +	Swig_mark_arg(i);
    +      } else if (strcmp(argv[i], "-debug-csymbols") == 0) {
    +	dump_csymbols = 1;
     	Swig_mark_arg(i);
           } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
     	dump_tags = 1;
    @@ -1156,11 +1161,16 @@ int SWIG_main(int argc, char *argv[], Language *l) {
         }
     
         if (dump_symtabs) {
    -      Swig_symbol_tables_print(Swig_symbol_global_scope());
    +      Swig_symbol_print_tables(Swig_symbol_global_scope());
    +      Swig_symbol_print_tables_summary();
         }
     
    -    if (dump_qsymtabs) {
    -      Swig_symbol_tables_summary_print();
    +    if (dump_symbols) {
    +      Swig_symbol_print_symbols();
    +    }
    +
    +    if (dump_csymbols) {
    +      Swig_symbol_print_csymbols();
         }
     
         if (dump_tags) {
    diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
    index e415493a0..33f977b52 100644
    --- a/Source/Swig/swig.h
    +++ b/Source/Swig/swig.h
    @@ -200,8 +200,10 @@ extern "C" {
     
     /* --- Symbol table module --- */
     
    -  extern void Swig_symbol_tables_print(Symtab *symtab);
    -  extern void Swig_symbol_tables_summary_print(void);
    +  extern void Swig_symbol_print_tables(Symtab *symtab);
    +  extern void Swig_symbol_print_tables_summary(void);
    +  extern void Swig_symbol_print_symbols(void);
    +  extern void Swig_symbol_print_csymbols(void);
       extern void Swig_symbol_init(void);
       extern void Swig_symbol_setscopename(const_String_or_char_ptr name);
       extern String *Swig_symbol_getscopename(void);
    diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
    index a13361aa8..ae8a274c6 100644
    --- a/Source/Swig/symbol.c
    +++ b/Source/Swig/symbol.c
    @@ -176,12 +176,12 @@ static Hash *global_scope = 0;	/* Global scope */
     
     
     /* -----------------------------------------------------------------------------
    - * Swig_symbol_tables_print()
    + * Swig_symbol_print_tables()
      *
      * Debug display of symbol tables
      * ----------------------------------------------------------------------------- */
     
    -void Swig_symbol_tables_print(Symtab *symtab) {
    +void Swig_symbol_print_tables(Symtab *symtab) {
       if (!symtab)
         symtab = current_symtab;
     
    @@ -191,17 +191,65 @@ void Swig_symbol_tables_print(Symtab *symtab) {
     }
     
     /* -----------------------------------------------------------------------------
    - * Swig_symbol_tables_summary_print()
    + * Swig_symbol_print_tables_summary()
      *
      * Debug summary display of all symbol tables by fully-qualified name 
      * ----------------------------------------------------------------------------- */
     
    -void Swig_symbol_tables_summary_print(void) {
    +void Swig_symbol_print_tables_summary(void) {
       Printf(stdout, "SYMBOL TABLES SUMMARY start  =======================================\n");
       Swig_print_node(symtabs);
       Printf(stdout, "SYMBOL TABLES SUMMARY finish =======================================\n");
     }
     
    +/* -----------------------------------------------------------------------------
    + * symbol_print_symbols()
    + * ----------------------------------------------------------------------------- */
    +
    +static void symbol_print_symbols(const char *symboltabletype) {
    +  Node *obj = symtabs;
    +  Iterator ki = First(obj);
    +  while (ki.key) {
    +    String *k = ki.key;
    +    Printf(stdout, "===================================================\n");
    +    Printf(stdout, "%s -\n", k);
    +    {
    +      Symtab *symtab = Getattr(Getattr(obj, k), symboltabletype);
    +      Iterator it = First(symtab);
    +      while (it.key) {
    +	String *symname = it.key;
    +	Printf(stdout, "  %s\n", symname);
    +	it = Next(it);
    +      }
    +    }
    +    ki = Next(ki);
    +  }
    +}
    +
    +/* -----------------------------------------------------------------------------
    + * Swig_symbol_print_symbols()
    + *
    + * Debug display of all the target language symbols
    + * ----------------------------------------------------------------------------- */
    +
    +void Swig_symbol_print_symbols(void) {
    +  Printf(stdout, "SYMBOLS start  =======================================\n");
    +  symbol_print_symbols("symtab");
    +  Printf(stdout, "SYMBOLS finish =======================================\n");
    +}
    +
    +/* -----------------------------------------------------------------------------
    + * Swig_symbol_print_csymbols()
    + *
    + * Debug display of all the C symbols
    + * ----------------------------------------------------------------------------- */
    +
    +void Swig_symbol_print_csymbols(void) {
    +  Printf(stdout, "CSYMBOLS start  =======================================\n");
    +  symbol_print_symbols("csymtab");
    +  Printf(stdout, "CSYMBOLS finish =======================================\n");
    +}
    +
     /* -----------------------------------------------------------------------------
      * Swig_symbol_init()
      *
    
    From ec6bf1ec9625f5f9cd42d619369c1cd35e65092d Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sun, 8 Nov 2009 00:14:47 +0000
    Subject: [PATCH 055/146] Fix nested template classes within a namespace
     generating uncompileable code by incorrectly adding in symbols into the
     symbol tables and not setting the scope correctly after the nested template
     was parsed
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11727 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     CHANGES.current                               |   7 +-
     Examples/test-suite/common.mk                 |   1 +
     .../java/template_nested_runme.java           |  30 +
     Examples/test-suite/template_nested.i         |  91 +++
     Source/CParse/parser.y                        | 704 +++++++++---------
     5 files changed, 500 insertions(+), 333 deletions(-)
     create mode 100644 Examples/test-suite/java/template_nested_runme.java
     create mode 100644 Examples/test-suite/template_nested.i
    
    diff --git a/CHANGES.current b/CHANGES.current
    index 67d9f9aa1..8192f30b5 100644
    --- a/CHANGES.current
    +++ b/CHANGES.current
    @@ -1,6 +1,11 @@
     Version 1.3.41 (in progress)
     ============================
     
    +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
    @@ -13,7 +18,7 @@ Version 1.3.41 (in progress)
                   namespace AA { /* ... */ }
                   using namespace ::AA;
     
    -            and bug #1816802 - SwigValueWrapper should be used ::
    +            and bug #1816802 - SwigValueWrapper should be used:
     
                   struct CC {
                     CC(int); // no default constructor
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index 7bc5a9fa0..473d6579d 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -330,6 +330,7 @@ CPP_TEST_CASES += \
     	template_inherit_abstract \
     	template_int_const \
     	template_methods \
    +	template_nested \
     	template_nested_typemaps \
     	template_ns \
     	template_ns2 \
    diff --git a/Examples/test-suite/java/template_nested_runme.java b/Examples/test-suite/java/template_nested_runme.java
    new file mode 100644
    index 000000000..407821674
    --- /dev/null
    +++ b/Examples/test-suite/java/template_nested_runme.java
    @@ -0,0 +1,30 @@
    +
    +import template_nested.*;
    +
    +public class template_nested_runme {
    +
    +  static {
    +    try {
    +	System.loadLibrary("template_nested");
    +    } catch (UnsatisfiedLinkError e) {
    +      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
    +      System.exit(1);
    +    }
    +  }
    +
    +  public static void main(String argv[]) {
    +    new T_NormalTemplateNormalClass().tmethod(new NormalClass());
    +    new OuterClass().T_OuterTMethodNormalClass(new NormalClass());
    +
    +    TemplateFuncs tf = new TemplateFuncs();
    +    if (tf.T_TemplateFuncs1Int(-10) != -10)
    +      throw new RuntimeException("it failed");
    +    if (tf.T_TemplateFuncs2Double(-12.3) != -12.3)
    +      throw new RuntimeException("it failed");
    +
    +    T_NestedOuterTemplateDouble tn = new T_NestedOuterTemplateDouble();
    +    if (tn.hohum(-12.3) != -12.3)
    +      throw new RuntimeException("it failed");
    +  }
    +}
    +
    diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i
    new file mode 100644
    index 000000000..cb5eddb50
    --- /dev/null
    +++ b/Examples/test-suite/template_nested.i
    @@ -0,0 +1,91 @@
    +%module template_nested
    +
    +// Test nested templates - that is template classes and template methods within a class.
    +
    +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
    +
    +%inline %{
    +
    +namespace ns {
    +
    +  class NormalClass {
    +  public:
    +    NormalClass() {}
    +    ~NormalClass() {}
    +  };
    +
    +  template  struct NormalTemplate {
    +    void tmethod(T t) {}
    +  };
    +
    +  class OuterClass {
    +  public:
    +    template  struct Inner1 {
    +      template  struct SuperInner1 {
    +        void method1(U t) {}
    +      };
    +      template  struct SuperInner2 {
    +        void method1(V t) {}
    +      };
    +      template  void tmethod(W w) {}
    +      template  void tmethodAgain(X x) {}
    +      template  struct SuperBase : public SuperInner1 {
    +        void method1(Y y) {}
    +      };
    +    };
    +
    +    template  void InnerTMethod(Z z) {}
    +
    +    template  class Inner2 : public NormalTemplate {
    +    public:
    +      template  class SuperInner1 {
    +      public:
    +        SuperInner1() {}
    +        void method1(U t) {}
    +      };
    +      template  struct SuperInner2 {
    +        void method1(V t) {}
    +      };
    +      int embeddedVar;
    +      template  void tmethod(X x) {}
    +      template  struct SuperBase : public SuperInner1 {
    +        void method1(Y y) {}
    +      };
    +    };
    +    int iii;
    +  };
    +  struct ABC {
    +    ABC() {}
    +    ~ABC() {}
    +  };
    +
    +  struct TemplateFuncs {
    +    template  X templateMethod1(X x) { return x; }
    +    template  X templateMethod2(X x) { return x; }
    +  };
    +
    +  template  struct OuterTemplate {
    +    template  struct NestedInnerTemplate1 {
    +      template  void NestedInnerInnerTMethod(Z z) {}
    +      void hohum() {}
    +    };
    +    template  void NestedInnerTMethod(UU u, W w) {}
    +    template  struct NestedInnerTemplate2 {
    +      void hohum() {}
    +    };
    +    UU hohum(UU u) { return u; }
    +    struct NestedStruct {
    +      NestedStruct() {}
    +      void hohum() {}
    +    };
    +  };
    +}
    +
    +%}
    +
    +%template(T_NormalTemplateNormalClass) ns::NormalTemplate;
    +%template(T_OuterTMethodNormalClass) ns::OuterClass::InnerTMethod;
    +%template(T_TemplateFuncs1Int) ns::TemplateFuncs::templateMethod1;
    +%template(T_TemplateFuncs2Double) ns::TemplateFuncs::templateMethod2;
    +%template(T_NestedOuterTemplateDouble) ns::OuterTemplate;
    +
    diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
    index 954b7af77..1cd7dc750 100644
    --- a/Source/CParse/parser.y
    +++ b/Source/CParse/parser.y
    @@ -43,6 +43,7 @@ static Node    *module_node = 0;
     static String  *Classprefix = 0;  
     static String  *Namespaceprefix = 0;
     static int      inclass = 0;
    +static int      nested_template = 0; /* template class/function definition within a class */
     static char    *last_cpptype = 0;
     static int      inherit_list = 0;
     static Parm    *template_parameters = 0;
    @@ -272,6 +273,14 @@ static int  add_only_one = 0;
     static void add_symbols(Node *n) {
       String *decl;
       String *wrn = 0;
    +
    +  if (nested_template) {
    +    if (!(n && Equal(nodeType(n), "template"))) {
    +      return;
    +    }
    +    /* continue if template function, but not template class, declared within a class */
    +  }
    +
       if (inclass && n) {
         cparse_normalize_void(n);
       }
    @@ -3227,10 +3236,10 @@ cpp_declaration : cpp_class_decl {  $$ = $1; }
                     | cpp_catch_decl { $$ = 0; }
                     ;
     
    -cpp_class_decl  :
     
     /* A simple class/struct/union definition */
    -                storage_class cpptype idcolon inherit LBRACE {
    +cpp_class_decl  : storage_class cpptype idcolon inherit LBRACE {
    +                 if (nested_template == 0) {
                        List *bases = 0;
     		   Node *scope = 0;
     		   $$ = new_node("class");
    @@ -3344,120 +3353,128 @@ cpp_class_decl  :
     		   }
     		   class_decl[class_level++] = $$;
     		   inclass = 1;
    +		 }
                    } cpp_members RBRACE cpp_opt_declarators {
    -		 Node *p;
    -		 SwigType *ty;
    -		 Symtab *cscope = prev_symtab;
    -		 Node *am = 0;
    -		 String *scpname = 0;
    -		 $$ = class_decl[--class_level];
    -		 inclass = 0;
    -		 
    -		 /* Check for pure-abstract class */
    -		 Setattr($$,"abstract", pure_abstract($7));
    -		 
    -		 /* This bit of code merges in a previously defined %extend directive (if any) */
    -		 
    -		 if (extendhash) {
    -		   String *clsname = Swig_symbol_qualifiedscopename(0);
    -		   am = Getattr(extendhash,clsname);
    -		   if (am) {
    -		     merge_extensions($$,am);
    -		     Delattr(extendhash,clsname);
    +		 if (nested_template == 0) {
    +		   Node *p;
    +		   SwigType *ty;
    +		   Symtab *cscope = prev_symtab;
    +		   Node *am = 0;
    +		   String *scpname = 0;
    +		   $$ = class_decl[--class_level];
    +		   inclass = 0;
    +		   
    +		   /* Check for pure-abstract class */
    +		   Setattr($$,"abstract", pure_abstract($7));
    +		   
    +		   /* This bit of code merges in a previously defined %extend directive (if any) */
    +		   
    +		   if (extendhash) {
    +		     String *clsname = Swig_symbol_qualifiedscopename(0);
    +		     am = Getattr(extendhash,clsname);
    +		     if (am) {
    +		       merge_extensions($$,am);
    +		       Delattr(extendhash,clsname);
    +		     }
    +		     Delete(clsname);
     		   }
    -		   Delete(clsname);
    -		 }
    -		 if (!classes) classes = NewHash();
    -		 scpname = Swig_symbol_qualifiedscopename(0);
    -		 Setattr(classes,scpname,$$);
    -		 Delete(scpname);
    +		   if (!classes) classes = NewHash();
    +		   scpname = Swig_symbol_qualifiedscopename(0);
    +		   Setattr(classes,scpname,$$);
    +		   Delete(scpname);
     
    -		 appendChild($$,$7);
    -		 
    -		 if (am) append_previous_extension($$,am);
    +		   appendChild($$,$7);
    +		   
    +		   if (am) append_previous_extension($$,am);
     
    -		 p = $9;
    -		 if (p) {
    -		   set_nextSibling($$,p);
    -		 }
    -		 
    -		 if (cparse_cplusplus && !cparse_externc) {
    -		   ty = NewString($3);
    -		 } else {
    -		   ty = NewStringf("%s %s", $2,$3);
    -		 }
    -		 while (p) {
    -		   Setattr(p,"storage",$1);
    -		   Setattr(p,"type",ty);
    -		   p = nextSibling(p);
    -		 }
    -		 /* Dump nested classes */
    -		 {
    -		   String *name = $3;
    -		   if ($9) {
    -		     SwigType *decltype = Getattr($9,"decl");
    -		     if (Cmp($1,"typedef") == 0) {
    -		       if (!decltype || !Len(decltype)) {
    -			 String *cname;
    -			 name = Getattr($9,"name");
    -			 cname = Copy(name);
    -			 Setattr($$,"tdname",cname);
    -			 Delete(cname);
    +		   p = $9;
    +		   if (p) {
    +		     set_nextSibling($$,p);
    +		   }
    +		   
    +		   if (cparse_cplusplus && !cparse_externc) {
    +		     ty = NewString($3);
    +		   } else {
    +		     ty = NewStringf("%s %s", $2,$3);
    +		   }
    +		   while (p) {
    +		     Setattr(p,"storage",$1);
    +		     Setattr(p,"type",ty);
    +		     p = nextSibling(p);
    +		   }
    +		   /* Dump nested classes */
    +		   {
    +		     String *name = $3;
    +		     if ($9) {
    +		       SwigType *decltype = Getattr($9,"decl");
    +		       if (Cmp($1,"typedef") == 0) {
    +			 if (!decltype || !Len(decltype)) {
    +			   String *cname;
    +			   name = Getattr($9,"name");
    +			   cname = Copy(name);
    +			   Setattr($$,"tdname",cname);
    +			   Delete(cname);
     
    -			 /* Use typedef name as class name */
    -			 if (class_rename && (Strcmp(class_rename,$3) == 0)) {
    -			   Delete(class_rename);
    -			   class_rename = NewString(name);
    +			   /* Use typedef name as class name */
    +			   if (class_rename && (Strcmp(class_rename,$3) == 0)) {
    +			     Delete(class_rename);
    +			     class_rename = NewString(name);
    +			   }
    +			   if (!Getattr(classes,name)) {
    +			     Setattr(classes,name,$$);
    +			   }
    +			   Setattr($$,"decl",decltype);
     			 }
    -			 if (!Getattr(classes,name)) {
    -			   Setattr(classes,name,$$);
    -			 }
    -			 Setattr($$,"decl",decltype);
     		       }
     		     }
    +		     appendChild($$,dump_nested(Char(name)));
     		   }
    -		   appendChild($$,dump_nested(Char(name)));
    -		 }
     
    -		 if (cplus_mode != CPLUS_PUBLIC) {
    -		 /* we 'open' the class at the end, to allow %template
    -		    to add new members */
    -		   Node *pa = new_node("access");
    -		   Setattr(pa,"kind","public");
    -		   cplus_mode = CPLUS_PUBLIC;
    -		   appendChild($$,pa);
    -		   Delete(pa);
    -		 }
    +		   if (cplus_mode != CPLUS_PUBLIC) {
    +		   /* we 'open' the class at the end, to allow %template
    +		      to add new members */
    +		     Node *pa = new_node("access");
    +		     Setattr(pa,"kind","public");
    +		     cplus_mode = CPLUS_PUBLIC;
    +		     appendChild($$,pa);
    +		     Delete(pa);
    +		   }
     
    -		 Setattr($$,"symtab",Swig_symbol_popscope());
    +		   Setattr($$,"symtab",Swig_symbol_popscope());
     
    -		 Classprefix = 0;
    -		 if (nscope_inner) {
    -		   /* this is tricky */
    -		   /* we add the declaration in the original namespace */
    -		   appendChild(nscope_inner,$$);
    -		   Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
    -		   Delete(Namespaceprefix);
    -		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    -		   add_symbols($$);
    -		   if (nscope) $$ = nscope;
    -		   /* but the variable definition in the current scope */
    +		   Classprefix = 0;
    +		   if (nscope_inner) {
    +		     /* this is tricky */
    +		     /* we add the declaration in the original namespace */
    +		     appendChild(nscope_inner,$$);
    +		     Swig_symbol_setscope(Getattr(nscope_inner,"symtab"));
    +		     Delete(Namespaceprefix);
    +		     Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    +		     add_symbols($$);
    +		     if (nscope) $$ = nscope;
    +		     /* but the variable definition in the current scope */
    +		     Swig_symbol_setscope(cscope);
    +		     Delete(Namespaceprefix);
    +		     Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    +		     add_symbols($9);
    +		   } else {
    +		     Delete(yyrename);
    +		     yyrename = Copy(class_rename);
    +		     Delete(Namespaceprefix);
    +		     Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    +
    +		     add_symbols($$);
    +		     add_symbols($9);
    +		   }
     		   Swig_symbol_setscope(cscope);
     		   Delete(Namespaceprefix);
     		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    -		   add_symbols($9);
     		 } else {
    -		   Delete(yyrename);
    -		   yyrename = Copy(class_rename);
    -		   Delete(Namespaceprefix);
    -		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    -
    -		   add_symbols($$);
    -		   add_symbols($9);
    +		    $$ = new_node("class");
    +		    Setattr($$,"kind",$2);
    +		    Setattr($$,"name",NewString($3));
    +		    SetFlag($$,"nestedtemplateclass");
     		 }
    -		 Swig_symbol_setscope(cscope);
    -		 Delete(Namespaceprefix);
    -		 Namespaceprefix = Swig_symbol_qualifiedscopename(0);
     	       }
     
     /* An unnamed struct, possibly with a typedef */
    @@ -3617,253 +3634,276 @@ cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
        template<...> decl
        ------------------------------------------------------------ */
     
    -cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible {
    -		      String *tname = 0;
    -		      int     error = 0;
    +cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { 
    +		    template_parameters = $3; 
    +		    if (inclass)
    +		      nested_template++;
     
    -		      /* check if we get a namespace node with a class declaration, and retrieve the class */
    -		      Symtab *cscope = Swig_symbol_current();
    -		      Symtab *sti = 0;
    -		      Node *ntop = $6;
    -		      Node *ni = ntop;
    -		      SwigType *ntype = ni ? nodeType(ni) : 0;
    -		      while (ni && Strcmp(ntype,"namespace") == 0) {
    -			sti = Getattr(ni,"symtab");
    -			ni = firstChild(ni);
    -			ntype = nodeType(ni);
    -		      }
    -		      if (sti) {
    -			Swig_symbol_setscope(sti);
    -			Delete(Namespaceprefix);
    -			Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    -			$6 = ni;
    -		      }
    +		  } cpp_temp_possible {
     
    -                      template_parameters = 0;
    -                      $$ = $6;
    -		      if ($$) tname = Getattr($$,"name");
    -		      
    -		      /* Check if the class is a template specialization */
    -		      if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
    -			/* If a specialization.  Check if defined. */
    -			Node *tempn = 0;
    -			{
    -			  String *tbase = SwigType_templateprefix(tname);
    -			  tempn = Swig_symbol_clookup_local(tbase,0);
    -			  if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
    -			    SWIG_WARN_NODE_BEGIN(tempn);
    -			    Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
    -			    SWIG_WARN_NODE_END(tempn);
    -			    tempn = 0;
    -			    error = 1;
    -			  }
    -			  Delete(tbase);
    +		    /* Don't ignore templated functions declared within a class, unless the templated function is within a nested class */
    +		    if (nested_template <= 1) {
    +		      int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass");
    +		      if (is_nested_template_class) {
    +			/* Nested template classes would probably better be ignored like ordinary nested classes using cpp_nested, but that introduces shift/reduce conflicts */
    +			if (cplus_mode == CPLUS_PUBLIC) {
    +			  Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored)\n", Getattr($6, "kind"), Getattr($6, "name"));
     			}
    -			Setattr($$,"specialization","1");
    -			Setattr($$,"templatetype",nodeType($$));
    -			set_nodeType($$,"template");
    -			/* Template partial specialization */
    -			if (tempn && ($3) && ($6)) {
    -			  List   *tlist;
    -			  String *targs = SwigType_templateargs(tname);
    -			  tlist = SwigType_parmlist(targs);
    -			  /*			  Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
    +			Delete($6);
    +			$$ = 0;
    +		      } else {
    +			String *tname = 0;
    +			int     error = 0;
    +
    +			/* check if we get a namespace node with a class declaration, and retrieve the class */
    +			Symtab *cscope = Swig_symbol_current();
    +			Symtab *sti = 0;
    +			Node *ntop = $6;
    +			Node *ni = ntop;
    +			SwigType *ntype = ni ? nodeType(ni) : 0;
    +			while (ni && Strcmp(ntype,"namespace") == 0) {
    +			  sti = Getattr(ni,"symtab");
    +			  ni = firstChild(ni);
    +			  ntype = nodeType(ni);
    +			}
    +			if (sti) {
    +			  Swig_symbol_setscope(sti);
    +			  Delete(Namespaceprefix);
    +			  Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    +			  $6 = ni;
    +			}
    +
    +			$$ = $6;
    +			if ($$) tname = Getattr($$,"name");
    +			
    +			/* Check if the class is a template specialization */
    +			if (($$) && (Strchr(tname,'<')) && (!is_operator(tname))) {
    +			  /* If a specialization.  Check if defined. */
    +			  Node *tempn = 0;
    +			  {
    +			    String *tbase = SwigType_templateprefix(tname);
    +			    tempn = Swig_symbol_clookup_local(tbase,0);
    +			    if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) {
    +			      SWIG_WARN_NODE_BEGIN(tempn);
    +			      Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase);
    +			      SWIG_WARN_NODE_END(tempn);
    +			      tempn = 0;
    +			      error = 1;
    +			    }
    +			    Delete(tbase);
    +			  }
    +			  Setattr($$,"specialization","1");
    +			  Setattr($$,"templatetype",nodeType($$));
    +			  set_nodeType($$,"template");
    +			  /* Template partial specialization */
    +			  if (tempn && ($3) && ($6)) {
    +			    List   *tlist;
    +			    String *targs = SwigType_templateargs(tname);
    +			    tlist = SwigType_parmlist(targs);
    +			    /*			  Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
    +			    if (!Getattr($$,"sym:weak")) {
    +			      Setattr($$,"sym:typename","1");
    +			    }
    +			    
    +			    if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
    +			      Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
    +			      
    +			    } else {
    +
    +			    /* This code builds the argument list for the partial template
    +			       specialization.  This is a little hairy, but the idea is as
    +			       follows:
    +
    +			       $3 contains a list of arguments supplied for the template.
    +			       For example template.
    +
    +			       tlist is a list of the specialization arguments--which may be
    +			       different.  For example class.
    +
    +			       tp is a copy of the arguments in the original template definition.
    +       
    +			       The patching algorithm walks through the list of supplied
    +			       arguments ($3), finds the position in the specialization arguments
    +			       (tlist), and then patches the name in the argument list of the
    +			       original template.
    +			    */
    +
    +			    {
    +			      String *pn;
    +			      Parm *p, *p1;
    +			      int i, nargs;
    +			      Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
    +			      nargs = Len(tlist);
    +			      p = $3;
    +			      while (p) {
    +				for (i = 0; i < nargs; i++){
    +				  pn = Getattr(p,"name");
    +				  if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
    +				    int j;
    +				    Parm *p1 = tp;
    +				    for (j = 0; j < i; j++) {
    +				      p1 = nextSibling(p1);
    +				    }
    +				    Setattr(p1,"name",pn);
    +				    Setattr(p1,"partialarg","1");
    +				  }
    +				}
    +				p = nextSibling(p);
    +			      }
    +			      p1 = tp;
    +			      i = 0;
    +			      while (p1) {
    +				if (!Getattr(p1,"partialarg")) {
    +				  Delattr(p1,"name");
    +				  Setattr(p1,"type", Getitem(tlist,i));
    +				} 
    +				i++;
    +				p1 = nextSibling(p1);
    +			      }
    +			      Setattr($$,"templateparms",tp);
    +			      Delete(tp);
    +			    }
    +  #if 0
    +			    /* Patch the parameter list */
    +			    if (tempn) {
    +			      Parm *p,*p1;
    +			      ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
    +			      p = $3;
    +			      p1 = tp;
    +			      while (p && p1) {
    +				String *pn = Getattr(p,"name");
    +				Printf(stdout,"pn = '%s'\n", pn);
    +				if (pn) Setattr(p1,"name",pn);
    +				else Delattr(p1,"name");
    +				pn = Getattr(p,"type");
    +				if (pn) Setattr(p1,"type",pn);
    +				p = nextSibling(p);
    +				p1 = nextSibling(p1);
    +			      }
    +			      Setattr($$,"templateparms",tp);
    +			      Delete(tp);
    +			    } else {
    +			      Setattr($$,"templateparms",$3);
    +			    }
    +  #endif
    +			    Delattr($$,"specialization");
    +			    Setattr($$,"partialspecialization","1");
    +			    /* Create a specialized name for matching */
    +			    {
    +			      Parm *p = $3;
    +			      String *fname = NewString(Getattr($$,"name"));
    +			      String *ffname = 0;
    +			      ParmList *partialparms = 0;
    +
    +			      char   tmp[32];
    +			      int    i, ilen;
    +			      while (p) {
    +				String *n = Getattr(p,"name");
    +				if (!n) {
    +				  p = nextSibling(p);
    +				  continue;
    +				}
    +				ilen = Len(tlist);
    +				for (i = 0; i < ilen; i++) {
    +				  if (Strstr(Getitem(tlist,i),n)) {
    +				    sprintf(tmp,"$%d",i+1);
    +				    Replaceid(fname,n,tmp);
    +				  }
    +				}
    +				p = nextSibling(p);
    +			      }
    +			      /* Patch argument names with typedef */
    +			      {
    +				Iterator tt;
    +				Parm *parm_current = 0;
    +				List *tparms = SwigType_parmlist(fname);
    +				ffname = SwigType_templateprefix(fname);
    +				Append(ffname,"<(");
    +				for (tt = First(tparms); tt.item; ) {
    +				  SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
    +				  SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
    +
    +				  Parm *newp = NewParm(ttr, 0);
    +				  if (partialparms)
    +				    set_nextSibling(parm_current, newp);
    +				  else
    +				    partialparms = newp;
    +				  parm_current = newp;
    +
    +				  Append(ffname,ttr);
    +				  tt = Next(tt);
    +				  if (tt.item) Putc(',',ffname);
    +				  Delete(rtt);
    +				  Delete(ttr);
    +				}
    +				Delete(tparms);
    +				Append(ffname,")>");
    +			      }
    +			      {
    +				Node *new_partial = NewHash();
    +				String *partials = Getattr(tempn,"partials");
    +				if (!partials) {
    +				  partials = NewList();
    +				  Setattr(tempn,"partials",partials);
    +				  Delete(partials);
    +				}
    +				/*			      Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
    +				Setattr(new_partial, "partialparms", partialparms);
    +				Setattr(new_partial, "templcsymname", ffname);
    +				Append(partials, new_partial);
    +			      }
    +			      Setattr($$,"partialargs",ffname);
    +			      Swig_symbol_cadd(ffname,$$);
    +			    }
    +			    }
    +			    Delete(tlist);
    +			    Delete(targs);
    +			  } else {
    +			    /* An explicit template specialization */
    +			    /* add default args from primary (unspecialized) template */
    +			    String *ty = Swig_symbol_template_deftype(tname,0);
    +			    String *fname = Swig_symbol_type_qualify(ty,0);
    +			    Swig_symbol_cadd(fname,$$);
    +			    Delete(ty);
    +			    Delete(fname);
    +			  }
    +			}  else if ($$) {
    +			  Setattr($$,"templatetype",nodeType($6));
    +			  set_nodeType($$,"template");
    +			  Setattr($$,"templateparms", $3);
     			  if (!Getattr($$,"sym:weak")) {
     			    Setattr($$,"sym:typename","1");
     			  }
    -			  
    -			  if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
    -			    Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
    -			    
    -			  } else {
    -
    -			  /* This code builds the argument list for the partial template
    -                             specialization.  This is a little hairy, but the idea is as
    -                             follows:
    -
    -                             $3 contains a list of arguments supplied for the template.
    -                             For example template.
    -
    -                             tlist is a list of the specialization arguments--which may be
    -                             different.  For example class.
    -
    -                             tp is a copy of the arguments in the original template definition.
    -     
    -                             The patching algorithm walks through the list of supplied
    -                             arguments ($3), finds the position in the specialization arguments
    -                             (tlist), and then patches the name in the argument list of the
    -                             original template.
    -			  */
    -
    +			  add_symbols($$);
    +			  default_arguments($$);
    +			  /* We also place a fully parameterized version in the symbol table */
     			  {
    -			    String *pn;
    -			    Parm *p, *p1;
    -			    int i, nargs;
    -			    Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
    -			    nargs = Len(tlist);
    +			    Parm *p;
    +			    String *fname = NewStringf("%s<(", Getattr($$,"name"));
     			    p = $3;
    -			    while (p) {
    -			      for (i = 0; i < nargs; i++){
    -				pn = Getattr(p,"name");
    -				if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
    -				  int j;
    -				  Parm *p1 = tp;
    -				  for (j = 0; j < i; j++) {
    -				    p1 = nextSibling(p1);
    -				  }
    -				  Setattr(p1,"name",pn);
    -				  Setattr(p1,"partialarg","1");
    -				}
    -			      }
    -			      p = nextSibling(p);
    -			    }
    -			    p1 = tp;
    -			    i = 0;
    -			    while (p1) {
    -			      if (!Getattr(p1,"partialarg")) {
    -				Delattr(p1,"name");
    -				Setattr(p1,"type", Getitem(tlist,i));
    -			      } 
    -			      i++;
    -			      p1 = nextSibling(p1);
    -			    }
    -			    Setattr($$,"templateparms",tp);
    -			    Delete(tp);
    -			  }
    -#if 0
    -			  /* Patch the parameter list */
    -			  if (tempn) {
    -			    Parm *p,*p1;
    -			    ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
    -			    p = $3;
    -			    p1 = tp;
    -			    while (p && p1) {
    -			      String *pn = Getattr(p,"name");
    -			      Printf(stdout,"pn = '%s'\n", pn);
    -			      if (pn) Setattr(p1,"name",pn);
    -			      else Delattr(p1,"name");
    -			      pn = Getattr(p,"type");
    -			      if (pn) Setattr(p1,"type",pn);
    -			      p = nextSibling(p);
    -			      p1 = nextSibling(p1);
    -			    }
    -			    Setattr($$,"templateparms",tp);
    -			    Delete(tp);
    -			  } else {
    -			    Setattr($$,"templateparms",$3);
    -			  }
    -#endif
    -			  Delattr($$,"specialization");
    -			  Setattr($$,"partialspecialization","1");
    -			  /* Create a specialized name for matching */
    -			  {
    -			    Parm *p = $3;
    -			    String *fname = NewString(Getattr($$,"name"));
    -			    String *ffname = 0;
    -			    ParmList *partialparms = 0;
    -
    -			    char   tmp[32];
    -			    int    i, ilen;
     			    while (p) {
     			      String *n = Getattr(p,"name");
    -			      if (!n) {
    -				p = nextSibling(p);
    -				continue;
    -			      }
    -			      ilen = Len(tlist);
    -			      for (i = 0; i < ilen; i++) {
    -				if (Strstr(Getitem(tlist,i),n)) {
    -				  sprintf(tmp,"$%d",i+1);
    -				  Replaceid(fname,n,tmp);
    -				}
    -			      }
    +			      if (!n) n = Getattr(p,"type");
    +			      Append(fname,n);
     			      p = nextSibling(p);
    +			      if (p) Putc(',',fname);
     			    }
    -			    /* Patch argument names with typedef */
    -			    {
    -			      Iterator tt;
    -			      Parm *parm_current = 0;
    -			      List *tparms = SwigType_parmlist(fname);
    -			      ffname = SwigType_templateprefix(fname);
    -			      Append(ffname,"<(");
    -			      for (tt = First(tparms); tt.item; ) {
    -				SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0);
    -				SwigType *ttr = Swig_symbol_type_qualify(rtt,0);
    -
    -				Parm *newp = NewParm(ttr, 0);
    -				if (partialparms)
    -				  set_nextSibling(parm_current, newp);
    -				else
    -				  partialparms = newp;
    -				parm_current = newp;
    -
    -				Append(ffname,ttr);
    -				tt = Next(tt);
    -				if (tt.item) Putc(',',ffname);
    -				Delete(rtt);
    -				Delete(ttr);
    -			      }
    -			      Delete(tparms);
    -			      Append(ffname,")>");
    -			    }
    -			    {
    -			      Node *new_partial = NewHash();
    -			      String *partials = Getattr(tempn,"partials");
    -			      if (!partials) {
    -				partials = NewList();
    -				Setattr(tempn,"partials",partials);
    -				Delete(partials);
    -			      }
    -			      /*			      Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */
    -			      Setattr(new_partial, "partialparms", partialparms);
    -			      Setattr(new_partial, "templcsymname", ffname);
    -			      Append(partials, new_partial);
    -			    }
    -			    Setattr($$,"partialargs",ffname);
    -			    Swig_symbol_cadd(ffname,$$);
    +			    Append(fname,")>");
    +			    Swig_symbol_cadd(fname,$$);
     			  }
    -			  }
    -			  Delete(tlist);
    -			  Delete(targs);
    -			} else {
    -			  /* An explicit template specialization */
    -			  /* add default args from primary (unspecialized) template */
    -			  String *ty = Swig_symbol_template_deftype(tname,0);
    -			  String *fname = Swig_symbol_type_qualify(ty,0);
    -			  Swig_symbol_cadd(fname,$$);
    -			  Delete(ty);
    -			  Delete(fname);
    -			}
    -		      }  else if ($$) {
    -			Setattr($$,"templatetype",nodeType($6));
    -			set_nodeType($$,"template");
    -			Setattr($$,"templateparms", $3);
    -			if (!Getattr($$,"sym:weak")) {
    -			  Setattr($$,"sym:typename","1");
    -			}
    -			add_symbols($$);
    -                        default_arguments($$);
    -			/* We also place a fully parameterized version in the symbol table */
    -			{
    -			  Parm *p;
    -			  String *fname = NewStringf("%s<(", Getattr($$,"name"));
    -			  p = $3;
    -			  while (p) {
    -			    String *n = Getattr(p,"name");
    -			    if (!n) n = Getattr(p,"type");
    -			    Append(fname,n);
    -			    p = nextSibling(p);
    -			    if (p) Putc(',',fname);
    -			  }
    -			  Append(fname,")>");
    -			  Swig_symbol_cadd(fname,$$);
     			}
    +			$$ = ntop;
    +			Swig_symbol_setscope(cscope);
    +			Delete(Namespaceprefix);
    +			Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    +			if (error) $$ = 0;
     		      }
    -		      $$ = ntop;
    -		      Swig_symbol_setscope(cscope);
    -		      Delete(Namespaceprefix);
    -		      Namespaceprefix = Swig_symbol_qualifiedscopename(0);
    -		      if (error) $$ = 0;
    +		    } else {
    +		      $$ = 0;
    +		    }
    +		    template_parameters = 0;
    +		    if (inclass)
    +		      nested_template--;
                       }
                     | TEMPLATE cpptype idcolon {
     		  Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
    @@ -4377,7 +4417,6 @@ cpp_nested :   storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
     		if (cplus_mode == CPLUS_PUBLIC) {
     		  if (strcmp($2,"class") == 0) {
     		    Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
    -		    /* Generate some code for a new class */
     		  } else if ($5.id) {
     		    /* Generate some code for a new class */
     		    Nested *n = (Nested *) malloc(sizeof(Nested));
    @@ -4409,6 +4448,7 @@ cpp_nested :   storage_class cpptype ID LBRACE { cparse_start_line = cparse_line
     		  Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n");
     		}
     	      }
    +/* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */
     /*
                   | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}');
                   } SEMI {
    
    From 9d65c100b977bd74151ac2c1c6cd03d1a27ed641 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sun, 8 Nov 2009 01:18:45 +0000
    Subject: [PATCH 056/146] Ignored nested class/struct warnings now display the
     name of the ignored class/struct.
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11728 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     CHANGES.current                      |  3 +++
     Doc/Manual/Warnings.html             |  3 +--
     Examples/test-suite/common.mk        |  1 +
     Examples/test-suite/derived_nested.i |  7 +++++
     Examples/test-suite/nested_class.i   | 40 ++++++++++++++++++++++++++++
     Source/CParse/parser.y               | 11 +++++---
     6 files changed, 59 insertions(+), 6 deletions(-)
     create mode 100644 Examples/test-suite/nested_class.i
    
    diff --git a/CHANGES.current b/CHANGES.current
    index 8192f30b5..2791a7a45 100644
    --- a/CHANGES.current
    +++ b/CHANGES.current
    @@ -1,6 +1,9 @@
     Version 1.3.41 (in progress)
     ============================
     
    +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
    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
    index df05478a6..1150c4dc5 100644
    --- a/Doc/Manual/Warnings.html
    +++ b/Doc/Manual/Warnings.html
    @@ -399,8 +399,7 @@ 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. Nested class not currently supported (name ignored).
  • 313. Unrecognized extern type "name" (ignored).
  • 314. 'identifier' is a lang keyword.
  • 315. Nothing known about 'identifier'. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 473d6579d..cf9faaad9 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -242,6 +242,7 @@ CPP_TEST_CASES += \ namespace_typemap \ namespace_virtual_method \ naturalvar \ + nested_class \ nested_comment \ newobject1 \ null_pointer \ diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i index 2e9ace304..babcac0aa 100644 --- a/Examples/test-suite/derived_nested.i +++ b/Examples/test-suite/derived_nested.i @@ -3,6 +3,8 @@ This was reported in bug #909389 */ %module derived_nested +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS + %inline %{ class A { int x; }; @@ -11,5 +13,10 @@ class B { class D : public A { int z; }; //ok }; +struct BB { + class CC { int y; }; + class DD : public A { int z; }; + struct EE : public A { int z; }; +}; %} diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i new file mode 100644 index 000000000..139c0c4cf --- /dev/null +++ b/Examples/test-suite/nested_class.i @@ -0,0 +1,40 @@ +%module nested_class + +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS + +%inline %{ +struct Outer { + struct Inner1 { + int x; + }; + + class Inner2 { + public: + int x; + }; + + class { + public: + int a; + }; + + struct { + int b; + }; + + union { + int c; + double d; + }; + + class Inner3 { + public: + int x; + } Inner3Name; + + struct Inner4 { + int x; + } Inner4Name; +}; + +%} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 1cd7dc750..5eccc2df0 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4395,7 +4395,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line n->next = 0; add_nested(n); } else { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); if (strcmp($2, "class") == 0) { /* For now, just treat the nested class as a forward * declaration (SF bug #909387). */ @@ -4416,7 +4416,10 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if (strcmp($2,"class") == 0) { - Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); + if ($5.id) + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (%s ignored)\n", $5.id); + else + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); } else if ($5.id) { /* Generate some code for a new class */ Nested *n = (Nested *) malloc(sizeof(Nested)); @@ -4445,7 +4448,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line } SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3); } } /* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */ @@ -4454,7 +4457,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line } SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6); } } */ From 99565a7c35a9936cac6c2b97f0861404900e969a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 8 Nov 2009 20:33:19 +0000 Subject: [PATCH 057/146] Add unions to the nested class test git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11729 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/nested_class.i | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index 139c0c4cf..744519b96 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -4,15 +4,20 @@ %inline %{ struct Outer { - struct Inner1 { + struct InnerStruct1 { int x; }; - class Inner2 { + class InnerClass1 { public: int x; }; + union InnerUnion1 { + int x; + double y; + }; + class { public: int a; @@ -27,14 +32,19 @@ struct Outer { double d; }; - class Inner3 { + class InnerClass2 { public: int x; - } Inner3Name; + } InnerClass2Name; - struct Inner4 { + struct InnerStruct2 { int x; - } Inner4Name; + } InnerStruct2Name; + + union InnerUnion2 { + int x; + double y; + } InnerUnion2Name; }; %} From 9b318c45bc1e93c6e03a12ec5e6ab7b7e8326a04 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 8 Nov 2009 20:45:48 +0000 Subject: [PATCH 058/146] inner declared types are treated as forward declarations - consistency now between innner/nested unions/structs and classes - only relevant to C++ git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11730 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 11 +++++++++++ Examples/test-suite/nested_class.i | 5 +++++ Examples/test-suite/nested_structs.i | 10 ---------- Source/CParse/parser.y | 22 +++++++++++----------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 2791a7a45..9568a0c14 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,17 @@ Version 1.3.41 (in progress) ============================ +2009-11-08: wsfulton + Fix inconsistency for inner 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. diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index 744519b96..ce45b2981 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -45,6 +45,11 @@ struct Outer { int x; double y; } InnerUnion2Name; + + // bug #909387 - inner declared types are treated as forward declarations + InnerStruct1* getInnerStruct1() { return 0; } + InnerClass1* getInnerClass1() { return 0; } + InnerUnion1* getInnerUnion1() { return 0; } }; %} diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i index 4b13ff69d..41cdd63fb 100644 --- a/Examples/test-suite/nested_structs.i +++ b/Examples/test-suite/nested_structs.i @@ -10,13 +10,3 @@ int a; %} -// bug #909387 -%inline %{ -struct foo { - struct happy; // no warning - struct sad { int x; }; // warning - happy *good(); // produces good code - sad *bad(); // produces bad code -}; -%} - diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 5eccc2df0..9c68cc647 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4396,17 +4396,16 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line add_nested(n); } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); - if (strcmp($2, "class") == 0) { - /* For now, just treat the nested class as a forward - * declaration (SF bug #909387). */ - $$ = new_node("classforward"); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"kind",$2); - Setattr($$,"name",$3); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - } + + /* For now, just treat the nested class/struct/union as a forward + * declaration (SF bug #909387). */ + $$ = new_node("classforward"); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"kind",$2); + Setattr($$,"name",$3); + Setattr($$,"sym:weak", "1"); + add_symbols($$); } } } @@ -4446,6 +4445,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line *****/ | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } SEMI { +Printf(stdout, "cpp_nested (c)\n"); $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3); From b279cd3dde30f8285d8621d5e57dab8563956bd8 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Tue, 10 Nov 2009 02:32:29 +0000 Subject: [PATCH 059/146] add std_map fix compact mode git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11731 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/r/r.swg | 8 ++++---- Lib/r/rtype.swg | 10 +++++----- Lib/r/std_map.i | 5 +++++ Lib/r/std_pair.i | 6 +++++- Source/Modules/r.cxx | 34 +++++++++++++++++----------------- 5 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 Lib/r/std_map.i diff --git a/Lib/r/r.swg b/Lib/r/r.swg index 7fd6d761f..b70d80581 100644 --- a/Lib/r/r.swg +++ b/Lib/r/r.swg @@ -50,7 +50,7 @@ SWIG_InitializeModule(0); %typemap(scheck) SWIGTYPE[ANY] %{ # assert(length($input) > $1_dim0) - assert(all(sapply($input, class) == "$R_class")) + assert(all(sapply($input, class) == "$R_class")); %} %typemap(out) void ""; @@ -122,14 +122,14 @@ SWIG_InitializeModule(0); /* Handling vector case to avoid warnings, although we just use the first one. */ %typemap(scheck) unsigned int %{ - assert(length($input) == 1 && $input >= 0, "All values must be non-negative") + assert(length($input) == 1 && $input >= 0, "All values must be non-negative"); %} %typemap(scheck) int, long %{ if(length($input) > 1) { - warning("using only the first element of $input") - } + warning("using only the first element of $input"); + }; %} diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg index 04441c03f..ee01d07d7 100644 --- a/Lib/r/rtype.swg +++ b/Lib/r/rtype.swg @@ -60,11 +60,11 @@ %typemap(scoercein) std::string, std::string *, std::string & %{ $input = as($input, "character"); %} %typemap(scoercein) enum SWIGTYPE - %{ $input = enumToInteger($input, "$R_class") %} + %{ $input = enumToInteger($input, "$R_class"); %} %typemap(scoercein) enum SWIGTYPE & - %{ $input = enumToInteger($input, "$R_class") %} + %{ $input = enumToInteger($input, "$R_class"); %} %typemap(scoercein) enum SWIGTYPE * - %{ $input = enumToInteger($input, "$R_class") %} + %{ $input = enumToInteger($input, "$R_class"); %} %typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE & @@ -84,14 +84,14 @@ %typemap(scoercein) SWIGTYPE[ANY] %{ if(is.list($input)) - assert(all(sapply($input, class) == "$R_class")) + assert(all(sapply($input, class) == "$R_class")); %} /* **************************************************************** */ %typemap(scoercein) bool, bool *, bool & - "$input = as.logical($input) "; + "$input = as.logical($input);"; %typemap(scoercein) int, int *, int &, diff --git a/Lib/r/std_map.i b/Lib/r/std_map.i new file mode 100644 index 000000000..56057514c --- /dev/null +++ b/Lib/r/std_map.i @@ -0,0 +1,5 @@ +%fragment("StdMapTraits","header") +%{ +%} + +%include diff --git a/Lib/r/std_pair.i b/Lib/r/std_pair.i index 3ac795704..e9803449e 100644 --- a/Lib/r/std_pair.i +++ b/Lib/r/std_pair.i @@ -1 +1,5 @@ -%include \ No newline at end of file +%fragment("StdPairTraits","header") +%{ +%} + +%include diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index e142c3bee..41058284f 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1601,9 +1601,9 @@ void R::dispatchFunction(Node *n) { List *dispatch = Swig_overload_rank(n, true); int nfunc = Len(dispatch); Printv(f->code, - "argtypes <- mapply(class, list(...))\n", - "argv <- list(...)\n", - "argc <- length(argtypes)\n", NIL ); + "argtypes <- mapply(class, list(...));\n", + "argv <- list(...);\n", + "argc <- length(argtypes);\n", NIL ); Printf(f->code, "# dispatch functions %d\n", nfunc); int cur_args = -1; @@ -1649,16 +1649,16 @@ void R::dispatchFunction(Node *n) { } p = Getattr(p, "tmap:in:next"); } - Printf(f->code, ") { f <- %s%s }\n", sfname, overname); + Printf(f->code, ") { f <- %s%s; }\n", sfname, overname); } else { - Printf(f->code, "f <- %s%s", sfname, overname); + Printf(f->code, "f <- %s%s; ", sfname, overname); } } if (cur_args != -1) { Printv(f->code, "}", NIL); } - Printv(f->code, "\nf(...)", NIL); - Printv(f->code, "\n}", NIL); + Printv(f->code, ";\nf(...)", NIL); + Printv(f->code, ";\n}", NIL); Wrapper_print(f, sfile); Printv(sfile, "# Dispatch function\n", NIL); DelWrapper(f); @@ -1886,16 +1886,16 @@ int R::functionWrapper(Node *n) { String *snargs = NewStringf("%d", nargs); Printv(sfun->code, "if(is.function(", name, ")) {", "\n", "assert('...' %in% names(formals(", name, - ")) || length(formals(", name, ")) >= ", snargs, ")\n} ", NIL); + ")) || length(formals(", name, ")) >= ", snargs, ");\n} ", NIL); Delete(snargs); Printv(sfun->code, "else {\n", "if(is.character(", name, ")) {\n", - name, " = getNativeSymbolInfo(", name, ")", - "\n}\n", + name, " = getNativeSymbolInfo(", name, ");", + "\n};\n", "if(is(", name, ", \"NativeSymbolInfo\")) {\n", - name, " = ", name, "$address", "\n}\n", - "}\n", + name, " = ", name, "$address", ";\n}\n", + "}; \n", NIL); } else { Printf(sfun->code, "%s\n", tm); @@ -2452,11 +2452,11 @@ int R::generateCopyRoutines(Node *n) { /* The S functions to get and set the member value. */ String *elNameT = replaceInitialDash(elName); - Printf(copyToR->code, "obj@%s = value$%s\n", elNameT, elNameT); - Printf(copyToC->code, "obj$%s = value@%s\n", elNameT, elNameT); + Printf(copyToR->code, "obj@%s = value$%s;\n", elNameT, elNameT); + Printf(copyToC->code, "obj$%s = value@%s;\n", elNameT, elNameT); Delete(elNameT); } - Printf(copyToR->code, "obj\n}\n\n"); + Printf(copyToR->code, "obj;\n}\n\n"); String *rclassName = getRClassNameCopyStruct(type, 0); // without the Ref. Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName); @@ -2466,9 +2466,9 @@ int R::generateCopyRoutines(Node *n) { Printf(sfile, "# Start definition of copy methods for %s\n", rclassName); - Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s)\n", rclassName, + Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s);\n", rclassName, mangledName); - Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s)\n\n", rclassName, + Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName, mangledName); Printf(sfile, "# End definition of copy methods for %s\n", rclassName); From f5e1371733a7264d7584ae869066d040ec2f4766 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Tue, 10 Nov 2009 02:38:11 +0000 Subject: [PATCH 060/146] add R changes to change list git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11732 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 9568a0c14..bfcb65514 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,5 +1,7 @@ Version 1.3.41 (in progress) ============================ +2009-11-09: drjoe + Fix R for -fcompact and add std_map.i 2009-11-08: wsfulton Fix inconsistency for inner structs/unions/classes. Uncompileable code was being From a0ff0a86d046e66da8355c7e290388ea9a392463 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 11 Nov 2009 00:22:38 +0000 Subject: [PATCH 061/146] Obscure seg fault bug fix git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11733 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/typesys.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c index 2562e12f8..2022daf6a 100644 --- a/Source/Swig/typesys.c +++ b/Source/Swig/typesys.c @@ -1120,11 +1120,13 @@ int SwigType_typedef_using(const_String_or_char_ptr name) { /* Figure out the scope the using directive refers to */ { prefix = Swig_scopename_prefix(name); - s = SwigType_find_scope(current_scope, prefix); - if (s) { - Hash *ttab = Getattr(s, "typetab"); - if (!Getattr(ttab, base) && defined_name) { - Setattr(ttab, base, defined_name); + if (prefix) { + s = SwigType_find_scope(current_scope, prefix); + if (s) { + Hash *ttab = Getattr(s, "typetab"); + if (!Getattr(ttab, base) && defined_name) { + Setattr(ttab, base, defined_name); + } } } } From ebed6508e4cc3cee2a782fd6e15d6017c8cdcb25 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 11 Nov 2009 00:30:34 +0000 Subject: [PATCH 062/146] Nested class improvements - Fixed inconsistency in handling C++ nested classes - sometimes they were treated as forward declarations, other times as if C nested struct was parsed. Added the nestedworkaround feature for C++ nested class handling. Document improved nested class handling. Numerous C and C++ nested struct/class/union test cases added. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11734 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 24 +++- Doc/Manual/Introduction.html | 2 +- Doc/Manual/SWIG.html | 14 ++- Doc/Manual/SWIGPlus.html | 107 +++++++++++++----- Examples/test-suite/common.mk | 1 + Examples/test-suite/nested.i | 21 ++++ Examples/test-suite/nested_class.i | 60 ++++++++-- Examples/test-suite/nested_workaround.i | 38 +++++++ .../python/nested_workaround_runme.py | 13 +++ Lib/swig.swg | 5 + Source/CParse/parser.y | 94 ++++++++------- Source/Swig/symbol.c | 3 +- 12 files changed, 300 insertions(+), 82 deletions(-) create mode 100644 Examples/test-suite/nested_workaround.i create mode 100644 Examples/test-suite/python/nested_workaround_runme.py diff --git a/CHANGES.current b/CHANGES.current index bfcb65514..e03d6773a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,12 +1,30 @@ Version 1.3.41 (in progress) ============================ +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 inner 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 + 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 { diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html index 099454cf0..df8d03fdf 100644 --- a/Doc/Manual/Introduction.html +++ b/Doc/Manual/Introduction.html @@ -334,7 +334,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.

    diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index 8705fa182..dd1b22095 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -334,6 +334,7 @@ currently supported: For example, SWIG does not support declarations such as the following (even though this is legal C): +

     /* Non-conventional placement of storage specifier (extern) */
    @@ -347,6 +348,7 @@ void bar(Spam (Grok)(Doh));
     
     
    +

    In practice, few (if any) C programmers actually write code like @@ -360,6 +362,7 @@ 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: +

    @@ -369,11 +372,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. +are not yet fully supported. Please see the C++ section +for more information.

    @@ -2633,6 +2637,12 @@ If you have a lot 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

    diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index f318af6a3..936fd3fb1 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -4695,37 +4695,49 @@ public:

    -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 {
    +#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
    +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:

    @@ -4738,14 +4750,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.

    @@ -4753,9 +4769,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 { @@ -4764,24 +4777,62 @@ 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.

    +

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

    + +

    6.27 A brief rant about const-correctness

    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index cf9faaad9..93c1cc909 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -244,6 +244,7 @@ CPP_TEST_CASES += \ naturalvar \ nested_class \ nested_comment \ + nested_workaround \ newobject1 \ null_pointer \ operator_overload \ diff --git a/Examples/test-suite/nested.i b/Examples/test-suite/nested.i index 0b93be46a..004cb4814 100644 --- a/Examples/test-suite/nested.i +++ b/Examples/test-suite/nested.i @@ -12,6 +12,27 @@ struct TestStruct { int a; }; +struct OuterStructNamed { + struct InnerStructNamed { + double dd; + } inner_struct_named; + union InnerUnionNamed { + double ee; + int ff; + } inner_union_named; +}; + +struct OuterStructUnnamed { + struct { + double xx; + } inner_struct_unnamed; + union { + double yy; + int zz; + } inner_union_unnamed; +}; + + typedef struct OuterStruct { union { diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index ce45b2981..3b964f756 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -4,52 +4,94 @@ %inline %{ struct Outer { + typedef int Integer; + /////////////////////////////////////////// struct InnerStruct1 { - int x; + Integer x; }; class InnerClass1 { public: - int x; + Integer x; }; union InnerUnion1 { - int x; + Integer x; double y; }; + /////////////////////////////////////////// class { public: - int a; + Integer a; }; struct { - int b; + Integer b; }; union { - int c; + Integer c; double d; }; + /////////////////////////////////////////// class InnerClass2 { public: - int x; + Integer x; } InnerClass2Name; struct InnerStruct2 { - int x; + Integer x; } InnerStruct2Name; union InnerUnion2 { - int x; + Integer x; double y; } InnerUnion2Name; + /////////////////////////////////////////// + class { + public: + Integer x; + } InnerClass3Name; + + struct { + Integer x; + } InnerStruct3Name; + + union { + Integer x; + double y; + } InnerUnion3Name; + + /////////////////////////////////////////// + typedef class { + public: + Integer x; + } InnerClass4; + + typedef struct { + Integer x; + } InnerStruct4; + + typedef union { + Integer x; + double y; + } InnerUnion4; + // bug #909387 - inner declared types are treated as forward declarations InnerStruct1* getInnerStruct1() { return 0; } InnerClass1* getInnerClass1() { return 0; } InnerUnion1* getInnerUnion1() { return 0; } + + InnerStruct2* getInnerStruct2() { return 0; } + InnerClass2* getInnerClass2() { return 0; } + InnerUnion2* getInnerUnion2() { return 0; } + + InnerStruct4* getInnerStruct4() { return 0; } + InnerClass4* getInnerClass4() { return 0; } + InnerUnion4* getInnerUnion4() { return 0; } }; %} diff --git a/Examples/test-suite/nested_workaround.i b/Examples/test-suite/nested_workaround.i new file mode 100644 index 000000000..9727dacee --- /dev/null +++ b/Examples/test-suite/nested_workaround.i @@ -0,0 +1,38 @@ +%module nested_workaround +// Similar to "Nested classes" documentation example. + +class Inner { + int val; + public: + Inner(int v = 0) : val(v) {} + void setValue(int v) { val = v; } + int getValue() const { return val; } +}; +%nestedworkaround Outer::Inner; + +%inline %{ +class Outer { +public: + class Inner { + int val; + public: + Inner(int v = 0) : val(v) {} + void setValue(int v) { val = v; } + int getValue() const { return val; } + }; + Inner createInner(int v) const { return Inner(v); } + int getInnerValue(const Inner& i) const { return i.getValue(); } + Inner doubleInnerValue(Inner inner) { + inner.setValue(inner.getValue() * 2); + return inner; + } +}; +%} + +// 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. +%{ +typedef Outer::Inner Inner; +%} + + diff --git a/Examples/test-suite/python/nested_workaround_runme.py b/Examples/test-suite/python/nested_workaround_runme.py new file mode 100644 index 000000000..a8a75d370 --- /dev/null +++ b/Examples/test-suite/python/nested_workaround_runme.py @@ -0,0 +1,13 @@ +from nested_workaround import * + +inner = Inner(5) +outer = Outer() +newInner = outer.doubleInnerValue(inner) +if newInner.getValue() != 10: + raise RuntimeError + +outer = Outer() +inner = outer.createInner(3) +newInner = outer.doubleInnerValue(inner) +if outer.getInnerValue(newInner) != 6: + raise RuntimeError diff --git a/Lib/swig.swg b/Lib/swig.swg index c0ecad9dd..af7fa6a30 100644 --- a/Lib/swig.swg +++ b/Lib/swig.swg @@ -136,6 +136,11 @@ #define %nocallback %feature("callback","0") #define %clearcallback %feature("callback","") +/* the %nestedworkaround directive */ +#define %nestedworkaround %feature("nestedworkaround") +#define %nonestedworkaround %feature("nestedworkaround","0") +#define %clearnestedworkaround %feature("nestedworkaround","") + /* the %fastdispatch directive */ #define %fastdispatch %feature("fastdispatch") #define %nofastdispatch %feature("fastdispatch","0") diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 9c68cc647..295f0a60c 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4374,18 +4374,33 @@ cpp_protection_decl : PUBLIC COLON { by SWIG or this whole thing is going to puke. ---------------------------------------------------------------------- */ -/* A struct sname { } id; declaration */ +/* struct sname { } id; or struct sname { }; declaration */ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } nested_decl SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - if ($6.id && strcmp($2, "class") != 0) { + if (cparse_cplusplus) { + /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ + $$ = new_node("classforward"); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"kind",$2); + Setattr($$,"name",$3); + Setattr($$,"sym:weak", "1"); + add_symbols($$); + + if (GetFlag($$, "feature:nestedworkaround")) { + Swig_symbol_remove($$); + $$ = 0; + } else { + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); + } + } else if ($6.id) { + /* Generate some code for a new struct */ Nested *n = (Nested *) malloc(sizeof(Nested)); n->code = NewStringEmpty(); - Printv(n->code, "typedef ", $2, " ", - Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL); - + Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL); n->name = Swig_copy_string($6.id); n->line = cparse_start_line; n->type = NewStringEmpty(); @@ -4394,50 +4409,53 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line SwigType_push(n->type, $6.type); n->next = 0; add_nested(n); - } else { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); - - /* For now, just treat the nested class/struct/union as a forward - * declaration (SF bug #909387). */ - $$ = new_node("classforward"); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"kind",$2); - Setattr($$,"name",$3); - Setattr($$,"sym:weak", "1"); - add_symbols($$); } } } -/* A struct { } id; declaration */ + +/* struct { } id; or struct { }; declaration */ + | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } nested_decl SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - if (strcmp($2,"class") == 0) { - if ($5.id) - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (%s ignored)\n", $5.id); - else - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); - } else if ($5.id) { - /* Generate some code for a new class */ - Nested *n = (Nested *) malloc(sizeof(Nested)); - n->code = NewStringEmpty(); - Printv(n->code, "typedef ", $2, " " , - Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL); - n->name = Swig_copy_string($5.id); - n->line = cparse_start_line; - n->type = NewStringEmpty(); - n->kind = $2; - n->unnamed = 1; - SwigType_push(n->type,$5.type); - n->next = 0; - add_nested(n); + if ($5.id) { + if (cparse_cplusplus) { + /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ + $$ = new_node("classforward"); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"kind",$2); + Setattr($$,"name",$5.id); + Setattr($$,"sym:weak", "1"); + add_symbols($$); + + if (GetFlag($$, "feature:nestedworkaround")) { + Swig_symbol_remove($$); + $$ = 0; + } else { + Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id); + } + } else { + /* Generate some code for a new struct */ + Nested *n = (Nested *) malloc(sizeof(Nested)); + n->code = NewStringEmpty(); + Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL); + n->name = Swig_copy_string($5.id); + n->line = cparse_start_line; + n->type = NewStringEmpty(); + n->kind = $2; + n->unnamed = 1; + SwigType_push(n->type,$5.type); + n->next = 0; + add_nested(n); + } } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); } } } + /* A 'class name : base_list { };' declaration, always ignored */ /***** This fixes derived_nested.i, but it adds one shift/reduce. Anyway, @@ -4445,12 +4463,12 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line *****/ | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } SEMI { -Printf(stdout, "cpp_nested (c)\n"); $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3); } } + /* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */ /* | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index ae8a274c6..b5ed37c0c 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -1331,7 +1331,8 @@ void Swig_symbol_remove(Node *n) { Setattr(symtab, symname, symnext); fixovername = symnext; /* fix as symbol to remove is at head of linked list */ } else { - Delattr(symtab, symname); + if (symname) + Delattr(symtab, symname); } } if (symnext) { From aa61c716a81d95ead028b34350cf98da87d68d14 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 12 Nov 2009 19:47:04 +0000 Subject: [PATCH 063/146] Stop generating uncompileable code when using nested template classes in functions. 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 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11735 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 18 ++++++++ Doc/Manual/SWIGPlus.html | 4 +- Doc/Manual/Warnings.html | 3 +- Examples/test-suite/derived_nested.i | 5 ++- Examples/test-suite/namespace_class.i | 3 +- Examples/test-suite/nested_class.i | 14 +++++- Examples/test-suite/nested_comment.i | 3 ++ Examples/test-suite/template_classes.i | 12 ------ Examples/test-suite/template_nested.i | 8 +++- Examples/test-suite/union_scope.i | 1 + Source/CParse/parser.y | 60 ++++++++++++++++++++------ Source/Include/swigwarn.h | 3 +- 12 files changed, 103 insertions(+), 31 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index e03d6773a..533c64dff 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,5 +1,23 @@ Version 1.3.41 (in progress) ============================ + +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 diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 936fd3fb1..3836c86a7 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -4714,7 +4714,8 @@ The easiest thing to do is turn a blind eye to the warning that SWIG generates,
    -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS
    +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::Inner;
    +
     class Outer {
     public:
       class Inner {
    @@ -4830,6 +4831,7 @@ This should just be a last resort for unusual corner cases now as SWIG can parse
     

    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.

    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 1150c4dc5..15f3aa9d2 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -399,7 +399,7 @@ 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) -
  • 312. Nested class not currently supported (name 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'. @@ -412,6 +412,7 @@ example.i(4): Syntax error in input.
  • 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. diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i index babcac0aa..9a7cfce07 100644 --- a/Examples/test-suite/derived_nested.i +++ b/Examples/test-suite/derived_nested.i @@ -3,7 +3,9 @@ This was reported in bug #909389 */ %module derived_nested -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE; %inline %{ @@ -17,6 +19,7 @@ struct BB { class CC { int y; }; class DD : public A { int z; }; struct EE : public A { int z; }; + void useEE(const EE& e) {} }; %} diff --git a/Examples/test-suite/namespace_class.i b/Examples/test-suite/namespace_class.i index 5e9545ce6..7dc9139cd 100644 --- a/Examples/test-suite/namespace_class.i +++ b/Examples/test-suite/namespace_class.i @@ -1,5 +1,7 @@ %module namespace_class +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola; + %inline %{ template void foobar(T t) {} namespace test { @@ -210,7 +212,6 @@ namespace a %} -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS // %copyctor doesn't work with nested class workaround %nocopyctor; diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index 3b964f756..cccebb136 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -1,6 +1,18 @@ %module nested_class -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS +#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4; %inline %{ struct Outer { diff --git a/Examples/test-suite/nested_comment.i b/Examples/test-suite/nested_comment.i index a9948eb0f..c246b8dab 100644 --- a/Examples/test-suite/nested_comment.i +++ b/Examples/test-suite/nested_comment.i @@ -1,5 +1,8 @@ %module nested_comment +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d; + // this example shows a problem with 'dump_nested' (parser.y). // bug #949654 diff --git a/Examples/test-suite/template_classes.i b/Examples/test-suite/template_classes.i index a05eb9b58..ebe13bd9f 100644 --- a/Examples/test-suite/template_classes.i +++ b/Examples/test-suite/template_classes.i @@ -3,12 +3,6 @@ %module template_classes - -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS - -%{ -%} - %inline %{ template @@ -27,21 +21,16 @@ public: private: Point point; - template struct pair2nd_eq { }; - - - struct Foo : Point { }; Foo foo; - }; %} @@ -49,4 +38,3 @@ private: %template(PointInt) Point; %template(RectangleInt) RectangleTest; - diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i index cb5eddb50..86b9230ae 100644 --- a/Examples/test-suite/template_nested.i +++ b/Examples/test-suite/template_nested.i @@ -2,7 +2,11 @@ // Test nested templates - that is template classes and template methods within a class. -#pragma SWIG nowarn=SWIGWARN_PARSE_NESTED_CLASS +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedStruct; %inline %{ @@ -33,6 +37,7 @@ namespace ns { void method1(Y y) {} }; }; + Inner1 useInner1(const Inner1& inner) { return inner; } template void InnerTMethod(Z z) {} @@ -52,6 +57,7 @@ namespace ns { void method1(Y y) {} }; }; + Inner2 useInner2(const Inner2& inner) { return inner; } int iii; }; struct ABC { diff --git a/Examples/test-suite/union_scope.i b/Examples/test-suite/union_scope.i index 67093eff6..a41b30406 100644 --- a/Examples/test-suite/union_scope.i +++ b/Examples/test-suite/union_scope.i @@ -2,6 +2,7 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) nRState::rstate; %inline %{ class nRState { diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 295f0a60c..f310d489b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3645,12 +3645,30 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { if (nested_template <= 1) { int is_nested_template_class = $6 && GetFlag($6, "nestedtemplateclass"); if (is_nested_template_class) { + $$ = 0; /* Nested template classes would probably better be ignored like ordinary nested classes using cpp_nested, but that introduces shift/reduce conflicts */ if (cplus_mode == CPLUS_PUBLIC) { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored)\n", Getattr($6, "kind"), Getattr($6, "name")); + /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ + String *kind = Getattr($6, "kind"); + String *name = Getattr($6, "name"); + $$ = new_node("template"); + Setattr($$,"kind",kind); + Setattr($$,"name",name); + Setattr($$,"sym:weak", "1"); + Setattr($$,"templatetype","classforward"); + Setattr($$,"templateparms", $3); + add_symbols($$); + + if (GetFlag($$, "feature:nestedworkaround")) { + Swig_symbol_remove($$); + $$ = 0; + } else { + SWIG_WARN_NODE_BEGIN($$); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested template %s not currently supported (%s ignored).\n", kind, name); + SWIG_WARN_NODE_END($$); + } } Delete($6); - $$ = 0; } else { String *tname = 0; int error = 0; @@ -4394,7 +4412,9 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line Swig_symbol_remove($$); $$ = 0; } else { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); + SWIG_WARN_NODE_BEGIN($$); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); + SWIG_WARN_NODE_END($$); } } else if ($6.id) { /* Generate some code for a new struct */ @@ -4434,7 +4454,9 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line Swig_symbol_remove($$); $$ = 0; } else { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id); + SWIG_WARN_NODE_BEGIN($$); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id); + SWIG_WARN_NODE_END($$); } } else { /* Generate some code for a new struct */ @@ -4451,21 +4473,35 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line add_nested(n); } } else { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); } } } -/* A 'class name : base_list { };' declaration, always ignored */ -/***** - This fixes derived_nested.i, but it adds one shift/reduce. Anyway, - we are waiting for the nested class support. - *****/ +/* class name : base_list { }; declaration */ +/* This adds one shift/reduce. */ + | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $3); + /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ + $$ = new_node("classforward"); + Setfile($$,cparse_file); + Setline($$,cparse_line); + Setattr($$,"kind",$2); + Setattr($$,"name",$3); + Setattr($$,"sym:weak", "1"); + add_symbols($$); + + if (GetFlag($$, "feature:nestedworkaround")) { + Swig_symbol_remove($$); + $$ = 0; + } else { + SWIG_WARN_NODE_BEGIN($$); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); + SWIG_WARN_NODE_END($$); + } } } @@ -4475,7 +4511,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line } SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $5, $6); } } */ diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h index 6c54c55bd..b400fbdeb 100644 --- a/Source/Include/swigwarn.h +++ b/Source/Include/swigwarn.h @@ -72,7 +72,7 @@ #define WARN_PARSE_PRIVATE_INHERIT 309 #define WARN_PARSE_TEMPLATE_REPEAT 310 #define WARN_PARSE_TEMPLATE_PARTIAL 311 -#define WARN_PARSE_NESTED_CLASS 312 +#define WARN_PARSE_UNNAMED_NESTED_CLASS 312 #define WARN_PARSE_UNDEFINED_EXTERN 313 #define WARN_PARSE_KEYWORD 314 #define WARN_PARSE_USING_UNDEF 315 @@ -85,6 +85,7 @@ #define WARN_PARSE_REDUNDANT 322 #define WARN_PARSE_REC_INHERITANCE 323 #define WARN_PARSE_NESTED_TEMPLATE 324 +#define WARN_PARSE_NAMED_NESTED_CLASS 325 #define WARN_IGNORE_OPERATOR_NEW 350 /* new */ #define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ From dd5714ea28db35cb31badfc686026aba909c86c3 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 13 Nov 2009 07:15:08 +0000 Subject: [PATCH 064/146] [php] Fix place where class prefix (as specified with -prefix) wasn't being used. Patch from gverbruggen in SF#2892647. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11736 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Source/Modules/php.cxx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index 533c64dff..6cfdc012a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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 diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index eee4d1fcc..cbad1ee84 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1684,7 +1684,7 @@ public: Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix); } Printf(output, "\t\t\tif (!class_exists($c)) {\n"); - Printf(output, "\t\t\t\treturn new %s($r);\n", Getattr(classLookup(d), "sym:name")); + Printf(output, "\t\t\t\treturn new %s%s($r);\n", prefix, Getattr(classLookup(d), "sym:name")); Printf(output, "\t\t\t}\n"); Printf(output, "\t\t\treturn new $c($r);\n"); } else { From b502f4fc5aa70e6d16d10787514f0e80d8562a63 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 13 Nov 2009 08:04:01 +0000 Subject: [PATCH 065/146] Fix usage of nested template classes within templated classes so that compileable code is generated. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11737 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 +++++- Examples/test-suite/template_nested.i | 19 +++++++++++++++++++ Source/Swig/stype.c | 8 +++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 6cfdc012a..58742c56f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,13 +1,17 @@ Version 1.3.41 (in progress) ============================ +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 + 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 diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i index 86b9230ae..1bb1c686a 100644 --- a/Examples/test-suite/template_nested.i +++ b/Examples/test-suite/template_nested.i @@ -6,8 +6,20 @@ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterClass::Inner2; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate1; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate2; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedInnerTemplate3; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) ns::OuterTemplate::NestedStruct; +namespace ns { +template struct ForwardTemplate; +} +%{ +namespace ns { + template struct ForwardTemplate { + void tmethod(T t) {} + }; +} +%} + %inline %{ namespace ns { @@ -80,10 +92,17 @@ namespace ns { void hohum() {} }; UU hohum(UU u) { return u; } + template struct NestedInnerTemplate3 : public NestedInnerTemplate2 { + void hohum() {} + }; struct NestedStruct { NestedStruct() {} void hohum() {} }; + NestedInnerTemplate1 useNestedInnerTemplate1(const NestedInnerTemplate1& inner) { return inner; } + NestedInnerTemplate2 useNestedInnerTemplate2(const NestedInnerTemplate2& inner) { return inner; } + NestedInnerTemplate3 useNestedInnerTemplate3(const NestedInnerTemplate3& inner) { return inner; } + NestedStruct useNestedStruct(const NestedStruct& inner) { return inner; } }; } diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index 8a7700bec..aa5d448a3 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -525,7 +525,13 @@ String *SwigType_namestr(const SwigType *t) { Putc(' ', r); Putc('>', r); suffix = SwigType_templatesuffix(t); - Append(r, suffix); + if (Len(suffix) > 0) { + String *suffix_namestr = SwigType_namestr(suffix); + Append(r, suffix_namestr); + Delete(suffix_namestr); + } else { + Append(r, suffix); + } Delete(suffix); Delete(p); return r; From 1b951d68f4194efd46a389ca8bd56a400b224053 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 13 Nov 2009 18:27:41 +0000 Subject: [PATCH 066/146] nested classes code refactor git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11738 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 81 ++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 51 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index f310d489b..886e77fd8 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1428,6 +1428,33 @@ static void default_arguments(Node *n) { } } +/* ----------------------------------------------------------------------------- + * nested_forward_declaration() + * + * Treat the nested class/struct/union as a forward declaration until a proper + * nested class solution is implemented. + * ----------------------------------------------------------------------------- */ + +static Node *nested_forward_declaration(const char *kind, const char *name) { + Node *n = new_node("classforward"); + Setfile(n,cparse_file); + Setline(n,cparse_line); + Setattr(n,"kind", kind); + Setattr(n,"name", name); + Setattr(n,"sym:weak", "1"); + add_symbols(n); + + if (GetFlag(n, "feature:nestedworkaround")) { + Swig_symbol_remove(n); + n = 0; + } else { + SWIG_WARN_NODE_BEGIN(n); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name); + SWIG_WARN_NODE_END(n); + } + return n; +} + /* ----------------------------------------------------------------------------- * tag_nodes() * @@ -4399,23 +4426,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if (cparse_cplusplus) { - /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ - $$ = new_node("classforward"); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"kind",$2); - Setattr($$,"name",$3); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - - if (GetFlag($$, "feature:nestedworkaround")) { - Swig_symbol_remove($$); - $$ = 0; - } else { - SWIG_WARN_NODE_BEGIN($$); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); - SWIG_WARN_NODE_END($$); - } + $$ = nested_forward_declaration($2, $3); } else if ($6.id) { /* Generate some code for a new struct */ Nested *n = (Nested *) malloc(sizeof(Nested)); @@ -4441,23 +4452,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line if (cplus_mode == CPLUS_PUBLIC) { if ($5.id) { if (cparse_cplusplus) { - /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ - $$ = new_node("classforward"); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"kind",$2); - Setattr($$,"name",$5.id); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - - if (GetFlag($$, "feature:nestedworkaround")) { - Swig_symbol_remove($$); - $$ = 0; - } else { - SWIG_WARN_NODE_BEGIN($$); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", $2, $5.id); - SWIG_WARN_NODE_END($$); - } + $$ = nested_forward_declaration($2, $5.id); } else { /* Generate some code for a new struct */ Nested *n = (Nested *) malloc(sizeof(Nested)); @@ -4485,23 +4480,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line } SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - /* Treat the nested class/struct/union as a forward declaration until a proper nested class solution is implemented */ - $$ = new_node("classforward"); - Setfile($$,cparse_file); - Setline($$,cparse_line); - Setattr($$,"kind",$2); - Setattr($$,"name",$3); - Setattr($$,"sym:weak", "1"); - add_symbols($$); - - if (GetFlag($$, "feature:nestedworkaround")) { - Swig_symbol_remove($$); - $$ = 0; - } else { - SWIG_WARN_NODE_BEGIN($$); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored).\n", $2, $3); - SWIG_WARN_NODE_END($$); - } + $$ = nested_forward_declaration($2, $3); } } From cd53dc68eeb48fab248fdea57293c75ececa4e86 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 13 Nov 2009 18:34:54 +0000 Subject: [PATCH 067/146] remove SWIGMAC and SWIGWIN32/SWIGWIN macros which have no effect git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11739 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Preprocessor.html | 2 -- Source/Modules/main.cxx | 6 ------ 2 files changed, 8 deletions(-) diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index 5afa59243..2dd79dac5 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -102,8 +102,6 @@ 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,
                                     such as 0x010311 (corresponding to SWIG-1.3.11).
     
    diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
    index 30d12f26b..4903416cd 100644
    --- a/Source/Modules/main.cxx
    +++ b/Source/Modules/main.cxx
    @@ -844,12 +844,6 @@ int SWIG_main(int argc, char *argv[], Language *l) {
     
       Preprocessor_define((DOH *) "SWIG 1", 0);
       Preprocessor_define((DOH *) "__STDC__", 0);
    -#ifdef MACSWIG
    -  Preprocessor_define((DOH *) "SWIGMAC 1", 0);
    -#endif
    -#ifdef SWIGWIN32
    -  Preprocessor_define((DOH *) "SWIGWIN32 1", 0);
    -#endif
     
       // Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C
       String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
    
    From 2bf42357e0e420d024b7a3628d997cd8e93907ae Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Fri, 13 Nov 2009 19:04:28 +0000
    Subject: [PATCH 068/146] fix suggested casts for displaying SWIG types in a
     debugger
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11740 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     Doc/Devel/internals.html | 12 ++++++------
     1 file changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html
    index d27ec12fa..63a8626ff 100644
    --- a/Doc/Devel/internals.html
    +++ b/Doc/Devel/internals.html
    @@ -1070,25 +1070,25 @@ 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
    will work depending on whether the underlying type is really a String * or char *. From 0509dbb95152a25aaa927a96ef70ca0f952b8444 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 13 Nov 2009 19:21:33 +0000 Subject: [PATCH 069/146] some parser code comments added git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11741 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 886e77fd8..81663abf8 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -859,6 +859,12 @@ static String *remove_block(Node *kw, const String *inputcode) { static Node *nscope = 0; static Node *nscope_inner = 0; + +/* Remove the scope prefix from cname and return the base name without the prefix. + * The scopes specified in the prefix are found, or created in the current namespace. + * So ultimately the scope is changed to that required for the base name. + * For example AA::BB::CC as input returns CC and creates the namespace AA then inner + * namespace BB in the current scope. If no scope separator (::) in the input, then nothing happens! */ static String *resolve_node_scope(String *cname) { Symtab *gscope = 0; nscope = 0; @@ -2848,10 +2854,10 @@ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN va Swig_symbol_setscope(csyms); } - /* Merge in addmethods for this class */ + /* Merge in %extend methods for this class */ /* !!! This may be broken. We may have to add the - addmethods at the beginning of the class */ + %extend methods at the beginning of the class */ if (extendhash) { String *stmp = 0; From 7ae45bc020e463f6b6ad3062607370b86af8e624 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 14 Nov 2009 15:55:23 +0000 Subject: [PATCH 070/146] Fix #2310483 - function pointer typedef within extern C block. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11742 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 +++ Examples/test-suite/common.mk | 1 + Examples/test-suite/extern_c.i | 16 ++++++++++++++++ Examples/test-suite/python/extern_c_runme.py | 4 ++++ Source/CParse/parser.y | 2 +- 5 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 Examples/test-suite/extern_c.i create mode 100644 Examples/test-suite/python/extern_c_runme.py diff --git a/CHANGES.current b/CHANGES.current index 58742c56f..8469fa815 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 93c1cc909..d7882a462 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -191,6 +191,7 @@ CPP_TEST_CASES += \ extend_placement \ extend_template \ extend_template_ns \ + extern_c \ extern_namespace \ extern_throws \ features \ diff --git a/Examples/test-suite/extern_c.i b/Examples/test-suite/extern_c.i new file mode 100644 index 000000000..9c17d18fb --- /dev/null +++ b/Examples/test-suite/extern_c.i @@ -0,0 +1,16 @@ +%module extern_c + +%inline %{ +extern "C" { +void RealFunction(int value); +typedef void Function1(int value); // Fails +typedef int Integer1; +} +typedef void Function2(int value); // Works +typedef int Integer2; +%} + +%{ +void RealFunction(int value) {} +%} + diff --git a/Examples/test-suite/python/extern_c_runme.py b/Examples/test-suite/python/extern_c_runme.py new file mode 100644 index 000000000..1a6d2aa12 --- /dev/null +++ b/Examples/test-suite/python/extern_c_runme.py @@ -0,0 +1,4 @@ +import extern_c + +extern_c.RealFunction(2) + diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 81663abf8..f78d5255b 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -2965,7 +2965,7 @@ c_declaration : c_decl { appendChild($$,n); while (n) { SwigType *decl = Getattr(n,"decl"); - if (SwigType_isfunction(decl)) { + if (SwigType_isfunction(decl) && Strcmp(Getattr(n, "storage"), "typedef") != 0) { Setattr(n,"storage","externc"); } n = nextSibling(n); From e0dd20350f434bce0edc5dfa5c4401c9b77f937c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 14 Nov 2009 21:50:41 +0000 Subject: [PATCH 071/146] Add caveat about using percent in varargs example as per suggestion in bug #2106353 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11743 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/python/class/example.i | 8 +---- Examples/python/class/runme.py | 55 +++++---------------------------- 2 files changed, 8 insertions(+), 55 deletions(-) diff --git a/Examples/python/class/example.i b/Examples/python/class/example.i index 75700b305..aa28dde80 100644 --- a/Examples/python/class/example.i +++ b/Examples/python/class/example.i @@ -1,10 +1,4 @@ /* File : example.i */ %module example -%{ -#include "example.h" -%} - -/* Let's just grab the original header file here */ -%include "example.h" - +int printf(const char *fmt, ...); diff --git a/Examples/python/class/runme.py b/Examples/python/class/runme.py index f1272ae81..54543be67 100644 --- a/Examples/python/class/runme.py +++ b/Examples/python/class/runme.py @@ -1,51 +1,10 @@ -# file: runme.py -# This file illustrates the proxy class C++ interface generated -# by SWIG. +from example import * -import example - -# ----- Object creation ----- - -print "Creating some objects:" -c = example.Circle(10) -print " Created circle", c -s = example.Square(10) -print " Created square", s - -# ----- Access a static member ----- - -print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" - -# ----- Member data access ----- - -# Set the location of the object - -c.x = 20 -c.y = 30 - -s.x = -10 -s.y = 5 - -print "\nHere is their current position:" -print " Circle = (%f, %f)" % (c.x,c.y) -print " Square = (%f, %f)" % (s.x,s.y) - -# ----- Call some methods ----- - -print "\nHere are some properties of the shapes:" -for o in [c,s]: - print " ", o - print " area = ", o.area() - print " perimeter = ", o.perimeter() - -print "\nGuess I'll clean up now" - -# Note: this invokes the virtual destructor -del c -del s - -s = 3 -print example.cvar.Shape_nshapes,"shapes remain" -print "Goodbye" +printf("hello\n") +name = "%shoot" +num = 22 +printf("Hello %s. Your number is %d\n" % (name, num)) +print("hello there %s." % name); +printf("Your result is 90%.\n") From 22c0c8ea9798ec79dcce647a5eb1c617457f19c7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 14 Nov 2009 21:54:18 +0000 Subject: [PATCH 072/146] Minor change to previous commit about varargs git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11744 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Varargs.html | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html index f40a1ff1f..fb34a3ad9 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

    From dde16ac54a26f7a844f666396c90f5c72c5df648 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 14 Nov 2009 22:07:51 +0000 Subject: [PATCH 073/146] Removed empty sections git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11745 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Python.html | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index a739543df..fcaebc014 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -3854,15 +3854,6 @@ If you need to return binary data, you might use the also be used to extra binary data from arbitrary pointers.

    -

    31.7.5 Arrays

    - - -

    31.7.6 String arrays

    - - -

    31.7.7 STL wrappers

    - -

    31.8 Typemaps

    From 5ea1852ecb1515ac45fc333bd737ec7931f5c44f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 14 Nov 2009 23:51:12 +0000 Subject: [PATCH 074/146] namespace_union.i now works given recent nested class improvements. Closes bug #811906 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11746 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 2 +- Examples/test-suite/namespace_union.i | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index d7882a462..c8ca09013 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -80,7 +80,6 @@ CPP_TEST_BROKEN += \ exception_partial_info \ extend_variable \ li_std_vector_ptr \ - namespace_union \ nested_structs \ overload_complicated \ template_default_pointer \ @@ -241,6 +240,7 @@ CPP_TEST_CASES += \ namespace_template \ namespace_typedef_class \ namespace_typemap \ + namespace_union \ namespace_virtual_method \ naturalvar \ nested_class \ diff --git a/Examples/test-suite/namespace_union.i b/Examples/test-suite/namespace_union.i index edade9640..70698682e 100644 --- a/Examples/test-suite/namespace_union.i +++ b/Examples/test-suite/namespace_union.i @@ -1,4 +1,7 @@ %module namespace_union + +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val; + %inline %{ namespace SpatialIndex { From 107c61d979480a4777e836f019dc1ea2530e6c56 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 15 Nov 2009 00:05:25 +0000 Subject: [PATCH 075/146] Remove bugs which have been fixed over time from cpp_broken.i git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11747 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/cpp_broken.i | 63 -------------------------------- 1 file changed, 63 deletions(-) diff --git a/Examples/test-suite/cpp_broken.i b/Examples/test-suite/cpp_broken.i index fe109ea43..84d6122e5 100644 --- a/Examples/test-suite/cpp_broken.i +++ b/Examples/test-suite/cpp_broken.i @@ -1,36 +1,6 @@ %module cpp_broken -// bug #1060789 -%inline %{ -#define MASK(shift, size) (((1 << (size)) - 1) << (shift)) -#define SOME_MASK_DEF (80*MASK(8, 10)) -%} - -// bug #1060079 -%inline %{ -#define FIELD(name, width) unsigned int name:width -#define SOME_CONST 2 -#define NEXT_CONST (2 * SOME_CONST) - -typedef struct { -FIELD(a, SOME_CONST); -FIELD(b, NEXT_CONST); -} MyStruct_t; -%} - -%{ -#ifdef max -#undef max -#endif -%} - -// bug #994301 -%inline %{ -#define max(a,b) ((a) > (b) ? (a) : (b)) -%} - - // bug #940318 %inline %{ typedef enum { @@ -40,36 +10,3 @@ eZero = 0 %} -// bug #754443 - -%inline %{ -#define MAG_STYLE_BORDER_OFFS 0 -#define MAG_STYLE_BORDER_BITS 3 -#define MAG_STYLE_BORDER_MASK (((1UL< Date: Sun, 15 Nov 2009 00:36:22 +0000 Subject: [PATCH 076/146] Fix #1960977 - Syntax error parsing derived nested class declaration and member variable instance git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11748 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Examples/test-suite/derived_nested.i | 2 ++ Source/CParse/parser.y | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index 8469fa815..3d5c27950 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/derived_nested.i b/Examples/test-suite/derived_nested.i index 9a7cfce07..29114d5a0 100644 --- a/Examples/test-suite/derived_nested.i +++ b/Examples/test-suite/derived_nested.i @@ -6,6 +6,7 @@ This was reported in bug #909389 */ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::CC; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::DD; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::EE; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) BB::FF; %inline %{ @@ -19,6 +20,7 @@ struct BB { class CC { int y; }; class DD : public A { int z; }; struct EE : public A { int z; }; + struct FF : public A { int z; } ff_instance; // Bug 1960977 void useEE(const EE& e) {} }; %} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index f78d5255b..b87ba9368 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -4483,7 +4483,7 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line /* This adds one shift/reduce. */ | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); - } SEMI { + } cpp_opt_declarators { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { $$ = nested_forward_declaration($2, $3); From 7fd36f5bd6c28331cf9375dc9d35fb5c58aecce3 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 17 Nov 2009 18:45:53 +0000 Subject: [PATCH 077/146] Fix parsing of struct declaration and initialization git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11750 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 7 +++++ Examples/test-suite/common.mk | 2 ++ .../python/struct_initialization_runme.py | 20 ++++++++++++ Examples/test-suite/struct_initialization.i | 31 +++++++++++++++++++ .../test-suite/struct_initialization_cpp.i | 5 +++ Source/CParse/parser.y | 10 +++--- 6 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 Examples/test-suite/python/struct_initialization_runme.py create mode 100644 Examples/test-suite/struct_initialization.i create mode 100644 Examples/test-suite/struct_initialization_cpp.i diff --git a/CHANGES.current b/CHANGES.current index 3d5c27950..e97bbc58a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,13 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index c8ca09013..db28917ef 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -303,6 +303,7 @@ CPP_TEST_CASES += \ static_array_member \ static_const_member \ static_const_member_2 \ + struct_initialization_cpp \ struct_value \ template \ template_arg_replace \ @@ -470,6 +471,7 @@ C_TEST_CASES += \ sizeof_pointer \ sneaky1 \ struct_rename \ + struct_initialization \ typedef_struct \ typemap_subst \ union_parameter \ diff --git a/Examples/test-suite/python/struct_initialization_runme.py b/Examples/test-suite/python/struct_initialization_runme.py new file mode 100644 index 000000000..fbed6a5e9 --- /dev/null +++ b/Examples/test-suite/python/struct_initialization_runme.py @@ -0,0 +1,20 @@ +from struct_initialization import * + +if cvar.instanceC1.x != 10: + raise RuntimeError + +if cvar.instanceD1.x != 10: + raise RuntimeError + +if cvar.instanceD2.x != 20: + raise RuntimeError + +if cvar.instanceD3.x != 30: + raise RuntimeError + +if cvar.instanceE1.x != 1: + raise RuntimeError + +if cvar.instanceF1.x != 1: + raise RuntimeError + diff --git a/Examples/test-suite/struct_initialization.i b/Examples/test-suite/struct_initialization.i new file mode 100644 index 000000000..c378ba31d --- /dev/null +++ b/Examples/test-suite/struct_initialization.i @@ -0,0 +1,31 @@ +// Test declaration and initialization of structs (C code) +%module struct_initialization + +%inline %{ + +// Named types +struct StructA { + int x; +} instanceA1; + +struct StructB { + int x; +} instanceB1, instanceB2, instanceB3; + +struct StructC { + int x; +} instanceC1 = { 10 }; + +struct StructD { + int x; +} instanceD1 = { 10 }, instanceD2 = { 20 }, instanceD3 = { 30 }; + +struct StructE { + int x; +} instanceE1[3] = { { 1 }, { 2 }, { 3} }; + +struct StructF { + int x; +} instanceF1[3] = { { 1 }, { 2 } }, instanceF2[2] = { { -1 }, { -2 } }, instanceF3[2] = { { 11 }, { 22 } }; + +%} diff --git a/Examples/test-suite/struct_initialization_cpp.i b/Examples/test-suite/struct_initialization_cpp.i new file mode 100644 index 000000000..dc47077b5 --- /dev/null +++ b/Examples/test-suite/struct_initialization_cpp.i @@ -0,0 +1,5 @@ +// Test declaration and initialization of structs (C++ code) +%module struct_initialization_cpp + +%include "struct_initialization.i" // C code + diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index b87ba9368..0da3666f8 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3546,7 +3546,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Classprefix = NewStringEmpty(); Delete(Namespaceprefix); Namespaceprefix = Swig_symbol_qualifiedscopename(0); - } cpp_members RBRACE declarator c_decl_tail { + } cpp_members RBRACE declarator initializer c_decl_tail { String *unnamed; Node *n; Classprefix = 0; @@ -3564,8 +3564,8 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { Setattr(n,"decl",$7.type); Setattr(n,"parms",$7.parms); Setattr(n,"storage",$1); - if ($8) { - Node *p = $8; + if ($9) { + Node *p = $9; set_nextSibling(n,p); while (p) { String *type = Copy(unnamed); @@ -3635,12 +3635,12 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { ; cpp_opt_declarators : SEMI { $$ = 0; } - | declarator c_decl_tail { + | declarator initializer c_decl_tail { $$ = new_node("cdecl"); Setattr($$,"name",$1.id); Setattr($$,"decl",$1.type); Setattr($$,"parms",$1.parms); - set_nextSibling($$,$2); + set_nextSibling($$,$3); } ; /* ------------------------------------------------------------ From f62c54c0f6d8a177580c9a715321f54cddae0e2c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 17 Nov 2009 19:28:29 +0000 Subject: [PATCH 078/146] add missing nested_workaround runtime test git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11751 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../java/nested_workaround_runme.java | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Examples/test-suite/java/nested_workaround_runme.java diff --git a/Examples/test-suite/java/nested_workaround_runme.java b/Examples/test-suite/java/nested_workaround_runme.java new file mode 100644 index 000000000..761a2da8e --- /dev/null +++ b/Examples/test-suite/java/nested_workaround_runme.java @@ -0,0 +1,31 @@ +import nested_workaround.*; + +public class nested_workaround_runme { + + static { + try { + System.loadLibrary("nested_workaround"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + { + Inner inner = new Inner(5); + Outer outer = new Outer(); + Inner newInner = outer.doubleInnerValue(inner); + if (newInner.getValue() != 10) + throw new RuntimeException("inner failed"); + } + + { + Outer outer = new Outer(); + Inner inner = outer.createInner(3); + Inner newInner = outer.doubleInnerValue(inner); + if (outer.getInnerValue(newInner) != 6) + throw new RuntimeException("inner failed"); + } + } +} From 7cb4e902d59aa73009cd4f928d5470fa68803f36 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 17 Nov 2009 19:31:13 +0000 Subject: [PATCH 079/146] Fix parsing of enum declaration and initialization git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11752 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 9 +++++++++ Examples/test-suite/enums.i | 20 ++++++++++++++++++-- Examples/test-suite/octave/enums_runme.m | 16 ++++++++++++++++ Examples/test-suite/python/enums_runme.py | 12 ++++++++++++ Source/CParse/parser.y | 6 +++--- 5 files changed, 58 insertions(+), 5 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index e97bbc58a..bc28d8fc1 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,15 @@ Version 1.3.41 (in progress) ============================ +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: diff --git a/Examples/test-suite/enums.i b/Examples/test-suite/enums.i index 00499f800..40be28e94 100644 --- a/Examples/test-suite/enums.i +++ b/Examples/test-suite/enums.i @@ -8,6 +8,7 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance1; %warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance2; %warnfilter(SWIGWARN_RUBY_WRONG_NAME) globalinstance3; +%warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK); %inline %{ @@ -64,7 +65,7 @@ typedef struct _iFoo enum { Phoo = +50, Char = 'a' - } e; + } e; } iFoo; %} #else @@ -77,5 +78,20 @@ struct iFoo }; }; %} - #endif + +// enum declaration and initialization +%inline %{ +enum Exclamation { + goodness, + gracious, + me +} enumInstance = me; + +enum ContainYourself { + slap = 10, + my, + thigh +} Slap = slap, My = my, Thigh = thigh, *pThigh = &Thigh, arrayContainYourself[3] = {slap, my, thigh}; +%} + diff --git a/Examples/test-suite/octave/enums_runme.m b/Examples/test-suite/octave/enums_runme.m index 91f2ce2bf..789f7c9e4 100644 --- a/Examples/test-suite/octave/enums_runme.m +++ b/Examples/test-suite/octave/enums_runme.m @@ -5,3 +5,19 @@ enums.bar2(1) enums.bar3(1) enums.bar1(1) +if (enums.cvar.enumInstance != 2) + error +endif + +if (enums.cvar.Slap != 10) + error +endif + +if (enums.cvar.My != 11) + error +endif + +if (enums.cvar.Thigh != 12) + error +endif + diff --git a/Examples/test-suite/python/enums_runme.py b/Examples/test-suite/python/enums_runme.py index 59a982974..e8dbe6942 100644 --- a/Examples/test-suite/python/enums_runme.py +++ b/Examples/test-suite/python/enums_runme.py @@ -5,3 +5,15 @@ _enums.bar2(1) _enums.bar3(1) _enums.bar1(1) +if _enums.cvar.enumInstance != 2: + raise RuntimeError + +if _enums.cvar.Slap != 10: + raise RuntimeError + +if _enums.cvar.My != 11: + raise RuntimeError + +if _enums.cvar.Thigh != 12: + raise RuntimeError + diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 0da3666f8..8b4521ef1 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3132,7 +3132,7 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI { add_symbols($$); /* Add to tag space */ add_symbols($5); /* Add enum values to id space */ } - | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail { + | storage_class ENUM ename LBRACE enumlist RBRACE declarator initializer c_decl_tail { Node *n; SwigType *ty = 0; String *unnamed = 0; @@ -3174,8 +3174,8 @@ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI { SetFlag(n,"unnamedinstance"); Delete(cty); } - if ($8) { - Node *p = $8; + if ($9) { + Node *p = $9; set_nextSibling(n,p); while (p) { SwigType *cty = Copy(ty); From a9ccc5a8662ea11776ab5c1b0aad66fade8086bf Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 18 Nov 2009 20:24:06 +0000 Subject: [PATCH 080/146] Fix multiple declarations of nested structs (C code) git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11753 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 8 + Examples/test-suite/common.mk | 2 +- .../test-suite/java/nested_structs_runme.java | 37 ++++ Examples/test-suite/nested_class.i | 5 + Examples/test-suite/nested_structs.i | 25 ++- Source/CParse/parser.y | 179 ++++++++++-------- 6 files changed, 176 insertions(+), 80 deletions(-) create mode 100644 Examples/test-suite/java/nested_structs_runme.java diff --git a/CHANGES.current b/CHANGES.current index bc28d8fc1..e00984fe0 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,14 @@ Version 1.3.41 (in progress) ============================ +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: diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index db28917ef..f9e06c0c4 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -80,7 +80,6 @@ CPP_TEST_BROKEN += \ exception_partial_info \ extend_variable \ li_std_vector_ptr \ - nested_structs \ overload_complicated \ template_default_pointer \ template_expr @@ -461,6 +460,7 @@ C_TEST_CASES += \ long_long \ name \ nested \ + nested_structs \ newobject2 \ overload_extend \ overload_extendc \ diff --git a/Examples/test-suite/java/nested_structs_runme.java b/Examples/test-suite/java/nested_structs_runme.java new file mode 100644 index 000000000..6e103cd12 --- /dev/null +++ b/Examples/test-suite/java/nested_structs_runme.java @@ -0,0 +1,37 @@ + +import nested_structs.*; + +public class nested_structs_runme { + + static { + try { + System.loadLibrary("nested_structs"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + Outer outer = new Outer(); + nested_structs.setValues(outer, 10); + + Outer_inner1 inner1 = outer.getInner1(); + Outer_inner2 inner2 = outer.getInner2(); + Outer_inner3 inner3 = outer.getInner3(); + Outer_inner4 inner4 = outer.getInner4(); + if (inner1.getVal() != 10) throw new RuntimeException("failed inner1"); + if (inner2.getVal() != 20) throw new RuntimeException("failed inner2"); + if (inner3.getVal() != 20) throw new RuntimeException("failed inner3"); + if (inner4.getVal() != 40) throw new RuntimeException("failed inner4"); + + Outer_inside1 inside1 = outer.getInside1(); + Outer_inside2 inside2 = outer.getInside2(); + Outer_inside3 inside3 = outer.getInside3(); + Outer_inside4 inside4 = outer.getInside4(); + if (inside1.getVal() != 100) throw new RuntimeException("failed inside1"); + if (inside2.getVal() != 200) throw new RuntimeException("failed inside2"); + if (inside3.getVal() != 200) throw new RuntimeException("failed inside3"); + if (inside4.getVal() != 400) throw new RuntimeException("failed inside4"); + } +} diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index cccebb136..89c9a8058 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -104,6 +104,11 @@ struct Outer { InnerStruct4* getInnerStruct4() { return 0; } InnerClass4* getInnerClass4() { return 0; } InnerUnion4* getInnerUnion4() { return 0; } + + /////////////////////////////////////////// + struct InnerMultiple { + Integer x; + } MultipleInstance1, MultipleInstance2; }; %} diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i index 41cdd63fb..60e34a638 100644 --- a/Examples/test-suite/nested_structs.i +++ b/Examples/test-suite/nested_structs.i @@ -2,11 +2,26 @@ // bug #491476 %inline %{ -struct { -struct { -int a; -} a, b; -} a; +struct Outer { + struct { + int val; + } inner1, inner2, *inner3, inner4[1]; + struct Named { + int val; + } inside1, inside2, *inside3, inside4[1]; +} outer; +void setValues(struct Outer *outer, int val) { + outer->inner1.val = val; + outer->inner2.val = val * 2; + outer->inner3 = &outer->inner2; + outer->inner4[0].val = val * 4; + + val = val * 10; + outer->inside1.val = val; + outer->inside2.val = val * 2; + outer->inside3 = &outer->inside2; + outer->inside4[0].val = val * 4; +} %} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 8b4521ef1..c7ca713f0 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -985,18 +985,16 @@ static String *resolve_node_scope(String *cname) { - - /* Structures for handling code fragments built for nested classes */ typedef struct Nested { String *code; /* Associated code fragment */ int line; /* line number where it starts */ - char *name; /* Name associated with this nested class */ - char *kind; /* Kind of class */ + const char *name; /* Name associated with this nested class */ + const char *kind; /* Kind of class */ int unnamed; /* unnamed class */ SwigType *type; /* Datatype associated with the name */ - struct Nested *next; /* Next code fragment in list */ + struct Nested *next; /* Next code fragment in list */ } Nested; /* Some internal variables for saving nested class information */ @@ -1006,15 +1004,96 @@ static Nested *nested_list = 0; /* Add a function to the nested list */ static void add_nested(Nested *n) { - Nested *n1; - if (!nested_list) nested_list = n; - else { - n1 = nested_list; - while (n1->next) n1 = n1->next; + if (!nested_list) { + nested_list = n; + } else { + Nested *n1 = nested_list; + while (n1->next) + n1 = n1->next; n1->next = n; } } +/* ----------------------------------------------------------------------------- + * nested_new_struct() + * + * Nested struct handling creates a global struct from the nested struct. + * ----------------------------------------------------------------------------- */ + +static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) { + String *name; + String *decl; + + /* Create a new global struct declaration which is just a copy of the nested struct */ + Nested *nested = (Nested *) malloc(sizeof(Nested)); + Nested *n = nested; + + name = Getattr(cpp_opt_declarators, "name"); + decl = Getattr(cpp_opt_declarators, "decl"); + n->code = NewStringEmpty(); + Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + n->name = Swig_copy_string(Char(name)); + n->line = cparse_start_line; + n->type = NewStringEmpty(); + n->kind = kind; + n->unnamed = 0; + SwigType_push(n->type, decl); + n->next = 0; + + /* Repeat for any multiple instances of the nested struct */ + { + Node *p = cpp_opt_declarators; + p = nextSibling(p); + while (p) { + Nested *nn = (Nested *) malloc(sizeof(Nested)); + + name = Getattr(p, "name"); + decl = Getattr(p, "decl"); + nn->code = NewStringEmpty(); + Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + nn->name = Swig_copy_string(Char(name)); + nn->line = cparse_start_line; + nn->type = NewStringEmpty(); + nn->kind = kind; + nn->unnamed = 0; + SwigType_push(nn->type, decl); + nn->next = 0; + n->next = nn; + n = nn; + p = nextSibling(p); + } + } + + add_nested(nested); +} + +/* ----------------------------------------------------------------------------- + * nested_forward_declaration() + * + * Treat the nested class/struct/union as a forward declaration until a proper + * nested class solution is implemented. + * ----------------------------------------------------------------------------- */ + +static Node *nested_forward_declaration(const char *kind, const char *name) { + Node *n = new_node("classforward"); + Setfile(n,cparse_file); + Setline(n,cparse_line); + Setattr(n,"kind", kind); + Setattr(n,"name", name); + Setattr(n,"sym:weak", "1"); + add_symbols(n); + + if (GetFlag(n, "feature:nestedworkaround")) { + Swig_symbol_remove(n); + n = 0; + } else { + SWIG_WARN_NODE_BEGIN(n); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name); + SWIG_WARN_NODE_END(n); + } + return n; +} + /* Strips C-style and C++-style comments from string in-place. */ static void strip_comments(char *string) { int state = 0; /* @@ -1434,33 +1513,6 @@ static void default_arguments(Node *n) { } } -/* ----------------------------------------------------------------------------- - * nested_forward_declaration() - * - * Treat the nested class/struct/union as a forward declaration until a proper - * nested class solution is implemented. - * ----------------------------------------------------------------------------- */ - -static Node *nested_forward_declaration(const char *kind, const char *name) { - Node *n = new_node("classforward"); - Setfile(n,cparse_file); - Setline(n,cparse_line); - Setattr(n,"kind", kind); - Setattr(n,"name", name); - Setattr(n,"sym:weak", "1"); - add_symbols(n); - - if (GetFlag(n, "feature:nestedworkaround")) { - Swig_symbol_remove(n); - n = 0; - } else { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name); - SWIG_WARN_NODE_END(n); - } - return n; -} - /* ----------------------------------------------------------------------------- * tag_nodes() * @@ -1609,7 +1661,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %type pragma_arg; %type includetype; %type pointer primitive_type; -%type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl; +%type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator; %type abstract_declarator direct_abstract_declarator ctor_end; %type typemap_type; %type idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi; @@ -4427,56 +4479,40 @@ cpp_protection_decl : PUBLIC COLON { /* struct sname { } id; or struct sname { }; declaration */ -cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); - } nested_decl SEMI { +cpp_nested : storage_class cpptype ID LBRACE { + cparse_start_line = cparse_line; skip_balanced('{','}'); + $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */ + } cpp_opt_declarators { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if (cparse_cplusplus) { $$ = nested_forward_declaration($2, $3); - } else if ($6.id) { - /* Generate some code for a new struct */ - Nested *n = (Nested *) malloc(sizeof(Nested)); - n->code = NewStringEmpty(); - Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL); - n->name = Swig_copy_string($6.id); - n->line = cparse_start_line; - n->type = NewStringEmpty(); - n->kind = $2; - n->unnamed = 0; - SwigType_push(n->type, $6.type); - n->next = 0; - add_nested(n); + } else if ($6) { + nested_new_struct($6, $2, $5); } } + Delete($5); } /* struct { } id; or struct { }; declaration */ - | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); - } nested_decl SEMI { + | storage_class cpptype LBRACE { + cparse_start_line = cparse_line; skip_balanced('{','}'); + $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */ + } cpp_opt_declarators { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - if ($5.id) { + if ($5) { if (cparse_cplusplus) { - $$ = nested_forward_declaration($2, $5.id); + $$ = nested_forward_declaration($2, Getattr($5, "name")); } else { - /* Generate some code for a new struct */ - Nested *n = (Nested *) malloc(sizeof(Nested)); - n->code = NewStringEmpty(); - Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL); - n->name = Swig_copy_string($5.id); - n->line = cparse_start_line; - n->type = NewStringEmpty(); - n->kind = $2; - n->unnamed = 1; - SwigType_push(n->type,$5.type); - n->next = 0; - add_nested(n); + nested_new_struct($5, $2, $4); } } else { Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); } } + Delete($4); } /* class name : base_list { }; declaration */ @@ -4502,11 +4538,6 @@ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line */ ; -nested_decl : declarator { $$ = $1;} - | empty { $$.id = 0; } - ; - - /* These directives can be included inside a class definition */ cpp_swig_directive: pragma_directive { $$ = $1; } From aa6712e3f2d39bb38e42f897508f323aad0023ee Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 18 Nov 2009 20:37:23 +0000 Subject: [PATCH 081/146] pretty print the nested structs generated as global structs git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11754 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index c7ca713f0..bf437cd66 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1021,6 +1021,7 @@ static void add_nested(Nested *n) { * ----------------------------------------------------------------------------- */ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) { + String *new_struct_decl; String *name; String *decl; @@ -1030,8 +1031,13 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin name = Getattr(cpp_opt_declarators, "name"); decl = Getattr(cpp_opt_declarators, "decl"); + n->code = NewStringEmpty(); - Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + new_struct_decl = NewStringEmpty(); + Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + Wrapper_pretty_print(new_struct_decl, n->code); + Delete(new_struct_decl); + n->name = Swig_copy_string(Char(name)); n->line = cparse_start_line; n->type = NewStringEmpty(); @@ -1049,8 +1055,13 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin name = Getattr(p, "name"); decl = Getattr(p, "decl"); + + new_struct_decl = NewStringEmpty(); nn->code = NewStringEmpty(); - Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); + Wrapper_pretty_print(new_struct_decl, n->code); + Delete(new_struct_decl); + nn->name = Swig_copy_string(Char(name)); nn->line = cparse_start_line; nn->type = NewStringEmpty(); From 43b6292681c8fd9629b1b4ebf39a87afd42a6952 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 18 Nov 2009 23:59:10 +0000 Subject: [PATCH 082/146] Nested struct pretty print rewrite and fix. The wrappers for C nested structs are now generated in the same order as declared in the parsed code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11755 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Source/CParse/parser.y | 47 ++++++++++++++---------------------------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index e00984fe0..10056a24b 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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 { diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index bf437cd66..431190790 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1021,7 +1021,6 @@ static void add_nested(Nested *n) { * ----------------------------------------------------------------------------- */ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) { - String *new_struct_decl; String *name; String *decl; @@ -1033,11 +1032,7 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin decl = Getattr(cpp_opt_declarators, "decl"); n->code = NewStringEmpty(); - new_struct_decl = NewStringEmpty(); - Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); - Wrapper_pretty_print(new_struct_decl, n->code); - Delete(new_struct_decl); - + Printv(n->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); n->name = Swig_copy_string(Char(name)); n->line = cparse_start_line; n->type = NewStringEmpty(); @@ -1056,12 +1051,8 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin name = Getattr(p, "name"); decl = Getattr(p, "decl"); - new_struct_decl = NewStringEmpty(); nn->code = NewStringEmpty(); - Printv(new_struct_decl, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); - Wrapper_pretty_print(new_struct_decl, n->code); - Delete(new_struct_decl); - + Printv(nn->code, "typedef ", kind, " ", struct_code, " $classname_", name, ";\n", NIL); nn->name = Swig_copy_string(Char(name)); nn->line = cparse_start_line; nn->type = NewStringEmpty(); @@ -1176,6 +1167,7 @@ static void strip_comments(char *string) { static Node *dump_nested(const char *parent) { Nested *n,*n1; Node *ret = 0; + Node *last = 0; n = nested_list; if (!parent) { nested_list = 0; @@ -1205,20 +1197,12 @@ static Node *dump_nested(const char *parent) { add_symbols(retx); if (ret) { - set_nextSibling(retx,ret); - Delete(ret); + set_nextSibling(last, retx); + Delete(retx); + } else { + ret = retx; } - ret = retx; - - /* Insert a forward class declaration */ - /* Disabled: [ 597599 ] union in class: incorrect scope - retx = new_node("classforward"); - Setattr(retx,"kind",n->kind); - Setattr(retx,"name",Copy(n->type)); - Setattr(retx,"sym:name", make_name(n->type,0)); - set_nextSibling(retx,ret); - ret = retx; - */ + last = retx; /* Strip comments - further code may break in presence of comments. */ strip_comments(Char(n->code)); @@ -1267,17 +1251,18 @@ static Node *dump_nested(const char *parent) { } } { - Node *head = new_node("insert"); - String *code = NewStringf("\n%s\n",n->code); - Setattr(head,"code", code); + Node *newnode = new_node("insert"); + String *code = NewStringEmpty(); + Wrapper_pretty_print(n->code, code); + Setattr(newnode,"code", code); Delete(code); - set_nextSibling(head,ret); - Delete(ret); - ret = head; + set_nextSibling(last, newnode); + Delete(newnode); + last = newnode; } /* Dump the code to the scanner */ - start_inline(Char(n->code),n->line); + start_inline(Char(Getattr(last, "code")),n->line); n1 = n->next; Delete(n->code); From 2a59a2e6a9c411be9da20de1c42869eaf4d91a1b Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 23 Nov 2009 23:02:01 +0000 Subject: [PATCH 083/146] Improved C++ nested class support - nested typedef'd classes now parsed and treated as forward class declaration git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11756 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 + .../test-suite/java/nested_class_runme.java | 72 ++++++++ Examples/test-suite/namespace_union.i | 2 +- Examples/test-suite/nested_class.i | 144 ++++++++++++--- Examples/test-suite/nested_comment.i | 31 ++-- Source/CParse/parser.y | 168 ++++++++++++------ 6 files changed, 324 insertions(+), 99 deletions(-) create mode 100644 Examples/test-suite/java/nested_class_runme.java diff --git a/CHANGES.current b/CHANGES.current index 10056a24b..bed2fea3f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/java/nested_class_runme.java b/Examples/test-suite/java/nested_class_runme.java new file mode 100644 index 000000000..f1c67a0af --- /dev/null +++ b/Examples/test-suite/java/nested_class_runme.java @@ -0,0 +1,72 @@ + +import nested_class.*; + +public class nested_class_runme { + + static { + try { + System.loadLibrary("nested_class"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + Outer outer = new Outer(); + SWIGTYPE_p_Outer__InnerStruct1 is1 = outer.makeInnerStruct1(); + SWIGTYPE_p_Outer__InnerClass1 ic1 = outer.makeInnerClass1(); + SWIGTYPE_p_Outer__InnerUnion1 iu1 = outer.makeInnerUnion1(); + + SWIGTYPE_p_Outer__InnerStruct2 is2 = outer.makeInnerStruct2(); + SWIGTYPE_p_Outer__InnerClass2 ic2 = outer.makeInnerClass2(); + SWIGTYPE_p_Outer__InnerUnion2 iu2 = outer.makeInnerUnion2(); + + SWIGTYPE_p_Outer__InnerClass4Typedef ic4 = outer.makeInnerClass4Typedef(); + SWIGTYPE_p_Outer__InnerStruct4Typedef is4 = outer.makeInnerStruct4Typedef(); + SWIGTYPE_p_Outer__InnerUnion4Typedef iu4 = outer.makeInnerUnion4Typedef(); + + SWIGTYPE_p_Outer__InnerClass5 ic5 = outer.makeInnerClass5(); + SWIGTYPE_p_Outer__InnerStruct5 is5 = outer.makeInnerStruct5(); + SWIGTYPE_p_Outer__InnerUnion5 iu5 = outer.makeInnerUnion5(); + + ic5 = outer.makeInnerClass5Typedef(); + is5 = outer.makeInnerStruct5Typedef(); + iu5 = outer.makeInnerUnion5Typedef(); + + { + SWIGTYPE_p_Outer__InnerMultiple im1 = outer.getMultipleInstance1(); + SWIGTYPE_p_Outer__InnerMultiple im2 = outer.getMultipleInstance2(); + SWIGTYPE_p_Outer__InnerMultiple im3 = outer.getMultipleInstance3(); + SWIGTYPE_p_Outer__InnerMultiple im4 = outer.getMultipleInstance4(); + } + + { + SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1(); + SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2(); + SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3(); + SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4(); + } + + { + SWIGTYPE_p_Outer__InnerMultipleDerived im1 = outer.getMultipleDerivedInstance1(); + SWIGTYPE_p_Outer__InnerMultipleDerived im2 = outer.getMultipleDerivedInstance2(); + SWIGTYPE_p_Outer__InnerMultipleDerived im3 = outer.getMultipleDerivedInstance3(); + SWIGTYPE_p_Outer__InnerMultipleDerived im4 = outer.getMultipleDerivedInstance4(); + } + + { + SWIGTYPE_p_Outer__InnerMultipleAnonTypedef1 mat1 = outer.makeInnerMultipleAnonTypedef1(); + SWIGTYPE_p_Outer__InnerMultipleAnonTypedef2 mat2 = outer.makeInnerMultipleAnonTypedef2(); + SWIGTYPE_p_Outer__InnerMultipleAnonTypedef3 mat3 = outer.makeInnerMultipleAnonTypedef3(); + + SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt = outer.makeInnerMultipleNamedTypedef(); + SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt1 = outer.makeInnerMultipleNamedTypedef1(); + SWIGTYPE_p_Outer__InnerMultipleNamedTypedef mnt2 = outer.makeInnerMultipleNamedTypedef2(); + SWIGTYPE_p_p_Outer__InnerMultipleNamedTypedef mnt3 = outer.makeInnerMultipleNamedTypedef3(); + } + { + SWIGTYPE_p_Outer__InnerSameName isn = outer.makeInnerSameName(); + } + } +} diff --git a/Examples/test-suite/namespace_union.i b/Examples/test-suite/namespace_union.i index 70698682e..85885f399 100644 --- a/Examples/test-suite/namespace_union.i +++ b/Examples/test-suite/namespace_union.i @@ -1,6 +1,6 @@ %module namespace_union -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) SpatialIndex::Variant::val; +#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS %inline %{ namespace SpatialIndex diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i index 89c9a8058..71d91f022 100644 --- a/Examples/test-suite/nested_class.i +++ b/Examples/test-suite/nested_class.i @@ -7,12 +7,18 @@ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass2; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct2; %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion2; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass3Name; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct3Name; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion3Name; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass4Typedef; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct4Typedef; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion4Typedef; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerClass5; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerStruct5; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerUnion5; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultiple; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleDerived; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleAnonTypedef1; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerMultipleNamedTypedef; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer::InnerSameName; +%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Outer2::IgnoreMe; %inline %{ struct Outer { @@ -51,64 +57,150 @@ struct Outer { class InnerClass2 { public: Integer x; - } InnerClass2Name; + } InnerClass2Instance; struct InnerStruct2 { Integer x; - } InnerStruct2Name; + } InnerStruct2Instance; union InnerUnion2 { Integer x; double y; - } InnerUnion2Name; + } InnerUnion2Instance; /////////////////////////////////////////// class { public: Integer x; - } InnerClass3Name; + } InnerClass3Instance; struct { Integer x; - } InnerStruct3Name; + } InnerStruct3Instance; union { Integer x; double y; - } InnerUnion3Name; + } InnerUnion3Instance; /////////////////////////////////////////// typedef class { public: Integer x; - } InnerClass4; + } InnerClass4Typedef; typedef struct { Integer x; - } InnerStruct4; + } InnerStruct4Typedef; typedef union { Integer x; double y; - } InnerUnion4; + } InnerUnion4Typedef; + + /////////////////////////////////////////// + typedef class InnerClass5 { + public: + Integer x; + } InnerClass5Typedef; + + typedef struct InnerStruct5 { + Integer x; + } InnerStruct5Typedef; + + typedef union InnerUnion5 { + Integer x; + double y; + } InnerUnion5Typedef; // bug #909387 - inner declared types are treated as forward declarations - InnerStruct1* getInnerStruct1() { return 0; } - InnerClass1* getInnerClass1() { return 0; } - InnerUnion1* getInnerUnion1() { return 0; } + InnerStruct1* makeInnerStruct1() { return 0; } + InnerClass1* makeInnerClass1() { return 0; } + InnerUnion1* makeInnerUnion1() { return 0; } - InnerStruct2* getInnerStruct2() { return 0; } - InnerClass2* getInnerClass2() { return 0; } - InnerUnion2* getInnerUnion2() { return 0; } + InnerStruct2* makeInnerStruct2() { return 0; } + InnerClass2* makeInnerClass2() { return 0; } + InnerUnion2* makeInnerUnion2() { return 0; } - InnerStruct4* getInnerStruct4() { return 0; } - InnerClass4* getInnerClass4() { return 0; } - InnerUnion4* getInnerUnion4() { return 0; } + InnerStruct4Typedef* makeInnerStruct4Typedef() { return 0; } + InnerClass4Typedef* makeInnerClass4Typedef() { return 0; } + InnerUnion4Typedef* makeInnerUnion4Typedef() { return 0; } + + InnerStruct5* makeInnerStruct5() { return 0; } + InnerClass5* makeInnerClass5() { return 0; } + InnerUnion5* makeInnerUnion5() { return 0; } + + InnerStruct5Typedef* makeInnerStruct5Typedef() { return 0; } + InnerClass5Typedef* makeInnerClass5Typedef() { return 0; } + InnerUnion5Typedef* makeInnerUnion5Typedef() { return 0; } /////////////////////////////////////////// struct InnerMultiple { Integer x; - } MultipleInstance1, MultipleInstance2; + } MultipleInstance1, MultipleInstance2, *MultipleInstance3, MultipleInstance4[2]; + + struct InnerMultipleDerived : public InnerMultiple { + Integer xx; + } MultipleDerivedInstance1, MultipleDerivedInstance2, *MultipleDerivedInstance3, MultipleDerivedInstance4[2]; + + struct { + Integer x; + } MultipleInstanceAnon1, MultipleInstanceAnon2, *MultipleInstanceAnon3, MultipleInstanceAnon4[2]; + + struct : public InnerMultiple { + Integer xx; + } MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2]; + + struct : public InnerMultiple { + Integer xx; + }; + + class : public InnerMultiple { + public: + Integer yy; + }; + + /////////////////////////////////////////// + typedef struct { + Integer x; + } InnerMultipleAnonTypedef1, InnerMultipleAnonTypedef2, *InnerMultipleAnonTypedef3; + + InnerMultipleAnonTypedef1* makeInnerMultipleAnonTypedef1() { return 0; } + InnerMultipleAnonTypedef2* makeInnerMultipleAnonTypedef2() { return 0; } + InnerMultipleAnonTypedef3* makeInnerMultipleAnonTypedef3() { return 0; } + + typedef struct InnerMultipleNamedTypedef { + Integer x; + } InnerMultipleNamedTypedef1, InnerMultipleNamedTypedef2, *InnerMultipleNamedTypedef3; + + InnerMultipleNamedTypedef* makeInnerMultipleNamedTypedef() { return 0; } + InnerMultipleNamedTypedef1* makeInnerMultipleNamedTypedef1() { return 0; } + InnerMultipleNamedTypedef2* makeInnerMultipleNamedTypedef2() { return 0; } + InnerMultipleNamedTypedef3* makeInnerMultipleNamedTypedef3() { return 0; } + + /////////////////////////////////////////// + typedef struct InnerSameName { + Integer x; + } InnerSameName; + + InnerSameName* makeInnerSameName() { return 0; } +}; +%} + +// Ignore nested struct instance +%ignore Outer2::IgnoreMeInstance; +%{ +struct Outer2 { + struct IgnoreMe { + int xx; + }; +}; +%} + +struct Outer2 { + struct IgnoreMe { + int xx; + } IgnoreMeInstance; }; -%} + diff --git a/Examples/test-suite/nested_comment.i b/Examples/test-suite/nested_comment.i index c246b8dab..99d0ffb43 100644 --- a/Examples/test-suite/nested_comment.i +++ b/Examples/test-suite/nested_comment.i @@ -1,26 +1,25 @@ %module nested_comment -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) s1::n; -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) a::d; +#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS // this example shows a problem with 'dump_nested' (parser.y). // bug #949654 %inline %{ -typedef struct s1 { -union { -int fsc; /* genie structure hiding - Conductor -*/ -int fso; /* genie structure hiding - FSOptions -*/ -struct { -double *vals; -int size; -} vector_val; /* matrix values are mainly used -in rlgc models */ -char *name; -} n ; -} s2; + typedef struct s1 { + union { + int fsc; /* genie structure hiding - Conductor + */ + int fso; /* genie structure hiding - FSOptions + */ + struct { + double *vals; + int size; + } vector_val; /* matrix values are mainly used + in rlgc models */ + char *name; + } n ; + } s2; %} // comment in nested struct diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 431190790..46485593f 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1017,10 +1017,21 @@ static void add_nested(Nested *n) { /* ----------------------------------------------------------------------------- * nested_new_struct() * - * Nested struct handling creates a global struct from the nested struct. + * Nested struct handling for C code only creates a global struct from the nested struct. + * + * Nested structure. This is a sick "hack". If we encounter + * a nested structure, we're going to grab the text of its definition and + * feed it back into the scanner. In the meantime, we need to grab + * variable declaration information and generate the associated wrapper + * code later. Yikes! + * + * This really only works in a limited sense. Since we use the + * code attached to the nested class to generate both C code + * it can't have any SWIG directives in it. It also needs to be parsable + * by SWIG or this whole thing is going to puke. * ----------------------------------------------------------------------------- */ -static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, String *struct_code) { +static void nested_new_struct(const char *kind, String *struct_code, Node *cpp_opt_declarators) { String *name; String *decl; @@ -1072,28 +1083,76 @@ static void nested_new_struct(Node *cpp_opt_declarators, const char *kind, Strin /* ----------------------------------------------------------------------------- * nested_forward_declaration() * + * Nested struct handling for C++ code only. + * * Treat the nested class/struct/union as a forward declaration until a proper * nested class solution is implemented. * ----------------------------------------------------------------------------- */ -static Node *nested_forward_declaration(const char *kind, const char *name) { - Node *n = new_node("classforward"); - Setfile(n,cparse_file); - Setline(n,cparse_line); - Setattr(n,"kind", kind); - Setattr(n,"name", name); - Setattr(n,"sym:weak", "1"); - add_symbols(n); +static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, const char *name, Node *cpp_opt_declarators) { + Node *nn = 0; + int warned = 0; - if (GetFlag(n, "feature:nestedworkaround")) { - Swig_symbol_remove(n); - n = 0; - } else { - SWIG_WARN_NODE_BEGIN(n); - Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, name); - SWIG_WARN_NODE_END(n); + if (sname) { + /* Add forward declaration of the nested type */ + Node *n = new_node("classforward"); + Setfile(n, cparse_file); + Setline(n, cparse_line); + Setattr(n, "kind", kind); + Setattr(n, "name", sname); + Setattr(n, "storage", storage); + Setattr(n, "sym:weak", "1"); + add_symbols(n); + nn = n; } - return n; + + /* Add any variable instances. Also add in any further typedefs of the nested type. + Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */ + if (cpp_opt_declarators) { + int storage_typedef = (storage && (strcmp(storage, "typedef") == 0)); + int variable_of_anonymous_type = !sname && !storage_typedef; + if (!variable_of_anonymous_type) { + int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0)); + Node *n = cpp_opt_declarators; + SwigType *type = NewString(name); + while (n) { + Setattr(n, "type", type); + Setattr(n, "storage", storage); + if (anonymous_typedef) { + Setattr(n, "nodeType", "classforward"); + Setattr(n, "sym:weak", "1"); + } + n = nextSibling(n); + } + Delete(type); + add_symbols(cpp_opt_declarators); + + if (nn) { + set_nextSibling(nn, cpp_opt_declarators); + } else { + nn = cpp_opt_declarators; + } + } + } + + if (nn && Equal(nodeType(nn), "classforward")) { + Node *n = nn; + if (GetFlag(n, "feature:nestedworkaround")) { + Swig_symbol_remove(n); + nn = 0; + warned = 1; + } else { + SWIG_WARN_NODE_BEGIN(n); + Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name); + SWIG_WARN_NODE_END(n); + warned = 1; + } + } + + if (!warned) + Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", kind); + + return nn; } /* Strips C-style and C++-style comments from string in-place. */ @@ -4460,67 +4519,64 @@ cpp_protection_decl : PUBLIC COLON { ; -/* ---------------------------------------------------------------------- - Nested structure. This is a sick "hack". If we encounter - a nested structure, we're going to grab the text of its definition and - feed it back into the scanner. In the meantime, we need to grab - variable declaration information and generate the associated wrapper - code later. Yikes! +/* ------------------------------------------------------------ + Named nested structs: + struct sname { }; + struct sname { } id; + struct sname : bases { }; + struct sname : bases { } id; + typedef sname struct { } td; + typedef sname struct : bases { } td; - This really only works in a limited sense. Since we use the - code attached to the nested class to generate both C/C++ code, - it can't have any SWIG directives in it. It also needs to be parsable - by SWIG or this whole thing is going to puke. - ---------------------------------------------------------------------- */ + Adding inheritance, ie replacing 'ID' with 'idcolon inherit' + added one shift/reduce + ------------------------------------------------------------ */ -/* struct sname { } id; or struct sname { }; declaration */ - -cpp_nested : storage_class cpptype ID LBRACE { +cpp_nested : storage_class cpptype idcolon inherit LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */ } cpp_opt_declarators { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if (cparse_cplusplus) { - $$ = nested_forward_declaration($2, $3); - } else if ($6) { - nested_new_struct($6, $2, $5); + $$ = nested_forward_declaration($1, $2, $3, $3, $7); + } else if ($7) { + nested_new_struct($2, $6, $7); } } - Delete($5); + Delete($6); } -/* struct { } id; or struct { }; declaration */ +/* ------------------------------------------------------------ + Unnamed/anonymous nested structs: + struct { }; + struct { } id; + struct : bases { }; + struct : bases { } id; + typedef struct { } td; + typedef struct : bases { } td; + ------------------------------------------------------------ */ - | storage_class cpptype LBRACE { + | storage_class cpptype inherit LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); $$ = NewString(scanner_ccode); /* copied as initializers overwrite scanner_ccode */ } cpp_opt_declarators { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { - if ($5) { - if (cparse_cplusplus) { - $$ = nested_forward_declaration($2, Getattr($5, "name")); - } else { - nested_new_struct($5, $2, $4); - } + if (cparse_cplusplus) { + const char *name = $6 ? Getattr($6, "name") : 0; + $$ = nested_forward_declaration($1, $2, 0, name, $6); } else { - Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + if ($6) { + nested_new_struct($2, $5, $6); + } else { + Swig_warning(WARN_PARSE_UNNAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); + } } } - Delete($4); + Delete($5); } -/* class name : base_list { }; declaration */ -/* This adds one shift/reduce. */ - - | storage_class cpptype idcolon COLON base_list LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); - } cpp_opt_declarators { - $$ = 0; - if (cplus_mode == CPLUS_PUBLIC) { - $$ = nested_forward_declaration($2, $3); - } - } /* This unfortunately introduces 4 shift/reduce conflicts, so instead the somewhat hacky nested_template is used for ignore nested template classes. */ /* From a07092b60c93de02beacf5c689693772bf499a6f Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 24 Nov 2009 07:16:26 +0000 Subject: [PATCH 084/146] Clarify typedef matching is typedef reduction only git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11757 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index da4fdadc9..7a89a679a 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -1245,6 +1245,26 @@ is rather esoteric--there's little practical reason to write a typemap quite lik to confuse your coworkers even more.

    +

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

    + +
    +
    +struct Struct {...};
    +typedef Struct StructTypedef;
    +
    +%typemap(in) StructTypedef { 
    +  ...
    +}
    +
    +void go(Struct aStruct);
    +
    +
    +

    10.3.3 Default typemaps

    From 1dd50f5ea8e75fe8035598661baf7a7535ee5de2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 26 Nov 2009 19:20:31 +0000 Subject: [PATCH 085/146] Fix %javaconst(1)/%csconst(1) for static const member variables to use the actual constant value if available git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11758 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 11 +++++++++++ Examples/test-suite/static_const_member.i | 6 ++++++ Source/Modules/csharp.cxx | 2 +- Source/Modules/java.cxx | 2 +- 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index bed2fea3f..e7ee49381 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,17 @@ Version 1.3.41 (in progress) ============================ +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 { diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i index 99dc89bd1..a650b8936 100644 --- a/Examples/test-suite/static_const_member.i +++ b/Examples/test-suite/static_const_member.i @@ -5,6 +5,12 @@ %module static_const_member +#if SWIGJAVA +%javaconst(1) EN; +#elif SWIGCSHARP +%csconst(1) EN; +#endif + %inline %{ class X { diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index a752fb933..1fb57baf3 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1394,7 +1394,7 @@ public: enum_constant_flag = false; } else { // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code - Printf(constants_code, "%s;\n", Getattr(n, "value")); + Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value")); } // Emit the generated code to appropriate place diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index fd6c768c9..20a665726 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1426,7 +1426,7 @@ public: enum_constant_flag = false; } else { // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code - Printf(constants_code, "%s;\n", Getattr(n, "value")); + Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value")); } // Emit the generated code to appropriate place From d756b28611396a8b2ac2c2df05a88babf0a585b2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 26 Nov 2009 19:32:14 +0000 Subject: [PATCH 086/146] Correct %exception documentation so no memory is leaked - bug #2903761 git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11759 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Customization.html | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html index ec73e5460..82e1c411f 100644 --- a/Doc/Manual/Customization.html +++ b/Doc/Manual/Customization.html @@ -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;
         }
     }
     
    From bf8ba3bf55f7b2e7d1cb1f18c637ee2e2b543f21 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 29 Nov 2009 01:29:26 +0000 Subject: [PATCH 087/146] Fix generated quoting when using %javaconst(1)/%csconst(1) for static const char member variables. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11760 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 10 ++++++++++ Examples/test-suite/static_const_member.i | 4 +++- Source/Modules/csharp.cxx | 9 ++++++++- Source/Modules/java.cxx | 9 ++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index e7ee49381..50c15c9e7 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,16 @@ Version 1.3.41 (in progress) ============================ +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 diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i index a650b8936..126f86496 100644 --- a/Examples/test-suite/static_const_member.i +++ b/Examples/test-suite/static_const_member.i @@ -6,9 +6,10 @@ %module static_const_member #if SWIGJAVA -%javaconst(1) EN; +%javaconst(1) CHARTEST; #elif SWIGCSHARP %csconst(1) EN; +%csconst(1) CHARTEST; #endif %inline %{ @@ -18,6 +19,7 @@ public: static const int PN = 0; static const int CN = 1; static const int EN = 2; + static const char CHARTEST = 'A'; }; %} diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 1fb57baf3..82a9a629c 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -1394,7 +1394,14 @@ public: enum_constant_flag = false; } else { // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code - Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value")); + if (Getattr(n, "wrappedasconstant")) { + if (SwigType_type(t) == T_CHAR) + Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value")); + else + Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); + } else { + Printf(constants_code, "%s;\n", Getattr(n, "value")); + } } // Emit the generated code to appropriate place diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 20a665726..7fccab5e1 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -1426,7 +1426,14 @@ public: enum_constant_flag = false; } else { // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code - Printf(constants_code, "%s;\n", Getattr(n, "wrappedasconstant") ? Getattr(n, "staticmembervariableHandler:value") : Getattr(n, "value")); + if (Getattr(n, "wrappedasconstant")) { + if (SwigType_type(t) == T_CHAR) + Printf(constants_code, "\'%s\';\n", Getattr(n, "staticmembervariableHandler:value")); + else + Printf(constants_code, "%s;\n", Getattr(n, "staticmembervariableHandler:value")); + } else { + Printf(constants_code, "%s;\n", Getattr(n, "value")); + } } // Emit the generated code to appropriate place From b9817010fb597babea511adee712cf8d379f219c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 29 Nov 2009 01:50:21 +0000 Subject: [PATCH 088/146] add in missing line since last commit git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11761 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/static_const_member.i | 1 + 1 file changed, 1 insertion(+) diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i index 126f86496..3db60b4c2 100644 --- a/Examples/test-suite/static_const_member.i +++ b/Examples/test-suite/static_const_member.i @@ -6,6 +6,7 @@ %module static_const_member #if SWIGJAVA +%javaconst(1) EN; %javaconst(1) CHARTEST; #elif SWIGCSHARP %csconst(1) EN; From 2bd190dbf1cd79c5c4072d3b0891054c6b03ff1e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 2 Dec 2009 00:01:31 +0000 Subject: [PATCH 089/146] 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. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11762 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 5 +++ Doc/Manual/SWIG.html | 10 ++--- Examples/test-suite/common.mk | 1 + Examples/test-suite/memberin_extend.i | 15 ++++++- Examples/test-suite/memberin_extend_c.i | 25 +++++++++++ .../python/memberin_extend_c_runme.py | 6 +++ Source/Modules/lang.cxx | 45 +++++++++---------- Source/Swig/cwrap.c | 14 +++--- Source/Swig/swig.h | 2 +- 9 files changed, 85 insertions(+), 38 deletions(-) create mode 100644 Examples/test-suite/memberin_extend_c.i create mode 100644 Examples/test-suite/python/memberin_extend_c_runme.py diff --git a/CHANGES.current b/CHANGES.current index 50c15c9e7..d5b5e9670 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,11 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index dd1b22095..8818a6c60 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -2493,7 +2493,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); } %} @@ -2512,10 +2512,10 @@ For example, consider this interface:
    -struct Person {
    +typedef struct {
        char name[50];
        ...
    -}
    +} Person;
     
    @@ -2527,12 +2527,12 @@ as follows to change this:
    -struct Person {
    +typedef struct {
         %extend {
            char *name;
         }
     ...
    -}
    +} Person;
     
     // Specific implementation of set/get functions
     %{
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index f9e06c0c4..bb72e4988 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -458,6 +458,7 @@ C_TEST_CASES += \
     	li_cpointer \
     	li_math \
     	long_long \
    +	memberin_extend_c \
     	name \
     	nested \
     	nested_structs \
    diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i
    index f20617b66..94d2cab3f 100644
    --- a/Examples/test-suite/memberin_extend.i
    +++ b/Examples/test-suite/memberin_extend.i
    @@ -12,8 +12,19 @@ struct ExtendMe {
     %{
     #include 
     std::map ExtendMeStringMap;
    -#define ExtendMe_thing_set(self_, val_) ExtendMeStringMap[self_]
    -#define ExtendMe_thing_get(self_) ExtendMeStringMap[self_]
    +void ExtendMe_thing_set(ExtendMe *self, const char *val) {
    +  char *old_val = ExtendMeStringMap[self];
    +  delete [] old_val;
    +  if (val) {
    +    ExtendMeStringMap[self] = new char[strlen(val)+1];
    +    strcpy(ExtendMeStringMap[self], val);
    +  } else {
    +    ExtendMeStringMap[self] = 0;
    +  }
    +}
    +char * ExtendMe_thing_get(ExtendMe *self) {
    +  return ExtendMeStringMap[self];
    +}
     %}
     
     %extend ExtendMe {
    diff --git a/Examples/test-suite/memberin_extend_c.i b/Examples/test-suite/memberin_extend_c.i
    new file mode 100644
    index 000000000..e0c2f6333
    --- /dev/null
    +++ b/Examples/test-suite/memberin_extend_c.i
    @@ -0,0 +1,25 @@
    +%module memberin_extend_c
    +
    +/* Example from the Manual, section 5.5.6: "Adding member functions to C structures" */
    +
    +%{
    +typedef struct {
    +    char name[50];
    +} Person;
    +%}
    +
    +typedef struct {
    +    %extend {
    +        char *name;
    +    }
    +} Person;
    +
    +/* Specific implementation of set/get functions */
    +%{
    +char *Person_name_get(Person *p) {
    +   return p->name;
    +}
    +void Person_name_set(Person *p, char *val) {
    +   strncpy(p->name,val,50);
    +}
    +%}
    diff --git a/Examples/test-suite/python/memberin_extend_c_runme.py b/Examples/test-suite/python/memberin_extend_c_runme.py
    new file mode 100644
    index 000000000..af84535eb
    --- /dev/null
    +++ b/Examples/test-suite/python/memberin_extend_c_runme.py
    @@ -0,0 +1,6 @@
    +import memberin_extend_c
    +
    +t = memberin_extend_c.Person()
    +t.name = "some name"
    +if t.name != "some name":
    +  raise RuntimeError("some name wrong")
    diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
    index e58f2b022..971b56ec1 100644
    --- a/Source/Modules/lang.cxx
    +++ b/Source/Modules/lang.cxx
    @@ -1407,39 +1407,36 @@ int Language::membervariableHandler(Node *n) {
     	  target = NewStringf("%s->%s", pname, name);
     	  Delete(pname);
     	}
    -      } else {
    -	 target = NewStringf("$extendgetcall"); // member variable access expanded later
    +	tm = Swig_typemap_lookup("memberin", n, target, 0);
           }
    -      tm = Swig_typemap_lookup("memberin", n, target, 0);
           int flags = Extend | SmartPointer | use_naturalvar_mode(n);
           if (is_non_virtual_protected_access(n))
             flags = flags | CWRAP_ALL_PROTECTED_ACCESS;
     
    -      String *call = 0;
    -      Swig_MembersetToFunction(n, ClassType, flags, &call);
    +      Swig_MembersetToFunction(n, ClassType, flags);
           Setattr(n, "memberset", "1");
    +      if (!Extend) {
    +	/* Check for a member in typemap here */
     
    -      if (!tm) {
    -	if (SwigType_isarray(type)) {
    -	  Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
    -	  make_set_wrapper = 0;
    +	if (!tm) {
    +	  if (SwigType_isarray(type)) {
    +	    Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type, 0));
    +	    make_set_wrapper = 0;
    +	  }
    +	} else {
    +	  String *pname0 = Swig_cparm_name(0, 0);
    +	  String *pname1 = Swig_cparm_name(0, 1);
    +	  Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
    +	  Replace(tm, "$target", target, DOH_REPLACE_ANY);
    +	  Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
    +	  Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
    +	  Setattr(n, "wrap:action", tm);
    +	  Delete(tm);
    +	  Delete(pname0);
    +	  Delete(pname1);
     	}
    -      } else {
    -	String *pname0 = Swig_cparm_name(0, 0);
    -	String *pname1 = Swig_cparm_name(0, 1);
    -	Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
    -	Replace(tm, "$target", target, DOH_REPLACE_ANY);
    -	Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
    -	Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
    -	Replace(tm, "$extendgetcall", call, DOH_REPLACE_ANY);
    -	Setattr(n, "wrap:action", tm);
    -	Delete(tm);
    -	Delete(pname0);
    -	Delete(pname1);
    +	Delete(target);
           }
    -      Delete(call);
    -      Delete(target);
    -
           if (make_set_wrapper) {
     	Setattr(n, "sym:name", mrename_set);
     	functionWrapper(n);
    diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c
    index 121ea150a..7b2646b0e 100644
    --- a/Source/Swig/cwrap.c
    +++ b/Source/Swig/cwrap.c
    @@ -1207,7 +1207,7 @@ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags)
      * This function creates a C wrapper for setting a structure member.
      * ----------------------------------------------------------------------------- */
     
    -int Swig_MembersetToFunction(Node *n, String *classname, int flags, String **call) {
    +int Swig_MembersetToFunction(Node *n, String *classname, int flags) {
       String *name;
       ParmList *parms;
       Parm *p;
    @@ -1255,21 +1255,23 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags, String **cal
       Delete(p);
     
       if (flags & CWRAP_EXTEND) {
    +    String *call;
         String *cres;
         String *code = Getattr(n, "code");
         if (code) {
           /* I don't think this ever gets run - WSF */
           Swig_add_extension_code(n, mangled, parms, void_type, code, cparse_cplusplus, "self");
         }
    -    *call = Swig_cfunction_call(mangled, parms);
    -    cres = NewStringf("%s;", *call);
    +    call = Swig_cfunction_call(mangled, parms);
    +    cres = NewStringf("%s;", call);
         Setattr(n, "wrap:action", cres);
    +    Delete(call);
         Delete(cres);
       } else {
    -    String *cres;
    -    *call = Swig_cmemberset_call(name, type, self, varcref);
    -    cres = NewStringf("%s;", *call);
    +    String *call = Swig_cmemberset_call(name, type, self, varcref);
    +    String *cres = NewStringf("%s;", call);
         Setattr(n, "wrap:action", cres);
    +    Delete(call);
         Delete(cres);
       }
       Setattr(n, "type", void_type);
    diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
    index 33f977b52..2c2d4aa3b 100644
    --- a/Source/Swig/swig.h
    +++ b/Source/Swig/swig.h
    @@ -348,7 +348,7 @@ extern int        ParmList_is_compactdefargs(ParmList *p);
       extern int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *director_type, int is_director);
       extern int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags);
       extern int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags);
    -  extern int Swig_MembersetToFunction(Node *n, String *classname, int flags, String **call);
    +  extern int Swig_MembersetToFunction(Node *n, String *classname, int flags);
       extern int Swig_MembergetToFunction(Node *n, String *classname, int flags);
       extern int Swig_VargetToFunction(Node *n, int flags);
       extern int Swig_VarsetToFunction(Node *n, int flags);
    
    From 2c74fbf9e41684fde01d6b2a99d0c1655e889fa2 Mon Sep 17 00:00:00 2001
    From: Olly Betts 
    Date: Wed, 2 Dec 2009 13:02:38 +0000
    Subject: [PATCH 090/146] [PHP] Fix warning and rename of reserved class name
     to be case insensitive.
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11763 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     CHANGES.current                           |   3 +
     Examples/test-suite/php_namewarn_rename.i |   8 +-
     Lib/php/phpkw.swg                         | 200 +++++++++++-----------
     3 files changed, 110 insertions(+), 101 deletions(-)
    
    diff --git a/CHANGES.current b/CHANGES.current
    index d5b5e9670..d81907f2c 100644
    --- a/CHANGES.current
    +++ b/CHANGES.current
    @@ -1,6 +1,9 @@
     Version 1.3.41 (in progress)
     ============================
     
    +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.
    diff --git a/Examples/test-suite/php_namewarn_rename.i b/Examples/test-suite/php_namewarn_rename.i
    index cebe93f02..e3447a9c4 100644
    --- a/Examples/test-suite/php_namewarn_rename.i
    +++ b/Examples/test-suite/php_namewarn_rename.i
    @@ -2,19 +2,25 @@
     
     #ifdef SWIGPHP
     %warnfilter(SWIGWARN_PARSE_KEYWORD) Empty();
    -// FIXME: this doesn't work for me:
     %warnfilter(SWIGWARN_PARSE_KEYWORD) stdClass;
    +%warnfilter(SWIGWARN_PARSE_KEYWORD) directory;
     %warnfilter(SWIGWARN_PARSE_KEYWORD) Hello::empty();
     #endif
     
     %inline %{
     
    +  int Exception() { return 13; }
    +
       void Empty() {}
     
       class stdClass
       {
       };
     
    +  class directory
    +  {
    +  };
    +
       struct Hello
       {
         void empty() {}
    diff --git a/Lib/php/phpkw.swg b/Lib/php/phpkw.swg
    index a5f410bc5..5e60583cb 100644
    --- a/Lib/php/phpkw.swg
    +++ b/Lib/php/phpkw.swg
    @@ -5,13 +5,13 @@
      * phpkw.swg
      * ----------------------------------------------------------------------------- */
     
    -#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword, renamed as 'c_" `x` "'",sourcefmt="%(lower)s",$isclass,rename="c_%s")  `x`
    +#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword, renamed as 'c_" `x` "'",sourcefmt="%(lower)s",rename="c_%s") `x`
     
    -#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name, class renamed as 'c_" `x` "'",%$isclass,rename="c_%s") `x`
    +#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name, class renamed as 'c_" `x` "'",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
     
    -#define PHPBN1(x) %builtinwarn("'" `x` "' conflicts with a built-in name in PHP",sourcefmt="%(lower)s")  `x`
    -#define PHPBN2(x) %builtinwarn("'" `x` "' conflicts with a built-in name in PHP")  "::" `x`
    -#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function, renamed as 'c_" `x` "'",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s")  `x`
    +#define PHPBN1(x) %builtinwarn("'" `x` "' conflicts with a built-in name in PHP",sourcefmt="%(lower)s") `x`
    +#define PHPBN2(x) %builtinwarn("'" `x` "' conflicts with a built-in name in PHP") "::" `x`
    +#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function, renamed as 'c_" `x` "'",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
     
     /*
        From
    @@ -355,105 +355,105 @@ PHPBN2(E_STRICT);
     PHPBN2(__COMPILER_HALT_OFFSET__);
     
     /* Class names reserved by PHP */
    -PHPCN(stdClass);
    -PHPCN(__PHP_Incomplete_Class);
    -PHPCN(Directory);
    -
    +/* case insensitive */
    +PHPCN(stdclass);
    +PHPCN(__php_incomplete_class);
    +PHPCN(directory);
     /* Added in PHP5 (this list apparently depends which extensions you load by default). */
     PHPCN(parent);
     PHPCN(self);
    -PHPCN(Exception);
    +PHPCN(exception);
     PHPCN(php_user_filter);
    -PHPCN(ErrorException);
    -PHPCN(XMLWriter);
    -PHPCN(LibXMLError);
    -PHPCN(SimpleXMLElement);
    -PHPCN(SoapClient);
    -PHPCN(SoapVar);
    -PHPCN(SoapServer);
    -PHPCN(SoapFault);
    -PHPCN(SoapParam);
    -PHPCN(SoapHeader);
    -PHPCN(RecursiveIteratorIterator);
    -PHPCN(FilterIterator);
    -PHPCN(RecursiveFilterIterator);
    -PHPCN(ParentIterator);
    -PHPCN(LimitIterator);
    -PHPCN(CachingIterator);
    -PHPCN(RecursiveCachingIterator);
    -PHPCN(IteratorIterator);
    -PHPCN(NoRewindIterator);
    -PHPCN(AppendIterator);
    -PHPCN(InfiniteIterator);
    -PHPCN(EmptyIterator);
    -PHPCN(ArrayObject);
    -PHPCN(ArrayIterator);
    -PHPCN(RecursiveArrayIterator);
    -PHPCN(SplFileInfo);
    -PHPCN(DirectoryIterator);
    -PHPCN(RecursiveDirectoryIterator);
    -PHPCN(SplFileObject);
    -PHPCN(SplTempFileObject);
    -PHPCN(SimpleXMLIterator);
    -PHPCN(LogicException);
    -PHPCN(BadFunctionCallException);
    -PHPCN(BadMethodCallException);
    -PHPCN(DomainException);
    -PHPCN(InvalidArgumentException);
    -PHPCN(LengthException);
    -PHPCN(OutOfRangeException);
    -PHPCN(RuntimeException);
    -PHPCN(OutOfBoundsException);
    -PHPCN(OverflowException);
    -PHPCN(RangeException);
    -PHPCN(UnderflowException);
    -PHPCN(UnexpectedValueException);
    -PHPCN(SplObjectStorage);
    -PHPCN(ReflectionException);
    -PHPCN(Reflection);
    -PHPCN(ReflectionFunction);
    -PHPCN(ReflectionParameter);
    -PHPCN(ReflectionMethod);
    -PHPCN(ReflectionClass);
    -PHPCN(ReflectionObject);
    -PHPCN(ReflectionProperty);
    -PHPCN(ReflectionExtension);
    -PHPCN(DOMException);
    -PHPCN(DOMStringList);
    -PHPCN(DOMNameList);
    -PHPCN(DOMImplementationList);
    -PHPCN(DOMImplementationSource);
    -PHPCN(DOMImplementation);
    -PHPCN(DOMNode);
    -PHPCN(DOMNameSpaceNode);
    -PHPCN(DOMDocumentFragment);
    -PHPCN(DOMDocument);
    -PHPCN(DOMNodeList);
    -PHPCN(DOMNamedNodeMap);
    -PHPCN(DOMCharacterData);
    -PHPCN(DOMAttr);
    -PHPCN(DOMElement);
    -PHPCN(DOMText);
    -PHPCN(DOMComment);
    -PHPCN(DOMTypeinfo);
    -PHPCN(DOMUserDataHandler);
    -PHPCN(DOMDomError);
    -PHPCN(DOMErrorHandler);
    -PHPCN(DOMLocator);
    -PHPCN(DOMConfiguration);
    -PHPCN(DOMCdataSection);
    -PHPCN(DOMDocumentType);
    -PHPCN(DOMNotation);
    -PHPCN(DOMEntity);
    -PHPCN(DOMEntityReference);
    -PHPCN(DOMProcessingInstruction);
    -PHPCN(DOMStringExtend);
    -PHPCN(DOMXPath);
    -PHPCN(XMLReader);
    -PHPCN(SQLiteDatabase);
    -PHPCN(SQLiteResult);
    -PHPCN(SQLiteUnbuffered);
    -PHPCN(SQLiteException);
    +PHPCN(errorexception);
    +PHPCN(xmlwriter);
    +PHPCN(libxmlerror);
    +PHPCN(simplexmlelement);
    +PHPCN(soapclient);
    +PHPCN(soapvar);
    +PHPCN(soapserver);
    +PHPCN(soapfault);
    +PHPCN(soapparam);
    +PHPCN(soapheader);
    +PHPCN(recursiveiteratoriterator);
    +PHPCN(filteriterator);
    +PHPCN(recursivefilteriterator);
    +PHPCN(parentiterator);
    +PHPCN(limititerator);
    +PHPCN(cachingiterator);
    +PHPCN(recursivecachingiterator);
    +PHPCN(iteratoriterator);
    +PHPCN(norewinditerator);
    +PHPCN(appenditerator);
    +PHPCN(infiniteiterator);
    +PHPCN(emptyiterator);
    +PHPCN(arrayobject);
    +PHPCN(arrayiterator);
    +PHPCN(recursivearrayiterator);
    +PHPCN(splfileinfo);
    +PHPCN(directoryiterator);
    +PHPCN(recursivedirectoryiterator);
    +PHPCN(splfileobject);
    +PHPCN(spltempfileobject);
    +PHPCN(simplexmliterator);
    +PHPCN(logicexception);
    +PHPCN(badfunctioncallexception);
    +PHPCN(badmethodcallexception);
    +PHPCN(domainexception);
    +PHPCN(invalidargumentexception);
    +PHPCN(lengthexception);
    +PHPCN(outofrangeexception);
    +PHPCN(runtimeexception);
    +PHPCN(outofboundsexception);
    +PHPCN(overflowexception);
    +PHPCN(rangeexception);
    +PHPCN(underflowexception);
    +PHPCN(unexpectedvalueexception);
    +PHPCN(splobjectstorage);
    +PHPCN(reflectionexception);
    +PHPCN(reflection);
    +PHPCN(reflectionfunction);
    +PHPCN(reflectionparameter);
    +PHPCN(reflectionmethod);
    +PHPCN(reflectionclass);
    +PHPCN(reflectionobject);
    +PHPCN(reflectionproperty);
    +PHPCN(reflectionextension);
    +PHPCN(domexception);
    +PHPCN(domstringlist);
    +PHPCN(domnamelist);
    +PHPCN(domimplementationlist);
    +PHPCN(domimplementationsource);
    +PHPCN(domimplementation);
    +PHPCN(domnode);
    +PHPCN(domnamespacenode);
    +PHPCN(domdocumentfragment);
    +PHPCN(domdocument);
    +PHPCN(domnodelist);
    +PHPCN(domnamednodemap);
    +PHPCN(domcharacterdata);
    +PHPCN(domattr);
    +PHPCN(domelement);
    +PHPCN(domtext);
    +PHPCN(domcomment);
    +PHPCN(domtypeinfo);
    +PHPCN(domuserdatahandler);
    +PHPCN(domdomerror);
    +PHPCN(domerrorhandler);
    +PHPCN(domlocator);
    +PHPCN(domconfiguration);
    +PHPCN(domcdatasection);
    +PHPCN(domdocumenttype);
    +PHPCN(domnotation);
    +PHPCN(domentity);
    +PHPCN(domentityreference);
    +PHPCN(domprocessinginstruction);
    +PHPCN(domstringextend);
    +PHPCN(domxpath);
    +PHPCN(xmlreader);
    +PHPCN(sqlitedatabase);
    +PHPCN(sqliteresult);
    +PHPCN(sqliteunbuffered);
    +PHPCN(sqliteexception);
     
     /* Built-in PHP functions (incomplete). */
     PHPFN(cos);
    
    From 09a801dd9e461f571e89c12efa02a6c908f8a77d Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Wed, 2 Dec 2009 22:16:48 +0000
    Subject: [PATCH 091/146] Change %extend example which said that char arrays
     were problematic to wrap, when in fact they are not
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11764 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     Doc/Manual/SWIG.html                          | 44 ++++++++++++-------
     Examples/test-suite/memberin_extend.i         |  2 +-
     Examples/test-suite/memberin_extend_c.i       | 29 ++++++++----
     .../python/memberin_extend_c_runme.py         |  6 +--
     4 files changed, 53 insertions(+), 28 deletions(-)
    
    diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
    index 8818a6c60..c17add4c5 100644
    --- a/Doc/Manual/SWIG.html
    +++ b/Doc/Manual/SWIG.html
    @@ -2506,41 +2506,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:

     typedef struct {
    -   char name[50];
    -   ...
    +  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:

     typedef struct {
    -    %extend {
    -       char *name;
    -    }
    -...
    +  %extend {
    +    char name[50];
    +  }
    +  ...
     } Person;
     
    -// Specific implementation of set/get functions
     %{
    -char *Person_name_get(Person *p) {
    -   return p->name;
    +#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 forcing capitalization */
    +
    +char *Person_name_get(Person *p) {
    +  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);
     }
     %}
     
    @@ -2550,7 +2562,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).

    @@ -2633,7 +2645,7 @@ $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. diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i index 94d2cab3f..c6eb10526 100644 --- a/Examples/test-suite/memberin_extend.i +++ b/Examples/test-suite/memberin_extend.i @@ -1,6 +1,6 @@ %module memberin_extend -// Tests memberin typemap. The default char * memberin typemap will be used. +// Tests memberin typemap is not used for %extend. // The test extends the struct with a pseudo member variable %inline %{ diff --git a/Examples/test-suite/memberin_extend_c.i b/Examples/test-suite/memberin_extend_c.i index e0c2f6333..0599e65a0 100644 --- a/Examples/test-suite/memberin_extend_c.i +++ b/Examples/test-suite/memberin_extend_c.i @@ -4,22 +4,35 @@ %{ typedef struct { - char name[50]; + char name[50]; } Person; %} typedef struct { - %extend { - char *name; - } + %extend { + char name[50]; + } } Person; -/* Specific implementation of set/get functions */ %{ -char *Person_name_get(Person *p) { - return p->name; +#include +#include + +void make_upper(char *name) { + char *c; + for (c = name; *c; ++c) + *c = (char)toupper((int)*c); } + +/* Specific implementation of set/get functions forcing capitalization */ + +char *Person_name_get(Person *p) { + 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); } %} diff --git a/Examples/test-suite/python/memberin_extend_c_runme.py b/Examples/test-suite/python/memberin_extend_c_runme.py index af84535eb..314761f89 100644 --- a/Examples/test-suite/python/memberin_extend_c_runme.py +++ b/Examples/test-suite/python/memberin_extend_c_runme.py @@ -1,6 +1,6 @@ import memberin_extend_c t = memberin_extend_c.Person() -t.name = "some name" -if t.name != "some name": - raise RuntimeError("some name wrong") +t.name = "Fred Bloggs" +if t.name != "FRED BLOGGS": + raise RuntimeError("name wrong") From 52bdfa30973c7912ae5bf31318f8c578a17db76b Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 01:29:45 +0000 Subject: [PATCH 092/146] Add input typemaps for long long and unsigned long long for PHP. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11765 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/php/php.swg | 4 ++++ Lib/php/utils.i | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Lib/php/php.swg b/Lib/php/php.swg index a604b035b..de8904cb0 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -55,6 +55,10 @@ %pass_by_val(long, CONVERT_INT_IN); %pass_by_val(unsigned long, CONVERT_INT_IN); +%pass_by_val(signed long long, CONVERT_LONG_LONG_IN); +%pass_by_val(long long, CONVERT_LONG_LONG_IN); +%pass_by_val(unsigned long long, CONVERT_UNSIGNED_LONG_LONG_IN); + %pass_by_val(signed char, CONVERT_INT_IN); %pass_by_val(char, CONVERT_CHAR_IN); %pass_by_val(unsigned char, CONVERT_INT_IN); diff --git a/Lib/php/utils.i b/Lib/php/utils.i index 166941585..07ac96900 100644 --- a/Lib/php/utils.i +++ b/Lib/php/utils.i @@ -9,6 +9,42 @@ lvar = (t) Z_LVAL_PP(invar); %enddef +%define CONVERT_LONG_LONG_IN(lvar,t,invar) + switch ((*(invar))->type) { + case IS_DOUBLE: + lvar = (t) (*(invar))->value.dval; + break; + case IS_STRING: { + char * endptr; + errno = 0; + lvar = (t) strtoll((*(invar))->value.str.val, &endptr, 10); + if (*endptr && !errno) break; + /* FALL THRU */ + } + default: + convert_to_long_ex(invar); + lvar = (t) (*(invar))->value.lval; + } +%enddef + +%define CONVERT_UNSIGNED_LONG_LONG_IN(lvar,t,invar) + switch ((*(invar))->type) { + case IS_DOUBLE: + lvar = (t) (*(invar))->value.dval; + break; + case IS_STRING: { + char * endptr; + errno = 0; + lvar = (t) strtoull((*(invar))->value.str.val, &endptr, 10); + if (*endptr && !errno) break; + /* FALL THRU */ + } + default: + convert_to_long_ex(invar); + lvar = (t) (*(invar))->value.lval; + } +%enddef + %define CONVERT_INT_OUT(lvar,invar) lvar = (t) Z_LVAL_PP(invar); %enddef From d6984c5253ee6115f51f9e217a98dcc8981f7ff1 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 04:48:54 +0000 Subject: [PATCH 093/146] [PHP] Add typemaps for long long and unsigned long long. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11766 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 3 +++ Lib/php/php.swg | 2 ++ Lib/php/typemaps.i | 32 ++++++++++++++++++++++++++------ 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index d81907f2c..60b19cf3e 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,9 @@ Version 1.3.41 (in progress) ============================ +2009-12-03: olly + [PHP] Add typemaps for long long and unsigned long long. + 2009-12-02: olly [PHP] Fix warning and rename of reserved class name to be case insensitive. diff --git a/Lib/php/php.swg b/Lib/php/php.swg index de8904cb0..8deb85254 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -361,6 +361,8 @@ %php_typecheck(unsigned short,SWIG_TYPECHECK_UINT16,IS_LONG) %php_typecheck(long,SWIG_TYPECHECK_INT64,IS_LONG) %php_typecheck(unsigned long,SWIG_TYPECHECK_UINT64,IS_LONG) +%php_typecheck(long long,SWIG_TYPECHECK_INT64,IS_LONG) +%php_typecheck(unsigned long long,SWIG_TYPECHECK_UINT64,IS_LONG) %php_typecheck(signed char,SWIG_TYPECHECK_INT8,IS_LONG) %php_typecheck(unsigned char,SWIG_TYPECHECK_UINT8,IS_LONG) %php_typecheck(size_t,SWIG_TYPECHECK_INT16,IS_LONG) diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i index 7af301d0d..cc2341b19 100644 --- a/Lib/php/typemaps.i +++ b/Lib/php/typemaps.i @@ -112,9 +112,7 @@ int_typemap(long long); } %typemap(in) TYPE *REFERENCE (long long lvalue) %{ - // FIXME won't work for values which don't fit in a long... - convert_to_long_ex($input); - lvalue = (long long) (*$input)->value.lval; + CONVERT_LONG_LONG_IN(lvalue, long long, $input) $1 = &lvalue; %} %typemap(argout) long long *REFERENCE @@ -128,6 +126,17 @@ int_typemap(long long); ZVAL_STRING((*$arg), temp, 1); } %} +%typemap(argout) long long &OUTPUT +%{ + if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) { + ($result)->value.lval = (long)(*arg$argnum); + ($result)->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%lld", *arg$argnum); + ZVAL_STRING($result, temp, 1); + } +%} int_typemap(unsigned long long); %typemap(argout,fragment="t_output_helper") unsigned long long *OUTPUT { @@ -144,9 +153,7 @@ int_typemap(unsigned long long); } %typemap(in) TYPE *REFERENCE (unsigned long long lvalue) %{ - // FIXME won't work for values which don't fit in a long... - convert_to_long_ex($input); - lvalue = (unsigned long long) (*$input)->value.lval; + CONVERT_UNSIGNED_LONG_LONG_IN(lvalue, unsigned long long, $input) $1 = &lvalue; %} %typemap(argout) unsigned long long *REFERENCE @@ -160,6 +167,17 @@ int_typemap(unsigned long long); ZVAL_STRING((*$arg), temp, 1); } %} +%typemap(argout) unsigned long long &OUTPUT +%{ + if (*arg$argnum <= (unsigned long long)LONG_MAX) { + ($result)->value.lval = (long)(*arg$argnum); + ($result)->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%llu", *arg$argnum); + ZVAL_STRING($result, temp, 1); + } +%} %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; @@ -181,11 +199,13 @@ int_typemap(unsigned long long); %typemap(in) short &INOUT = short *INPUT; %typemap(in) long &INOUT = long *INPUT; %typemap(in) long long &INOUT = long long *INPUT; +%typemap(in) long long &INPUT = long long *INPUT; %typemap(in) unsigned &INOUT = unsigned *INPUT; %typemap(in) unsigned short &INOUT = unsigned short *INPUT; %typemap(in) unsigned long &INOUT = unsigned long *INPUT; %typemap(in) unsigned char &INOUT = unsigned char *INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long *INPUT; +%typemap(in) unsigned long long &INPUT = unsigned long long *INPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT= double *OUTPUT; From d2773541679f8887df7faa6927b688414306d886 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 05:21:48 +0000 Subject: [PATCH 094/146] Add long long and unsigned long long const reference typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11767 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../test-suite/php/primitive_ref_runme.php | 6 +-- Lib/php/php.swg | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/php/primitive_ref_runme.php b/Examples/test-suite/php/primitive_ref_runme.php index 6a5a3f43d..ab23fb1cc 100644 --- a/Examples/test-suite/php/primitive_ref_runme.php +++ b/Examples/test-suite/php/primitive_ref_runme.php @@ -17,9 +17,9 @@ check::equal(ref_bool(true), true, "ref_bool failed"); check::equal(ref_float(3.5), 3.5, "ref_float failed"); check::equal(ref_double(3.5), 3.5, "ref_double failed"); check::equal(ref_char('x'), 'x', "ref_char failed"); -//check::equal(ref_longlong(0x123456789ABCDEF0), 0x123456789ABCDEF0, "ref_longlong failed"); -//check::equal(ref_ulonglong(0xF23456789ABCDEF0), 0xF23456789ABCDEF0, "ref_ulonglong failed"); -printf("TODO: long long and unsigned long long const reference typemaps\n"); +check::equal(ref_longlong(0x123456789ABCDEF0), 0x123456789ABCDEF0, "ref_longlong failed"); +# 0xF23456789ABCDEF0 won't fit in a long, so PHP makes it a double, but SWIG opts to return it as a string. +check::equal((double)ref_ulonglong(0xF23456789ABCDEF0), 0xF23456789ABCDEF0, "ref_ulonglong failed"); check::done(); ?> diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 8deb85254..704b6c616 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -198,6 +198,29 @@ ZVAL_LONG(return_value,$1); } +%typemap(out) long long +%{ + if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) { + return_value->value.lval = (long)($1); + return_value->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%lld", $1); + ZVAL_STRING(return_value, temp, 1); + } +%} +%typemap(out) unsigned long long +%{ + if ($1 <= (unsigned long long)LONG_MAX) { + return_value->value.lval = (long)($1); + return_value->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%llu", $1); + ZVAL_STRING(return_value, temp, 1); + } +%} + %typemap(out) const int &, const unsigned int &, const short &, @@ -213,6 +236,29 @@ ZVAL_LONG(return_value,*$1); } +%typemap(out) const long long & +%{ + if ((long long)LONG_MIN <= *$1 && *$1 <= (long long)LONG_MAX) { + return_value->value.lval = (long)(*$1); + return_value->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%lld", *$1); + ZVAL_STRING(return_value, temp, 1); + } +%} +%typemap(out) const unsigned long long & +%{ + if (*$1 <= (unsigned long long)LONG_MAX) { + return_value->value.lval = (long)(*$1); + return_value->type = IS_LONG; + } else { + char temp[256]; + sprintf(temp, "%llu", *$1); + ZVAL_STRING(return_value, temp, 1); + } +%} + %typemap(directorin) int, unsigned int, short, From 67bbac487280b65664255379a4988d1d5056672c Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 12:59:59 +0000 Subject: [PATCH 095/146] Add PHP typemaps for pointer to method. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11768 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 ++++-- Lib/php/const.i | 3 +++ Lib/php/globalvar.i | 29 ++++++++++++++++++++++++++++- Lib/php/php.swg | 17 +++++++++++++++++ Lib/php/phpinit.swg | 1 + Lib/php/phprun.swg | 9 +++++++++ 6 files changed, 62 insertions(+), 3 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 60b19cf3e..1c39df098 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -2,10 +2,12 @@ Version 1.3.41 (in progress) ============================ 2009-12-03: olly - [PHP] Add typemaps for long long and unsigned long long. + [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. + [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 diff --git a/Lib/php/const.i b/Lib/php/const.i index 6ddd403d0..d2d1c75bd 100644 --- a/Lib/php/const.i +++ b/Lib/php/const.i @@ -51,3 +51,6 @@ c.module_number = module_number; zend_register_constant( &c TSRMLS_CC ); } + +/* Handled as a global variable. */ +%typemap(consttab) SWIGTYPE (CLASS::*) ""; diff --git a/Lib/php/globalvar.i b/Lib/php/globalvar.i index df8cfade7..be20a96bc 100644 --- a/Lib/php/globalvar.i +++ b/Lib/php/globalvar.i @@ -105,6 +105,16 @@ zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void*)&z_var, sizeof(zval *), NULL); } +%typemap(varinit) SWIGTYPE (CLASS::*) +{ + void * p = emalloc(sizeof($1)); + memcpy(p, &$1, sizeof($1)); + zval * resource; + MAKE_STD_ZVAL(resource); + ZEND_REGISTER_RESOURCE(resource, p, le_member_ptr); + zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void*)&resource, sizeof(zval *), NULL); +} + %typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE { zval **z_var; @@ -216,6 +226,15 @@ $1 = ($1_ltype)_temp; } +%typemap(varin) SWIGTYPE (CLASS::*) +{ + zval **z_var; + + zend_hash_find(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void**)&z_var); + void * p = (void*)zend_fetch_resource(*z_var TSRMLS_CC, -1, SWIG_MEMBER_PTR, NULL, 1, le_member_ptr); + memcpy(&$1, p, sizeof($1)); +} + %typemap(varout) int, unsigned int, unsigned short, @@ -328,4 +347,12 @@ deliberate error cos this code looks bogus to me SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, 0); } - +%typemap(varout) SWIGTYPE (CLASS::*) +{ + void * p = emalloc(sizeof($1)); + memcpy(p, &$1, sizeof($1)); + zval * resource; + MAKE_STD_ZVAL(resource); + ZEND_REGISTER_RESOURCE(resource, p, le_member_ptr); + zend_hash_add(&EG(symbol_table), (char*)"$1", sizeof("$1"), (void*)&resource, sizeof(zval *), NULL); +} diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 704b6c616..77985e3c5 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -354,6 +354,23 @@ SWIG_SetPointerZval($input, (void *)&$1_name, $1_descriptor, $owner); %} +%typemap(out) SWIGTYPE (CLASS::*) +{ + void * p = emalloc(sizeof($1)); + memcpy(p, &$1, sizeof($1)); + zval * resource; + MAKE_STD_ZVAL(resource); + ZEND_REGISTER_RESOURCE(resource, p, le_member_ptr); + + SWIG_SetPointerZval(return_value, (void *)&$1, $1_descriptor, $owner); +} + +%typemap(in) SWIGTYPE (CLASS::*) +{ + void * p = (void*)zend_fetch_resource($input TSRMLS_CC, -1, SWIG_MEMBER_PTR, NULL, 1, le_member_ptr); + memcpy(&$1, p, sizeof($1)); +} + %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { diff --git a/Lib/php/phpinit.swg b/Lib/php/phpinit.swg index b7a0fc9d4..5d8278ba4 100644 --- a/Lib/php/phpinit.swg +++ b/Lib/php/phpinit.swg @@ -8,5 +8,6 @@ %init %{ SWIG_php_minit { SWIG_InitializeModule(0); + le_member_ptr = zend_register_list_destructors_ex(member_ptr_dtor, NULL, SWIG_MEMBER_PTR, module_number); %} diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index f48748914..d3fe9d8c1 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -261,3 +261,12 @@ static void SWIG_Php_SetModule(swig_module_info *pointer) { TSRMLS_FETCH(); REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, 0); } + +#define SWIG_MEMBER_PTR ((char*)"CLASS::*") + +static void member_ptr_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) { + efree(rsrc->ptr); +} + +static int le_member_ptr; + From 7ba280b4b8e5dbf16770f4ef801aa3e0262a510f Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 13:58:44 +0000 Subject: [PATCH 096/146] Fix warnings for passing string constant for char * (the PHP API isn't const correct). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11769 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/php/phprun.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index d3fe9d8c1..3aff867b4 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -36,7 +36,7 @@ extern "C" { #define SWIG_LONG_CONSTANT(N, V) zend_register_long_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) #define SWIG_DOUBLE_CONSTANT(N, V) zend_register_double_constant((char*)#N, sizeof(#N), V, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) -#define SWIG_STRING_CONSTANT(N, V) zend_register_stringl_constant((char*)#N, sizeof(#N), V, strlen(V), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) +#define SWIG_STRING_CONSTANT(N, V) zend_register_stringl_constant((char*)#N, sizeof(#N), (char*)(V), strlen(V), CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC) #define SWIG_CHAR_CONSTANT(N, V) do {\ static char swig_char = (V);\ zend_register_stringl_constant((char*)#N, sizeof(#N), &swig_char, 1, CONST_CS | CONST_PERSISTENT, module_number TSRMLS_CC);\ From 2c50482854b6e0ca27c28b567103ee045e916769 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 3 Dec 2009 14:12:42 +0000 Subject: [PATCH 097/146] Fix testcase to conform with actual expected behaviour. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11770 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/php/arrays_runme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/test-suite/php/arrays_runme.php b/Examples/test-suite/php/arrays_runme.php index 7419504d1..1a4fe993f 100644 --- a/Examples/test-suite/php/arrays_runme.php +++ b/Examples/test-suite/php/arrays_runme.php @@ -12,7 +12,7 @@ check::classname(simplestruct,$ss); $as=new arraystruct(); $as->array_c="abc"; -check::equal($as->array_c,"ab",'$as->array_c=="ab"'); +check::equal($as->array_c,"a",'$as->array_c=="a"'); check::done(); ?> From 8461ba43ffb3b0bd7d6aa2a6cab68ce6b1cff5aa Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 4 Dec 2009 03:54:24 +0000 Subject: [PATCH 098/146] Update lists of expected function, classes, and globals to match what we get with PHP5. There are no longer any warnings about these. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11771 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/php/arrays_global_runme.php | 2 +- Examples/test-suite/php/arrays_global_twodim_runme.php | 2 +- Examples/test-suite/php/arrays_runme.php | 3 +-- Examples/test-suite/php/arrays_scope_runme.php | 8 ++++---- Examples/test-suite/php/cpp_static_runme.php | 10 +++++----- Examples/test-suite/php/enum_scope_template_runme.php | 2 +- Examples/test-suite/php/ignore_parameter_runme.php | 10 +++++----- Examples/test-suite/php/li_carrays_runme.php | 6 +++--- 8 files changed, 21 insertions(+), 22 deletions(-) diff --git a/Examples/test-suite/php/arrays_global_runme.php b/Examples/test-suite/php/arrays_global_runme.php index 7748786a1..12a7806c9 100644 --- a/Examples/test-suite/php/arrays_global_runme.php +++ b/Examples/test-suite/php/arrays_global_runme.php @@ -5,7 +5,7 @@ require "arrays_global.php"; check::functions(array(test_a,test_b,new_simplestruct,new_material)); check::classes(array(arrays_global,SimpleStruct,Material)); -check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,beginstring_fix44a,beginstring_fix44b,beginstring_fix44c,beginstring_fix44d,beginstring_fix44e,beginstring_fix44f,chitmat,hitmat_val,hitmat)); +check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,beginstring_fix44a,beginstring_fix44b,beginstring_fix44c,beginstring_fix44d,beginstring_fix44e,beginstring_fix44f,chitmat,hitmat_val,hitmat,simplestruct_double_field)); // The size of array_c is 2, but the last byte is \0, so we can only store a // single byte string in it. check::set(array_c,"Z"); diff --git a/Examples/test-suite/php/arrays_global_twodim_runme.php b/Examples/test-suite/php/arrays_global_twodim_runme.php index 9f16a6cf6..40ecf1719 100644 --- a/Examples/test-suite/php/arrays_global_twodim_runme.php +++ b/Examples/test-suite/php/arrays_global_twodim_runme.php @@ -5,7 +5,7 @@ require "arrays_global_twodim.php"; check::functions(array(fn_taking_arrays,get_2d_array,new_simplestruct,new_material)); check::classes(array(arrays_global_twodim,SimpleStruct,Material)); -check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,chitmat,hitmat_val,hitmat)); +check::globals(array(array_c,array_sc,array_uc,array_s,array_us,array_i,array_ui,array_l,array_ul,array_ll,array_f,array_d,array_struct,array_structpointers,array_ipointers,array_enum,array_enumpointers,array_const_i,chitmat,hitmat_val,hitmat,simplestruct_double_field)); $a1=array(10,11,12,13); $a2=array(14,15,16,17); $a=array($a1,$a2); diff --git a/Examples/test-suite/php/arrays_runme.php b/Examples/test-suite/php/arrays_runme.php index 1a4fe993f..23490e61e 100644 --- a/Examples/test-suite/php/arrays_runme.php +++ b/Examples/test-suite/php/arrays_runme.php @@ -4,8 +4,7 @@ require "arrays.php"; check::functions(array(fn_taking_arrays,newintpointer,setintfrompointer,getintfrompointer,array_pointer_func)); check::classes(array(arrays,SimpleStruct,ArrayStruct,CartPoseData_t)); -// No new vars -check::globals(array()); +check::globals(array(simplestruct_double_field,arraystruct_array_c,arraystruct_array_sc,arraystruct_array_uc,arraystruct_array_s,arraystruct_array_us,arraystruct_array_i,arraystruct_array_ui,arraystruct_array_l,arraystruct_array_ul,arraystruct_array_ll,arraystruct_array_f,arraystruct_array_d,arraystruct_array_struct,arraystruct_array_structpointers,arraystruct_array_ipointers,arraystruct_array_enum,arraystruct_array_enumpointers,arraystruct_array_const_i,cartposedata_t_p)); $ss=new simplestruct(); check::classname(simplestruct,$ss); diff --git a/Examples/test-suite/php/arrays_scope_runme.php b/Examples/test-suite/php/arrays_scope_runme.php index 6d3eba76d..c208b7518 100644 --- a/Examples/test-suite/php/arrays_scope_runme.php +++ b/Examples/test-suite/php/arrays_scope_runme.php @@ -3,12 +3,12 @@ require "tests.php"; require "arrays_scope.php"; -// No new functions +// New functions check::functions(array(new_bar,bar_blah)); -// No new classes +// New classes check::classes(array(arrays_scope,Bar)); -// now new vars -check::globals(array()); +// New vars +check::globals(array(bar_adata,bar_bdata,bar_cdata)); $bar=new bar(); diff --git a/Examples/test-suite/php/cpp_static_runme.php b/Examples/test-suite/php/cpp_static_runme.php index 9292a63cf..e1cc3e733 100644 --- a/Examples/test-suite/php/cpp_static_runme.php +++ b/Examples/test-suite/php/cpp_static_runme.php @@ -3,12 +3,12 @@ require "tests.php"; require "cpp_static.php"; -// No new functions -check::functions(array()); -// No new classes +// New functions +check::functions(array(staticfunctiontest_static_func,staticfunctiontest_static_func_2,staticfunctiontest_static_func_3)); +// New classes check::classes(array(StaticMemberTest,StaticFunctionTest)); -// now new vars -check::globals(array()); +// New vars +check::globals(array(staticmembertest_static_int)); check::done(); ?> diff --git a/Examples/test-suite/php/enum_scope_template_runme.php b/Examples/test-suite/php/enum_scope_template_runme.php index e152efca6..85ba467b7 100644 --- a/Examples/test-suite/php/enum_scope_template_runme.php +++ b/Examples/test-suite/php/enum_scope_template_runme.php @@ -3,7 +3,7 @@ require "tests.php"; require "enum_scope_template.php"; check::classes(array("enum_scope_template", "TreeInt")); -check::functions("chops"); +check::functions(array("chops","treeint_chops")); check::equal(0,TreeInt_Oak,"0==TreeInt_Oak"); check::equal(1,TreeInt_Fir,"1==TreeInt_Fir"); check::equal(2,TreeInt_Cedar,"2==TreeInt_Cedar"); diff --git a/Examples/test-suite/php/ignore_parameter_runme.php b/Examples/test-suite/php/ignore_parameter_runme.php index d455c39a1..1c8c76ad4 100644 --- a/Examples/test-suite/php/ignore_parameter_runme.php +++ b/Examples/test-suite/php/ignore_parameter_runme.php @@ -3,11 +3,11 @@ require "tests.php"; require "ignore_parameter.php"; -// No new functions -check::functions(array(jaguar,lotus,tvr,ferrari)); -// No new classes -check::classes(array(sportscars,minicooper,morrisminor,fordanglia,austinallegro)); -// now new vars +// New functions +check::functions(array(jaguar,lotus,tvr,ferrari,sportscars_daimler,sportscars_astonmartin,sportscars_bugatti,sportscars_lamborghini)); +// New classes +check::classes(array(ignore_parameter,SportsCars,MiniCooper,MorrisMinor,FordAnglia,AustinAllegro)); +// No new vars check::globals(array()); check::equal(jaguar(2,3.4),"hello",'jaguar(2,3.4)=="hello"'); diff --git a/Examples/test-suite/php/li_carrays_runme.php b/Examples/test-suite/php/li_carrays_runme.php index b6d47e926..fbe5cc793 100644 --- a/Examples/test-suite/php/li_carrays_runme.php +++ b/Examples/test-suite/php/li_carrays_runme.php @@ -3,14 +3,14 @@ require "tests.php"; require "li_carrays.php"; // Check functions. -check::functions(array(new_intarray,delete_intarray,intarray_getitem,intarray_setitem)); +check::functions(array(new_intarray,delete_intarray,intarray_getitem,intarray_setitem,doublearray_getitem,doublearray_setitem,doublearray_cast,doublearray_frompointer,xyarray_getitem,xyarray_setitem,xyarray_cast,xyarray_frompointer,delete_abarray,abarray_getitem,abarray_setitem)); // Check classes. // NB An "li_carrays" class is created as a mock namespace. check::classes(array(li_carrays,doubleArray,AB,XY,XYArray)); -// No new global variables. -check::globals(array()); +// Check global variables. +check::globals(array(xy_x,xy_y,globalxyarray,ab_a,ab_b,globalabarray)); $d = new doubleArray(10); From 0633acd24f607a57d2dce65c9a5596df36ad9308 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 4 Dec 2009 04:33:58 +0000 Subject: [PATCH 099/146] [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 *** git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11772 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 6 ++++++ Lib/php/std_map.i | 20 ++++++++++++-------- Lib/std/_std_deque.i | 25 +++++++++++++++++-------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 1c39df098..26c135d9a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Lib/php/std_map.i b/Lib/php/std_map.i index c6721806b..2c9e1fd9a 100644 --- a/Lib/php/std_map.i +++ b/Lib/php/std_map.i @@ -30,8 +30,6 @@ namespace std { map(const map &); unsigned int size() const; - %rename(is_empty) empty; - bool empty() const; void clear(); %extend { T& get(const K& key) throw (std::out_of_range) { @@ -55,6 +53,9 @@ namespace std { std::map::iterator i = self->find(key); return i != self->end(); } + bool is_empty() const { + return self->empty(); + } } }; @@ -70,8 +71,6 @@ namespace std { map(const map &); unsigned int size() const; - %rename(is_empty) empty; - bool empty() const; void clear(); %extend { T& get(K key) throw (std::out_of_range) { @@ -95,6 +94,9 @@ namespace std { std::map::iterator i = self->find(key); return i != self->end(); } + bool is_empty() const { + return self->empty(); + } } }; %enddef @@ -107,8 +109,6 @@ namespace std { map(const map &); unsigned int size() const; - %rename(is_empty) empty; - bool empty() const; void clear(); %extend { T get(const K& key) throw (std::out_of_range) { @@ -132,6 +132,9 @@ namespace std { std::map::iterator i = self->find(key); return i != self->end(); } + bool is_empty() const { + return self->empty(); + } } }; %enddef @@ -145,8 +148,6 @@ namespace std { map(const map &); unsigned int size() const; - %rename(is_empty) empty; - bool empty() const; void clear(); %extend { T get(K key) throw (std::out_of_range) { @@ -170,6 +171,9 @@ namespace std { std::map::iterator i = self->find(key); return i != self->end(); } + bool is_empty() const { + return self->empty(); + } } }; %enddef diff --git a/Lib/std/_std_deque.i b/Lib/std/_std_deque.i index 026f373d6..9b2908cec 100644 --- a/Lib/std/_std_deque.i +++ b/Lib/std/_std_deque.i @@ -27,7 +27,7 @@ }; */ -%define %std_deque_methods(T) +%define %std_deque_methods_noempty(T) typedef T &reference; typedef const T& const_reference; @@ -41,7 +41,6 @@ unsigned int size() const; unsigned int max_size() const; void resize(unsigned int n, T c = T()); - bool empty() const; const_reference front(); const_reference back(); void push_front(const T& x); @@ -69,7 +68,7 @@ throw std::out_of_range("deque index out of range"); } void delitem(int i) throw (std::out_of_range) { - int size = int(self->size()); + int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); @@ -77,7 +76,7 @@ throw std::out_of_range("deque index out of range"); } } - std::deque getslice(int i, int j) { + std::deque getslice(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; @@ -112,15 +111,25 @@ self->erase(self->begin()+i,self->begin()+j); } }; - %enddef +#ifdef SWIGPHP +%define %std_deque_methods(T) + %extend { + bool is_empty() const { + return self->empty(); + } + }; +%enddef +#else +%define %std_deque_methods(T) + bool empty() const; +%enddef +#endif + namespace std { template class deque { public: %std_deque_methods(T); }; } - - - From bcda9644f1acd46cdabde5c1cb6ab8654a895a16 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 4 Dec 2009 04:56:10 +0000 Subject: [PATCH 100/146] Remove two commented out lines of code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11773 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index cbad1ee84..b427f9c64 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1929,9 +1929,7 @@ done: virtual int classHandler(Node *n) { constructors = 0; - //SwigType *t = Getattr(n, "classtype"); current_class = n; - // String *use_class_name=SwigType_manglestr(SwigType_ltype(t)); if (shadow) { char *rename = GetChar(n, "sym:name"); From 02eb6a81d1836cc7d39c171cb9074fbd98c01828 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 4 Dec 2009 05:46:31 +0000 Subject: [PATCH 101/146] Fix handling of modulo operator (%) in constant expressions (SF#2818562). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11774 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Examples/test-suite/common.mk | 1 + Examples/test-suite/constant_expr.i | 11 +++++++++++ Source/CParse/parser.y | 6 +++--- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 Examples/test-suite/constant_expr.i diff --git a/CHANGES.current b/CHANGES.current index 26c135d9a..cc1004148 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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 diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index bb72e4988..203ea3e72 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -441,6 +441,7 @@ C_TEST_CASES += \ arrays \ char_constant \ const_const \ + constant_expr \ empty \ enums \ extern_declaration \ diff --git a/Examples/test-suite/constant_expr.i b/Examples/test-suite/constant_expr.i new file mode 100644 index 000000000..47db2d026 --- /dev/null +++ b/Examples/test-suite/constant_expr.i @@ -0,0 +1,11 @@ +%module constant_expr; +/* Tests of constant expressions. */ + +%inline %{ + +/* % didn't work in SWIG 1.3.40 and earlier. */ +const int X = 123%7; +#define FOO 12 % 6 +double d_array[12 % 6]; + +%} diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 46485593f..0da5c3122 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -1647,7 +1647,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %token NATIVE INLINE %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT %token WARN -%token LESSTHAN GREATERTHAN MODULO DELETE_KW +%token LESSTHAN GREATERTHAN DELETE_KW %token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO %token QUESTIONMARK %token TYPES PARMS @@ -1668,7 +1668,7 @@ static void tag_nodes(Node *n, const_String_or_char_ptr attrname, DOH *value) { %left GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO %left LSHIFT RSHIFT %left PLUS MINUS -%left STAR SLASH MODULUS +%left STAR SLASH MODULO %left UMINUS NOT LNOT %left DCOLON @@ -5745,7 +5745,7 @@ exprcompound : expr PLUS expr { $$.val = NewStringf("%s/%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } - | expr MODULUS expr { + | expr MODULO expr { $$.val = NewStringf("%s%%%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } From ab06b22bab63dbb1828934faa0c7fd9a444086c7 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 4 Dec 2009 08:52:12 +0000 Subject: [PATCH 102/146] [Ruby] Improve support for Ruby 1.9 under GCC. Addresses part of SF#2859614. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11775 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Lib/ruby/rubyhead.swg | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index cc1004148..038485a13 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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). diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg index 4b425dfd8..9960087c6 100644 --- a/Lib/ruby/rubyhead.swg +++ b/Lib/ruby/rubyhead.swg @@ -1,5 +1,14 @@ #include +/* Ruby 1.9.1 has a "memoisation optimisation" when compiling with GCC which + * breaks using rb_intern as an lvalue, as SWIG does. We work around this + * issue for now by disabling this. + * https://sourceforge.net/tracker/?func=detail&aid=2859614&group_id=1645&atid=101645 + */ +#ifdef rb_intern +# undef rb_intern +#endif + /* Remove global macros defined in Ruby's win32.h */ #ifdef write # undef write From bfb09161f744bab4172b20c7f323909ed6b1abd3 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 10 Dec 2009 11:52:29 +0000 Subject: [PATCH 103/146] Eliminate "int error;" declaration from generated PHP director support code if it isn't used. No change in behaviour, and the compiler will just optimise away the unused variable, but it can cause an "unused variable" warning. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11776 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/php.cxx | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index b427f9c64..ca9d4e742 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2536,7 +2536,24 @@ done: } p = nextSibling(p); } - Append(w->code, "int error;\n"); + + /* exception handling */ + tm = Swig_typemap_lookup("director:except", n, "result", 0); + if (!tm) { + tm = Getattr(n, "feature:director:except"); + if (tm) + tm = Copy(tm); + } + if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { + if (Replaceall(tm, "$error", "error")) { + /* Only declare error if it is used by the typemap. */ + Append(w->code, "int error;\n"); + } + } else { + Delete(tm); + tm = NULL; + } + if (!idx) { Printf(w->code, "zval **args = NULL;\n", idx); } else { @@ -2555,18 +2572,10 @@ done: Append(w->code, "call_user_function(EG(function_table), (zval**)&swig_self, &funcname,\n"); Printf(w->code, " result, %d, args TSRMLS_CC);\n", idx); - /* exception handling */ - tm = Swig_typemap_lookup("director:except", n, "result", 0); - if (!tm) { - tm = Getattr(n, "feature:director:except"); - if (tm) - tm = Copy(tm); - } - if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { - Replaceall(tm, "$error", "error"); + if (tm) { Printv(w->code, Str(tm), "\n", NIL); + Delete(tm); } - Delete(tm); /* marshal return value from PHP to C/C++ type */ From f65ad1caca6b7acbb7fde20e76f1f3242d536d31 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 10 Dec 2009 12:03:26 +0000 Subject: [PATCH 104/146] "make distclean" is supposed to return the source tree to a bootstrapped state so don't remove "configure" as that breaks "make distclean;./configure". Add new "maintainer-clean" target and remove configure in that instead. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11777 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CCache/Makefile.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CCache/Makefile.in b/CCache/Makefile.in index f885e72ae..ef20f48a0 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -63,8 +63,11 @@ test: test.sh check: test distclean: clean distclean-docs - /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status configure config.h.in ccache_swig_config.h + /bin/rm -f Makefile config.h config.sub config.log build-stamp config.status config.h.in ccache_swig_config.h +maintainer-clean: distclean + /bin/rm -f configure + # FIXME: To fix this, test.sh needs to be able to take ccache from the # installed prefix, not from the source dir. installcheck: From 7bcc0699829bf4b7357f5e5930677ddace4dbd63 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Dec 2009 22:34:02 +0000 Subject: [PATCH 105/146] Suppress incorrect 'unused value' bison warning git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11778 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/parser.y | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index 0da5c3122..b9db52104 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -3495,6 +3495,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { inclass = 1; } } cpp_members RBRACE cpp_opt_declarators { + (void) $6; if (nested_template == 0) { Node *p; SwigType *ty; @@ -3656,6 +3657,7 @@ cpp_class_decl : storage_class cpptype idcolon inherit LBRACE { } cpp_members RBRACE declarator initializer c_decl_tail { String *unnamed; Node *n; + (void) $4; Classprefix = 0; $$ = class_decl[--class_level]; inclass = 0; From f3828ee02828c79df788a3758103295cbe79c8bc Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Dec 2009 22:58:55 +0000 Subject: [PATCH 106/146] nested class warning suppression git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11779 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/union_scope.i | 1 + 1 file changed, 1 insertion(+) diff --git a/Examples/test-suite/union_scope.i b/Examples/test-suite/union_scope.i index a41b30406..f66a0543a 100644 --- a/Examples/test-suite/union_scope.i +++ b/Examples/test-suite/union_scope.i @@ -3,6 +3,7 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) nRState::rstate; +#pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS %inline %{ class nRState { From 9354467b872e56b22f3156ceaa886f59795bf9fc Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 12 Dec 2009 21:11:45 +0000 Subject: [PATCH 107/146] remove Octave -api option and use new OCTAVE_API_VERSION_NUMBER instead git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11780 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Lib/octave/octrun.swg | 34 +++++++++++++--------------------- Lib/octave/octruntime.swg | 6 +++--- Source/Modules/octave.cxx | 15 +-------------- 4 files changed, 21 insertions(+), 38 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 038485a13..1ff98e258 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg index a2bf52070..be2dc9653 100644 --- a/Lib/octave/octrun.swg +++ b/Lib/octave/octrun.swg @@ -1,24 +1,16 @@ -#if OCTAVE_API_VERSION_OPTION>0 -#define USE_OCTAVE_API_VERSION OCTAVE_API_VERSION_OPTION -#else - #include -#ifdef OCTAVE_API_VERSION_N -#define USE_OCTAVE_API_VERSION OCTAVE_API_VERSION_N +#ifndef OCTAVE_API_VERSION_NUMBER -#else // Interim hack to distinguish between Octave 3.2 and earlier versions. - -#define ComplexLU __ignore -#include -#undef ComplexLU -#ifdef octave_Complex_LU_h -#define USE_OCTAVE_API_VERSION 36 -#else -#define USE_OCTAVE_API_VERSION 37 -#endif - -#endif + // Hack to distinguish between Octave 3.2 and earlier versions before OCTAVE_API_VERSION_NUMBER existed + #define ComplexLU __ignore + #include + #undef ComplexLU + #ifdef octave_Complex_LU_h + # define OCTAVE_API_VERSION_NUMBER 36 + #else + # define OCTAVE_API_VERSION_NUMBER 37 + #endif #endif @@ -469,7 +461,7 @@ namespace Swig { install_builtin_function(it->second.first->method, it->first, it->second.first->doc?it->second.first->doc:std::string()); else if (it->second.second.is_defined()) { -#if USE_OCTAVE_API_VERSION<37 +#if OCTAVE_API_VERSION_NUMBER<37 link_to_global_variable(curr_sym_tab->lookup(it->first, true)); #else symbol_table::varref(it->first); @@ -477,7 +469,7 @@ namespace Swig { #endif set_global_value(it->first, it->second.second); -#if USE_OCTAVE_API_VERSION<37 +#if OCTAVE_API_VERSION_NUMBER<37 octave_swig_type *ost = Swig::swig_value_deref(it->second.second); if (ost) { const char* h = ost->help_text(); @@ -1389,7 +1381,7 @@ SWIGRUNTIME swig_module_info *SWIG_Octave_GetModule(void *clientdata) { SWIGRUNTIME void SWIG_Octave_SetModule(void *clientdata, swig_module_info *pointer) { octave_value ov = new octave_swig_packed(0, &pointer, sizeof(swig_module_info *)); const char *module_var = "__SWIG_MODULE__" SWIG_TYPE_TABLE_NAME SWIG_RUNTIME_VERSION; -#if USE_OCTAVE_API_VERSION<37 +#if OCTAVE_API_VERSION_NUMBER<37 link_to_global_variable(curr_sym_tab->lookup(module_var, true)); #else symbol_table::varref(module_var); diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg index 0ab7bd70b..e19b781c2 100644 --- a/Lib/octave/octruntime.swg +++ b/Lib/octave/octruntime.swg @@ -72,7 +72,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { module_ns->install_global(); module_ns->decref(); -#if USE_OCTAVE_API_VERSION<37 +#if OCTAVE_API_VERSION_NUMBER<37 link_to_global_variable(curr_sym_tab->lookup(SWIG_name_d,true)); #else symbol_table::varref(SWIG_name_d); @@ -80,7 +80,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { #endif set_global_value(SWIG_name_d,Swig::swig_value_ref(module_ns)); -#if USE_OCTAVE_API_VERSION>=37 +#if OCTAVE_API_VERSION_NUMBER>=37 mlock(); #endif @@ -89,7 +89,7 @@ DEFUN_DLD (SWIG_name,args,nargout,SWIG_name_d) { // workaround bug in octave where installing global variable of custom type and then // exiting without explicitly clearing the variable causes octave to segfault. -#if USE_OCTAVE_API_VERSION>=37 +#if OCTAVE_API_VERSION_NUMBER>=37 struct oct_file_unload { ~oct_file_unload() { string_vector vars = symbol_table::global_variable_names(); diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index aeb72f77a..1804334d6 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -13,7 +13,7 @@ char cvsroot_octave_cxx[] = "$Id$"; static const char *usage = (char *) "\ Octave Options (available with -octave)\n\ - -api - Generate code that assumes Octave API N [default: 37]\n\ + [no additional options]\n\ \n"; @@ -36,8 +36,6 @@ private: int have_destructor; String *constructor_name; - int api_version; - Hash *docs; public: @@ -56,7 +54,6 @@ public: director_multiple_inheritance = 1; director_language = 1; docs = NewHash(); - api_version = 0; } virtual void main(int argc, char *argv[]) { @@ -64,15 +61,6 @@ public: if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { fputs(usage, stderr); - } else if (strcmp(argv[i], "-api") == 0) { - if (argv[i + 1]) { - api_version = atoi(argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } } } } @@ -138,7 +126,6 @@ public: Printf(f_runtime, "#define SWIGOCTAVE\n"); Printf(f_runtime, "#define SWIG_name_d \"%s\"\n", module); Printf(f_runtime, "#define SWIG_name %s\n", module); - Printf(f_runtime, "#define OCTAVE_API_VERSION_OPTION %i\n", api_version); if (directorsEnabled()) { Printf(f_runtime, "#define SWIG_DIRECTORS\n"); From f309dc92626364563af78de648a90412c6619fae Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 12 Dec 2009 22:27:22 +0000 Subject: [PATCH 108/146] gcc-4.4 warning fix for ruby git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11781 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/ruby/rubyrun.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg index 24d861d5a..177e395d0 100644 --- a/Lib/ruby/rubyrun.swg +++ b/Lib/ruby/rubyrun.swg @@ -45,7 +45,7 @@ /* Error manipulation */ #define SWIG_ErrorType(code) SWIG_Ruby_ErrorType(code) -#define SWIG_Error(code, msg) rb_raise(SWIG_Ruby_ErrorType(code), msg) +#define SWIG_Error(code, msg) rb_raise(SWIG_Ruby_ErrorType(code), "%s", msg) #define SWIG_fail goto fail From 008ef5df5ab9885a06cb06c1a3a638e03045cc4a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 14 Dec 2009 20:44:51 +0000 Subject: [PATCH 109/146] Minor fix for warning suppression git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11782 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/union_scope.i | 1 - 1 file changed, 1 deletion(-) diff --git a/Examples/test-suite/union_scope.i b/Examples/test-suite/union_scope.i index f66a0543a..b7307cb29 100644 --- a/Examples/test-suite/union_scope.i +++ b/Examples/test-suite/union_scope.i @@ -2,7 +2,6 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState; // Ruby, wrong class name %warnfilter(SWIGWARN_RUBY_WRONG_NAME) nRState_rstate; // Ruby, wrong class name -%warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) nRState::rstate; #pragma SWIG nowarn=SWIGWARN_PARSE_UNNAMED_NESTED_CLASS %inline %{ From fb4ad0b18de593f6b12546da3c98b7d16ceac287 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 15 Dec 2009 07:04:32 +0000 Subject: [PATCH 110/146] Add back in all the deque methods git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11783 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/std/_std_deque.i | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Lib/std/_std_deque.i b/Lib/std/_std_deque.i index 9b2908cec..3d68c385f 100644 --- a/Lib/std/_std_deque.i +++ b/Lib/std/_std_deque.i @@ -115,15 +115,17 @@ #ifdef SWIGPHP %define %std_deque_methods(T) - %extend { - bool is_empty() const { - return self->empty(); - } - }; + %extend { + bool is_empty() const { + return self->empty(); + } + }; + %std_deque_methods_noempty(T) %enddef #else %define %std_deque_methods(T) - bool empty() const; + bool empty() const; + %std_deque_methods_noempty(T) %enddef #endif From b86939aae57c47ac8233a5639858fd362c933044 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 15 Dec 2009 07:08:53 +0000 Subject: [PATCH 111/146] Remove redundant code which is no longer being used since the template specialization improvements were added git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11784 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/templ.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 1f1620094..d78c12b1a 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -494,7 +494,7 @@ static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { Node *n = 0; - String *tname = 0, *rname = 0; + String *tname = 0; Node *templ; Symtab *primary_scope = 0; List *possiblepartials = 0; @@ -591,34 +591,6 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { * only (1) is really supported for partial specializations */ - /* Generate reduced template name (stripped of extraneous pointers, etc.) */ - rname = NewStringf("%s<(", name); - p = parms; - while (p) { - String *t; - t = Getattr(p, "type"); - if (!t) - t = Getattr(p, "value"); - if (t) { - String *tyr = Swig_symbol_typedef_reduce(t, tscope); - String *ty = SwigType_strip_qualifiers(tyr); - String *tb = SwigType_base(ty); - String *td = SwigType_default(ty); - Replaceid(td, "enum SWIGTYPE", tb); - Replaceid(td, "SWIGTYPE", tb); - Append(rname, td); - Delete(tb); - Delete(td); - Delete(ty); - Delete(tyr); - } - p = nextSibling(p); - if (p) { - Append(rname, ","); - } - } - Append(rname, ")>"); - /* Rank each template parameter against the desired template parameters then build a matrix of best matches */ possiblepartials = NewList(); { @@ -819,7 +791,6 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { } success: Delete(tname); - Delete(rname); Delete(possiblepartials); if ((template_debug) && (n)) { /* From 3a0e056d638625780612d6b81dadd84362e876c6 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 15 Dec 2009 14:29:03 +0000 Subject: [PATCH 112/146] Fix typo in literal string. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11785 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/php/cpointer/runme.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/php/cpointer/runme.php b/Examples/php/cpointer/runme.php index f5ef08a3c..48f0ad631 100644 --- a/Examples/php/cpointer/runme.php +++ b/Examples/php/cpointer/runme.php @@ -22,7 +22,7 @@ # Now get the result $r = intp_value($c); - print " 38 + 42 = $r\n"; + print " 37 + 42 = $r\n"; # Clean up the pointers delete_intp($a); From d1eed0bc8ef9462e66418751284efa02e7c45235 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 15 Dec 2009 14:33:47 +0000 Subject: [PATCH 113/146] Don't use -Wno-long-double on OS X - it seems to no longer be supported by Apple's compilers, and was never supported by FSF GCC on any platform. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11786 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- configure.in | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/configure.in b/configure.in index 96c3d18b0..f457d73e3 100644 --- a/configure.in +++ b/configure.in @@ -316,11 +316,7 @@ esac # Optional CFLAGS used to silence compiler warnings on some platforms. AC_SUBST(PLATFLAGS) -case $host in - *-*-darwin*) PLATFLAGS="-Wno-long-double";; - *) PLATFLAGS="";; -esac - +PLATFLAGS= # Check for specific libraries. Used for SWIG examples AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV From 28983db50f045a12a4c192ce61d429112d60bda1 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 17 Dec 2009 19:34:53 +0000 Subject: [PATCH 114/146] variable name corrections for consistency to use typemap method instead of op git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11787 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/typemap.c | 65 ++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 9fcbb38e0..b2c9ef3b2 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -223,7 +223,7 @@ void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms /* For a multi-argument typemap, the typemap code and information is really only stored in the last argument. However, to make this work, we perform a really neat trick using - the typemap operator name. + the typemap method name. For example, consider this typemap @@ -233,26 +233,26 @@ void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms To store it, we look at typemaps for the following: - operator type-name + typemap method type-name ---------------------------------------------- "in" int foo "in-int+foo:" int *bar "in-int+foo:-p.int+bar: char *blah[] - Notice how the operator expands to encode information about + Notice how the typemap method name expands to encode information about previous arguments. */ np = nextSibling(parms); if (np) { - /* Make an entirely new operator key */ - String *newop = NewStringf("%s-%s+%s:", tmap_method, type, pname); + /* Make an entirely new typemap method key */ + String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname); /* Now reregister on the remaining arguments */ - Swig_typemap_register(newop, np, code, locals, kwargs); + Swig_typemap_register(multi_tmap_method, np, code, locals, kwargs); - /* Setattr(tm2,newop,newop); */ - Delete(newop); + /* Setattr(tm2,multi_tmap_method,multi_tmap_method); */ + Delete(multi_tmap_method); } else { String *str = SwigType_str(type, pname); String *typemap = NewStringf("typemap(%s) %s", tmap_method, str); @@ -311,7 +311,7 @@ int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, String *pname; SwigType *ptype; int ts = tm_scope; - String *tm_methods, *newop; + String *tm_methods, *multi_tmap_method; if (ParmList_len(parms) != ParmList_len(srcparms)) return -1; @@ -333,9 +333,9 @@ int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, break; /* Got a match. Look for next typemap */ - newop = NewStringf("%s-%s+%s:", tm_methods, ptype, pname); + multi_tmap_method = NewStringf("%s-%s+%s:", tm_methods, ptype, pname); Delete(tm_methods); - tm_methods = newop; + tm_methods = multi_tmap_method; p = nextSibling(p); } Delete(tm_methods); @@ -363,11 +363,11 @@ void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) { SwigType *type; String *name; Parm *p; - String *newop; + String *multi_tmap_method; Hash *tm = 0; /* This might not work */ - newop = NewString(tmap_method); + multi_tmap_method = NewString(tmap_method); p = parms; while (p) { type = Getattr(p, "type"); @@ -377,17 +377,17 @@ void Swig_typemap_clear(const_String_or_char_ptr tmap_method, ParmList *parms) { return; p = nextSibling(p); if (p) - Printf(newop, "-%s+%s:", type, name); + Printf(multi_tmap_method, "-%s+%s:", type, name); } if (tm) { - tm = Getattr(tm, typemap_method_name(newop)); + tm = Getattr(tm, typemap_method_name(multi_tmap_method)); if (tm) { Delattr(tm, "code"); Delattr(tm, "locals"); Delattr(tm, "kwargs"); } } - Delete(newop); + Delete(multi_tmap_method); } /* ----------------------------------------------------------------------------- @@ -752,8 +752,9 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList SwigType *type; SwigType *mtype = 0; String *name; - String *newop; - Hash *tm, *tm1; + String *multi_tmap_method; + Hash *tm; + Hash *tm1 = 0; if (!parms) { *nmatch = 0; @@ -769,8 +770,8 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList Setattr(parms, "tmap:match", mtype); } Delete(mtype); - newop = NewStringf("%s-%s+%s:", tmap_method, type, name); - tm1 = typemap_search_multi(newop, nextSibling(parms), nmatch); + multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, name); + tm1 = typemap_search_multi(multi_tmap_method, nextSibling(parms), nmatch); if (tm1) tm = tm1; if (Getattr(tm, "code")) { @@ -778,7 +779,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList } else { tm = 0; } - Delete(newop); + Delete(multi_tmap_method); } return tm; } @@ -1204,7 +1205,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No String *symname; String *cname = 0; String *clname = 0; - char *cop = Char(tmap_method); + char *cmethod = Char(tmap_method); int optimal_attribute = 0; int optimal_substitution = 0; int num_substitutions = 0; @@ -1269,7 +1270,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No Append(value, mangle); Delete(mangle); } - sprintf(temp, "%s:%s", cop, ckwname); + sprintf(temp, "%s:%s", cmethod, ckwname); Setattr(node, typemap_method_name(temp), value); if (Cmp(temp, "out:optimal") == 0) optimal_attribute = (Cmp(value, "0") != 0) ? 1 : 0; @@ -1361,20 +1362,20 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No Setattr(node, typemap_method_name(tmap_method), s); if (locals) { - sprintf(temp, "%s:locals", cop); + sprintf(temp, "%s:locals", cmethod); Setattr(node, typemap_method_name(temp), locals); Delete(locals); } if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cop); + sprintf(temp, "%s:SWIGTYPE", cmethod); Setattr(node, typemap_method_name(temp), "1"); } /* Look for warnings */ { String *w; - sprintf(temp, "%s:warning", cop); + sprintf(temp, "%s:warning", cmethod); w = Getattr(node, typemap_method_name(temp)); if (w) { Swig_warning(0, Getfile(node), Getline(node), "%s\n", w); @@ -1384,7 +1385,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No /* Look for code fragments */ { String *fragment; - sprintf(temp, "%s:fragment", cop); + sprintf(temp, "%s:fragment", cmethod); fragment = Getattr(node, typemap_method_name(temp)); if (fragment) { String *fname = Copy(fragment); @@ -1520,7 +1521,7 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p ParmList *locals; int argnum = 0; char temp[256]; - char *cop = Char(tmap_method); + char *cmethod = Char(tmap_method); String *kwmatch = 0; p = parms; @@ -1639,7 +1640,7 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p } if (Checkattr(tm, "type", "SWIGTYPE")) { - sprintf(temp, "%s:SWIGTYPE", cop); + sprintf(temp, "%s:SWIGTYPE", cmethod); Setattr(p, typemap_method_name(temp), "1"); } p = nextSibling(p); @@ -1662,13 +1663,13 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p Setattr(firstp, typemap_method_name(tmap_method), s); /* Code object */ if (locals) { - sprintf(temp, "%s:locals", cop); + sprintf(temp, "%s:locals", cmethod); Setattr(firstp, typemap_method_name(temp), locals); Delete(locals); } /* Attach a link to the next parameter. Needed for multimaps */ - sprintf(temp, "%s:next", cop); + sprintf(temp, "%s:next", cmethod); Setattr(firstp, typemap_method_name(temp), p); /* Attach kwargs */ @@ -1934,3 +1935,5 @@ void Swig_typemap_debug() { } Printf(stdout, "-----------------------------------------------------------------------------\n"); } + + From 9e2f8265b248eaad412fa31b0ebd7452e7a44be3 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 19 Dec 2009 11:23:20 +0000 Subject: [PATCH 115/146] Fix C comment stripping when the comment contains * git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11788 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/misc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c index 050e5357a..9b3e54fae 100644 --- a/Source/Swig/misc.c +++ b/Source/Swig/misc.c @@ -88,8 +88,8 @@ void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) { /* ----------------------------------------------------------------------------- * Swig_strip_c_comments() * - * Return a new string with C comments stripped from the input string. Null is - * returned if there aren't any. + * Return a new string with C comments stripped from the input string. NULL is + * returned if there aren't any comments. * ----------------------------------------------------------------------------- */ String *Swig_strip_c_comments(const String *s) { @@ -107,9 +107,10 @@ String *Swig_strip_c_comments(const String *s) { comment_begin = c-1; } else if (comment_begin && !comment_end && *c == '*') { ++c; - if (*c == '/') + if (*c == '/') { comment_end = c; - break; + break; + } } ++c; } From 2e9624af945c1d520db9d97a69482e74ffc61f97 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 19 Dec 2009 11:47:05 +0000 Subject: [PATCH 116/146] Minor correction in a comment git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11789 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/templ.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index d78c12b1a..9cbd18d6b 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -457,11 +457,11 @@ static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const check for match to partial specialization type, for example, all of the following could match the type in the %template: template struct XX {}; template struct XX {}; // r.$1 - template struct XX {}; // r.q(const).$1 - template struct XX {}; // r.q(const).p.$1 + template struct XX {}; // r.q(const).$1 + template struct XX {}; // r.q(const).p.$1 %template(XXX) XX; // r.q(const).p.int - where type="r.q(const).p.int" will match either of tt="r.$1", tt="r.q(const)" tt="r.q(const).p" + where type="r.q(const).p.int" will match either of tt="r.", tt="r.q(const)" tt="r.q(const).p" */ Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */ len = Len(tt); From d1ff2c6a8bd1b259efb98185df611c71bad1df81 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 20 Dec 2009 00:24:34 +0000 Subject: [PATCH 117/146] Add -debug-tmsearch option for debugging the typemap pattern matching rules git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11790 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++ Doc/Manual/Typemaps.html | 111 ++++++++++++++++++++++++++++++++++++--- Source/Modules/main.cxx | 6 ++- Source/Swig/swig.h | 1 + Source/Swig/typemap.c | 83 +++++++++++++++++++++++++---- 5 files changed, 189 insertions(+), 16 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 1ff98e258..570b0473f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 7a89a679a..3a8242866 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -31,10 +31,11 @@

  • Pattern matching rules
  • Code generation rules -
  • Typemaps for multiple languages +
  • Typemaps for multiple target languages
  • Optimal code generation when returning by value
  • Multi-argument typemaps
  • The run-time type checker @@ -1090,7 +1091,7 @@ void F(int x[1000]); // int [ANY] rule (typemap 5)
  • -

    10.3.2 Typedef reductions

    +

    10.3.2 Typedef reductions

    @@ -1432,6 +1433,104 @@ but all subsequent arguments must match exactly.

    +

    10.3.6 Debugging typemap pattern matching

    + + +

    +The -debug-tmsearch command line option is available 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 -debug-tmsearch example.i
    +...
    +---- Searching for a suitable 'in' typemap for: Row4 rows[10]
    +  Looking for: Row4 rows[10]
    +  Looking for: Row4 [10]
    +  Looking for: Row4 [ANY]
    +  Looking for: Integer rows[10][4]
    +  Looking for: Integer [10][4]
    +  Looking for: Integer [ANY][ANY]
    +  Looking for: int rows[10][4]
    +  Looking for: int [10][4]
    +  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 just the typemap method name and type in this format: %typemap(method) type. +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 this particular typemap, +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);
    +...
    +}
    +
    +
    +

    10.4 Code generation rules

    @@ -2705,12 +2804,12 @@ 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:

    @@ -3220,7 +3319,7 @@ language modules.
  • 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.

    diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 4903416cd..9194d39a0 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -69,7 +69,8 @@ static const char *usage1 = (const char *) "\ -debug-template - Display information for debugging templates\n\ -debug-top - Display entire parse tree at stages 1-4, is a csv list of stages\n\ -debug-typedef - Display information about the types and typedefs in the interface\n\ - -debug-typemap - Display information for debugging typemaps\n\ + -debug-typemap - Display typemap debugging information\n\ + -debug-tmsearch - Display typemap search debugging information\n\ -directors - Turn on director mode for all the classes, mainly for testing\n\ -dirprot - Turn on wrapping of protected members for director classes (default)\n\ -D - Define a symbol (for conditional compilation)\n\ @@ -655,6 +656,9 @@ void SWIG_getoptions(int argc, char *argv[]) { } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (strcmp(argv[i], "-tm_debug") == 0)) { tm_debug = 1; Swig_mark_arg(i); + } else if (strcmp(argv[i], "-debug-tmsearch") == 0) { + Swig_typemap_search_debug_set(); + Swig_mark_arg(i); } else if (strcmp(argv[i], "-module") == 0) { Swig_mark_arg(i); if (argv[i + 1]) { diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 2c2d4aa3b..677176cf8 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -374,6 +374,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat); extern void Swig_typemap_clear_apply(ParmList *pattern); extern void Swig_typemap_debug(void); + extern void Swig_typemap_search_debug_set(void); extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f); extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index b2c9ef3b2..ffd9f5e19 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -17,6 +17,9 @@ char cvsroot_typemap_c[] = "$Id$"; #define SWIG_DEBUG #endif +static int typemap_search_debug = 0; +static int in_typemap_search_multi = 0; + static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f); /* ----------------------------------------------------------------------------- @@ -171,12 +174,12 @@ Hash *Swig_typemap_pop_scope() { #endif /* ----------------------------------------------------------------------------- - * Swig_typemap_register() + * typemap_register() * - * Add a new multi-argument typemap + * Internal implementation for Swig_typemap_register() * ----------------------------------------------------------------------------- */ -void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) { +static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, const_String_or_char_ptr actual_tmap_method, ParmList *parmlist_start) { Hash *tm; Hash *tm1; Hash *tm2; @@ -249,13 +252,13 @@ void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms /* Make an entirely new typemap method key */ String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname); /* Now reregister on the remaining arguments */ - Swig_typemap_register(multi_tmap_method, np, code, locals, kwargs); + typemap_register(multi_tmap_method, np, code, locals, kwargs, actual_tmap_method, parmlist_start); /* Setattr(tm2,multi_tmap_method,multi_tmap_method); */ Delete(multi_tmap_method); } else { - String *str = SwigType_str(type, pname); - String *typemap = NewStringf("typemap(%s) %s", tmap_method, str); + String *parms_str = ParmList_str(parmlist_start); + String *typemap = NewStringf("typemap(%s) %s", actual_tmap_method, parms_str); ParmList *clocals = CopyParmList(locals); ParmList *ckwargs = CopyParmList(kwargs); @@ -271,11 +274,21 @@ void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms Delete(clocals); Delete(ckwargs); - Delete(str); + Delete(parms_str); Delete(typemap); } } +/* ----------------------------------------------------------------------------- + * Swig_typemap_register() + * + * Add a new, possibly multi-argument, typemap + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) { + typemap_register(tmap_method, parms, code, locals, kwargs, tmap_method, parms); +} + /* ----------------------------------------------------------------------------- * typemap_get() * @@ -594,6 +607,13 @@ static SwigType *strip_arrays(SwigType *type) { return t; } +static void debug_search_result_display(Node *tm) { + if (tm) + Printf(stdout, " Using: %%%s\n", Getattr(tm, "typemap")); + else + Printf(stdout, " None found\n"); +} + /* ----------------------------------------------------------------------------- * typemap_search() * @@ -612,16 +632,23 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type const String *cname = 0; SwigType *unstripped = 0; String *tm_method = typemap_method_name(tmap_method); + int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug; if ((name) && Len(name)) cname = name; ts = tm_scope; + if (debug_display) { + const String *empty_string = NewStringEmpty(); + Printf(stdout, "---- Searching for a suitable '%s' typemap for: %s\n", tmap_method, SwigType_str(type, cname ? cname : empty_string)); + } while (ts >= 0) { ctype = type; while (ctype) { /* Try to get an exact type-match */ tm = get_typemap(ts, ctype); + if (debug_display && cname) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cname)); if (tm && cname) { tm1 = Getattr(tm, cname); if (tm1) { @@ -632,6 +659,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type backup = result; } } + if (debug_display) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, 0)); if (tm) { result = Getattr(tm, tm_method); /* See if there is simply a type match */ if (result && Getattr(result, "code")) @@ -647,6 +676,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type noarrays = strip_arrays(ctype); } tma = get_typemap(ts, noarrays); + if (debug_display) + Printf(stdout, " Looking for: %s\n", SwigType_str(noarrays, 0)); if (tma && cname) { tm1 = Getattr(tma, cname); if (tm1) { @@ -694,11 +725,13 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type } } - /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */ + /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default (SWIGTYPE) mapping */ primitive = SwigType_default(type); while (primitive) { tm = get_typemap(ts, primitive); + if (debug_display && cname) + Printf(stdout, " Looking for: %s\n", SwigType_str(primitive, cname)); if (tm && cname) { tm1 = Getattr(tm, cname); if (tm1) { @@ -707,6 +740,8 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type goto ret_result; } } + if (debug_display) + Printf(stdout, " Looking for: %s\n", SwigType_str(primitive, 0)); if (tm) { /* See if there is simply a type match */ result = Getattr(tm, tm_method); if (result) @@ -771,16 +806,25 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList } Delete(mtype); multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, name); + in_typemap_search_multi++; tm1 = typemap_search_multi(multi_tmap_method, nextSibling(parms), nmatch); + in_typemap_search_multi--; if (tm1) tm = tm1; if (Getattr(tm, "code")) { *(nmatch) = *nmatch + 1; + if (typemap_search_debug && tm1 && (in_typemap_search_multi == 0)) { + Printf(stdout, " Multi-argument typemap found...\n"); + } } else { tm = 0; } Delete(multi_tmap_method); } + + if (typemap_search_debug && (in_typemap_search_multi == 0)) + debug_search_result_display(tm); + return tm; } @@ -1236,16 +1280,25 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No if (qsn) { if (Len(qsn) && !Equal(qsn, pname)) { tm = typemap_search(tmap_method, type, qsn, &mtype); + /* TODO: move the search for qualified names into typemap_search to make it more efficient */ if (tm && (!Getattr(tm, "pname") || strstr(Char(Getattr(tm, "type")), "SWIGTYPE"))) { + if (typemap_search_debug) + Printf(stdout, " Found but not using\n"); tm = 0; + } else { + if (typemap_search_debug) + debug_search_result_display(tm); } } Delete(qsn); } } - if (!tm) + if (!tm) { #endif tm = typemap_search(tmap_method, type, pname, &mtype); + if (typemap_search_debug) + debug_search_result_display(tm); + } if (!tm) return sdef; @@ -1921,6 +1974,8 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper /* ----------------------------------------------------------------------------- * Swig_typemap_debug() + * + * Display all typemaps * ----------------------------------------------------------------------------- */ void Swig_typemap_debug() { @@ -1937,3 +1992,13 @@ void Swig_typemap_debug() { } +/* ----------------------------------------------------------------------------- + * Swig_typemap_search_debug_set() + * + * Turn on typemap searching debug display + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_search_debug_set(void) { + typemap_search_debug = 1; +} + From f755bf73bfd1d626670caa27ded5876784b915c0 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 20 Dec 2009 01:19:48 +0000 Subject: [PATCH 118/146] Make docs on c++ source files more technically correct and fix some html errors git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11791 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/SWIG.html | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index c17add4c5..5b6b6410e 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -330,11 +330,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) */
      @@ -348,7 +350,6 @@ void bar(Spam (Grok)(Doh));
       
       
      -

      In practice, few (if any) C programmers actually write code like @@ -357,27 +358,32 @@ 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 ...
       }
       
      -

    • -
    • Certain advanced features of C++ such as nested classes -are not yet fully supported. Please see the C++ section +
    • +

      +Certain advanced features of C++ such as nested classes +are not yet fully supported. Please see the C++ Nested classes section for more information. +

    From f83d09f2761c8fcf898a7af416c4ce0271d8b393 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 20 Dec 2009 01:20:50 +0000 Subject: [PATCH 119/146] Section number renumbering git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11792 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Contents.html | 8 +++----- Doc/Manual/Python.html | 3 --- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html index 108106035..0cda0b8f4 100644 --- a/Doc/Manual/Contents.html +++ b/Doc/Manual/Contents.html @@ -346,10 +346,11 @@

  • Pattern matching rules
  • Code generation rules -
  • Typemaps for multiple languages +
  • Typemaps for multiple target languages
  • Optimal code generation when returning by value
  • Multi-argument typemaps
  • The run-time type checker @@ -1280,9 +1281,6 @@
  • Simple pointers
  • Unbounded C Arrays
  • String handling -
  • Arrays -
  • String arrays -
  • STL wrappers
  • Typemaps
  • Typemaps
      From ac224e857007a76fb63ab026fb82bb2d3cc0e606 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 21 Dec 2009 01:08:53 +0000 Subject: [PATCH 120/146] -debug-tmsearch improvements and fixes. Also slightly more efficient typemap searches when using fully qualified names. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11793 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 3 ++ Source/Swig/typemap.c | 113 ++++++++++++++++++++++++--------------- 2 files changed, 74 insertions(+), 42 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 3a8242866..bd9d6dbeb 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -1467,12 +1467,15 @@ swig -debug-tmsearch example.i ---- 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] diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index ffd9f5e19..1d69d5c9c 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -617,11 +617,12 @@ static void debug_search_result_display(Node *tm) { /* ----------------------------------------------------------------------------- * typemap_search() * - * Search for a typemap match. Tries to find the most specific typemap - * that includes a 'code' attribute. + * Search for a typemap match. This is where the typemap pattern matching rules + * are implemented... tries to find the most specific typemap that includes a + * 'code' attribute. * ----------------------------------------------------------------------------- */ -static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, SwigType **matchtype) { +static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype) { Hash *result = 0, *tm, *tm1, *tma; Hash *backup = 0; SwigType *noarrays = 0; @@ -630,29 +631,46 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type int ts; int isarray; const String *cname = 0; + const String *cqualifiedname = 0; SwigType *unstripped = 0; String *tm_method = typemap_method_name(tmap_method); int debug_display = (in_typemap_search_multi == 0) && typemap_search_debug; if ((name) && Len(name)) cname = name; + if ((qualifiedname) && Len(qualifiedname)) + cqualifiedname = qualifiedname; ts = tm_scope; if (debug_display) { const String *empty_string = NewStringEmpty(); - Printf(stdout, "---- Searching for a suitable '%s' typemap for: %s\n", tmap_method, SwigType_str(type, cname ? cname : empty_string)); + String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : (cname ? cname : empty_string)); + Printf(stdout, "---- Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr); + Delete(typestr); } while (ts >= 0) { ctype = type; while (ctype) { /* Try to get an exact type-match */ tm = get_typemap(ts, ctype); + if (debug_display && cqualifiedname) + Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cqualifiedname)); + if (tm && cqualifiedname) { + tm1 = Getattr(tm, cqualifiedname); + if (tm1) { + result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */ + if (result && Getattr(result, "code")) + goto ret_result; + if (result) + backup = result; + } + } if (debug_display && cname) Printf(stdout, " Looking for: %s\n", SwigType_str(ctype, cname)); if (tm && cname) { tm1 = Getattr(tm, cname); if (tm1) { - result = Getattr(tm1, tm_method); /* See if there is a type-name match */ + result = Getattr(tm1, tm_method); /* See if there is a type - name match */ if (result && Getattr(result, "code")) goto ret_result; if (result) @@ -676,20 +694,34 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type noarrays = strip_arrays(ctype); } tma = get_typemap(ts, noarrays); - if (debug_display) - Printf(stdout, " Looking for: %s\n", SwigType_str(noarrays, 0)); - if (tma && cname) { - tm1 = Getattr(tma, cname); + if (debug_display && cqualifiedname) + Printf(stdout, " Looking for: %s\n", SwigType_str(noarrays, cqualifiedname)); + if (tma && cqualifiedname) { + tm1 = Getattr(tma, cqualifiedname); if (tm1) { - result = Getattr(tm1, tm_method); /* type-name match */ + result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */ if (result && Getattr(result, "code")) goto ret_result; if (result) backup = result; } } + if (debug_display && cname) + Printf(stdout, " Looking for: %s\n", SwigType_str(noarrays, cname)); + if (tma && cname) { + tm1 = Getattr(tma, cname); + if (tm1) { + result = Getattr(tm1, tm_method); /* See if there is a type - name match */ + if (result && Getattr(result, "code")) + goto ret_result; + if (result) + backup = result; + } + } + if (debug_display) + Printf(stdout, " Looking for: %s\n", SwigType_str(noarrays, 0)); if (tma) { - result = Getattr(tma, tm_method); /* type match */ + result = Getattr(tma, tm_method); /* See if there is a type match */ if (result && Getattr(result, "code")) goto ret_result; if (result) @@ -730,20 +762,30 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type primitive = SwigType_default(type); while (primitive) { tm = get_typemap(ts, primitive); + if (debug_display && cqualifiedname) + Printf(stdout, " Looking for: %s\n", SwigType_str(primitive, cqualifiedname)); + if (tm && cqualifiedname) { + tm1 = Getattr(tm, cqualifiedname); + if (tm1) { + result = Getattr(tm1, tm_method); /* See if there is a type - qualified name match */ + if (result) + goto ret_result; + } + } if (debug_display && cname) Printf(stdout, " Looking for: %s\n", SwigType_str(primitive, cname)); if (tm && cname) { tm1 = Getattr(tm, cname); if (tm1) { - result = Getattr(tm1, tm_method); /* See if there is a type-name match */ + result = Getattr(tm1, tm_method); /* See if there is a type - name match */ if (result) goto ret_result; } } if (debug_display) Printf(stdout, " Looking for: %s\n", SwigType_str(primitive, 0)); - if (tm) { /* See if there is simply a type match */ - result = Getattr(tm, tm_method); + if (tm) { + result = Getattr(tm, tm_method); /* See if there is simply a type match */ if (result) goto ret_result; } @@ -799,7 +841,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList name = Getattr(parms, "name"); /* Try to find a match on the first type */ - tm = typemap_search(tmap_method, type, name, &mtype); + tm = typemap_search(tmap_method, type, name, 0, &mtype); if (tm) { if (mtype && SwigType_isarray(mtype)) { Setattr(parms, "tmap:match", mtype); @@ -1240,6 +1282,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No SwigType *type; SwigType *mtype = 0; String *pname; + String *qpname = 0; Hash *tm = 0; String *s = 0; String *sdef = 0; @@ -1254,8 +1297,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No int optimal_substitution = 0; int num_substitutions = 0; - /* special case, we need to check for 'ref' call - and set the default code 'sdef' */ + /* special case, we need to check for 'ref' call and set the default code 'sdef' */ if (node && Cmp(tmap_method, "newfree") == 0) { sdef = Swig_ref_call(node, lname); } @@ -1266,39 +1308,26 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No pname = Getattr(node, "name"); -#if 1 if (pname && node && checkAttribute(node, "kind", "function")) { /* - For functions, look qualified names first, such as - + For functions, add on a qualified name search, for example struct Foo { - int *foo(int bar) -> Foo::foo + int *foo(int bar) -> Foo::foo }; */ Symtab *st = Getattr(node, "sym:symtab"); String *qsn = st ? Swig_symbol_string_qualify(pname, st) : 0; - if (qsn) { - if (Len(qsn) && !Equal(qsn, pname)) { - tm = typemap_search(tmap_method, type, qsn, &mtype); - /* TODO: move the search for qualified names into typemap_search to make it more efficient */ - if (tm && (!Getattr(tm, "pname") || strstr(Char(Getattr(tm, "type")), "SWIGTYPE"))) { - if (typemap_search_debug) - Printf(stdout, " Found but not using\n"); - tm = 0; - } else { - if (typemap_search_debug) - debug_search_result_display(tm); - } - } - Delete(qsn); - } - } - if (!tm) { -#endif - tm = typemap_search(tmap_method, type, pname, &mtype); - if (typemap_search_debug) - debug_search_result_display(tm); + if (qsn && Len(qsn) && !Equal(qsn, pname)) + qpname = qsn; } + + tm = typemap_search(tmap_method, type, pname, qpname, &mtype); + if (typemap_search_debug) + debug_search_result_display(tm); + + Delete(qpname); + qpname = 0; + if (!tm) return sdef; From 97f959ddf03ecc915499ca4c952127fc489e857c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 22 Dec 2009 19:21:55 +0000 Subject: [PATCH 121/146] Slight improvement to -debug-tmsearch and multi-argument typemaps git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11794 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 18 +++++++++++++++++- Source/Swig/typemap.c | 11 ++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index bd9d6dbeb..43ab01248 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -1403,7 +1403,7 @@ Expect to see them being used more and more within the various libraries in late

      -

      10.3.5 Multi-arguments typemaps

      +

      10.3.5 Multi-arguments typemaps

      @@ -1534,6 +1534,22 @@ SWIGINTERN PyObject *_wrap_foo(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {

  • +

    +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 previous section is as follows: +

    + +
    +
    +...
    +---- Searching for a suitable 'in' typemap for: char *buffer
    +  Looking for: char *buffer
    +  Multi-argument typemap found...
    +  Using: %typemap(in) (char *buffer,int len)
    +...
    +
    +
    +

    10.4 Code generation rules

    diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 1d69d5c9c..d38f00db9 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -257,10 +257,14 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par /* Setattr(tm2,multi_tmap_method,multi_tmap_method); */ Delete(multi_tmap_method); } else { - String *parms_str = ParmList_str(parmlist_start); - String *typemap = NewStringf("typemap(%s) %s", actual_tmap_method, parms_str); ParmList *clocals = CopyParmList(locals); ParmList *ckwargs = CopyParmList(kwargs); + String *parms_str = ParmList_str(parmlist_start); + String *typemap; + if (ParmList_len(parmlist_start) > 1) + typemap = NewStringf("typemap(%s) (%s)", actual_tmap_method, parms_str); + else + typemap = NewStringf("typemap(%s) %s", actual_tmap_method, parms_str); Setattr(tm2, "code", code); Setattr(tm2, "type", type); @@ -643,10 +647,11 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type ts = tm_scope; if (debug_display) { - const String *empty_string = NewStringEmpty(); + String *empty_string = NewStringEmpty(); String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : (cname ? cname : empty_string)); Printf(stdout, "---- Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr); Delete(typestr); + Delete(empty_string); } while (ts >= 0) { ctype = type; From eefaef3bdbd1bf6dda0d45dcce17540849857a64 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 22 Dec 2009 23:08:28 +0000 Subject: [PATCH 122/146] Add link for const sections git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11795 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/SWIG.html | 6 ++++++ Doc/Manual/SWIGPlus.html | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index 5b6b6410e..02d0ca3a4 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -797,6 +797,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 diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 3836c86a7..8e051a0ec 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -56,7 +56,7 @@

  • Smart pointers and operator->()
  • Using declarations and inheritance
  • Nested classes -
  • A brief rant about const-correctness +
  • A brief rant about const-correctness
  • Where to go for more information @@ -4835,7 +4835,7 @@ Nested class warnings could also not be suppressed using %warnfilter.

    -

    6.27 A brief rant about const-correctness

    +

    6.27 A brief rant about const-correctness

    From bd84f7f794f94348a6b13cb96fa9cd81e761e245 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 23 Dec 2009 00:02:52 +0000 Subject: [PATCH 123/146] add link to %%newobject section git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11796 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Library.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html index eaebbede5..833a38393 100644 --- a/Doc/Manual/Library.html +++ b/Doc/Manual/Library.html @@ -890,7 +890,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

    From 6dad327ed37aa43e781a1dd802cf38fac91de84c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 23 Dec 2009 01:05:17 +0000 Subject: [PATCH 124/146] Fix for %%javaexception and directors so that all the appropriate throws clauses are generated git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11797 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ .../test-suite/java/java_director_runme.java | 17 +++++++++++++++++ Examples/test-suite/java_director.i | 8 ++++++++ Source/Modules/java.cxx | 3 +++ 4 files changed, 32 insertions(+) diff --git a/CHANGES.current b/CHANGES.current index 570b0473f..92b882c4c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +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. diff --git a/Examples/test-suite/java/java_director_runme.java b/Examples/test-suite/java/java_director_runme.java index dffba0ea5..86c92d49a 100644 --- a/Examples/test-suite/java/java_director_runme.java +++ b/Examples/test-suite/java/java_director_runme.java @@ -34,6 +34,12 @@ public class java_director_runme { System.gc(); System.runFinalization(); + // Give the finalizers a chance to run + try { + Thread.sleep(50); + } catch (InterruptedException e) { + } + /* Watch the Quux objects formerly in the QuuxContainer object get reaped */ System.gc(); @@ -73,3 +79,14 @@ class java_director_MyQuux extends Quux { return "java_director_MyQuux:" + member(); } } + +class java_director_JavaExceptionTest extends JavaExceptionTest { + public java_director_JavaExceptionTest() { + super(); + } + + public void etest() throws Exception { + super.etest(); + } +} + diff --git a/Examples/test-suite/java_director.i b/Examples/test-suite/java_director.i index 04d55e196..03d733d6a 100644 --- a/Examples/test-suite/java_director.i +++ b/Examples/test-suite/java_director.i @@ -122,3 +122,11 @@ struct JObjectTest { %} +%javaexception("Exception") etest "$action" +%inline %{ +struct JavaExceptionTest { + virtual ~JavaExceptionTest() {} + virtual void etest() {} +}; +%} + diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 7fccab5e1..bef41b0d2 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -3724,6 +3724,9 @@ public: String *upcall = NewStringf("self.%s(%s)", symname, imcall_args); + // Handle exception classes specified in the "except" feature's "throws" attribute + addThrows(n, "feature:except", n); + if (!is_void) { Parm *tp = NewParmFromNode(returntype, empty_str, n); From 1e8fa8fee022de3151209d0719aa30aa0fdb4e65 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 24 Dec 2009 15:50:03 +0000 Subject: [PATCH 125/146] remove warn.c - it isn't used git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11798 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/swig.h | 5 ----- Source/Swig/warn.c | 34 ---------------------------------- 2 files changed, 39 deletions(-) delete mode 100644 Source/Swig/warn.c diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 677176cf8..5108c7d33 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -307,13 +307,8 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern String *Swig_string_title(String *s); extern void Swig_init(void); - extern void Swig_warn(const char *filename, int line, const char *msg); - extern int Swig_value_wrapper_mode(int mode); - -#define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg) - typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat; extern void Swig_warning(int num, const_String_or_char_ptr filename, int line, const char *fmt, ...); diff --git a/Source/Swig/warn.c b/Source/Swig/warn.c deleted file mode 100644 index a8dadc70b..000000000 --- a/Source/Swig/warn.c +++ /dev/null @@ -1,34 +0,0 @@ -/* ----------------------------------------------------------------------------- - * 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. - * - * warn.c - * - * SWIG warning framework. This was added to warn developers about - * deprecated APIs and other features. - * ----------------------------------------------------------------------------- */ - -char cvsroot_warn_c[] = "$Id$"; - -#include "swig.h" - -static Hash *warnings = 0; - -/* ----------------------------------------------------------------------------- - * Swig_warn() - * - * Issue a warning - * ----------------------------------------------------------------------------- */ - -void Swig_warn(const char *filename, int line, const char *msg) { - String *key; - if (!warnings) { - warnings = NewHash(); - } - key = NewStringf("%s:%d", filename, line); - if (!Getattr(warnings, key)) { - Printf(stderr, "swig-dev warning:%s:%d:%s\n", filename, line, msg); - Setattr(warnings, key, key); - } - Delete(key); -} From 9bc7f3c676c5597504a38e1a1824f4c00ed6463a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 24 Dec 2009 15:53:01 +0000 Subject: [PATCH 126/146] remove warn.c - it isn't used git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11799 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/Makefile.am b/Source/Makefile.am index aadf50d28..bc3222b25 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -86,7 +86,6 @@ eswig_SOURCES = CParse/cscanner.c \ Swig/typeobj.c \ Swig/typemap.c \ Swig/typesys.c \ - Swig/warn.c \ Swig/wrapfunc.c bin_PROGRAMS = eswig From 6b2fe71e0ed9f6b7cc7d33245ce64d792a278620 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 24 Dec 2009 16:51:45 +0000 Subject: [PATCH 127/146] Add Swig_diagnostic() for displaying file and line number messages to stdout git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11800 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/error.c | 34 ++++++++++++++++++++++++++++++++-- Source/Swig/swig.h | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 156fe06a7..0f4728954 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -49,13 +49,15 @@ static char wrn_wnum_fmt[64]; static char wrn_nnum_fmt[64]; static char err_line_fmt[64]; static char err_eof_fmt[64]; +static char diag_line_fmt[64]; +static char diag_eof_fmt[64]; static String *format_filename(const_String_or_char_ptr filename); /* ----------------------------------------------------------------------------- * Swig_warning() * - * Issue a warning message + * Issue a warning message on stderr. * ----------------------------------------------------------------------------- */ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const char *fmt, ...) { @@ -118,7 +120,7 @@ void Swig_warning(int wnum, const_String_or_char_ptr filename, int line, const c /* ----------------------------------------------------------------------------- * Swig_error() * - * Issue an error message + * Issue an error message on stderr. * ----------------------------------------------------------------------------- */ void Swig_error(const_String_or_char_ptr filename, int line, const char *fmt, ...) { @@ -258,6 +260,8 @@ void Swig_error_msg_format(ErrorMessageFormat format) { sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); + sprintf(diag_line_fmt, "%s: ", fmt_line); + sprintf(diag_eof_fmt, "%s: ", fmt_eof); msg_format = format; init_fmt = 1; @@ -275,3 +279,29 @@ static String *format_filename(const_String_or_char_ptr filename) { #endif return formatted_filename; } + +/* ----------------------------------------------------------------------------- + * Swig_diagnostic() + * + * Issue a diagnostic message on stdout. + * ----------------------------------------------------------------------------- */ + +void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...) { + va_list ap; + String *formatted_filename = NULL; + + if (!init_fmt) + Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); + + va_start(ap, fmt); + formatted_filename = format_filename(filename); + if (line > 0) { + Printf(stdout, diag_line_fmt, formatted_filename, line); + } else { + Printf(stdout, diag_eof_fmt, formatted_filename); + } + vPrintf(stdout, fmt, ap); + va_end(ap); + Delete(formatted_filename); +} + diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 5108c7d33..8c4d50000 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -319,6 +319,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern void Swig_warnall(void); extern int Swig_warn_count(void); extern void Swig_error_msg_format(ErrorMessageFormat format); + extern void Swig_diagnostic(const_String_or_char_ptr filename, int line, const char *fmt, ...); /* --- C Wrappers --- */ extern String *Swig_cparm_name(Parm *p, int i); From 8b7c0afcfc7ba5fce62b11bb17932f3310dceef9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 24 Dec 2009 17:00:35 +0000 Subject: [PATCH 128/146] Display filename and line number in output when using -debug-tmsearch git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11801 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 4 ++-- Source/Swig/typemap.c | 51 +++++++++++++++++----------------------- 2 files changed, 24 insertions(+), 31 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 43ab01248..89cae62a3 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -1464,7 +1464,7 @@ A sample of the debugging output is shown below for the "in" typemap:
     swig -debug-tmsearch example.i
     ...
    ----- Searching for a suitable 'in' typemap for: Row4 rows[10]
    +example.h:26: Searching for a suitable 'in' typemap for: Row4 rows[10]
       Looking for: Row4 rows[10]
       Looking for: Row4 [10]
       Looking for: Row4 rows[ANY]
    @@ -1542,7 +1542,7 @@ For example, the output for the code in the 
     
     ...
    ----- Searching for a suitable 'in' typemap for: char *buffer
    +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)
    diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
    index d38f00db9..3bb4e6909 100644
    --- a/Source/Swig/typemap.c
    +++ b/Source/Swig/typemap.c
    @@ -626,7 +626,7 @@ static void debug_search_result_display(Node *tm) {
      * 'code' attribute.
      * ----------------------------------------------------------------------------- */
     
    -static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype) {
    +static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type, const_String_or_char_ptr name, const_String_or_char_ptr qualifiedname, SwigType **matchtype, Node *node) {
       Hash *result = 0, *tm, *tm1, *tma;
       Hash *backup = 0;
       SwigType *noarrays = 0;
    @@ -649,7 +649,7 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type
       if (debug_display) {
         String *empty_string = NewStringEmpty();
         String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : (cname ? cname : empty_string));
    -    Printf(stdout, "---- Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr);
    +    Swig_diagnostic(Getfile(node), Getline(node), "Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr);
         Delete(typestr);
         Delete(empty_string);
       }
    @@ -846,7 +846,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList
       name = Getattr(parms, "name");
     
       /* Try to find a match on the first type */
    -  tm = typemap_search(tmap_method, type, name, 0, &mtype);
    +  tm = typemap_search(tmap_method, type, name, 0, &mtype, parms);
       if (tm) {
         if (mtype && SwigType_isarray(mtype)) {
           Setattr(parms, "tmap:match", mtype);
    @@ -1259,6 +1259,22 @@ static void typemap_locals(DOHString * s, ParmList *l, Wrapper *f, int argnum) {
       }
     }
     
    +/* -----------------------------------------------------------------------------
    + * typemap_warn()
    + *
    + * If any warning message is attached to this parameter's "tmap::warning"
    + * attribute, print that warning message.
    + * ----------------------------------------------------------------------------- */
    +
    +static void typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
    +  String *temp = NewStringf("%s:warning", tmap_method);
    +  String *w = Getattr(p, typemap_method_name(temp));
    +  Delete(temp);
    +  if (w) {
    +    Swig_warning(0, Getfile(p), Getline(p), "%s\n", w);
    +  }
    +}
    +
     /* -----------------------------------------------------------------------------
      * Swig_typemap_lookup()
      *
    @@ -1326,7 +1342,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
           qpname = qsn;
       }
     
    -  tm = typemap_search(tmap_method, type, pname, qpname, &mtype);
    +  tm = typemap_search(tmap_method, type, pname, qpname, &mtype, node);
       if (typemap_search_debug)
         debug_search_result_display(tm);
     
    @@ -1459,15 +1475,8 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No
         Setattr(node, typemap_method_name(temp), "1");
       }
     
    -  /* Look for warnings */
    -  {
    -    String *w;
    -    sprintf(temp, "%s:warning", cmethod);
    -    w = Getattr(node, typemap_method_name(temp));
    -    if (w) {
    -      Swig_warning(0, Getfile(node), Getline(node), "%s\n", w);
    -    }
    -  }
    +  /* Print warnings, if any */
    +  typemap_warn(cmethod, node);
     
       /* Look for code fragments */
       {
    @@ -1542,22 +1551,6 @@ static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method
       Delete(temp);
     }
     
    -/* -----------------------------------------------------------------------------
    - * typemap_warn()
    - *
    - * If any warning message is attached to this parameter's "tmap::warning"
    - * attribute, print that warning message.
    - * ----------------------------------------------------------------------------- */
    -
    -static void typemap_warn(const_String_or_char_ptr tmap_method, Parm *p) {
    -  String *temp = NewStringf("%s:warning", tmap_method);
    -  String *w = Getattr(p, typemap_method_name(temp));
    -  Delete(temp);
    -  if (w) {
    -    Swig_warning(0, Getfile(p), Getline(p), "%s\n", w);
    -  }
    -}
    -
     static void typemap_emit_code_fragments(const_String_or_char_ptr tmap_method, Parm *p) {
       String *temp = NewStringf("%s:fragment", tmap_method);
       String *f = Getattr(p, typemap_method_name(temp));
    
    From 83bd8202859d9d703cc9ace6c3827c5f12047bd6 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Mon, 4 Jan 2010 19:33:52 +0000
    Subject: [PATCH 129/146] Add typemaps used debugging option (-debug-tmused).
     Fix missing file/line numbers for typemap warnings and in the output from the
     -debug-tmsearch/-debug-tmused options
    
    git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11802 626c5289-ae23-0410-ae9c-e8d60b6d4f22
    ---
     CHANGES.current             | 10 ++++++++++
     Doc/Manual/Typemaps.html    | 26 ++++++++++++++++++++++---
     Source/CParse/cparse.h      |  2 +-
     Source/CParse/parser.y      | 22 +++++++++++----------
     Source/CParse/templ.c       |  2 +-
     Source/Modules/allocate.cxx |  2 +-
     Source/Modules/cffi.cxx     | 12 ++++++------
     Source/Modules/clisp.cxx    |  2 +-
     Source/Modules/csharp.cxx   | 17 +++++------------
     Source/Modules/guile.cxx    | 18 ++++++++++--------
     Source/Modules/java.cxx     | 29 +++++++++++-----------------
     Source/Modules/lang.cxx     | 12 ++++++++----
     Source/Modules/main.cxx     |  4 ++++
     Source/Modules/mzscheme.cxx | 16 +++++++++-------
     Source/Modules/ocaml.cxx    |  4 ++--
     Source/Modules/octave.cxx   |  4 ++--
     Source/Modules/php.cxx      |  2 +-
     Source/Modules/python.cxx   |  4 ++--
     Source/Modules/r.cxx        |  7 ++-----
     Source/Modules/ruby.cxx     |  4 ++--
     Source/Swig/cwrap.c         | 12 ++++++------
     Source/Swig/parms.c         | 19 +++++++++++++++++--
     Source/Swig/swig.h          |  3 ++-
     Source/Swig/swigparm.h      |  3 ++-
     Source/Swig/symbol.c        |  4 ++--
     Source/Swig/typemap.c       | 38 +++++++++++++++++++++++++++++++------
     Source/Swig/typeobj.c       |  6 ++++--
     27 files changed, 178 insertions(+), 106 deletions(-)
    
    diff --git a/CHANGES.current b/CHANGES.current
    index 92b882c4c..cb6c9f9c0 100644
    --- a/CHANGES.current
    +++ b/CHANGES.current
    @@ -1,6 +1,16 @@
     Version 1.3.41 (in progress)
     ============================
     
    +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.
    diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
    index 89cae62a3..9fa487ab4 100644
    --- a/Doc/Manual/Typemaps.html
    +++ b/Doc/Manual/Typemaps.html
    @@ -1437,7 +1437,11 @@ but all subsequent arguments must match exactly.
     
     
     

    -The -debug-tmsearch command line option is available for debugging typemap searches. +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. @@ -1462,9 +1466,9 @@ A sample of the debugging output is shown below for the "in" typemap:

    -swig -debug-tmsearch example.i
    +swig -perl -debug-tmsearch example.i
     ...
    -example.h:26: Searching for a suitable 'in' typemap for: Row4 rows[10]
    +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]
    @@ -1550,6 +1554,22 @@ example.h:39: Searching for a suitable 'in' typemap for: char *buffer
     
    +

    +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 below is for the example code at the start of this section on debugging. +

    + +
    +
    +$ swig -perl -debug-tmused example.i
    +example.h:3: Using %typemap(in) SWIGTYPE [] for: Row4 rows[10]
    +example.h:3: Using %typemap(typecheck) SWIGTYPE * for: Row4 rows[10]
    +example.h:3: Using %typemap(freearg) SWIGTYPE [] for: Row4 rows[10]
    +example.h:3: Using %typemap(out) void for: void foo
    +
    +
    +

    10.4 Code generation rules

    diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h index 9be41c60e..a71be786f 100644 --- a/Source/CParse/cparse.h +++ b/Source/CParse/cparse.h @@ -53,7 +53,7 @@ extern "C" { extern void Swig_cparse_replace_descriptor(String *s); extern void cparse_normalize_void(Node *); extern Parm *Swig_cparse_parm(String *s); - extern ParmList *Swig_cparse_parms(String *s); + extern ParmList *Swig_cparse_parms(String *s, Node *file_line_node); /* templ.c */ diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y index b9db52104..dafecc96f 100644 --- a/Source/CParse/parser.y +++ b/Source/CParse/parser.y @@ -2724,11 +2724,11 @@ typemap_parm : type typemap_parameter_declarator { Parm *parm; SwigType_push($1,$2.type); $$ = new_node("typemapitem"); - parm = NewParm($1,$2.id); + parm = NewParmWithoutFileLineInfo($1,$2.id); Setattr($$,"pattern",parm); Setattr($$,"parms", $2.parms); Delete(parm); - /* $$ = NewParm($1,$2.id); + /* $$ = NewParmWithoutFileLineInfo($1,$2.id); Setattr($$,"parms",$2.parms); */ } | LPAREN parms RPAREN { @@ -3983,7 +3983,7 @@ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { SwigType *rtt = Swig_symbol_typedef_reduce(tt.item,0); SwigType *ttr = Swig_symbol_type_qualify(rtt,0); - Parm *newp = NewParm(ttr, 0); + Parm *newp = NewParmWithoutFileLineInfo(ttr, 0); if (partialparms) set_nextSibling(parm_current, newp); else @@ -4129,7 +4129,7 @@ templateparameters : templateparameter templateparameterstail { ; templateparameter : templcpptype { - $$ = NewParm(NewString($1), 0); + $$ = NewParmWithoutFileLineInfo(NewString($1), 0); } | parm { $$ = $1; @@ -4708,7 +4708,7 @@ ptail : COMMA parm ptail { parm : rawtype parameter_declarator { SwigType_push($1,$2.type); - $$ = NewParm($1,$2.id); + $$ = NewParmWithoutFileLineInfo($1,$2.id); Setfile($$,cparse_file); Setline($$,cparse_line); if ($2.defarg) { @@ -4717,7 +4717,7 @@ parm : rawtype parameter_declarator { } | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args { - $$ = NewParm(NewStringf("template %s %s", $5,$6), 0); + $$ = NewParmWithoutFileLineInfo(NewStringf("template %s %s", $5,$6), 0); Setfile($$,cparse_file); Setline($$,cparse_line); if ($7.val) { @@ -4726,7 +4726,7 @@ parm : rawtype parameter_declarator { } | PERIOD PERIOD PERIOD { SwigType *t = NewString("v(...)"); - $$ = NewParm(t, 0); + $$ = NewParmWithoutFileLineInfo(t, 0); Setfile($$,cparse_file); Setline($$,cparse_line); } @@ -4789,7 +4789,7 @@ valparm : parm { } | valexpr { - $$ = NewParm(0,0); + $$ = NewParmWithoutFileLineInfo(0,0); Setfile($$,cparse_file); Setline($$,cparse_line); Setattr($$,"value",$1.val); @@ -6226,14 +6226,16 @@ Parm *Swig_cparse_parm(String *s) { } -ParmList *Swig_cparse_parms(String *s) { +ParmList *Swig_cparse_parms(String *s, Node *file_line_node) { String *ns; char *cs = Char(s); if (cs && cs[0] != '(') { ns = NewStringf("(%s);",s); } else { ns = NewStringf("%s;",s); - } + } + Setfile(ns, Getfile(file_line_node)); + Setline(ns, Getline(file_line_node)); Seek(ns,0,SEEK_SET); scanner_file(ns); top = 0; diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index 9cbd18d6b..c3cc115c6 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -262,7 +262,7 @@ int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab /* Look for partial specialization matching */ if (Getattr(n, "partialargs")) { Parm *p, *tp; - ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs")); + ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"), n); p = ptargs; tp = tparms; while (p && tp) { diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx index d78dd13d7..e37358be6 100644 --- a/Source/Modules/allocate.cxx +++ b/Source/Modules/allocate.cxx @@ -518,7 +518,7 @@ class Allocate:public Dispatcher { */ String *scatchlist = Getattr(n, "feature:catches"); if (scatchlist) { - catchlist = Swig_cparse_parms(scatchlist); + catchlist = Swig_cparse_parms(scatchlist, n); if (catchlist) { Setattr(n, "catchlist", catchlist); mark_exception_classes(catchlist); diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx index 062b9f0ff..09e97f448 100644 --- a/Source/Modules/cffi.cxx +++ b/Source/Modules/cffi.cxx @@ -618,12 +618,12 @@ int CFFI::enumDeclaration(Node *n) { slot_name_keywords = true; //Registering the enum name to the cin and cout typemaps - Parm *pattern = NewParm(name, NULL); + Parm *pattern = NewParm(name, NULL, n); Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); Delete(pattern); //Registering with the kind, i.e., enum - pattern = NewParm(NewStringf("enum %s", name), NULL); + pattern = NewParm(NewStringf("enum %s", name), NULL, n); Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); Delete(pattern); @@ -688,7 +688,7 @@ void CFFI::emit_class(Node *n) { Printf(f_clos, "\n(cl:defclass %s%s", lisp_name, supers); Printf(f_clos, "\n ((ff-pointer :reader ff-pointer)))\n\n"); - Parm *pattern = NewParm(Getattr(n, "name"), NULL); + Parm *pattern = NewParm(Getattr(n, "name"), NULL, n); Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL); SwigType_add_pointer(Getattr(pattern, "type")); @@ -758,7 +758,7 @@ void CFFI::emit_class(Node *n) { Delete(supers); // Delete(ns_list); - // Parm *pattern = NewParm(name,NULL); + // Parm *pattern = NewParm(name, NULL, n); // Swig_typemap_register("cin",pattern,lisp_name,NULL,NULL); //Swig_typemap_register("cout",pattern,lisp_name,NULL,NULL); //Delete(pattern); @@ -787,12 +787,12 @@ void CFFI::emit_struct_union(Node *n, bool un = false) { //Register the struct/union name to the cin and cout typemaps - Parm *pattern = NewParm(name, NULL); + Parm *pattern = NewParm(name, NULL, n); Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); Delete(pattern); //Registering with the kind, i.e., struct or union - pattern = NewParm(NewStringf("%s %s", kind, name), NULL); + pattern = NewParm(NewStringf("%s %s", kind, name), NULL, n); Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL); Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL); Delete(pattern); diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx index 46c5ef84a..2dc30667f 100644 --- a/Source/Modules/clisp.cxx +++ b/Source/Modules/clisp.cxx @@ -452,7 +452,7 @@ String *CLISP::get_ffi_type(Node *n, SwigType *ty) { SwigType *cp = Copy(ty); SwigType *fn = SwigType_pop_function(cp); String *args = NewString(""); - ParmList *pl = SwigType_function_parms(fn); + ParmList *pl = SwigType_function_parms(fn, n); if (ParmList_len(pl) != 0) { Printf(args, "(:arguments "); } diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 82a9a629c..7fb481271 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -86,13 +86,6 @@ class CSHARP:public Language { enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum }; - static Parm *NewParmFromNode(SwigType *type, const_String_or_char_ptr name, Node *n) { - Parm *p = NewParm(type, name); - Setfile(p, Getfile(n)); - Setline(p, Getline(n)); - return p; - } - public: /* ----------------------------------------------------------------------------- @@ -3331,7 +3324,7 @@ public: } /* Create the intermediate class wrapper */ - Parm *tp = NewParmFromNode(returntype, empty_str, n); + Parm *tp = NewParm(returntype, empty_str, n); tm = Swig_typemap_lookup("imtype", tp, "", 0); if (tm) { @@ -3351,7 +3344,7 @@ public: Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0)); } - Parm *retpm = NewParmFromNode(returntype, empty_str, n); + Parm *retpm = NewParm(returntype, empty_str, n); if ((c_ret_type = Swig_typemap_lookup("ctype", retpm, "", 0))) { @@ -3438,7 +3431,7 @@ public: if (ctypeout) c_param_type = ctypeout; - Parm *tp = NewParmFromNode(c_param_type, empty_str, n); + Parm *tp = NewParm(c_param_type, empty_str, n); String *desc_tm = NULL; /* Add to local variables */ @@ -3593,7 +3586,7 @@ public: String *upcall = NewStringf("%s(%s)", symname, imcall_args); if (!is_void) { - Parm *tp = NewParmFromNode(returntype, empty_str, n); + Parm *tp = NewParm(returntype, empty_str, n); if ((tm = Swig_typemap_lookup("csdirectorout", tp, "", 0))) { substituteClassname(returntype, tm); @@ -3619,7 +3612,7 @@ public: if (!is_void) { String *jresult_str = NewString("jresult"); String *result_str = NewString("c_result"); - Parm *tp = NewParmFromNode(returntype, result_str, n); + Parm *tp = NewParm(returntype, result_str, n); /* Copy jresult into c_result... */ if ((tm = Swig_typemap_lookup("directorout", tp, result_str, w))) { diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx index 0c72de8d0..38ee7b9f5 100644 --- a/Source/Modules/guile.cxx +++ b/Source/Modules/guile.cxx @@ -1407,16 +1407,18 @@ public: } { /* Hack alert: will cleanup later -- Dave */ - Node *n = NewHash(); - Setattr(n, "name", var_name); - Setattr(n, "sym:name", iname); - Setattr(n, "type", nctype); - SetFlag(n, "feature:immutable"); + Node *nn = NewHash(); + Setfile(nn, Getfile(n)); + Setline(nn, Getline(n)); + Setattr(nn, "name", var_name); + Setattr(nn, "sym:name", iname); + Setattr(nn, "type", nctype); + SetFlag(nn, "feature:immutable"); if (constasvar) { - SetFlag(n, "feature:constasvar"); + SetFlag(nn, "feature:constasvar"); } - variableWrapper(n); - Delete(n); + variableWrapper(nn); + Delete(nn); } Delete(var_name); Delete(nctype); diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index bef41b0d2..5eb6dcae9 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -83,13 +83,6 @@ class JAVA:public Language { enum EnumFeature { SimpleEnum, TypeunsafeEnum, TypesafeEnum, ProperEnum }; - static Parm *NewParmFromNode(SwigType *type, const_String_or_char_ptr name, Node *n) { - Parm *p = NewParm(type, name); - Setfile(p, Getfile(n)); - Setline(p, Getline(n)); - return p; - } - public: /* ----------------------------------------------------------------------------- @@ -1981,7 +1974,7 @@ public: if (qualifier) SwigType_push(this_type, qualifier); SwigType_add_pointer(this_type); - Parm *this_parm = NewParm(this_type, name); + Parm *this_parm = NewParm(this_type, name, n); Swig_typemap_attach_parms("jtype", this_parm, NULL); Swig_typemap_attach_parms("jstype", this_parm, NULL); @@ -3389,7 +3382,7 @@ public: } /* Create the intermediate class wrapper */ - Parm *tp = NewParmFromNode(returntype, empty_str, n); + Parm *tp = NewParm(returntype, empty_str, n); tm = Swig_typemap_lookup("jtype", tp, "", 0); if (tm) { @@ -3401,7 +3394,7 @@ public: String *cdesc = NULL; SwigType *covariant = Getattr(n, "covariant"); SwigType *adjustedreturntype = covariant ? covariant : returntype; - Parm *adjustedreturntypeparm = NewParmFromNode(adjustedreturntype, empty_str, n); + Parm *adjustedreturntypeparm = NewParm(adjustedreturntype, empty_str, n); if ((tm = Swig_typemap_lookup("directorin", adjustedreturntypeparm, "", 0)) && (cdesc = Getattr(adjustedreturntypeparm, "tmap:directorin:descriptor"))) { @@ -3421,10 +3414,10 @@ public: /* Get the JNI field descriptor for this return type, add the JNI field descriptor to jniret_desc */ - Parm *retpm = NewParmFromNode(returntype, empty_str, n); + Parm *retpm = NewParm(returntype, empty_str, n); if ((c_ret_type = Swig_typemap_lookup("jni", retpm, "", 0))) { - Parm *tp = NewParmFromNode(c_ret_type, empty_str, n); + Parm *tp = NewParm(c_ret_type, empty_str, n); if (!is_void && !ignored_method) { String *jretval_decl = NewStringf("%s jresult", c_ret_type); @@ -3526,7 +3519,7 @@ public: } /* Start the Java field descriptor for the intermediate class's upcall (insert self object) */ - Parm *tp = NewParmFromNode(c_classname, empty_str, n); + Parm *tp = NewParm(c_classname, empty_str, n); String *jdesc; if ((tm = Swig_typemap_lookup("directorin", tp, "", 0)) @@ -3568,7 +3561,7 @@ public: /* Get parameter's intermediary C type */ if ((c_param_type = Getattr(p, "tmap:jni"))) { - Parm *tp = NewParmFromNode(c_param_type, empty_str, n); + Parm *tp = NewParm(c_param_type, empty_str, n); String *desc_tm = NULL, *jdesc = NULL, *cdesc = NULL; /* Add to local variables */ @@ -3728,7 +3721,7 @@ public: addThrows(n, "feature:except", n); if (!is_void) { - Parm *tp = NewParmFromNode(returntype, empty_str, n); + Parm *tp = NewParm(returntype, empty_str, n); if ((tm = Swig_typemap_lookup("javadirectorout", tp, "", 0))) { addThrows(n, "tmap:javadirectorout", tp); @@ -3772,7 +3765,7 @@ public: if (!is_void) { String *jresult_str = NewString("jresult"); String *result_str = NewString("c_result"); - Parm *tp = NewParmFromNode(returntype, result_str, n); + Parm *tp = NewParm(returntype, result_str, n); /* Copy jresult into c_result... */ if ((tm = Swig_typemap_lookup("directorout", tp, result_str, w))) { @@ -3865,7 +3858,7 @@ public: SwigType_add_pointer(jenv_type); - p = NewParmFromNode(jenv_type, NewString("jenv"), n); + p = NewParm(jenv_type, NewString("jenv"), n); Setattr(p, "arg:byname", "1"); set_nextSibling(p, NULL); @@ -3902,7 +3895,7 @@ public: String *jenv_type = NewString("JNIEnv"); SwigType_add_pointer(jenv_type); - p = NewParmFromNode(jenv_type, NewString("jenv"), n); + p = NewParm(jenv_type, NewString("jenv"), n); set_nextSibling(p, parms); parms = p; diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index 971b56ec1..ea1f09133 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -900,7 +900,7 @@ int Language::cDeclaration(Node *n) { Delete(ty); ty = fullty; fullty = 0; - ParmList *parms = SwigType_function_parms(ty); + ParmList *parms = SwigType_function_parms(ty, n); Setattr(n, "parms", parms); } /* Transform the node into a 'function' node and emit */ @@ -1188,6 +1188,8 @@ int Language::memberfunctionHandler(Node *n) { Setattr(cbn, "type", cbty); Setattr(cbn, "value", cbvalue); Setattr(cbn, "name", name); + Setfile(cbn, Getfile(n)); + Setline(cbn, Getline(n)); memberconstantHandler(cbn); Setattr(n, "feature:callback:name", Swig_name_member(ClassPrefix, cbname)); @@ -1478,7 +1480,7 @@ int Language::membervariableHandler(Node *n) { Parm *p; String *gname; SwigType *vty; - p = NewParm(type, 0); + p = NewParm(type, 0, n); gname = NewStringf(AttributeFunctionGet, symname); if (!Extend) { ActionFunc = Copy(Swig_cmemberget_call(name, type)); @@ -1904,12 +1906,14 @@ int Language::classDirectorDisown(Node *n) { String *type = NewString(ClassType); String *name = NewString("self"); SwigType_add_pointer(type); - Parm *p = NewParm(type, name); + Parm *p = NewParm(type, name, n); Delete(name); Delete(type); type = NewString("void"); String *action = NewString(""); Printv(action, "{\n", "Swig::Director *director = dynamic_cast(arg1);\n", "if (director) director->swig_disown();\n", "}\n", NULL); + Setfile(disown, Getfile(n)); + Setline(disown, Getline(n)); Setattr(disown, "wrap:action", action); Setattr(disown, "name", mrename); Setattr(disown, "sym:name", mrename); @@ -2162,7 +2166,7 @@ static void addCopyConstructor(Node *n) { if (!symname) { symname = Copy(csymname); } - Parm *p = NewParm(cc, "other"); + Parm *p = NewParm(cc, "other", n); Setattr(cn, "name", name); Setattr(cn, "sym:name", symname); diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx index 9194d39a0..34914efa3 100644 --- a/Source/Modules/main.cxx +++ b/Source/Modules/main.cxx @@ -71,6 +71,7 @@ static const char *usage1 = (const char *) "\ -debug-typedef - Display information about the types and typedefs in the interface\n\ -debug-typemap - Display typemap debugging information\n\ -debug-tmsearch - Display typemap search debugging information\n\ + -debug-tmused - Display typemaps used debugging information\n\ -directors - Turn on director mode for all the classes, mainly for testing\n\ -dirprot - Turn on wrapping of protected members for director classes (default)\n\ -D - Define a symbol (for conditional compilation)\n\ @@ -659,6 +660,9 @@ void SWIG_getoptions(int argc, char *argv[]) { } else if (strcmp(argv[i], "-debug-tmsearch") == 0) { Swig_typemap_search_debug_set(); Swig_mark_arg(i); + } else if (strcmp(argv[i], "-debug-tmused") == 0) { + Swig_typemap_used_debug_set(); + Swig_mark_arg(i); } else if (strcmp(argv[i], "-module") == 0) { Swig_mark_arg(i); if (argv[i + 1]) { diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 28dd8ecd2..77339d325 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -647,13 +647,15 @@ public: { /* Hack alert: will cleanup later -- Dave */ - Node *n = NewHash(); - Setattr(n, "name", var_name); - Setattr(n, "sym:name", iname); - Setattr(n, "type", type); - SetFlag(n, "feature:immutable"); - variableWrapper(n); - Delete(n); + Node *nn = NewHash(); + Setfile(nn, Getfile(n)); + Setline(nn, Getline(n)); + Setattr(nn, "name", var_name); + Setattr(nn, "sym:name", iname); + Setattr(nn, "type", type); + SetFlag(nn, "feature:immutable"); + variableWrapper(nn); + Delete(nn); } } Delete(proc_name); diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 8a797759c..cfd4fc682 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1727,7 +1727,7 @@ public: ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("CAML_VALUE"); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); q = Copy(p); set_nextSibling(q, superparms); set_nextSibling(p, parms); @@ -1780,7 +1780,7 @@ public: ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("CAML_VALUE"); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); q = Copy(p); set_nextSibling(p, parms); parms = p; diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 1804334d6..ff880fc5a 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -956,7 +956,7 @@ public: String *name = NewString("self"); String *type = NewString("void"); SwigType_add_pointer(type); - self = NewParm(type, name); + self = NewParm(type, name, n); Delete(type); Delete(name); Setattr(self, "lname", "self_obj"); @@ -1051,7 +1051,7 @@ public: ParmList *parms = CopyParmList(superparms); String *type = NewString("void"); SwigType_add_pointer(type); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); set_nextSibling(p, parms); parms = p; diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index ca9d4e742..e98a16f7d 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2323,7 +2323,7 @@ done: ParmList *parms = CopyParmList(superparms); String *type = NewString("zval"); SwigType_add_pointer(type); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); set_nextSibling(p, parms); parms = p; diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 9475139a3..bc76f17d4 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2625,7 +2625,7 @@ public: ParmList *parms = CopyParmList(superparms); String *type = NewString("PyObject"); SwigType_add_pointer(type); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); set_nextSibling(p, parms); parms = p; @@ -3205,7 +3205,7 @@ public: String *name = NewString("self"); String *type = NewString("PyObject"); SwigType_add_pointer(type); - self = NewParm(type, name); + self = NewParm(type, name, n); Delete(type); Delete(name); Setattr(self, "lname", "O"); diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 41058284f..fec2330bd 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -588,7 +588,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { // ParmList *parms = Getattr(n, "parms"); // memory leak - ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t))); + ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n); // if (debugMode) { @@ -712,10 +712,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) { XXX Have to be a little more clever so that we can deal with struct A * - the * is getting lost. Is this still true? If so, will a SwigType_push() solve things? */ - Node *bbase = NewHash(); - - Setattr(bbase, "type", rettype); - Setattr(bbase, "name", NewString("result")); + Parm *bbase = NewParm(rettype, "result", n); String *returnTM = Swig_typemap_lookup("in", bbase, "result", f); if(returnTM) { String *tm = returnTM; diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 8d5ab4fae..a28256753 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -2590,7 +2590,7 @@ public: Parm *self; String *name = NewString("self"); String *type = NewString("VALUE"); - self = NewParm(type, name); + self = NewParm(type, name, n); Delete(type); Delete(name); Setattr(self, "lname", "Qnil"); @@ -2812,7 +2812,7 @@ public: ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("VALUE"); - p = NewParm(type, NewString("self")); + p = NewParm(type, NewString("self"), n); set_nextSibling(p, parms); parms = p; diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 7b2646b0e..f4c925206 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -803,7 +803,7 @@ int Swig_MethodToFunction(Node *n, String *classname, int flags, SwigType *direc SwigType_push(type, qualifier); } SwigType_add_pointer(type); - p = NewParm(type, "self"); + p = NewParm(type, "self", n); Setattr(p, "self", "1"); Setattr(p, "hidden","1"); /* @@ -1155,7 +1155,7 @@ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) type = NewString(classname); SwigType_add_pointer(type); - p = NewParm(type, "self"); + p = NewParm(type, "self", n); Setattr(p, "self", "1"); Setattr(p, "hidden", "1"); Setattr(p, "wrap:disown", "1"); @@ -1238,13 +1238,13 @@ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { t = NewString(classname); SwigType_add_pointer(t); - parms = NewParm(t, "self"); + parms = NewParm(t, "self", n); Setattr(parms, "self", "1"); Setattr(parms, "hidden","1"); Delete(t); ty = Swig_wrapped_member_var_type(type, varcref); - p = NewParm(ty, name); + p = NewParm(ty, name, n); Setattr(parms, "hidden", "1"); set_nextSibling(parms, p); @@ -1327,7 +1327,7 @@ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { t = NewString(classname); SwigType_add_pointer(t); - parms = NewParm(t, "self"); + parms = NewParm(t, "self", n); Setattr(parms, "self", "1"); Setattr(parms, "hidden","1"); Delete(t); @@ -1383,7 +1383,7 @@ int Swig_VarsetToFunction(Node *n, int flags) { type = Getattr(n, "type"); nname = SwigType_namestr(name); ty = Swig_wrapped_var_type(type, varcref); - parms = NewParm(ty, name); + parms = NewParm(ty, name, n); if (flags & CWRAP_EXTEND) { String *sname = Swig_name_set(name); diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index 6b0863ee4..494599adb 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -14,10 +14,25 @@ char cvsroot_parms_c[] = "$Id$"; /* ------------------------------------------------------------------------ * NewParm() * - * Create a new parameter from datatype 'type' and name 'name'. + * Create a new parameter from datatype 'type' and name 'name' copying + * the file and line number from the Node file_line_node. * ------------------------------------------------------------------------ */ -Parm *NewParm(SwigType *type, const_String_or_char_ptr name) { +Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node) { + Parm *p = NewParmWithoutFileLineInfo(type, name); + Setfile(p, Getfile(file_line_node)); + Setline(p, Getline(file_line_node)); + return p; +} + +/* ------------------------------------------------------------------------ + * NewParmWithoutFileLineInfo() + * + * Create a new parameter from datatype 'type' and name 'name' without any + * file / line numbering information. + * ------------------------------------------------------------------------ */ + +Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name) { Parm *p = NewHash(); set_nodeType(p, "parm"); if (type) { diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h index 8c4d50000..3e7ae8c38 100644 --- a/Source/Swig/swig.h +++ b/Source/Swig/swig.h @@ -123,7 +123,7 @@ extern "C" { extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms); extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms); extern SwigType *SwigType_pop_function(SwigType *t); - extern ParmList *SwigType_function_parms(SwigType *t); + extern ParmList *SwigType_function_parms(SwigType *t, Node *file_line_node); extern List *SwigType_split(const SwigType *t); extern String *SwigType_pop(SwigType *t); extern void SwigType_push(SwigType *t, SwigType *s); @@ -371,6 +371,7 @@ extern int ParmList_is_compactdefargs(ParmList *p); extern void Swig_typemap_clear_apply(ParmList *pattern); extern void Swig_typemap_debug(void); extern void Swig_typemap_search_debug_set(void); + extern void Swig_typemap_used_debug_set(void); extern String *Swig_typemap_lookup(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f); extern String *Swig_typemap_lookup_out(const_String_or_char_ptr tmap_method, Node *n, const_String_or_char_ptr lname, Wrapper *f, String *actioncode); diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h index 49ae7992e..d1209a5b2 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -11,7 +11,8 @@ /* $Id: swig.h 9629 2006-12-30 18:27:47Z beazley $ */ /* Individual parameters */ -extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name); +extern Parm *NewParm(SwigType *type, const_String_or_char_ptr name, Node *file_line_node); +extern Parm *NewParmWithoutFileLineInfo(SwigType *type, const_String_or_char_ptr name); extern Parm *CopyParm(Parm *p); /* Parameter lists */ diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c index b5ed37c0c..e018029a1 100644 --- a/Source/Swig/symbol.c +++ b/Source/Swig/symbol.c @@ -1807,7 +1807,7 @@ ParmList *Swig_symbol_template_defargs(Parm *parms, Parm *targs, Symtab *tscope, ntq = ty; } /* Printf(stderr,"value %s %s %s\n",value,ntr,ntq); */ - cp = NewParm(ntq, 0); + cp = NewParmWithoutFileLineInfo(ntq, 0); if (lp) set_nextSibling(lp, cp); else @@ -1884,7 +1884,7 @@ SwigType *Swig_symbol_template_deftype(const SwigType *type, Symtab *tscope) { String *tprefix = SwigType_templateprefix(base); String *targs = SwigType_templateargs(base); String *tsuffix = SwigType_templatesuffix(base); - ParmList *tparms = SwigType_function_parms(targs); + ParmList *tparms = SwigType_function_parms(targs, 0); Node *tempn = Swig_symbol_clookup_local(tprefix, tscope); if (!tempn && tsuffix && Len(tsuffix)) { tempn = Swig_symbol_clookup(tprefix, 0); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 3bb4e6909..a912b4948 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -18,9 +18,10 @@ char cvsroot_typemap_c[] = "$Id$"; #endif static int typemap_search_debug = 0; +static int typemaps_used_debug = 0; static int in_typemap_search_multi = 0; -static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f); +static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node); /* ----------------------------------------------------------------------------- * Typemaps are stored in a collection of nested hash tables. Something like @@ -266,6 +267,8 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par else typemap = NewStringf("typemap(%s) %s", actual_tmap_method, parms_str); + Setfile(tm2, Getfile(code)); + Setline(tm2, Getline(code)); Setattr(tm2, "code", code); Setattr(tm2, "type", type); Setattr(tm2, "typemap", typemap); @@ -871,6 +874,12 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList if (typemap_search_debug && (in_typemap_search_multi == 0)) debug_search_result_display(tm); + if (typemaps_used_debug && tm) { + String *typestr = SwigType_str(type, name); + Swig_diagnostic(Getfile(parms), Getline(parms), "Using %%%s for: %s\n", Getattr(tm, "typemap"), typestr); + assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ + Delete(typestr); + } return tm; } @@ -1345,6 +1354,13 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No tm = typemap_search(tmap_method, type, pname, qpname, &mtype, node); if (typemap_search_debug) debug_search_result_display(tm); + if (typemaps_used_debug && tm) { + String *typestr = SwigType_str(type, qpname ? qpname : pname); + Swig_diagnostic(Getfile(node), Getline(node), "Using %%%s for: %s\n", Getattr(tm, "typemap"), typestr); + assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */ + Delete(typestr); + } + Delete(qpname); qpname = 0; @@ -1450,9 +1466,9 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No } { - ParmList *parm_sublist = NewParm(type, pname); + ParmList *parm_sublist = NewParmWithoutFileLineInfo(type, pname); Setattr(parm_sublist, "lname", lname); - replace_embedded_typemap(s, parm_sublist, f); + replace_embedded_typemap(s, parm_sublist, f, tm); Delete(parm_sublist); } @@ -1730,7 +1746,7 @@ void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *p typemap_locals(s, locals, f, argnum); } - replace_embedded_typemap(s, firstp, f); + replace_embedded_typemap(s, firstp, f, tm); /* Replace the argument number */ sprintf(temp, "%d", argnum); @@ -1851,7 +1867,7 @@ static List *split_embedded_typemap(String *s) { * $typemap(in, (Foo a, int b)) # multi-argument typemap matching %typemap(in) (Foo a, int b) {...} * ----------------------------------------------------------------------------- */ -static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f) { +static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper *f, Node *file_line_node) { char *start = 0; while ((start = strstr(Char(s), "$TYPEMAP("))) { /* note $typemap capitalisation to $TYPEMAP hack */ @@ -1895,7 +1911,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper /* the second parameter might contain multiple sub-parameters for multi-argument * typemap matching, so split these parameters apart */ - to_match_parms = Swig_cparse_parms(Getitem(l, 1)); + to_match_parms = Swig_cparse_parms(Getitem(l, 1), file_line_node); if (to_match_parms) { Parm *p = to_match_parms; Parm *sub_p = parm_sublist; @@ -2029,3 +2045,13 @@ void Swig_typemap_search_debug_set(void) { typemap_search_debug = 1; } +/* ----------------------------------------------------------------------------- + * Swig_typemap_used_debug_set() + * + * Turn on typemaps used debug display + * ----------------------------------------------------------------------------- */ + +void Swig_typemap_used_debug_set(void) { + typemaps_used_debug = 1; +} + diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c index 8ff31bc0b..cbc2fd414 100644 --- a/Source/Swig/typeobj.c +++ b/Source/Swig/typeobj.c @@ -781,13 +781,15 @@ int SwigType_isfunction(SwigType *t) { return 0; } -ParmList *SwigType_function_parms(SwigType *t) { +/* Create a list of parameters from the type t, using the file_line_node Node for + * file and line numbering for the parameters */ +ParmList *SwigType_function_parms(SwigType *t, Node *file_line_node) { List *l = SwigType_parmlist(t); Hash *p, *pp = 0, *firstp = 0; Iterator o; for (o = First(l); o.item; o = Next(o)) { - p = NewParm(o.item, 0); + p = file_line_node ? NewParm(o.item, 0, file_line_node) : NewParmWithoutFileLineInfo(o.item, 0); if (!firstp) firstp = p; if (pp) { From b1ad69ade542140409fde0244585908f02eedee7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 5 Jan 2010 23:24:47 +0000 Subject: [PATCH 130/146] Fix -debug-tmsearch and -debug-tmused to show tthat the typemap came from a typemap copy or %apply git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11803 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/parms.c | 18 +++++++++++++ Source/Swig/swigparm.h | 1 + Source/Swig/typemap.c | 58 +++++++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c index 494599adb..90a072a7e 100644 --- a/Source/Swig/parms.c +++ b/Source/Swig/parms.c @@ -183,6 +183,24 @@ String *ParmList_str_defaultargs(ParmList *p) { return out; } +/* ----------------------------------------------------------------------------- + * ParmList_str_multibrackets() + * + * Generates a string of parameters including default arguments adding brackets + * if more than one parameter + * ----------------------------------------------------------------------------- */ + +String *ParmList_str_multibrackets(ParmList *p) { + String *out; + String *parm_str = ParmList_str_defaultargs(p); + if (ParmList_len(p) > 1) + out = NewStringf("(%s)", parm_str); + else + out = NewStringf("%s", parm_str); + Delete(parm_str); + return out; +} + /* --------------------------------------------------------------------- * ParmList_protostr() * diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h index d1209a5b2..4a928999e 100644 --- a/Source/Swig/swigparm.h +++ b/Source/Swig/swigparm.h @@ -25,6 +25,7 @@ extern int ParmList_has_defaultargs(ParmList *p); /* Output functions */ extern String *ParmList_str(ParmList *); extern String *ParmList_str_defaultargs(ParmList *); +extern String *ParmList_str_multibrackets(ParmList *); extern String *ParmList_protostr(ParmList *); diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index a912b4948..2a77bb06f 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -40,7 +40,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper * "type" - Typemap type * "pname" - Parameter name * "code" - Typemap code - * "typemap" - Descriptive text describing the actual map + * "source" - Source directive (%apply or %typemap) for the typemap * "locals" - Local variables (if any) * "kwargs" - Typemap attributes * @@ -50,7 +50,7 @@ static void replace_embedded_typemap(String *s, ParmList *parm_sublist, Wrapper * "type" - r.int * "pname" - my_int * "code" - $1 = $input; - * "typemap" - typemap(in) int &my_int + * "source" - typemap(in) int &my_int * "locals" - int tmp * "kwargs" - warning="987:my typemap warning", foo=123 * @@ -180,7 +180,7 @@ Hash *Swig_typemap_pop_scope() { * Internal implementation for Swig_typemap_register() * ----------------------------------------------------------------------------- */ -static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, const_String_or_char_ptr actual_tmap_method, ParmList *parmlist_start) { +static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs, String *source_directive) { Hash *tm; Hash *tm1; Hash *tm2; @@ -252,26 +252,20 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par if (np) { /* Make an entirely new typemap method key */ String *multi_tmap_method = NewStringf("%s-%s+%s:", tmap_method, type, pname); - /* Now reregister on the remaining arguments */ - typemap_register(multi_tmap_method, np, code, locals, kwargs, actual_tmap_method, parmlist_start); - /* Setattr(tm2,multi_tmap_method,multi_tmap_method); */ + /* Now reregister on the remaining arguments */ + typemap_register(multi_tmap_method, np, code, locals, kwargs, source_directive); + Delete(multi_tmap_method); } else { ParmList *clocals = CopyParmList(locals); ParmList *ckwargs = CopyParmList(kwargs); - String *parms_str = ParmList_str(parmlist_start); - String *typemap; - if (ParmList_len(parmlist_start) > 1) - typemap = NewStringf("typemap(%s) (%s)", actual_tmap_method, parms_str); - else - typemap = NewStringf("typemap(%s) %s", actual_tmap_method, parms_str); Setfile(tm2, Getfile(code)); Setline(tm2, Getline(code)); Setattr(tm2, "code", code); Setattr(tm2, "type", type); - Setattr(tm2, "typemap", typemap); + Setattr(tm2, "source", source_directive); if (pname) { Setattr(tm2, "pname", pname); } @@ -280,9 +274,6 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par Delete(clocals); Delete(ckwargs); - - Delete(parms_str); - Delete(typemap); } } @@ -293,7 +284,13 @@ static void typemap_register(const_String_or_char_ptr tmap_method, ParmList *par * ----------------------------------------------------------------------------- */ void Swig_typemap_register(const_String_or_char_ptr tmap_method, ParmList *parms, const_String_or_char_ptr code, ParmList *locals, ParmList *kwargs) { - typemap_register(tmap_method, parms, code, locals, kwargs, tmap_method, parms); + String *parms_str = ParmList_str_multibrackets(parms); + String *source_directive = NewStringf("typemap(%s) %s", tmap_method, parms_str); + + typemap_register(tmap_method, parms, code, locals, kwargs, source_directive); + + Delete(source_directive); + Delete(parms_str); } /* ----------------------------------------------------------------------------- @@ -361,9 +358,16 @@ int Swig_typemap_copy(const_String_or_char_ptr tmap_method, ParmList *srcparms, Delete(tm_methods); if (!p && tm) { - /* Got some kind of match */ - Swig_typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs")); + String *parms_str = ParmList_str_multibrackets(parms); + String *srcparms_str = ParmList_str_multibrackets(srcparms); + String *source_directive = NewStringf("typemap(%s) %s = %s", tmap_method, parms_str, srcparms_str); + + typemap_register(tmap_method, parms, Getattr(tm, "code"), Getattr(tm, "locals"), Getattr(tm, "kwargs"), source_directive); + + Delete(source_directive); + Delete(srcparms_str); + Delete(parms_str); return 0; } ts--; @@ -529,9 +533,17 @@ int Swig_typemap_apply(ParmList *src, ParmList *dest) { locals = Getattr(sm1, "locals"); kwargs = Getattr(sm1, "kwargs"); if (code) { + String *src_str = ParmList_str_multibrackets(src); + String *dest_str = ParmList_str_multibrackets(dest); + String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str); + Replace(nkey, dsig, "", DOH_REPLACE_ANY); Replace(nkey, "tmap:", "", DOH_REPLACE_ANY); - Swig_typemap_register(nkey, dest, code, locals, kwargs); + typemap_register(nkey, dest, code, locals, kwargs, source_directive); + + Delete(source_directive); + Delete(dest_str); + Delete(src_str); } } Delete(nkey); @@ -616,7 +628,7 @@ static SwigType *strip_arrays(SwigType *type) { static void debug_search_result_display(Node *tm) { if (tm) - Printf(stdout, " Using: %%%s\n", Getattr(tm, "typemap")); + Printf(stdout, " Using: %%%s\n", Getattr(tm, "source")); else Printf(stdout, " None found\n"); } @@ -876,7 +888,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList debug_search_result_display(tm); if (typemaps_used_debug && tm) { String *typestr = SwigType_str(type, name); - Swig_diagnostic(Getfile(parms), Getline(parms), "Using %%%s for: %s\n", Getattr(tm, "typemap"), typestr); + Swig_diagnostic(Getfile(parms), Getline(parms), "Using %%%s for: %s\n", Getattr(tm, "source"), typestr); assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ Delete(typestr); } @@ -1356,7 +1368,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No debug_search_result_display(tm); if (typemaps_used_debug && tm) { String *typestr = SwigType_str(type, qpname ? qpname : pname); - Swig_diagnostic(Getfile(node), Getline(node), "Using %%%s for: %s\n", Getattr(tm, "typemap"), typestr); + Swig_diagnostic(Getfile(node), Getline(node), "Using %%%s for: %s\n", Getattr(tm, "source"), typestr); assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */ Delete(typestr); } From 65a52707f0e7860e24a62c455cfd7edf04d3d1f1 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 5 Jan 2010 23:44:42 +0000 Subject: [PATCH 131/146] Minor fix for -debug-tmused and multi-argument typemaps git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11804 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/typemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 2a77bb06f..e27b44f24 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -886,7 +886,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList if (typemap_search_debug && (in_typemap_search_multi == 0)) debug_search_result_display(tm); - if (typemaps_used_debug && tm) { + if (typemaps_used_debug && (in_typemap_search_multi == 0) && tm) { String *typestr = SwigType_str(type, name); Swig_diagnostic(Getfile(parms), Getline(parms), "Using %%%s for: %s\n", Getattr(tm, "source"), typestr); assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ From eb2e4a59d02a98be13aab1cb040c64cec8bb177d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 8 Jan 2010 08:09:41 +0000 Subject: [PATCH 132/146] minor tidy up git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11805 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/typemap.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index e27b44f24..86688b153 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -662,11 +662,9 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type ts = tm_scope; if (debug_display) { - String *empty_string = NewStringEmpty(); - String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : (cname ? cname : empty_string)); + String *typestr = SwigType_str(type, cqualifiedname ? cqualifiedname : cname); Swig_diagnostic(Getfile(node), Getline(node), "Searching for a suitable '%s' typemap for: %s\n", tmap_method, typestr); Delete(typestr); - Delete(empty_string); } while (ts >= 0) { ctype = type; @@ -824,15 +822,12 @@ static Hash *typemap_search(const_String_or_char_ptr tmap_method, SwigType *type result = backup; ret_result: - if (noarrays) - Delete(noarrays); - if (primitive) - Delete(primitive); + Delete(noarrays); + Delete(primitive); if ((unstripped) && (unstripped != type)) Delete(unstripped); - if (matchtype) { + if (matchtype) *matchtype = Copy(ctype); - } if (type != ctype) Delete(ctype); return result; From d82621ca351e00f2fb5817ab89c3391cc03df325 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 8 Jan 2010 18:42:31 +0000 Subject: [PATCH 133/146] Fix SwigType_str so that should the name contain type information it is displayed correctly - noticeable in -debug-tmsearch and -debug-tmused git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11806 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/stype.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index aa5d448a3..707232558 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -550,7 +550,10 @@ String *SwigType_str(SwigType *s, const_String_or_char_ptr id) { int nelements, i; if (id) { - result = NewString(id); + /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */ + String *id_str = NewString(id); /* unfortunate copy due to current const limitations */ + result = SwigType_str(id_str, 0); + Delete(id_str); } else { result = NewStringEmpty(); } From ff1cc536a5883f1bbfeb0a8005a0874e1dbccfb6 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 8 Jan 2010 18:46:41 +0000 Subject: [PATCH 134/146] Very minor perf tweak git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11807 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/mzscheme.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx index 77339d325..1641b719a 100644 --- a/Source/Modules/mzscheme.cxx +++ b/Source/Modules/mzscheme.cxx @@ -764,7 +764,7 @@ public: Printv(access_mem, "(ptr)->", name, NIL); if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { Printv(convert_tab, tab4, "fields[i++] = ", NIL); - Printv(convert_tab, "_swig_convert_struct_", swigtype, "((", SwigType_str(ctype_ptr, ""), ")&((ptr)->", name, "));\n", NIL); + Printv(convert_tab, "_swig_convert_struct_", swigtype, "((", SwigType_str(ctype_ptr, 0), ")&((ptr)->", name, "));\n", NIL); } else if ((tm = Swig_typemap_lookup("varout", n, access_mem, 0))) { Replaceall(tm, "$result", "fields[i++]"); Printv(convert_tab, tm, "\n", NIL); From 0f93753a082caa669962a3b9d1f24265ce5d43d7 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 00:24:25 +0000 Subject: [PATCH 135/146] Improve -debug-tmused output so that the typemap method name is always shown - it was missing when the typemap came from a %apply. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11808 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 77 ++++++++++++++++++++++++++++++++++++---- Source/Swig/typemap.c | 4 +-- 2 files changed, 72 insertions(+), 9 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 9fa487ab4..cd4c074f1 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -681,8 +681,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.

    @@ -1557,19 +1558,81 @@ example.h:39: Searching for a suitable 'in' typemap for: char *buffer

    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 below is for the example code at the start of this section on debugging. +The output displays the type, and name if present, the typemap method in brackets and then the actual typemap used. +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: Using %typemap(in) SWIGTYPE [] for: Row4 rows[10]
    -example.h:3: Using %typemap(typecheck) SWIGTYPE * for: Row4 rows[10]
    -example.h:3: Using %typemap(freearg) SWIGTYPE [] for: Row4 rows[10]
    -example.h:3: Using %typemap(out) void for: void foo
    +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 ... */
    +  }
    +}
    +
    +%apply SWIGTYPE * { const char* val, const char* another_value } // use default pointer handling instead of strings
    +
    +%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

    diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index 86688b153..f0bf9eef3 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -883,7 +883,7 @@ static Hash *typemap_search_multi(const_String_or_char_ptr tmap_method, ParmList debug_search_result_display(tm); if (typemaps_used_debug && (in_typemap_search_multi == 0) && tm) { String *typestr = SwigType_str(type, name); - Swig_diagnostic(Getfile(parms), Getline(parms), "Using %%%s for: %s\n", Getattr(tm, "source"), typestr); + Swig_diagnostic(Getfile(parms), Getline(parms), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); assert(Getfile(parms) && Len(Getfile(parms)) > 0); /* Missing file and line numbering information */ Delete(typestr); } @@ -1363,7 +1363,7 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No debug_search_result_display(tm); if (typemaps_used_debug && tm) { String *typestr = SwigType_str(type, qpname ? qpname : pname); - Swig_diagnostic(Getfile(node), Getline(node), "Using %%%s for: %s\n", Getattr(tm, "source"), typestr); + Swig_diagnostic(Getfile(node), Getline(node), "Typemap for %s (%s) : %%%s\n", typestr, tmap_method, Getattr(tm, "source")); assert(Getfile(node) && Len(Getfile(node)) > 0); /* Missing file and line numbering information */ Delete(typestr); } From 1b3ca38023342b017f009c5e3f4f025497faa5ff Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 00:42:01 +0000 Subject: [PATCH 136/146] 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. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11809 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 12 ++++++++++++ Source/Swig/error.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index cb6c9f9c0..2016a1e53 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,18 @@ Version 1.3.41 (in progress) ============================ +2010-01-09: 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. + + *** POTENTIAL INCOMPATIBILITY *** + 2010-01-03: wsfulton Fix missing file/line numbers for typemap warnings and in output from the -debug-tmsearch/-debug-tmused options. diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 0f4728954..48a54f1d3 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -256,7 +256,7 @@ void Swig_error_msg_format(ErrorMessageFormat format) { fmt_eof = "%s:EOF"; } - sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning); + sprintf(wrn_wnum_fmt, "%s: %s %%d: ", fmt_line, warning); sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); From 43e07da0f645e364e8f8d49ec0b86e5bf0d2b1d4 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 00:56:02 +0000 Subject: [PATCH 137/146] Update warnings to newer slightly modified warning format git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11810 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/CSharp.html | 2 +- Doc/Manual/Java.html | 2 +- Doc/Manual/Lua.html | 2 +- Doc/Manual/Modules.html | 2 +- Doc/Manual/Python.html | 2 +- Doc/Manual/Ruby.html | 4 ++-- Doc/Manual/SWIGPlus.html | 8 ++++---- Doc/Manual/Tcl.html | 2 +- Doc/Manual/Typemaps.html | 4 ++-- Doc/Manual/Warnings.html | 4 ++-- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index a4bb9e2d1..324be63ec 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -987,7 +987,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.
     
    diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html index fc5646c10..7ab997a11 100644 --- a/Doc/Manual/Java.html +++ b/Doc/Manual/Java.html @@ -1772,7 +1772,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.
     
    diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html index e66c1c7f3..cc7663cd4 100644 --- a/Doc/Manual/Lua.html +++ b/Doc/Manual/Lua.html @@ -684,7 +684,7 @@ 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)
    +example.i:12: Warning 509: Overloaded spam(short) is shadowed by spam(int)
     at example.i:11.
     

    diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html index 1b628f802..406bdeaef 100644 --- a/Doc/Manual/Modules.html +++ b/Doc/Manual/Modules.html @@ -138,7 +138,7 @@ base class's methods. Typically you will get a warning when the module name is m

    -derived_module.i:8: Warning(401): Base class 'base' ignored - unknown module name for base. Either import 
    +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.
     
    diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index efa500c2d..7ed0da658 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -1710,7 +1710,7 @@ 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)
    +example.i:12: Warning 509: Overloaded spam(short) is shadowed by spam(int)
     at example.i:11.
     
    diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 643a6daec..05457a906 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -1559,7 +1559,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.
    @@ -1810,7 +1810,7 @@ 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 spam(short) is shadowed by spam(int)
    at example.i:11.
    diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 8e051a0ec..1194a4c26 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -1616,7 +1616,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.
     
    @@ -2031,7 +2031,7 @@ 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 foo(long) is shadowed by foo(int) at example.i:3.
     
    @@ -2041,7 +2041,7 @@ 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. Method foo(int)
     at example.i:3 used.
     
    @@ -2091,7 +2091,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').
     
    diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index 8b8c74dc0..11d4b7010 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -1502,7 +1502,7 @@ 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)
    +example.i:12: Warning 509: Overloaded spam(short) is shadowed by spam(int)
     at example.i:11.
     
    diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index cd4c074f1..863d43f1f 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -3093,7 +3093,7 @@ 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 
    +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: 
     try {
       result = XX::create();
    @@ -3115,7 +3115,7 @@ 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 
    +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.
     
    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 15f3aa9d2..fd5d4916a 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -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)
     
    From 5a3ba0d607132bfe78c5c23b3d8d2694a9250957 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 17:20:11 +0000 Subject: [PATCH 138/146] Modify -debug-tags output to use standard file name/line reporting so that editors can easily navigate to the appropriate line git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11811 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 10 ++++++++++ Source/Swig/tree.c | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 2016a1e53..844092b38 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,16 @@ Version 1.3.41 (in progress) ============================ +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-09: 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 diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c index 14d231afa..98ae9ed16 100644 --- a/Source/Swig/tree.c +++ b/Source/Swig/tree.c @@ -30,7 +30,7 @@ void Swig_print_tags(DOH *obj, DOH *root) { croot = root; while (obj) { - Printf(stdout, "%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj)); + Swig_diagnostic(Getfile(obj), Getline(obj), "%s . %s\n", croot, nodeType(obj)); cobj = firstChild(obj); if (cobj) { newroot = NewStringf("%s . %s", croot, nodeType(obj)); @@ -268,7 +268,7 @@ void Swig_require(const char *ns, Node *n, ...) { } obj = Getattr(n, name); if (!opt && !obj) { - Printf(stderr, "%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", Getfile(n), Getline(n), name, nodeType(n)); + Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", name, nodeType(n)); assert(obj); } if (!obj) From a541f7c2030e5601bd717b68c6399234181fcd59 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 19:26:34 +0000 Subject: [PATCH 139/146] Change -debug-template to use Swig_diagnostic for file/line display git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11812 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/CParse/cscanner.c | 4 ++-- Source/CParse/templ.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c index b5c485f5d..a98bfb47f 100644 --- a/Source/CParse/cscanner.c +++ b/Source/CParse/cscanner.c @@ -135,7 +135,7 @@ static void scanner_locator(String *loc) { break; Putc(c, fn); } - /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line); */ + /* Swig_diagnostic(cparse_file, cparse_line, "Scanner_set_location\n"); */ Scanner_set_location(scan,cparse_file,cparse_line); Delete(fn); } @@ -502,7 +502,7 @@ int yylex(void) { l = yylook(); - /* Printf(stdout, "%s:%d:::%d: '%s'\n", cparse_file, cparse_line, l, Scanner_text(scan)); */ + /* Swig_diagnostic(cparse_file, cparse_line, ":::%d: '%s'\n", l, Scanner_text(scan)); */ if (l == NONID) { last_id = 1; diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c index c3cc115c6..91a1d31ff 100644 --- a/Source/CParse/templ.c +++ b/Source/CParse/templ.c @@ -512,7 +512,8 @@ static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) { if (template_debug) { tname = Copy(name); SwigType_add_template(tname, tparms); - Printf(stdout, "\n%s:%d: template_debug: Searching for match to: '%s'\n", cparse_file, cparse_line, tname); + Printf(stdout, "\n"); + Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname); Delete(tname); tname = 0; } From e554146aacf1e0fe1b79aec35cc433d711cc8a85 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 19:34:43 +0000 Subject: [PATCH 140/146] Fix a few inconsistencies in reporting of file/line numberings including modifying the overload warnings to now be two line warnings git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11813 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++ Doc/Manual/Lua.html | 4 +- Doc/Manual/Python.html | 4 +- Doc/Manual/Ruby.html | 6 ++- Doc/Manual/SWIGPlus.html | 6 ++- Doc/Manual/Tcl.html | 4 +- Doc/Manual/Warnings.html | 10 ++-- Source/Modules/allegrocl.cxx | 34 ++++++------- Source/Modules/lang.cxx | 2 +- Source/Modules/overload.cxx | 32 +++++++------ Source/Modules/r.cxx | 92 ++++++++++++++++++------------------ 11 files changed, 106 insertions(+), 92 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 844092b38..ebb8ae54e 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,10 @@ Version 1.3.41 (in progress) ============================ +2010-01-10: wsfulton + Fix a few inconsistencies in reporting of file/line numberings including modifying + the overload warnings 509, 512, 516 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. diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html index cc7663cd4..b236ab9f7 100644 --- a/Doc/Manual/Lua.html +++ b/Doc/Manual/Lua.html @@ -684,8 +684,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: diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html index 7ed0da658..b22a7e30e 100644 --- a/Doc/Manual/Python.html +++ b/Doc/Manual/Python.html @@ -1710,8 +1710,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).
     
    diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html index 05457a906..3b1e5c45c 100644 --- a/Doc/Manual/Ruby.html +++ b/Doc/Manual/Ruby.html @@ -1810,7 +1810,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).
    +
    +
    diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html index 1194a4c26..bd8a7ab5d 100644 --- a/Doc/Manual/SWIGPlus.html +++ b/Doc/Manual/SWIGPlus.html @@ -2031,7 +2031,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).
     
    @@ -2041,7 +2042,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.
     
    diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html index 11d4b7010..b37df2853 100644 --- a/Doc/Manual/Tcl.html +++ b/Doc/Manual/Tcl.html @@ -1502,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).
     
    diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index fd5d4916a..26707b1a0 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -494,22 +494,22 @@ 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.
    • 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. +
    • 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 diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx index 2f1b07296..bb5070a70 100644 --- a/Source/Modules/allegrocl.cxx +++ b/Source/Modules/allegrocl.cxx @@ -1900,14 +1900,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", - Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n", - Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms), - Getattr(nodes[i].n, "name"), ParmList_errorstr(nodes[i].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } } nodes[j].error = 1; @@ -1916,14 +1917,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", - Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n", - Getattr(nodes[j].n, "name"), ParmList_errorstr(nodes[j].parms), - Getattr(nodes[i].n, "name"), ParmList_errorstr(nodes[i].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } } nodes[j].error = 1; @@ -1937,15 +1939,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s is shadowed by %s at %s:%d.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), + "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } nodes[j].error = 1; } diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index ea1f09133..3228a2cc1 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -175,7 +175,7 @@ int Dispatcher::emit_one(Node *n) { } else if (strcmp(tag, "types") == 0) { ret = typesDirective(n); } else { - Printf(stderr, "%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag); + Swig_error(input_file, line_number, "Unrecognized parse tree node type '%s'\n", tag); ret = SWIG_ERROR; } if (wrn) { diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx index 79656517a..14c677783 100644 --- a/Source/Modules/overload.cxx +++ b/Source/Modules/overload.cxx @@ -223,13 +223,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Non-const method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } } nodes[j].error = 1; @@ -238,13 +240,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Non-const method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } } nodes[j].error = 1; @@ -258,15 +262,15 @@ static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s is shadowed by %s at %s:%d.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), + "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); } nodes[j].error = 1; } diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index fec2330bd..13b832752 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1486,8 +1486,8 @@ static List * Swig_overload_rank(Node *n, } if (!differ) { /* See if declarations differ by const only */ - String *d1 = Getattr(nodes[i].n,"decl"); - String *d2 = Getattr(nodes[j].n,"decl"); + String *d1 = Getattr(nodes[i].n, "decl"); + String *d2 = Getattr(nodes[j].n, "decl"); if (d1 && d2) { String *dq1 = Copy(d1); String *dq2 = Copy(d2); @@ -1497,49 +1497,47 @@ static List * Swig_overload_rank(Node *n, if (SwigType_isconst(d2)) { Delete(SwigType_pop(dq2)); } - if (Strcmp(dq1,dq2) == 0) { - + if (Strcmp(dq1, dq2) == 0) { + if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { - if (script_lang_wrapping) { - // Swap nodes so that the const method gets ignored (shadowed by the non-const method) - Overloaded t = nodes[i]; - nodes[i] = nodes[j]; - nodes[j] = t; - } + if (script_lang_wrapping) { + // Swap nodes so that the const method gets ignored (shadowed by the non-const method) + Overloaded t = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = t; + } differ = 1; if (!nodes[j].error) { - if (script_lang_wrapping) { + if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", - Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n", - Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms), - Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].parms), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); + } else { + if (!Getattr(nodes[j].n, "overload:ignore")) + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } } nodes[j].error = 1; } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { differ = 1; if (!nodes[j].error) { - if (script_lang_wrapping) { + if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", - Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n", - Getattr(nodes[j].n,"name"), ParmList_errorstr(nodes[j].parms), - Getattr(nodes[i].n,"name"), ParmList_errorstr(nodes[i].parms), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } - } + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[i].n), Getline(nodes[i].n), + "using non-const method %s instead.\n", Swig_name_decl(nodes[i].n)); + } else { + if (!Getattr(nodes[j].n, "overload:ignore")) + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } + } nodes[j].error = 1; } } @@ -1549,18 +1547,18 @@ static List * Swig_overload_rank(Node *n, } if (!differ) { if (!nodes[j].error) { - if (script_lang_wrapping) { - Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s is shadowed by %s at %s:%d.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } else { - if (!Getattr(nodes[j].n, "overload:ignore")) - Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), - "Overloaded method %s ignored. Method %s at %s:%d used.\n", - Swig_name_decl(nodes[j].n), Swig_name_decl(nodes[i].n), - Getfile(nodes[i].n), Getline(nodes[i].n)); - } + if (script_lang_wrapping) { + Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded method %s effectively ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[i].n), Getline(nodes[i].n), + "as it is shadowed by %s.\n", Swig_name_decl(nodes[i].n)); + } else { + if (!Getattr(nodes[j].n, "overload:ignore")) + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), + "Overloaded method %s ignored,\n", Swig_name_decl(nodes[j].n)); + Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[i].n), Getline(nodes[i].n), + "using %s instead.\n", Swig_name_decl(nodes[i].n)); + } nodes[j].error = 1; } } From 71c8881ddac38462cbdb8f40ba27ecf1c225abeb Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 20:00:27 +0000 Subject: [PATCH 141/146] Some more file and line numbering reporting consistency fixes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11814 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Typemaps.html | 8 ++++---- Doc/Manual/Warnings.html | 6 +++--- Source/Swig/typemap.c | 9 ++++++--- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html index 863d43f1f..7fe932828 100644 --- a/Doc/Manual/Typemaps.html +++ b/Doc/Manual/Typemaps.html @@ -3093,8 +3093,8 @@ 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) {
      @@ -3115,8 +3115,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 optimal attribute usage in
      +example.i:7: Warning 475: the out typemap.
       
      diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index 26707b1a0..cd65d2cee 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -484,8 +484,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.
    @@ -501,7 +501,7 @@ example.i(4): Syntax error in input.
  • 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. +
  • 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. diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c index f0bf9eef3..ec44cd015 100644 --- a/Source/Swig/typemap.c +++ b/Source/Swig/typemap.c @@ -1431,7 +1431,8 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No } } if (!optimal_substitution) { - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute in the out typemap at %s:%d ignored as the following cannot be used to generate optimal code: %s\n", Swig_name_decl(node), Getfile(s), Getline(s), clname); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node)); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", clname); Delattr(node, "tmap:out:optimal"); } } else { @@ -1465,8 +1466,10 @@ static String *Swig_typemap_lookup_impl(const_String_or_char_ptr tmap_method, No } else { num_substitutions = typemap_replace_vars(s, locals, type, type, pname, (char *) lname, 1); } - if (optimal_substitution && num_substitutions > 1) - Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in the out typemap at %s:%d.\n", Swig_name_decl(node), Getfile(s), Getline(s)); + if (optimal_substitution && num_substitutions > 1) { + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to optimal attribute usage in\n", Swig_name_decl(node)); + Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "the out typemap.\n"); + } if (locals && f) { typemap_locals(s, locals, f, -1); From c1a302cbf2f37cd84d8ac0e24c15149ac0516b97 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 20:01:16 +0000 Subject: [PATCH 142/146] Some more file and line numbering reporting consistency fixes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11815 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index ebb8ae54e..d22ea4e7b 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -3,7 +3,7 @@ Version 1.3.41 (in progress) 2010-01-10: wsfulton Fix a few inconsistencies in reporting of file/line numberings including modifying - the overload warnings 509, 512, 516 to now be two line warnings. + 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 From 4a9d73e5327f599321522ec221904eebd2ca9482 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sat, 9 Jan 2010 20:06:27 +0000 Subject: [PATCH 143/146] Warning text update git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11816 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Warnings.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index cd65d2cee..c24a4364a 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -405,7 +405,7 @@ example.i(4): Syntax error in input.
  • 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. From 237f64a6e13ee31362f2a341cbaec48befcb7cc4 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 10 Jan 2010 22:37:28 +0000 Subject: [PATCH 144/146] subtle fix to -Fmicrosoft format adding in missing space git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11818 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 27 +++++++++++++++------------ Source/Swig/error.c | 2 +- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index d22ea4e7b..f435f9cb8 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,21 @@ Version 1.3.41 (in progress) ============================ +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. @@ -15,18 +30,6 @@ Version 1.3.41 (in progress) /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-09: 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. - - *** POTENTIAL INCOMPATIBILITY *** - 2010-01-03: wsfulton Fix missing file/line numbers for typemap warnings and in output from the -debug-tmsearch/-debug-tmused options. diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 48a54f1d3..24e15e933 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -247,7 +247,7 @@ void Swig_error_msg_format(ErrorMessageFormat format) { by now a switch is used to translated into one. */ switch (format) { case EMF_MICROSOFT: - fmt_line = "%s(%d)"; + fmt_line = "%s(%d) "; fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */ break; case EMF_STANDARD: From 70d2bb62afe1bd8a6d304814a78489413b208e16 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 10 Jan 2010 22:41:10 +0000 Subject: [PATCH 145/146] subtle fix to -Fmicrosoft format adding in missing space git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11819 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Warnings.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html index c24a4364a..5409248c9 100644 --- a/Doc/Manual/Warnings.html +++ b/Doc/Manual/Warnings.html @@ -344,7 +344,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

    From 3b06d6e44277ec1f175f7a41053eab2371d9b664 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Sun, 10 Jan 2010 22:51:19 +0000 Subject: [PATCH 146/146] subtle fix to -Fmicrosoft format adding in missing space git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@11820 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Swig/error.c b/Source/Swig/error.c index 24e15e933..3271f93fc 100644 --- a/Source/Swig/error.c +++ b/Source/Swig/error.c @@ -248,7 +248,7 @@ void Swig_error_msg_format(ErrorMessageFormat format) { switch (format) { case EMF_MICROSOFT: fmt_line = "%s(%d) "; - fmt_eof = "%s(999999)"; /* Is there a special character for EOF? Just use a large number. */ + fmt_eof = "%s(999999) "; /* Is there a special character for EOF? Just use a large number. */ break; case EMF_STANDARD: default: