fixes for latest zig: a lot of stuff

This commit is contained in:
Luna 2022-04-27 20:01:12 -03:00
parent c817170a04
commit 5d1bcf33ee
7 changed files with 80 additions and 75 deletions

View File

@ -12,11 +12,11 @@ const RunBuffers = plugins.RunBuffers;
pub const RandomNoise = struct { pub const RandomNoise = struct {
r: std.rand.DefaultPrng, r: std.rand.DefaultPrng,
rand_buf: ?[]f32 = null, rand_buf: ?[]f32 = null,
allocator: ?*std.mem.Allocator = null, allocator: ?std.mem.Allocator = null,
cnt: usize = 0, cnt: usize = 0,
pub fn init( pub fn init(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
params: anytype, params: anytype,
) ?RandomNoise { ) ?RandomNoise {
var r = std.rand.DefaultPrng.init(params.seed); var r = std.rand.DefaultPrng.init(params.seed);
@ -25,7 +25,7 @@ pub const RandomNoise = struct {
var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null; var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null;
for (rand_buf) |_, idx| { for (rand_buf) |_, idx| {
rand_buf[idx] = r.random.float(f32); rand_buf[idx] = r.random().float(f32);
} }
return RandomNoise{ return RandomNoise{
@ -52,7 +52,7 @@ pub const RandomNoise = struct {
bufs.out[0] = rand_buf[self.cnt]; bufs.out[0] = rand_buf[self.cnt];
self.cnt += 1; self.cnt += 1;
} else { } else {
bufs.out[0] = self.r.random.float(f32); bufs.out[0] = self.r.random().float(f32);
} }
} }
}; };
@ -60,11 +60,11 @@ pub const RandomNoise = struct {
pub const WildNoise = struct { pub const WildNoise = struct {
r: std.rand.DefaultPrng, r: std.rand.DefaultPrng,
rand_buf: ?[]f32 = null, rand_buf: ?[]f32 = null,
allocator: ?*std.mem.Allocator = null, allocator: ?std.mem.Allocator = null,
cnt: usize = 0, cnt: usize = 0,
pub fn init( pub fn init(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
params: anytype, params: anytype,
) ?WildNoise { ) ?WildNoise {
var r = std.rand.DefaultPrng.init(params.seed); var r = std.rand.DefaultPrng.init(params.seed);
@ -73,7 +73,7 @@ pub const WildNoise = struct {
var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null; var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null;
for (rand_buf) |_, idx| { for (rand_buf) |_, idx| {
rand_buf[idx] = @intToFloat(f32, r.random.int(u1)); rand_buf[idx] = @intToFloat(f32, r.random().int(u1));
} }
return WildNoise{ return WildNoise{
@ -99,7 +99,7 @@ pub const WildNoise = struct {
bufs.out[0] = rand_buf[self.cnt]; bufs.out[0] = rand_buf[self.cnt];
self.cnt += 1; self.cnt += 1;
} else { } else {
bufs.out[0] = @intToFloat(f32, self.r.random.int(u1)); bufs.out[0] = @intToFloat(f32, self.r.random().int(u1));
} }
} }
}; };
@ -112,15 +112,18 @@ pub const Write = struct {
data: f32, data: f32,
pub fn init( pub fn init(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
params: anytype, params: anytype,
) Write { ) Write {
_ = allocator;
return Write{ return Write{
.data = params.data, .data = params.data,
}; };
} }
pub fn deinit(self: *Write) void {} pub fn deinit(self: *Write) void {
_ = self;
}
pub fn run(self: *Write, bufs: *RunBuffers) void { pub fn run(self: *Write, bufs: *RunBuffers) void {
bufs.out[0] = self.data; bufs.out[0] = self.data;
@ -128,13 +131,13 @@ pub const Write = struct {
}; };
pub const Embed = struct { pub const Embed = struct {
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
filepath: []const u8, filepath: []const u8,
sndfile: *c.SNDFILE = undefined, sndfile: *c.SNDFILE = undefined,
buf: []f32 = undefined, buf: []f32 = undefined,
pub fn init(allocator: *std.mem.Allocator, params: anytype) @This() { pub fn init(allocator: std.mem.Allocator, params: anytype) @This() {
return Embed{ return Embed{
.allocator = allocator, .allocator = allocator,
.filepath = params.path, .filepath = params.path,
@ -163,7 +166,9 @@ pub const Embed = struct {
self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels)); self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels));
} }
pub fn deinit(self: *@This()) void {} pub fn deinit(self: *@This()) void {
_ = self;
}
pub fn run(self: *@This(), bufs: *RunBuffers) void { pub fn run(self: *@This(), bufs: *RunBuffers) void {
const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1); const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1);

View File

@ -21,7 +21,7 @@ pub const ImageError = error{
/// Low level integration function with libsndfile. /// Low level integration function with libsndfile.
pub fn sopen( pub fn sopen(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
path: []const u8, path: []const u8,
mode: i32, mode: i32,
fmt: *c.SF_INFO, fmt: *c.SF_INFO,
@ -43,10 +43,10 @@ pub fn sopen(
const frames_on_end = c.sf_seek(file, 0, c.SEEK_END); const frames_on_end = c.sf_seek(file, 0, c.SEEK_END);
_ = c.sf_seek(file, 0, c.SEEK_SET); _ = c.sf_seek(file, 0, c.SEEK_SET);
std.testing.expectEqual(fmt.frames, frames_on_end); try std.testing.expectEqual(fmt.frames, frames_on_end);
const frames_on_end_by_end = c.sf_seek(file, frames_on_end, c.SEEK_SET); const frames_on_end_by_end = c.sf_seek(file, frames_on_end, c.SEEK_SET);
std.testing.expectEqual(frames_on_end, frames_on_end_by_end); try std.testing.expectEqual(frames_on_end, frames_on_end_by_end);
log.debug("frames on end: {}, frame on end (2): {}\n", .{ frames_on_end, frames_on_end_by_end }); log.debug("frames on end: {}, frame on end (2): {}\n", .{ frames_on_end, frames_on_end_by_end });
@ -66,7 +66,7 @@ pub fn sseek(file: *c.SNDFILE, offset: usize) void {
const offset_i64 = @intCast(i64, offset); const offset_i64 = @intCast(i64, offset);
const frames = c.sf_seek(file, offset_i64, c.SEEK_SET); const frames = c.sf_seek(file, offset_i64, c.SEEK_SET);
const frames_current = c.sf_seek(file, 0, c.SEEK_CUR); const frames_current = c.sf_seek(file, 0, c.SEEK_CUR);
std.testing.expectEqual(frames, frames_current); std.debug.assert(frames == frames_current);
if (frames != offset_i64) { if (frames != offset_i64) {
log.debug("failed to seek to {} (seeked {} frames, offset_i64={})\n", .{ offset, frames, offset_i64 }); log.debug("failed to seek to {} (seeked {} frames, offset_i64={})\n", .{ offset, frames, offset_i64 });
@ -74,7 +74,7 @@ pub fn sseek(file: *c.SNDFILE, offset: usize) void {
} }
/// Caller owns the returned memory. /// Caller owns the returned memory.
pub fn temporaryName(allocator: *std.mem.Allocator) ![]u8 { pub fn temporaryName(allocator: std.mem.Allocator) ![]u8 {
const template_start = "/temp/temp_"; const template_start = "/temp/temp_";
const template = "/tmp/temp_XXXXXXXXXXXXXXXXXXXXX"; const template = "/tmp/temp_XXXXXXXXXXXXXXXXXXXXX";
var nam = try allocator.alloc(u8, template.len); var nam = try allocator.alloc(u8, template.len);
@ -89,7 +89,7 @@ pub fn temporaryName(allocator: *std.mem.Allocator) ![]u8 {
while (i < 100) : (i += 1) { while (i < 100) : (i += 1) {
// generate a random uppercase letter, that is, 65 + random number. // generate a random uppercase letter, that is, 65 + random number.
for (fill) |_, f_idx| { for (fill) |_, f_idx| {
var idx = @intCast(u8, r.random.uintLessThan(u5, 24)); var idx = @intCast(u8, r.random().uintLessThan(u5, 24));
var letter = @as(u8, 65) + idx; var letter = @as(u8, 65) + idx;
fill[f_idx] = letter; fill[f_idx] = letter;
} }
@ -97,7 +97,7 @@ pub fn temporaryName(allocator: *std.mem.Allocator) ![]u8 {
// if we fail to access it, we assume it doesn't exist and return it. // if we fail to access it, we assume it doesn't exist and return it.
var tmp_file: std.fs.File = std.fs.cwd().openFile( var tmp_file: std.fs.File = std.fs.cwd().openFile(
nam, nam,
.{ .read = true, .write = false }, .{ .mode = .read_only },
) catch |err| { ) catch |err| {
if (err == error.FileNotFound) return nam else continue; if (err == error.FileNotFound) return nam else continue;
}; };
@ -122,7 +122,7 @@ pub fn mkSfInfo() c.SF_INFO {
} }
pub const Image = struct { pub const Image = struct {
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
/// Pointer to the underlying libsndfile's SNDFILE struct. /// Pointer to the underlying libsndfile's SNDFILE struct.
sndfile: *c.SNDFILE, sndfile: *c.SNDFILE,
@ -137,7 +137,7 @@ pub const Image = struct {
curpath: []const u8, curpath: []const u8,
/// Open a BMP image for later. /// Open a BMP image for later.
pub fn open(allocator: *std.mem.Allocator, path: []const u8) !*Image { pub fn open(allocator: std.mem.Allocator, path: []const u8) !*Image {
var in_fmt = mkSfInfo(); var in_fmt = mkSfInfo();
var sndfile = try sopen(allocator, path, c.SFM_READ, &in_fmt); var sndfile = try sopen(allocator, path, c.SFM_READ, &in_fmt);
@ -197,9 +197,7 @@ pub const Image = struct {
} }
pub fn read(self: *Image, file_chans: c_int, buf: []f32) bool { pub fn read(self: *Image, file_chans: c_int, buf: []f32) bool {
var file = file_opt.?; const n_read: c.sf_count_t = c.sf_readf_float(self.sndfile, buf.ptr, 1);
const n_read: c.sf_count_t = c.sf_readf_float(file, buf.ptr, 1);
const buf_chans = @intCast(c_int, buf.len); const buf_chans = @intCast(c_int, buf.len);
var i = file_chans - 1; var i = file_chans - 1;
@ -276,7 +274,7 @@ pub const Image = struct {
} }
pub fn checkValid(self: *Image) !void { pub fn checkValid(self: *Image) !void {
var file = try std.fs.cwd().openFile(self.path, .{ .read = true }); var file = try std.fs.cwd().openFile(self.path, .{ .mode = .read_only });
defer file.close(); defer file.close();
// main bmp header: // main bmp header:

View File

@ -471,7 +471,7 @@ pub const CommandList = struct {
list: CmdArrayList, list: CmdArrayList,
const Self = @This(); const Self = @This();
pub fn init(allocator: *std.mem.Allocator) Self { pub fn init(allocator: std.mem.Allocator) Self {
return .{ return .{
.list = CmdArrayList.init(allocator), .list = CmdArrayList.init(allocator),
}; };
@ -486,13 +486,16 @@ pub const CommandList = struct {
@field(Command.Tag, field.name); @field(Command.Tag, field.name);
// if we find a match on the tag, we can get the type // if we find a match on the tag, we can get the type
const typ = Command.tagToType(actual_tag); const typ = Command.tagToType(actual_tag);
_ = typ;
inline for (@typeInfo(typ).Struct.fields) |cmd_field| { // TODO fix
switch (cmd_field.field_type) {
[]u8, []const u8 => self.list.allocator.destroy(@field(typ, cmd_field.name)), //inline for (@typeInfo(typ).Struct.fields) |cmd_field| {
else => {}, // switch (cmd_field.field_type) {
} // []u8, []const u8 => self.list.allocator.destroy(@field(typ, cmd_field.name)),
} // else => {},
// }
//}
} }
} }
} }
@ -506,18 +509,20 @@ pub const CommandList = struct {
/// A parser. /// A parser.
pub const Lang = struct { pub const Lang = struct {
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
has_error: bool = false, has_error: bool = false,
line: usize = 0, line: usize = 0,
pub fn init(allocator: *std.mem.Allocator) Lang { pub fn init(allocator: std.mem.Allocator) Lang {
return Lang{ return Lang{
.allocator = allocator, .allocator = allocator,
}; };
} }
pub fn deinit(self: *Lang) void {} pub fn deinit(self: *Lang) void {
_ = self;
}
pub fn reset(self: *Lang) void { pub fn reset(self: *Lang) void {
self.has_error = false; self.has_error = false;
@ -534,7 +539,7 @@ pub const Lang = struct {
fn parseCommandArguments( fn parseCommandArguments(
self: *@This(), self: *@This(),
comptime command_struct: type, comptime command_struct: type,
tok_it: *std.mem.TokenIterator, tok_it: *std.mem.SplitIterator(u8),
commands: *CommandList, commands: *CommandList,
) !void { ) !void {
// Based on the command struct fields, we can parse the arguments. // Based on the command struct fields, we can parse the arguments.
@ -622,7 +627,7 @@ pub const Lang = struct {
} }
pub fn parse(self: *Lang, data: []const u8) !CommandList { pub fn parse(self: *Lang, data: []const u8) !CommandList {
var splitted_it = std.mem.split(data, ";"); var splitted_it = std.mem.split(u8, data, ";");
var cmds = CommandList.init(self.allocator); var cmds = CommandList.init(self.allocator);
errdefer cmds.deinit(); errdefer cmds.deinit();
@ -635,7 +640,7 @@ pub const Lang = struct {
if (std.mem.startsWith(u8, stmt, "#")) continue; if (std.mem.startsWith(u8, stmt, "#")) continue;
// TODO better tokenizer instead of just tokenize(" ")...maybe???? // TODO better tokenizer instead of just tokenize(" ")...maybe????
var tok_it = std.mem.tokenize(stmt, " "); var tok_it = std.mem.split(u8, stmt, " ");
var cmd_opt = tok_it.next(); var cmd_opt = tok_it.next();
if (cmd_opt == null) { if (cmd_opt == null) {
@ -647,15 +652,14 @@ pub const Lang = struct {
var found: bool = false; var found: bool = false;
inline for (@typeInfo(Command).Struct.decls) |cmd_struct_decl| { inline for (@typeInfo(Command).Struct.decls) |cmd_struct_decl| {
switch (cmd_struct_decl.data) { const struct_name = cmd_struct_decl.name;
.Type => |typ| switch (@typeInfo(typ)) { const cmd_struct_type = @field(Command, struct_name);
.Struct => {},
else => continue, switch (@typeInfo(@TypeOf(cmd_struct_type))) {
}, .Struct => {},
else => continue, else => continue,
} }
const struct_name = cmd_struct_decl.name;
comptime var lowered_command_name = [_]u8{0} ** struct_name.len; comptime var lowered_command_name = [_]u8{0} ** struct_name.len;
comptime { comptime {
for (struct_name) |c, i| { for (struct_name) |c, i| {
@ -675,7 +679,6 @@ pub const Lang = struct {
if (std.mem.eql(u8, &lowered_command_name, command_string)) { if (std.mem.eql(u8, &lowered_command_name, command_string)) {
found = true; found = true;
const cmd_struct_type = cmd_struct_decl.data.Type;
try self.parseCommandArguments(cmd_struct_type, &tok_it, &cmds); try self.parseCommandArguments(cmd_struct_type, &tok_it, &cmds);
} }
} }
@ -699,8 +702,8 @@ test "noop" {
var cmds = try lang.parse("noop;"); var cmds = try lang.parse("noop;");
defer cmds.deinit(); defer cmds.deinit();
std.testing.expectEqual(cmds.list.items.len, 1); try std.testing.expectEqual(cmds.list.items.len, 1);
std.testing.expectEqual(cmds.list.items[0].tag, .noop); try std.testing.expectEqual(cmds.list.items[0].tag, .noop);
} }
test "load, phaser, quicksave" { test "load, phaser, quicksave" {
@ -716,10 +719,10 @@ test "load, phaser, quicksave" {
var cmds = try lang.parse(prog); var cmds = try lang.parse(prog);
defer cmds.deinit(); defer cmds.deinit();
std.testing.expectEqual(cmds.list.items.len, 3); try std.testing.expectEqual(cmds.list.items.len, 3);
std.testing.expectEqual(cmds.list.items[0].tag, .load); try std.testing.expectEqual(cmds.list.items[0].tag, .load);
std.testing.expectEqual(cmds.list.items[1].tag, .phaser); try std.testing.expectEqual(cmds.list.items[1].tag, .phaser);
std.testing.expectEqual(cmds.list.items[2].tag, .quicksave); try std.testing.expectEqual(cmds.list.items[2].tag, .quicksave);
} }
test "load, phaser with errors, quicksave" { test "load, phaser with errors, quicksave" {
@ -732,9 +735,5 @@ test "load, phaser with errors, quicksave" {
\\quicksave; \\quicksave;
; ;
var cmds = lang.parse(prog) catch |err| { try std.testing.expectError(error.ParseFail, lang.parse(prog));
return;
};
unreachable;
} }

View File

@ -29,6 +29,7 @@ pub const MagickContext = struct {
} }
pub fn doErr(self: *MagickContext) !void { pub fn doErr(self: *MagickContext) !void {
_ = self;
return error.WandError; return error.WandError;
} }
}; };

View File

@ -18,13 +18,13 @@ const readline = @cImport({
@cInclude("readline/history.h"); @cInclude("readline/history.h");
}); });
fn wrapInCmdList(allocator: *std.mem.Allocator, cmd: *langs.Command) !langs.CommandList { fn wrapInCmdList(allocator: std.mem.Allocator, cmd: *langs.Command) !langs.CommandList {
var cmds = langs.CommandList.init(allocator); var cmds = langs.CommandList.init(allocator);
try cmds.append(cmd); try cmds.append(cmd);
return cmds; return cmds;
} }
fn copyCommandToHeap(allocator: *std.mem.Allocator, command: langs.Command, comptime tag: langs.Command.Tag) !*langs.Command { fn copyCommandToHeap(allocator: std.mem.Allocator, command: langs.Command, comptime tag: langs.Command.Tag) !*langs.Command {
const CommandStruct = langs.Command.tagToType(tag); const CommandStruct = langs.Command.tagToType(tag);
const casted = command.cast(CommandStruct).?; const casted = command.cast(CommandStruct).?;
var heap_cmd = try allocator.create(CommandStruct); var heap_cmd = try allocator.create(CommandStruct);
@ -38,7 +38,7 @@ fn copyCommandToHeap(allocator: *std.mem.Allocator, command: langs.Command, comp
return &heap_cmd.base; return &heap_cmd.base;
} }
pub fn doRepl(allocator: *std.mem.Allocator, args_it: anytype) !void { pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void {
var stdout_file = std.io.getStdOut(); var stdout_file = std.io.getStdOut();
const stdout = &stdout_file.writer(); const stdout = &stdout_file.writer();
const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path")); const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path"));
@ -239,7 +239,7 @@ fn doHelp() void {
log.debug("\tscritcher repl path_to_script.scri path_to_input_file.bmp\n", .{}); log.debug("\tscritcher repl path_to_script.scri path_to_input_file.bmp\n", .{});
} }
fn doRun(allocator: *std.mem.Allocator, args_it: anytype) !void { fn doRun(allocator: std.mem.Allocator, args_it: anytype) !void {
var lang = langs.Lang.init(allocator); var lang = langs.Lang.init(allocator);
defer lang.deinit(); defer lang.deinit();

View File

@ -47,7 +47,7 @@ pub const Position = struct {
/// Represents the starting context for a single plugin run. /// Represents the starting context for a single plugin run.
pub const Context = struct { pub const Context = struct {
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
world: *c.LilvWorld, world: *c.LilvWorld,
plugin: *const c.LilvPlugin, plugin: *const c.LilvPlugin,
@ -75,9 +75,11 @@ pub const RunContext = struct {
instance: *c.LilvInstance, instance: *c.LilvInstance,
pub fn init( pub fn init(
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
plugin: *const c.LilvPlugin, plugin: *const c.LilvPlugin,
) !RunContext { ) !RunContext {
_ = allocator; // TODO batch RunBuffers?
var instance = c.lilv_plugin_instantiate(plugin, @as(f64, 44100), null); var instance = c.lilv_plugin_instantiate(plugin, @as(f64, 44100), null);
errdefer c.lilv_instance_free(instance); errdefer c.lilv_instance_free(instance);
@ -128,7 +130,7 @@ pub const RunContext = struct {
} }
}; };
pub fn makeContext(allocator: *std.mem.Allocator, plugin_uri: []const u8) !Context { pub fn makeContext(allocator: std.mem.Allocator, plugin_uri: []const u8) !Context {
const cstr_plugin_uri = try std.cstr.addNullByte(allocator, plugin_uri); const cstr_plugin_uri = try std.cstr.addNullByte(allocator, plugin_uri);
defer allocator.free(cstr_plugin_uri); defer allocator.free(cstr_plugin_uri);

View File

@ -20,7 +20,7 @@ pub const RunError = error{
}; };
pub const Runner = struct { pub const Runner = struct {
allocator: *std.mem.Allocator, allocator: std.mem.Allocator,
/// The currently opened image in the runner /// The currently opened image in the runner
image: ?*Image = null, image: ?*Image = null,
@ -30,7 +30,7 @@ pub const Runner = struct {
args: []const [:0]u8, args: []const [:0]u8,
pub fn init(allocator: *std.mem.Allocator, repl: bool) Runner { pub fn init(allocator: std.mem.Allocator, repl: bool) Runner {
return Runner{ return Runner{
.allocator = allocator, .allocator = allocator,
.repl = repl, .repl = repl,
@ -164,6 +164,8 @@ pub const Runner = struct {
// if N isn't a number, we just ignore that file // if N isn't a number, we just ignore that file
const idx_str = entry.name[entry_gidx + 2 .. entry_pidx]; const idx_str = entry.name[entry_gidx + 2 .. entry_pidx];
const idx = std.fmt.parseInt(usize, idx_str, 10) catch |err| { const idx = std.fmt.parseInt(usize, idx_str, 10) catch |err| {
log.debug("ignoring file {s}", .{@errorName(err)});
break :blk {}; break :blk {};
}; };
@ -254,7 +256,7 @@ pub const Runner = struct {
cmd: lang.Command, cmd: lang.Command,
comptime tag: lang.Command.Tag, comptime tag: lang.Command.Tag,
) !void { ) !void {
comptime const typ = lang.Command.tagToType(tag); const typ = lang.Command.tagToType(tag);
const command = cmd.cast(typ).?; const command = cmd.cast(typ).?;
const ctype = typ.command_type; const ctype = typ.command_type;
switch (ctype) { switch (ctype) {
@ -315,6 +317,7 @@ pub const Runner = struct {
cmds: lang.CommandList, cmds: lang.CommandList,
debug_flag: bool, debug_flag: bool,
) !void { ) !void {
_ = debug_flag;
for (cmds.list.items) |cmd| { for (cmds.list.items) |cmd| {
cmd.print(); cmd.print();
try self.runCommand(cmd.*); try self.runCommand(cmd.*);
@ -323,18 +326,15 @@ pub const Runner = struct {
}; };
test "running noop" { test "running noop" {
const allocator = std.heap.direct_allocator; const allocator = std.testing.allocator;
var cmds = lang.CommandList.init(allocator); var cmds = lang.CommandList.init(allocator);
defer cmds.deinit(); defer cmds.deinit();
var cmd_ptr = try allocator.create(lang.Command); var command = lang.Command{ .tag = .noop };
cmd_ptr.* = lang.Command{ var noop = lang.Command.Noop{ .base = command };
.command = .Noop, try cmds.append(&noop.base);
.args = lang.ArgList.init(allocator),
};
try cmds.append(cmd_ptr);
var runner = Runner.init(allocator); var runner = Runner.init(allocator, false);
defer runner.deinit(); defer runner.deinit();
try runner.runCommands(cmds, false); try runner.runCommands(cmds, false);