summaryrefslogtreecommitdiff
path: root/clap
diff options
context:
space:
mode:
authorGravatar Asherah Connor2020-08-23 13:48:12 +1000
committerGravatar Komari Spaghetti2020-08-28 09:43:42 +0200
commit08bab91e1e8ced3f06c128a57bd991b9a1b901fc (patch)
tree0a86df5776f0840b3262697af3c8ed7b1974fb71 /clap
parentparse multiple options (diff)
downloadzig-clap-08bab91e1e8ced3f06c128a57bd991b9a1b901fc.tar.gz
zig-clap-08bab91e1e8ced3f06c128a57bd991b9a1b901fc.tar.xz
zig-clap-08bab91e1e8ced3f06c128a57bd991b9a1b901fc.zip
parse and validate multiple option
Diffstat (limited to 'clap')
-rw-r--r--clap/comptime.zig23
-rw-r--r--clap/streaming.zig34
2 files changed, 39 insertions, 18 deletions
diff --git a/clap/comptime.zig b/clap/comptime.zig
index 90d34e9..cecfcb2 100644
--- a/clap/comptime.zig
+++ b/clap/comptime.zig
@@ -13,7 +13,7 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
13 for (params) |param| { 13 for (params) |param| {
14 var index: usize = 0; 14 var index: usize = 0;
15 if (param.names.long != null or param.names.short != null) { 15 if (param.names.long != null or param.names.short != null) {
16 const ptr = if (param.takes_value) &options else &flags; 16 const ptr = if (param.takes_value != .None) &options else &flags;
17 index = ptr.*; 17 index = ptr.*;
18 ptr.* += 1; 18 ptr.* += 1;
19 } 19 }
@@ -52,7 +52,7 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
52 const param = arg.param; 52 const param = arg.param;
53 if (param.names.long == null and param.names.short == null) { 53 if (param.names.long == null and param.names.short == null) {
54 try pos.append(arg.value.?); 54 try pos.append(arg.value.?);
55 } else if (param.takes_value) { 55 } else if (param.takes_value != .None) {
56 // If we don't have any optional parameters, then this code should 56 // If we don't have any optional parameters, then this code should
57 // never be reached. 57 // never be reached.
58 debug.assert(res.options.len != 0); 58 debug.assert(res.options.len != 0);
@@ -80,7 +80,7 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
80 80
81 pub fn flag(parser: @This(), comptime name: []const u8) bool { 81 pub fn flag(parser: @This(), comptime name: []const u8) bool {
82 const param = comptime findParam(name); 82 const param = comptime findParam(name);
83 if (param.takes_value) 83 if (param.takes_value != .None)
84 @compileError(name ++ " is an option and not a flag."); 84 @compileError(name ++ " is an option and not a flag.");
85 85
86 return parser.flags[param.id]; 86 return parser.flags[param.id];
@@ -88,14 +88,21 @@ pub fn ComptimeClap(comptime Id: type, comptime params: []const clap.Param(Id))
88 88
89 pub fn allOptions(parser: @This(), comptime name: []const u8) [][]const u8 { 89 pub fn allOptions(parser: @This(), comptime name: []const u8) [][]const u8 {
90 const param = comptime findParam(name); 90 const param = comptime findParam(name);
91 if (!param.takes_value) 91 if (param.takes_value == .None)
92 @compileError(name ++ " is a flag and not an option."); 92 @compileError(name ++ " is a flag and not an option.");
93 if (param.takes_value == .One)
94 @compileError(name ++ " takes one option, not multiple.");
93 95
94 return parser.options[param.id].items; 96 return parser.options[param.id].items;
95 } 97 }
96 98
97 pub fn option(parser: @This(), comptime name: []const u8) ?[]const u8 { 99 pub fn option(parser: @This(), comptime name: []const u8) ?[]const u8 {
98 const items = parser.allOptions(name); 100 const param = comptime findParam(name);
101 if (param.takes_value == .None)
102 @compileError(name ++ " is a flag and not an option.");
103 if (param.takes_value == .Many)
104 @compileError(name ++ " takes many options, not one.");
105 const items = parser.options[param.id].items;
99 return if (items.len > 0) items[0] else null; 106 return if (items.len > 0) items[0] else null;
100 } 107 }
101 108
@@ -127,9 +134,9 @@ test "clap.comptime.ComptimeClap" {
127 clap.parseParam("-a, --aa ") catch unreachable, 134 clap.parseParam("-a, --aa ") catch unreachable,
128 clap.parseParam("-b, --bb ") catch unreachable, 135 clap.parseParam("-b, --bb ") catch unreachable,
129 clap.parseParam("-c, --cc <V>") catch unreachable, 136 clap.parseParam("-c, --cc <V>") catch unreachable,
130 clap.parseParam("-d, --dd <V>") catch unreachable, 137 clap.parseParam("-d, --dd <V>...") catch unreachable,
131 clap.Param(clap.Help){ 138 clap.Param(clap.Help){
132 .takes_value = true, 139 .takes_value = .One,
133 }, 140 },
134 }); 141 });
135 142
@@ -151,6 +158,6 @@ test "clap.comptime.ComptimeClap" {
151 testing.expectEqualStrings("0", args.option("--cc").?); 158 testing.expectEqualStrings("0", args.option("--cc").?);
152 testing.expectEqual(@as(usize, 1), args.positionals().len); 159 testing.expectEqual(@as(usize, 1), args.positionals().len);
153 testing.expectEqualStrings("something", args.positionals()[0]); 160 testing.expectEqualStrings("something", args.positionals()[0]);
154 testing.expectEqualStrings("a", args.option("-d").?); 161 testing.expectEqualSlices([]const u8, &[_][]const u8{ "a", "b" }, args.allOptions("-d"));
155 testing.expectEqualSlices([]const u8, &[_][]const u8{ "a", "b" }, args.allOptions("--dd")); 162 testing.expectEqualSlices([]const u8, &[_][]const u8{ "a", "b" }, args.allOptions("--dd"));
156} 163}
diff --git a/clap/streaming.zig b/clap/streaming.zig
index 95ee581..b843bff 100644
--- a/clap/streaming.zig
+++ b/clap/streaming.zig
@@ -75,7 +75,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
75 75
76 if (!mem.eql(u8, name, match)) 76 if (!mem.eql(u8, name, match))
77 continue; 77 continue;
78 if (!param.takes_value) { 78 if (param.takes_value == .None) {
79 if (maybe_value != null) 79 if (maybe_value != null)
80 return error.DoesntTakeValue; 80 return error.DoesntTakeValue;
81 81
@@ -128,7 +128,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
128 128
129 // Before we return, we have to set the new state of the clap 129 // Before we return, we have to set the new state of the clap
130 defer { 130 defer {
131 if (arg.len <= next_index or param.takes_value) { 131 if (arg.len <= next_index or param.takes_value != .None) {
132 parser.state = State.Normal; 132 parser.state = State.Normal;
133 } else { 133 } else {
134 parser.state = State{ 134 parser.state = State{
@@ -140,7 +140,7 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
140 } 140 }
141 } 141 }
142 142
143 if (!param.takes_value) 143 if (param.takes_value == .None)
144 return Arg(Id){ .param = param }; 144 return Arg(Id){ .param = param };
145 145
146 if (arg.len <= next_index) { 146 if (arg.len <= next_index) {
@@ -194,20 +194,26 @@ test "clap.streaming.StreamingClap: short params" {
194 clap.Param(u8){ 194 clap.Param(u8){
195 .id = 2, 195 .id = 2,
196 .names = clap.Names{ .short = 'c' }, 196 .names = clap.Names{ .short = 'c' },
197 .takes_value = true, 197 .takes_value = .One,
198 },
199 clap.Param(u8){
200 .id = 3,
201 .names = clap.Names{ .short = 'd' },
202 .takes_value = .Many,
198 }, 203 },
199 }; 204 };
200 205
201 const a = &params[0]; 206 const a = &params[0];
202 const b = &params[1]; 207 const b = &params[1];
203 const c = &params[2]; 208 const c = &params[2];
209 const d = &params[3];
204 210
205 testNoErr( 211 testNoErr(
206 &params, 212 &params,
207 &[_][]const u8{ 213 &[_][]const u8{
208 "-a", "-b", "-ab", "-ba", 214 "-a", "-b", "-ab", "-ba",
209 "-c", "0", "-c=0", "-ac", 215 "-c", "0", "-c=0", "-ac",
210 "0", "-ac=0", 216 "0", "-ac=0", "-d=0",
211 }, 217 },
212 &[_]Arg(u8){ 218 &[_]Arg(u8){
213 Arg(u8){ .param = a }, 219 Arg(u8){ .param = a },
@@ -222,6 +228,7 @@ test "clap.streaming.StreamingClap: short params" {
222 Arg(u8){ .param = c, .value = "0" }, 228 Arg(u8){ .param = c, .value = "0" },
223 Arg(u8){ .param = a }, 229 Arg(u8){ .param = a },
224 Arg(u8){ .param = c, .value = "0" }, 230 Arg(u8){ .param = c, .value = "0" },
231 Arg(u8){ .param = d, .value = "0" },
225 }, 232 },
226 ); 233 );
227} 234}
@@ -239,26 +246,33 @@ test "clap.streaming.StreamingClap: long params" {
239 clap.Param(u8){ 246 clap.Param(u8){
240 .id = 2, 247 .id = 2,
241 .names = clap.Names{ .long = "cc" }, 248 .names = clap.Names{ .long = "cc" },
242 .takes_value = true, 249 .takes_value = .One,
250 },
251 clap.Param(u8){
252 .id = 3,
253 .names = clap.Names{ .long = "dd" },
254 .takes_value = .Many,
243 }, 255 },
244 }; 256 };
245 257
246 const aa = &params[0]; 258 const aa = &params[0];
247 const bb = &params[1]; 259 const bb = &params[1];
248 const cc = &params[2]; 260 const cc = &params[2];
261 const dd = &params[3];
249 262
250 testNoErr( 263 testNoErr(
251 &params, 264 &params,
252 &[_][]const u8{ 265 &[_][]const u8{
253 "--aa", "--bb", 266 "--aa", "--bb",
254 "--cc", "0", 267 "--cc", "0",
255 "--cc=0", 268 "--cc=0", "--dd=0",
256 }, 269 },
257 &[_]Arg(u8){ 270 &[_]Arg(u8){
258 Arg(u8){ .param = aa }, 271 Arg(u8){ .param = aa },
259 Arg(u8){ .param = bb }, 272 Arg(u8){ .param = bb },
260 Arg(u8){ .param = cc, .value = "0" }, 273 Arg(u8){ .param = cc, .value = "0" },
261 Arg(u8){ .param = cc, .value = "0" }, 274 Arg(u8){ .param = cc, .value = "0" },
275 Arg(u8){ .param = dd, .value = "0" },
262 }, 276 },
263 ); 277 );
264} 278}
@@ -266,7 +280,7 @@ test "clap.streaming.StreamingClap: long params" {
266test "clap.streaming.StreamingClap: positional params" { 280test "clap.streaming.StreamingClap: positional params" {
267 const params = [_]clap.Param(u8){clap.Param(u8){ 281 const params = [_]clap.Param(u8){clap.Param(u8){
268 .id = 0, 282 .id = 0,
269 .takes_value = true, 283 .takes_value = .One,
270 }}; 284 }};
271 285
272 testNoErr( 286 testNoErr(
@@ -301,11 +315,11 @@ test "clap.streaming.StreamingClap: all params" {
301 .short = 'c', 315 .short = 'c',
302 .long = "cc", 316 .long = "cc",
303 }, 317 },
304 .takes_value = true, 318 .takes_value = .One,
305 }, 319 },
306 clap.Param(u8){ 320 clap.Param(u8){
307 .id = 3, 321 .id = 3,
308 .takes_value = true, 322 .takes_value = .One,
309 }, 323 },
310 }; 324 };
311 325