authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-09-27 14:00:31-07:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2023-09-28 02:25:52-07:00
loga362d3963c879af47661f54b0a698729e142619f
treecc4580245fd8f153482c50c42148833975e4f051
parent937138cb90ae9327b0f7a932910c8d6080984f5c

resinator: Update to latest, fix for big endian arch


5 files changed, 47 insertions(+), 34 deletions(-)

src/resinator/bmp.zig+1-1
...@@ -92,7 +92,7 @@ pub fn read(reader: anytype, max_size: u64) ReadError!BitmapInfo {...@@ -92,7 +92,7 @@ pub fn read(reader: anytype, max_size: u64) ReadError!BitmapInfo {
92 const id = std.mem.readIntNative(u16, file_header[0..2]);92 const id = std.mem.readIntNative(u16, file_header[0..2]);
93 if (id != windows_format_id) return error.InvalidFileHeader;93 if (id != windows_format_id) return error.InvalidFileHeader;
9494
95 bitmap_info.pixel_data_offset = std.mem.readIntNative(u32, file_header[10..14]);95 bitmap_info.pixel_data_offset = std.mem.readIntLittle(u32, file_header[10..14]);
96 if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset;96 if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset;
9797
98 bitmap_info.dib_header_size = reader.readIntLittle(u32) catch return error.UnexpectedEOF;98 bitmap_info.dib_header_size = reader.readIntLittle(u32) catch return error.UnexpectedEOF;
src/resinator/compile.zig+18-16
...@@ -571,7 +571,7 @@ pub const Compiler = struct {...@@ -571,7 +571,7 @@ pub const Compiler = struct {
571 }571 }
572572
573 try file.seekTo(entry.data_offset_from_start_of_file);573 try file.seekTo(entry.data_offset_from_start_of_file);
574 const header_bytes = file.reader().readBytesNoEof(16) catch {574 var header_bytes = file.reader().readBytesNoEof(16) catch {
575 return self.iconReadError(575 return self.iconReadError(
576 error.UnexpectedEOF,576 error.UnexpectedEOF,
577 filename_utf8,577 filename_utf8,
...@@ -647,8 +647,11 @@ pub const Compiler = struct {...@@ -647,8 +647,11 @@ pub const Compiler = struct {
647 },647 },
648 },648 },
649 .dib => {649 .dib => {
650 const bitmap_header: *const ico.BitmapHeader = @ptrCast(@alignCast(&header_bytes));650 var bitmap_header: *ico.BitmapHeader = @ptrCast(@alignCast(&header_bytes));
651 const bitmap_version = ico.BitmapHeader.Version.get(std.mem.littleToNative(u32, bitmap_header.bcSize));651 if (builtin.cpu.arch.endian() == .Big) {
652 std.mem.byteSwapAllFields(ico.BitmapHeader, bitmap_header);
653 }
654 const bitmap_version = ico.BitmapHeader.Version.get(bitmap_header.bcSize);
652655
653 // The Win32 RC compiler only allows headers with656 // The Win32 RC compiler only allows headers with
654 // `bcSize == sizeof(BITMAPINFOHEADER)`, but it seems unlikely657 // `bcSize == sizeof(BITMAPINFOHEADER)`, but it seems unlikely
...@@ -684,15 +687,15 @@ pub const Compiler = struct {...@@ -684,15 +687,15 @@ pub const Compiler = struct {
684 .icon => {687 .icon => {
685 // The values in the icon's BITMAPINFOHEADER always take precedence over688 // The values in the icon's BITMAPINFOHEADER always take precedence over
686 // the values in the IconDir, but not in the LOCALHEADER (see above).689 // the values in the IconDir, but not in the LOCALHEADER (see above).
687 entry.type_specific_data.icon.color_planes = std.mem.littleToNative(u16, bitmap_header.bcPlanes);690 entry.type_specific_data.icon.color_planes = bitmap_header.bcPlanes;
688 entry.type_specific_data.icon.bits_per_pixel = std.mem.littleToNative(u16, bitmap_header.bcBitCount);691 entry.type_specific_data.icon.bits_per_pixel = bitmap_header.bcBitCount;
689 },692 },
690 .cursor => {693 .cursor => {
691 // Only cursors get the width/height from BITMAPINFOHEADER (icons don't)694 // Only cursors get the width/height from BITMAPINFOHEADER (icons don't)
692 entry.width = @intCast(bitmap_header.bcWidth);695 entry.width = @intCast(bitmap_header.bcWidth);
693 entry.height = @intCast(bitmap_header.bcHeight);696 entry.height = @intCast(bitmap_header.bcHeight);
694 entry.type_specific_data.cursor.hotspot_x = std.mem.littleToNative(u16, bitmap_header.bcPlanes);697 entry.type_specific_data.cursor.hotspot_x = bitmap_header.bcPlanes;
695 entry.type_specific_data.cursor.hotspot_y = std.mem.littleToNative(u16, bitmap_header.bcBitCount);698 entry.type_specific_data.cursor.hotspot_y = bitmap_header.bcBitCount;
696 },699 },
697 }700 }
698 },701 },
...@@ -826,9 +829,11 @@ pub const Compiler = struct {...@@ -826,9 +829,11 @@ pub const Compiler = struct {
826 }829 }
827 if (bitmap_info.getExpectedPaletteByteLen() > 0) {830 if (bitmap_info.getExpectedPaletteByteLen() > 0) {
828 try writeResourceDataNoPadding(writer, file_reader, @intCast(bitmap_info.getActualPaletteByteLen()));831 try writeResourceDataNoPadding(writer, file_reader, @intCast(bitmap_info.getActualPaletteByteLen()));
829 const padding_bytes = bitmap_info.getMissingPaletteByteLen();832 // We know that the number of missing palette bytes is <= 4096
833 // (see `bmp_too_many_missing_palette_bytes` error case above)
834 const padding_bytes: usize = @intCast(bitmap_info.getMissingPaletteByteLen());
830 if (padding_bytes > 0) {835 if (padding_bytes > 0) {
831 try writer.writeByteNTimes(0, @intCast(padding_bytes));836 try writer.writeByteNTimes(0, padding_bytes);
832 }837 }
833 }838 }
834 try file.seekTo(bitmap_info.pixel_data_offset);839 try file.seekTo(bitmap_info.pixel_data_offset);
...@@ -2855,7 +2860,7 @@ pub const SearchDir = struct {...@@ -2855,7 +2860,7 @@ pub const SearchDir = struct {
2855pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) type {2860pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype) type {
2856 return struct {2861 return struct {
2857 child_reader: ReaderType,2862 child_reader: ReaderType,
2858 bytes_read: u64 = 0,2863 bytes_read: usize = 0,
2859 slurped_header: [size]u8 = [_]u8{0x00} ** size,2864 slurped_header: [size]u8 = [_]u8{0x00} ** size,
28602865
2861 pub const Error = ReaderType.Error;2866 pub const Error = ReaderType.Error;
...@@ -2866,10 +2871,9 @@ pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype)...@@ -2866,10 +2871,9 @@ pub fn HeaderSlurpingReader(comptime size: usize, comptime ReaderType: anytype)
2866 if (self.bytes_read < size) {2871 if (self.bytes_read < size) {
2867 const bytes_to_add = @min(amt, size - self.bytes_read);2872 const bytes_to_add = @min(amt, size - self.bytes_read);
2868 const end_index = self.bytes_read + bytes_to_add;2873 const end_index = self.bytes_read + bytes_to_add;
2869 const dest = self.slurped_header[@intCast(self.bytes_read)..@intCast(end_index)];2874 std.mem.copy(u8, self.slurped_header[self.bytes_read..end_index], buf[0..bytes_to_add]);
2870 std.mem.copy(u8, dest, buf[0..bytes_to_add]);
2871 }2875 }
2872 self.bytes_read += amt;2876 self.bytes_read +|= amt;
2873 return amt;2877 return amt;
2874 }2878 }
28752879
...@@ -3196,9 +3200,7 @@ pub const StringTable = struct {...@@ -3196,9 +3200,7 @@ pub const StringTable = struct {
3196 // We already trimmed any trailing NULs, so we know it will be a new addition to the string.3200 // We already trimmed any trailing NULs, so we know it will be a new addition to the string.
3197 if (compiler.null_terminate_string_table_strings) string_len_in_utf16_code_units += 1;3201 if (compiler.null_terminate_string_table_strings) string_len_in_utf16_code_units += 1;
3198 try data_writer.writeIntLittle(u16, string_len_in_utf16_code_units);3202 try data_writer.writeIntLittle(u16, string_len_in_utf16_code_units);
3199 for (trimmed_string) |wc| {3203 try data_writer.writeAll(std.mem.sliceAsBytes(trimmed_string));
3200 try data_writer.writeIntLittle(u16, wc);
3201 }
3202 if (compiler.null_terminate_string_table_strings) {3204 if (compiler.null_terminate_string_table_strings) {
3203 try data_writer.writeIntLittle(u16, 0);3205 try data_writer.writeIntLittle(u16, 0);
3204 }3206 }
src/resinator/errors.zig+14-2
...@@ -7,6 +7,7 @@ const res = @import("res.zig");...@@ -7,6 +7,7 @@ const res = @import("res.zig");
7const ico = @import("ico.zig");7const ico = @import("ico.zig");
8const bmp = @import("bmp.zig");8const bmp = @import("bmp.zig");
9const parse = @import("parse.zig");9const parse = @import("parse.zig");
10const lang = @import("lang.zig");
10const CodePage = @import("code_pages.zig").CodePage;11const CodePage = @import("code_pages.zig").CodePage;
1112
12pub const Diagnostics = struct {13pub const Diagnostics = struct {
...@@ -558,8 +559,19 @@ pub const ErrorDetails = struct {...@@ -558,8 +559,19 @@ pub const ErrorDetails = struct {
558 .hint => return,559 .hint => return,
559 },560 },
560 .string_already_defined => switch (self.type) {561 .string_already_defined => switch (self.type) {
561 // TODO: better printing of language, using constant names from WinNT.h562 .err, .warning => {
562 .err, .warning => return writer.print("string with id {d} (0x{X}) already defined for language {d},{d}", .{ self.extra.string_and_language.id, self.extra.string_and_language.id, self.extra.string_and_language.language.primary_language_id, self.extra.string_and_language.language.sublanguage_id }),563 const language_id = self.extra.string_and_language.language.asInt();
564 const language_name = language_name: {
565 if (std.meta.intToEnum(lang.LanguageId, language_id)) |lang_enum_val| {
566 break :language_name @tagName(lang_enum_val);
567 } else |_| {}
568 if (language_id == lang.LOCALE_CUSTOM_UNSPECIFIED) {
569 break :language_name "LOCALE_CUSTOM_UNSPECIFIED";
570 }
571 break :language_name "<UNKNOWN>";
572 };
573 return writer.print("string with id {d} (0x{X}) already defined for language {s} (0x{X})", .{ self.extra.string_and_language.id, self.extra.string_and_language.id, language_name, language_id });
574 },
563 .note => return writer.print("previous definition of string with id {d} (0x{X}) here", .{ self.extra.string_and_language.id, self.extra.string_and_language.id }),575 .note => return writer.print("previous definition of string with id {d} (0x{X}) here", .{ self.extra.string_and_language.id, self.extra.string_and_language.id }),
564 .hint => return,576 .hint => return,
565 },577 },
src/resinator/literals.zig+7-7
...@@ -395,7 +395,7 @@ pub fn parseQuotedString(...@@ -395,7 +395,7 @@ pub fn parseQuotedString(
395 while (try iterative_parser.next()) |parsed| {395 while (try iterative_parser.next()) |parsed| {
396 const c = parsed.codepoint;396 const c = parsed.codepoint;
397 if (parsed.from_escaped_integer) {397 if (parsed.from_escaped_integer) {
398 try buf.append(@intCast(c));398 try buf.append(std.mem.nativeToLittle(T, @intCast(c)));
399 } else {399 } else {
400 switch (literal_type) {400 switch (literal_type) {
401 .ascii => switch (options.output_code_page) {401 .ascii => switch (options.output_code_page) {
...@@ -658,7 +658,7 @@ test "parse quoted wide string" {...@@ -658,7 +658,7 @@ test "parse quoted wide string" {
658 defer arena_allocator.deinit();658 defer arena_allocator.deinit();
659 const arena = arena_allocator.allocator();659 const arena = arena_allocator.allocator();
660660
661 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 'h', 'e', 'l', 'l', 'o' }, try parseQuotedWideString(arena, .{661 try std.testing.expectEqualSentinel(u16, 0, std.unicode.utf8ToUtf16LeStringLiteral("hello"), try parseQuotedWideString(arena, .{
662 .slice =662 .slice =
663 \\L"hello"663 \\L"hello"
664 ,664 ,
...@@ -672,21 +672,21 @@ test "parse quoted wide string" {...@@ -672,21 +672,21 @@ test "parse quoted wide string" {
672 .code_page = .windows1252,672 .code_page = .windows1252,
673 }, .{}));673 }, .{}));
674 // hex max of 4 digits674 // hex max of 4 digits
675 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 0xFFFF, 'f' }, try parseQuotedWideString(arena, .{675 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0xFFFF), std.mem.nativeToLittle(u16, 'f') }, try parseQuotedWideString(arena, .{
676 .slice =676 .slice =
677 \\L"\XfFfFf"677 \\L"\XfFfFf"
678 ,678 ,
679 .code_page = .windows1252,679 .code_page = .windows1252,
680 }, .{}));680 }, .{}));
681 // octal max of 7 digits681 // octal max of 7 digits
682 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ 0x9493, '3', '3' }, try parseQuotedWideString(arena, .{682 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0x9493), std.mem.nativeToLittle(u16, '3'), std.mem.nativeToLittle(u16, '3') }, try parseQuotedWideString(arena, .{
683 .slice =683 .slice =
684 \\L"\111222333"684 \\L"\111222333"
685 ,685 ,
686 .code_page = .windows1252,686 .code_page = .windows1252,
687 }, .{}));687 }, .{}));
688 // octal overflow688 // octal overflow
689 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{0xFF01}, try parseQuotedWideString(arena, .{689 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{std.mem.nativeToLittle(u16, 0xFF01)}, try parseQuotedWideString(arena, .{
690 .slice =690 .slice =
691 \\L"\777401"691 \\L"\777401"
692 ,692 ,
...@@ -757,12 +757,12 @@ test "parse quoted ascii string as wide string" {...@@ -757,12 +757,12 @@ test "parse quoted ascii string as wide string" {
757 .{},757 .{},
758 ));758 ));
759 // Maximum escape sequence value is also determined by the L prefix759 // Maximum escape sequence value is also determined by the L prefix
760 try std.testing.expectEqualSentinel(u16, 0, std.unicode.utf8ToUtf16LeStringLiteral("\x1234"), try parseQuotedStringAsWideString(760 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{ std.mem.nativeToLittle(u16, 0x12), std.mem.nativeToLittle(u16, '3'), std.mem.nativeToLittle(u16, '4') }, try parseQuotedStringAsWideString(
761 arena,761 arena,
762 .{ .slice = "\"\\x1234\"", .code_page = .windows1252 },762 .{ .slice = "\"\\x1234\"", .code_page = .windows1252 },
763 .{},763 .{},
764 ));764 ));
765 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{0x1234}, try parseQuotedStringAsWideString(765 try std.testing.expectEqualSentinel(u16, 0, &[_:0]u16{std.mem.nativeToLittle(u16, 0x1234)}, try parseQuotedStringAsWideString(
766 arena,766 arena,
767 .{ .slice = "L\"\\x1234\"", .code_page = .windows1252 },767 .{ .slice = "L\"\\x1234\"", .code_page = .windows1252 },
768 .{},768 .{},
src/resinator/res.zig+7-8
...@@ -218,6 +218,7 @@ pub const ControlClass = enum(u16) {...@@ -218,6 +218,7 @@ pub const ControlClass = enum(u16) {
218};218};
219219
220pub const NameOrOrdinal = union(enum) {220pub const NameOrOrdinal = union(enum) {
221 // UTF-16 LE
221 name: [:0]const u16,222 name: [:0]const u16,
222 ordinal: u16,223 ordinal: u16,
223224
...@@ -245,9 +246,7 @@ pub const NameOrOrdinal = union(enum) {...@@ -245,9 +246,7 @@ pub const NameOrOrdinal = union(enum) {
245 pub fn write(self: NameOrOrdinal, writer: anytype) !void {246 pub fn write(self: NameOrOrdinal, writer: anytype) !void {
246 switch (self) {247 switch (self) {
247 .name => |name| {248 .name => |name| {
248 for (name[0 .. name.len + 1]) |code_unit| {249 try writer.writeAll(std.mem.sliceAsBytes(name[0 .. name.len + 1]));
249 try writer.writeIntLittle(u16, code_unit);
250 }
251 },250 },
252 .ordinal => |ordinal| {251 .ordinal => |ordinal| {
253 try writer.writeIntLittle(u16, 0xffff);252 try writer.writeIntLittle(u16, 0xffff);
...@@ -281,7 +280,7 @@ pub const NameOrOrdinal = union(enum) {...@@ -281,7 +280,7 @@ pub const NameOrOrdinal = union(enum) {
281 try buf.append(std.mem.nativeToLittle(u16, '�'));280 try buf.append(std.mem.nativeToLittle(u16, '�'));
282 } else if (c < 0x7F) {281 } else if (c < 0x7F) {
283 // ASCII chars in names are always converted to uppercase282 // ASCII chars in names are always converted to uppercase
284 try buf.append(std.ascii.toUpper(@intCast(c)));283 try buf.append(std.mem.nativeToLittle(u16, std.ascii.toUpper(@intCast(c))));
285 } else if (c < 0x10000) {284 } else if (c < 0x10000) {
286 const short: u16 = @intCast(c);285 const short: u16 = @intCast(c);
287 try buf.append(std.mem.nativeToLittle(u16, short));286 try buf.append(std.mem.nativeToLittle(u16, short));
...@@ -518,10 +517,10 @@ test "NameOrOrdinal" {...@@ -518,10 +517,10 @@ test "NameOrOrdinal" {
518 var expected_u8_bytes = "00614982008907933748980730280674788429543776231864944218790698304852300002973622122844631429099469274282385299397783838528QFFL7SHNSIETG0QKLR1UYPBTUV1PMFQRRA0VJDG354GQEDJMUPGPP1W1EXVNTZVEIZ6K3IPQM1AWGEYALMEODYVEZGOD3MFMGEY8FNR4JUETTB1PZDEWSNDRGZUA8SNXP3NGO";517 var expected_u8_bytes = "00614982008907933748980730280674788429543776231864944218790698304852300002973622122844631429099469274282385299397783838528QFFL7SHNSIETG0QKLR1UYPBTUV1PMFQRRA0VJDG354GQEDJMUPGPP1W1EXVNTZVEIZ6K3IPQM1AWGEYALMEODYVEZGOD3MFMGEY8FNR4JUETTB1PZDEWSNDRGZUA8SNXP3NGO";
519 var buf: [256:0]u16 = undefined;518 var buf: [256:0]u16 = undefined;
520 for (expected_u8_bytes, 0..) |byte, i| {519 for (expected_u8_bytes, 0..) |byte, i| {
521 buf[i] = byte;520 buf[i] = std.mem.nativeToLittle(u16, byte);
522 }521 }
523 // surrogate pair that is now orphaned522 // surrogate pair that is now orphaned
524 buf[255] = 0xD801;523 buf[255] = std.mem.nativeToLittle(u16, 0xD801);
525 break :blk buf;524 break :blk buf;
526 };525 };
527 try expectNameOrOrdinal(526 try expectNameOrOrdinal(
...@@ -908,7 +907,7 @@ pub const ForcedOrdinal = struct {...@@ -908,7 +907,7 @@ pub const ForcedOrdinal = struct {
908 var result: u16 = 0;907 var result: u16 = 0;
909 for (utf16) |code_unit| {908 for (utf16) |code_unit| {
910 if (result != 0) result *%= 10;909 if (result != 0) result *%= 10;
911 result +%= code_unit -% '0';910 result +%= std.mem.littleToNative(u16, code_unit) -% '0';
912 }911 }
913 return result;912 return result;
914 }913 }
...@@ -929,7 +928,7 @@ test "forced ordinal" {...@@ -929,7 +928,7 @@ test "forced ordinal" {
929 try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromBytes(.{ .slice = "0\u{10100}", .code_page = .utf8 }));928 try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromBytes(.{ .slice = "0\u{10100}", .code_page = .utf8 }));
930929
931 // From UTF-16930 // From UTF-16
932 try std.testing.expectEqual(@as(u16, 0x122), ForcedOrdinal.fromUtf16Le(&[_:0]u16{ '0', 'Œ' }));931 try std.testing.expectEqual(@as(u16, 0x122), ForcedOrdinal.fromUtf16Le(&[_:0]u16{ std.mem.nativeToLittle(u16, '0'), std.mem.nativeToLittle(u16, 'Œ') }));
933 try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromUtf16Le(std.unicode.utf8ToUtf16LeStringLiteral("0\u{10100}")));932 try std.testing.expectEqual(@as(u16, 0x4AF0), ForcedOrdinal.fromUtf16Le(std.unicode.utf8ToUtf16LeStringLiteral("0\u{10100}")));
934}933}
935934