diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i index f73326f50..a00dee177 100644 --- a/Examples/test-suite/argcargvtest.i +++ b/Examples/test-suite/argcargvtest.i @@ -15,7 +15,7 @@ int mainc(size_t argc, const char **argv) const char* mainv(size_t argc, const char **argv, int idx) { - return argv[idx]; + return argv[idx] ? argv[idx] : "<>"; } void initializeApp(size_t argc, const char **argv, bool setPGid = true, bool isMakeline = false) diff --git a/Examples/test-suite/csharp/argcargvtest_runme.cs b/Examples/test-suite/csharp/argcargvtest_runme.cs index 236c64f5d..83bc878bf 100644 --- a/Examples/test-suite/csharp/argcargvtest_runme.cs +++ b/Examples/test-suite/csharp/argcargvtest_runme.cs @@ -13,6 +13,8 @@ public class argcargvtest_runme { throw new Exception("bad main typemap"); if (!argcargvtest.mainv(targs, 1).Equals("hola")) throw new Exception("bad main typemap"); + if (!argcargvtest.mainv(targs, 2).Equals("<>")) + throw new Exception("bad main typemap"); // For dynamically typed languages we test this throws an exception or similar // at runtime, but for C# this doesn't even compile (but we can't easily @@ -25,6 +27,8 @@ public class argcargvtest_runme { string[] empty_args = {}; if (argcargvtest.mainc(empty_args) != 0) throw new Exception("bad main typemap"); + if (!argcargvtest.mainv(empty_args, 0).Equals("<>")) + throw new Exception("bad main typemap"); // Check that empty strings are handled. string[] empty_string = {"hello", "", "world"}; @@ -36,5 +40,7 @@ public class argcargvtest_runme { throw new Exception("bad main typemap"); if (argcargvtest.mainv(empty_string, 2) != "world") throw new Exception("bad main typemap"); + if (argcargvtest.mainv(empty_string, 3) != "<>") + throw new Exception("bad main typemap"); } } diff --git a/Examples/test-suite/d/argcargvtest_runme.2.d b/Examples/test-suite/d/argcargvtest_runme.2.d index 17aa4413a..466f19ed5 100644 --- a/Examples/test-suite/d/argcargvtest_runme.2.d +++ b/Examples/test-suite/d/argcargvtest_runme.2.d @@ -10,6 +10,7 @@ void main() { auto targs = ["hi", "hola"]; enforce(mainv(targs, 0) == "hi", "calling mainv failed"); enforce(mainv(targs, 1) == "hola", "calling mainv failed"); + enforce(mainv(targs, 2) == "<>", "calling mainv failed"); // For dynamically typed languages we test this throws an exception or similar // at runtime, but for D language this doesn't even compile (but we can't easily @@ -21,6 +22,7 @@ void main() { // Check that an empty array works. string[] empty_args; enforce(mainc(empty_args) == 0, "calling mainc failed"); + enforce(mainv(empty_args, 0) == "<>", "calling mainv failed"); // In D, an empty array created like empty_args is identical to null. enforce(mainc(null) == 0, "calling mainc failed"); // However an empty array created like this has a non-null .array so test @@ -38,4 +40,5 @@ void main() { enforce(mainv(empty_string, 0) == "hello", "calling mainv failed"); enforce(mainv(empty_string, 1) == "", "calling mainv failed"); enforce(mainv(empty_string, 2) == "world", "calling mainv failed"); + enforce(mainv(empty_string, 3) == "<>", "calling mainv failed"); } diff --git a/Examples/test-suite/go/argcargvtest_runme.go b/Examples/test-suite/go/argcargvtest_runme.go index 2beec5a2e..1bb1feb77 100644 --- a/Examples/test-suite/go/argcargvtest_runme.go +++ b/Examples/test-suite/go/argcargvtest_runme.go @@ -15,6 +15,9 @@ func main() { if rs := wrap.Mainv(targs, 1); rs != "hola" { panic(rs) } + if rs := wrap.Mainv(targs, 2); rs != "<>" { + panic(rs) + } // For dynamically typed languages we test this throws an exception or similar // at runtime, but for Go this doesn't even compile (but we can't easily @@ -28,6 +31,9 @@ func main() { if ri := wrap.Mainc(empty_args); ri != 0 { panic(ri) } + if rs := wrap.Mainv(empty_args, 0); rs != "<>" { + panic(rs) + } // Check that empty strings are handled. empty_string := []string{"hello", "", "world"}; @@ -43,4 +49,7 @@ func main() { if rs := wrap.Mainv(empty_string, 2); rs != "world" { panic(rs) } + if rs := wrap.Mainv(empty_string, 3); rs != "<>" { + panic(rs) + } } diff --git a/Examples/test-suite/java/argcargvtest_runme.java b/Examples/test-suite/java/argcargvtest_runme.java index d5f4eb1e4..376b368ab 100644 --- a/Examples/test-suite/java/argcargvtest_runme.java +++ b/Examples/test-suite/java/argcargvtest_runme.java @@ -23,6 +23,8 @@ public class argcargvtest_runme { throw new RuntimeException("bad main typemap"); if (!test.mainv(targs, 1).equals("hola")) throw new RuntimeException("bad main typemap"); + if (!test.mainv(targs, 2).equals("<>")) + throw new RuntimeException("bad main typemap"); // For dynamically typed languages we test this throws an exception or similar // at runtime, but for Java this doesn't even compile (but we can't easily @@ -35,6 +37,8 @@ public class argcargvtest_runme { String[] empty_args = {}; if (test.mainc(empty_args) != 0) throw new RuntimeException("bad main typemap"); + if (!test.mainv(empty_args, 0).equals("<>")) + throw new RuntimeException("bad main typemap"); // Check that empty strings are handled. String[] empty_string = {"hello", "", "world"}; @@ -46,5 +50,7 @@ public class argcargvtest_runme { throw new RuntimeException("bad main typemap"); if (!test.mainv(empty_string, 2).equals("world")) throw new RuntimeException("bad main typemap"); + if (!test.mainv(empty_string, 3).equals("<>")) + throw new RuntimeException("bad main typemap"); } } diff --git a/Examples/test-suite/javascript/argcargvtest_runme.js b/Examples/test-suite/javascript/argcargvtest_runme.js index b6fd00fc3..855354224 100644 --- a/Examples/test-suite/javascript/argcargvtest_runme.js +++ b/Examples/test-suite/javascript/argcargvtest_runme.js @@ -9,6 +9,8 @@ if (test.mainv(targs, 0) != "hi") throw "calling mainv failed"; if (test.mainv(targs, 1) != "hola") throw "calling mainv failed"; +if (test.mainv(targs, 2) != "<>") + throw "calling mainv failed"; caughtException = false; try { @@ -26,6 +28,8 @@ test.initializeApp(largs); const empty_args = []; if (test.mainc(empty_args) != 0) throw "bad main typemap"; +if (test.mainv(empty_args, 0) != "<>") + throw "calling mainv failed"; // Check that empty strings are handled. const empty_string = ["hello", "", "world"]; @@ -37,3 +41,5 @@ if (test.mainv(empty_string, 1) != "") throw "bad main typemap"; if (test.mainv(empty_string, 2) != "world") throw "bad main typemap"; +if (test.mainv(empty_string, 3) != "<>") + throw "bad main typemap"; diff --git a/Examples/test-suite/lua/argcargvtest_runme.lua b/Examples/test-suite/lua/argcargvtest_runme.lua index 3b164478e..eea522272 100644 --- a/Examples/test-suite/lua/argcargvtest_runme.lua +++ b/Examples/test-suite/lua/argcargvtest_runme.lua @@ -13,6 +13,7 @@ assert(v.mainc(largs) == 3, "bad main typemap") targs = {"hi", "hola"} assert(v.mainv(targs, 0) == "hi", "bad main typemap") assert(v.mainv(targs, 1) == "hola", "bad main typemap") +assert(v.mainv(targs, 2) == "<>", "bad main typemap") errorVal = 0 function try() @@ -26,6 +27,7 @@ v.initializeApp(largs) -- Check that an empty array works. empty_args = {} assert(v.mainc(empty_args) == 0, "bad main typemap") +assert(v.mainv(empty_args, 0) == "<>", "bad main typemap") -- Check that empty strings are handled. empty_string = {"hello", "", "world"} @@ -33,3 +35,4 @@ assert(v.mainc(empty_string) == 3, "bad main typemap") assert(v.mainv(empty_string, 0) == "hello", "bad main typemap") assert(v.mainv(empty_string, 1) == "", "bad main typemap") assert(v.mainv(empty_string, 2) == "world", "bad main typemap") +assert(v.mainv(empty_string, 3) == "<>", "bad main typemap") diff --git a/Examples/test-suite/mzscheme/argcargvtest_runme.scm b/Examples/test-suite/mzscheme/argcargvtest_runme.scm index 5d06c3bfb..f1c43a703 100644 --- a/Examples/test-suite/mzscheme/argcargvtest_runme.scm +++ b/Examples/test-suite/mzscheme/argcargvtest_runme.scm @@ -9,6 +9,8 @@ (error "calling mainv failed")) (when (not (string=? (mainv targs 1) "hola")) (error "calling mainv failed")) +(when (not (string=? (mainv targs 2) "<>")) + (error "calling mainv failed")) (with-handlers ([exn:fail? (lambda (exn) (when (not (string=? (exn-message exn) @@ -23,6 +25,8 @@ (define empty_args #()) (when (not (= (mainc empty_args) 0)) (error "calling mainc failed")) +(when (not (string=? (mainv empty_args 0) "<>")) + (error "calling mainv failed")) ; Check that empty strings are handled. (define empty_string #("hello" "" "world")) @@ -34,5 +38,7 @@ (error "calling mainv 1 failed")) (when (not (string=? (mainv empty_string 2) "world")) (error "calling mainv 2 failed")) +(when (not (string=? (mainv empty_string 3) "<>")) + (error "calling mainv 3 failed")) (exit 0) diff --git a/Examples/test-suite/octave/argcargvtest_runme.m b/Examples/test-suite/octave/argcargvtest_runme.m index 907cb9e32..23687594f 100644 --- a/Examples/test-suite/octave/argcargvtest_runme.m +++ b/Examples/test-suite/octave/argcargvtest_runme.m @@ -17,6 +17,9 @@ endif if (mainv(targs,1) != 'hola') error("bad main typemap"); endif +if (mainv(targs,2) != '<>') + error("bad main typemap"); +endif try error_flag = 0; @@ -36,6 +39,9 @@ empty_args={}; if (mainc(empty_args) != 0) error("bad main typemap"); endif +if (mainv(empty_args,0) != '<>') + error("bad main typemap"); +endif # Check that empty strings are handled. empty_string={"hello", blanks(0), "world"}; @@ -52,3 +58,6 @@ endif if (mainv(empty_string, 2) != "world") error("bad main typemap"); endif +if (mainv(empty_string, 3) != "<>") + error("bad main typemap"); +endif diff --git a/Examples/test-suite/perl5/argcargvtest_runme.pl b/Examples/test-suite/perl5/argcargvtest_runme.pl index 5afd7ab57..ccc570f08 100644 --- a/Examples/test-suite/perl5/argcargvtest_runme.pl +++ b/Examples/test-suite/perl5/argcargvtest_runme.pl @@ -1,6 +1,6 @@ use strict; use warnings; -use Test::More tests => 14; +use Test::More tests => 17; BEGIN { use_ok('argcargvtest') } require_ok('argcargvtest'); @@ -10,6 +10,7 @@ is(argcargvtest::mainc($largs), 3, "test main typemap 1"); my $targs = ["hi", "hola"]; is(argcargvtest::mainv($targs, 0), "hi", "test main typemap 2a"); is(argcargvtest::mainv($targs, 1), "hola", "test main typemap 2b"); +is(argcargvtest::mainv($targs, 2), "<>", "test main typemap 2c"); my $errorVal = 0; my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;); @@ -21,6 +22,7 @@ is(argcargvtest::initializeApp($largs), undef, "test main typemap 5"); # Check that an empty array works. my @empty_args = (); is(argcargvtest::mainc(\@empty_args), 0, "test main typemap 6"); +is(argcargvtest::mainv(\@empty_args, 0), "<>", "test main typemap 6a"); # Check that empty strings are handled. my @empty_string = ("hello", "", "world"); @@ -28,5 +30,6 @@ is(argcargvtest::mainc(\@empty_string), 3, "test main typemap 7"); is(argcargvtest::mainv(\@empty_string, 0), "hello", "test main typemap 8a"); is(argcargvtest::mainv(\@empty_string, 1), "", "test main typemap 8b"); is(argcargvtest::mainv(\@empty_string, 2), "world", "test main typemap 8c"); +is(argcargvtest::mainv(\@empty_string, 3), "<>", "test main typemap 8d"); ok(1, "done"); diff --git a/Examples/test-suite/php/argcargvtest_runme.php b/Examples/test-suite/php/argcargvtest_runme.php index 62525b4d0..dac427098 100644 --- a/Examples/test-suite/php/argcargvtest_runme.php +++ b/Examples/test-suite/php/argcargvtest_runme.php @@ -15,6 +15,7 @@ check::equal(mainc($largs), 3, 'Test main typemap 1'); $targs = array('hi', 'hola'); check::equal(mainv($targs, 0), 'hi', 'Test main typemap 2a'); check::equal(mainv($targs, 1), 'hola', 'Test main typemap 2b'); +check::equal(mainv($targs, 2), '<>', 'Test main typemap 2c'); $error = 0; try { @@ -30,6 +31,7 @@ initializeApp($largs); # Check that an empty array works. $empty_args = []; check::equal(mainc($empty_args), 0, "test main typemap 4"); +check::equal(mainv($empty_args, 0), '<>', 'Test main typemap 4a'); # Check that empty strings are handled. $empty_string = ["hello", "", "world"]; @@ -37,5 +39,6 @@ check::equal(mainc($empty_string), 3, "test main typemap 5"); check::equal(mainv($empty_string, 0), "hello", "test main typemap 6a"); check::equal(mainv($empty_string, 1), "", "test main typemap 6b"); check::equal(mainv($empty_string, 2), "world", "test main typemap 6c"); +check::equal(mainv($empty_string, 3), "<>", "test main typemap 6d"); check::done(); diff --git a/Examples/test-suite/python/argcargvtest_runme.py b/Examples/test-suite/python/argcargvtest_runme.py index 9609ebf02..52d428b2d 100644 --- a/Examples/test-suite/python/argcargvtest_runme.py +++ b/Examples/test-suite/python/argcargvtest_runme.py @@ -13,6 +13,8 @@ if mainv(targs, 0) != "hi": raise RuntimeError("bad main typemap") if mainv(targs, 1) != "hola": raise RuntimeError("bad main typemap") +if mainv(targs, 2) != "<>": + raise RuntimeError("bad main typemap") try: error = 0 @@ -30,9 +32,13 @@ initializeApp(largs) empty_args = [] if mainc(empty_args) != 0: raise RuntimeError("bad main typemap") +if mainv(empty_args, 0) != "<>": + raise RuntimeError("bad main typemap") empty_tuple = () if mainc(empty_tuple) != 0: raise RuntimeError("bad main typemap") +if mainv(empty_tuple, 0) != "<>": + raise RuntimeError("bad main typemap") # Check that empty strings are handled. empty_string = ["hello", "", "world"] @@ -44,3 +50,5 @@ if mainv(empty_string, 1) != "": raise RuntimeError("bad main typemap") if mainv(empty_string, 2) != "world": raise RuntimeError("bad main typemap") +if mainv(empty_string, 3) != "<>": + raise RuntimeError("bad main typemap") diff --git a/Examples/test-suite/r/argcargvtest_runme.R b/Examples/test-suite/r/argcargvtest_runme.R index 7f4986df2..bbb474763 100644 --- a/Examples/test-suite/r/argcargvtest_runme.R +++ b/Examples/test-suite/r/argcargvtest_runme.R @@ -10,6 +10,7 @@ unittest(3, mainc(largs)) targs = c("hi", "hola") unittest("hi", mainv(targs, 0)) unittest("hola", mainv(targs, 1)) +unittest("<>", mainv(targs, 2)) # R convert the string to a string vector with a single string. # So instead of exception we simply get null @@ -33,6 +34,7 @@ initializeApp(largs, TRUE) # Check that an empty array works. empty_args = c() unittest(0, mainc(empty_args)) +unittest("<>", mainv(empty_args, 0)) # check dispatcher with empty array. initializeApp(empty_args) @@ -44,3 +46,4 @@ unittest(3, mainc(empty_string)) unittest("hello", mainv(empty_string, 0)) unittest("", mainv(empty_string, 1)) unittest("world", mainv(empty_string, 2)) +unittest("<>", mainv(empty_string, 3)) diff --git a/Examples/test-suite/ruby/argcargvtest_runme.rb b/Examples/test-suite/ruby/argcargvtest_runme.rb index 672c877c9..da6536593 100644 --- a/Examples/test-suite/ruby/argcargvtest_runme.rb +++ b/Examples/test-suite/ruby/argcargvtest_runme.rb @@ -18,6 +18,9 @@ end if mainv($targs, 1) != "hola" raise RuntimeError, "bad main typemap" end +if mainv($targs, 2) != "<>" + raise RuntimeError, "bad main typemap" +end $error = 0 $ret = 0 @@ -39,6 +42,9 @@ $empty_args = [] if mainc($empty_args) != 0 raise RuntimeError, "bad main typemap" end +if mainv($empty_args, 0) != "<>" + raise RuntimeError, "bad main typemap" +end # Check that empty strings are handled. $empty_string = ["hello", "", "world"] @@ -54,3 +60,6 @@ end if mainv($empty_string, 2) != "world" raise RuntimeError, "bad main typemap" end +if mainv($empty_string, 3) != "<>" + raise RuntimeError, "bad main typemap" +end diff --git a/Examples/test-suite/schemerunme/argcargvtest.scm b/Examples/test-suite/schemerunme/argcargvtest.scm index 7b4e90e9a..bf7d90b5b 100644 --- a/Examples/test-suite/schemerunme/argcargvtest.scm +++ b/Examples/test-suite/schemerunme/argcargvtest.scm @@ -7,6 +7,8 @@ (error "calling mainv failed")) (when (not (string=? (mainv targs 1) "hola")) (error "calling mainv failed")) +(when (not (string=? (mainv targs 2) "<>")) + (error "calling mainv failed")) (expect-throw 'swig-contract-assertion-failed (mainv "hello" 1)) @@ -17,6 +19,8 @@ (define empty_args #()) (when (not (= (mainc empty_args) 0)) (error "calling mainc failed")) +(when (not (string=? (mainv empty_args 0) "<>")) + (error "calling mainv failed")) ; Check that empty strings are handled. (define empty_string #("hello" "" "world")) @@ -28,5 +32,7 @@ (error "calling mainv 1 failed")) (when (not (string=? (mainv empty_string 2) "world")) (error "calling mainv 2 failed")) +(when (not (string=? (mainv empty_string 3) "<>")) + (error "calling mainv 3 failed")) (exit 0) diff --git a/Examples/test-suite/scilab/argcargvtest_runme.sci b/Examples/test-suite/scilab/argcargvtest_runme.sci index 55c7ded29..b72f84935 100644 --- a/Examples/test-suite/scilab/argcargvtest_runme.sci +++ b/Examples/test-suite/scilab/argcargvtest_runme.sci @@ -6,6 +6,7 @@ checkequal(mainc(largs), 3, "calling mainc"); targs = ["hi" "hola"] checkequal(mainv(targs, 0), "hi", "calling mainv"); checkequal(mainv(targs, 1), "hola", "calling mainv"); +checkequal(mainv(targs, 2), "<>", "calling mainv"); checkequal(mainv("hi", 0), "hi", "calling mainv with a single string"); @@ -20,6 +21,7 @@ initializeApp(largs); // Check that an empty array works. empty_args = []; checkequal(mainc(empty_args), 0, "calling mainc"); +checkequal(mainv(empty_args, 0), "<>", "calling mainv"); // Check that empty strings are handled. empty_string = ["hello", "", "world"]; @@ -27,5 +29,6 @@ checkequal(mainc(empty_string), 3, "calling mainc"); checkequal(mainv(empty_string, 0), "hello", "calling mainv"); checkequal(mainv(empty_string, 1), "", "calling mainv"); checkequal(mainv(empty_string, 2), "world", "calling mainv"); +checkequal(mainv(empty_string, 3), "<>", "calling mainv"); exec("swigtest.quit", -1); diff --git a/Examples/test-suite/tcl/argcargvtest_runme.tcl b/Examples/test-suite/tcl/argcargvtest_runme.tcl index f77097eb7..bb7656c5a 100644 --- a/Examples/test-suite/tcl/argcargvtest_runme.tcl +++ b/Examples/test-suite/tcl/argcargvtest_runme.tcl @@ -17,6 +17,10 @@ if {[mainv $targs 1] != "hola"} { puts stderr "bad main typemap" exit 1 } +if {[mainv $targs 2] != "<>"} { + puts stderr "bad main typemap" + exit 1 +} set targs " hi hola " if {[mainv $targs 0] != "hi"} { @@ -41,6 +45,10 @@ if {[mainc $empty_args] != 0} { puts stderr "bad main typemap" exit 1 } +if {[mainv $empty_args 0] != "<>"} { + puts stderr "bad main typemap" + exit 1 +} # Check that empty strings are handled. set empty_string {"hello" "" "world"} @@ -60,3 +68,7 @@ if {[mainv $empty_string 2] != "world"} { puts stderr "bad main typemap" exit 1 } +if {[mainv $empty_string 3] != "<>"} { + puts stderr "bad main typemap" + exit 1 +} diff --git a/Lib/csharp/argcargv.i b/Lib/csharp/argcargv.i index 1dd5ee5a5..2dae1f6dc 100644 --- a/Lib/csharp/argcargv.i +++ b/Lib/csharp/argcargv.i @@ -32,8 +32,10 @@ SWIGEXPORT void* SWIGSTDCALL SWIG_csharp_string_array_to_c(int len, void *array) size_t alen, slen; char *p, **ptr; SWIG_csharp_string_array *ret; - /* Special care is needed here to handle an empty array. */ - alen = sizeof(SWIG_csharp_string_array) + sizeof(char *) * (len - (len > 0)); + /* We don't need to add one to len for the terminating NULL here because + * SWIG_csharp_string_array includes one element already. + */ + alen = sizeof(SWIG_csharp_string_array) + sizeof(char *) * len; ret = (SWIG_csharp_string_array *)malloc(alen); if (ret == SWIG_NULLPTR) { SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "fail to duplicate array."); @@ -52,6 +54,7 @@ SWIGEXPORT void* SWIGSTDCALL SWIG_csharp_string_array_to_c(int len, void *array) memcpy(p, ptr[i], slen); ret->array[i] = p; } + ret->array[i] = SWIG_NULLPTR; return ret; } diff --git a/Lib/r/argcargv.i b/Lib/r/argcargv.i index 7ca3618bf..9224d3a30 100644 --- a/Lib/r/argcargv.i +++ b/Lib/r/argcargv.i @@ -17,6 +17,7 @@ /* Empty array */ $1 = 0; $2 = ($2_ltype) malloc(sizeof($*2_ltype)); + $2[0] = SWIG_NULLPTR; } else if (!Rf_isVectorAtomic($input) || TYPEOF($input) != STRSXP) { SWIG_exception_fail(SWIG_RuntimeError, "Wrong array type."); } else {