Skip to content

Commit 224ce77

Browse files
committed
Fixes in add_arg_table macro parsing, tests
1 parent ad6efdc commit 224ce77

File tree

2 files changed

+132
-7
lines changed

2 files changed

+132
-7
lines changed

src/ArgParse.jl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -755,13 +755,15 @@ macro add_arg_table(s, x...)
755755
# Was parsed as doc syntax. Split into components
756756
splice!(x, i, y.args[2:end])
757757
continue
758-
elseif isa(y, AbstractString) || Meta.isexpr(y, (:vcat, :tuple))
759-
# found a string, or a vector expression, or a tuple:
760-
# this must be the option name
761-
if Meta.isexpr(y, :tuple)
762-
# transform tuples into vectors
763-
y.head = :vcat
758+
elseif isa(y, AbstractString) || Meta.isexpr(y, (:vect, :tuple))
759+
Meta.isexpr(y, :tuple) && (y.head = :vect) # transform tuples into vectors
760+
if Meta.isexpr(y, :vect) && (isempty(y.args) || !all(x->x isa AbstractString, y.args))
761+
# heterogeneous elements: splice it in place, just like blocks
762+
splice!(x, i, y.args)
763+
continue
764764
end
765+
# found a string, or a vector/tuple of strings:
766+
# this must be the option name
765767
if name nothing
766768
# there was a previous arg field on hold
767769
# first, concretely build the options

test/argparse_test2.jl

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,130 @@ function ap_settings2b()
7979
return s
8080
end
8181

82-
for s = [ap_settings2(), ap_settings2b()]
82+
function ap_settings2c()
83+
84+
s = ArgParseSettings(description = "Test 2 for ArgParse.jl",
85+
epilog = "Have fun!",
86+
version = "Version 1.0",
87+
add_version = true,
88+
exc_handler = ArgParse.debug_handler)
89+
90+
@add_arg_table(s
91+
, "--opt1"
92+
, nargs = '?' # '?' means optional argument
93+
, arg_type = Int # only Int arguments allowed
94+
, default = 0 # this is used when the option is not passed
95+
, constant = 1 # this is used if --opt1 is paseed with no argument
96+
, help = "an option"
97+
, ["--flag", "-f"]
98+
, action = :store_true # this makes it a flag
99+
, help = "a flag"
100+
, ["--karma", "-k"]
101+
, action = :count_invocations # increase a counter each time the option is given
102+
, help = "increase karma"
103+
, "arg1"
104+
, nargs = 2 # eats up two arguments; puts the result in a Vector
105+
, help = "first argument, two " *
106+
"entries at once"
107+
, required = true
108+
, "arg2"
109+
, nargs = '*' # eats up as many arguments as possible before an option
110+
, default = Any["no_arg_given"] # since the result will be a Vector{Any}, the default must
111+
# also be (or it can be [] or nothing)
112+
, help = "second argument, eats up " *
113+
"as many items as possible " *
114+
"before an option"
115+
)
116+
117+
return s
118+
end
119+
120+
function ap_settings2d()
121+
122+
s = ArgParseSettings(description = "Test 2 for ArgParse.jl",
123+
epilog = "Have fun!",
124+
version = "Version 1.0",
125+
add_version = true,
126+
exc_handler = ArgParse.debug_handler)
127+
128+
@add_arg_table s begin
129+
("--opt1";
130+
nargs = '?'; # '?' means optional argument
131+
arg_type = Int; # only Int arguments allowed
132+
default = 0; # this is used when the option is not passed
133+
constant = 1; # this is used if --opt1 is paseed with no argument
134+
help = "an option"),
135+
(["--flag", "-f"];
136+
action = :store_true; # this makes it a flag
137+
help = "a flag")
138+
(["--karma", "-k"];
139+
action = :count_invocations; # increase a counter each time the option is given
140+
help = "increase karma")
141+
("arg1";
142+
nargs = 2; # eats up two arguments; puts the result in a Vector
143+
help = "first argument, two " *
144+
"entries at once";
145+
required = true)
146+
("arg2";
147+
nargs = '*'; # eats up as many arguments as possible before an option
148+
default = Any["no_arg_given"]; # since the result will be a Vector{Any}, the default must
149+
# also be (or it can be [] or nothing)
150+
help = "second argument, eats up " *
151+
"as many items as possible " *
152+
"before an option")
153+
end
154+
155+
return s
156+
end
157+
158+
function ap_settings2e()
159+
160+
s = ArgParseSettings(description = "Test 2 for ArgParse.jl",
161+
epilog = "Have fun!",
162+
version = "Version 1.0",
163+
add_version = true,
164+
exc_handler = ArgParse.debug_handler)
165+
166+
@add_arg_table(s,
167+
"--opt1",
168+
begin
169+
nargs = '?' # '?' means optional argument
170+
arg_type = Int # only Int arguments allowed
171+
default = 0 # this is used when the option is not passed
172+
constant = 1 # this is used if --opt1 is paseed with no argument
173+
help = "an option"
174+
end,
175+
["--flag", "-f"],
176+
begin
177+
action = :store_true # this makes it a flag
178+
help = "a flag"
179+
end,
180+
["--karma", "-k"],
181+
begin
182+
action = :count_invocations # increase a counter each time the option is given
183+
help = "increase karma"
184+
end,
185+
"arg1",
186+
begin
187+
nargs = 2 # eats up two arguments; puts the result in a Vector
188+
help = "first argument, two " *
189+
"entries at once"
190+
required = true
191+
end,
192+
"arg2",
193+
begin
194+
nargs = '*' # eats up as many arguments as possible before an option
195+
default = Any["no_arg_given"] # since the result will be a Vector{Any}, the default must
196+
# also be (or it can be [] or nothing)
197+
help = "second argument, eats up " *
198+
"as many items as possible " *
199+
"before an option"
200+
end)
201+
202+
return s
203+
end
204+
205+
for s = [ap_settings2(), ap_settings2b(), ap_settings2c(), ap_settings2d(), ap_settings2e()]
83206
ap_test2(args) = parse_args(args, s)
84207

85208
@test stringhelp(s) == """

0 commit comments

Comments
 (0)