From 98441fc6ad6d6097c98baf28b54c7059045806b6 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Sun, 17 Oct 2010 07:33:58 +0000 Subject: [PATCH 001/317] [R] Fix failure in overloaded functions which was breaking QuantLib-SWIG git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12282 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ++++ Source/Modules/r.cxx | 14 +++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES.current b/CHANGES.current index a5f149421..65489354c 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,10 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.2 (in progress) =========================== +2010-10-17: drjoe + [R] Fix failure in overloaded functions which was breaking + QuantLib-SWIG + 2010-10-14: olly [PHP] Allow compilation on non-conforming Microsoft C++ compilers which don't accept: return function_returning_void(); diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 749797c78..61cbcdd79 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1603,6 +1603,16 @@ void R::dispatchFunction(Node *n) { j == 0 ? "" : " && ", j+1); } + else if (DohStrcmp(tm,"integer")==0) { + Printf(f->code, "%s(is.integer(argv[[%d]]) || is.numeric(argv[[%d]]))", + j == 0 ? "" : " && ", + j+1, j+1); + } + else if (DohStrcmp(tm,"character")==0) { + Printf(f->code, "%sis.character(argv[[%d]])", + j == 0 ? "" : " && ", + j+1); + } else { Printf(f->code, "%sextends(argtypes[%d], '%s')", j == 0 ? "" : " && ", @@ -1617,7 +1627,9 @@ void R::dispatchFunction(Node *n) { } } if (cur_args != -1) { - Printv(f->code, "}", NIL); + Printf(f->code, "} else {\n" + "stop(\"cannot find overloaded function for %s\");\n" + "}", sfname); } Printv(f->code, ";\nf(...)", NIL); Printv(f->code, ";\n}", NIL); From f77ccd81d5c0b09ba0d99833e60945edf381f2f5 Mon Sep 17 00:00:00 2001 From: Joseph Wang Date: Sun, 17 Oct 2010 09:35:34 +0000 Subject: [PATCH 002/317] [R] Improve error message for missing argtypes git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12283 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/r.cxx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx index 61cbcdd79..8eb784c68 100644 --- a/Source/Modules/r.cxx +++ b/Source/Modules/r.cxx @@ -1628,7 +1628,8 @@ void R::dispatchFunction(Node *n) { } if (cur_args != -1) { Printf(f->code, "} else {\n" - "stop(\"cannot find overloaded function for %s\");\n" + "stop(\"cannot find overloaded function for %s with argtypes (\"," + "toString(argtypes),\")\");\n" "}", sfname); } Printv(f->code, ";\nf(...)", NIL); From 383230d734280c8cbd8ca159d30fe5677134883d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Mon, 18 Oct 2010 18:59:57 +0000 Subject: [PATCH 003/317] minor clarification about %{ %} blocks git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12284 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/Introduction.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html index 3bac9484e..24579d946 100644 --- a/Doc/Manual/Introduction.html +++ b/Doc/Manual/Introduction.html @@ -195,9 +195,9 @@ extern int my_mod(int n, int m);

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

2.3.2 The swig command

From 28e277f8c59322fd1041bb3cc68c5ed779bff407 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Tue, 19 Oct 2010 06:31:31 +0000 Subject: [PATCH 004/317] Fix typo "the the" -> "the" git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12285 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/octave/octcontainer.swg | 3 +-- Lib/python/pycontainer.swg | 3 +-- Lib/ruby/rubycontainer.swg | 3 +-- Source/Swig/cwrap.c | 2 +- Source/Swig/stype.c | 2 +- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg index 6613fcfff..4f14ccef1 100644 --- a/Lib/octave/octcontainer.swg +++ b/Lib/octave/octcontainer.swg @@ -4,8 +4,7 @@ * Octave cell <-> C++ container wrapper * * This wrapper, and its iterator, allows a general use (and reuse) of - * the the mapping between C++ and Octave, thanks to the C++ - * templates. + * the mapping between C++ and Octave, thanks to the C++ templates. * * Of course, it needs the C++ compiler to support templates, but * since we will use this wrapper with the STL containers, that should diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg index efca86cf1..40506e15b 100644 --- a/Lib/python/pycontainer.swg +++ b/Lib/python/pycontainer.swg @@ -4,8 +4,7 @@ * Python sequence <-> C++ container wrapper * * This wrapper, and its iterator, allows a general use (and reuse) of - * the the mapping between C++ and Python, thanks to the C++ - * templates. + * the mapping between C++ and Python, thanks to the C++ templates. * * Of course, it needs the C++ compiler to support templates, but * since we will use this wrapper with the STL containers, that should diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg index fa4b619f9..f643e84b3 100644 --- a/Lib/ruby/rubycontainer.swg +++ b/Lib/ruby/rubycontainer.swg @@ -4,8 +4,7 @@ * Ruby sequence <-> C++ container wrapper * * This wrapper, and its iterator, allows a general use (and reuse) of - * the the mapping between C++ and Ruby, thanks to the C++ - * templates. + * the mapping between C++ and Ruby, thanks to the C++ templates. * * Of course, it needs the C++ compiler to support templates, but * since we will use this wrapper with the STL containers, that should diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c index 799d434a6..28401f89f 100644 --- a/Source/Swig/cwrap.c +++ b/Source/Swig/cwrap.c @@ -216,7 +216,7 @@ int Swig_cargs(Wrapper *w, ParmList *p) { SwigType_del_reference(tvalue); tycode = SwigType_type(tvalue); if (tycode != T_USER) { - /* plain primitive type, we copy the the def value */ + /* plain primitive type, we copy the def value */ String *lstr = SwigType_lstr(tvalue, defname); defvalue = NewStringf("%s = %s", lstr, qvalue); Delete(lstr); diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c index a13f87cfc..742b6232a 100644 --- a/Source/Swig/stype.c +++ b/Source/Swig/stype.c @@ -366,7 +366,7 @@ SwigType *SwigType_default_create(SwigType *ty) { * SwigType_default_create() before calling this function. * * Example deductions (matching the examples described in SwigType_default_create), - * where the the most specialized matches are highest in the list: + * where the most specialized matches are highest in the list: * * a(ANY).a(ANY).SWIGTYPE * a(ANY).a().SWIGTYPE From 43794d90cdcaa6a4c477ef331c37e3076951c800 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 29 Oct 2010 10:22:03 +0000 Subject: [PATCH 005/317] Revert of commit 12269 see: http://sourceforge.net/mailarchive/forum.php?thread_name=4CC08FAA.5050009%40fultondesigns.co.uk&forum_name=swig-devel git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12286 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 4 ---- configure.in | 14 -------------- 2 files changed, 18 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 65489354c..ebfb2cb81 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -18,7 +18,3 @@ Version 2.0.2 (in progress) Fix unary scope operator (::) (global scope) regression introduced in 2.0.0, reported by Ben Walker. The mangled symbol names were incorrect, sometimes resulting in types being incorrectly treated as opaque types. - -2010-10-14: Sylvestre Ledru - Fails the configure if cannot find a yacc implementation - (like bison) diff --git a/configure.in b/configure.in index 7f584e5d6..36337b41d 100644 --- a/configure.in +++ b/configure.in @@ -122,20 +122,6 @@ echo "Note : None of the following packages are required for users to compile an echo "" AC_PROG_YACC -echo "YACC $YACC" -if test -z "$YACC"; then - AC_MSG_ERROR([No implementation of Yacc (bison, yacc) detected.]) -fi -# Actually, AC_PROG_YACC is lying. It sometimes put yacc into $YACC even it -# hasn't been able to find it. -# AC_CHECK_PROG(YACC_PRESENT, $YACC, AC_MSG_ERROR([No implementation of Yacc (bison, yacc) detected. Please install it (package bison)]) ) - -AC_CHECK_PROG(yacc_present, $YACC, "yes","no") -if test "x$yacc_present" != "xyes"; then - AC_MSG_ERROR([No implementation of Yacc (bison, yacc) detected. Please install it (package bison)]) -fi - - AC_PROG_RANLIB AC_CHECK_PROGS(AR, ar aal, ar) AC_SUBST(AR) From 77b87aa9196c226b8625218b8608b5696b335d06 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 11 Nov 2010 19:30:44 +0000 Subject: [PATCH 006/317] typo fix in help message git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12288 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/python.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 80f2e68df..6d5f500a4 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -130,7 +130,7 @@ static const char *usage2 = (char *) "\ -nofastproxy - Use traditional proxy mechanism for member methods (default) \n\ -nofastquery - Use traditional query mechanism for types (default) \n\ -noh - Don't generate the output header file\n\ - -nomodern - Don't use modern python features which are not back compatible \n\ + -nomodern - Don't use modern python features which are not backwards compatible \n\ -nomodernargs - Use classic ParseTuple/CallFunction methods to pack/unpack the function arguments (default) \n"; static const char *usage3 = (char *) "\ -noolddefs - Don't emit the old method definitions even when using fastproxy (default) \n\ From 580f2549582602399553fded9e12bca6f9746143 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 12 Nov 2010 16:43:03 +0000 Subject: [PATCH 007/317] Update for recent runtime name changes (a better mechanism is clearly needed here). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12290 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/go/cdata.i | 4 ++-- Lib/go/goruntime.swg | 12 ++++++------ Source/Modules/go.cxx | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Lib/go/cdata.i b/Lib/go/cdata.i index decf297c1..6cfdffea1 100644 --- a/Lib/go/cdata.i +++ b/Lib/go/cdata.i @@ -59,8 +59,8 @@ void _swig_gc_makegobyteslice(void *a, int32 n) { cgocallback(·_swig_internal_makegobyteslice, a, n); } void ·_swig_allocategobyteslice(byte *data, int32 len, swigcdata ret) { - ret.data = mal(len); - mcpy(ret.data, data, len); + ret.data = runtime·mal(len); + runtime·mcpy(ret.data, data, len); ret.len = len; FLUSH(&ret); } diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg index 057f81d01..6cde68f55 100644 --- a/Lib/go/goruntime.swg +++ b/Lib/go/goruntime.swg @@ -109,23 +109,23 @@ static void _swig_gopanic(const char *p) { extern void ·_swig_internal_allocate(void); #pragma dynexport _swig_gc_allocate _swig_gc_allocate void _swig_gc_allocate(void *a, int32 n) { - cgocallback(·_swig_internal_allocate, a, n); + runtime·cgocallback(·_swig_internal_allocate, a, n); } void ·_swig_allocatememory(int32 len, byte *ret) { - ret = mal(len); + ret = runtime·mal(len); FLUSH(&ret); } extern void ·_swig_internal_makegostring(void); #pragma dynexport _swig_gc_makegostring _swig_gc_makegostring void _swig_gc_makegostring(void *a, int32 n) { - cgocallback(·_swig_internal_makegostring, a, n); + runtime·cgocallback(·_swig_internal_makegostring, a, n); } void ·_swig_allocatestring(byte *p, int32 l, String ret) { - ret.str = mal(l+1); - mcpy(ret.str, p, l); + ret.str = runtime·mal(l+1); + runtime·mcpy(ret.str, p, l); ret.len = l; FLUSH(&ret); } @@ -133,7 +133,7 @@ void ·_swig_allocatestring(byte *p, int32 l, String ret) { extern void ·_swig_internal_gopanic(void); #pragma dynexport _swig_gc_gopanic _swig_gc_gopanic void _swig_gc_gopanic(void *a, int32 n) { - cgocallback(·_swig_internal_gopanic, a, n); + runtime·cgocallback(·_swig_internal_gopanic, a, n); } %} diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 4b1d05b92..d3de53f8f 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -1068,7 +1068,7 @@ private: Delete(parm_size); Printv(f->code, "{\n", NULL); - Printv(f->code, "\tcgocall(", wname, ", &p);\n", NULL); + Printv(f->code, "\truntime\xc2\xb7" "cgocall(", wname, ", &p);\n", NULL); Printv(f->code, "}\n", NULL); Printv(f->code, "\n", NULL); @@ -2749,7 +2749,7 @@ private: Printv(f_gc_wrappers, "void\n", NULL); Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL); Printv(f_gc_wrappers, "{\n", NULL); - Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", go_name, ", a, n);\n", NULL); + Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", go_name, ", a, n);\n", NULL); Printv(f_gc_wrappers, "}\n\n", NULL); } else { Printv(f_c_directors, " ", wname, "(go_val);\n", NULL); @@ -3475,7 +3475,7 @@ private: Printv(f_gc_wrappers, "void\n", NULL); Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL); Printv(f_gc_wrappers, "{\n", NULL); - Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", callback_name, ", a, n);\n", NULL); + Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", callback_name, ", a, n);\n", NULL); Printv(f_gc_wrappers, "}\n\n", NULL); } else { if (SwigType_type(result) != T_VOID) { From e30befd13806fb89c1591c56a7a66a5c24d1a14e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 16 Nov 2010 14:08:50 +0000 Subject: [PATCH 008/317] Correct explanation of how to match on class name in %rename. Replace incorrect documentation of $parentNode from %rename discussion: it advised using match$parentNode but this doesn't work because the parent node is not yet set when %rename is parsed. Document the "fullname" attribute of %rename which can be used to restrict the match to the given full name of a declaration only. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12291 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/SWIG.html | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html index e51e55986..b8e3e2260 100644 --- a/Doc/Manual/SWIG.html +++ b/Doc/Manual/SWIG.html @@ -2002,22 +2002,6 @@ documentation is not exhaustive, see "%rename predicates" section of swig.swg for the full list of supported match expressions.

-

-Another important feature of match is that it can be applied not -only to the declaration itself but also to its enclosing declaration. So -match$parentNode$name="SomeClass" would be true only for members of -the C++ class with the specified name. This can, of course, be combined with -more complicated matches making it possible to write -

-
-
-%rename("%(lowercase)s", match$parentNode$name="SomeClass", %$isenum) "";
-
-
-

-to rename all enums nested in the given class to lower case. -

-

In addition to literally matching some string with match you can also use regexmatch or notregexmatch to match a string @@ -2039,6 +2023,14 @@ declaration name directly can be preferable and can also be done using %rename("$ignore", regextarget=1) "Old$"; +Notice that the check is done only against the name of the declaration +itself, if you need to match the full name of a C++ declaration you +must use fullname attribute: +

+
+%rename("$ignore", regextarget=1, fullname=1) "NameSpace::ClassName::.*Old$";
+
+

As for notregexmatch, it restricts the match only to the strings not From 953c4abacaad7c8cab4eb5c5f87e5164c7e414c8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 16 Nov 2010 14:09:09 +0000 Subject: [PATCH 009/317] Use rename list and not hash for renames with regextarget attribute. Renames which are regular expressions can't be put in the regex hash as they don't literally match the real declarations names. Instead, put them in the rename list against which we will match the declarations names later. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12292 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Swig/naming.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 5bf42f7cc..70744586c 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -1110,7 +1110,7 @@ void Swig_name_nameobj_add(Hash *name_hash, List *name_list, String *prefix, Str } if (!nname || !Len(nname) || Getattr(nameobj, "fullname") || /* any of these options trigger a 'list' nameobj */ - Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist")) { + Getattr(nameobj, "sourcefmt") || Getattr(nameobj, "matchlist") || Getattr(nameobj, "regextarget")) { if (decl) Setattr(nameobj, "decl", decl); if (nname && Len(nname)) From f6cab0170abdb69b1ac562b223d101bf55e5700f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 16 Nov 2010 14:09:39 +0000 Subject: [PATCH 010/317] Ignore non-matching regex renames when searching renames list. Skip over %renames with non-matching %(regex)s expansion when looking for the one to apply to the given name. This allows to have multiple anonymous renames using regex as now the first _matching_ one will be used instead of always using the first one and ignoring all the rest of them. Extend unit tests to verify that applying two anonymous %renames does work as expected. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12293 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 10 ++++++++++ .../test-suite/csharp/rename_pcre_encoder_runme.cs | 12 ++++++++++++ .../test-suite/java/rename_pcre_encoder_runme.java | 14 ++++++++++++++ .../test-suite/python/rename_pcre_encoder_runme.py | 3 +++ Examples/test-suite/rename_pcre_encoder.i | 9 +++++++-- Source/Swig/naming.c | 8 +++++++- 6 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 Examples/test-suite/csharp/rename_pcre_encoder_runme.cs create mode 100644 Examples/test-suite/java/rename_pcre_encoder_runme.java diff --git a/CHANGES.current b/CHANGES.current index ebfb2cb81..f18011e1a 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,16 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.2 (in progress) =========================== +2010-11-12: vadz + Fix handling of multiple regex-using %renames attached to the same + declaration. For example, now + + %rename("%(regex/^Set(.*)/put\\1/)s") ""; + %rename("%(regex/^Get(.*)/get\\1/)s") ""; + + works as expected whereas before only the last anonymous rename was + taken into account. + 2010-10-17: drjoe [R] Fix failure in overloaded functions which was breaking QuantLib-SWIG diff --git a/Examples/test-suite/csharp/rename_pcre_encoder_runme.cs b/Examples/test-suite/csharp/rename_pcre_encoder_runme.cs new file mode 100644 index 000000000..f6289e7e2 --- /dev/null +++ b/Examples/test-suite/csharp/rename_pcre_encoder_runme.cs @@ -0,0 +1,12 @@ +using System; +using rename_pcre_encoderNamespace; + +public class runme { + static void Main() { + SomeWidget w = new SomeWidget(); + w.putBorderWidth(17); + if ( w.getBorderWidth() != 17 ) + throw new Exception(String.Format("Border with should be 17, not {0}", + w.getBorderWidth())); + } +} diff --git a/Examples/test-suite/java/rename_pcre_encoder_runme.java b/Examples/test-suite/java/rename_pcre_encoder_runme.java new file mode 100644 index 000000000..cb843338b --- /dev/null +++ b/Examples/test-suite/java/rename_pcre_encoder_runme.java @@ -0,0 +1,14 @@ +import rename_pcre_encoder.*; + +public class rename_pcre_encoder_runme { + static { System.loadLibrary("rename_pcre_encoder"); } + + public static void main(String argv[]) + { + SomeWidget w = new SomeWidget(); + w.putBorderWidth(17); + if ( w.getBorderWidth() != 17 ) + throw new RuntimeException(String.format("Border with should be 17, not %d", + w.getBorderWidth())); + } +} diff --git a/Examples/test-suite/python/rename_pcre_encoder_runme.py b/Examples/test-suite/python/rename_pcre_encoder_runme.py index ed7ca48b1..1186703a0 100644 --- a/Examples/test-suite/python/rename_pcre_encoder_runme.py +++ b/Examples/test-suite/python/rename_pcre_encoder_runme.py @@ -2,6 +2,9 @@ from rename_pcre_encoder import * s = SomeWidget() s.putBorderWidth(3) +if s.getBorderWidth() != 3: + raise RuntimeError("Border should be 3, not %d" % (s.getBorderWidth(),)) + s.putSize(4, 5) a = AnotherWidget() a.DoSomething() diff --git a/Examples/test-suite/rename_pcre_encoder.i b/Examples/test-suite/rename_pcre_encoder.i index c90af164d..66f30c7bc 100644 --- a/Examples/test-suite/rename_pcre_encoder.i +++ b/Examples/test-suite/rename_pcre_encoder.i @@ -3,14 +3,19 @@ // strip the wx prefix from all identifiers except those starting with wxEVT %rename("%(regex:/wx(?!EVT)(.*)/\\1/)s") ""; -// Replace "Set" prefix with "put" in all functions +// Replace "Set" and "Get" prefixes with "put" and "get" respectively. %rename("%(regex:/^Set(.*)/put\\1/)s", %$isfunction) ""; +%rename("%(regex:/^Get(.*)/get\\1/)s", %$isfunction) ""; %inline %{ struct wxSomeWidget { - void SetBorderWidth(int) {} + void SetBorderWidth(int width) { m_width = width; } + int GetBorderWidth() const { return m_width; } + void SetSize(int, int) {} + + int m_width; }; struct wxAnotherWidget { diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c index 70744586c..6beecc130 100644 --- a/Source/Swig/naming.c +++ b/Source/Swig/naming.c @@ -1302,7 +1302,13 @@ Hash *Swig_name_nameobj_lget(List *namelist, Node *n, String *prefix, String *na : Swig_name_match_value(tname, sname); Delete(sname); } else { - match = 1; + /* Applying the renaming rule may fail if it contains a %(regex)s expression that doesn't match the given name. */ + String *sname = NewStringf(Getattr(rn, "name"), name); + if (sname) { + if (Len(sname)) + match = 1; + Delete(sname); + } } } if (match) { From ee1c2f3ef086080a54cf5aec99f8b46e3f4d910d Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:15:13 +0000 Subject: [PATCH 011/317] Renamed 'immutable' test-case to 'immutable_values'. This is a part of the pending merge of the D module, where 'immutable' is a keyword (and thus not a valid module name). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12294 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 2 +- Examples/test-suite/{immutable.i => immutable_values.i} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename Examples/test-suite/{immutable.i => immutable_values.i} (90%) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 026612db5..05d2f80c8 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -466,7 +466,7 @@ C_TEST_CASES += \ extern_declaration \ funcptr \ function_typedef \ - immutable \ + immutable_values \ inctest \ integers \ keyword_rename \ diff --git a/Examples/test-suite/immutable.i b/Examples/test-suite/immutable_values.i similarity index 90% rename from Examples/test-suite/immutable.i rename to Examples/test-suite/immutable_values.i index ff5081e9c..1c1978661 100644 --- a/Examples/test-suite/immutable.i +++ b/Examples/test-suite/immutable_values.i @@ -1,6 +1,6 @@ // test to make sure setters are not generated for constants -%module immutable +%module immutable_values %immutable; From 0fb77ce2068128e02217cdddd6a388e6c6d30d9f Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:15:41 +0000 Subject: [PATCH 012/317] Renamed 'template' test-case to 'template_basic'. This is a part of the pending merge of the D module, where 'template' is a keyword (and thus not a valid module name). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12295 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/common.mk | 2 +- Examples/test-suite/{template.i => template_basic.i} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename Examples/test-suite/{template.i => template_basic.i} (89%) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 05d2f80c8..f0fe4af1c 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -318,11 +318,11 @@ CPP_TEST_CASES += \ struct_initialization_cpp \ struct_value \ symbol_clash \ - template \ template_arg_replace \ template_arg_scope \ template_arg_typename \ template_array_numeric \ + template_basic \ template_base_template \ template_classes \ template_const_ref \ diff --git a/Examples/test-suite/template.i b/Examples/test-suite/template_basic.i similarity index 89% rename from Examples/test-suite/template.i rename to Examples/test-suite/template_basic.i index d2c7a91ed..570392bf6 100644 --- a/Examples/test-suite/template.i +++ b/Examples/test-suite/template_basic.i @@ -1,5 +1,5 @@ -/* File : example.i */ -%module "template" +/* File: template_basic.i */ +%module "template_basic" %warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector; /* Ruby, wrong class name */ %warnfilter(SWIGWARN_RUBY_WRONG_NAME) vector; /* Ruby, wrong class name */ @@ -31,7 +31,7 @@ template class vector { void set(int index, T &val) { v[index] = val; } - // This really doesn't do anything except test const handling + // This really doesn't do anything except test const handling void testconst(const T x) { } }; From 4d09774cefd745dc6a0e38db0a3ab320d79c992c Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:16:02 +0000 Subject: [PATCH 013/317] Minor rename in the 'smart_pointer_templatemethods' test-case to avoid special casing for D. This is a part of the pending merge of the D module, where 'Object' is a keyword. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12296 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/smart_pointer_templatemethods.i | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Examples/test-suite/smart_pointer_templatemethods.i b/Examples/test-suite/smart_pointer_templatemethods.i index 7baa6386a..f79bbcc9d 100644 --- a/Examples/test-suite/smart_pointer_templatemethods.i +++ b/Examples/test-suite/smart_pointer_templatemethods.i @@ -1,4 +1,3 @@ - %module smart_pointer_templatemethods %inline %{ @@ -29,21 +28,21 @@ public: void DisposeObjekt (void) {} }; -class Object +class Objct { public: - Object () {} - virtual ~Object () {} + Objct () {} + virtual ~Objct () {} template Ptr QueryInterface (InterfaceId iid) const { return Ptr(); } - void DisposeObject (void) {} + void DisposeObjct (void) {} }; #ifdef SWIG -%template(PtrObject) Ptr; +%template(PtrObjct) Ptr; %template(PtrInt) Ptr; %template(ObjektInt) Objekt; %template(PtrObjektInt) Ptr >; -%template(QueryInterfaceObject) Object::QueryInterface; +%template(QueryInterfaceObjct) Objct::QueryInterface; #endif }; // namespace From 2070812f09468e17b6a1e027dcaa6b5ae3774570 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:16:23 +0000 Subject: [PATCH 014/317] Minor rename in the 'operbool' test-case to avoid special casing for D. This is a part of the pending merge of the D module, where a method having the same name as the module would lead to ambiguities. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12297 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/operbool.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/test-suite/operbool.i b/Examples/test-suite/operbool.i index 793c0174e..ee8c889e9 100644 --- a/Examples/test-suite/operbool.i +++ b/Examples/test-suite/operbool.i @@ -1,6 +1,6 @@ %module operbool -%rename(operbool) operator bool(); +%rename(operator_bool) operator bool(); %inline %{ class Test { From a355d2d46af56c655816c37f24bb59fa6bade43f Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:17:37 +0000 Subject: [PATCH 015/317] Added special cases to the test-suite as required for D. This is a part of the pending merge of the D module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12298 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/abstract_virtual.i | 6 ++-- Examples/test-suite/contract.i | 7 ++++- Examples/test-suite/default_constructor.i | 6 ++-- Examples/test-suite/dynamic_cast.i | 13 +++++++-- Examples/test-suite/enums.i | 5 ++++ Examples/test-suite/evil_diamond.i | 3 +- Examples/test-suite/evil_diamond_ns.i | 3 +- Examples/test-suite/evil_diamond_prop.i | 1 + Examples/test-suite/import_nomodule.i | 8 ++--- Examples/test-suite/inherit_target_language.i | 8 ++++- Examples/test-suite/li_boost_shared_ptr.i | 2 +- .../test-suite/li_boost_shared_ptr_bits.i | 2 +- Examples/test-suite/li_std_combinations.i | 2 +- Examples/test-suite/minherit2.i | 29 +++++++++++++++++-- Examples/test-suite/multiple_inheritance.i | 6 ++-- Examples/test-suite/namespace_class.i | 4 +++ Examples/test-suite/preproc_line_file.i | 4 +-- Examples/test-suite/pure_virtual.i | 5 ++-- Examples/test-suite/samename.i | 2 +- Examples/test-suite/special_variable_macros.i | 14 +++++++++ Examples/test-suite/static_const_member.i | 3 ++ Examples/test-suite/template_enum.i | 4 +++ .../test-suite/template_inherit_abstract.i | 5 ++-- Examples/test-suite/typemap_namespace.i | 9 +++++- Examples/test-suite/typemap_out_optimal.i | 6 +++- Examples/test-suite/typemap_subst.i | 4 +-- Examples/test-suite/using_composition.i | 9 ++++-- Examples/test-suite/using_extend.i | 3 +- Examples/test-suite/using_namespace.i | 3 +- 29 files changed, 137 insertions(+), 39 deletions(-) diff --git a/Examples/test-suite/abstract_virtual.i b/Examples/test-suite/abstract_virtual.i index 2e4d105b1..d8372c936 100644 --- a/Examples/test-suite/abstract_virtual.i +++ b/Examples/test-suite/abstract_virtual.i @@ -2,10 +2,12 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) D; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) D; /* C#, D, Java, PHP multiple inheritance */ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) E; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) E; /* C#, D, Java, PHP multiple inheritance */ %inline %{ #if defined(_MSC_VER) diff --git a/Examples/test-suite/contract.i b/Examples/test-suite/contract.i index b979ef19e..0ad7e8e7c 100644 --- a/Examples/test-suite/contract.i +++ b/Examples/test-suite/contract.i @@ -3,12 +3,17 @@ %warnfilter(SWIGWARN_RUBY_MULTIPLE_INHERITANCE, SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) C; /* Ruby, C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) C; /* Ruby, C#, D, Java, PHP multiple inheritance */ #ifdef SWIGCSHARP %ignore B::bar; // otherwise get a warning: `C.bar' no suitable methods found to override #endif +#ifdef SWIGD +%ignore B::bar; // Prevents getting an error that C.bar does not override any function because multiple inheritance is not supported. +#endif + %contract test_preassert(int a, int b) { require: a > 0; diff --git a/Examples/test-suite/default_constructor.i b/Examples/test-suite/default_constructor.i index ff22c7834..091adff20 100644 --- a/Examples/test-suite/default_constructor.i +++ b/Examples/test-suite/default_constructor.i @@ -5,11 +5,13 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) EB; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) EB; /* C#, D, Java, PHP multiple inheritance */ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) AD; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) AD; /* C#, D, Java, PHP multiple inheritance */ %warnfilter(SWIGWARN_LANG_FRIEND_IGNORE) F; /* friend function */ diff --git a/Examples/test-suite/dynamic_cast.i b/Examples/test-suite/dynamic_cast.i index ccbaa5b47..17850985a 100644 --- a/Examples/test-suite/dynamic_cast.i +++ b/Examples/test-suite/dynamic_cast.i @@ -1,7 +1,7 @@ /* File : example.i */ %module dynamic_cast -#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) +#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) && !defined(SWIGD) %apply SWIGTYPE *DYNAMIC { Foo * }; #endif @@ -17,7 +17,7 @@ public: }; %} -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO) || defined(SWIGD) %typemap(out) Foo *blah { Bar *downcast = dynamic_cast($1); *(Bar **)&$result = downcast; @@ -37,6 +37,13 @@ public: } #endif +#if defined(SWIGD) +%typemap(dout, excode=SWIGEXCODE) Foo * { + Bar ret = new Bar($wcall, $owner);$excode + return ret; +} +#endif + #if defined(SWIGGO) %insert(go_runtime) %{ func FooToBar(f Foo) Bar { @@ -62,7 +69,7 @@ char *do_test(Bar *b) { } %} -#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) +#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) && !defined(SWIGD) // A general purpose function for dynamic casting of a Foo * %{ static swig_type_info * diff --git a/Examples/test-suite/enums.i b/Examples/test-suite/enums.i index 5632b5e97..14c6efbba 100644 --- a/Examples/test-suite/enums.i +++ b/Examples/test-suite/enums.i @@ -58,6 +58,11 @@ typedef struct _Foo { %warnfilter(SWIGWARN_RUBY_WRONG_NAME) _iFoo; +#ifdef SWIGD +/* Work around missing support for proper char quoting due to parser shortcomings. */ +%dconstvalue("'a'") _iFoo::Char; +#endif + #ifndef __cplusplus %inline %{ typedef struct _iFoo diff --git a/Examples/test-suite/evil_diamond.i b/Examples/test-suite/evil_diamond.i index 7b2e9152f..a8d48b30b 100644 --- a/Examples/test-suite/evil_diamond.i +++ b/Examples/test-suite/evil_diamond.i @@ -6,7 +6,8 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME, SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) spam; // Ruby, wrong class name - C# & Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) spam; // Ruby, wrong class name - C#, D & Java, PHP multiple inheritance %inline %{ diff --git a/Examples/test-suite/evil_diamond_ns.i b/Examples/test-suite/evil_diamond_ns.i index 515044007..0227b31ee 100644 --- a/Examples/test-suite/evil_diamond_ns.i +++ b/Examples/test-suite/evil_diamond_ns.i @@ -6,7 +6,8 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME, SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) Blah::spam; // Ruby, wrong class name - C# & Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) Blah::spam; // Ruby, wrong class name - C#, D & Java, PHP multiple inheritance %inline %{ namespace Blah { diff --git a/Examples/test-suite/evil_diamond_prop.i b/Examples/test-suite/evil_diamond_prop.i index 804ea66b4..2dac6eab7 100644 --- a/Examples/test-suite/evil_diamond_prop.i +++ b/Examples/test-suite/evil_diamond_prop.i @@ -6,6 +6,7 @@ %warnfilter(SWIGWARN_RUBY_WRONG_NAME, SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE) spam; // Ruby, wrong class name - C# & Java, PHP multiple inheritance %inline %{ diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i index a1ba9ad7a..4fd5cbf65 100644 --- a/Examples/test-suite/import_nomodule.i +++ b/Examples/test-suite/import_nomodule.i @@ -8,16 +8,16 @@ %import "import_nomodule.h" -#if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) +#if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) && !defined(SWIGD) /** * The proxy class does not have Bar derived from Foo, yet an instance of Bar * can successfully be passed to a proxy function taking a Foo pointer (for some * language modules). * - * This violation of the type system is not possible in Java and C# due to static - * type checking. It's also not (currently) possible in Ruby, but this may be - * fixable (needs more investigation). + * This violation of the type system is not possible in Java, C# and D due to + * static type checking. It's also not (currently) possible in Ruby, but this may + * be fixable (needs more investigation). */ %newobject create_Foo; diff --git a/Examples/test-suite/inherit_target_language.i b/Examples/test-suite/inherit_target_language.i index 20fb93fda..88801f3f6 100644 --- a/Examples/test-suite/inherit_target_language.i +++ b/Examples/test-suite/inherit_target_language.i @@ -1,4 +1,4 @@ -// Test using a target language specified base class, primarily for Java/C# and possibly other single inheritance languages +// Test using a target language specified base class, primarily for Java/C#/D and possibly other single inheritance languages // Note the multiple inheritance warnings don't appear because of the two techniques used in here: typemaps and %ignore @@ -6,6 +6,8 @@ #if defined(SWIGJAVA) # define csbase javabase +#elif defined(SWIGD) +# define csbase dbase #endif %pragma(csharp) moduleimports=%{ @@ -20,6 +22,10 @@ class TargetLanguageBase { public void targetLanguageBaseMethod() {} }; class TargetLanguageBase2 { public void targetLanguageBase2Method() {} }; %} +%pragma(d) globalproxyimports=%{ +private class TargetLanguageBase { public void targetLanguageBaseMethod() {} }; +private class TargetLanguageBase2 { public void targetLanguageBase2Method() {} }; +%} %typemap(csbase) SWIGTYPE "TargetLanguageBase" diff --git a/Examples/test-suite/li_boost_shared_ptr.i b/Examples/test-suite/li_boost_shared_ptr.i index f92df23a9..fc51e7b5a 100644 --- a/Examples/test-suite/li_boost_shared_ptr.i +++ b/Examples/test-suite/li_boost_shared_ptr.i @@ -34,7 +34,7 @@ # define SWIG_SHARED_PTR_NAMESPACE SwigBoost #endif -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD) #define SHARED_PTR_WRAPPERS_IMPLEMENTED #endif diff --git a/Examples/test-suite/li_boost_shared_ptr_bits.i b/Examples/test-suite/li_boost_shared_ptr_bits.i index 610edb4b4..2232b6cf6 100644 --- a/Examples/test-suite/li_boost_shared_ptr_bits.i +++ b/Examples/test-suite/li_boost_shared_ptr_bits.i @@ -1,6 +1,6 @@ %module li_boost_shared_ptr_bits -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD) #define SHARED_PTR_WRAPPERS_IMPLEMENTED #endif diff --git a/Examples/test-suite/li_std_combinations.i b/Examples/test-suite/li_std_combinations.i index 9acc8f23d..57f945bcd 100644 --- a/Examples/test-suite/li_std_combinations.i +++ b/Examples/test-suite/li_std_combinations.i @@ -14,7 +14,7 @@ %template(VectorVectorString) std::vector< std::vector >; %template(PairIntPairIntString) std::pair< int, std::pair >; -#if defined(SWIGCSHARP) +#if defined(SWIGCSHARP) || defined(SWIGD) // Checks macro containing a type with a comma SWIG_STD_VECTOR_ENHANCED(std::pair< double, std::string >) #endif diff --git a/Examples/test-suite/minherit2.i b/Examples/test-suite/minherit2.i index 1bca4fc48..7d470d30e 100644 --- a/Examples/test-suite/minherit2.i +++ b/Examples/test-suite/minherit2.i @@ -1,16 +1,18 @@ %module minherit2 -// A multiple inheritance example, mainly for Java and C#. -// The example shows how it is possible to turn C++ abstract base classes into Java/C# interface. +// A multiple inheritance example, mainly for Java, C# and D. +// The example shows how it is possible to turn C++ abstract base classes into +// Java/C#/D interfaces. // In the future, all this trouble might be more automated. %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, + SWIGWARN_D_MULTIPLE_INHERITANCE, SWIGWARN_RUBY_MULTIPLE_INHERITANCE, SWIGWARN_PHP_MULTIPLE_INHERITANCE) RemoteMpe; -#if defined(SWIGJAVA) || defined(SWIGCSHARP) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) #if defined(SWIGCSHARP) #define javaclassmodifiers csclassmodifiers @@ -22,6 +24,21 @@ #define javabase csbase #endif +#if defined(SWIGD) +#define javaclassmodifiers dclassmodifiers +#define javabody dbody +#define javafinalize ddestructor +#define javadestruct ddispose +#define javaout dout +#define javainterfaces dinterfaces +#define javabase dbase + +%typemap(dimports) RemoteMpe %{ +$importtype(IRemoteSyncIO) +$importtype(IRemoteAsyncIO) +%} +#endif + // Modify multiple inherited base classes into inheriting interfaces %typemap(javainterfaces) RemoteMpe "IRemoteSyncIO, IRemoteAsyncIO"; %typemap(javabase, replace="1") RemoteMpe ""; @@ -51,6 +68,12 @@ // Features are inherited by derived classes, so override this %csmethodmodifiers RemoteMpe::syncmethod "public" %csmethodmodifiers RemoteMpe::asyncmethod "public" +#elif defined(SWIGD) +%dmethodmodifiers IRemoteSyncIO::syncmethod ""; +%dmethodmodifiers IRemoteAsyncIO::asyncmethod ""; +// Features are inherited by derived classes, so override this +%dmethodmodifiers RemoteMpe::syncmethod "public" +%dmethodmodifiers RemoteMpe::asyncmethod "public" #endif #endif diff --git a/Examples/test-suite/multiple_inheritance.i b/Examples/test-suite/multiple_inheritance.i index 1fc68eef9..044345020 100644 --- a/Examples/test-suite/multiple_inheritance.i +++ b/Examples/test-suite/multiple_inheritance.i @@ -5,11 +5,13 @@ It tests basic multiple inheritance */ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; /* C#, D, Java, PHP multiple inheritance */ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBarSpam; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBarSpam; /* C#, D, Java, PHP multiple inheritance */ %inline %{ diff --git a/Examples/test-suite/namespace_class.i b/Examples/test-suite/namespace_class.i index 7dc9139cd..aea5362d1 100644 --- a/Examples/test-suite/namespace_class.i +++ b/Examples/test-suite/namespace_class.i @@ -2,6 +2,10 @@ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Ala::Ola; +#ifdef SWIGD +%warnfilter(SWIGWARN_IGNORE_OPERATOR_LT); +#endif + %inline %{ template void foobar(T t) {} namespace test { diff --git a/Examples/test-suite/preproc_line_file.i b/Examples/test-suite/preproc_line_file.i index 353aa999f..91ff2133e 100644 --- a/Examples/test-suite/preproc_line_file.i +++ b/Examples/test-suite/preproc_line_file.i @@ -33,12 +33,12 @@ const int NUMBER_UNIQUE(thing) = -2; /* resolves to thing28 */ %javaconst(1); #elif defined(SWIGCSHARP) %csconst(1); +#elif defined(SWIGD) +%dnativeconst; #else %ignore LINE_NUMBER; %ignore LINE_NUM; /* spare space */ - - #endif %{ diff --git a/Examples/test-suite/pure_virtual.i b/Examples/test-suite/pure_virtual.i index 5bda283cf..9e345e2a4 100644 --- a/Examples/test-suite/pure_virtual.i +++ b/Examples/test-suite/pure_virtual.i @@ -9,7 +9,8 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) E; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) E; /* C#, D, Java, PHP multiple inheritance */ %nodefaultctor C; %nodefaultdtor C; @@ -65,7 +66,7 @@ public: %} /* Fill in method from AA. This class should be constructable */ -#ifdef SWIGCSHARP +#if defined(SWIGCSHARP) || defined(SWIGD) %ignore F::method2(); // Work around for lack of multiple inheritance support - base AA is ignored. #endif diff --git a/Examples/test-suite/samename.i b/Examples/test-suite/samename.i index 819cb4abd..cc03995bc 100644 --- a/Examples/test-suite/samename.i +++ b/Examples/test-suite/samename.i @@ -1,6 +1,6 @@ %module samename -#if !(defined(SWIGCSHARP) || defined(SWIGJAVA)) +#if !(defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGD)) class samename { public: void do_something() { diff --git a/Examples/test-suite/special_variable_macros.i b/Examples/test-suite/special_variable_macros.i index c168b4747..45eab0507 100644 --- a/Examples/test-suite/special_variable_macros.i +++ b/Examples/test-suite/special_variable_macros.i @@ -165,6 +165,20 @@ namespace Space { return new $typemap(jstype, Space::RenameMe)( new $typemap(jstype, Name)(s) ); } %} +#elif defined(SWIGD) +#if (SWIG_D_VERSION == 1) +%typemap(dcode) Space::RenameMe %{ + public static NewName factory(char[] s) { + return new $typemap(dptype, Space::RenameMe)( new $typemap(dptype, Name)(s) ); + } +%} +#else +%typemap(dcode) Space::RenameMe %{ + public static NewName factory(string s) { + return new $typemap(dptype, Space::RenameMe)( new $typemap(dptype, Name)(s) ); + } +%} +#endif #endif %rename(NewName) Space::RenameMe; diff --git a/Examples/test-suite/static_const_member.i b/Examples/test-suite/static_const_member.i index 3db60b4c2..945e28490 100644 --- a/Examples/test-suite/static_const_member.i +++ b/Examples/test-suite/static_const_member.i @@ -11,6 +11,9 @@ #elif SWIGCSHARP %csconst(1) EN; %csconst(1) CHARTEST; +#elif SWIGD +%dnativeconst EN; +%dnativeconst CHARTEST; #endif %inline %{ diff --git a/Examples/test-suite/template_enum.i b/Examples/test-suite/template_enum.i index 0d6fbf5b9..f36d5dc40 100644 --- a/Examples/test-suite/template_enum.i +++ b/Examples/test-suite/template_enum.i @@ -13,6 +13,10 @@ public: %template(foo_i) foo; %template(foo_d) foo; +#ifdef SWIGD +// Workaround for the D module which uses the literal value in the generated wrapper code. +%dconstvalue("3") Manta::ColorSpace::NumComponents; +#endif %inline { diff --git a/Examples/test-suite/template_inherit_abstract.i b/Examples/test-suite/template_inherit_abstract.i index 2f83433a5..87c921eab 100644 --- a/Examples/test-suite/template_inherit_abstract.i +++ b/Examples/test-suite/template_inherit_abstract.i @@ -4,7 +4,8 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) oss::Module; /* C#, Java, PHP multiple inheritance */ + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) oss::Module; /* C#, D, Java, PHP multiple inheritance */ %inline %{ @@ -56,7 +57,7 @@ namespace oss %inline %{ namespace oss { -#if defined(SWIG) && defined(SWIGCSHARP) +#if defined(SWIG) && (defined(SWIGCSHARP) || defined(SWIGD)) %ignore HModule::get(); // Work around for lack of multiple inheritance support - base ModuleBase is ignored. #endif struct test : HModule diff --git a/Examples/test-suite/typemap_namespace.i b/Examples/test-suite/typemap_namespace.i index 6614e0372..5a198b554 100644 --- a/Examples/test-suite/typemap_namespace.i +++ b/Examples/test-suite/typemap_namespace.i @@ -28,9 +28,16 @@ namespace Foo { #endif #ifdef SWIGGO %typemap(gotype) Str1 * = char *; +#endif +#ifdef SWIGD + %typemap(cwtype) Str1 * = char *; + %typemap(dwtype) Str1 * = char *; + %typemap(dptype) Str1 * = char *; + %typemap(din) Str1 * = char *; + %typemap(dout) Str1 * = char *; #endif %typemap(in) Str1 * = char *; -#if !(defined(SWIGCSHARP) || defined(SWIGLUA) || defined(SWIGPHP) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGGO)) +#if !(defined(SWIGCSHARP) || defined(SWIGLUA) || defined(SWIGPHP) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGGO) || defined(SWIGD)) %typemap(freearg) Str1 * = char *; #endif %typemap(typecheck) Str1 * = char *; diff --git a/Examples/test-suite/typemap_out_optimal.i b/Examples/test-suite/typemap_out_optimal.i index 23cd2ad3f..d707ed2d5 100644 --- a/Examples/test-suite/typemap_out_optimal.i +++ b/Examples/test-suite/typemap_out_optimal.i @@ -2,7 +2,7 @@ %module typemap_out_optimal // Just the following languages tested -#if defined (SWIGCSHARP) +#if defined (SWIGCSHARP) || defined (SWIGD) %typemap(out, optimal="1") SWIGTYPE %{ $result = new $1_ltype((const $1_ltype &)$1); %} @@ -18,6 +18,10 @@ %ignore XX::operator=; +#ifdef SWIGD +%rename(trace) XX::debug; +#endif + %inline %{ #include using namespace std; diff --git a/Examples/test-suite/typemap_subst.i b/Examples/test-suite/typemap_subst.i index 1b1f8a3f4..91ac62020 100644 --- a/Examples/test-suite/typemap_subst.i +++ b/Examples/test-suite/typemap_subst.i @@ -61,8 +61,8 @@ $1 = ($ltype) temp; } -/* Java, C# and Go modules don't use SWIG's runtime type system */ -#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) +/* Java, C#, Go and D modules don't use SWIG's runtime type system */ +#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO) && !defined(SWIGD) %inline %{ void foo(const struct xyzzy **TEST) {} %} diff --git a/Examples/test-suite/using_composition.i b/Examples/test-suite/using_composition.i index bd0f712b5..052412b5f 100644 --- a/Examples/test-suite/using_composition.i +++ b/Examples/test-suite/using_composition.i @@ -2,13 +2,16 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; // C#, Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; // C#, D, Java, PHP multiple inheritance %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar2; // C#, Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar2; // C#, D, Java, PHP multiple inheritance %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar3; // C#, Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar3; // C#, D, Java, PHP multiple inheritance #ifdef SWIGLUA // lua only has one numeric type, so some overloads shadow each other creating warnings %warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) blah; #endif diff --git a/Examples/test-suite/using_extend.i b/Examples/test-suite/using_extend.i index e14cc28e8..c52f65c23 100644 --- a/Examples/test-suite/using_extend.i +++ b/Examples/test-suite/using_extend.i @@ -2,7 +2,8 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; // C#, Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) FooBar; // C#, D, Java, PHP multiple inheritance #ifdef SWIGLUA // lua only has one numeric type, so some overloads shadow each other creating warnings %warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) blah; #endif diff --git a/Examples/test-suite/using_namespace.i b/Examples/test-suite/using_namespace.i index ce02e9a87..1119b46f7 100644 --- a/Examples/test-suite/using_namespace.i +++ b/Examples/test-suite/using_namespace.i @@ -5,7 +5,8 @@ %warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE, SWIGWARN_CSHARP_MULTIPLE_INHERITANCE, - SWIGWARN_PHP_MULTIPLE_INHERITANCE) Hi; // C#, Java, PHP multiple inheritance + SWIGWARN_D_MULTIPLE_INHERITANCE, + SWIGWARN_PHP_MULTIPLE_INHERITANCE) Hi; // C#, D, Java, PHP multiple inheritance %inline %{ namespace hello From 03aefbc6e95d094a6de231e1f5264c0946e209a3 Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Thu, 18 Nov 2010 00:24:02 +0000 Subject: [PATCH 016/317] Added support for the D programming languge. It is still a bit rough around some edges, particularly with regard to multi-threading and operator overloading, and there are some documentation bits missing, but it should be fine for basic use. The test-suite should build and run fine with the current versions of DMD, LDC and Tango (at least) on Linux x86_64 and Mac OS X 10.6. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12299 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Doc/Manual/D.html | 401 ++ Doc/Manual/Sections.html | 1 + Doc/Manual/chapters | 1 + Examples/Makefile.in | 89 +- Examples/d/callback/Makefile | 28 + Examples/d/callback/d1/runme.d | 36 + Examples/d/callback/d2/runme.d | 36 + Examples/d/callback/example.cxx | 4 + Examples/d/callback/example.h | 24 + Examples/d/callback/example.i | 13 + Examples/d/check.list | 9 + Examples/d/class/Makefile | 28 + Examples/d/class/d1/runme.d | 58 + Examples/d/class/d2/runme.d | 58 + Examples/d/class/example.cxx | 28 + Examples/d/class/example.h | 34 + Examples/d/class/example.i | 10 + Examples/d/constants/Makefile | 28 + Examples/d/constants/d1/runme.d | 28 + Examples/d/constants/d2/runme.d | 28 + Examples/d/constants/example.d | 23 + Examples/d/constants/example.i | 32 + Examples/d/enum/Makefile | 28 + Examples/d/enum/d1/runme.d | 28 + Examples/d/enum/d2/runme.d | 28 + Examples/d/enum/example.cxx | 37 + Examples/d/enum/example.h | 13 + Examples/d/enum/example.i | 11 + Examples/d/extend/Makefile | 28 + Examples/d/extend/d1/runme.d | 75 + Examples/d/extend/d2/runme.d | 75 + Examples/d/extend/example.cxx | 4 + Examples/d/extend/example.h | 56 + Examples/d/extend/example.i | 14 + Examples/d/funcptr/Makefile | 28 + Examples/d/funcptr/d1/runme.d | 34 + Examples/d/funcptr/d2/runme.d | 34 + Examples/d/funcptr/example.c | 19 + Examples/d/funcptr/example.h | 9 + Examples/d/funcptr/example.i | 16 + Examples/d/simple/Makefile | 28 + Examples/d/simple/d1/runme.d | 27 + Examples/d/simple/d2/runme.d | 27 + Examples/d/simple/example.c | 18 + Examples/d/simple/example.i | 7 + Examples/d/variables/Makefile | 28 + Examples/d/variables/d1/runme.d | 71 + Examples/d/variables/d2/runme.d | 71 + Examples/d/variables/example.c | 91 + Examples/d/variables/example.h | 6 + Examples/d/variables/example.i | 49 + Examples/test-suite/d/Makefile.in | 80 + Examples/test-suite/d/README | 7 + Examples/test-suite/d/aggregate_runme.1.d | 25 + Examples/test-suite/d/aggregate_runme.2.d | 25 + Examples/test-suite/d/allprotected_runme.1.d | 65 + Examples/test-suite/d/allprotected_runme.2.d | 65 + Examples/test-suite/d/apply_strings_runme.1.d | 12 + Examples/test-suite/d/apply_strings_runme.2.d | 12 + Examples/test-suite/d/bools_runme.1.d | 20 + Examples/test-suite/d/bools_runme.2.d | 20 + Examples/test-suite/d/catches_runme.1.d | 33 + Examples/test-suite/d/catches_runme.2.d | 33 + Examples/test-suite/d/char_strings_runme.1.d | 151 + Examples/test-suite/d/char_strings_runme.2.d | 123 + Examples/test-suite/d/constover_runme.1.d | 31 + Examples/test-suite/d/constover_runme.2.d | 16 + .../test-suite/d/d_nativepointers_runme.1.d | 23 + .../test-suite/d/d_nativepointers_runme.2.d | 23 + Examples/test-suite/d/default_args_runme.1.d | 127 + Examples/test-suite/d/default_args_runme.2.d | 84 + .../d/default_constructor_runme.1.d | 30 + .../d/default_constructor_runme.2.d | 25 + .../test-suite/d/director_basic_runme.1.d | 59 + .../test-suite/d/director_basic_runme.2.d | 46 + .../test-suite/d/director_classes_runme.1.d | 168 + .../test-suite/d/director_classes_runme.2.d | 169 + .../test-suite/d/director_classic_runme.1.d | 207 + .../test-suite/d/director_classic_runme.2.d | 202 + .../test-suite/d/director_ignore_runme.1.d | 39 + .../test-suite/d/director_ignore_runme.2.d | 38 + .../d/director_primitives_runme.1.d | 122 + .../d/director_primitives_runme.2.d | 123 + .../test-suite/d/director_protected_runme.1.d | 50 + .../test-suite/d/director_protected_runme.2.d | 36 + .../test-suite/d/director_string_runme.1.d | 46 + .../test-suite/d/director_string_runme.2.d | 42 + Examples/test-suite/d/enum_thorough_runme.1.d | 424 ++ Examples/test-suite/d/enum_thorough_runme.2.d | 425 ++ .../d/inherit_target_language_runme.1.d | 29 + .../d/inherit_target_language_runme.2.d | 29 + Examples/test-suite/d/li_attribute_runme.1.d | 75 + Examples/test-suite/d/li_attribute_runme.2.d | 58 + .../d/li_boost_shared_ptr_bits_runme.1.d | 21 + .../d/li_boost_shared_ptr_bits_runme.2.d | 19 + .../d/li_boost_shared_ptr_runme.1.d | 604 +++ .../d/li_boost_shared_ptr_runme.2.d | 602 +++ Examples/test-suite/d/li_std_except_runme.1.d | 40 + Examples/test-suite/d/li_std_except_runme.2.d | 34 + Examples/test-suite/d/li_std_string_runme.1.d | 97 + Examples/test-suite/d/li_std_string_runme.2.d | 86 + Examples/test-suite/d/li_std_vector_runme.1.d | 219 + Examples/test-suite/d/li_std_vector_runme.2.d | 207 + Examples/test-suite/d/li_typemaps_runme.1.d | 94 + Examples/test-suite/d/li_typemaps_runme.2.d | 91 + Examples/test-suite/d/long_long_runme.1.d | 35 + Examples/test-suite/d/long_long_runme.2.d | 32 + .../test-suite/d/member_pointer_runme.1.d | 43 + .../test-suite/d/member_pointer_runme.2.d | 42 + .../d/overload_complicated_runme.1.d | 50 + .../d/overload_complicated_runme.2.d | 34 + .../test-suite/d/overload_template_runme.1.d | 146 + .../test-suite/d/overload_template_runme.2.d | 80 + .../test-suite/d/pointer_reference_runme.1.d | 13 + .../test-suite/d/pointer_reference_runme.2.d | 14 + .../d/preproc_constants_c_runme.1.d | 63 + .../d/preproc_constants_c_runme.2.d | 63 + .../test-suite/d/preproc_constants_runme.1.d | 62 + .../test-suite/d/preproc_constants_runme.2.d | 62 + Examples/test-suite/d/sizet_runme.1.d | 15 + Examples/test-suite/d/sizet_runme.2.d | 14 + Examples/test-suite/d/sneaky1_runme.1.d | 21 + Examples/test-suite/d/sneaky1_runme.2.d | 11 + .../d/special_variable_macros_runme.1.d | 39 + .../d/special_variable_macros_runme.2.d | 21 + Examples/test-suite/d/threads_runme.1.d | 70 + Examples/test-suite/d/threads_runme.2.d | 55 + .../test-suite/d/throw_exception_runme.1.d | 30 + .../test-suite/d/throw_exception_runme.2.d | 30 + .../test-suite/d/typemap_namespace_runme.1.d | 13 + .../test-suite/d/typemap_namespace_runme.2.d | 9 + .../d/typemap_out_optimal_runme.1.d | 9 + .../d/typemap_out_optimal_runme.2.d | 9 + Examples/test-suite/d/varargs_runme.1.d | 20 + Examples/test-suite/d/varargs_runme.2.d | 13 + Examples/test-suite/d/virtual_poly_runme.1.d | 27 + Examples/test-suite/d/virtual_poly_runme.2.d | 22 + Examples/test-suite/d_nativepointers.i | 18 + Lib/allkw.swg | 1 + Lib/d/boost_shared_ptr.i | 201 + Lib/d/carrays.i | 111 + Lib/d/cpointer.i | 171 + Lib/d/d.swg | 46 + Lib/d/dclassgen.swg | 172 + Lib/d/ddirectives.swg | 11 + Lib/d/denums.swg | 60 + Lib/d/dexception.swg | 30 + Lib/d/dhead.swg | 310 ++ Lib/d/director.swg | 46 + Lib/d/dkw.swg | 126 + Lib/d/dmemberfunctionpointers.swg | 92 + Lib/d/doperators.swg | 77 + Lib/d/dprimitives.swg | 158 + Lib/d/dstrings.swg | 80 + Lib/d/dswigtype.swg | 177 + Lib/d/dvoid.swg | 18 + Lib/d/std_common.i | 5 + Lib/d/std_deque.i | 1 + Lib/d/std_except.i | 30 + Lib/d/std_map.i | 59 + Lib/d/std_pair.i | 34 + Lib/d/std_shared_ptr.i | 2 + Lib/d/std_string.i | 98 + Lib/d/std_vector.i | 591 +++ Lib/d/stl.i | 12 + Lib/d/typemaps.i | 298 ++ Lib/d/wrapperloader.swg | 303 ++ Lib/exception.i | 36 +- Lib/std_except.i | 2 +- Lib/swig.swg | 4 +- Makefile.in | 17 +- Source/Include/swigwarn.h | 21 +- Source/Makefile.am | 1 + Source/Modules/d.cxx | 4359 +++++++++++++++++ Source/Modules/swigmain.cxx | 2 + configure.in | 43 + 176 files changed, 16449 insertions(+), 29 deletions(-) create mode 100644 Doc/Manual/D.html create mode 100644 Examples/d/callback/Makefile create mode 100644 Examples/d/callback/d1/runme.d create mode 100644 Examples/d/callback/d2/runme.d create mode 100644 Examples/d/callback/example.cxx create mode 100644 Examples/d/callback/example.h create mode 100644 Examples/d/callback/example.i create mode 100644 Examples/d/check.list create mode 100644 Examples/d/class/Makefile create mode 100644 Examples/d/class/d1/runme.d create mode 100644 Examples/d/class/d2/runme.d create mode 100644 Examples/d/class/example.cxx create mode 100644 Examples/d/class/example.h create mode 100644 Examples/d/class/example.i create mode 100644 Examples/d/constants/Makefile create mode 100644 Examples/d/constants/d1/runme.d create mode 100644 Examples/d/constants/d2/runme.d create mode 100644 Examples/d/constants/example.d create mode 100644 Examples/d/constants/example.i create mode 100644 Examples/d/enum/Makefile create mode 100644 Examples/d/enum/d1/runme.d create mode 100644 Examples/d/enum/d2/runme.d create mode 100644 Examples/d/enum/example.cxx create mode 100644 Examples/d/enum/example.h create mode 100644 Examples/d/enum/example.i create mode 100644 Examples/d/extend/Makefile create mode 100644 Examples/d/extend/d1/runme.d create mode 100644 Examples/d/extend/d2/runme.d create mode 100644 Examples/d/extend/example.cxx create mode 100644 Examples/d/extend/example.h create mode 100644 Examples/d/extend/example.i create mode 100644 Examples/d/funcptr/Makefile create mode 100644 Examples/d/funcptr/d1/runme.d create mode 100644 Examples/d/funcptr/d2/runme.d create mode 100644 Examples/d/funcptr/example.c create mode 100644 Examples/d/funcptr/example.h create mode 100644 Examples/d/funcptr/example.i create mode 100644 Examples/d/simple/Makefile create mode 100644 Examples/d/simple/d1/runme.d create mode 100644 Examples/d/simple/d2/runme.d create mode 100644 Examples/d/simple/example.c create mode 100644 Examples/d/simple/example.i create mode 100644 Examples/d/variables/Makefile create mode 100644 Examples/d/variables/d1/runme.d create mode 100644 Examples/d/variables/d2/runme.d create mode 100644 Examples/d/variables/example.c create mode 100644 Examples/d/variables/example.h create mode 100644 Examples/d/variables/example.i create mode 100644 Examples/test-suite/d/Makefile.in create mode 100644 Examples/test-suite/d/README create mode 100644 Examples/test-suite/d/aggregate_runme.1.d create mode 100644 Examples/test-suite/d/aggregate_runme.2.d create mode 100644 Examples/test-suite/d/allprotected_runme.1.d create mode 100644 Examples/test-suite/d/allprotected_runme.2.d create mode 100644 Examples/test-suite/d/apply_strings_runme.1.d create mode 100644 Examples/test-suite/d/apply_strings_runme.2.d create mode 100644 Examples/test-suite/d/bools_runme.1.d create mode 100644 Examples/test-suite/d/bools_runme.2.d create mode 100644 Examples/test-suite/d/catches_runme.1.d create mode 100644 Examples/test-suite/d/catches_runme.2.d create mode 100644 Examples/test-suite/d/char_strings_runme.1.d create mode 100644 Examples/test-suite/d/char_strings_runme.2.d create mode 100644 Examples/test-suite/d/constover_runme.1.d create mode 100644 Examples/test-suite/d/constover_runme.2.d create mode 100644 Examples/test-suite/d/d_nativepointers_runme.1.d create mode 100644 Examples/test-suite/d/d_nativepointers_runme.2.d create mode 100644 Examples/test-suite/d/default_args_runme.1.d create mode 100644 Examples/test-suite/d/default_args_runme.2.d create mode 100644 Examples/test-suite/d/default_constructor_runme.1.d create mode 100644 Examples/test-suite/d/default_constructor_runme.2.d create mode 100644 Examples/test-suite/d/director_basic_runme.1.d create mode 100644 Examples/test-suite/d/director_basic_runme.2.d create mode 100644 Examples/test-suite/d/director_classes_runme.1.d create mode 100644 Examples/test-suite/d/director_classes_runme.2.d create mode 100644 Examples/test-suite/d/director_classic_runme.1.d create mode 100644 Examples/test-suite/d/director_classic_runme.2.d create mode 100644 Examples/test-suite/d/director_ignore_runme.1.d create mode 100644 Examples/test-suite/d/director_ignore_runme.2.d create mode 100644 Examples/test-suite/d/director_primitives_runme.1.d create mode 100644 Examples/test-suite/d/director_primitives_runme.2.d create mode 100644 Examples/test-suite/d/director_protected_runme.1.d create mode 100644 Examples/test-suite/d/director_protected_runme.2.d create mode 100644 Examples/test-suite/d/director_string_runme.1.d create mode 100644 Examples/test-suite/d/director_string_runme.2.d create mode 100644 Examples/test-suite/d/enum_thorough_runme.1.d create mode 100644 Examples/test-suite/d/enum_thorough_runme.2.d create mode 100644 Examples/test-suite/d/inherit_target_language_runme.1.d create mode 100644 Examples/test-suite/d/inherit_target_language_runme.2.d create mode 100644 Examples/test-suite/d/li_attribute_runme.1.d create mode 100644 Examples/test-suite/d/li_attribute_runme.2.d create mode 100644 Examples/test-suite/d/li_boost_shared_ptr_bits_runme.1.d create mode 100644 Examples/test-suite/d/li_boost_shared_ptr_bits_runme.2.d create mode 100644 Examples/test-suite/d/li_boost_shared_ptr_runme.1.d create mode 100644 Examples/test-suite/d/li_boost_shared_ptr_runme.2.d create mode 100644 Examples/test-suite/d/li_std_except_runme.1.d create mode 100644 Examples/test-suite/d/li_std_except_runme.2.d create mode 100644 Examples/test-suite/d/li_std_string_runme.1.d create mode 100644 Examples/test-suite/d/li_std_string_runme.2.d create mode 100644 Examples/test-suite/d/li_std_vector_runme.1.d create mode 100644 Examples/test-suite/d/li_std_vector_runme.2.d create mode 100644 Examples/test-suite/d/li_typemaps_runme.1.d create mode 100644 Examples/test-suite/d/li_typemaps_runme.2.d create mode 100644 Examples/test-suite/d/long_long_runme.1.d create mode 100644 Examples/test-suite/d/long_long_runme.2.d create mode 100644 Examples/test-suite/d/member_pointer_runme.1.d create mode 100644 Examples/test-suite/d/member_pointer_runme.2.d create mode 100644 Examples/test-suite/d/overload_complicated_runme.1.d create mode 100644 Examples/test-suite/d/overload_complicated_runme.2.d create mode 100644 Examples/test-suite/d/overload_template_runme.1.d create mode 100644 Examples/test-suite/d/overload_template_runme.2.d create mode 100644 Examples/test-suite/d/pointer_reference_runme.1.d create mode 100644 Examples/test-suite/d/pointer_reference_runme.2.d create mode 100644 Examples/test-suite/d/preproc_constants_c_runme.1.d create mode 100644 Examples/test-suite/d/preproc_constants_c_runme.2.d create mode 100644 Examples/test-suite/d/preproc_constants_runme.1.d create mode 100644 Examples/test-suite/d/preproc_constants_runme.2.d create mode 100644 Examples/test-suite/d/sizet_runme.1.d create mode 100644 Examples/test-suite/d/sizet_runme.2.d create mode 100644 Examples/test-suite/d/sneaky1_runme.1.d create mode 100644 Examples/test-suite/d/sneaky1_runme.2.d create mode 100644 Examples/test-suite/d/special_variable_macros_runme.1.d create mode 100644 Examples/test-suite/d/special_variable_macros_runme.2.d create mode 100644 Examples/test-suite/d/threads_runme.1.d create mode 100644 Examples/test-suite/d/threads_runme.2.d create mode 100644 Examples/test-suite/d/throw_exception_runme.1.d create mode 100644 Examples/test-suite/d/throw_exception_runme.2.d create mode 100644 Examples/test-suite/d/typemap_namespace_runme.1.d create mode 100644 Examples/test-suite/d/typemap_namespace_runme.2.d create mode 100644 Examples/test-suite/d/typemap_out_optimal_runme.1.d create mode 100644 Examples/test-suite/d/typemap_out_optimal_runme.2.d create mode 100644 Examples/test-suite/d/varargs_runme.1.d create mode 100644 Examples/test-suite/d/varargs_runme.2.d create mode 100644 Examples/test-suite/d/virtual_poly_runme.1.d create mode 100644 Examples/test-suite/d/virtual_poly_runme.2.d create mode 100644 Examples/test-suite/d_nativepointers.i create mode 100644 Lib/d/boost_shared_ptr.i create mode 100644 Lib/d/carrays.i create mode 100644 Lib/d/cpointer.i create mode 100644 Lib/d/d.swg create mode 100644 Lib/d/dclassgen.swg create mode 100644 Lib/d/ddirectives.swg create mode 100644 Lib/d/denums.swg create mode 100644 Lib/d/dexception.swg create mode 100644 Lib/d/dhead.swg create mode 100644 Lib/d/director.swg create mode 100644 Lib/d/dkw.swg create mode 100644 Lib/d/dmemberfunctionpointers.swg create mode 100644 Lib/d/doperators.swg create mode 100644 Lib/d/dprimitives.swg create mode 100644 Lib/d/dstrings.swg create mode 100644 Lib/d/dswigtype.swg create mode 100644 Lib/d/dvoid.swg create mode 100644 Lib/d/std_common.i create mode 100644 Lib/d/std_deque.i create mode 100644 Lib/d/std_except.i create mode 100644 Lib/d/std_map.i create mode 100644 Lib/d/std_pair.i create mode 100644 Lib/d/std_shared_ptr.i create mode 100644 Lib/d/std_string.i create mode 100644 Lib/d/std_vector.i create mode 100644 Lib/d/stl.i create mode 100644 Lib/d/typemaps.i create mode 100644 Lib/d/wrapperloader.swg create mode 100644 Source/Modules/d.cxx diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html new file mode 100644 index 000000000..2b563788f --- /dev/null +++ b/Doc/Manual/D.html @@ -0,0 +1,401 @@ + + + +SWIG and D + + + + +

20 SWIG and D

+ + + + + + +

20.1 Introduction

+ + +

From the D Programming Language web site: »D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. […] The D language is statically typed and compiles directly to machine code.« As such, it is not very surprising that D is able to directly interface with C libraries. Why would a SWIG module for D be needed then in the first place?

+ +

Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to \0-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.

+ +

While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. D did not support interfacing to C++ in version 1 at all, and even if extern(C++) has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases.

+ +

To help addressing these issues, the SWIG C# module has been forked to support D. Is has evolved quite a lot since then, but there are still many similarities, so if you do not find what you are looking for on this page, it might be worth having a look at the chapter on C# (and also on Java, since the C# module was in turn forked from it).

+ + +

20.2 Command line invocation

+ + +

To activate the D module, pass the -d option to SWIG at the command line. The same standard command line switches as with any other language module are available, plus the following D specific ones:

+ +
+
-splitproxy
+
+

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

+

If the split proxy mode is enabled by passing this switch at the command line, all proxy classes and enums are emitted to their own D module instead. The main proxy module only contains free functions and constants in this case.

+
+ +
-package <pkg>
+
+

By default, the proxy D modules and the wrap D module are written to the root package. Using this option, you can specify another target package instead.

+
+ +
-wrapperlibrary <wl>
+
+

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

+

This might especially be useful if you want to invoke SWIG several times on separate modules, but compile the resulting code into a single shared library.

+
+
+ + +

20.3 Typemaps

+ + +

20.3.1 C# <-> D name comparison

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

20.3.2 cwtype, dwtype, dptype

+ + +

Mapping of types between the C/C++ library, the C/C++ library wrapper exposing the C functions, the D wrapper module importing these functions and the D proxy code.

+ +

The cwtype typemap is used to determine the types to use in the C wrapper functions. The types from the dwtype typemap are used in the extern(C) declarations of these functions in the D wrap module. The dptype typemap contains the D types used in the D proxy module/class.

+ + +

20.3.3 in, out, directorin, directorout

+ + +

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

+ +

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

+ +

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

+ + +

20.3.4 din, dout, ddirectorin, ddirectorout

+ + +

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

+ +

The din typemap is used for converting function parameter types from the type used in the proxy module or class to the type used in the D wrap module (the $dinput macro is replaced).

+ +

The dout typemap is used for converting function return values from the return type used in the wrap D module to the type returned by the proxy function. The $excode special variable in dout typemaps is replaced by the excode typemap attribute code if the method can throw any exceptions from unmanaged code, otherwise by nothing (the $wcall and $owner macros are replaced).

+ +

The code from the ddirectorin and ddirectorout typemaps is used for conversion in director callback functions. Arguments are converted to the type used in the proxy class method they are calling by using the code from ddirectorin, the proxy class method return value is converted to the type the C++ code expects via the ddirectorout typemap (the $dpcall and $winput macros are replaced).

+ +

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

+ +
      type CPPClass::method(type a)
+        ↑                     ↓
+   <directorout>         <directorin>
+        ↑                     ↓
+     cwtype methodCallback(cwtype a)    C++
+ ::::::::::::::::::::::::::::::::::::::::::
+     dwtype methodCallback(dwtype a)    D
+        ↑                     ↓
+  <ddirectorout>       <ddirectorin>
+        ↑                     ↓
+      dptype DClass.method(dptype a)
+ + +

20.3.5 typecheck typemaps

+ + +

Because, unlike many scripting languages supported by SWIG, D does not need any dynamic dispatch helper to access an overloaded function, the purpose of these is merely to issue a warning for overloaded C++ functions that cannot be overloaded in D (as more than one C++ type maps to a single D type).

+ + +

20.3.6 Code injection typemaps

+ + +

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

+ +

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

+ +

Using dcode and dimports, you can specify additional D code which will be emitted into the class body respectively the imports section of the D module the class is written to.

+ +

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

+ + +

20.3.7 Special variable macros

+ + +

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

+ +

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

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

This special variable works similar to $n_type in that it returns the name of a type – it expands to the D proxy class name of the type being wrapped. If the type does not have an associated proxy class, it expands to the type wrapper class name, for example, SWIGTYPE_p_p_SomeCppClass is generated when wrapping SomeCppClass **.

+

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

+
+ +
$null
+

In code inserted into the generated C/C++ wrapper functions, this variable is replaced by either 0 or nothing at all, depending on whether the function has a return value or not. It can be used to bail out early e.g. in case of errors (return $null;).

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

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

+

For example, this input

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

leads to the following D proxy code being generated:

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

These variables are used in dout typemaps. $wcall contains the call to the wrapper layer which provides the value to be used, and $owner signals if the caller is responsible for managing the object lifetime (that is, if the called method is a constructor or has been marked via %newobject).

+

Consider the following example:

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

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

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

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

+ +
$excode
+

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

+ +
$dbaseclass
+

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

+ +
$directorconnect
+
+

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

+

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

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

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

+

Consider the following code snippet:

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

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

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

For this to work, AnInterface and AnotherInterface have to be in scope. If SWIG is not in split proxy mode, this is already the case, but it it is, they have to be added to the import list via the dimports typemap. Additionally, the import statement depends on the package SWIG is configured to emit the modules to.

+

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

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

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

+
+ +
$module
+

Expands to the name of the main proxy D module.

+ +
$wrapdmodule
+

Contains the fully qualified name of the wrap D module.

+
+ + +

20.4 %features

+ + +

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

+ + +
+
%dnativeconst and %dconstvalue(value)
+
+

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

+

For this to work, the C/C++ code for the constant value must directly compile as D code, though. If this is not the case, you can manually override the expression written to the D wrapper using the %dconstvalue directive, passing the new value as parameter.

+

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

+
+ +
%dmethodmodifiers
+
+

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

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

20.5 Pragmas

+ + +

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

+ +
+
%pragma(d) wrapdmodulecode
+

The passed text (D code) is copied verbatim to the wrap D module. For example, it can be (and is, internally) used to emit additional private helper code for the use by proxy typemaps.

+ +
%pragma(d) wrapdmoduleimports
+

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

+ +
%pragma(d) proxydmodulecode
+

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

+ +
%pragma(d) globalproxyimports
+
+

The D module currently does not support specifying dependencies on external modules (e.g. from the standard library) for the D typemaps. To add the import statements to the proxy modules (resp. to all proxy modules if in split proxy mode), you can use the globalproxyimports directive.

+

For example:

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

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

+

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

+
+ +
%pragma(d) wrapperloaderbindcommand
+
+

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

+

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

+
+
+ + +

20.6 D Exceptions

+ + +

Out of the box, C++ exceptions are fundamentally incompatible to their equivalent in the D world and cannot simply be propagated to a calling D method. There is, however, an easy way to solve this problem: Just catch the exception in the C/C++ wrapper layer, pass the contents to D, and make the wrapper code rethrow the exception in the D world.

+ +

The implementation details of this are a bit crude, but the SWIG D module automatically takes care of this, as long as it is able to detect that an exception could potentially be thrown (e.g. because the C++ method has a throw(…) exception specification).

+ +

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

+ + +

20.7 D Directors

+ + +

When the directors feature is activated, SWIG generates extra code on both the C++ and the D side to enable cross-language polymorphism. Essentially, this means that if you subclass a proxy class in D, C++ code can access any overridden virtual methods just as if you created a derived class in C++.

+ +

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

+ + +

20.8 Other features

+ + +

The nspace feature of SWIG is not yet supported for D – all class modules are written to the same package, regardless of which C++ namespace they are in.

+ +

Support of pointers to primitive types.

+ + +

20.9 D Typemap examples

+ + +

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

+ + + +

20.10 Work in progress and planned features

+ + +

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

+ +
    +
  • Static linking: Currently, the C wrapper code is compiled into a dynamic library, out of which the symbol addresses are looked up at runtime by the D part. If statically linking the different languages into one binary was supported, a tool-chain capable of performing IPO at link time could inline the wrapping code, effectively reducing the overhead for simple calls to zero.
  • +
  • C array handling: Many data structures in some C/C++ libraries contain array containing of a pointer to the first element and the element count. Currently, one must manually writing wrapper code to be able to access these from D. It should be possible to add a set of SWIG macros to semi-automatically generate conversion code.
  • +
  • Operator overloading: Currently, operator overloading is supported only to a very limited extent – many C++ operators are just ignored with a warning. The problem here is that the way D handles operator overloading differs quite a lot from the way C++ does it, both syntactically and semantically, and even more so since the advent of template-based operator overloading in D2.
  • +
+ +

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

+ +
    +
  • Memory management: Although the currently generated wrapper code works fine with regard to the GC for the test-suite, there might be issues coming up in real-world multi-threaded usage.
  • +
  • D2 support: Originally, the module has been developed for the use with D1, D2/Phobos support has been added in later. The basic features should work equally well for both, but there could be issues concerning const-correctness etc.
  • +
+ + + + + diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index 855244790..a44571992 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -52,6 +52,7 @@ Last update : SWIG-2.0.2 (in progress)
  • R support
  • Ruby support
  • Tcl support
  • +
  • D support
  • Developer Documentation

    diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index e918e234a..924c8cfde 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -17,6 +17,7 @@ CCache.html Allegrocl.html CSharp.html Chicken.html +D.html Go.html Guile.html Java.html diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 582c75f29..5d5590311 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -69,7 +69,7 @@ IOBJS = $(IWRAP:.i=.@OBJEXT@) CPP_DLLIBS = #-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ -L/usr/local/lib -lg++ -lstdc++ -lgcc -# Solaris workshop 5.0 +# Solaris workshop 5.0 # CPP_DLLIBS = -L/opt/SUNWspro/lib -lCrun # Symbols used for using shared libraries @@ -159,7 +159,7 @@ tcl_cpp: $(SRCS) # ----------------------------------------------------------------- tcl_clean: - rm -f *_wrap* *~ .~* mytclsh@EXEEXT@ + rm -f *_wrap* *~ .~* mytclsh@EXEEXT@ rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@SO@ @@ -296,9 +296,9 @@ python_static_cpp: $(SRCS) $(CXX) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) \ $(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET) -# ----------------------------------------------------------------- +# ----------------------------------------------------------------- # Running a Python example -# ----------------------------------------------------------------- +# ----------------------------------------------------------------- ifeq (,$(PY3)) PYSCRIPT = runme.py @@ -313,7 +313,7 @@ python_run: $(PYSCRIPT) runme3.py: runme.py cp $< $@ - $(PY2TO3) -w $@ >/dev/null 2>&1 + $(PY2TO3) -w $@ >/dev/null 2>&1 # ----------------------------------------------------------------- # Cleaning the python examples @@ -332,7 +332,7 @@ python_clean: # Make sure these locate your Octave installation OCTAVE_INCLUDE= $(DEFS) @OCTAVEEXT@ -OCTAVE_LIB = +OCTAVE_LIB = # Extra Octave specific dynamic linking options OCTAVE_DLNK = @OCTAVEDYNAMICLINKING@ @@ -548,14 +548,14 @@ mzscheme: $(SRCS) mzscheme_cpp: $(SRCS) $(SWIG) -mzscheme -c++ $(SWIGOPT) $(INTERFACEPATH) $(COMPILETOOL) $(MZC) `echo $(INCLUDES) | sed 's/-I/++ccf -I/g'` --cc $(ICXXSRCS) $(SRCS) $(CXXSRCS) - $(CXXSHARED) $(CFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS) + $(CXXSHARED) $(CFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS) # ----------------------------------------------------------------- # Cleaning the mzscheme examples # ----------------------------------------------------------------- mzscheme_clean: - rm -f *_wrap* *~ .~* + rm -f *_wrap* *~ .~* rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@SO@ @@ -643,7 +643,7 @@ ocaml_static_cpp: $(SRCS) $(INTERFACE:%.i=%.cmo) \ $(PROGFILE:%.ml=%.cmo) \ $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \ - -cclib "$(LIBS)" -cc '$(CXX)' + -cclib "$(LIBS)" -cc '$(CXX)' ocaml_static_cpp_toplevel: $(SRCS) $(OCAMLCORE) @@ -661,7 +661,7 @@ ocaml_static_cpp_toplevel: $(SRCS) -g -ccopt -g -cclib -g -custom -o $(TARGET)_top \ $(INTERFACE:%.i=%.cmo) \ $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) \ - -cclib "$(LIBS)" -cc '$(CXX)' + -cclib "$(LIBS)" -cc '$(CXX)' ocaml_dynamic_cpp: $(SRCS) $(OCAMLCORE) @@ -844,7 +844,7 @@ pike_cpp_static: $(SRCS) # ----------------------------------------------------------------- pike_clean: - rm -f *_wrap* *~ .~* mypike@EXEEXT@ + rm -f *_wrap* *~ .~* mypike@EXEEXT@ rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@SO@ @@ -861,7 +861,7 @@ CHICKEN_CFLAGS = @CHICKENOPTS@ CHICKENOPTS = -quiet CHICKEN_MAIN = -# SWIG produces $(ISRCS) (the C wrapper file) +# SWIG produces $(ISRCS) (the C wrapper file) # and $(CHICKEN_GENERATED_SCHEME) (the Scheme wrapper file): CHICKEN_GENERATED_SCHEME = $(INTERFACE:.i=.scm) CHICKEN_COMPILED_SCHEME = $(INTERFACE:.i=_chicken.c) @@ -1053,12 +1053,12 @@ lua_clean: allegrocl: $(SRCS) $(SWIG) -allegrocl -cwrap $(SWIGOPT) $(INTERFACEPATH) - $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) allegrocl_cpp: $(SRCS) $(SWIG) -c++ -allegrocl $(SWIGOPT) $(INTERFACEPATH) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) allegrocl_clean: @@ -1087,12 +1087,12 @@ clisp_clean: cffi: $(SRCS) $(SWIG) -cffi $(SWIGOPT) $(INTERFACEPATH) -# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) +# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) # $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) cffi_cpp: $(SRCS) $(SWIG) -c++ -cffi $(SWIGOPT) $(INTERFACEPATH) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) cffi_clean: @@ -1106,12 +1106,12 @@ cffi_clean: uffi: $(SRCS) $(SWIG) -uffi $(SWIGOPT) $(INTERFACEPATH) -# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) +# $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCS) # $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) uffi_cpp: $(SRCS) $(SWIG) -c++ -uffi $(SWIGOPT) $(INTERFACEPATH) -# $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) +# $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) # $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) uffi_clean: @@ -1212,3 +1212,56 @@ go_clean: rm -f *_wrap* *_gc* .~* runme rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *.[568] *.a *@SO@ + +################################################################## +##### D ###### +################################################################## + +DLIBPREFIX = @DLIBPREFIX@ + +ifeq (2,$(D_VERSION)) + SWIGD = $(SWIG) -d -d2 + DCOMPILER = @D2COMPILER@ +else + SWIGD = $(SWIG) -d + DCOMPILER = @D1COMPILER@ +endif + +ifeq (dmd,$(DCOMPILER)) + # DMD is 32bit only by now + CFLAGS += -m32 +endif + +# ---------------------------------------------------------------- +# Build a dynamically loadable D wrapper for a C module +# ---------------------------------------------------------------- + +d: $(SRCS) + $(SWIGD) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(EXTRA_CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) + $(LDSHARED) $(CFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO) + +# ---------------------------------------------------------------- +# Build a dynamically loadable D wrapper for a C++ module +# ---------------------------------------------------------------- + +d_cpp: $(SRCS) + $(SWIGD) -c++ $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(EXTRA_CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) + $(CXXSHARED) $(CFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO) + +# ---------------------------------------------------------------- +# Compile D files +# ---------------------------------------------------------------- + +d_compile: $(SRCS) + $(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS) + +# ----------------------------------------------------------------- +# Clean the D examples +# ----------------------------------------------------------------- + +d_clean: + rm -f *_wrap* *~ .~* runme runme.exe `find . -name \*.d | grep -v runme.d` + rm -f core @EXTRA_CLEAN@ + rm -f *.@OBJEXT@ *@SO@ diff --git a/Examples/d/callback/Makefile b/Examples/d/callback/Makefile new file mode 100644 index 000000000..bc16dd0fc --- /dev/null +++ b/Examples/d/callback/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/callback/d1/runme.d b/Examples/d/callback/d1/runme.d new file mode 100644 index 000000000..e34e09603 --- /dev/null +++ b/Examples/d/callback/d1/runme.d @@ -0,0 +1,36 @@ +module runme; + +import tango.io.Stdout; +import example; + +public class DCallback : Callback { + public override void run() { + Stdout( "DCallback.run()" ).newline; + } +} + +void main() { + auto caller = new Caller(); + + Stdout( "Adding and calling a normal C++ callback" ).newline; + Stdout( "----------------------------------------" ).newline; + { + scope auto callback = new Callback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + Stdout.newline; + Stdout( "Adding and calling a D callback" ).newline; + Stdout( "-------------------------------" ).newline; + { + scope auto callback = new DCallback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + Stdout.newline; + Stdout( "D exit" ).newline; +} diff --git a/Examples/d/callback/d2/runme.d b/Examples/d/callback/d2/runme.d new file mode 100644 index 000000000..88ffcdefd --- /dev/null +++ b/Examples/d/callback/d2/runme.d @@ -0,0 +1,36 @@ +module runme; + +import std.stdio; +import example; + +public class DCallback : Callback { + public override void run() { + writeln( "DCallback.run()" ); + } +} + +void main() { + auto caller = new Caller(); + + writeln( "Adding and calling a normal C++ callback" ); + writeln( "----------------------------------------" ); + { + scope auto callback = new Callback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + writeln(); + writeln( "Adding and calling a D callback" ); + writeln( "-------------------------------" ); + { + scope auto callback = new DCallback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + writeln(); + writeln( "D exit" ); +} diff --git a/Examples/d/callback/example.cxx b/Examples/d/callback/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/d/callback/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/d/callback/example.h b/Examples/d/callback/example.h new file mode 100644 index 000000000..38d25a043 --- /dev/null +++ b/Examples/d/callback/example.h @@ -0,0 +1,24 @@ +/* File : example.h */ + +#include +#include + +class Callback { +public: + virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } + virtual void run() { std::cout << "Callback::run()" << std::endl; } +}; + + +class Caller { +private: + Callback *_callback; +public: + Caller(): _callback(0) {} + ~Caller() { delCallback(); } + void delCallback() { delete _callback; _callback = 0; } + void setCallback(Callback *cb) { delCallback(); _callback = cb; } + void resetCallback() { _callback = 0; } + void call() { if (_callback) _callback->run(); } +}; + diff --git a/Examples/d/callback/example.i b/Examples/d/callback/example.i new file mode 100644 index 000000000..90beda01a --- /dev/null +++ b/Examples/d/callback/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping Callback */ +%feature("director") Callback; + +%include "example.h" + diff --git a/Examples/d/check.list b/Examples/d/check.list new file mode 100644 index 000000000..010e7bbfc --- /dev/null +++ b/Examples/d/check.list @@ -0,0 +1,9 @@ +# See top-level Makefile.in. +callback +class +constants +enum +extend +funcptr +simple +variables diff --git a/Examples/d/class/Makefile b/Examples/d/class/Makefile new file mode 100644 index 000000000..bc16dd0fc --- /dev/null +++ b/Examples/d/class/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/class/d1/runme.d b/Examples/d/class/d1/runme.d new file mode 100644 index 000000000..b0c4263a2 --- /dev/null +++ b/Examples/d/class/d1/runme.d @@ -0,0 +1,58 @@ +// This example illustrates how C++ classes can be used from D using SWIG. +// The D class gets mapped onto the C++ class and behaves as if it is a D class. +module runme; + +import tango.io.Stdout; +import example; + +void main() { + // ----- Object creation ----- + + Stdout( "Creating some objects:" ).newline; + + { + scope Square s = new Square(10); + scope Circle c = new Circle(10); + + // ----- Access a static member ----- + Stdout.format( "{} shapes were created.", Shape.nshapes ).newline; + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.x = 20; + c.y = 30; + + // Now use the same functions in the base class + Shape shape = s; + shape.x = -10; + shape.y = 5; + + Stdout( "\nHere is their current position:" ).newline; + Stdout.format( " Circle = ( {}, {} )", c.x, c.y ).newline; + Stdout.format( " Square = ( {}, {} )", s.x, s.y ).newline; + + // ----- Call some methods ----- + + Stdout( "\nHere are some properties of the shapes:" ).newline; + Shape[] shapes = [ cast(Shape) c, cast(Shape) s ]; + foreach ( currentShape; shapes ) + { + Stdout.format( " {}", currentShape.classinfo.name ).newline; + Stdout.format( " area = {}", currentShape.area() ).newline; + Stdout.format( " perimeter = {}", currentShape.perimeter() ).newline; + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + Stdout( "\nGuess I'll clean up now:" ).newline; + // Note: when this using scope is exited the D destructors are called which + // in turn call the C++ destructors. + } + + Stdout.format( "{} shapes remain", Shape.nshapes ).newline; + Stdout( "\nGoodbye!" ).newline; +} diff --git a/Examples/d/class/d2/runme.d b/Examples/d/class/d2/runme.d new file mode 100644 index 000000000..2e86c5fc7 --- /dev/null +++ b/Examples/d/class/d2/runme.d @@ -0,0 +1,58 @@ +// This example illustrates how C++ classes can be used from D using SWIG. +// The D class gets mapped onto the C++ class and behaves as if it is a D class. +module runme; + +import std.stdio; +import example; + +void main() { + // ----- Object creation ----- + + writeln( "Creating some objects:" ); + + { + scope Square s = new Square(10); + scope Circle c = new Circle(10); + + // ----- Access a static member ----- + writefln( "%s shapes were created.", Shape.nshapes ); + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.x = 20; + c.y = 30; + + // Now use the same functions in the base class + Shape shape = s; + shape.x = -10; + shape.y = 5; + + writeln( "\nHere is their current position:" ); + writefln( " Circle = ( %s, %s )", c.x, c.y ); + writefln( " Square = ( %s, %s )", s.x, s.y ); + + // ----- Call some methods ----- + + writeln( "\nHere are some properties of the shapes:" ); + Shape[] shapes = [ cast(Shape) c, cast(Shape) s ]; + foreach ( currentShape; shapes ) + { + writefln( " %s", currentShape.classinfo.name ); + writefln( " area = %s", currentShape.area() ); + writefln( " perimeter = %s", currentShape.perimeter() ); + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + writeln( "\nGuess I'll clean up now:" ); + // Note: when this using scope is exited the D destructors are called which + // in turn call the C++ destructors. + } + + writefln( "%s shapes remain", Shape.nshapes ); + writeln( "\nGoodbye!" ); +} diff --git a/Examples/d/class/example.cxx b/Examples/d/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/d/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/d/class/example.h b/Examples/d/class/example.h new file mode 100644 index 000000000..0d4527e92 --- /dev/null +++ b/Examples/d/class/example.h @@ -0,0 +1,34 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/d/class/example.i b/Examples/d/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/d/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/d/constants/Makefile b/Examples/d/constants/Makefile new file mode 100644 index 000000000..ce17134ec --- /dev/null +++ b/Examples/d/constants/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ example_wrap.c +EXTRA_LDFLAGS = example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/constants/d1/runme.d b/Examples/d/constants/d1/runme.d new file mode 100644 index 000000000..47362cbf3 --- /dev/null +++ b/Examples/d/constants/d1/runme.d @@ -0,0 +1,28 @@ +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + Stdout.formatln("ICONST = {} (should be 42)", example.ICONST); + Stdout.formatln("FCONST = {} (should be 2.18)", example.FCONST); + Stdout.formatln("CCONST = {} (should be 'x')", example.CCONST); + Stdout.formatln("CCONST2 = {} (this should be on a new line)", example.CCONST2); + Stdout.formatln("SCONST = {} (should be 'Hello World')", example.SCONST); + Stdout.formatln("SCONST2 = {} (should be '\"Hello World\"')", example.SCONST2); + Stdout.formatln("EXPR = {} (should be 48.55)", example.EXPR); + Stdout.formatln("iconst = {} (should be 37)", example.iconst); + Stdout.formatln("fconst = {} (should be 3.14)", example.fconst); + + static if (is(typeof(example.EXTERN))) { + Stdout.formatln("EXTERN should not be defined, but is: {}.", example.EXTERN ); + } else { + Stdout.formatln("EXTERN isn't defined (good)"); + } + + static if (is(typeof(example.FOO))) { + Stdout.formatln("FOO should not be defined, but is: {}.", example.FOO); + } else { + Stdout.formatln("FOO isn't defined (good)"); + } +} diff --git a/Examples/d/constants/d2/runme.d b/Examples/d/constants/d2/runme.d new file mode 100644 index 000000000..4be510d16 --- /dev/null +++ b/Examples/d/constants/d2/runme.d @@ -0,0 +1,28 @@ +module runme; + +import std.stdio; +static import example; + +void main() { + writefln("ICONST = %s (should be 42)", example.ICONST); + writefln("FCONST = %s (should be 2.1828)", example.FCONST); + writefln("CCONST = %s (should be 'x')", example.CCONST); + writefln("CCONST2 = %s (this should be on a new line)", example.CCONST2); + writefln("SCONST = %s (should be 'Hello World')", example.SCONST); + writefln("SCONST2 = %s (should be '\"Hello World\"')", example.SCONST2); + writefln("EXPR = %s (should be 48.5484)", example.EXPR); + writefln("iconst = %s (should be 37)", example.iconst); + writefln("fconst = %s (should be 3.14)", example.fconst); + + static if (is(typeof(example.EXTERN))) { + writefln("EXTERN should not be defined, but is: %s.", example.EXTERN ); + } else { + writeln("EXTERN isn't defined (good)"); + } + + static if (is(typeof(example.FOO))) { + writefln("FOO should not be defined, but is: %s.", example.FOO); + } else { + writeln("FOO isn't defined (good)"); + } +} diff --git a/Examples/d/constants/example.d b/Examples/d/constants/example.d new file mode 100644 index 000000000..7448d0ad9 --- /dev/null +++ b/Examples/d/constants/example.d @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.41 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +module example; + +static import example_wrap; + +static import tango.stdc.stringz; + +public const int ICONST = 42; +public const double FCONST = 2.1828; +public const char CCONST = 'x'; +public const char CCONST2 = '\n'; +public const char[] SCONST = "Hello World"; +public const char[] SCONST2 = "\"Hello World\""; +public const double EXPR = 42+3*(2.1828); +public const int iconst = 37; +public const double fconst = 3.14; diff --git a/Examples/d/constants/example.i b/Examples/d/constants/example.i new file mode 100644 index 000000000..5eb541919 --- /dev/null +++ b/Examples/d/constants/example.i @@ -0,0 +1,32 @@ +/* File : example.i */ +%module example + +/* Force the generated D code to use the C constant values rather than + retrieving them at runtime. You can also try disabling the feature and + compare the generated code. */ +%dnativeconst; + + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/d/enum/Makefile b/Examples/d/enum/Makefile new file mode 100644 index 000000000..bc16dd0fc --- /dev/null +++ b/Examples/d/enum/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/enum/d1/runme.d b/Examples/d/enum/d1/runme.d new file mode 100644 index 000000000..d986986d1 --- /dev/null +++ b/Examples/d/enum/d1/runme.d @@ -0,0 +1,28 @@ +module runme; + +import tango.io.Stdout; +import example; + +void main() { + Stdout( "Printing out some enum values:" ).newline; + Stdout(" color:").newline; + Stdout.formatln(" {} = {}", color.RED, cast(int)color.RED); + Stdout.formatln(" {} = {}", color.BLUE, cast(int)color.BLUE); + Stdout.formatln(" {} = {}", color.GREEN, cast(int)color.GREEN); + + Stdout("\n Foo.speed:").newline; + Stdout.formatln(" Foo.{} = {}", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE); + Stdout.formatln(" Foo.{} = {}", Foo.speed.WARP, cast(int)Foo.speed.WARP); + Stdout.formatln(" Foo.{} = {}", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS); + + Stdout("\nTesting use of enums with functions:").newline; + example.enum_test(color.RED, Foo.speed.IMPULSE); + example.enum_test(color.BLUE, Foo.speed.WARP); + example.enum_test(color.GREEN, Foo.speed.LUDICROUS); + + Stdout( "\nTesting use of enum with class method:" ).newline; + scope f = new Foo(); + f.enum_test(Foo.speed.IMPULSE); + f.enum_test(Foo.speed.WARP); + f.enum_test(Foo.speed.LUDICROUS); +} diff --git a/Examples/d/enum/d2/runme.d b/Examples/d/enum/d2/runme.d new file mode 100644 index 000000000..acaec8ae8 --- /dev/null +++ b/Examples/d/enum/d2/runme.d @@ -0,0 +1,28 @@ +module runme; + +import std.stdio; +import example; + +void main() { + writeln( "Printing out some enum values:" ); + writeln(" color:"); + writefln(" %s = %s", color.RED, cast(int)color.RED); + writefln(" %s = %s", color.BLUE, cast(int)color.BLUE); + writefln(" %s = %s", color.GREEN, cast(int)color.GREEN); + + writeln("\n Foo.speed:"); + writefln(" Foo.%s = %s", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE); + writefln(" Foo.%s = %s", Foo.speed.WARP, cast(int)Foo.speed.WARP); + writefln(" Foo.%s = %s", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS); + + writeln("\nTesting use of enums with functions:"); + example.enum_test(color.RED, Foo.speed.IMPULSE); + example.enum_test(color.BLUE, Foo.speed.WARP); + example.enum_test(color.GREEN, Foo.speed.LUDICROUS); + + writeln( "\nTesting use of enum with class method:" ); + scope f = new Foo(); + f.enum_test(Foo.speed.IMPULSE); + f.enum_test(Foo.speed.WARP); + f.enum_test(Foo.speed.LUDICROUS); +} diff --git a/Examples/d/enum/example.cxx b/Examples/d/enum/example.cxx new file mode 100644 index 000000000..df7bb6328 --- /dev/null +++ b/Examples/d/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.cxx */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/d/enum/example.h b/Examples/d/enum/example.h new file mode 100644 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/d/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/d/enum/example.i b/Examples/d/enum/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/d/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/d/extend/Makefile b/Examples/d/extend/Makefile new file mode 100644 index 000000000..bc16dd0fc --- /dev/null +++ b/Examples/d/extend/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/extend/d1/runme.d b/Examples/d/extend/d1/runme.d new file mode 100644 index 000000000..96501d1a4 --- /dev/null +++ b/Examples/d/extend/d1/runme.d @@ -0,0 +1,75 @@ +/// This file illustrates the cross language polymorphism using directors. +module runme; + +import example; +import tango.io.Stdout; + +// CEO class, which overrides Employee.getPosition(). +class CEO : Manager { +public: + this( char[] name ) { + super( name ); + } + + override char[] getPosition() { + return "CEO"; + } + + // Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory. + void disownMemory() { + swigCMemOwn = false; + } +} + +void main() { + // Create an instance of CEO, a class derived from the D proxy of the + // underlying C++ class. The calls to getName() and getPosition() are standard, + // the call to getTitle() uses the director wrappers to call CEO.getPosition(). + + auto e = new CEO( "Alice" ); + Stdout.formatln( "{} is a {}.", e.getName(), e.getPosition() ); + Stdout.formatln( "Just call her '{}'.", e.getTitle() ); + Stdout( "----------------------" ).newline; + + { + // Create a new EmployeeList instance. This class does not have a C++ + // director wrapper, but can be used freely with other classes that do. + scope auto list = new EmployeeList(); + + // EmployeeList owns its items, so we must surrender ownership of objects we add. + e.disownMemory(); + list.addEmployee(e); + Stdout( "----------------------" ).newline; + + // Now we access the first four items in list (three are C++ objects that + // EmployeeList's constructor adds, the last is our CEO). The virtual + // methods of all these instances are treated the same. For items 0, 1, and + // 2, all methods resolve in C++. For item 3, our CEO, getTitle calls + // getPosition which resolves in D. The call to getPosition is + // slightly different, however, because of the overidden getPosition() call, since + // now the object reference has been "laundered" by passing through + // EmployeeList as an Employee*. Previously, D resolved the call + // immediately in CEO, but now D thinks the object is an instance of + // class Employee. So the call passes through the + // Employee proxy class and on to the C wrappers and C++ director, + // eventually ending up back at the D CEO implementation of getPosition(). + // The call to getTitle() for item 3 runs the C++ Employee::getTitle() + // method, which in turn calls getPosition(). This virtual method call + // passes down through the C++ director class to the D implementation + // in CEO. All this routing takes place transparently. + + Stdout( "(position, title) for items 0-3:" ).newline; + Stdout.formatln( " {}, '{}'", list.getItem(0).getPosition(), list.getItem(0).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(1).getPosition(), list.getItem(1).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(2).getPosition(), list.getItem(2).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(3).getPosition(), list.getItem(3).getTitle() ); + Stdout( "----------------------" ).newline; + + // All Employees will be destroyed when the EmployeeList goes out of scope, + // including the CEO instance. + } + Stdout( "----------------------" ).newline; + + // All done. + Stdout( "Exiting cleanly from D code." ).newline; +} diff --git a/Examples/d/extend/d2/runme.d b/Examples/d/extend/d2/runme.d new file mode 100644 index 000000000..1ea6dfd21 --- /dev/null +++ b/Examples/d/extend/d2/runme.d @@ -0,0 +1,75 @@ +/// This file illustrates the cross language polymorphism using directors. +module runme; + +import std.stdio; +import example; + +// CEO class, which overrides Employee.getPosition(). +class CEO : Manager { +public: + this( string name ) { + super( name ); + } + + override string getPosition() const { + return "CEO"; + } + + // Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory. + void disownMemory() { + swigCMemOwn = false; + } +} + +void main() { + // Create an instance of CEO, a class derived from the D proxy of the + // underlying C++ class. The calls to getName() and getPosition() are standard, + // the call to getTitle() uses the director wrappers to call CEO.getPosition(). + + auto e = new CEO( "Alice" ); + writefln( "%s is a %s.", e.getName(), e.getPosition() ); + writefln( "Just call her '%s'.", e.getTitle() ); + writeln( "----------------------" ); + + { + // Create a new EmployeeList instance. This class does not have a C++ + // director wrapper, but can be used freely with other classes that do. + scope auto list = new EmployeeList(); + + // EmployeeList owns its items, so we must surrender ownership of objects we add. + e.disownMemory(); + list.addEmployee(e); + writeln( "----------------------" ); + + // Now we access the first four items in list (three are C++ objects that + // EmployeeList's constructor adds, the last is our CEO). The virtual + // methods of all these instances are treated the same. For items 0, 1, and + // 2, all methods resolve in C++. For item 3, our CEO, getTitle calls + // getPosition which resolves in D. The call to getPosition is + // slightly different, however, because of the overidden getPosition() call, since + // now the object reference has been "laundered" by passing through + // EmployeeList as an Employee*. Previously, D resolved the call + // immediately in CEO, but now D thinks the object is an instance of + // class Employee. So the call passes through the + // Employee proxy class and on to the C wrappers and C++ director, + // eventually ending up back at the D CEO implementation of getPosition(). + // The call to getTitle() for item 3 runs the C++ Employee::getTitle() + // method, which in turn calls getPosition(). This virtual method call + // passes down through the C++ director class to the D implementation + // in CEO. All this routing takes place transparently. + + writeln( "(position, title) for items 0-3:" ); + writefln( " %s, '%s'", list.getItem(0).getPosition(), list.getItem(0).getTitle() ); + writefln( " %s, '%s'", list.getItem(1).getPosition(), list.getItem(1).getTitle() ); + writefln( " %s, '%s'", list.getItem(2).getPosition(), list.getItem(2).getTitle() ); + writefln( " %s, '%s'", list.getItem(3).getPosition(), list.getItem(3).getTitle() ); + writeln( "----------------------" ); + + // All Employees will be destroyed when the EmployeeList goes out of scope, + // including the CEO instance. + } + writeln( "----------------------" ); + + // All done. + writeln( "Exiting cleanly from D code." ); +} diff --git a/Examples/d/extend/example.cxx b/Examples/d/extend/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/d/extend/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/d/extend/example.h b/Examples/d/extend/example.h new file mode 100644 index 000000000..7ad93fbc1 --- /dev/null +++ b/Examples/d/extend/example.h @@ -0,0 +1,56 @@ +/* File : example.h */ + +#include +#include +#include +#include +#include + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *getItem(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + diff --git a/Examples/d/extend/example.i b/Examples/d/extend/example.i new file mode 100644 index 000000000..0647e1319 --- /dev/null +++ b/Examples/d/extend/example.i @@ -0,0 +1,14 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + diff --git a/Examples/d/funcptr/Makefile b/Examples/d/funcptr/Makefile new file mode 100644 index 000000000..616102926 --- /dev/null +++ b/Examples/d/funcptr/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/funcptr/d1/runme.d b/Examples/d/funcptr/d1/runme.d new file mode 100644 index 000000000..2947602a5 --- /dev/null +++ b/Examples/d/funcptr/d1/runme.d @@ -0,0 +1,34 @@ +module runme; + +import tango.io.Stdout; +static import example; + +extern(C) int add(int a, int b) { + return a + b; +} + +extern(C) int sub(int a, int b) { + return a - b; +} + +extern(C) int mul(int a, int b) { + return a * b; +} + +void main() { + int a = 37; + int b = 42; + + Stdout( "a = " )( a ).newline; + Stdout( "b = " )( b ).newline; + + Stdout( "Trying some C callback functions:" ).newline; + Stdout( " ADD(a,b) = " )( example.do_op( a, b, example.ADD ) ).newline; + Stdout( " SUB(a,b) = " )( example.do_op( a, b, example.SUB ) ).newline; + Stdout( " MUL(a,b) = " )( example.do_op( a, b, example.MUL ) ).newline; + + Stdout( "Now the same with callback functions defined in D:" ).newline; + Stdout( " add(a,b) = " )( example.do_op( a, b, &add ) ).newline; + Stdout( " sub(a,b) = " )( example.do_op( a, b, &sub ) ).newline; + Stdout( " mul(a,b) = " )( example.do_op( a, b, &mul ) ).newline; +} diff --git a/Examples/d/funcptr/d2/runme.d b/Examples/d/funcptr/d2/runme.d new file mode 100644 index 000000000..929911d6c --- /dev/null +++ b/Examples/d/funcptr/d2/runme.d @@ -0,0 +1,34 @@ +module runme; + +import std.stdio; +static import example; + +extern(C) int add(int a, int b) { + return a + b; +} + +extern(C) int sub(int a, int b) { + return a - b; +} + +extern(C) int mul(int a, int b) { + return a * b; +} + +void main() { + int a = 37; + int b = 42; + + writefln( "a = %s", a ); + writefln( "b = %s", b ); + + writeln( "Trying some C callback functions:" ); + writefln( " ADD(a,b) = %s", example.do_op( a, b, example.ADD ) ); + writefln( " SUB(a,b) = %s", example.do_op( a, b, example.SUB ) ); + writefln( " MUL(a,b) = %s", example.do_op( a, b, example.MUL ) ); + + writeln( "Now the same with callback functions defined in D:" ); + writefln( " add(a,b) = %s", example.do_op( a, b, &add ) ); + writefln( " sub(a,b) = %s", example.do_op( a, b, &sub ) ); + writefln( " mul(a,b) = %s", example.do_op( a, b, &mul ) ); +} diff --git a/Examples/d/funcptr/example.c b/Examples/d/funcptr/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/d/funcptr/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/d/funcptr/example.h b/Examples/d/funcptr/example.h new file mode 100644 index 000000000..9936e24fc --- /dev/null +++ b/Examples/d/funcptr/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/Examples/d/funcptr/example.i b/Examples/d/funcptr/example.i new file mode 100644 index 000000000..8b3bef678 --- /dev/null +++ b/Examples/d/funcptr/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + +extern int (*funcvar)(int,int); + diff --git a/Examples/d/simple/Makefile b/Examples/d/simple/Makefile new file mode 100644 index 000000000..312e6a9e9 --- /dev/null +++ b/Examples/d/simple/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/simple/d1/runme.d b/Examples/d/simple/d1/runme.d new file mode 100644 index 000000000..1293f1839 --- /dev/null +++ b/Examples/d/simple/d1/runme.d @@ -0,0 +1,27 @@ +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + /* + * Call our gcd() function. + */ + int x = 42; + int y = 105; + int g = example.gcd( x, y ); + Stdout.format( "The gcd of {} and {} is {}.", x, y, g ).newline; + + /* + * Manipulate the Foo global variable. + */ + + // Output its current value + Stdout.format( "Foo = {}", example.Foo ).newline; + + // Change its value + example.Foo = 3.1415926; + + // See if the change took effect + Stdout.format( "Foo = {}", example.Foo ).newline; +} diff --git a/Examples/d/simple/d2/runme.d b/Examples/d/simple/d2/runme.d new file mode 100644 index 000000000..7f278923b --- /dev/null +++ b/Examples/d/simple/d2/runme.d @@ -0,0 +1,27 @@ +module runme; + +import std.stdio; +static import example; + +void main() { + /* + * Call our gcd() function. + */ + int x = 42; + int y = 105; + int g = example.gcd(x, y); + writefln("The gcd of %s and %s is %s.", x, y, g); + + /* + * Manipulate the Foo global variable. + */ + + // Output its current value + writefln("Foo = %s", example.Foo); + + // Change its value + example.Foo = 3.1415926; + + // See if the change took effect + writefln("Foo = %s", example.Foo); +} diff --git a/Examples/d/simple/example.c b/Examples/d/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/d/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/d/simple/example.i b/Examples/d/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/d/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/d/variables/Makefile b/Examples/d/variables/Makefile new file mode 100644 index 000000000..312e6a9e9 --- /dev/null +++ b/Examples/d/variables/Makefile @@ -0,0 +1,28 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all diff --git a/Examples/d/variables/d1/runme.d b/Examples/d/variables/d1/runme.d new file mode 100644 index 000000000..35c896bdc --- /dev/null +++ b/Examples/d/variables/d1/runme.d @@ -0,0 +1,71 @@ +// This example illustrates global variable access from C#. +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + // Try to set the values of some global variables + example.ivar = 42; + example.svar = -31000; + example.lvar = 65537; + example.uivar = 123456; + example.usvar = 61000; + example.ulvar = 654321; + example.scvar = -13; + example.ucvar = 251; + example.cvar = 'S'; + example.fvar = 3.14159f; + example.dvar = 2.1828; + example.strvar = "Hello World"; + example.iptrvar = example.new_int(37); + example.ptptr = example.new_Point(37,42); + example.name = "Bill"; + + // Now print out the values of the variables + Stdout.formatln( "Variables (printed from D):" ); + Stdout.formatln( "ivar = {}", example.ivar ); + Stdout.formatln( "svar = {}", example.svar ); + Stdout.formatln( "lvar = {}", example.lvar ); + Stdout.formatln( "uivar = {}", example.uivar ); + Stdout.formatln( "usvar = {}", example.usvar ); + Stdout.formatln( "ulvar = {}", example.ulvar ); + Stdout.formatln( "scvar = {}", example.scvar ); + Stdout.formatln( "ucvar = {}", example.ucvar ); + Stdout.formatln( "fvar = {}", example.fvar ); + Stdout.formatln( "dvar = {}", example.dvar ); + Stdout.formatln( "cvar = {}", example.cvar ); + Stdout.formatln( "strvar = {}", example.strvar ); + Stdout.formatln( "cstrvar = {}", example.cstrvar ); + Stdout.formatln( "iptrvar = {}", example.iptrvar ); + Stdout.formatln( "name = {}", example.name ); + Stdout.formatln( "ptptr = {} {}", example.ptptr, example.Point_print(example.ptptr) ); + Stdout.formatln( "pt = {} {}", example.pt, example.Point_print(example.pt) ); + Stdout.formatln( "status = {}", example.status ); + + Stdout.formatln( "\nVariables (printed from the C library):" ); + example.print_vars(); + + Stdout.formatln( "\nNow I'm going to try and modify some read only variables:" ); + Stdout.formatln( "Checking that the read only variables are readonly..." ); + + Stdout( " 'path'..." ); + static if ( is( typeof( example.path = "a" ) ) ) + Stdout.formatln("Oh dear, this variable is not read only!"); + else + Stdout.formatln("Good."); + + Stdout( " 'status'..." ); + static if ( is( typeof( example.status = 2 ) ) ) + Stdout.formatln("Oh dear, this variable is not read only!"); + else + Stdout.formatln("Good."); + + Stdout.formatln( "\nI'm going to try and update a structure variable:" ); + + example.pt = example.ptptr; + + Stdout( "The new value is " ).flush; + example.pt_print(); + Stdout.formatln( "You should see the value {}", example.Point_print(example.ptptr) ); +} diff --git a/Examples/d/variables/d2/runme.d b/Examples/d/variables/d2/runme.d new file mode 100644 index 000000000..f80b81819 --- /dev/null +++ b/Examples/d/variables/d2/runme.d @@ -0,0 +1,71 @@ +// This example illustrates global variable access from C#. +module runme; + +import std.stdio; +static import example; + +void main() { + // Try to set the values of some global variables + example.ivar = 42; + example.svar = -31000; + example.lvar = 65537; + example.uivar = 123456; + example.usvar = 61000; + example.ulvar = 654321; + example.scvar = -13; + example.ucvar = 251; + example.cvar = 'S'; + example.fvar = 3.14159f; + example.dvar = 2.1828; + example.strvar = "Hello World"; + example.iptrvar = example.new_int(37); + example.ptptr = example.new_Point(37,42); + example.name = "Bill"; + + // Now print out the values of the variables + writefln( "Variables (printed from D):" ); + writefln( "ivar = %s", example.ivar ); + writefln( "svar = %s", example.svar ); + writefln( "lvar = %s", example.lvar ); + writefln( "uivar = %s", example.uivar ); + writefln( "usvar = %s", example.usvar ); + writefln( "ulvar = %s", example.ulvar ); + writefln( "scvar = %s", example.scvar ); + writefln( "ucvar = %s", example.ucvar ); + writefln( "fvar = %s", example.fvar ); + writefln( "dvar = %s", example.dvar ); + writefln( "cvar = %s", example.cvar ); + writefln( "strvar = %s", example.strvar ); + writefln( "cstrvar = %s", example.cstrvar ); + writefln( "iptrvar = %s", example.iptrvar ); + writefln( "name = %s", example.name ); + writefln( "ptptr = %s %s", example.ptptr, example.Point_print(example.ptptr) ); + writefln( "pt = %s %s", example.pt, example.Point_print(example.pt) ); + writefln( "status = %s", example.status ); + + writefln( "\nVariables (printed from the C library):" ); + example.print_vars(); + + writefln( "\nNow I'm going to try and modify some read only variables:" ); + writefln( "Checking that the read only variables are readonly..." ); + + writeln( " 'path'..." ); + static if ( is( typeof( example.path = "a" ) ) ) + writefln("Oh dear, this variable is not read only!"); + else + writefln("Good."); + + writeln( " 'status'..." ); + static if ( is( typeof( example.status = 2 ) ) ) + writefln("Oh dear, this variable is not read only!"); + else + writefln("Good."); + + writefln( "\nI'm going to try and update a structure variable:" ); + + example.pt = example.ptptr; + + write( "The new value is " ); + example.pt_print(); + writefln( "You should see the value %s", example.Point_print(example.ptptr) ); +} diff --git a/Examples/d/variables/example.c b/Examples/d/variables/example.c new file mode 100644 index 000000000..1bf9c120f --- /dev/null +++ b/Examples/d/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d, %d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/d/variables/example.h b/Examples/d/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/d/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/d/variables/example.i b/Examples/d/variables/example.i new file mode 100644 index 000000000..591b871ed --- /dev/null +++ b/Examples/d/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in new file mode 100644 index 000000000..2e9eb827f --- /dev/null +++ b/Examples/test-suite/d/Makefile.in @@ -0,0 +1,80 @@ +####################################################################### +# Makefile for D test-suite +####################################################################### + +LANGUAGE = d +srcdir = @srcdir@ +top_srcdir = ../@top_srcdir@ +top_builddir = ../@top_builddir@ + +ifeq (2,$(D_VERSION)) + VERSIONSUFFIX = .2 +else + VERSIONSUFFIX = .1 +endif + +TESTSUFFIX = _runme$(VERSIONSUFFIX).d + +CPP_TEST_CASES = \ + d_nativepointers \ + exception_partial_info + +include $(srcdir)/../common.mk + +# Override some variables from common.mk: + +TARGETSUFFIX = _wrap + +SWIGOPT+=-splitproxy -package $* + +# Rules for the different types of tests +%.cpptest: + $(setup) + +(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_cpp)) + +$(run_testcase) + +%.ctest: + $(setup) + +(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_c)) + +$(run_testcase) + +%.multicpptest: + $(setup) + +(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_multi_cpp)) + +$(run_testcase) + +# Makes a directory for the testcase if it does not exist +setup = \ + if [ -f $(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) ]; then \ + echo "$(ACTION)ing testcase $* (with run test) under $(LANGUAGE)" ; \ + else \ + echo "$(ACTION)ing testcase $* under $(LANGUAGE)" ; \ + fi; \ + if [ ! -d $*$(VERSIONSUFFIX) ]; then \ + mkdir $*$(VERSIONSUFFIX); \ + fi; \ + if [ ! -d $*$(VERSIONSUFFIX)/$* ]; then \ + mkdir $*$(VERSIONSUFFIX)/$*; \ + fi + +# Compiles D files then runs the testcase. A testcase is only run if +# a file is found which has _runme.d appended after the testcase name. +run_testcase = \ + if [ -f $(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) ]; then \ + cd $*$(VERSIONSUFFIX) && \ + $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \ + DFLAGS='-of$*_runme' \ + DSRCS='../$(srcdir)/$(TESTPREFIX)$*$(TESTSUFFIX) $*/*.d' d_compile && \ + env LD_LIBRARY_PATH=".:$$LD_LIBRARY_PATH" $(RUNTOOL) ./$*_runme; \ + else \ + cd $*$(VERSIONSUFFIX) && \ + $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \ + DFLAGS='-c' \ + DSRCS='$*/*.d' d_compile && cd .. ; \ + fi + +# Clean: remove testcase directories +%.clean: + @if [ -d $* ]; then \ + rm -rf $*; \ + fi diff --git a/Examples/test-suite/d/README b/Examples/test-suite/d/README new file mode 100644 index 000000000..bb5372882 --- /dev/null +++ b/Examples/test-suite/d/README @@ -0,0 +1,7 @@ +D language module testsuite +--------------------------- + +Please see ../README for the common readme file. + +By default the D1 version is built, set D_VERSION=2 (in the environment or at +the make command line) to run it for D2 instead. diff --git a/Examples/test-suite/d/aggregate_runme.1.d b/Examples/test-suite/d/aggregate_runme.1.d new file mode 100644 index 000000000..a00d34c25 --- /dev/null +++ b/Examples/test-suite/d/aggregate_runme.1.d @@ -0,0 +1,25 @@ +module aggregate_runme; + +import aggregate.aggregate; + +void main() { + // Confirm that move() returns correct results under normal use. + int result = move(UP); + if (result != UP) throw new Exception("UP failed"); + + result = move(DOWN); + if (result != DOWN) throw new Exception("DOWN failed"); + + result = move(LEFT); + if (result != LEFT) throw new Exception("LEFT failed"); + + result = move(RIGHT); + if (result != RIGHT) throw new Exception("RIGHT failed"); + + // Confirm that move() raises an exception when the contract is violated. + try { + move(0); + throw new Exception("0 test failed"); + } + catch (Exception e) {} +} diff --git a/Examples/test-suite/d/aggregate_runme.2.d b/Examples/test-suite/d/aggregate_runme.2.d new file mode 100644 index 000000000..a00d34c25 --- /dev/null +++ b/Examples/test-suite/d/aggregate_runme.2.d @@ -0,0 +1,25 @@ +module aggregate_runme; + +import aggregate.aggregate; + +void main() { + // Confirm that move() returns correct results under normal use. + int result = move(UP); + if (result != UP) throw new Exception("UP failed"); + + result = move(DOWN); + if (result != DOWN) throw new Exception("DOWN failed"); + + result = move(LEFT); + if (result != LEFT) throw new Exception("LEFT failed"); + + result = move(RIGHT); + if (result != RIGHT) throw new Exception("RIGHT failed"); + + // Confirm that move() raises an exception when the contract is violated. + try { + move(0); + throw new Exception("0 test failed"); + } + catch (Exception e) {} +} diff --git a/Examples/test-suite/d/allprotected_runme.1.d b/Examples/test-suite/d/allprotected_runme.1.d new file mode 100644 index 000000000..82a180e66 --- /dev/null +++ b/Examples/test-suite/d/allprotected_runme.1.d @@ -0,0 +1,65 @@ +module allprotected_runme; + +import allprotected.Klass; +import allprotected.ProtectedBase; + +void main() { + auto mpb = new MyProtectedBase("MyProtectedBase"); + mpb.accessProtected(); +} + +class MyProtectedBase : ProtectedBase { +public: + this(char[] name) { + super(name); + } + + void accessProtected() { + char[] s = virtualMethod(); + if (s != "ProtectedBase") + throw new Exception("Failed"); + + Klass k = instanceMethod(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = instanceOverloaded(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = instanceOverloaded(new Klass("xyz"), "abc"); + if (k.getName() != "abc") + throw new Exception("Failed"); + + k = staticMethod(new Klass("abc")); + if (k.getName() != "abc") + throw new Exception("Failed"); + + k = staticOverloaded(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = staticOverloaded(new Klass("xyz"), "abc"); + if (k.getName() != "abc") + throw new Exception("Failed"); + + instanceMemberVariable = 30; + int i = instanceMemberVariable; + if (i != 30) + throw new Exception("Failed"); + + staticMemberVariable = 40; + i = staticMemberVariable; + if (i != 40) + throw new Exception("Failed"); + + i = staticConstMemberVariable; + if (i != 20) + throw new Exception("Failed"); + + anEnum = ProtectedBase.AnEnum.EnumVal1; + ProtectedBase.AnEnum ae = anEnum; + if (ae != ProtectedBase.AnEnum.EnumVal1) + throw new Exception("Failed"); + } +} diff --git a/Examples/test-suite/d/allprotected_runme.2.d b/Examples/test-suite/d/allprotected_runme.2.d new file mode 100644 index 000000000..799230291 --- /dev/null +++ b/Examples/test-suite/d/allprotected_runme.2.d @@ -0,0 +1,65 @@ +module allprotected_runme; + +import allprotected.Klass; +import allprotected.ProtectedBase; + +void main() { + auto mpb = new MyProtectedBase("MyProtectedBase"); + mpb.accessProtected(); +} + +class MyProtectedBase : ProtectedBase { +public: + this(string name) { + super(name); + } + + void accessProtected() { + string s = virtualMethod(); + if (s != "ProtectedBase") + throw new Exception("Failed"); + + Klass k = instanceMethod(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = instanceOverloaded(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = instanceOverloaded(new Klass("xyz"), "abc"); + if (k.getName() != "abc") + throw new Exception("Failed"); + + k = staticMethod(new Klass("abc")); + if (k.getName() != "abc") + throw new Exception("Failed"); + + k = staticOverloaded(new Klass("xyz")); + if (k.getName() != "xyz") + throw new Exception("Failed"); + + k = staticOverloaded(new Klass("xyz"), "abc"); + if (k.getName() != "abc") + throw new Exception("Failed"); + + instanceMemberVariable = 30; + int i = instanceMemberVariable; + if (i != 30) + throw new Exception("Failed"); + + staticMemberVariable = 40; + i = staticMemberVariable; + if (i != 40) + throw new Exception("Failed"); + + i = staticConstMemberVariable; + if (i != 20) + throw new Exception("Failed"); + + anEnum = ProtectedBase.AnEnum.EnumVal1; + ProtectedBase.AnEnum ae = anEnum; + if (ae != ProtectedBase.AnEnum.EnumVal1) + throw new Exception("Failed"); + } +} diff --git a/Examples/test-suite/d/apply_strings_runme.1.d b/Examples/test-suite/d/apply_strings_runme.1.d new file mode 100644 index 000000000..960caa4ca --- /dev/null +++ b/Examples/test-suite/d/apply_strings_runme.1.d @@ -0,0 +1,12 @@ +module apply_strings_runme; + +import apply_strings.apply_strings; + +const char[] TEST_MESSAGE = "A message from target language to the C++ world and back again."; + +void main() { + if (UCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("UCharFunction failed"); + if (SCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("SCharFunction failed"); + auto pChar = CharFunction(null); + if (pChar !is null) throw new Exception("CharFunction failed"); +} diff --git a/Examples/test-suite/d/apply_strings_runme.2.d b/Examples/test-suite/d/apply_strings_runme.2.d new file mode 100644 index 000000000..86183f8a3 --- /dev/null +++ b/Examples/test-suite/d/apply_strings_runme.2.d @@ -0,0 +1,12 @@ +module apply_strings_runme; + +import apply_strings.apply_strings; + +enum string TEST_MESSAGE = "A message from target language to the C++ world and back again."; + +void main() { + if (UCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("UCharFunction failed"); + if (SCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("SCharFunction failed"); + auto pChar = CharFunction(null); + if (pChar !is null) throw new Exception("CharFunction failed"); +} diff --git a/Examples/test-suite/d/bools_runme.1.d b/Examples/test-suite/d/bools_runme.1.d new file mode 100644 index 000000000..f501b0762 --- /dev/null +++ b/Examples/test-suite/d/bools_runme.1.d @@ -0,0 +1,20 @@ +/// This is the bool runtime testcase. It checks that the C++ bool type works. +module bools_runme; + +import bools.bools; + +void main() { + bool t = true; + bool f = false; + + check_bo(f); + check_bo(t); +} + +void check_bo(bool input) { + for (int i = 0; i < 1000; ++i) { + if (bo(input) != input) { + throw new Exception("Runtime test check_bo failed."); + } + } +} diff --git a/Examples/test-suite/d/bools_runme.2.d b/Examples/test-suite/d/bools_runme.2.d new file mode 100644 index 000000000..f501b0762 --- /dev/null +++ b/Examples/test-suite/d/bools_runme.2.d @@ -0,0 +1,20 @@ +/// This is the bool runtime testcase. It checks that the C++ bool type works. +module bools_runme; + +import bools.bools; + +void main() { + bool t = true; + bool f = false; + + check_bo(f); + check_bo(t); +} + +void check_bo(bool input) { + for (int i = 0; i < 1000; ++i) { + if (bo(input) != input) { + throw new Exception("Runtime test check_bo failed."); + } + } +} diff --git a/Examples/test-suite/d/catches_runme.1.d b/Examples/test-suite/d/catches_runme.1.d new file mode 100644 index 000000000..55b18132d --- /dev/null +++ b/Examples/test-suite/d/catches_runme.1.d @@ -0,0 +1,33 @@ +module catches_runme; + +import catches.catches; + +void main() { + test({ test_catches(1); }, "C++ int exception thrown, value: 1"); + test({ test_catches(2); }, "two"); + test({ test_catches(3); }, "C++ ThreeException const & exception thrown"); + + test({ test_exception_specification(1); }, "C++ int exception thrown, value: 1"); + test({ test_exception_specification(2); }, "unknown exception"); + test({ test_exception_specification(3); }, "unknown exception"); + + test({ test_catches_all(1); }, "unknown exception"); +} + +void test(void delegate() command, char[] expectedMessage) { + bool didntThrow; + try { + command(); + didntThrow = true; + } catch (Exception e) { + if (e.msg != expectedMessage) { + throw new Exception("Failed to propagate C++ exception. Expected '" ~ + expectedMessage ~ "', but received '" ~ e.msg ~ "'."); + } + } + + if (didntThrow) { + throw new Exception("Failed to propagate C++ exception. Expected '" ~ + expectedMessage ~ "', but no exception was thrown."); + } +} diff --git a/Examples/test-suite/d/catches_runme.2.d b/Examples/test-suite/d/catches_runme.2.d new file mode 100644 index 000000000..508558485 --- /dev/null +++ b/Examples/test-suite/d/catches_runme.2.d @@ -0,0 +1,33 @@ +module catches_runme; + +import catches.catches; + +void main() { + test({ test_catches(1); }, "C++ int exception thrown, value: 1"); + test({ test_catches(2); }, "two"); + test({ test_catches(3); }, "C++ ThreeException const & exception thrown"); + + test({ test_exception_specification(1); }, "C++ int exception thrown, value: 1"); + test({ test_exception_specification(2); }, "unknown exception"); + test({ test_exception_specification(3); }, "unknown exception"); + + test({ test_catches_all(1); }, "unknown exception"); +} + +void test(void delegate() command, string expectedMessage) { + bool didntThrow; + try { + command(); + didntThrow = true; + } catch (Exception e) { + if (e.msg != expectedMessage) { + throw new Exception("Failed to propagate C++ exception. Expected '" ~ + expectedMessage ~ "', but received '" ~ e.msg ~ "'."); + } + } + + if (didntThrow) { + throw new Exception("Failed to propagate C++ exception. Expected '" ~ + expectedMessage ~ "', but no exception was thrown."); + } +} diff --git a/Examples/test-suite/d/char_strings_runme.1.d b/Examples/test-suite/d/char_strings_runme.1.d new file mode 100644 index 000000000..cde6fe0f7 --- /dev/null +++ b/Examples/test-suite/d/char_strings_runme.1.d @@ -0,0 +1,151 @@ +module char_strings_runme; + +import tango.text.convert.Integer; +import char_strings.char_strings; + +const char[] CPLUSPLUS_MSG = "A message from the deep dark world of C++, where anything is possible."; +const char[] OTHERLAND_MSG = "Little message from the safe world."; + +void main() { + const uint count = 10000; + uint i = 0; + + // get functions + for (i=0; i