From 0dc5516ac66285bc4ec6b32ff77cb9f78a7dc997 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 22 Nov 2023 21:08:39 -0800 Subject: config: add "theme" config, track inputs --- src/cli/args.zig | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/cli/args.zig') diff --git a/src/cli/args.zig b/src/cli/args.zig index 678c44b1d..d8b670852 100644 --- a/src/cli/args.zig +++ b/src/cli/args.zig @@ -67,6 +67,11 @@ pub fn parse(comptime T: type, alloc: Allocator, dst: *T, iter: anytype) !void { }; while (iter.next()) |arg| { + // If an _inputs fields exist we keep track of the inputs. + if (@hasField(T, "_inputs")) { + try dst._inputs.append(arena_alloc, try arena_alloc.dupe(u8, arg)); + } + // Do manual parsing if we have a hook for it. if (@hasDecl(T, "parseManuallyHook")) { if (!try dst.parseManuallyHook(arena_alloc, arg, iter)) return; @@ -381,6 +386,30 @@ test "parse: error tracking" { try testing.expect(!data._errors.empty()); } +test "parse: input tracking" { + const testing = std.testing; + + var data: struct { + a: []const u8 = "", + b: enum { one } = .one, + + _arena: ?ArenaAllocator = null, + _errors: ErrorList = .{}, + _inputs: std.ArrayListUnmanaged([]const u8) = .{}, + } = .{}; + defer if (data._arena) |arena| arena.deinit(); + + var iter = try std.process.ArgIteratorGeneral(.{}).init( + testing.allocator, + "--what --a=42", + ); + defer iter.deinit(); + try parse(@TypeOf(data), testing.allocator, &data, &iter); + try testing.expect(data._arena != null); + try testing.expect(data._inputs.items.len == 2); + try testing.expectEqualStrings("--what", data._inputs.items[0]); + try testing.expectEqualStrings("--a=42", data._inputs.items[1]); +} test "parseIntoField: ignore underscore-prefixed fields" { const testing = std.testing; var arena = ArenaAllocator.init(testing.allocator); @@ -732,6 +761,25 @@ pub fn lineIterator(reader: anytype) LineIterator(@TypeOf(reader)) { return .{ .r = reader }; } +/// An iterator valid for arg parsing from a slice. +pub const SliceIterator = struct { + const Self = @This(); + + slice: []const []const u8, + idx: usize = 0, + + pub fn next(self: *Self) ?[]const u8 { + if (self.idx >= self.slice.len) return null; + defer self.idx += 1; + return self.slice[self.idx]; + } +}; + +/// Construct a SliceIterator from a slice. +pub fn sliceIterator(slice: []const []const u8) SliceIterator { + return .{ .slice = slice }; +} + test "LineIterator" { const testing = std.testing; var fbs = std.io.fixedBufferStream( -- cgit v1.2.3