mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2026-01-17 22:52:40 +01:00
588 lines
26 KiB
Diff
588 lines
26 KiB
Diff
From bde89d2af1d042c015c3999933b5101278af83eb Mon Sep 17 00:00:00 2001
|
|
From: Rene Schallner <rene@rocks.ai>
|
|
Date: Fri, 23 Dec 2022 14:44:34 +0100
|
|
Subject: [PATCH 1/3] updated code to work with zig master 0.11
|
|
|
|
---
|
|
build.zig | 2 +-
|
|
src/args.zig | 202 ++++++++++++++++++++++++++----------------
|
|
src/gitversiontag.zig | 7 +-
|
|
src/main.zig | 13 +--
|
|
4 files changed, 140 insertions(+), 84 deletions(-)
|
|
|
|
diff --git a/build.zig b/build.zig
|
|
index 92e964e..ab9b67e 100644
|
|
--- a/build.zig
|
|
+++ b/build.zig
|
|
@@ -5,7 +5,7 @@ pub fn build(b: *std.build.Builder) void {
|
|
// write src/version.zig
|
|
const alloc = std.heap.page_allocator;
|
|
const gvs = gitVersionTag(alloc);
|
|
- const efmt = "WARNING: could not write src/version.zig:\n {s}\n";
|
|
+ const efmt = "WARNING: could not write src/version.zig:\n {!}\n";
|
|
if (std.fs.cwd().createFile("src/version.zig", .{})) |file| {
|
|
defer file.close();
|
|
const zigfmt = "pub const version_string = \"{s}\";";
|
|
diff --git a/src/args.zig b/src/args.zig
|
|
index a790120..7fa3517 100644
|
|
--- a/src/args.zig
|
|
+++ b/src/args.zig
|
|
@@ -1,7 +1,3 @@
|
|
-// From: https://github.com/MasterQ32/zig-args
|
|
-// Commit: 72a79c87fdf5aaa98f81796fbf6500b5c06b1ebc
|
|
-// (compatible with zig 0.9.1)
|
|
-
|
|
const std = @import("std");
|
|
|
|
/// Parses arguments for the given specification and our current process.
|
|
@@ -9,9 +5,13 @@ const std = @import("std");
|
|
/// - `allocator` is the allocator that is used to allocate all required memory
|
|
/// - `error_handling` defines how parser errors will be handled.
|
|
pub fn parseForCurrentProcess(comptime Spec: type, allocator: std.mem.Allocator, error_handling: ErrorHandling) !ParseArgsResult(Spec, null) {
|
|
- var args = std.process.args();
|
|
+ // Use argsWithAllocator for portability.
|
|
+ // All data allocated by the ArgIterator is freed at the end of the function.
|
|
+ // Data returned to the user is always duplicated using the allocator.
|
|
+ var args = try std.process.argsWithAllocator(allocator);
|
|
+ defer args.deinit();
|
|
|
|
- const executable_name = try (args.next(allocator) orelse {
|
|
+ const executable_name = args.next() orelse {
|
|
try error_handling.process(error.NoExecutableName, Error{
|
|
.option = "",
|
|
.kind = .missing_executable_name,
|
|
@@ -19,12 +19,11 @@ pub fn parseForCurrentProcess(comptime Spec: type, allocator: std.mem.Allocator,
|
|
|
|
// we do not assume any more arguments appear here anyways...
|
|
return error.NoExecutableName;
|
|
- });
|
|
- errdefer allocator.free(executable_name);
|
|
+ };
|
|
|
|
var result = try parseInternal(Spec, null, &args, allocator, error_handling);
|
|
|
|
- result.executable_name = executable_name;
|
|
+ result.executable_name = try allocator.dupeZ(u8, executable_name);
|
|
|
|
return result;
|
|
}
|
|
@@ -34,9 +33,13 @@ pub fn parseForCurrentProcess(comptime Spec: type, allocator: std.mem.Allocator,
|
|
/// - `allocator` is the allocator that is used to allocate all required memory
|
|
/// - `error_handling` defines how parser errors will be handled.
|
|
pub fn parseWithVerbForCurrentProcess(comptime Spec: type, comptime Verb: type, allocator: std.mem.Allocator, error_handling: ErrorHandling) !ParseArgsResult(Spec, Verb) {
|
|
- var args = std.process.args();
|
|
+ // Use argsWithAllocator for portability.
|
|
+ // All data allocated by the ArgIterator is freed at the end of the function.
|
|
+ // Data returned to the user is always duplicated using the allocator.
|
|
+ var args = try std.process.argsWithAllocator(allocator);
|
|
+ defer args.deinit();
|
|
|
|
- const executable_name = try (args.next(allocator) orelse {
|
|
+ const executable_name = args.next() orelse {
|
|
try error_handling.process(error.NoExecutableName, Error{
|
|
.option = "",
|
|
.kind = .missing_executable_name,
|
|
@@ -44,12 +47,11 @@ pub fn parseWithVerbForCurrentProcess(comptime Spec: type, comptime Verb: type,
|
|
|
|
// we do not assume any more arguments appear here anyways...
|
|
return error.NoExecutableName;
|
|
- });
|
|
- errdefer allocator.free(executable_name);
|
|
+ };
|
|
|
|
var result = try parseInternal(Spec, Verb, &args, allocator, error_handling);
|
|
|
|
- result.executable_name = executable_name;
|
|
+ result.executable_name = try allocator.dupeZ(u8, executable_name);
|
|
|
|
return result;
|
|
}
|
|
@@ -92,16 +94,15 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
var result_arena_allocator = result.arena.allocator();
|
|
|
|
var arglist = std.ArrayList([:0]const u8).init(allocator);
|
|
- errdefer arglist.deinit();
|
|
+ defer arglist.deinit();
|
|
|
|
var last_error: ?anyerror = null;
|
|
|
|
- while (args_iterator.next(result_arena_allocator)) |item_or_error| {
|
|
- const item = try item_or_error;
|
|
-
|
|
+ while (args_iterator.next()) |item| {
|
|
if (std.mem.startsWith(u8, item, "--")) {
|
|
if (std.mem.eql(u8, item, "--")) {
|
|
// double hyphen is considered 'everything from here now is positional'
|
|
+ result.raw_start_index = arglist.items.len;
|
|
break;
|
|
}
|
|
|
|
@@ -135,19 +136,21 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
const Tag = std.meta.Tag(Verb);
|
|
inline for (std.meta.fields(Verb)) |verb_info| {
|
|
if (verb.* == @field(Tag, verb_info.name)) {
|
|
- inline for (std.meta.fields(verb_info.field_type)) |fld| {
|
|
- if (std.mem.eql(u8, pair.name, fld.name)) {
|
|
- try parseOption(
|
|
- verb_info.field_type,
|
|
- result_arena_allocator,
|
|
- &@field(verb.*, verb_info.name),
|
|
- args_iterator,
|
|
- error_handling,
|
|
- &last_error,
|
|
- fld.name,
|
|
- pair.value,
|
|
- );
|
|
- found = true;
|
|
+ if (comptime canHaveFieldsAndIsNotZeroSized(verb_info.type)) {
|
|
+ inline for (std.meta.fields(verb_info.type)) |fld| {
|
|
+ if (std.mem.eql(u8, pair.name, fld.name)) {
|
|
+ try parseOption(
|
|
+ verb_info.type,
|
|
+ result_arena_allocator,
|
|
+ &@field(verb.*, verb_info.name),
|
|
+ args_iterator,
|
|
+ error_handling,
|
|
+ &last_error,
|
|
+ fld.name,
|
|
+ pair.value,
|
|
+ );
|
|
+ found = true;
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -166,7 +169,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
} else if (std.mem.startsWith(u8, item, "-")) {
|
|
if (std.mem.eql(u8, item, "-")) {
|
|
// single hyphen is considered a positional argument
|
|
- try arglist.append(item);
|
|
+ try arglist.append(try result_arena_allocator.dupeZ(u8, item));
|
|
} else {
|
|
var any_shorthands = false;
|
|
for (item[1..]) |char, index| {
|
|
@@ -202,30 +205,32 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
if (!found) {
|
|
const Tag = std.meta.Tag(Verb);
|
|
inline for (std.meta.fields(Verb)) |verb_info| {
|
|
- const VerbType = verb_info.field_type;
|
|
- if (verb.* == @field(Tag, verb_info.name)) {
|
|
- const target_value = &@field(verb.*, verb_info.name);
|
|
- if (@hasDecl(VerbType, "shorthands")) {
|
|
- any_shorthands = true;
|
|
- inline for (std.meta.fields(@TypeOf(VerbType.shorthands))) |fld| {
|
|
- if (fld.name.len != 1)
|
|
- @compileError("All shorthand fields must be exactly one character long!");
|
|
- if (fld.name[0] == char) {
|
|
- const real_name = @field(VerbType.shorthands, fld.name);
|
|
- const real_fld_type = @TypeOf(@field(target_value.*, real_name));
|
|
-
|
|
- // -2 because we stripped of the "-" at the beginning
|
|
- if (requiresArg(real_fld_type) and index != item.len - 2) {
|
|
- last_error = error.EncounteredUnexpectedArgument;
|
|
- try error_handling.process(error.EncounteredUnexpectedArgument, Error{
|
|
- .option = &option_name,
|
|
- .kind = .invalid_placement,
|
|
- });
|
|
- } else {
|
|
- try parseOption(VerbType, result_arena_allocator, target_value, args_iterator, error_handling, &last_error, real_name, null);
|
|
+ const VerbType = verb_info.type;
|
|
+ if (comptime canHaveFieldsAndIsNotZeroSized(VerbType)) {
|
|
+ if (verb.* == @field(Tag, verb_info.name)) {
|
|
+ const target_value = &@field(verb.*, verb_info.name);
|
|
+ if (@hasDecl(VerbType, "shorthands")) {
|
|
+ any_shorthands = true;
|
|
+ inline for (std.meta.fields(@TypeOf(VerbType.shorthands))) |fld| {
|
|
+ if (fld.name.len != 1)
|
|
+ @compileError("All shorthand fields must be exactly one character long!");
|
|
+ if (fld.name[0] == char) {
|
|
+ const real_name = @field(VerbType.shorthands, fld.name);
|
|
+ const real_fld_type = @TypeOf(@field(target_value.*, real_name));
|
|
+
|
|
+ // -2 because we stripped of the "-" at the beginning
|
|
+ if (requiresArg(real_fld_type) and index != item.len - 2) {
|
|
+ last_error = error.EncounteredUnexpectedArgument;
|
|
+ try error_handling.process(error.EncounteredUnexpectedArgument, Error{
|
|
+ .option = &option_name,
|
|
+ .kind = .invalid_placement,
|
|
+ });
|
|
+ } else {
|
|
+ try parseOption(VerbType, result_arena_allocator, target_value, args_iterator, error_handling, &last_error, real_name, null);
|
|
+ }
|
|
+ last_error = null; // we need to reset that error here, as it was set previously
|
|
+ found = true;
|
|
}
|
|
- last_error = null; // we need to reset that error here, as it was set previously
|
|
- found = true;
|
|
}
|
|
}
|
|
}
|
|
@@ -255,7 +260,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
inline for (std.meta.fields(Verb)) |fld| {
|
|
if (std.mem.eql(u8, item, fld.name)) {
|
|
// found active verb, default-initialize it
|
|
- result.verb = @unionInit(Verb, fld.name, fld.field_type{});
|
|
+ result.verb = @unionInit(Verb, fld.name, fld.type{});
|
|
}
|
|
}
|
|
|
|
@@ -270,7 +275,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
}
|
|
}
|
|
|
|
- try arglist.append(item);
|
|
+ try arglist.append(try result_arena_allocator.dupeZ(u8, item));
|
|
}
|
|
}
|
|
|
|
@@ -279,22 +284,28 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
|
|
// This will consume the rest of the arguments as positional ones.
|
|
// Only executes when the above loop is broken.
|
|
- while (args_iterator.next(result_arena_allocator)) |item_or_error| {
|
|
- const item = try item_or_error;
|
|
- try arglist.append(item);
|
|
+ while (args_iterator.next()) |item| {
|
|
+ try arglist.append(try result_arena_allocator.dupeZ(u8, item));
|
|
}
|
|
|
|
- result.positionals = arglist.toOwnedSlice();
|
|
+ result.positionals = try arglist.toOwnedSlice();
|
|
return result;
|
|
}
|
|
|
|
+fn canHaveFieldsAndIsNotZeroSized(comptime T: type) bool {
|
|
+ return switch (@typeInfo(T)) {
|
|
+ .Struct, .Union, .Enum, .ErrorSet => @sizeOf(T) != 0,
|
|
+ else => false,
|
|
+ };
|
|
+}
|
|
+
|
|
/// The return type of the argument parser.
|
|
pub fn ParseArgsResult(comptime Generic: type, comptime MaybeVerb: ?type) type {
|
|
if (@typeInfo(Generic) != .Struct)
|
|
@compileError("Generic argument definition must be a struct");
|
|
|
|
if (MaybeVerb) |Verb| {
|
|
- const ti: std.builtin.TypeInfo = @typeInfo(Verb);
|
|
+ const ti: std.builtin.Type = @typeInfo(Verb);
|
|
if (ti != .Union or ti.Union.tag_type == null)
|
|
@compileError("Verb must be a tagged union");
|
|
}
|
|
@@ -318,6 +329,9 @@ pub fn ParseArgsResult(comptime Generic: type, comptime MaybeVerb: ?type) type {
|
|
/// The positional arguments that were passed to the process.
|
|
positionals: [][:0]const u8,
|
|
|
|
+ // The index of the first "raw arg", meaning the first arg after "--"
|
|
+ raw_start_index: ?usize = null,
|
|
+
|
|
/// Name of the executable file (or: zeroth argument)
|
|
executable_name: ?[:0]const u8,
|
|
|
|
@@ -491,21 +505,28 @@ fn parseOption(
|
|
) !void {
|
|
const field_type = @TypeOf(@field(target_struct, name));
|
|
|
|
- const final_value = if (value) |val|
|
|
- val // use the literal value
|
|
- else if (requiresArg(field_type))
|
|
+ const final_value = if (value) |val| blk: {
|
|
+ // use the literal value
|
|
+ const res = try arena.dupeZ(u8, val);
|
|
+ break :blk res;
|
|
+ } else if (requiresArg(field_type)) blk: {
|
|
// fetch from parser
|
|
- try (args.next(arena) orelse {
|
|
+ const val = args.next();
|
|
+ if (val == null or std.mem.eql(u8, val.?, "--")) {
|
|
last_error.* = error.MissingArgument;
|
|
try error_handling.process(error.MissingArgument, Error{
|
|
.option = "--" ++ name,
|
|
.kind = .missing_argument,
|
|
});
|
|
return;
|
|
- })
|
|
- else
|
|
+ }
|
|
+
|
|
+ const res = try arena.dupeZ(u8, val.?);
|
|
+ break :blk res;
|
|
+ } else blk: {
|
|
// argument is "empty"
|
|
- "";
|
|
+ break :blk "";
|
|
+ };
|
|
|
|
@field(target_struct, name) = convertArgumentValue(field_type, arena, final_value) catch |err| {
|
|
last_error.* = err;
|
|
@@ -515,7 +536,7 @@ fn parseOption(
|
|
});
|
|
// we couldn't parse the value, so we return a undefined value as we have signalled an
|
|
// error and won't return this anyways.
|
|
- return undefined;
|
|
+ return;
|
|
};
|
|
}
|
|
|
|
@@ -671,10 +692,10 @@ const TestIterator = struct {
|
|
return TestIterator{ .sequence = items };
|
|
}
|
|
|
|
- pub fn next(self: *@This(), allocator: std.mem.Allocator) ?(error{OutOfMemory}![:0]u8) {
|
|
+ pub fn next(self: *@This()) ?[:0]const u8 {
|
|
if (self.index >= self.sequence.len)
|
|
return null;
|
|
- const result = try allocator.dupeZ(u8, self.sequence[self.index]);
|
|
+ const result = self.sequence[self.index];
|
|
self.index += 1;
|
|
return result;
|
|
}
|
|
@@ -791,9 +812,9 @@ test "shorthand parsing (no verbs)" {
|
|
|
|
test "basic parsing (with verbs)" {
|
|
var titerator = TestIterator.init(&[_][:0]const u8{
|
|
- "booze", // verb
|
|
- "--output",
|
|
+ "--output", // non-verb options can come before or after verb
|
|
"foobar",
|
|
+ "booze", // verb
|
|
"--with-offset",
|
|
"--numberOfBytes",
|
|
"-250",
|
|
@@ -901,3 +922,36 @@ test "strings with sentinel" {
|
|
|
|
try std.testing.expectEqualStrings("foobar", args.options.output.?);
|
|
}
|
|
+
|
|
+test "option argument --" {
|
|
+ var titerator = TestIterator.init(&[_][:0]const u8{
|
|
+ "--output",
|
|
+ "--",
|
|
+ });
|
|
+
|
|
+ try std.testing.expectError(error.MissingArgument, parseInternal(
|
|
+ struct {
|
|
+ output: ?[:0]const u8 = null,
|
|
+ },
|
|
+ null,
|
|
+ &titerator,
|
|
+ std.testing.allocator,
|
|
+ .silent,
|
|
+ ));
|
|
+}
|
|
+
|
|
+test "index of raw indicator --" {
|
|
+ var titerator = TestIterator.init(&[_][:0]const u8{ "stdin", "-", "--", "not-stdin", "-", "--" });
|
|
+
|
|
+ var args = try parseInternal(
|
|
+ struct {},
|
|
+ null,
|
|
+ &titerator,
|
|
+ std.testing.allocator,
|
|
+ .print,
|
|
+ );
|
|
+ defer args.deinit();
|
|
+
|
|
+ try std.testing.expectEqual(args.raw_start_index, 2);
|
|
+ try std.testing.expectEqual(args.positionals.len, 5);
|
|
+}
|
|
diff --git a/src/gitversiontag.zig b/src/gitversiontag.zig
|
|
index 2a05a24..40aed0f 100644
|
|
--- a/src/gitversiontag.zig
|
|
+++ b/src/gitversiontag.zig
|
|
@@ -1,5 +1,5 @@
|
|
const std = @import("std");
|
|
-pub fn gitVersionTag(a: std.mem.Allocator) ![]const u8 {
|
|
+pub fn gitVersionTag(a: std.mem.Allocator) []const u8 {
|
|
const args = [_][]const u8{
|
|
"git",
|
|
"tag",
|
|
@@ -7,13 +7,14 @@ pub fn gitVersionTag(a: std.mem.Allocator) ![]const u8 {
|
|
};
|
|
|
|
if (std.ChildProcess.exec(.{ .argv = args[0..], .allocator = a })) |ret| {
|
|
- if (std.mem.split(u8, ret.stdout, "\n").next()) |firstline| {
|
|
+ var it = std.mem.split(u8, ret.stdout, "\n");
|
|
+ if (it.next()) |firstline| {
|
|
return firstline;
|
|
} else {
|
|
return "unknown";
|
|
}
|
|
} else |err| {
|
|
- std.log.err("Unable to spawn and wait: {any}", .{err});
|
|
+ std.log.err("Unable to spawn and wait: {!}", .{err});
|
|
}
|
|
return "unknown";
|
|
}
|
|
diff --git a/src/main.zig b/src/main.zig
|
|
index 3b4d57d..ae21302 100644
|
|
--- a/src/main.zig
|
|
+++ b/src/main.zig
|
|
@@ -108,7 +108,8 @@ fn addToAddressBook(
|
|
key: []const u8,
|
|
value: []const u8,
|
|
) !void {
|
|
- var file = try std.fs.cwd().openFile(filn, .{ .write = true });
|
|
+ // TODO check if write onlu would be OK
|
|
+ var file = try std.fs.cwd().openFile(filn, .{ .mode = .read_write });
|
|
defer file.close();
|
|
try file.seekFromEnd(0);
|
|
try file.writer().print("\n{s} : {s}", .{ key, value });
|
|
@@ -119,7 +120,7 @@ fn addEmailsToAddressBook(
|
|
map: std.StringHashMap([]const u8),
|
|
emails: std.StringHashMap([]const u8),
|
|
) !void {
|
|
- var file = try std.fs.cwd().openFile(filn, .{ .write = true });
|
|
+ var file = try std.fs.cwd().openFile(filn, .{ .mode = .read_write });
|
|
defer file.close();
|
|
try file.seekFromEnd(0);
|
|
var it = emails.iterator();
|
|
@@ -355,7 +356,7 @@ pub fn main() anyerror!void {
|
|
// do nothing
|
|
} else |err| {
|
|
const errwriter = std.io.getStdErr().writer();
|
|
- try errwriter.print("Error {s}: {s}\n", .{ err, filn });
|
|
+ try errwriter.print("Error {!}: {s}\n", .{ err, filn });
|
|
return;
|
|
}
|
|
const ret = try parseMailFromStdin(alloc);
|
|
@@ -393,7 +394,7 @@ pub fn main() anyerror!void {
|
|
//
|
|
} else |err| {
|
|
const errwriter = std.io.getStdErr().writer();
|
|
- try errwriter.print("Error {s}: {s}\n", .{ err, filn });
|
|
+ try errwriter.print("Error {!}: {s}\n", .{ err, filn });
|
|
return;
|
|
}
|
|
// check if key exists
|
|
@@ -426,7 +427,7 @@ pub fn main() anyerror!void {
|
|
// do nothing
|
|
} else |err| {
|
|
const errwriter = std.io.getStdErr().writer();
|
|
- try errwriter.print("Error {s}: {s}\n", .{ err, filn });
|
|
+ try errwriter.print("Error {!}: {s}\n", .{ err, filn });
|
|
return;
|
|
}
|
|
|
|
@@ -470,7 +471,7 @@ pub fn main() anyerror!void {
|
|
}
|
|
}
|
|
} else |err| {
|
|
- std.debug.print("{s}", .{err});
|
|
+ std.debug.print("{!}", .{err});
|
|
help();
|
|
}
|
|
}
|
|
--
|
|
2.40.0
|
|
|
|
|
|
From 7efc520767869f2eea82a65b943c0d3d64a2b33c Mon Sep 17 00:00:00 2001
|
|
From: Rene Schallner <rene@renerocks.ai>
|
|
Date: Wed, 28 Dec 2022 13:33:16 +0100
|
|
Subject: [PATCH 2/3] back-ported zig-master branch for zig-0.10
|
|
|
|
---
|
|
src/args.zig | 14 +++++++-------
|
|
1 file changed, 7 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/src/args.zig b/src/args.zig
|
|
index 7fa3517..daf27ac 100644
|
|
--- a/src/args.zig
|
|
+++ b/src/args.zig
|
|
@@ -94,7 +94,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
var result_arena_allocator = result.arena.allocator();
|
|
|
|
var arglist = std.ArrayList([:0]const u8).init(allocator);
|
|
- defer arglist.deinit();
|
|
+ errdefer arglist.deinit();
|
|
|
|
var last_error: ?anyerror = null;
|
|
|
|
@@ -136,11 +136,11 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
const Tag = std.meta.Tag(Verb);
|
|
inline for (std.meta.fields(Verb)) |verb_info| {
|
|
if (verb.* == @field(Tag, verb_info.name)) {
|
|
- if (comptime canHaveFieldsAndIsNotZeroSized(verb_info.type)) {
|
|
- inline for (std.meta.fields(verb_info.type)) |fld| {
|
|
+ if (comptime canHaveFieldsAndIsNotZeroSized(verb_info.field_type)) {
|
|
+ inline for (std.meta.fields(verb_info.field_type)) |fld| {
|
|
if (std.mem.eql(u8, pair.name, fld.name)) {
|
|
try parseOption(
|
|
- verb_info.type,
|
|
+ verb_info.field_type,
|
|
result_arena_allocator,
|
|
&@field(verb.*, verb_info.name),
|
|
args_iterator,
|
|
@@ -205,7 +205,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
if (!found) {
|
|
const Tag = std.meta.Tag(Verb);
|
|
inline for (std.meta.fields(Verb)) |verb_info| {
|
|
- const VerbType = verb_info.type;
|
|
+ const VerbType = verb_info.field_type;
|
|
if (comptime canHaveFieldsAndIsNotZeroSized(VerbType)) {
|
|
if (verb.* == @field(Tag, verb_info.name)) {
|
|
const target_value = &@field(verb.*, verb_info.name);
|
|
@@ -260,7 +260,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
inline for (std.meta.fields(Verb)) |fld| {
|
|
if (std.mem.eql(u8, item, fld.name)) {
|
|
// found active verb, default-initialize it
|
|
- result.verb = @unionInit(Verb, fld.name, fld.type{});
|
|
+ result.verb = @unionInit(Verb, fld.name, fld.field_type{});
|
|
}
|
|
}
|
|
|
|
@@ -288,7 +288,7 @@ fn parseInternal(comptime Generic: type, comptime MaybeVerb: ?type, args_iterato
|
|
try arglist.append(try result_arena_allocator.dupeZ(u8, item));
|
|
}
|
|
|
|
- result.positionals = try arglist.toOwnedSlice();
|
|
+ result.positionals = arglist.toOwnedSlice();
|
|
return result;
|
|
}
|
|
|
|
--
|
|
2.40.0
|
|
|
|
|
|
From 85e5c4c3c8dfdec3d103ce3778e8cfe35ad4b074 Mon Sep 17 00:00:00 2001
|
|
From: Rene Schallner <rene@renerocks.ai>
|
|
Date: Wed, 28 Dec 2022 14:00:59 +0100
|
|
Subject: [PATCH 3/3] updated readme
|
|
|
|
---
|
|
README.md | 13 +++++++------
|
|
1 file changed, 7 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/README.md b/README.md
|
|
index e75ebba..8d0b6da 100644
|
|
--- a/README.md
|
|
+++ b/README.md
|
|
@@ -260,8 +260,8 @@ suggested as completion.
|
|
|
|
# Building it
|
|
|
|
-Make sure you have [zig 0.9.1](https://ziglang.org/download/) installed. Then
|
|
-run:
|
|
+Make sure you have the latest stable release of zig, [zig
|
|
+0.10.0](https://ziglang.org/download/) installed. Then run:
|
|
|
|
```console
|
|
zig build
|
|
@@ -272,7 +272,8 @@ This will produce `aercbook` in the `./zig-out/bin/` directory. From there,
|
|
|
|
# Tested with
|
|
|
|
-- zig 0.9.1
|
|
-- aerc 0.11.0
|
|
-- on Linux: NixOS 22.05 ([patched for aerc 0.11.0 instead of
|
|
- 0.10.0](https://sr.ht/~renerocksai/nixpkgs/))
|
|
+- zig 0.10.0
|
|
+- aerc 0.13.0
|
|
+- on Linux:
|
|
+ - NixOS 22.05 ([patched for aerc 0.11.0 instead of 0.10.0](https://sr.ht/~renerocksai/nixpkgs/))
|
|
+ - Ubuntu 20.04.5 LTS on crostini (ChromeOS x86_64)
|
|
--
|
|
2.40.0
|
|
|