summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jimmi Holst Christensen2025-02-21 21:24:16 +0100
committerGravatar Jimmi Holst Christensen2025-02-21 21:24:16 +0100
commit1d89fdc16a446c139bf37ecfe1c7ef07d89d4894 (patch)
tree2e26c486780b9b8a1946d5db2efe53ca63a8a4f4
parentchore: update to zig version 0.14.0-dev.2837+f38d7a92c (diff)
downloadzig-clap-1d89fdc16a446c139bf37ecfe1c7ef07d89d4894.tar.gz
zig-clap-1d89fdc16a446c139bf37ecfe1c7ef07d89d4894.tar.xz
zig-clap-1d89fdc16a446c139bf37ecfe1c7ef07d89d4894.zip
fix: More than 2 positionals not parsing correctly
Fixes #149
-rw-r--r--clap.zig70
1 files changed, 44 insertions, 26 deletions
diff --git a/clap.zig b/clap.zig
index c12839e..b666f56 100644
--- a/clap.zig
+++ b/clap.zig
@@ -795,7 +795,7 @@ pub fn parseEx(
795 const i = positionals_index; 795 const i = positionals_index;
796 positionals_index += 1; 796 positionals_index += 1;
797 797
798 if (stream.positional != arg.param) 798 if (arg.param.names.longest().kind != .positional)
799 // This is a trick to emulate a runtime `continue` in an `inline for`. 799 // This is a trick to emulate a runtime `continue` in an `inline for`.
800 break :continue_params_loop; 800 break :continue_params_loop;
801 801
@@ -809,15 +809,17 @@ pub fn parseEx(
809 // positional parameters, the rest are stored in the last `positional` field. 809 // positional parameters, the rest are stored in the last `positional` field.
810 const pos = &positionals[i]; 810 const pos = &positionals[i];
811 const last = positionals.len == i + 1; 811 const last = positionals.len == i + 1;
812 if ((last and positional_count >= i) or positional_count == i) 812 if ((last and positional_count >= i) or positional_count == i) {
813 switch (@typeInfo(@TypeOf(pos.*))) { 813 switch (@typeInfo(@TypeOf(pos.*))) {
814 .optional => pos.* = try parser(arg.value.?), 814 .optional => pos.* = try parser(arg.value.?),
815 else => try pos.append(allocator, try parser(arg.value.?)), 815 else => try pos.append(allocator, try parser(arg.value.?)),
816 }; 816 }
817 817
818 if (opt.terminating_positional <= positional_count) 818 if (opt.terminating_positional <= positional_count)
819 break :arg_loop; 819 break :arg_loop;
820 positional_count += 1; 820 positional_count += 1;
821 continue :arg_loop;
822 }
821 } 823 }
822 } 824 }
823 825
@@ -1111,41 +1113,57 @@ test "single positional" {
1111test "multiple positionals" { 1113test "multiple positionals" {
1112 const params = comptime parseParamsComptime( 1114 const params = comptime parseParamsComptime(
1113 \\<u8> 1115 \\<u8>
1116 \\<u8>
1114 \\<str> 1117 \\<str>
1115 \\ 1118 \\
1116 ); 1119 );
1117 1120
1118 // { 1121 {
1119 // var iter = args.SliceIterator{ .args = &.{} }; 1122 var iter = args.SliceIterator{ .args = &.{} };
1120 // var res = try parseEx(Help, &params, parsers.default, &iter, .{ 1123 var res = try parseEx(Help, &params, parsers.default, &iter, .{
1121 // .allocator = std.testing.allocator, 1124 .allocator = std.testing.allocator,
1122 // }); 1125 });
1123 // defer res.deinit(); 1126 defer res.deinit();
1124 1127
1125 // try std.testing.expect(res.positionals[0] == null); 1128 try std.testing.expect(res.positionals[0] == null);
1126 // try std.testing.expect(res.positionals[1] == null); 1129 try std.testing.expect(res.positionals[1] == null);
1127 // } 1130 try std.testing.expect(res.positionals[2] == null);
1131 }
1128 1132
1129 // { 1133 {
1130 // var iter = args.SliceIterator{ .args = &.{"1"} }; 1134 var iter = args.SliceIterator{ .args = &.{"1"} };
1131 // var res = try parseEx(Help, &params, parsers.default, &iter, .{ 1135 var res = try parseEx(Help, &params, parsers.default, &iter, .{
1132 // .allocator = std.testing.allocator, 1136 .allocator = std.testing.allocator,
1133 // }); 1137 });
1134 // defer res.deinit(); 1138 defer res.deinit();
1135 1139
1136 // try std.testing.expectEqual(@as(u8, 1), res.positionals[0].?); 1140 try std.testing.expectEqual(@as(u8, 1), res.positionals[0].?);
1137 // try std.testing.expect(res.positionals[1] == null); 1141 try std.testing.expect(res.positionals[1] == null);
1138 // } 1142 try std.testing.expect(res.positionals[2] == null);
1143 }
1144
1145 {
1146 var iter = args.SliceIterator{ .args = &.{ "1", "2" } };
1147 var res = try parseEx(Help, &params, parsers.default, &iter, .{
1148 .allocator = std.testing.allocator,
1149 });
1150 defer res.deinit();
1151
1152 try std.testing.expectEqual(@as(u8, 1), res.positionals[0].?);
1153 try std.testing.expectEqual(@as(u8, 2), res.positionals[1].?);
1154 try std.testing.expect(res.positionals[2] == null);
1155 }
1139 1156
1140 { 1157 {
1141 var iter = args.SliceIterator{ .args = &.{ "1", "b" } }; 1158 var iter = args.SliceIterator{ .args = &.{ "1", "2", "b" } };
1142 var res = try parseEx(Help, &params, parsers.default, &iter, .{ 1159 var res = try parseEx(Help, &params, parsers.default, &iter, .{
1143 .allocator = std.testing.allocator, 1160 .allocator = std.testing.allocator,
1144 }); 1161 });
1145 defer res.deinit(); 1162 defer res.deinit();
1146 1163
1147 try std.testing.expectEqual(@as(u8, 1), res.positionals[0].?); 1164 try std.testing.expectEqual(@as(u8, 1), res.positionals[0].?);
1148 try std.testing.expectEqualStrings("b", res.positionals[1].?); 1165 try std.testing.expectEqual(@as(u8, 2), res.positionals[1].?);
1166 try std.testing.expectEqualStrings("b", res.positionals[2].?);
1149 } 1167 }
1150} 1168}
1151 1169