summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clap.zig120
-rw-r--r--clap/args.zig7
-rw-r--r--clap/comptime.zig3
-rw-r--r--clap/streaming.zig22
4 files changed, 111 insertions, 41 deletions
diff --git a/clap.zig b/clap.zig
index 1e47b42..ee2dad8 100644
--- a/clap.zig
+++ b/clap.zig
@@ -43,8 +43,8 @@ pub const Values = enum {
43/// * "-abc value" 43/// * "-abc value"
44/// * "-abc=value" 44/// * "-abc=value"
45/// * "-abcvalue" 45/// * "-abcvalue"
46/// * Long ("--long-param"): Should be used for less common parameters, or when no single character 46/// * Long ("--long-param"): Should be used for less common parameters, or when no single
47/// can describe the paramter. 47/// character can describe the paramter.
48/// * They can take a value two different ways. 48/// * They can take a value two different ways.
49/// * "--long-param value" 49/// * "--long-param value"
50/// * "--long-param=value" 50/// * "--long-param=value"
@@ -229,9 +229,18 @@ pub const Diagnostic = struct {
229 Arg{ .prefix = "", .name = diag.arg }; 229 Arg{ .prefix = "", .name = diag.arg };
230 230
231 switch (err) { 231 switch (err) {
232 error.DoesntTakeValue => try stream.print("The argument '{s}{s}' does not take a value\n", .{ a.prefix, a.name }), 232 error.DoesntTakeValue => try stream.print(
233 error.MissingValue => try stream.print("The argument '{s}{s}' requires a value but none was supplied\n", .{ a.prefix, a.name }), 233 "The argument '{s}{s}' does not take a value\n",
234 error.InvalidArgument => try stream.print("Invalid argument '{s}{s}'\n", .{ a.prefix, a.name }), 234 .{ a.prefix, a.name },
235 ),
236 error.MissingValue => try stream.print(
237 "The argument '{s}{s}' requires a value but none was supplied\n",
238 .{ a.prefix, a.name },
239 ),
240 error.InvalidArgument => try stream.print(
241 "Invalid argument '{s}{s}'\n",
242 .{ a.prefix, a.name },
243 ),
235 else => try stream.print("Error while parsing arguments: {s}\n", .{@errorName(err)}), 244 else => try stream.print("Error while parsing arguments: {s}\n", .{@errorName(err)}),
236 } 245 }
237 } 246 }
@@ -246,15 +255,51 @@ fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) !void {
246 255
247test "Diagnostic.report" { 256test "Diagnostic.report" {
248 try testDiag(.{ .arg = "c" }, error.InvalidArgument, "Invalid argument 'c'\n"); 257 try testDiag(.{ .arg = "c" }, error.InvalidArgument, "Invalid argument 'c'\n");
249 try testDiag(.{ .name = .{ .long = "cc" } }, error.InvalidArgument, "Invalid argument '--cc'\n"); 258 try testDiag(
250 try testDiag(.{ .name = .{ .short = 'c' } }, error.DoesntTakeValue, "The argument '-c' does not take a value\n"); 259 .{ .name = .{ .long = "cc" } },
251 try testDiag(.{ .name = .{ .long = "cc" } }, error.DoesntTakeValue, "The argument '--cc' does not take a value\n"); 260 error.InvalidArgument,
252 try testDiag(.{ .name = .{ .short = 'c' } }, error.MissingValue, "The argument '-c' requires a value but none was supplied\n"); 261 "Invalid argument '--cc'\n",
253 try testDiag(.{ .name = .{ .long = "cc" } }, error.MissingValue, "The argument '--cc' requires a value but none was supplied\n"); 262 );
254 try testDiag(.{ .name = .{ .short = 'c' } }, error.InvalidArgument, "Invalid argument '-c'\n"); 263 try testDiag(
255 try testDiag(.{ .name = .{ .long = "cc" } }, error.InvalidArgument, "Invalid argument '--cc'\n"); 264 .{ .name = .{ .short = 'c' } },
256 try testDiag(.{ .name = .{ .short = 'c' } }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n"); 265 error.DoesntTakeValue,
257 try testDiag(.{ .name = .{ .long = "cc" } }, error.SomethingElse, "Error while parsing arguments: SomethingElse\n"); 266 "The argument '-c' does not take a value\n",
267 );
268 try testDiag(
269 .{ .name = .{ .long = "cc" } },
270 error.DoesntTakeValue,
271 "The argument '--cc' does not take a value\n",
272 );
273 try testDiag(
274 .{ .name = .{ .short = 'c' } },
275 error.MissingValue,
276 "The argument '-c' requires a value but none was supplied\n",
277 );
278 try testDiag(
279 .{ .name = .{ .long = "cc" } },
280 error.MissingValue,
281 "The argument '--cc' requires a value but none was supplied\n",
282 );
283 try testDiag(
284 .{ .name = .{ .short = 'c' } },
285 error.InvalidArgument,
286 "Invalid argument '-c'\n",
287 );
288 try testDiag(
289 .{ .name = .{ .long = "cc" } },
290 error.InvalidArgument,
291 "Invalid argument '--cc'\n",
292 );
293 try testDiag(
294 .{ .name = .{ .short = 'c' } },
295 error.SomethingElse,
296 "Error while parsing arguments: SomethingElse\n",
297 );
298 try testDiag(
299 .{ .name = .{ .long = "cc" } },
300 error.SomethingElse,
301 "Error while parsing arguments: SomethingElse\n",
302 );
258} 303}
259 304
260pub fn Args(comptime Id: type, comptime params: []const Param(Id)) type { 305pub fn Args(comptime Id: type, comptime params: []const Param(Id)) type {
@@ -466,7 +511,9 @@ test "clap.help" {
466 parseParam("-c, --cc Both flag.") catch unreachable, 511 parseParam("-c, --cc Both flag.") catch unreachable,
467 parseParam("-d, --dd <V3> Both option.") catch unreachable, 512 parseParam("-d, --dd <V3> Both option.") catch unreachable,
468 parseParam("-d, --dd <V3>... Both repeated option.") catch unreachable, 513 parseParam("-d, --dd <V3>... Both repeated option.") catch unreachable,
469 parseParam("<P> Positional. This should not appear in the help message.") catch unreachable, 514 parseParam(
515 "<P> Positional. This should not appear in the help message.",
516 ) catch unreachable,
470 }, 517 },
471 ); 518 );
472 519
@@ -516,12 +563,16 @@ pub fn usageFull(
516 563
517 const prefix = if (param.names.short) |_| "-" else "--"; 564 const prefix = if (param.names.short) |_| "-" else "--";
518 565
519 // Seems the zig compiler is being a little wierd. I doesn't allow me to write 566 const name = if (param.names.short) |*s|
520 // @as(*const [1]u8, s) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV 567 // Seems the zig compiler is being a little wierd. I doesn't allow me to write
521 const name = if (param.names.short) |*s| @ptrCast([*]const u8, s)[0..1] else param.names.long orelse { 568 // @as(*const [1]u8, s)
522 positional = param; 569 @ptrCast([*]const u8, s)[0..1]
523 continue; 570 else
524 }; 571 param.names.long orelse {
572 positional = param;
573 continue;
574 };
575
525 if (cos.bytes_written != 0) 576 if (cos.bytes_written != 0)
526 try cs.writeByte(' '); 577 try cs.writeByte(' ');
527 578
@@ -601,16 +652,19 @@ test "usage" {
601 try testUsage("<file>", &.{ 652 try testUsage("<file>", &.{
602 try parseParam("<file>"), 653 try parseParam("<file>"),
603 }); 654 });
604 try testUsage("[-ab] [-c <value>] [-d <v>] [--e] [--f] [--g <value>] [--h <v>] [-i <v>...] <file>", &.{ 655 try testUsage(
605 try parseParam("-a"), 656 "[-ab] [-c <value>] [-d <v>] [--e] [--f] [--g <value>] [--h <v>] [-i <v>...] <file>",
606 try parseParam("-b"), 657 &.{
607 try parseParam("-c <value>"), 658 try parseParam("-a"),
608 try parseParam("-d <v>"), 659 try parseParam("-b"),
609 try parseParam("--e"), 660 try parseParam("-c <value>"),
610 try parseParam("--f"), 661 try parseParam("-d <v>"),
611 try parseParam("--g <value>"), 662 try parseParam("--e"),
612 try parseParam("--h <v>"), 663 try parseParam("--f"),
613 try parseParam("-i <v>..."), 664 try parseParam("--g <value>"),
614 try parseParam("<file>"), 665 try parseParam("--h <v>"),
615 }); 666 try parseParam("-i <v>..."),
667 try parseParam("<file>"),
668 },
669 );
616} 670}
diff --git a/clap/args.zig b/clap/args.zig
index 555e8ab..d848eb7 100644
--- a/clap/args.zig
+++ b/clap/args.zig
@@ -252,7 +252,12 @@ pub const ShellIterator = struct {
252 } 252 }
253 } 253 }
254 254
255 fn result(iter: *ShellIterator, start: usize, end: usize, list: *std.ArrayList(u8)) Error!?[]const u8 { 255 fn result(
256 iter: *ShellIterator,
257 start: usize,
258 end: usize,
259 list: *std.ArrayList(u8),
260 ) Error!?[]const u8 {
256 const res = iter.str[start..end]; 261 const res = iter.str[start..end];
257 262
258 // If we already have something in `list` that means that we could not 263 // If we already have something in `list` that means that we could not
diff --git a/clap/comptime.zig b/clap/comptime.zig
index 7808f52..cbc872e 100644
--- a/clap/comptime.zig
+++ b/clap/comptime.zig
@@ -45,9 +45,8 @@ pub fn ComptimeClap(
45 pub fn parse(iter: anytype, opt: clap.ParseOptions) !@This() { 45 pub fn parse(iter: anytype, opt: clap.ParseOptions) !@This() {
46 const allocator = opt.allocator; 46 const allocator = opt.allocator;
47 var multis = [_]std.ArrayList([]const u8){undefined} ** multi_options; 47 var multis = [_]std.ArrayList([]const u8){undefined} ** multi_options;
48 for (multis) |*multi| { 48 for (multis) |*multi|
49 multi.* = std.ArrayList([]const u8).init(allocator); 49 multi.* = std.ArrayList([]const u8).init(allocator);
50 }
51 50
52 var pos = std.ArrayList([]const u8).init(allocator); 51 var pos = std.ArrayList([]const u8).init(allocator);
53 52
diff --git a/clap/streaming.zig b/clap/streaming.zig
index e2f1311..885c581 100644
--- a/clap/streaming.zig
+++ b/clap/streaming.zig
@@ -21,8 +21,8 @@ pub fn Arg(comptime Id: type) type {
21} 21}
22 22
23/// A command line argument parser which, given an ArgIterator, will parse arguments according 23/// A command line argument parser which, given an ArgIterator, will parse arguments according
24/// to the params. StreamingClap parses in an iterating manner, so you have to use a loop together with 24/// to the params. StreamingClap parses in an iterating manner, so you have to use a loop
25/// StreamingClap.next to parse all the arguments of your program. 25/// together with StreamingClap.next to parse all the arguments of your program.
26pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type { 26pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
27 return struct { 27 return struct {
28 const State = union(enum) { 28 const State = union(enum) {
@@ -203,7 +203,11 @@ pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type {
203 }; 203 };
204} 204}
205 205
206fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, results: []const Arg(u8)) !void { 206fn testNoErr(
207 params: []const clap.Param(u8),
208 args_strings: []const []const u8,
209 results: []const Arg(u8),
210) !void {
207 var iter = args.SliceIterator{ .args = args_strings }; 211 var iter = args.SliceIterator{ .args = args_strings };
208 var c = StreamingClap(u8, args.SliceIterator){ 212 var c = StreamingClap(u8, args.SliceIterator){
209 .params = params, 213 .params = params,
@@ -225,7 +229,11 @@ fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, r
225 return error.TestFailed; 229 return error.TestFailed;
226} 230}
227 231
228fn testErr(params: []const clap.Param(u8), args_strings: []const []const u8, expected: []const u8) !void { 232fn testErr(
233 params: []const clap.Param(u8),
234 args_strings: []const []const u8,
235 expected: []const u8,
236) !void {
229 var diag: clap.Diagnostic = undefined; 237 var diag: clap.Diagnostic = undefined;
230 var iter = args.SliceIterator{ .args = args_strings }; 238 var iter = args.SliceIterator{ .args = args_strings };
231 var c = StreamingClap(u8, args.SliceIterator){ 239 var c = StreamingClap(u8, args.SliceIterator){
@@ -420,5 +428,9 @@ test "errors" {
420 try testErr(&params, &.{"-a=1"}, "The argument '-a' does not take a value\n"); 428 try testErr(&params, &.{"-a=1"}, "The argument '-a' does not take a value\n");
421 try testErr(&params, &.{"--aa=1"}, "The argument '--aa' does not take a value\n"); 429 try testErr(&params, &.{"--aa=1"}, "The argument '--aa' does not take a value\n");
422 try testErr(&params, &.{"-c"}, "The argument '-c' requires a value but none was supplied\n"); 430 try testErr(&params, &.{"-c"}, "The argument '-c' requires a value but none was supplied\n");
423 try testErr(&params, &.{"--cc"}, "The argument '--cc' requires a value but none was supplied\n"); 431 try testErr(
432 &params,
433 &.{"--cc"},
434 "The argument '--cc' requires a value but none was supplied\n",
435 );
424} 436}