diff options
Diffstat (limited to 'src/deps/zig-clap')
m--------- | src/deps/zig-clap | 0 | ||||
-rw-r--r-- | src/deps/zig-clap/.gitignore | 1 | ||||
-rw-r--r-- | src/deps/zig-clap/LICENSE | 24 | ||||
-rw-r--r-- | src/deps/zig-clap/build.zig | 55 | ||||
-rw-r--r-- | src/deps/zig-clap/clap.zig | 546 | ||||
-rw-r--r-- | src/deps/zig-clap/clap/args.zig | 337 | ||||
-rw-r--r-- | src/deps/zig-clap/clap/comptime.zig | 194 | ||||
-rw-r--r-- | src/deps/zig-clap/clap/streaming.zig | 430 | ||||
-rw-r--r-- | src/deps/zig-clap/gyro.zzz | 14 | ||||
-rw-r--r-- | src/deps/zig-clap/zig.mod | 5 |
10 files changed, 0 insertions, 1606 deletions
diff --git a/src/deps/zig-clap b/src/deps/zig-clap new file mode 160000 +Subproject 9c3ac846121a03934c7460cc54989059b1f66b2 diff --git a/src/deps/zig-clap/.gitignore b/src/deps/zig-clap/.gitignore deleted file mode 100644 index 2040c29db..000000000 --- a/src/deps/zig-clap/.gitignore +++ /dev/null @@ -1 +0,0 @@ -zig-cache diff --git a/src/deps/zig-clap/LICENSE b/src/deps/zig-clap/LICENSE deleted file mode 100644 index cf1ab25da..000000000 --- a/src/deps/zig-clap/LICENSE +++ /dev/null @@ -1,24 +0,0 @@ -This is free and unencumbered software released into the public domain. - -Anyone is free to copy, modify, publish, use, compile, sell, or -distribute this software, either in source code form or as a compiled -binary, for any purpose, commercial or non-commercial, and by any -means. - -In jurisdictions that recognize copyright laws, the author or authors -of this software dedicate any and all copyright interest in the -software to the public domain. We make this dedication for the benefit -of the public at large and to the detriment of our heirs and -successors. We intend this dedication to be an overt act of -relinquishment in perpetuity of all present and future rights to this -software under copyright law. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -For more information, please refer to <http://unlicense.org> diff --git a/src/deps/zig-clap/build.zig b/src/deps/zig-clap/build.zig deleted file mode 100644 index 5ab66da8a..000000000 --- a/src/deps/zig-clap/build.zig +++ /dev/null @@ -1,55 +0,0 @@ -const builtin = @import("builtin"); -const std = @import("std"); - -const Builder = std.build.Builder; -const Mode = std.builtin.Mode; - -pub fn build(b: *Builder) void { - const mode = b.standardReleaseOptions(); - const target = b.standardTargetOptions(.{}); - - const test_all_step = b.step("test", "Run all tests in all modes."); - inline for ([_]Mode{ Mode.Debug, Mode.ReleaseFast, Mode.ReleaseSafe, Mode.ReleaseSmall }) |test_mode| { - const mode_str = comptime modeToString(test_mode); - - const tests = b.addTest("clap.zig"); - tests.setBuildMode(test_mode); - tests.setTarget(target); - tests.setNamePrefix(mode_str ++ " "); - - const test_step = b.step("test-" ++ mode_str, "Run all tests in " ++ mode_str ++ "."); - test_step.dependOn(&tests.step); - test_all_step.dependOn(test_step); - } - - const example_step = b.step("examples", "Build examples"); - inline for ([_][]const u8{ - "simple", - "simple-ex", - //"simple-error", - "streaming-clap", - "help", - "usage", - }) |example_name| { - const example = b.addExecutable(example_name, "example/" ++ example_name ++ ".zig"); - example.addPackagePath("clap", "clap.zig"); - example.setBuildMode(mode); - example.setTarget(target); - example.install(); - example_step.dependOn(&example.step); - } - - const all_step = b.step("all", "Build everything and runs all tests"); - all_step.dependOn(test_all_step); - - b.default_step.dependOn(all_step); -} - -fn modeToString(mode: Mode) []const u8 { - return switch (mode) { - Mode.Debug => "debug", - Mode.ReleaseFast => "release-fast", - Mode.ReleaseSafe => "release-safe", - Mode.ReleaseSmall => "release-small", - }; -} diff --git a/src/deps/zig-clap/clap.zig b/src/deps/zig-clap/clap.zig deleted file mode 100644 index a21a1cb1a..000000000 --- a/src/deps/zig-clap/clap.zig +++ /dev/null @@ -1,546 +0,0 @@ -const std = @import("std"); - -const debug = std.debug; -const heap = std.heap; -const io = std.io; -const mem = std.mem; -const testing = std.testing; - -pub const args = @import("clap/args.zig"); - -test "clap" { - testing.refAllDecls(@This()); -} - -pub const ComptimeClap = @import("clap/comptime.zig").ComptimeClap; -pub const StreamingClap = @import("clap/streaming.zig").StreamingClap; - -/// The names a ::Param can have. -pub const Names = struct { - /// '-' prefix - short: ?u8 = null, - - /// '--' prefix - long: ?[]const u8 = null, -}; - -/// Whether a param takes no value (a flag), one value, or can be specified multiple times. -pub const Values = enum { - none, - one, - many, - one_optional, -}; - -/// Represents a parameter for the command line. -/// Parameters come in three kinds: -/// * Short ("-a"): Should be used for the most commonly used parameters in your program. -/// * They can take a value three different ways. -/// * "-a value" -/// * "-a=value" -/// * "-avalue" -/// * They chain if they don't take values: "-abc". -/// * The last given parameter can take a value in the same way that a single parameter can: -/// * "-abc value" -/// * "-abc=value" -/// * "-abcvalue" -/// * Long ("--long-param"): Should be used for less common parameters, or when no single character -/// can describe the paramter. -/// * They can take a value two different ways. -/// * "--long-param value" -/// * "--long-param=value" -/// * Positional: Should be used as the primary parameter of the program, like a filename or -/// an expression to parse. -/// * Positional parameters have both names.long and names.short == null. -/// * Positional parameters must take a value. -pub fn Param(comptime Id: type) type { - return struct { - id: Id = std.mem.zeroes(Id), - names: Names = std.mem.zeroes(Names), - takes_value: Values = .none, - }; -} - -/// Takes a string and parses it to a Param(Help). -/// This is the reverse of 'help' but for at single parameter only. -pub fn parseParam(line: []const u8) !Param(Help) { - @setEvalBranchQuota(999999); - - var found_comma = false; - var it = mem.tokenize(u8, line, " \t"); - var param_str = it.next() orelse return error.NoParamFound; - - const short_name = if (!mem.startsWith(u8, param_str, "--") and - mem.startsWith(u8, param_str, "-")) - blk: { - found_comma = param_str[param_str.len - 1] == ','; - if (found_comma) - param_str = param_str[0 .. param_str.len - 1]; - - if (param_str.len != 2) - return error.InvalidShortParam; - - const short_name = param_str[1]; - if (!found_comma) { - var res = parseParamRest(it.rest()); - res.names.short = short_name; - return res; - } - - param_str = it.next() orelse return error.NoParamFound; - break :blk short_name; - } else null; - - _ = if (mem.startsWith(u8, param_str, "--")) { - if (param_str[param_str.len - 1] == ',') - return error.TrailingComma; - } else if (found_comma) { - return error.TrailingComma; - } else if (short_name == null) { - return parseParamRest(mem.trimLeft(u8, line, " \t")); - } else null; - - var res = parseParamRest(it.rest()); - res.names.long = param_str[2..]; - res.names.short = short_name; - return res; -} - -fn parseParamRest(line: []const u8) Param(Help) { - if (mem.startsWith(u8, line, "<")) blk: { - const len = mem.indexOfScalar(u8, line, '>') orelse break :blk; - const takes_many = mem.startsWith(u8, line[len + 1 ..], "..."); - const takes_one_optional = mem.startsWith(u8, line[len + 1 ..], "?"); - const help_start = len + 1 + @as(usize, 3) * @boolToInt(takes_many) + (@as(usize, 1) * @boolToInt(takes_one_optional)); - return .{ - .takes_value = if (takes_many) Values.many else if (takes_one_optional) Values.one_optional else Values.one, - .id = .{ - .msg = mem.trim(u8, line[help_start..], " \t"), - .value = line[1..len], - }, - }; - } - - return .{ .id = .{ .msg = mem.trim(u8, line, " \t") } }; -} - -fn expectParam(expect: Param(Help), actual: Param(Help)) void { - testing.expectEqualStrings(expect.id.msg, actual.id.msg); - testing.expectEqualStrings(expect.id.value, actual.id.value); - testing.expectEqual(expect.names.short, actual.names.short); - testing.expectEqual(expect.takes_value, actual.takes_value); - if (expect.names.long) |long| { - testing.expectEqualStrings(long, actual.names.long.?); - } else { - testing.expectEqual(@as(?[]const u8, null), actual.names.long); - } -} - -test "parseParam" { - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "value" }, - .names = .{ .short = 's', .long = "long" }, - .takes_value = .one, - }, try parseParam("-s, --long <value> Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "value" }, - .names = .{ .short = 's', .long = "long" }, - .takes_value = .many, - }, try parseParam("-s, --long <value>... Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "value" }, - .names = .{ .long = "long" }, - .takes_value = .one, - }, try parseParam("--long <value> Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "value" }, - .names = .{ .short = 's' }, - .takes_value = .one, - }, try parseParam("-s <value> Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text" }, - .names = .{ .short = 's', .long = "long" }, - }, try parseParam("-s, --long Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text" }, - .names = .{ .short = 's' }, - }, try parseParam("-s Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text" }, - .names = .{ .long = "long" }, - }, try parseParam("--long Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "A | B" }, - .names = .{ .long = "long" }, - .takes_value = .one, - }, try parseParam("--long <A | B> Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "A" }, - .names = .{}, - .takes_value = .one, - }, try parseParam("<A> Help text")); - - expectParam(Param(Help){ - .id = .{ .msg = "Help text", .value = "A" }, - .names = .{}, - .takes_value = .many, - }, try parseParam("<A>... Help text")); - - testing.expectError(error.TrailingComma, parseParam("--long, Help")); - testing.expectError(error.TrailingComma, parseParam("-s, Help")); - testing.expectError(error.InvalidShortParam, parseParam("-ss Help")); - testing.expectError(error.InvalidShortParam, parseParam("-ss <value> Help")); - testing.expectError(error.InvalidShortParam, parseParam("- Help")); -} - -/// Optional diagnostics used for reporting useful errors -pub const Diagnostic = struct { - arg: []const u8 = "", - name: Names = Names{}, - - /// Default diagnostics reporter when all you want is English with no colors. - /// Use this as a reference for implementing your own if needed. - pub fn report(diag: Diagnostic, stream: anytype, err: anyerror) !void { - const Arg = struct { - prefix: []const u8, - name: []const u8, - }; - const a = if (diag.name.short) |*c| - Arg{ .prefix = "-", .name = @as(*const [1]u8, c)[0..] } - else if (diag.name.long) |l| - Arg{ .prefix = "--", .name = l } - else - Arg{ .prefix = "", .name = diag.arg }; - - switch (err) { - error.DoesntTakeValue => try stream.print("The argument '{s}{s}' does not take a value\n", .{ a.prefix, a.name }), - error.MissingValue => try stream.print("The argument '{s}{s}' requires a value but none was supplied\n", .{ a.prefix, a.name }), - error.InvalidArgument => if (a.prefix.len > 0 and a.name.len > 0) - try stream.print("Invalid argument '{s}{s}'\n", .{ a.prefix, a.name }) - else - try stream.print("Failed to parse argument due to unexpected single dash\n", .{}), - else => try stream.print("Error while parsing arguments: {s}\n", .{@errorName(err)}), - } - } -}; - -fn testDiag(diag: Diagnostic, err: anyerror, expected: []const u8) void { - var buf: [1024]u8 = undefined; - var slice_stream = io.fixedBufferStream(&buf); - diag.report(slice_stream.writer(), err) catch unreachable; - testing.expectEqualStrings(expected, slice_stream.getWritten()); -} - -pub fn Args(comptime Id: type, comptime params: []const Param(Id)) type { - return struct { - arena: std.heap.ArenaAllocator, - clap: ComptimeClap(Id, params), - exe_arg: ?[]const u8, - - pub fn deinit(a: *@This()) void { - a.arena.deinit(); - } - - pub fn flag(a: @This(), comptime name: []const u8) bool { - return a.clap.flag(name); - } - - pub fn option(a: @This(), comptime name: []const u8) ?[]const u8 { - return a.clap.option(name); - } - - pub fn options(a: @This(), comptime name: []const u8) []const []const u8 { - return a.clap.options(name); - } - - pub fn positionals(a: @This()) []const []const u8 { - return a.clap.positionals(); - } - - pub fn remaining(a: @This()) []const []const u8 { - return a.clap.remaining(); - } - - pub fn hasFlag(comptime name: []const u8) bool { - return ComptimeClap(Id, params).hasFlag(name); - } - }; -} - -/// Options that can be set to customize the behavior of parsing. -pub const ParseOptions = struct { - /// The allocator used for all memory allocations. Defaults to the `heap.page_allocator`. - /// Note: You should probably override this allocator if you are calling `parseEx`. Unlike - /// `parse`, `parseEx` does not wrap the allocator so the heap allocator can be - /// quite expensive. (TODO: Can we pick a better default? For `parse`, this allocator - /// is fine, as it wraps it in an arena) - allocator: mem.Allocator = heap.page_allocator, - diagnostic: ?*Diagnostic = null, - stop_after_positional_at: usize = 0, -}; - -/// Same as `parseEx` but uses the `args.OsIterator` by default. -pub fn parse( - comptime Id: type, - comptime params: []const Param(Id), - opt: ParseOptions, -) !Args(Id, params) { - var iter = args.OsIterator.init(opt.allocator); - var res = Args(Id, params){ - .arena = iter.arena, - .exe_arg = iter.exe_arg, - .clap = undefined, - }; - - // Let's reuse the arena from the `OSIterator` since we already have - // it. - res.clap = try parseEx(Id, params, &iter, .{ - .allocator = res.arena.allocator(), - .diagnostic = opt.diagnostic, - .stop_after_positional_at = opt.stop_after_positional_at, - }); - return res; -} - -/// Parses the command line arguments passed into the program based on an -/// array of `Param`s. -pub fn parseEx( - comptime Id: type, - comptime params: []const Param(Id), - iter: anytype, - opt: ParseOptions, -) !ComptimeClap(Id, params) { - const Clap = ComptimeClap(Id, params); - return try Clap.parse(iter, opt); -} - -/// Will print a help message in the following format: -/// -s, --long <valueText> helpText -/// -s, helpText -/// -s <valueText> helpText -/// --long helpText -/// --long <valueText> helpText -pub fn helpFull( - stream: anytype, - comptime Id: type, - params: []const Param(Id), - comptime Error: type, - context: anytype, - helpText: fn (@TypeOf(context), Param(Id)) Error![]const u8, - valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8, -) !void { - const max_spacing = blk: { - var res: usize = 0; - for (params) |param| { - var cs = io.countingWriter(io.null_writer); - try printParam(cs.writer(), Id, param, Error, context, valueText); - if (res < cs.bytes_written) - res = @intCast(usize, cs.bytes_written); - } - - break :blk res; - }; - - for (params) |param| { - if (param.names.short == null and param.names.long == null) - continue; - - var cs = io.countingWriter(stream); - try stream.print("\t", .{}); - try printParam(cs.writer(), Id, param, Error, context, valueText); - try stream.writeByteNTimes(' ', max_spacing - @intCast(usize, cs.bytes_written)); - try stream.print("\t{s}\n", .{try helpText(context, param)}); - } -} - -fn printParam( - stream: anytype, - comptime Id: type, - param: Param(Id), - comptime Error: type, - context: anytype, - valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8, -) !void { - if (param.names.short) |s| { - try stream.print("-{c}", .{s}); - } else { - try stream.print(" ", .{}); - } - if (param.names.long) |l| { - if (param.names.short) |_| { - try stream.print(", ", .{}); - } else { - try stream.print(" ", .{}); - } - - try stream.print("--{s}", .{l}); - } - - switch (param.takes_value) { - .none => {}, - .one => try stream.print(" <{s}>", .{try valueText(context, param)}), - .one_optional => try stream.print(" <{s}>?", .{try valueText(context, param)}), - .many => try stream.print(" <{s}>...", .{try valueText(context, param)}), - } -} - -/// A wrapper around helpFull for simple helpText and valueText functions that -/// cant return an error or take a context. -pub fn helpEx( - stream: anytype, - comptime Id: type, - params: []const Param(Id), - helpText: *const fn (Param(Id)) []const u8, - valueText: *const fn (Param(Id)) []const u8, -) !void { - const Context = struct { - helpText: *const fn (Param(Id)) []const u8, - valueText: *const fn (Param(Id)) []const u8, - - pub fn help(c: @This(), p: Param(Id)) error{}![]const u8 { - return c.helpText(p); - } - - pub fn value(c: @This(), p: Param(Id)) error{}![]const u8 { - return c.valueText(p); - } - }; - - return helpFull( - stream, - Id, - params, - error{}, - Context{ - .helpText = helpText, - .valueText = valueText, - }, - Context.help, - Context.value, - ); -} - -pub const Help = struct { - msg: []const u8 = "", - value: []const u8 = "", -}; - -/// A wrapper around helpEx that takes a Param(Help). -pub fn help(stream: anytype, params: []const Param(Help)) !void { - try helpEx(stream, Help, params, getHelpSimple, getValueSimple); -} - -fn getHelpSimple(param: Param(Help)) []const u8 { - return param.id.msg; -} - -fn getValueSimple(param: Param(Help)) []const u8 { - return param.id.value; -} - -/// Will print a usage message in the following format: -/// [-abc] [--longa] [-d <valueText>] [--longb <valueText>] <valueText> -/// -/// First all none value taking parameters, which have a short name are -/// printed, then non positional parameters and finally the positinal. -pub fn usageFull( - stream: anytype, - comptime Id: type, - params: []const Param(Id), - comptime Error: type, - context: anytype, - valueText: fn (@TypeOf(context), Param(Id)) Error![]const u8, -) !void { - var cos = io.countingWriter(stream); - const cs = cos.writer(); - for (params) |param| { - const name = param.names.short orelse continue; - if (param.takes_value != .none) - continue; - - if (cos.bytes_written == 0) - try stream.writeAll("[-"); - try cs.writeByte(name); - } - if (cos.bytes_written != 0) - try cs.writeByte(']'); - - var positional: ?Param(Id) = null; - for (params) |param| { - if (param.takes_value == .none and param.names.short != null) - continue; - - const prefix = if (param.names.short) |_| "-" else "--"; - - // Seems the zig compiler is being a little wierd. I doesn't allow me to write - // @as(*const [1]u8, s) VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV - const name = if (param.names.short) |*s| @ptrCast([*]const u8, s)[0..1] else param.names.long orelse { - positional = param; - continue; - }; - if (cos.bytes_written != 0) - try cs.writeByte(' '); - - try cs.print("[{s}{s}", .{ prefix, name }); - switch (param.takes_value) { - .none => {}, - .one => try cs.print(" <{s}>", .{try valueText(context, param)}), - .one_optional => try cs.print(" <{s}>?", .{try valueText(context, param)}), - .many => try cs.print(" <{s}>...", .{try valueText(context, param)}), - } - - try cs.writeByte(']'); - } - - if (positional) |p| { - if (cos.bytes_written != 0) - try cs.writeByte(' '); - try cs.print("<{s}>", .{try valueText(context, p)}); - } -} - -/// A wrapper around usageFull for a simple valueText functions that -/// cant return an error or take a context. -pub fn usageEx( - stream: anytype, - comptime Id: type, - params: []const Param(Id), - valueText: fn (Param(Id)) []const u8, -) !void { - const Context = struct { - valueText: fn (Param(Id)) []const u8, - - pub fn value(c: @This(), p: Param(Id)) error{}![]const u8 { - return c.valueText(p); - } - }; - - return usageFull( - stream, - Id, - params, - error{}, - Context{ .valueText = valueText }, - Context.value, - ); -} - -/// A wrapper around usageEx that takes a Param(Help). -pub fn usage(stream: anytype, params: []const Param(Help)) !void { - try usageEx(stream, Help, params, getValueSimple); -} - -fn testUsage(expected: []const u8, params: []const Param(Help)) !void { - var buf: [1024]u8 = undefined; - var fbs = io.fixedBufferStream(&buf); - try usage(fbs.writer(), params); - testing.expectEqualStrings(expected, fbs.getWritten()); -} diff --git a/src/deps/zig-clap/clap/args.zig b/src/deps/zig-clap/clap/args.zig deleted file mode 100644 index a1fa3773a..000000000 --- a/src/deps/zig-clap/clap/args.zig +++ /dev/null @@ -1,337 +0,0 @@ -const std = @import("std"); - -const builtin = @import("builtin"); -const debug = std.debug; -const heap = std.heap; -const mem = std.mem; -const process = std.process; -const testing = std.testing; - -/// An example of what methods should be implemented on an arg iterator. -pub const ExampleArgIterator = struct { - const Error = error{}; - - pub fn next(_: *ExampleArgIterator) Error!?[]const u8 { - return "2"; - } -}; - -/// An argument iterator which iterates over a slice of arguments. -/// This implementation does not allocate. -pub const SliceIterator = struct { - const Error = error{}; - - args: []const []const u8, - index: usize = 0, - - pub fn next(iter: *SliceIterator) Error!?[]const u8 { - if (iter.args.len <= iter.index) - return null; - - defer iter.index += 1; - return iter.args[iter.index]; - } -}; - -test "SliceIterator" { - const args = &[_][]const u8{ "A", "BB", "CCC" }; - var iter = SliceIterator{ .args = args }; - - for (args) |a| { - const b = try iter.next(); - debug.assert(mem.eql(u8, a, b.?)); - } -} - -/// An argument iterator which wraps the ArgIterator in ::std. -/// On windows, this iterator allocates. -pub const OsIterator = struct { - const Error = process.ArgIterator.InitError; - - arena: heap.ArenaAllocator, - args: process.ArgIterator, - - /// The executable path (this is the first argument passed to the program) - /// TODO: Is it the right choice for this to be null? Maybe `init` should - /// return an error when we have no exe. - exe_arg: ?[:0]const u8, - - pub fn init(allocator: mem.Allocator) OsIterator { - var res = OsIterator{ - .arena = heap.ArenaAllocator.init(allocator), - .args = process.args(), - .exe_arg = undefined, - }; - res.exe_arg = res.next(); - return res; - } - - pub fn deinit(iter: *OsIterator) void { - iter.arena.deinit(); - } - - pub fn next(iter: *OsIterator) ?[:0]const u8 { - return iter.args.next(); - } -}; - -/// An argument iterator that takes a string and parses it into arguments, simulating -/// how shells split arguments. -pub const ShellIterator = struct { - const Error = error{ - DanglingEscape, - QuoteNotClosed, - } || mem.Allocator.Error; - - arena: heap.ArenaAllocator, - str: []const u8, - - pub fn init(allocator: mem.Allocator, str: []const u8) ShellIterator { - return .{ - .arena = heap.ArenaAllocator.init(allocator), - .str = str, - }; - } - - pub fn deinit(iter: *ShellIterator) void { - iter.arena.deinit(); - } - - pub fn next(iter: *ShellIterator) Error!?[]const u8 { - // Whenever possible, this iterator will return slices into `str` instead of - // allocating. Sometimes this is not possible, for example, escaped characters - // have be be unescape, so we need to allocate in this case. - var list = std.ArrayList(u8).init(&iter.arena.allocator); - var start: usize = 0; - var state: enum { - skip_whitespace, - no_quote, - no_quote_escape, - single_quote, - double_quote, - double_quote_escape, - after_quote, - } = .skip_whitespace; - - for (iter.str, 0..) |c, i| { - switch (state) { - // The state that skips the initial whitespace. - .skip_whitespace => switch (c) { - ' ', '\t', '\n' => {}, - '\'' => { - start = i + 1; - state = .single_quote; - }, - '"' => { - start = i + 1; - state = .double_quote; - }, - '\\' => { - start = i + 1; - state = .no_quote_escape; - }, - else => { - start = i; - state = .no_quote; - }, - }, - - // The state that parses the none quoted part of a argument. - .no_quote => switch (c) { - // We're done parsing a none quoted argument when we hit a - // whitespace. - ' ', '\t', '\n' => { - defer iter.str = iter.str[i..]; - return iter.result(start, i, &list); - }, - - // Slicing is not possible if a quote starts while parsing none - // quoted args. - // Example: - // ab'cd' -> abcd - '\'' => { - try list.appendSlice(iter.str[start..i]); - start = i + 1; - state = .single_quote; - }, - '"' => { - try list.appendSlice(iter.str[start..i]); - start = i + 1; - state = .double_quote; - }, - - // Slicing is not possible if we need to escape a character. - // Example: - // ab\"d -> ab"d - '\\' => { - try list.appendSlice(iter.str[start..i]); - start = i + 1; - state = .no_quote_escape; - }, - else => {}, - }, - - // We're in this state after having parsed the quoted part of an - // argument. This state works mostly the same as .no_quote, but - // is aware, that the last character seen was a quote, which should - // not be part of the argument. This is why you will see `i - 1` here - // instead of just `i` when `iter.str` is sliced. - .after_quote => switch (c) { - ' ', '\t', '\n' => { - defer iter.str = iter.str[i..]; - return iter.result(start, i - 1, &list); - }, - '\'' => { - try list.appendSlice(iter.str[start .. i - 1]); - start = i + 1; - state = .single_quote; - }, - '"' => { - try list.appendSlice(iter.str[start .. i - 1]); - start = i + 1; - state = .double_quote; - }, - '\\' => { - try list.appendSlice(iter.str[start .. i - 1]); - start = i + 1; - state = .no_quote_escape; - }, - else => { - try list.appendSlice(iter.str[start .. i - 1]); - start = i; - state = .no_quote; - }, - }, - - // The states that parse the quoted part of arguments. The only differnece - // between single and double quoted arguments is that single quoted - // arguments ignore escape sequences, while double quoted arguments - // does escaping. - .single_quote => switch (c) { - '\'' => state = .after_quote, - else => {}, - }, - .double_quote => switch (c) { - '"' => state = .after_quote, - '\\' => { - try list.appendSlice(iter.str[start..i]); - start = i + 1; - state = .double_quote_escape; - }, - else => {}, - }, - - // The state we end up when after the escape character (`\`). All these - // states do is transition back into the previous state. - // TODO: Are there any escape sequences that does transform the second - // character into something else? For example, in Zig, `\n` is - // transformed into the line feed ascii character. - .no_quote_escape => switch (c) { - else => state = .no_quote, - }, - .double_quote_escape => switch (c) { - else => state = .double_quote, - }, - } - } - - defer iter.str = iter.str[iter.str.len..]; - switch (state) { - .skip_whitespace => return null, - .no_quote => return iter.result(start, iter.str.len, &list), - .after_quote => return iter.result(start, iter.str.len - 1, &list), - .no_quote_escape => return Error.DanglingEscape, - .single_quote, - .double_quote, - .double_quote_escape, - => return Error.QuoteNotClosed, - } - } - - fn result(iter: *ShellIterator, start: usize, end: usize, list: *std.ArrayList(u8)) Error!?[]const u8 { - const res = iter.str[start..end]; - - // If we already have something in `list` that means that we could not - // parse the argument without allocation. We therefor need to just append - // the rest we have to the list and return that. - if (list.items.len != 0) { - try list.appendSlice(res); - return try list.toOwnedSlice(); - } - return res; - } -}; - -fn testShellIteratorOk(str: []const u8, allocations: usize, expect: []const []const u8) void { - var allocator = testing.FailingAllocator.init(testing.allocator, allocations); - var it = ShellIterator.init(&allocator.allocator, str); - defer it.deinit(); - - for (expect) |e| { - if (it.next()) |actual| { - testing.expect(actual != null); - testing.expectEqualStrings(e, actual.?); - } else |err| testing.expectEqual(@as(anyerror![]const u8, e), err); - } - - if (it.next()) |actual| { - testing.expectEqual(@as(?[]const u8, null), actual); - testing.expectEqual(allocations, allocator.allocations); - } else |err| testing.expectEqual(@as(anyerror!void, {}), err); -} - -fn testShellIteratorErr(str: []const u8, expect: anyerror) void { - var it = ShellIterator.init(testing.allocator, str); - defer it.deinit(); - - while (it.next() catch |err| { - testing.expectError(expect, @as(anyerror!void, err)); - return; - }) |_| {} - - testing.expectError(expect, @as(anyerror!void, {})); -} - -test "ShellIterator" { - testShellIteratorOk("a", 0, &[_][]const u8{"a"}); - testShellIteratorOk("'a'", 0, &[_][]const u8{"a"}); - testShellIteratorOk("\"a\"", 0, &[_][]const u8{"a"}); - testShellIteratorOk("a b", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("'a' b", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("\"a\" b", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("a 'b'", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("a \"b\"", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("'a b'", 0, &[_][]const u8{"a b"}); - testShellIteratorOk("\"a b\"", 0, &[_][]const u8{"a b"}); - testShellIteratorOk("\"a\"\"b\"", 1, &[_][]const u8{"ab"}); - testShellIteratorOk("'a''b'", 1, &[_][]const u8{"ab"}); - testShellIteratorOk("'a'b", 1, &[_][]const u8{"ab"}); - testShellIteratorOk("a'b'", 1, &[_][]const u8{"ab"}); - testShellIteratorOk("a\\ b", 1, &[_][]const u8{"a b"}); - testShellIteratorOk("\"a\\ b\"", 1, &[_][]const u8{"a b"}); - testShellIteratorOk("'a\\ b'", 0, &[_][]const u8{"a\\ b"}); - testShellIteratorOk(" a b ", 0, &[_][]const u8{ "a", "b" }); - testShellIteratorOk("\\ \\ ", 0, &[_][]const u8{ " ", " " }); - - testShellIteratorOk( - \\printf 'run\nuninstall\n' - , 0, &[_][]const u8{ "printf", "run\\nuninstall\\n" }); - testShellIteratorOk( - \\setsid -f steam "steam://$action/$id" - , 0, &[_][]const u8{ "setsid", "-f", "steam", "steam://$action/$id" }); - testShellIteratorOk( - \\xargs -I% rg --no-heading --no-line-number --only-matching - \\ --case-sensitive --multiline --text --byte-offset '(?-u)%' $@ - \\ - , 0, &[_][]const u8{ - "xargs", "-I%", "rg", "--no-heading", - "--no-line-number", "--only-matching", "--case-sensitive", "--multiline", - "--text", "--byte-offset", "(?-u)%", "$@", - }); - - testShellIteratorErr("'a", error.QuoteNotClosed); - testShellIteratorErr("'a\\", error.QuoteNotClosed); - testShellIteratorErr("\"a", error.QuoteNotClosed); - testShellIteratorErr("\"a\\", error.QuoteNotClosed); - testShellIteratorErr("a\\", error.DanglingEscape); -} diff --git a/src/deps/zig-clap/clap/comptime.zig b/src/deps/zig-clap/clap/comptime.zig deleted file mode 100644 index 3dcd4f7d7..000000000 --- a/src/deps/zig-clap/clap/comptime.zig +++ /dev/null @@ -1,194 +0,0 @@ -const clap = @import("../clap.zig"); -const std = @import("std"); - -const debug = std.debug; -const heap = std.heap; -const mem = std.mem; -const testing = std.testing; - -/// Deprecated: Use `parseEx` instead -pub fn ComptimeClap( - comptime Id: type, - comptime params: []const clap.Param(Id), -) type { - var _flags: usize = 0; - var _single_options: usize = 0; - var _multi_options: usize = 0; - var _converted_params: []const clap.Param(usize) = &[_]clap.Param(usize){}; - for (params) |param| { - var index: usize = 0; - if (param.names.long != null or param.names.short != null) { - const ptr = switch (param.takes_value) { - .none => &_flags, - .one_optional, .one => &_single_options, - .many => &_multi_options, - }; - index = ptr.*; - ptr.* += 1; - } - - const converted = clap.Param(usize){ - .id = index, - .names = param.names, - .takes_value = param.takes_value, - }; - _converted_params = _converted_params ++ [_]clap.Param(usize){converted}; - } - const flags = _flags; - const single_options = _single_options; - const multi_options = _multi_options; - const converted_params = _converted_params; - - return struct { - single_options: [single_options]?[]const u8, - multi_options: [multi_options][]const []const u8, - flags: [flags]bool, - pos: []const []const u8, - passthrough_positionals: []const []const u8, - allocator: mem.Allocator, - - pub fn parse(iter: anytype, opt: clap.ParseOptions) !@This() { - const allocator = opt.allocator; - var multis = [_]std.ArrayList([]const u8){undefined} ** multi_options; - for (&multis) |*multi| { - multi.* = std.ArrayList([]const u8).init(allocator); - } - - var pos = std.ArrayList([]const u8).init(allocator); - var passthrough_positionals = std.ArrayList([]const u8).init(allocator); - - var res = @This(){ - .single_options = [_]?[]const u8{null} ** single_options, - .multi_options = [_][]const []const u8{undefined} ** multi_options, - .flags = [_]bool{false} ** flags, - .pos = undefined, - .allocator = allocator, - .passthrough_positionals = undefined, - }; - - var stream = clap.StreamingClap(usize, @typeInfo(@TypeOf(iter)).Pointer.child){ - .params = converted_params, - .iter = iter, - }; - - while (try stream.next()) |arg| { - const param = arg.param; - if (param.names.long == null and param.names.short == null) { - try pos.append(arg.value.?); - if (opt.stop_after_positional_at > 0 and pos.items.len >= opt.stop_after_positional_at) { - const bun = @import("bun"); - if (comptime bun.Environment.isWindows) @compileError( - "TODO: implement stop_after_positional_at on windows", - ); - - var remaining_ = std.os.argv[@min(std.os.argv.len, stream.iter.args.inner.index)..]; - const first: []const u8 = if (remaining_.len > 0) bun.span(remaining_[0]) else ""; - if (first.len > 0 and std.mem.eql(u8, first, "--")) { - remaining_ = remaining_[1..]; - } - - try passthrough_positionals.ensureTotalCapacityPrecise(remaining_.len); - for (remaining_) |arg_| { - // use bun.span due to the optimization for long strings - passthrough_positionals.appendAssumeCapacity(bun.span(arg_)); - } - break; - } - } else if (param.takes_value == .one or param.takes_value == .one_optional) { - debug.assert(res.single_options.len != 0); - if (res.single_options.len != 0) - res.single_options[param.id] = arg.value orelse ""; - } else if (param.takes_value == .many) { - debug.assert(multis.len != 0); - if (multis.len != 0) - try multis[param.id].append(arg.value.?); - } else { - debug.assert(res.flags.len != 0); - if (res.flags.len != 0) - res.flags[param.id] = true; - } - } - - for (&multis, 0..) |*multi, i| - res.multi_options[i] = try multi.toOwnedSlice(); - res.pos = try pos.toOwnedSlice(); - res.passthrough_positionals = try passthrough_positionals.toOwnedSlice(); - return res; - } - - pub fn deinit(parser: @This()) void { - for (parser.multi_options) |o| - parser.allocator.free(o); - parser.allocator.free(parser.pos); - } - - pub fn flag(parser: @This(), comptime name: []const u8) bool { - const param = comptime findParam(name); - if (param.takes_value != .none and param.takes_value != .one_optional) - @compileError(name ++ " is an option and not a flag."); - - return parser.flags[param.id]; - } - - pub fn option(parser: @This(), comptime name: []const u8) ?[]const u8 { - const param = comptime findParam(name); - if (param.takes_value == .none) - @compileError(name ++ " is a flag and not an option."); - if (param.takes_value == .many) - @compileError(name ++ " takes many options, not one."); - return parser.single_options[param.id]; - } - - pub fn options(parser: @This(), comptime name: []const u8) []const []const u8 { - const param = comptime findParam(name); - if (param.takes_value == .none) - @compileError(name ++ " is a flag and not an option."); - if (param.takes_value == .one or param.takes_value == .one_optional) - @compileError(name ++ " takes one option, not multiple."); - - return parser.multi_options[param.id]; - } - - pub fn positionals(parser: @This()) []const []const u8 { - return parser.pos; - } - - pub fn remaining(parser: @This()) []const []const u8 { - return parser.passthrough_positionals; - } - - pub fn hasFlag(comptime name: []const u8) bool { - comptime { - for (converted_params) |param| { - if (param.names.short) |s| { - if (mem.eql(u8, name, "-" ++ [_]u8{s})) - return true; - } - if (param.names.long) |l| { - if (mem.eql(u8, name, "--" ++ l)) - return true; - } - } - - return false; - } - } - - fn findParam(comptime name: []const u8) clap.Param(usize) { - comptime { - for (converted_params) |param| { - if (param.names.short) |s| { - if (mem.eql(u8, name, "-" ++ [_]u8{s})) - return param; - } - if (param.names.long) |l| { - if (mem.eql(u8, name, "--" ++ l)) - return param; - } - } - - @compileError(name ++ " is not a parameter."); - } - } - }; -} diff --git a/src/deps/zig-clap/clap/streaming.zig b/src/deps/zig-clap/clap/streaming.zig deleted file mode 100644 index e3948e33b..000000000 --- a/src/deps/zig-clap/clap/streaming.zig +++ /dev/null @@ -1,430 +0,0 @@ -const builtin = @import("builtin"); -const clap = @import("../clap.zig"); -const std = @import("std"); - -const args = clap.args; -const debug = std.debug; -const heap = std.heap; -const io = std.io; -const mem = std.mem; -const os = std.os; -const testing = std.testing; - -/// The result returned from StreamingClap.next -pub fn Arg(comptime Id: type) type { - return struct { - const Self = @This(); - - param: *const clap.Param(Id), - value: ?[]const u8 = null, - }; -} - -/// A command line argument parser which, given an ArgIterator, will parse arguments according -/// to the params. StreamingClap parses in an iterating manner, so you have to use a loop together with -/// StreamingClap.next to parse all the arguments of your program. -pub fn StreamingClap(comptime Id: type, comptime ArgIterator: type) type { - return struct { - const State = union(enum) { - normal, - chaining: Chaining, - rest_are_positional, - - const Chaining = struct { - arg: []const u8, - index: usize, - }; - }; - - params: []const clap.Param(Id), - iter: *ArgIterator, - state: State = .normal, - positional: ?*const clap.Param(Id) = null, - diagnostic: ?*clap.Diagnostic = null, - - /// Get the next Arg that matches a Param. - pub fn next(parser: *@This()) !?Arg(Id) { - switch (parser.state) { - .normal => return try parser.normal(), - .chaining => |state| return try parser.chainging(state), - .rest_are_positional => { - const param = parser.positionalParam() orelse unreachable; - const value = parser.iter.next() orelse return null; - return Arg(Id){ .param = param, .value = value }; - }, - } - } - - fn normal(parser: *@This()) !?Arg(Id) { - const ArgType = Arg(Id); - const arg_info = (try parser.parseNextArg()) orelse return null; - const arg = arg_info.arg; - - switch (arg_info.kind) { - .long => { - const eql_index = mem.indexOfScalar(u8, arg, '='); - const name = if (eql_index) |i| arg[0..i] else arg; - const maybe_value = if (eql_index) |i| arg[i + 1 ..] else null; - - for (parser.params) |*param| { - const match = param.names.long orelse continue; - - if (!mem.eql(u8, name, match)) - continue; - if (param.takes_value == .none) { - if (maybe_value != null) - return parser.err(arg, .{ .long = name }, error.DoesntTakeValue); - - return ArgType{ .param = param }; - } - - const value = blk: { - if (maybe_value) |v| - break :blk v; - - break :blk parser.iter.next() orelse brk2: { - if (param.takes_value != .one_optional) - return parser.err(arg, .{ .long = name }, error.MissingValue); - - break :brk2 ""; - }; - }; - - return ArgType{ .param = param, .value = value }; - } - - return null; - }, - .short => return try parser.chainging(.{ - .arg = arg, - .index = 0, - }), - .positional => if (parser.positionalParam()) |param| { - // If we find a positional with the value `--` then we - // interpret the rest of the arguments as positional - // arguments. - if (mem.eql(u8, arg, "--")) { - parser.state = .rest_are_positional; - const value = parser.iter.next() orelse return null; - return Arg(Id){ .param = param, .value = value }; - } - - return Arg(Id){ .param = param, .value = arg }; - } else { - return parser.err(arg, .{}, error.InvalidArgument); - }, - } - } - - fn chainging(parser: *@This(), state: State.Chaining) !?Arg(Id) { - const arg = state.arg; - const index = state.index; - const next_index = index + 1; - - for (parser.params) |*param| { - const short = param.names.short orelse continue; - if (short != arg[index]) - continue; - - // Before we return, we have to set the new state of the clap - defer { - if (arg.len <= next_index or param.takes_value != .none) { - parser.state = .normal; - } else { - parser.state = .{ - .chaining = .{ - .arg = arg, - .index = next_index, - }, - }; - } - } - - const next_is_eql = if (next_index < arg.len) arg[next_index] == '=' else false; - if (param.takes_value == .none or param.takes_value == .one_optional) { - if (next_is_eql and param.takes_value == .none) - return parser.err(arg, .{ .short = short }, error.DoesntTakeValue); - return Arg(Id){ .param = param }; - } - - if (arg.len <= next_index) { - const value = parser.iter.next() orelse - return parser.err(arg, .{ .short = short }, error.MissingValue); - - return Arg(Id){ .param = param, .value = value }; - } - - if (next_is_eql) - return Arg(Id){ .param = param, .value = arg[next_index + 1 ..] }; - - return Arg(Id){ .param = param, .value = arg[next_index..] }; - } - - return parser.err(arg, .{ .short = arg[index] }, error.InvalidArgument); - } - - fn positionalParam(parser: *@This()) ?*const clap.Param(Id) { - if (parser.positional) |p| - return p; - - for (parser.params) |*param| { - if (param.names.long) |_| - continue; - if (param.names.short) |_| - continue; - - parser.positional = param; - return param; - } - - return null; - } - - const ArgInfo = struct { - arg: []const u8, - kind: enum { - long, - short, - positional, - }, - }; - - fn parseNextArg(parser: *@This()) !?ArgInfo { - const full_arg = parser.iter.next() orelse return null; - if (mem.eql(u8, full_arg, "--") or mem.eql(u8, full_arg, "-")) - return ArgInfo{ .arg = full_arg, .kind = .positional }; - if (mem.startsWith(u8, full_arg, "--")) - return ArgInfo{ .arg = full_arg[2..], .kind = .long }; - if (mem.startsWith(u8, full_arg, "-")) - return ArgInfo{ .arg = full_arg[1..], .kind = .short }; - - return ArgInfo{ .arg = full_arg, .kind = .positional }; - } - - fn err(parser: @This(), arg: []const u8, names: clap.Names, _err: anytype) @TypeOf(_err) { - if (parser.diagnostic) |d| - d.* = .{ .arg = arg, .name = names }; - return _err; - } - }; -} - -fn testNoErr(params: []const clap.Param(u8), args_strings: []const []const u8, results: []const Arg(u8)) void { - var iter = args.SliceIterator{ .args = args_strings }; - var c = StreamingClap(u8, args.SliceIterator){ - .params = params, - .iter = &iter, - }; - - for (results) |res| { - const arg = (c.next() catch unreachable) orelse unreachable; - testing.expectEqual(res.param, arg.param); - const expected_value = res.value orelse { - testing.expectEqual(@as(@TypeOf(arg.value), null), arg.value); - continue; - }; - const actual_value = arg.value orelse unreachable; - testing.expectEqualSlices(u8, expected_value, actual_value); - } - - if (c.next() catch unreachable) |_| - unreachable; -} - -fn testErr(params: []const clap.Param(u8), args_strings: []const []const u8, expected: []const u8) void { - var diag = clap.Diagnostic{}; - var iter = args.SliceIterator{ .args = args_strings }; - var c = StreamingClap(u8, args.SliceIterator){ - .params = params, - .iter = &iter, - .diagnostic = &diag, - }; - while (c.next() catch |err| { - var buf: [1024]u8 = undefined; - var fbs = io.fixedBufferStream(&buf); - diag.report(fbs.writer(), err) catch unreachable; - testing.expectEqualStrings(expected, fbs.getWritten()); - return; - }) |_| {} - - testing.expect(false); -} - -test "short params" { - const params = [_]clap.Param(u8){ - .{ .id = 0, .names = .{ .short = 'a' } }, - .{ .id = 1, .names = .{ .short = 'b' } }, - .{ - .id = 2, - .names = .{ .short = 'c' }, - .takes_value = .one, - }, - .{ - .id = 3, - .names = .{ .short = 'd' }, - .takes_value = .many, - }, - }; - - const a = ¶ms[0]; - const b = ¶ms[1]; - const c = ¶ms[2]; - const d = ¶ms[3]; - - testNoErr( - ¶ms, - &[_][]const u8{ - "-a", "-b", "-ab", "-ba", - "-c", "0", "-c=0", "-ac", - "0", "-ac=0", "-d=0", - }, - &[_]Arg(u8){ - .{ .param = a }, - .{ .param = b }, - .{ .param = a }, - .{ .param = b }, - .{ .param = b }, - .{ .param = a }, - .{ .param = c, .value = "0" }, - .{ .param = c, .value = "0" }, - .{ .param = a }, - .{ .param = c, .value = "0" }, - .{ .param = a }, - .{ .param = c, .value = "0" }, - .{ .param = d, .value = "0" }, - }, - ); -} - -test "long params" { - const params = [_]clap.Param(u8){ - .{ .id = 0, .names = .{ .long = "aa" } }, - .{ .id = 1, .names = .{ .long = "bb" } }, - .{ - .id = 2, - .names = .{ .long = "cc" }, - .takes_value = .one, - }, - .{ - .id = 3, - .names = .{ .long = "dd" }, - .takes_value = .many, - }, - }; - - const aa = ¶ms[0]; - const bb = ¶ms[1]; - const cc = ¶ms[2]; - const dd = ¶ms[3]; - - testNoErr( - ¶ms, - &[_][]const u8{ - "--aa", "--bb", - "--cc", "0", - "--cc=0", "--dd=0", - }, - &[_]Arg(u8){ - .{ .param = aa }, - .{ .param = bb }, - .{ .param = cc, .value = "0" }, - .{ .param = cc, .value = "0" }, - .{ .param = dd, .value = "0" }, - }, - ); -} - -test "positional params" { - const params = [_]clap.Param(u8){.{ - .id = 0, - .takes_value = .one, - }}; - - testNoErr( - ¶ms, - &[_][]const u8{ "aa", "bb" }, - &[_]Arg(u8){ - .{ .param = ¶ms[0], .value = "aa" }, - .{ .param = ¶ms[0], .value = "bb" }, - }, - ); -} - -test "all params" { - const params = [_]clap.Param(u8){ - .{ - .id = 0, - .names = .{ .short = 'a', .long = "aa" }, - }, - .{ - .id = 1, - .names = .{ .short = 'b', .long = "bb" }, - }, - .{ - .id = 2, - .names = .{ .short = 'c', .long = "cc" }, - .takes_value = .one, - }, - .{ .id = 3, .takes_value = .one }, - }; - - const aa = ¶ms[0]; - const bb = ¶ms[1]; - const cc = ¶ms[2]; - const positional = ¶ms[3]; - - testNoErr( - ¶ms, - &[_][]const u8{ - "-a", "-b", "-ab", "-ba", - "-c", "0", "-c=0", "-ac", - "0", "-ac=0", "--aa", "--bb", - "--cc", "0", "--cc=0", "something", - "-", "--", "--cc=0", "-a", - }, - &[_]Arg(u8){ - .{ .param = aa }, - .{ .param = bb }, - .{ .param = aa }, - .{ .param = bb }, - .{ .param = bb }, - .{ .param = aa }, - .{ .param = cc, .value = "0" }, - .{ .param = cc, .value = "0" }, - .{ .param = aa }, - .{ .param = cc, .value = "0" }, - .{ .param = aa }, - .{ .param = cc, .value = "0" }, - .{ .param = aa }, - .{ .param = bb }, - .{ .param = cc, .value = "0" }, - .{ .param = cc, .value = "0" }, - .{ .param = positional, .value = "something" }, - .{ .param = positional, .value = "-" }, - .{ .param = positional, .value = "--cc=0" }, - .{ .param = positional, .value = "-a" }, - }, - ); -} - -test "errors" { - const params = [_]clap.Param(u8){ - .{ - .id = 0, - .names = .{ .short = 'a', .long = "aa" }, - }, - .{ - .id = 1, - .names = .{ .short = 'c', .long = "cc" }, - .takes_value = .one, - }, - }; - testErr(¶ms, &[_][]const u8{"q"}, "Invalid argument 'q'\n"); - testErr(¶ms, &[_][]const u8{"-q"}, "Invalid argument '-q'\n"); - testErr(¶ms, &[_][]const u8{"--q"}, "Invalid argument '--q'\n"); - testErr(¶ms, &[_][]const u8{"--q=1"}, "Invalid argument '--q'\n"); - testErr(¶ms, &[_][]const u8{"-a=1"}, "The argument '-a' does not take a value\n"); - testErr(¶ms, &[_][]const u8{"--aa=1"}, "The argument '--aa' does not take a value\n"); - testErr(¶ms, &[_][]const u8{"-c"}, "The argument '-c' requires a value but none was supplied\n"); - testErr(¶ms, &[_][]const u8{"--cc"}, "The argument '--cc' requires a value but none was supplied\n"); -} diff --git a/src/deps/zig-clap/gyro.zzz b/src/deps/zig-clap/gyro.zzz deleted file mode 100644 index 3853db049..000000000 --- a/src/deps/zig-clap/gyro.zzz +++ /dev/null @@ -1,14 +0,0 @@ -pkgs: - clap: - version: 0.3.0 - license: Unlicense - description: Simple command line argument parsing library - source_url: "https://github.com/Hejsil/zig-clap" - root: clap.zig - files: - README.md - LICENSE - build.zig - clap/*.zig - example/*.zig - diff --git a/src/deps/zig-clap/zig.mod b/src/deps/zig-clap/zig.mod deleted file mode 100644 index 00c1a690d..000000000 --- a/src/deps/zig-clap/zig.mod +++ /dev/null @@ -1,5 +0,0 @@ -id: aoe2l16htluewam6bfwvv0khsbbno8g8jd7suonifg74u7kd -name: clap -main: clap.zig -license: Unlicense -dependencies: |