diff --git a/build.zig b/build.zig index f7b08f9..467240c 100644 --- a/build.zig +++ b/build.zig @@ -24,19 +24,19 @@ fn setupLinks(step: *builds.LibExeObjStep) void { for (possible_lilv_include_dirs) |possible_lilv_dir| { var possible_dir = std.fs.cwd().openDir(possible_lilv_dir, .{}) catch |err| { - std.debug.print("possible lilv {s} fail: {s}\n", .{ possible_lilv_dir, err }); + std.debug.warn("possible lilv {s} fail: {s}\n", .{ possible_lilv_dir, err }); continue; }; possible_dir.close(); found_any_lilv = true; - std.debug.print("found lilv at '{s}'\n", .{possible_lilv_dir}); + std.debug.warn("found lilv at '{s}'\n", .{possible_lilv_dir}); step.addIncludeDir(possible_lilv_dir); } if (!found_any_lilv) { - std.debug.print("No LILV library was found :(\n", .{}); + std.debug.warn("No LILV library was found :(\n", .{}); @panic("no lilv found"); } } diff --git a/src/bmp_valid.zig b/src/bmp_valid.zig index 55970b8..6468658 100644 --- a/src/bmp_valid.zig +++ b/src/bmp_valid.zig @@ -1,10 +1,11 @@ const std = @import("std"); -const log = std.log.scoped(.scritcher_bmp); + pub const BMPValidError = error{InvalidMagic}; const VALID_MAGICS = [_][]const u8{ "BM", "BA", + "CI", "CP", "IC", @@ -19,7 +20,7 @@ pub fn magicValid(magic: []const u8) !void { } if (!valid) { - log.debug("\tINVALID HEADER: '{s}'\n", .{magic}); + std.debug.warn("\tINVALID HEADER: '{s}'\n", .{magic}); return BMPValidError.InvalidMagic; } } diff --git a/src/custom.zig b/src/custom.zig index 4e48d6a..03120f0 100644 --- a/src/custom.zig +++ b/src/custom.zig @@ -4,7 +4,6 @@ const lv2 = @import("lv2_helpers.zig"); const plugins = @import("plugin.zig"); const image = @import("image.zig"); -const log = std.log.scoped(.scritcher_custom); const c = lv2.c; const RunBuffers = plugins.RunBuffers; @@ -12,11 +11,11 @@ const RunBuffers = plugins.RunBuffers; pub const RandomNoise = struct { r: std.rand.DefaultPrng, rand_buf: ?[]f32 = null, - allocator: ?std.mem.Allocator = null, + allocator: ?*std.mem.Allocator = null, cnt: usize = 0, pub fn init( - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, params: anytype, ) ?RandomNoise { var r = std.rand.DefaultPrng.init(params.seed); @@ -25,7 +24,7 @@ pub const RandomNoise = struct { var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null; for (rand_buf) |_, idx| { - rand_buf[idx] = r.random().float(f32); + rand_buf[idx] = r.random.float(f32); } return RandomNoise{ @@ -52,7 +51,7 @@ pub const RandomNoise = struct { bufs.out[0] = rand_buf[self.cnt]; self.cnt += 1; } else { - bufs.out[0] = self.r.random().float(f32); + bufs.out[0] = self.r.random.float(f32); } } }; @@ -60,11 +59,11 @@ pub const RandomNoise = struct { pub const WildNoise = struct { r: std.rand.DefaultPrng, rand_buf: ?[]f32 = null, - allocator: ?std.mem.Allocator = null, + allocator: ?*std.mem.Allocator = null, cnt: usize = 0, pub fn init( - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, params: anytype, ) ?WildNoise { var r = std.rand.DefaultPrng.init(params.seed); @@ -73,7 +72,7 @@ pub const WildNoise = struct { var rand_buf = allocator.alloc(f32, params.fill_bytes) catch return null; for (rand_buf) |_, idx| { - rand_buf[idx] = @intToFloat(f32, r.random().int(u1)); + rand_buf[idx] = @intToFloat(f32, r.random.int(u1)); } return WildNoise{ @@ -99,7 +98,7 @@ pub const WildNoise = struct { bufs.out[0] = rand_buf[self.cnt]; self.cnt += 1; } else { - bufs.out[0] = @intToFloat(f32, self.r.random().int(u1)); + bufs.out[0] = @intToFloat(f32, self.r.random.int(u1)); } } }; @@ -112,18 +111,15 @@ pub const Write = struct { data: f32, pub fn init( - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, params: anytype, ) Write { - _ = allocator; return Write{ .data = params.data, }; } - pub fn deinit(self: *Write) void { - _ = self; - } + pub fn deinit(self: *Write) void {} pub fn run(self: *Write, bufs: *RunBuffers) void { bufs.out[0] = self.data; @@ -131,13 +127,13 @@ pub const Write = struct { }; pub const Embed = struct { - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, filepath: []const u8, sndfile: *c.SNDFILE = 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{ .allocator = allocator, .filepath = params.path, @@ -166,9 +162,7 @@ pub const Embed = struct { self.buf = try self.allocator.alloc(f32, @intCast(usize, in_fmt.channels)); } - pub fn deinit(self: *@This()) void { - _ = self; - } + pub fn deinit(self: *@This()) void {} pub fn run(self: *@This(), bufs: *RunBuffers) void { const read_bytes = c.sf_readf_float(self.sndfile, self.buf.ptr, 1); @@ -180,7 +174,7 @@ pub const Embed = struct { if (read_bytes < 0) { const st: i32 = c.sf_error(self.sndfile); - log.debug("Failed to read {s} ({s})\n", .{ + std.debug.warn("Failed to read {s} ({s})\n", .{ self.filepath, c.sf_error_number(st), }); diff --git a/src/image.zig b/src/image.zig index 073ffc4..b6e13ae 100644 --- a/src/image.zig +++ b/src/image.zig @@ -3,7 +3,6 @@ const lv2 = @import("lv2_helpers.zig"); const c = lv2.c; const bmp = @import("bmp_valid.zig"); -const log = std.log.scoped(.scritcher_image); const plugins = @import("plugin.zig"); /// Buffer size for main image copying. @@ -21,7 +20,7 @@ pub const ImageError = error{ /// Low level integration function with libsndfile. pub fn sopen( - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, path: []const u8, mode: i32, fmt: *c.SF_INFO, @@ -33,7 +32,7 @@ pub fn sopen( const st: i32 = c.sf_error(file); if (st != 0) { - log.debug("Failed to open {s} ({s})\n", .{ + std.debug.warn("Failed to open {s} ({s})\n", .{ path, c.sf_error_number(st), }); @@ -43,12 +42,12 @@ pub fn sopen( const frames_on_end = c.sf_seek(file, 0, c.SEEK_END); _ = c.sf_seek(file, 0, c.SEEK_SET); - try std.testing.expectEqual(fmt.frames, frames_on_end); + std.testing.expectEqual(fmt.frames, frames_on_end); const frames_on_end_by_end = c.sf_seek(file, frames_on_end, c.SEEK_SET); - try std.testing.expectEqual(frames_on_end, frames_on_end_by_end); + 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 }); + std.debug.warn("frames on end: {}, frame on end (2): {}\n", .{ frames_on_end, frames_on_end_by_end }); return file.?; } @@ -57,7 +56,7 @@ pub fn swrite(file: *c.SNDFILE, buf: [*]f32, frames: i64) !void { const count = c.sf_writef_float(file, buf, frames); if (count != frames) { - log.debug("Wanted to write {}, got {}\n", .{ frames, count }); + std.debug.warn("Wanted to write {}, got {}\n", .{ frames, count }); return ImageError.WriteFail; } } @@ -66,15 +65,15 @@ pub fn sseek(file: *c.SNDFILE, offset: usize) void { const offset_i64 = @intCast(i64, offset); const frames = c.sf_seek(file, offset_i64, c.SEEK_SET); const frames_current = c.sf_seek(file, 0, c.SEEK_CUR); - std.debug.assert(frames == frames_current); + std.testing.expectEqual(frames, frames_current); if (frames != offset_i64) { - log.debug("failed to seek to {} (seeked {} frames, offset_i64={})\n", .{ offset, frames, offset_i64 }); + std.debug.warn("failed to seek to {} (seeked {} frames, offset_i64={})\n", .{ offset, frames, offset_i64 }); } } /// 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 = "/tmp/temp_XXXXXXXXXXXXXXXXXXXXX"; var nam = try allocator.alloc(u8, template.len); @@ -89,7 +88,7 @@ pub fn temporaryName(allocator: std.mem.Allocator) ![]u8 { while (i < 100) : (i += 1) { // generate a random uppercase letter, that is, 65 + random number. 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; fill[f_idx] = letter; } @@ -97,7 +96,7 @@ pub fn temporaryName(allocator: std.mem.Allocator) ![]u8 { // 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( nam, - .{ .mode = .read_only }, + .{ .read = true, .write = false }, ) catch |err| { if (err == error.FileNotFound) return nam else continue; }; @@ -122,7 +121,7 @@ pub fn mkSfInfo() c.SF_INFO { } pub const Image = struct { - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, /// Pointer to the underlying libsndfile's SNDFILE struct. sndfile: *c.SNDFILE, @@ -137,7 +136,7 @@ pub const Image = struct { curpath: []const u8, /// 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 sndfile = try sopen(allocator, path, c.SFM_READ, &in_fmt); @@ -182,7 +181,7 @@ pub const Image = struct { pub fn close(self: *Image) void { var st: i32 = c.sf_close(self.sndfile); if (st != 0) { - log.debug("Failed to close {s} ({s})\n", .{ + std.debug.warn("Failed to close {s} ({s})\n", .{ self.path, c.sf_error_number(st), }); @@ -197,7 +196,9 @@ pub const Image = struct { } pub fn read(self: *Image, file_chans: c_int, buf: []f32) bool { - const n_read: c.sf_count_t = c.sf_readf_float(self.sndfile, buf.ptr, 1); + var file = file_opt.?; + + const n_read: c.sf_count_t = c.sf_readf_float(file, buf.ptr, 1); const buf_chans = @intCast(c_int, buf.len); var i = file_chans - 1; @@ -227,7 +228,7 @@ pub const Image = struct { sseek(out_file, start); while (i <= end) : (i += buf.len) { - log.debug("\t\ti={d}, buf.len={d}, end={d}\n", .{ i, buf.len, end }); + std.debug.warn("\t\ti={d}, buf.len={d}, end={d}\n", .{ i, buf.len, end }); sseek(self.sndfile, i); sseek(out_file, i); @@ -253,7 +254,7 @@ pub const Image = struct { fn getSeekPos(self: *Image, position: plugins.Position) plugins.SeekPos { const file_end = self.frames; var seek_pos = position.seekPos(file_end); - log.debug("\tstart {d} end {d}\n", .{ seek_pos.start, seek_pos.end }); + std.debug.warn("\tstart {d} end {d}\n", .{ seek_pos.start, seek_pos.end }); return seek_pos; } @@ -266,7 +267,7 @@ pub const Image = struct { self.curpath = path; self.frames = @intCast(usize, in_fmt.frames); - log.debug("\timage: reopened on '{s}' (frames={d}, fmt.frames={d})\n", .{ + std.debug.warn("\timage: reopened on '{s}' (frames={d}, fmt.frames={d})\n", .{ self.curpath, self.frames, in_fmt.frames, @@ -274,7 +275,7 @@ pub const Image = struct { } pub fn checkValid(self: *Image) !void { - var file = try std.fs.cwd().openFile(self.path, .{ .mode = .read_only }); + var file = try std.fs.cwd().openFile(self.path, .{ .read = true }); defer file.close(); // main bmp header: @@ -309,12 +310,12 @@ pub const Image = struct { defer ctx.allocator.free(ports); if (ctx.n_audio_in > 2) { - log.debug("plugin <{s}> has more than two inputs.\n", .{plugin_uri}); + std.debug.warn("plugin <{s}> has more than two inputs.\n", .{plugin_uri}); return ImageError.InvalidPlugin; } if (ctx.n_audio_out > 2) { - log.debug("plugin <{s}> has more than two outputs.\n", .{plugin_uri}); + std.debug.warn("plugin <{s}> has more than two outputs.\n", .{plugin_uri}); return ImageError.InvalidPlugin; } @@ -326,14 +327,14 @@ pub const Image = struct { var sym = c.lilv_new_string(ctx.world, sym_cstr.ptr); const port = c.lilv_plugin_get_port_by_symbol(ctx.plugin, sym) orelse { - log.debug("assert fail: symbol {s} not found on port\n", .{param.sym}); + std.debug.warn("assert fail: symbol {s} not found on port\n", .{param.sym}); return ImageError.InvalidSymbol; }; c.lilv_node_free(sym); var idx = c.lilv_port_get_index(ctx.plugin, port); - log.debug("\tset sym={s}, idx={d} to val={}\n", .{ + std.debug.warn("\tset sym={s}, idx={d} to val={}\n", .{ param.sym, idx, param.value, @@ -344,7 +345,7 @@ pub const Image = struct { // now we need to generate a temporary file and put the output of // running the plugin on that file var tmpnam = try temporaryName(self.allocator); - log.debug("\trunning plugin from '{s}' to '{s}'\n", .{ self.curpath, tmpnam }); + std.debug.warn("\trunning plugin from '{s}' to '{s}'\n", .{ self.curpath, tmpnam }); var out_fmt = mkSfInfo(); var out_file = try sopen(self.allocator, tmpnam, c.SFM_WRITE, &out_fmt); @@ -377,7 +378,7 @@ pub const Image = struct { sseek(self.sndfile, seek_pos.start); var i: usize = seek_pos.start; - log.debug("\tseek pos start: {d} end: {d}\n", .{ seek_pos.start, seek_pos.end }); + std.debug.warn("\tseek pos start: {d} end: {d}\n", .{ seek_pos.start, seek_pos.end }); var inbuf = &rctx.buffers.in; var outbuf = &rctx.buffers.out; @@ -388,7 +389,7 @@ pub const Image = struct { const read_bytes = c.sf_readf_float(self.sndfile, inbuf, 1); if (read_bytes == 0) { - log.debug("WARN! reached EOF at idx={d}\n", .{i}); + std.debug.warn("WARN! reached EOF at idx={d}\n", .{i}); break; } @@ -417,11 +418,11 @@ pub const Image = struct { try self.checkValid(); var time_taken = timer.read(); - log.debug("\ttook {d:.2}ms running plugin\n", .{time_taken / std.time.us_per_ms}); + std.debug.warn("\ttook {d:.2}ms running plugin\n", .{time_taken / std.time.us_per_ms}); } pub fn saveTo(self: *Image, out_path: []const u8) !void { - log.debug("\timg: copy from '{s}' to '{s}'\n", .{ self.curpath, out_path }); + std.debug.warn("\timg: copy from '{s}' to '{s}'\n", .{ self.curpath, out_path }); try std.fs.copyFileAbsolute(self.curpath, out_path, .{}); } @@ -449,7 +450,7 @@ pub const Image = struct { // the code here is a copypaste of runPlugin() without the specific // lilv things. var tmpnam = try temporaryName(self.allocator); - log.debug("\trunning CUSTOM plugin from '{s}' to '{s}'\n", .{ self.curpath, tmpnam }); + std.debug.warn("\trunning CUSTOM plugin from '{s}' to '{s}'\n", .{ self.curpath, tmpnam }); var out_fmt = mkSfInfo(); var out_file = try sopen(self.allocator, tmpnam, c.SFM_WRITE, &out_fmt); @@ -476,7 +477,7 @@ pub const Image = struct { sseek(self.sndfile, seek_pos.start); var i: usize = seek_pos.start; - log.debug("\tseek pos start: {d} end: {d}\n", .{ seek_pos.start, seek_pos.end }); + std.debug.warn("\tseek pos start: {d} end: {d}\n", .{ seek_pos.start, seek_pos.end }); var inbuf = &bufs.in; var outbuf = &bufs.out; @@ -484,7 +485,7 @@ pub const Image = struct { while (i <= seek_pos.end) : (i += 1) { const read_bytes = c.sf_readf_float(self.sndfile, inbuf, 1); if (read_bytes == 0) { - log.debug("WARN! reached EOF at idx={d}\n", .{i}); + std.debug.warn("WARN! reached EOF at idx={d}\n", .{i}); break; } diff --git a/src/lang.zig b/src/lang.zig index 98b1e77..3ad0c41 100644 --- a/src/lang.zig +++ b/src/lang.zig @@ -3,7 +3,6 @@ const std = @import("std"); const plugin = @import("plugin.zig"); const custom = @import("custom.zig"); -const log = std.log.scoped(.scritcher_lang); pub const ParseError = error{ParseFail}; pub const CommandType = enum { @@ -147,7 +146,7 @@ pub const Command = struct { } pub fn print(base: *const @This()) void { - log.debug("tag: {s}\n", .{base.tag}); + std.debug.warn("tag: {s}\n", .{base.tag}); } pub const Noop = struct { @@ -471,7 +470,7 @@ pub const CommandList = struct { list: CmdArrayList, const Self = @This(); - pub fn init(allocator: std.mem.Allocator) Self { + pub fn init(allocator: *std.mem.Allocator) Self { return .{ .list = CmdArrayList.init(allocator), }; @@ -479,25 +478,7 @@ pub const CommandList = struct { pub fn deinit(self: *Self) void { for (self.list.items) |cmd_ptr| { - //self.list.allocator.destroy(cmd_ptr); - inline for (@typeInfo(Command.Tag).Enum.fields) |field| { - if (cmd_ptr.tag == @field(Command.Tag, field.name)) { - const actual_tag = - @field(Command.Tag, field.name); - // if we find a match on the tag, we can get the type - const typ = Command.tagToType(actual_tag); - _ = typ; - - // TODO fix - - //inline for (@typeInfo(typ).Struct.fields) |cmd_field| { - // switch (cmd_field.field_type) { - // []u8, []const u8 => self.list.allocator.destroy(@field(typ, cmd_field.name)), - // else => {}, - // } - //} - } - } + self.list.allocator.destroy(cmd_ptr); } self.list.deinit(); } @@ -509,20 +490,18 @@ pub const CommandList = struct { /// A parser. pub const Lang = struct { - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, has_error: bool = false, line: usize = 0, - pub fn init(allocator: std.mem.Allocator) Lang { + pub fn init(allocator: *std.mem.Allocator) Lang { return Lang{ .allocator = allocator, }; } - pub fn deinit(self: *Lang) void { - _ = self; - } + pub fn deinit(self: *Lang) void {} pub fn reset(self: *Lang) void { self.has_error = false; @@ -530,16 +509,16 @@ pub const Lang = struct { } fn doError(self: *Lang, comptime fmt: []const u8, args: anytype) void { - log.err("ERROR! at line {}: ", .{self.line}); - log.err(fmt, args); - log.err("\n", .{}); + std.debug.warn("ERROR! at line {}: ", .{self.line}); + std.debug.warn(fmt, args); + std.debug.warn("\n", .{}); self.has_error = true; } fn parseCommandArguments( self: *@This(), comptime command_struct: type, - tok_it: *std.mem.SplitIterator(u8), + tok_it: *std.mem.TokenIterator, commands: *CommandList, ) !void { // Based on the command struct fields, we can parse the arguments. @@ -582,7 +561,7 @@ pub const Lang = struct { f32 => try std.fmt.parseFloat(f32, arg), u64 => try std.fmt.parseInt(u64, arg, 10), usize => try std.fmt.parseInt(usize, arg, 10), - []const u8 => @as([]const u8, try self.allocator.dupe(u8, arg)), + []const u8 => arg, else => @compileError("parameter struct has unsupported type " ++ @typeName(cmd_field.field_type)), }; @@ -607,11 +586,11 @@ pub const Lang = struct { usize => try std.fmt.parseInt(usize, arg, 10), i32 => try std.fmt.parseInt(i32, arg, 10), f32 => try std.fmt.parseFloat(f32, arg), - []const u8 => @as([]const u8, try self.allocator.dupe(u8, arg)), + []const u8 => arg, else => @compileError("Invalid parameter type (" ++ @typeName(cmd_field.field_type) ++ ") left on command struct " ++ @typeName(command_struct) ++ "."), }; - log.debug("parsing {s}, arg of type {s} => {any}\n", .{ + std.debug.warn("parsing {s}, arg of type {s} => {any}\n", .{ @typeName(command_struct), @typeName(@TypeOf(argument_value)), argument_value, @@ -623,11 +602,11 @@ pub const Lang = struct { cmd.base.tag = command_struct.base_tag; const command = cmd.base.cast(command_struct).?; - log.debug("cmd: {s}\n", .{command}); + std.debug.warn("cmd: {s}\n", .{command}); } pub fn parse(self: *Lang, data: []const u8) !CommandList { - var splitted_it = std.mem.split(u8, data, ";"); + var splitted_it = std.mem.split(data, ";"); var cmds = CommandList.init(self.allocator); errdefer cmds.deinit(); @@ -640,7 +619,7 @@ pub const Lang = struct { if (std.mem.startsWith(u8, stmt, "#")) continue; // TODO better tokenizer instead of just tokenize(" ")...maybe???? - var tok_it = std.mem.split(u8, stmt, " "); + var tok_it = std.mem.tokenize(stmt, " "); var cmd_opt = tok_it.next(); if (cmd_opt == null) { @@ -652,23 +631,15 @@ pub const Lang = struct { var found: bool = false; inline for (@typeInfo(Command).Struct.decls) |cmd_struct_decl| { + switch (cmd_struct_decl.data) { + .Type => |typ| switch (@typeInfo(typ)) { + .Struct => {}, + else => continue, + }, + else => continue, + } + const struct_name = cmd_struct_decl.name; - const cmd_struct_type = @field(Command, struct_name); - - const info_of_info = @typeInfo(@TypeOf(cmd_struct_type)); - - switch (info_of_info) { - .Type => {}, - else => continue, - } - - const info = @typeInfo(cmd_struct_type); - - switch (info) { - .Struct => {}, - else => continue, - } - comptime var lowered_command_name = [_]u8{0} ** struct_name.len; comptime { for (struct_name) |c, i| { @@ -686,8 +657,9 @@ pub const Lang = struct { // Attempting to use ComptimeHashMap hits compiler bugs and I'm // not sure if we can map strings to *types* in it. - if ((!found) and std.mem.eql(u8, &lowered_command_name, command_string)) { + if (std.mem.eql(u8, &lowered_command_name, command_string)) { found = true; + const cmd_struct_type = cmd_struct_decl.data.Type; try self.parseCommandArguments(cmd_struct_type, &tok_it, &cmds); } } @@ -711,8 +683,8 @@ test "noop" { var cmds = try lang.parse("noop;"); defer cmds.deinit(); - try std.testing.expectEqual(cmds.list.items.len, 1); - try std.testing.expectEqual(cmds.list.items[0].tag, .noop); + std.testing.expectEqual(cmds.list.items.len, 1); + std.testing.expectEqual(cmds.list.items[0].tag, .noop); } test "load, phaser, quicksave" { @@ -728,10 +700,10 @@ test "load, phaser, quicksave" { var cmds = try lang.parse(prog); defer cmds.deinit(); - try std.testing.expectEqual(cmds.list.items.len, 3); - try std.testing.expectEqual(cmds.list.items[0].tag, .load); - try std.testing.expectEqual(cmds.list.items[1].tag, .phaser); - try std.testing.expectEqual(cmds.list.items[2].tag, .quicksave); + std.testing.expectEqual(cmds.list.items.len, 3); + std.testing.expectEqual(cmds.list.items[0].tag, .load); + std.testing.expectEqual(cmds.list.items[1].tag, .phaser); + std.testing.expectEqual(cmds.list.items[2].tag, .quicksave); } test "load, phaser with errors, quicksave" { @@ -744,5 +716,9 @@ test "load, phaser with errors, quicksave" { \\quicksave; ; - try std.testing.expectError(error.ParseFail, lang.parse(prog)); + var cmds = lang.parse(prog) catch |err| { + return; + }; + + unreachable; } diff --git a/src/lv2_helpers.zig b/src/lv2_helpers.zig index 62570df..599370c 100644 --- a/src/lv2_helpers.zig +++ b/src/lv2_helpers.zig @@ -1,8 +1,6 @@ const std = @import("std"); const plugin = @import("plugin.zig"); -const log = std.log.scoped(.scritcher_lv2); - pub const c = @cImport({ @cInclude("sndfile.h"); @cInclude("lilv/lilv.h"); @@ -23,7 +21,7 @@ const LV2_CORE__connectionOptional = Lv2Core("#connectionOptional"); pub fn lilv_instance_connect_port( instance: [*c]c.LilvInstance, port_index: u32, - data_location: ?*anyopaque, + data_location: ?*c_void, ) void { instance.?.*.lv2_descriptor.?.*.connect_port.?(instance.?.*.lv2_handle, port_index, data_location); } @@ -120,7 +118,7 @@ pub fn setupPorts(ctx: *plugin.Context) ![]Port { if (c.lilv_port_is_a(ctx.plugin, lport, lv2_InputPort)) { port.is_input = true; } else if (!c.lilv_port_is_a(ctx.plugin, lport, lv2_OutputPort) and !port.optional) { - log.debug("Port {d} is neither input or output\n", .{i}); + std.debug.warn("Port {d} is neither input or output\n", .{i}); return error.UnassignedIOPort; } @@ -136,7 +134,7 @@ pub fn setupPorts(ctx: *plugin.Context) ![]Port { ctx.n_audio_out += 1; } } else if (!port.optional) { - log.debug("Port {d} has unsupported type\n", .{i}); + std.debug.warn("Port {d} has unsupported type\n", .{i}); return error.UnsupportedPortType; } } diff --git a/src/magick.zig b/src/magick.zig index c88ceba..dd5f295 100644 --- a/src/magick.zig +++ b/src/magick.zig @@ -2,7 +2,6 @@ const std = @import("std"); const images = @import("image.zig"); -const log = std.log.scoped(.scritcher_magick); const Image = images.Image; const mc = @cImport({ @@ -29,7 +28,6 @@ pub const MagickContext = struct { } pub fn doErr(self: *MagickContext) !void { - _ = self; return error.WandError; } }; @@ -41,7 +39,7 @@ fn magickLoad(image: *Image) !MagickContext { var curpath = try std.cstr.addNullByte(image.allocator, image.curpath); defer image.allocator.free(curpath); - log.debug("loading '{s}'\n", .{curpath}); + std.debug.warn("loading '{s}'\n", .{curpath}); if (mc.MagickReadImage(mctx.wand, curpath.ptr) != 1) return error.MagickReadFail; @@ -56,12 +54,12 @@ fn magickSave(image: *Image, wand: *mc.MagickWand) !void { var c_tmpnam = try std.cstr.addNullByte(allocator, tmpnam); defer allocator.free(c_tmpnam); - log.debug("\tmagick: saving to '{s}'..", .{c_tmpnam}); + std.debug.warn("\tmagick: saving to '{s}'..", .{c_tmpnam}); if (mc.MagickWriteImage(wand, c_tmpnam.ptr) != 1) return error.MagickWriteFail; - log.debug("OK\n", .{}); + std.debug.warn("OK\n", .{}); try image.reopen(tmpnam); } diff --git a/src/main.zig b/src/main.zig index 9045304..f1cb3c8 100644 --- a/src/main.zig +++ b/src/main.zig @@ -3,8 +3,6 @@ const langs = @import("lang.zig"); const runners = @import("runner.zig"); const printer = @import("printer.zig"); -const log = std.log.scoped(.scritcher); - test "scritcher" { _ = @import("lang.zig"); _ = @import("runner.zig"); @@ -18,13 +16,13 @@ const readline = @cImport({ @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); try cmds.append(cmd); 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 casted = command.cast(CommandStruct).?; var heap_cmd = try allocator.create(CommandStruct); @@ -38,12 +36,10 @@ fn copyCommandToHeap(allocator: std.mem.Allocator, command: langs.Command, compt 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(); const stdout = &stdout_file.writer(); const scri_path = try (args_it.next(allocator) orelse @panic("expected scri path")); - errdefer allocator.free(scri_path); - defer allocator.free(scri_path); var file_read_opt: ?std.fs.File = std.fs.cwd().openFile(scri_path, .{}) catch |err| blk: { if (err == error.FileNotFound) break :blk null; @@ -58,9 +54,11 @@ pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void { defer lang.deinit(); if (total_bytes > 0) { + // this MUST BE long lived (a reference to it is kept inside + // existing_cmds, and then passed along to cmds), + // we can't defer them here var scri_existing = try allocator.alloc(u8, total_bytes); _ = try file_read_opt.?.read(scri_existing); - defer allocator.free(scri_existing); // we can't defer this directly because we copy the // Command pointers to the cmds list. running deinit() directly @@ -91,9 +89,9 @@ pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void { file_read.close(); } - var file = try std.fs.cwd().createFile(scri_path, .{ + var file = try std.fs.cwd().openFile(scri_path, .{ + .write = true, .read = false, - .truncate = true, }); defer file.close(); @@ -134,7 +132,7 @@ pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void { var rd_line = readline.readline("> "); if (rd_line == null) { - log.debug("leaving from eof\n", .{}); + std.debug.warn("leaving from eof\n", .{}); break; } readline.add_history(rd_line); @@ -202,14 +200,14 @@ pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void { try printer.printList(cmds, stream); continue; } else if (std.mem.eql(u8, line, "quit") or std.mem.eql(u8, line, "q")) { - log.debug("leaving\n", .{}); + std.debug.warn("leaving\n", .{}); break; } else if (std.mem.startsWith(u8, line, "#")) { continue; } var cmds_parsed = lang.parse(line) catch |err| { - log.debug("repl: error while parsing: {}\n", .{err}); + std.debug.warn("repl: error while parsing: {}\n", .{err}); continue; }; @@ -233,13 +231,13 @@ pub fn doRepl(allocator: std.mem.Allocator, args_it: anytype) !void { } fn doHelp() void { - log.debug("scritcher!\n", .{}); - log.debug("usage: scritcher [run|help|repl]\n", .{}); - log.debug("\tscritcher run path_to_script.scri path_to_input_file.bmp\n", .{}); - log.debug("\tscritcher repl path_to_script.scri path_to_input_file.bmp\n", .{}); + std.debug.warn("scritcher!\n", .{}); + std.debug.warn("usage: scritcher [run|help|repl]\n", .{}); + std.debug.warn("\tscritcher run path_to_script.scri path_to_input_file.bmp\n", .{}); + std.debug.warn("\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); defer lang.deinit(); @@ -290,7 +288,7 @@ pub fn main() !void { } else if (std.mem.eql(u8, cli_command, "run")) { return try doRun(allocator, &args_it); } else { - log.debug("unknown command: '{s}'\n", .{cli_command}); + std.debug.warn("unknown command: '{s}'\n", .{cli_command}); return error.UnknownCommand; } } diff --git a/src/plugin.zig b/src/plugin.zig index 8e88283..cb8c64a 100644 --- a/src/plugin.zig +++ b/src/plugin.zig @@ -3,7 +3,6 @@ const std = @import("std"); const lv2 = @import("lv2_helpers.zig"); const c = lv2.c; -const log = std.log.scoped(.scritcher_plugin); const ImageError = @import("image.zig").ImageError; /// Control port @@ -47,7 +46,7 @@ pub const Position = struct { /// Represents the starting context for a single plugin run. pub const Context = struct { - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, world: *c.LilvWorld, plugin: *const c.LilvPlugin, @@ -75,11 +74,9 @@ pub const RunContext = struct { instance: *c.LilvInstance, pub fn init( - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, plugin: *const c.LilvPlugin, ) !RunContext { - _ = allocator; // TODO batch RunBuffers? - var instance = c.lilv_plugin_instantiate(plugin, @as(f64, 44100), null); errdefer c.lilv_instance_free(instance); @@ -130,7 +127,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); defer allocator.free(cstr_plugin_uri); @@ -140,7 +137,7 @@ pub fn makeContext(allocator: std.mem.Allocator, plugin_uri: []const u8) !Contex c.lilv_world_load_all(world); var uri: *c.LilvNode = c.lilv_new_uri(world, cstr_plugin_uri.ptr) orelse { - log.debug("Invalid plugin URI <{s}>\n", .{plugin_uri}); + std.debug.warn("Invalid plugin URI <{s}>\n", .{plugin_uri}); return ImageError.InvalidPlugin; }; defer c.lilv_node_free(uri); @@ -148,7 +145,7 @@ pub fn makeContext(allocator: std.mem.Allocator, plugin_uri: []const u8) !Contex const plugins: *const c.LilvPlugins = c.lilv_world_get_all_plugins(world).?; var plugin: *const c.LilvPlugin = c.lilv_plugins_get_by_uri(plugins, uri) orelse { - log.debug("Plugin <{s}> not found\n", .{plugin_uri}); + std.debug.warn("Plugin <{s}> not found\n", .{plugin_uri}); return ImageError.UnknownPlugin; }; diff --git a/src/printer.zig b/src/printer.zig index a851602..c1fab31 100644 --- a/src/printer.zig +++ b/src/printer.zig @@ -1,8 +1,6 @@ const std = @import("std"); const langs = @import("lang.zig"); -const log = std.log.scoped(.scritcher_printer); - fn printCommandWithParams(stream: anytype, command: anytype) !void { const Parameters = @TypeOf(command.parameters); try stream.print(" {d} {d}", .{ command.split, command.index }); diff --git a/src/runner.zig b/src/runner.zig index eb41231..16bbc12 100644 --- a/src/runner.zig +++ b/src/runner.zig @@ -5,8 +5,6 @@ const plugin = @import("plugin.zig"); const custom = @import("custom.zig"); const magick = @import("magick.zig"); -const log = std.log.scoped(.scritcher_runner); - const Position = plugin.Position; const ParamList = plugin.ParamList; const ParamMap = plugin.ParamMap; @@ -20,7 +18,7 @@ pub const RunError = error{ }; pub const Runner = struct { - allocator: std.mem.Allocator, + allocator: *std.mem.Allocator, /// The currently opened image in the runner image: ?*Image = null, @@ -30,7 +28,7 @@ pub const Runner = struct { 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{ .allocator = allocator, .repl = repl, @@ -67,12 +65,12 @@ pub const Runner = struct { // 'scritcher repl ./script ./image' // ':0' should ALWAYS point to the image. - if (self.repl) index += 3 else index += 3; + if (self.repl) index += 4 else index += 3; for (self.args) |arg, idx| { - log.debug("arg{d} = {s}\n", .{ idx, arg }); + std.debug.warn("arg{d} = {s}\n", .{ idx, arg }); } - log.debug("fetch arg idx={d}, val={s}\n", .{ index, self.args[index] }); + std.debug.warn("fetch arg idx={d}, val={s}\n", .{ index, self.args[index] }); return self.args[index]; } else { return load_path; @@ -92,7 +90,7 @@ pub const Runner = struct { fn loadCmd(self: *Runner, path_or_argidx: []const u8) !void { const load_path = try self.resolveArgPath(path_or_argidx); - log.debug("\tload path: {s}\n", .{load_path}); + std.debug.warn("\tload path: {s}\n", .{load_path}); // we could use ImageMagick to convert from X to BMP // but i can't find an easy way to do things in memory. @@ -102,7 +100,7 @@ pub const Runner = struct { // krita/gimp and make it export a bmp and while in the program you can // apply filters, etc. if (!std.mem.endsWith(u8, load_path, ".bmp") and !std.mem.endsWith(u8, load_path, ".ppm")) { - log.debug("Only BMP files are allowed to be loaded. Got path '{s}'\n", .{load_path}); + std.debug.warn("Only BMP files are allowed to be loaded. Got path '{s}'\n", .{load_path}); return RunError.NoBMP; } @@ -117,7 +115,7 @@ pub const Runner = struct { if (self.image) |image| { return image; } else { - log.debug("image is required!\n", .{}); + std.debug.warn("image is required!\n", .{}); return RunError.ImageRequired; } } @@ -164,8 +162,6 @@ pub const Runner = struct { // if N isn't a number, we just ignore that file const idx_str = entry.name[entry_gidx + 2 .. entry_pidx]; const idx = std.fmt.parseInt(usize, idx_str, 10) catch |err| { - log.debug("ignoring file {s}", .{@errorName(err)}); - break :blk {}; }; @@ -205,7 +201,7 @@ pub const Runner = struct { ); defer proc.deinit(); - log.debug("running '{s} {s}'\n", .{ runqs.program, out_path }); + std.debug.warn("running '{s} {s}'\n", .{ runqs.program, out_path }); _ = try proc.spawnAndWait(); } @@ -256,7 +252,7 @@ pub const Runner = struct { cmd: lang.Command, comptime tag: lang.Command.Tag, ) !void { - const typ = lang.Command.tagToType(tag); + comptime const typ = lang.Command.tagToType(tag); const command = cmd.cast(typ).?; const ctype = typ.command_type; switch (ctype) { @@ -317,7 +313,6 @@ pub const Runner = struct { cmds: lang.CommandList, debug_flag: bool, ) !void { - _ = debug_flag; for (cmds.list.items) |cmd| { cmd.print(); try self.runCommand(cmd.*); @@ -326,15 +321,18 @@ pub const Runner = struct { }; test "running noop" { - const allocator = std.testing.allocator; + const allocator = std.heap.direct_allocator; var cmds = lang.CommandList.init(allocator); defer cmds.deinit(); - var command = lang.Command{ .tag = .noop }; - var noop = lang.Command.Noop{ .base = command }; - try cmds.append(&noop.base); + var cmd_ptr = try allocator.create(lang.Command); + cmd_ptr.* = lang.Command{ + .command = .Noop, + .args = lang.ArgList.init(allocator), + }; + try cmds.append(cmd_ptr); - var runner = Runner.init(allocator, false); + var runner = Runner.init(allocator); defer runner.deinit(); try runner.runCommands(cmds, false);