argcargv.i: NULL terminate argv with empty input
Fixes needed for: C# R
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index f73326f..a00dee1 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -15,7 +15,7 @@
const char* mainv(size_t argc, const char **argv, int idx)
{
- return argv[idx];
+ return argv[idx] ? argv[idx] : "<<NULL>>";
}
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 236c64f..83bc878 100644
--- a/Examples/test-suite/csharp/argcargvtest_runme.cs
+++ b/Examples/test-suite/csharp/argcargvtest_runme.cs
@@ -13,6 +13,8 @@
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("<<NULL>>"))
+ 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 @@
string[] empty_args = {};
if (argcargvtest.mainc(empty_args) != 0)
throw new Exception("bad main typemap");
+ if (!argcargvtest.mainv(empty_args, 0).Equals("<<NULL>>"))
+ throw new Exception("bad main typemap");
// Check that empty strings are handled.
string[] empty_string = {"hello", "", "world"};
@@ -36,5 +40,7 @@
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) != "<<NULL>>")
+ 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 17aa441..466f19e 100644
--- a/Examples/test-suite/d/argcargvtest_runme.2.d
+++ b/Examples/test-suite/d/argcargvtest_runme.2.d
@@ -10,6 +10,7 @@
auto targs = ["hi", "hola"];
enforce(mainv(targs, 0) == "hi", "calling mainv failed");
enforce(mainv(targs, 1) == "hola", "calling mainv failed");
+ enforce(mainv(targs, 2) == "<<NULL>>", "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 @@
// Check that an empty array works.
string[] empty_args;
enforce(mainc(empty_args) == 0, "calling mainc failed");
+ enforce(mainv(empty_args, 0) == "<<NULL>>", "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 @@
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) == "<<NULL>>", "calling mainv failed");
}
diff --git a/Examples/test-suite/go/argcargvtest_runme.go b/Examples/test-suite/go/argcargvtest_runme.go
index 2beec5a..1bb1feb 100644
--- a/Examples/test-suite/go/argcargvtest_runme.go
+++ b/Examples/test-suite/go/argcargvtest_runme.go
@@ -15,6 +15,9 @@
if rs := wrap.Mainv(targs, 1); rs != "hola" {
panic(rs)
}
+ if rs := wrap.Mainv(targs, 2); rs != "<<NULL>>" {
+ 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 @@
if ri := wrap.Mainc(empty_args); ri != 0 {
panic(ri)
}
+ if rs := wrap.Mainv(empty_args, 0); rs != "<<NULL>>" {
+ panic(rs)
+ }
// Check that empty strings are handled.
empty_string := []string{"hello", "", "world"};
@@ -43,4 +49,7 @@
if rs := wrap.Mainv(empty_string, 2); rs != "world" {
panic(rs)
}
+ if rs := wrap.Mainv(empty_string, 3); rs != "<<NULL>>" {
+ panic(rs)
+ }
}
diff --git a/Examples/test-suite/java/argcargvtest_runme.java b/Examples/test-suite/java/argcargvtest_runme.java
index d5f4eb1..376b368 100644
--- a/Examples/test-suite/java/argcargvtest_runme.java
+++ b/Examples/test-suite/java/argcargvtest_runme.java
@@ -23,6 +23,8 @@
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("<<NULL>>"))
+ 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 @@
String[] empty_args = {};
if (test.mainc(empty_args) != 0)
throw new RuntimeException("bad main typemap");
+ if (!test.mainv(empty_args, 0).equals("<<NULL>>"))
+ throw new RuntimeException("bad main typemap");
// Check that empty strings are handled.
String[] empty_string = {"hello", "", "world"};
@@ -46,5 +50,7 @@
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("<<NULL>>"))
+ 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 b6fd00f..8553542 100644
--- a/Examples/test-suite/javascript/argcargvtest_runme.js
+++ b/Examples/test-suite/javascript/argcargvtest_runme.js
@@ -9,6 +9,8 @@
throw "calling mainv failed";
if (test.mainv(targs, 1) != "hola")
throw "calling mainv failed";
+if (test.mainv(targs, 2) != "<<NULL>>")
+ throw "calling mainv failed";
caughtException = false;
try {
@@ -26,6 +28,8 @@
const empty_args = [];
if (test.mainc(empty_args) != 0)
throw "bad main typemap";
+if (test.mainv(empty_args, 0) != "<<NULL>>")
+ throw "calling mainv failed";
// Check that empty strings are handled.
const empty_string = ["hello", "", "world"];
@@ -37,3 +41,5 @@
throw "bad main typemap";
if (test.mainv(empty_string, 2) != "world")
throw "bad main typemap";
+if (test.mainv(empty_string, 3) != "<<NULL>>")
+ throw "bad main typemap";
diff --git a/Examples/test-suite/lua/argcargvtest_runme.lua b/Examples/test-suite/lua/argcargvtest_runme.lua
index 3b16447..eea5222 100644
--- a/Examples/test-suite/lua/argcargvtest_runme.lua
+++ b/Examples/test-suite/lua/argcargvtest_runme.lua
@@ -13,6 +13,7 @@
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) == "<<NULL>>", "bad main typemap")
errorVal = 0
function try()
@@ -26,6 +27,7 @@
-- Check that an empty array works.
empty_args = {}
assert(v.mainc(empty_args) == 0, "bad main typemap")
+assert(v.mainv(empty_args, 0) == "<<NULL>>", "bad main typemap")
-- Check that empty strings are handled.
empty_string = {"hello", "", "world"}
@@ -33,3 +35,4 @@
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) == "<<NULL>>", "bad main typemap")
diff --git a/Examples/test-suite/mzscheme/argcargvtest_runme.scm b/Examples/test-suite/mzscheme/argcargvtest_runme.scm
index 5d06c3b..f1c43a7 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) "<<NULL>>"))
+ (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) "<<NULL>>"))
+ (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) "<<NULL>>"))
+ (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 907cb9e..2368759 100644
--- a/Examples/test-suite/octave/argcargvtest_runme.m
+++ b/Examples/test-suite/octave/argcargvtest_runme.m
@@ -17,6 +17,9 @@
if (mainv(targs,1) != 'hola')
error("bad main typemap");
endif
+if (mainv(targs,2) != '<<NULL>>')
+ error("bad main typemap");
+endif
try
error_flag = 0;
@@ -36,6 +39,9 @@
if (mainc(empty_args) != 0)
error("bad main typemap");
endif
+if (mainv(empty_args,0) != '<<NULL>>')
+ error("bad main typemap");
+endif
# Check that empty strings are handled.
empty_string={"hello", blanks(0), "world"};
@@ -52,3 +58,6 @@
if (mainv(empty_string, 2) != "world")
error("bad main typemap");
endif
+if (mainv(empty_string, 3) != "<<NULL>>")
+ error("bad main typemap");
+endif
diff --git a/Examples/test-suite/perl5/argcargvtest_runme.pl b/Examples/test-suite/perl5/argcargvtest_runme.pl
index 5afd7ab..ccc570f 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 @@
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), "<<NULL>>", "test main typemap 2c");
my $errorVal = 0;
my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;);
@@ -21,6 +22,7 @@
# 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), "<<NULL>>", "test main typemap 6a");
# Check that empty strings are handled.
my @empty_string = ("hello", "", "world");
@@ -28,5 +30,6 @@
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), "<<NULL>>", "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 62525b4..dac4270 100644
--- a/Examples/test-suite/php/argcargvtest_runme.php
+++ b/Examples/test-suite/php/argcargvtest_runme.php
@@ -15,6 +15,7 @@
$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), '<<NULL>>', 'Test main typemap 2c');
$error = 0;
try {
@@ -30,6 +31,7 @@
# Check that an empty array works.
$empty_args = [];
check::equal(mainc($empty_args), 0, "test main typemap 4");
+check::equal(mainv($empty_args, 0), '<<NULL>>', 'Test main typemap 4a');
# Check that empty strings are handled.
$empty_string = ["hello", "", "world"];
@@ -37,5 +39,6 @@
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), "<<NULL>>", "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 9609ebf..52d428b 100644
--- a/Examples/test-suite/python/argcargvtest_runme.py
+++ b/Examples/test-suite/python/argcargvtest_runme.py
@@ -13,6 +13,8 @@
raise RuntimeError("bad main typemap")
if mainv(targs, 1) != "hola":
raise RuntimeError("bad main typemap")
+if mainv(targs, 2) != "<<NULL>>":
+ raise RuntimeError("bad main typemap")
try:
error = 0
@@ -30,9 +32,13 @@
empty_args = []
if mainc(empty_args) != 0:
raise RuntimeError("bad main typemap")
+if mainv(empty_args, 0) != "<<NULL>>":
+ raise RuntimeError("bad main typemap")
empty_tuple = ()
if mainc(empty_tuple) != 0:
raise RuntimeError("bad main typemap")
+if mainv(empty_tuple, 0) != "<<NULL>>":
+ raise RuntimeError("bad main typemap")
# Check that empty strings are handled.
empty_string = ["hello", "", "world"]
@@ -44,3 +50,5 @@
raise RuntimeError("bad main typemap")
if mainv(empty_string, 2) != "world":
raise RuntimeError("bad main typemap")
+if mainv(empty_string, 3) != "<<NULL>>":
+ raise RuntimeError("bad main typemap")
diff --git a/Examples/test-suite/r/argcargvtest_runme.R b/Examples/test-suite/r/argcargvtest_runme.R
index 7f4986d..bbb4747 100644
--- a/Examples/test-suite/r/argcargvtest_runme.R
+++ b/Examples/test-suite/r/argcargvtest_runme.R
@@ -10,6 +10,7 @@
targs = c("hi", "hola")
unittest("hi", mainv(targs, 0))
unittest("hola", mainv(targs, 1))
+unittest("<<NULL>>", 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 @@
# Check that an empty array works.
empty_args = c()
unittest(0, mainc(empty_args))
+unittest("<<NULL>>", mainv(empty_args, 0))
# check dispatcher with empty array.
initializeApp(empty_args)
@@ -44,3 +46,4 @@
unittest("hello", mainv(empty_string, 0))
unittest("", mainv(empty_string, 1))
unittest("world", mainv(empty_string, 2))
+unittest("<<NULL>>", mainv(empty_string, 3))
diff --git a/Examples/test-suite/ruby/argcargvtest_runme.rb b/Examples/test-suite/ruby/argcargvtest_runme.rb
index 672c877..da65365 100644
--- a/Examples/test-suite/ruby/argcargvtest_runme.rb
+++ b/Examples/test-suite/ruby/argcargvtest_runme.rb
@@ -18,6 +18,9 @@
if mainv($targs, 1) != "hola"
raise RuntimeError, "bad main typemap"
end
+if mainv($targs, 2) != "<<NULL>>"
+ raise RuntimeError, "bad main typemap"
+end
$error = 0
$ret = 0
@@ -39,6 +42,9 @@
if mainc($empty_args) != 0
raise RuntimeError, "bad main typemap"
end
+if mainv($empty_args, 0) != "<<NULL>>"
+ raise RuntimeError, "bad main typemap"
+end
# Check that empty strings are handled.
$empty_string = ["hello", "", "world"]
@@ -54,3 +60,6 @@
if mainv($empty_string, 2) != "world"
raise RuntimeError, "bad main typemap"
end
+if mainv($empty_string, 3) != "<<NULL>>"
+ raise RuntimeError, "bad main typemap"
+end
diff --git a/Examples/test-suite/schemerunme/argcargvtest.scm b/Examples/test-suite/schemerunme/argcargvtest.scm
index 7b4e90e..bf7d90b 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) "<<NULL>>"))
+ (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) "<<NULL>>"))
+ (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) "<<NULL>>"))
+ (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 55c7ded..b72f849 100644
--- a/Examples/test-suite/scilab/argcargvtest_runme.sci
+++ b/Examples/test-suite/scilab/argcargvtest_runme.sci
@@ -6,6 +6,7 @@
targs = ["hi" "hola"]
checkequal(mainv(targs, 0), "hi", "calling mainv");
checkequal(mainv(targs, 1), "hola", "calling mainv");
+checkequal(mainv(targs, 2), "<<NULL>>", "calling mainv");
checkequal(mainv("hi", 0), "hi", "calling mainv with a single string");
@@ -20,6 +21,7 @@
// Check that an empty array works.
empty_args = [];
checkequal(mainc(empty_args), 0, "calling mainc");
+checkequal(mainv(empty_args, 0), "<<NULL>>", "calling mainv");
// Check that empty strings are handled.
empty_string = ["hello", "", "world"];
@@ -27,5 +29,6 @@
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), "<<NULL>>", "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 f77097e..bb7656c 100644
--- a/Examples/test-suite/tcl/argcargvtest_runme.tcl
+++ b/Examples/test-suite/tcl/argcargvtest_runme.tcl
@@ -17,6 +17,10 @@
puts stderr "bad main typemap"
exit 1
}
+if {[mainv $targs 2] != "<<NULL>>"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
set targs " hi hola "
if {[mainv $targs 0] != "hi"} {
@@ -41,6 +45,10 @@
puts stderr "bad main typemap"
exit 1
}
+if {[mainv $empty_args 0] != "<<NULL>>"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
# Check that empty strings are handled.
set empty_string {"hello" "" "world"}
@@ -60,3 +68,7 @@
puts stderr "bad main typemap"
exit 1
}
+if {[mainv $empty_string 3] != "<<NULL>>"} {
+ puts stderr "bad main typemap"
+ exit 1
+}
diff --git a/Lib/csharp/argcargv.i b/Lib/csharp/argcargv.i
index 1dd5ee5..2dae1f6 100644
--- a/Lib/csharp/argcargv.i
+++ b/Lib/csharp/argcargv.i
@@ -32,8 +32,10 @@
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 @@
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 7ca3618..9224d3a 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 {