From ab69ef2db44b6c4b7f00283d52d38fbe71d16c42 Mon Sep 17 00:00:00 2001 From: Devin J. Pohly Date: Sun, 2 Apr 2023 06:10:40 -0500 Subject: Count occurrences of flags (was "Add .count type for flags") (#96) Breaking change: parseEx now counts the number of occurrences of flag parameters (those with takes_value == .none) and returns the count as a u8. Users of the library will need to change if (arg_result.my_flag) to if (arg_result.my_flag != 0) --- README.md | 9 +++++---- clap.zig | 26 +++++++++++++++++++++----- example/README.md.template | 1 + example/help.zig | 2 +- example/simple-ex.zig | 2 +- example/simple.zig | 2 +- example/usage.zig | 2 +- 7 files changed, 31 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index bbf61e5..f5018fc 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ in the release notes. * Short arguments `-a` * Chaining `-abc` where `a` and `b` does not take values. + * Multiple specifications are tallied (e.g. `-v -v`). * Long arguments `--long` * Supports both passing values using spacing and `=` (`-a 100`, `-a=100`) * Short args also support passing values with no spacing or `=` (`-a100`) @@ -59,7 +60,7 @@ pub fn main() !void { }; defer res.deinit(); - if (res.args.help) + if (res.args.help != 0) debug.print("--help\n", .{}); if (res.args.number) |n| debug.print("--number = {}\n", .{n}); @@ -121,7 +122,7 @@ pub fn main() !void { }; defer res.deinit(); - if (res.args.help) + if (res.args.help != 0) debug.print("--help\n", .{}); if (res.args.number) |n| debug.print("--number = {}\n", .{n}); @@ -231,7 +232,7 @@ pub fn main() !void { // where `Id` has a `describtion` and `value` method (`Param(Help)` is one such parameter). // The last argument contains options as to how `help` should print those parameters. Using // `.{}` means the default options. - if (res.args.help) + if (res.args.help != 0) return clap.help(std.io.getStdErr().writer(), clap.Help, ¶ms, .{}); } @@ -268,7 +269,7 @@ pub fn main() !void { // `clap.usage` is a function that can print a simple help message. It can print any `Param` // where `Id` has a `value` method (`Param(Help)` is one such parameter). - if (res.args.help) + if (res.args.help != 0) return clap.usage(std.io.getStdErr().writer(), clap.Help, ¶ms); } diff --git a/clap.zig b/clap.zig index 50b8c1c..8a9b961 100644 --- a/clap.zig +++ b/clap.zig @@ -803,7 +803,7 @@ fn parseArg( const longest = comptime param.names.longest(); switch (longest.kind) { .short, .long => switch (param.takes_value) { - .none => @field(arguments, longest.name) = true, + .none => @field(arguments, longest.name) +|= 1, .one => @field(arguments, longest.name) = try parser(arg.value.?), .many => { const value = try parser(arg.value.?); @@ -912,7 +912,7 @@ fn Arguments( const T = ParamType(Id, param, value_parsers); const default_value = switch (param.takes_value) { - .none => false, + .none => @as(u8, 0), .one => @as(?T, null), .many => switch (multi_arg_kind) { .slice => @as([]const T, &[_]T{}), @@ -965,21 +965,37 @@ test "everything" { ); var iter = args.SliceIterator{ - .args = &.{ "-a", "-c", "0", "something", "-d", "1", "--dd", "2" }, + .args = &.{ "-a", "--aa", "-c", "0", "something", "-d", "1", "--dd", "2" }, }; var res = try parseEx(Help, ¶ms, parsers.default, &iter, .{ .allocator = testing.allocator, }); defer res.deinit(); - try testing.expect(res.args.aa); - try testing.expect(!res.args.bb); + try testing.expect(res.args.aa == 2); + try testing.expect(res.args.bb == 0); try testing.expectEqualStrings("0", res.args.cc.?); try testing.expectEqual(@as(usize, 1), res.positionals.len); try testing.expectEqualStrings("something", res.positionals[0]); try testing.expectEqualSlices(usize, &.{ 1, 2 }, res.args.dd); } +test "overflow-safe" { + const params = comptime parseParamsComptime( + \\-a, --aa + ); + + var iter = args.SliceIterator{ + .args = &(.{"-" ++ ("a" ** 300)}), + }; + + // This just needs to not crash + var res = try parseEx(Help, ¶ms, parsers.default, &iter, .{ + .allocator = testing.allocator, + }); + defer res.deinit(); +} + test "empty" { var iter = args.SliceIterator{ .args = &.{} }; var res = try parseEx(u8, &[_]Param(u8){}, parsers.default, &iter, .{ diff --git a/example/README.md.template b/example/README.md.template index 696c598..34bff56 100644 --- a/example/README.md.template +++ b/example/README.md.template @@ -14,6 +14,7 @@ in the release notes. * Short arguments `-a` * Chaining `-abc` where `a` and `b` does not take values. + * Multiple specifications are tallied (e.g. `-v -v`). * Long arguments `--long` * Supports both passing values using spacing and `=` (`-a 100`, `-a=100`) * Short args also support passing values with no spacing or `=` (`-a100`) diff --git a/example/help.zig b/example/help.zig index dd9c9ea..e83ae44 100644 --- a/example/help.zig +++ b/example/help.zig @@ -15,6 +15,6 @@ pub fn main() !void { // where `Id` has a `describtion` and `value` method (`Param(Help)` is one such parameter). // The last argument contains options as to how `help` should print those parameters. Using // `.{}` means the default options. - if (res.args.help) + if (res.args.help != 0) return clap.help(std.io.getStdErr().writer(), clap.Help, ¶ms, .{}); } diff --git a/example/simple-ex.zig b/example/simple-ex.zig index fb20d07..dd5d929 100644 --- a/example/simple-ex.zig +++ b/example/simple-ex.zig @@ -36,7 +36,7 @@ pub fn main() !void { }; defer res.deinit(); - if (res.args.help) + if (res.args.help != 0) debug.print("--help\n", .{}); if (res.args.number) |n| debug.print("--number = {}\n", .{n}); diff --git a/example/simple.zig b/example/simple.zig index 2d32463..429f095 100644 --- a/example/simple.zig +++ b/example/simple.zig @@ -28,7 +28,7 @@ pub fn main() !void { }; defer res.deinit(); - if (res.args.help) + if (res.args.help != 0) debug.print("--help\n", .{}); if (res.args.number) |n| debug.print("--number = {}\n", .{n}); diff --git a/example/usage.zig b/example/usage.zig index 0d21352..333536b 100644 --- a/example/usage.zig +++ b/example/usage.zig @@ -14,6 +14,6 @@ pub fn main() !void { // `clap.usage` is a function that can print a simple help message. It can print any `Param` // where `Id` has a `value` method (`Param(Help)` is one such parameter). - if (res.args.help) + if (res.args.help != 0) return clap.usage(std.io.getStdErr().writer(), clap.Help, ¶ms); } -- cgit v1.2.3