summaryrefslogtreecommitdiff
path: root/clap.zig
diff options
context:
space:
mode:
authorGravatar Jimmi Holst Christensen2022-03-21 23:01:55 +0100
committerGravatar Jimmi Holst Christensen2022-03-21 23:01:55 +0100
commitdc70efb14f9946a9ce1359cc5c731c445aff7298 (patch)
tree6c31ec3e7b07b97fcfb1bf6aeeb101de6a1fd4c9 /clap.zig
parentAllow for clap to parse argument values into types (diff)
downloadzig-clap-dc70efb14f9946a9ce1359cc5c731c445aff7298.tar.gz
zig-clap-dc70efb14f9946a9ce1359cc5c731c445aff7298.tar.xz
zig-clap-dc70efb14f9946a9ce1359cc5c731c445aff7298.zip
Workaround infinit loop caused by `try` inside `inline for`
fixes #72
Diffstat (limited to 'clap.zig')
-rw-r--r--clap.zig78
1 files changed, 59 insertions, 19 deletions
diff --git a/clap.zig b/clap.zig
index 1dc90ee..a578615 100644
--- a/clap.zig
+++ b/clap.zig
@@ -421,29 +421,26 @@ pub fn parseEx(
421 .diagnostic = opt.diagnostic, 421 .diagnostic = opt.diagnostic,
422 }; 422 };
423 while (try stream.next()) |arg| { 423 while (try stream.next()) |arg| {
424 // TODO: We cannot use `try` inside the inline for because of a compiler bug that
425 // generates an infinit loop. For now, use a variable to store the error
426 // and use `try` outside. The downside of this is that we have to use
427 // `anyerror` :(
428 var res: anyerror!void = {};
424 inline for (params) |*param| { 429 inline for (params) |*param| {
425 if (param == arg.param) { 430 if (param == arg.param) {
426 const parser = comptime switch (param.takes_value) { 431 res = parseArg(
427 .none => undefined, 432 Id,
428 .one, .many => @field(value_parsers, param.id.value()), 433 param.*,
429 }; 434 value_parsers,
430 435 allocator,
431 // TODO: Update opt.diagnostics when `parser` fails. This is blocked by compiler 436 &arguments,
432 // bugs that causes an infinit loop. 437 &positionals,
433 const longest = comptime param.names.longest(); 438 arg,
434 switch (longest.kind) { 439 );
435 .short, .long => switch (param.takes_value) {
436 .none => @field(arguments, longest.name) = true,
437 .one => @field(arguments, longest.name) = try parser(arg.value.?),
438 .many => {
439 const value = try parser(arg.value.?);
440 try @field(arguments, longest.name).append(allocator, value);
441 },
442 },
443 .positinal => try positionals.append(try parser(arg.value.?)),
444 }
445 } 440 }
446 } 441 }
442
443 try res;
447 } 444 }
448 445
449 var result_args = Arguments(Id, params, value_parsers, .slice){}; 446 var result_args = Arguments(Id, params, value_parsers, .slice){};
@@ -465,6 +462,34 @@ pub fn parseEx(
465 }; 462 };
466} 463}
467 464
465fn parseArg(
466 comptime Id: type,
467 comptime param: Param(Id),
468 comptime value_parsers: anytype,
469 allocator: mem.Allocator,
470 arguments: anytype,
471 positionals: anytype,
472 arg: streaming.Arg(Id),
473) !void {
474 const parser = comptime switch (param.takes_value) {
475 .none => undefined,
476 .one, .many => @field(value_parsers, param.id.value()),
477 };
478
479 const longest = comptime param.names.longest();
480 switch (longest.kind) {
481 .short, .long => switch (param.takes_value) {
482 .none => @field(arguments, longest.name) = true,
483 .one => @field(arguments, longest.name) = try parser(arg.value.?),
484 .many => {
485 const value = try parser(arg.value.?);
486 try @field(arguments, longest.name).append(allocator, value);
487 },
488 },
489 .positinal => try positionals.append(try parser(arg.value.?)),
490 }
491}
492
468pub fn ResultEx( 493pub fn ResultEx(
469 comptime Id: type, 494 comptime Id: type,
470 comptime params: []const Param(Id), 495 comptime params: []const Param(Id),
@@ -580,6 +605,21 @@ fn Arguments(
580 } }); 605 } });
581} 606}
582 607
608test "str and u64" {
609 const params = comptime &.{
610 parseParam("--str <str>") catch unreachable,
611 parseParam("--num <u64>") catch unreachable,
612 };
613
614 var iter = args.SliceIterator{
615 .args = &.{ "--num", "10", "--str", "cooley_rec_inp_ptr" },
616 };
617 var res = try parseEx(Help, params, parsers.default, &iter, .{
618 .allocator = testing.allocator,
619 });
620 defer res.deinit();
621}
622
583test "" { 623test "" {
584 const params = comptime &.{ 624 const params = comptime &.{
585 parseParam("-a, --aa") catch unreachable, 625 parseParam("-a, --aa") catch unreachable,