From 858716aa4d569d280e9e31c91fe804eb2a29ef5d Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 6 Aug 2025 01:11:00 -0700 Subject: resinator: a few more updates/fixes Just enough to get things working correctly again --- lib/compiler/resinator/cli.zig | 12 +++++----- lib/compiler/resinator/cvtres.zig | 47 +++++++++++++++++---------------------- lib/compiler/resinator/ico.zig | 6 ++--- lib/compiler/resinator/main.zig | 4 ++-- 4 files changed, 32 insertions(+), 37 deletions(-) (limited to 'lib') diff --git a/lib/compiler/resinator/cli.zig b/lib/compiler/resinator/cli.zig index 6d4a368b4e..bfc67d8791 100644 --- a/lib/compiler/resinator/cli.zig +++ b/lib/compiler/resinator/cli.zig @@ -1141,6 +1141,8 @@ pub fn parse(allocator: Allocator, args: []const []const u8, diagnostics: *Diagn } output_format = .res; } + } else { + output_format_source = .output_format_arg; } options.output_source = .{ .filename = try filepathWithExtension(allocator, options.input_source.filename, output_format.?.extension()) }; } else { @@ -1529,21 +1531,21 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti var diagnostics = Diagnostics.init(std.testing.allocator); defer diagnostics.deinit(); - var output = std.ArrayList(u8).init(std.testing.allocator); + var output: std.io.Writer.Allocating = .init(std.testing.allocator); defer output.deinit(); var options = parse(std.testing.allocator, args, &diagnostics) catch |err| switch (err) { error.ParseError => { - try diagnostics.renderToWriter(args, output.writer(), .no_color); - try std.testing.expectEqualStrings(expected_output, output.items); + try diagnostics.renderToWriter(args, &output.writer, .no_color); + try std.testing.expectEqualStrings(expected_output, output.getWritten()); return null; }, else => |e| return e, }; errdefer options.deinit(); - try diagnostics.renderToWriter(args, output.writer(), .no_color); - try std.testing.expectEqualStrings(expected_output, output.items); + try diagnostics.renderToWriter(args, &output.writer, .no_color); + try std.testing.expectEqualStrings(expected_output, output.getWritten()); return options; } diff --git a/lib/compiler/resinator/cvtres.zig b/lib/compiler/resinator/cvtres.zig index e0c69ad4d9..27e14ae9a3 100644 --- a/lib/compiler/resinator/cvtres.zig +++ b/lib/compiler/resinator/cvtres.zig @@ -65,7 +65,7 @@ pub const ParseResOptions = struct { }; /// The returned ParsedResources should be freed by calling its `deinit` function. -pub fn parseRes(allocator: Allocator, reader: anytype, options: ParseResOptions) !ParsedResources { +pub fn parseRes(allocator: Allocator, reader: *std.Io.Reader, options: ParseResOptions) !ParsedResources { var resources = ParsedResources.init(allocator); errdefer resources.deinit(); @@ -74,7 +74,7 @@ pub fn parseRes(allocator: Allocator, reader: anytype, options: ParseResOptions) return resources; } -pub fn parseResInto(resources: *ParsedResources, reader: anytype, options: ParseResOptions) !void { +pub fn parseResInto(resources: *ParsedResources, reader: *std.Io.Reader, options: ParseResOptions) !void { const allocator = resources.allocator; var bytes_remaining: u64 = options.max_size; { @@ -103,45 +103,38 @@ pub const ResourceAndSize = struct { total_size: u64, }; -pub fn parseResource(allocator: Allocator, reader: anytype, max_size: u64) !ResourceAndSize { - var header_counting_reader = std.io.countingReader(reader); - var buffer: [1024]u8 = undefined; - var header_reader_adapter = header_counting_reader.reader().adaptToNewApi(&buffer); - const header_reader = &header_reader_adapter.new_interface; - const data_size = try header_reader.takeInt(u32, .little); - const header_size = try header_reader.takeInt(u32, .little); +pub fn parseResource(allocator: Allocator, reader: *std.Io.Reader, max_size: u64) !ResourceAndSize { + const data_size = try reader.takeInt(u32, .little); + const header_size = try reader.takeInt(u32, .little); const total_size: u64 = @as(u64, header_size) + data_size; if (total_size > max_size) return error.ImpossibleSize; - var header_bytes_available = header_size -| 8; - var type_reader: std.Io.Reader = .fixed(try header_reader.take(header_bytes_available)); - const type_value = try parseNameOrOrdinal(allocator, &type_reader); + const remaining_header_bytes = try reader.take(header_size -| 8); + var remaining_header_reader: std.Io.Reader = .fixed(remaining_header_bytes); + const type_value = try parseNameOrOrdinal(allocator, &remaining_header_reader); errdefer type_value.deinit(allocator); - header_bytes_available -|= @intCast(type_value.byteLen()); - var name_reader: std.Io.Reader = .fixed(try header_reader.take(header_bytes_available)); - const name_value = try parseNameOrOrdinal(allocator, &name_reader); + const name_value = try parseNameOrOrdinal(allocator, &remaining_header_reader); errdefer name_value.deinit(allocator); - const padding_after_name = numPaddingBytesNeeded(@intCast(header_counting_reader.bytes_read)); - try header_reader.discardAll(padding_after_name); + const padding_after_name = numPaddingBytesNeeded(@intCast(remaining_header_reader.seek)); + try remaining_header_reader.discardAll(padding_after_name); - std.debug.assert(header_counting_reader.bytes_read % 4 == 0); - const data_version = try header_reader.takeInt(u32, .little); - const memory_flags: MemoryFlags = @bitCast(try header_reader.takeInt(u16, .little)); - const language: Language = @bitCast(try header_reader.takeInt(u16, .little)); - const version = try header_reader.takeInt(u32, .little); - const characteristics = try header_reader.takeInt(u32, .little); + std.debug.assert(remaining_header_reader.seek % 4 == 0); + const data_version = try remaining_header_reader.takeInt(u32, .little); + const memory_flags: MemoryFlags = @bitCast(try remaining_header_reader.takeInt(u16, .little)); + const language: Language = @bitCast(try remaining_header_reader.takeInt(u16, .little)); + const version = try remaining_header_reader.takeInt(u32, .little); + const characteristics = try remaining_header_reader.takeInt(u32, .little); - const header_bytes_read = header_counting_reader.bytes_read; - if (header_size != header_bytes_read) return error.HeaderSizeMismatch; + if (remaining_header_reader.seek != remaining_header_reader.end) return error.HeaderSizeMismatch; const data = try allocator.alloc(u8, data_size); errdefer allocator.free(data); - try reader.readNoEof(data); + try reader.readSliceAll(data); const padding_after_data = numPaddingBytesNeeded(@intCast(data_size)); - try reader.skipBytes(padding_after_data, .{ .buf_size = 3 }); + try reader.discardAll(padding_after_data); return .{ .resource = .{ diff --git a/lib/compiler/resinator/ico.zig b/lib/compiler/resinator/ico.zig index a73becd7b9..dca74fc857 100644 --- a/lib/compiler/resinator/ico.zig +++ b/lib/compiler/resinator/ico.zig @@ -14,12 +14,12 @@ pub fn read(allocator: std.mem.Allocator, reader: anytype, max_size: u64) ReadEr // Some Reader implementations have an empty ReadError error set which would // cause 'unreachable else' if we tried to use an else in the switch, so we // need to detect this case and not try to translate to ReadError + const anyerror_reader_errorset = @TypeOf(reader).Error == anyerror; const empty_reader_errorset = @typeInfo(@TypeOf(reader).Error).error_set == null or @typeInfo(@TypeOf(reader).Error).error_set.?.len == 0; - if (empty_reader_errorset) { + if (empty_reader_errorset and !anyerror_reader_errorset) { return readAnyError(allocator, reader, max_size) catch |err| switch (err) { error.EndOfStream => error.UnexpectedEOF, - error.OutOfMemory, error.InvalidHeader, error.InvalidImageType, error.ImpossibleDataSize, error.UnexpectedEOF, error.ReadError => |e| return e, - else => return error.ReadError, + else => |e| return e, }; } else { return readAnyError(allocator, reader, max_size) catch |err| switch (err) { diff --git a/lib/compiler/resinator/main.zig b/lib/compiler/resinator/main.zig index 30e9c825bb..3187f038b9 100644 --- a/lib/compiler/resinator/main.zig +++ b/lib/compiler/resinator/main.zig @@ -325,8 +325,8 @@ pub fn main() !void { std.debug.assert(options.output_format == .coff); // TODO: Maybe use a buffered file reader instead of reading file into memory -> fbs - var fbs = std.io.fixedBufferStream(res_data.bytes); - break :resources cvtres.parseRes(allocator, fbs.reader(), .{ .max_size = res_data.bytes.len }) catch |err| { + var res_reader: std.Io.Reader = .fixed(res_data.bytes); + break :resources cvtres.parseRes(allocator, &res_reader, .{ .max_size = res_data.bytes.len }) catch |err| { // TODO: Better errors try error_handler.emitMessage(allocator, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) }); std.process.exit(1); -- cgit v1.2.3