Skip to content

Commit d60724b

Browse files
committed
Merge branch 'more_argcargv'
* more_argcargv: Document argc argv library argcargv.i cosmetic updates Typemaps for (int ARGC, char **ARGV) fixup Fix argcargv.i in Perl5, Tcl, PHP Add missing type map for type check. Add testing of argcargv.i for Perl5, Tcl, PHP and Ruby. Add Lua test for argcargv.i Add argcargv.i to more languages: Perl 5, Tcl, PHP Add argcargv.i to Lua
2 parents 6939d91 + 6860e2b commit d60724b

File tree

15 files changed

+360
-23
lines changed

15 files changed

+360
-23
lines changed

CHANGES.current

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
77
Version 4.1.0 (in progress)
88
===========================
99

10+
2022-05-15: erezgeva, eiselekd
11+
[Lua, Perl, PHP, Tcl] #2275 #2276 Add argcargv.i library containing
12+
(int ARGC, char **ARGV) multi-argument typemaps.
13+
14+
Document this library in Typemaps.html.
15+
1016
2022-05-07: KrisThielemans
1117
[Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
1218
using PyPy 3.8 and later.

Doc/Manual/Contents.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ <h3><a href="Library.html#Library">12 SWIG library</a></h3>
419419
<li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
420420
<li><a href="Library.html#Library_nn3">C arrays and pointers</a>
421421
<ul>
422+
<li><a href="Library.html#Library_argcargv">argcargv.i</a>
422423
<li><a href="Library.html#Library_nn4">cpointer.i</a>
423424
<li><a href="Library.html#Library_carrays">carrays.i</a>
424425
<li><a href="Library.html#Library_nn6">cmalloc.i</a>

Doc/Manual/Library.html

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ <H1><a name="Library">12 SWIG library</a></H1>
1414
<li><a href="#Library_nn2">The %include directive and library search path</a>
1515
<li><a href="#Library_nn3">C arrays and pointers</a>
1616
<ul>
17+
<li><a href="#Library_argcargv">argcargv.i</a>
1718
<li><a href="#Library_nn4">cpointer.i</a>
1819
<li><a href="#Library_carrays">carrays.i</a>
1920
<li><a href="#Library_nn6">cmalloc.i</a>
@@ -115,7 +116,48 @@ <H2><a name="Library_nn3">12.2 C arrays and pointers</a></H2>
115116
memory, their use is potentially unsafe and you should exercise caution.
116117
</p>
117118

118-
<H3><a name="Library_nn4">12.2.1 cpointer.i</a></H3>
119+
<H3><a name="Library_argcargv">12.2.1 argcargv.i</a></H3>
120+
121+
122+
<p>
123+
The argcargv.i library is a simple library providing multi-argument typemaps for handling C
124+
argc argv command line argument C string arrays.
125+
The <tt>argc</tt> parameter contains the argument count and <tt>argv</tt> contains the argument vector array.
126+
</p>
127+
128+
<p>
129+
This library provides the following multi-argument typemap:
130+
</p>
131+
132+
<p>
133+
<b><tt>(int ARGC, char **ARGV)</tt></b>
134+
</p>
135+
136+
<p>
137+
Apply this multi-argument typemap to your use case, for example:
138+
</p>
139+
140+
<div class="code">
141+
<pre>
142+
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
143+
144+
int mainApp(size_t argc, const char **argv);
145+
</pre>
146+
</div>
147+
148+
<p>
149+
then from Ruby:
150+
</p>
151+
152+
<div class="targetlang">
153+
<pre>
154+
$args = ["myarg1", "myarg2"]
155+
mainApp(args);
156+
</pre>
157+
</div>
158+
159+
160+
<H3><a name="Library_nn4">12.2.2 cpointer.i</a></H3>
119161

120162

121163
<p>
@@ -331,7 +373,7 @@ <H3><a name="Library_nn4">12.2.1 cpointer.i</a></H3>
331373
<b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation.
332374
</p>
333375

334-
<H3><a name="Library_carrays">12.2.2 carrays.i</a></H3>
376+
<H3><a name="Library_carrays">12.2.3 carrays.i</a></H3>
335377

336378

337379
<p>
@@ -510,7 +552,7 @@ <H3><a name="Library_carrays">12.2.2 carrays.i</a></H3>
510552
SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
511553
</p>
512554

513-
<H3><a name="Library_nn6">12.2.3 cmalloc.i</a></H3>
555+
<H3><a name="Library_nn6">12.2.4 cmalloc.i</a></H3>
514556

515557

516558
<p>
@@ -671,7 +713,7 @@ <H3><a name="Library_nn6">12.2.3 cmalloc.i</a></H3>
671713
</pre>
672714
</div>
673715

674-
<H3><a name="Library_nn7">12.2.4 cdata.i</a></H3>
716+
<H3><a name="Library_nn7">12.2.5 cdata.i</a></H3>
675717

676718

677719
<p>

Examples/test-suite/argcargvtest.i

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
%module argcargvtest
22

3+
#if !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGGO) && !defined(SWIGGUILE) && !defined(SWIGJAVA) && !defined(SWIGJAVASCRIPT) && !defined(SWIGMZSCHEME) && !defined(SWIGOCTAVE) && !defined(SWIGR) && !defined(SWIGSCILAB)
34
%include <argcargv.i>
45

56
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
7+
#endif
68

79
%inline %{
810

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
require("import") -- the import fn
2+
import("argcargvtest") -- import lib
3+
v = argcargvtest
4+
5+
-- catch "undefined" global variables
6+
local env = _ENV -- Lua 5.2
7+
if not env then env = getfenv () end -- Lua 5.1
8+
setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
9+
10+
largs = {"hi", "hola", "hello"}
11+
assert(v.mainc(largs) == 3, "bad main typemap")
12+
13+
targs = {"hi", "hola"}
14+
assert(v.mainv(targs, 1) == "hola", "bad main typemap")
15+
16+
targs = {"hi", "hola"}
17+
assert(v.mainv(targs, 1) == "hola", "bad main typemap")
18+
19+
errorVal = 0
20+
function try()
21+
mainv("hello", 1)
22+
errorVal = 1
23+
end
24+
assert(not pcall(try) and errorVal == 0, "bad main typemap")
25+
26+
v.initializeApp(largs)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use strict;
2+
use warnings;
3+
use Test::More tests => 8;
4+
BEGIN { use_ok('argcargvtest') }
5+
require_ok('argcargvtest');
6+
7+
my $largs = ["hi", "hola", "hello"];
8+
is(argcargvtest::mainc($largs), 3, "test main typemap 1");
9+
10+
my $targs = ["hi", "hola"];
11+
is(argcargvtest::mainv($targs, 1), "hola", "test main typemap 2");
12+
13+
my $errorVal = 0;
14+
my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;);
15+
is($ret, undef, "test main typemap 3");
16+
is($errorVal, 0, "test main typemap 4");
17+
18+
is(argcargvtest::initializeApp($largs), undef, "test main typemap 5");
19+
20+
ok(1, "done");
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
require "tests.php";
4+
5+
// New functions
6+
check::functions(array('mainc', 'mainv', 'initializeapp'));
7+
// New classes
8+
check::classes(array('argcargvtest'));
9+
// No new vars
10+
check::globals(array());
11+
12+
$largs = array('hi', 'hola', 'hello');
13+
check::equal(mainc($largs), 3, 'Test main typemap 1');
14+
15+
$targs = array('hi', 'hola');
16+
check::equal(mainv($targs, 1), 'hola', 'Test main typemap 2');
17+
18+
$error = 0;
19+
try {
20+
mainv('hello', 1);
21+
$error = 1;
22+
}
23+
catch (exception $e) {
24+
}
25+
check::equal($error, 0, 'Test main typemap 3');
26+
27+
initializeApp($largs);
28+
29+
check::done();
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'swig_assert'
4+
require 'argcargvtest'
5+
6+
include Argcargvtest
7+
8+
9+
$largs = ["hi", "hola", "hello"]
10+
if mainc($largs) != 3
11+
raise RuntimeError, "bad main typemap"
12+
end
13+
14+
$targs = ["hi", "hola"]
15+
if mainv($targs, 1) != "hola"
16+
raise RuntimeError, "bad main typemap"
17+
end
18+
19+
$error = 0
20+
$ret = 0
21+
begin
22+
mainv("hello", 1)
23+
$error = 1
24+
rescue => e
25+
$ret = 1
26+
end
27+
28+
if $error == 1 or $ret != 1
29+
raise RuntimeError, "bad main typemap"
30+
end
31+
32+
initializeApp($largs)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
if [ catch { load ./argcargvtest[info sharedlibextension] argcargvtest} err_msg ] {
2+
puts stderr "Could not load shared object:\n$err_msg"
3+
}
4+
5+
set largs {hi hola hello}
6+
if {[mainc $largs] != 3} {
7+
puts stderr "bad main typemap"
8+
exit 1
9+
}
10+
11+
set targs {hi hola}
12+
if {[mainv $targs 1] != "hola"} {
13+
puts stderr "bad main typemap"
14+
exit 1
15+
}
16+
17+
set targs " hi hola "
18+
if {[mainv $targs 1] != "hola"} {
19+
puts stderr "bad main typemap"
20+
exit 1
21+
}
22+
23+
if { ! [ catch { mainv("hello", 1) } ] } {
24+
puts stderr "bad main typemap"
25+
exit 1
26+
}
27+
28+
initializeApp $largs

Lib/lua/argcargv.i

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* ------------------------------------------------------------
2+
* SWIG library containing argc and argv multi-argument typemaps
3+
4+
Use it as follows:
5+
6+
%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
7+
extern int mainApp(size_t argc, const char **argv);
8+
9+
then from lua:
10+
11+
args = { "arg0", "arg1" }
12+
mainApp(args)
13+
14+
* ------------------------------------------------------------ */
15+
16+
%{
17+
SWIGINTERN int SWIG_argv_size(lua_State* L, int index) {
18+
int n=0;
19+
while(1){
20+
lua_rawgeti(L,index,n+1);
21+
if (lua_isnil(L,-1))
22+
break;
23+
++n;
24+
lua_pop(L,1);
25+
}
26+
lua_pop(L,1);
27+
return n;
28+
}
29+
%}
30+
31+
%typemap(in) (int ARGC, char **ARGV) {
32+
if (lua_istable(L,$input)) {
33+
int i, size = SWIG_argv_size(L,$input);
34+
$1 = ($1_ltype) size;
35+
$2 = (char **) malloc((size+1)*sizeof(char *));
36+
for (i = 0; i < size; i++) {
37+
lua_rawgeti(L,$input,i+1);
38+
if (lua_isnil(L,-1))
39+
break;
40+
$2[i] = (char *)lua_tostring(L, -1);
41+
lua_pop(L,1);
42+
}
43+
$2[i]=NULL;
44+
} else {
45+
$1 = 0; $2 = 0;
46+
lua_pushstring(L,"Expecting argv array");
47+
lua_error(L);
48+
}
49+
}
50+
51+
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
52+
$1 = lua_istable(L,$input);
53+
}
54+
55+
%typemap(freearg) (int ARGC, char **ARGV) {
56+
free((char *) $2);
57+
}

0 commit comments

Comments
 (0)