authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-01-13 01:47:27-08:00
committergravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2026-01-14 01:04:24+01:00
log9d1a39c50ffeca1e42ed5f1b75a05d92eec869db
tree03c56dae947600041d0b0f52287db87e7b5b6ef9
parent3da6e671997442df44df3257e882819eae649c8d

resinator: Sync with upstream

No functional differences, just some shuffling things around and the removal of the now-obsolete `utils.openFileNotDir`.

6 files changed, 39 insertions(+), 53 deletions(-)

lib/compiler/resinator/cli.zig+10-6
...@@ -128,15 +128,19 @@ pub const Diagnostics = struct {...@@ -128,15 +128,19 @@ pub const Diagnostics = struct {
128 pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) Io.Cancelable!void {128 pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) Io.Cancelable!void {
129 const stderr = try io.lockStderr(&.{}, null);129 const stderr = try io.lockStderr(&.{}, null);
130 defer io.unlockStderr();130 defer io.unlockStderr();
131 self.renderToWriter(args, stderr.terminal()) catch return;131 self.renderToTerminal(stderr.terminal(), args) catch return;
132 }132 }
133133
134 pub fn renderToWriter(self: *Diagnostics, args: []const []const u8, t: Io.Terminal) !void {134 pub fn renderToTerminal(self: *Diagnostics, terminal: Io.Terminal, args: []const []const u8) !void {
135 for (self.errors.items) |err_details| {135 for (self.errors.items) |err_details| {
136 try renderErrorMessage(t, err_details, args);136 try renderErrorMessage(terminal, err_details, args);
137 }137 }
138 }138 }
139139
140 pub fn renderToWriter(self: *Diagnostics, writer: *Io.Writer, args: []const []const u8) !void {
141 return self.renderToTerminal(.{ .writer = writer, .mode = .no_color }, args);
142 }
143
140 pub fn hasError(self: *const Diagnostics) bool {144 pub fn hasError(self: *const Diagnostics) bool {
141 for (self.errors.items) |err| {145 for (self.errors.items) |err| {
142 if (err.type == .err) return true;146 if (err.type == .err) return true;
...@@ -1475,9 +1479,9 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti...@@ -1475,9 +1479,9 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti
1475 var output: std.Io.Writer.Allocating = .init(std.testing.allocator);1479 var output: std.Io.Writer.Allocating = .init(std.testing.allocator);
1476 defer output.deinit();1480 defer output.deinit();
14771481
1478 var options = parse(std.testing.allocator, args, &diagnostics) catch |err| switch (err) {1482 var options = parse(std.testing.allocator, std.testing.io, args, &diagnostics) catch |err| switch (err) {
1479 error.ParseError => {1483 error.ParseError => {
1480 try diagnostics.renderToWriter(args, &output.writer, .no_color);1484 try diagnostics.renderToWriter(&output.writer, args);
1481 try std.testing.expectEqualStrings(expected_output, output.written());1485 try std.testing.expectEqualStrings(expected_output, output.written());
1482 return null;1486 return null;
1483 },1487 },
...@@ -1485,7 +1489,7 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti...@@ -1485,7 +1489,7 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti
1485 };1489 };
1486 errdefer options.deinit();1490 errdefer options.deinit();
14871491
1488 try diagnostics.renderToWriter(args, &output.writer, .no_color);1492 try diagnostics.renderToWriter(&output.writer, args);
1489 try std.testing.expectEqualStrings(expected_output, output.written());1493 try std.testing.expectEqualStrings(expected_output, output.written());
1490 return options;1494 return options;
1491}1495}
lib/compiler/resinator/compile.zig+5-4
...@@ -59,6 +59,7 @@ pub const CompileOptions = struct {...@@ -59,6 +59,7 @@ pub const CompileOptions = struct {
59 max_string_literal_codepoints: u15 = lex.default_max_string_literal_codepoints,59 max_string_literal_codepoints: u15 = lex.default_max_string_literal_codepoints,
60 silent_duplicate_control_ids: bool = false,60 silent_duplicate_control_ids: bool = false,
61 warn_instead_of_error_on_invalid_code_page: bool = false,61 warn_instead_of_error_on_invalid_code_page: bool = false,
62 include_env_value: ?[]const u8 = null,
62};63};
6364
64pub const Dependencies = struct {65pub const Dependencies = struct {
...@@ -80,7 +81,7 @@ pub const Dependencies = struct {...@@ -80,7 +81,7 @@ pub const Dependencies = struct {
80 }81 }
81};82};
8283
83pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions, environ_map: *const std.process.Environ.Map) !void {84pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void {
84 var lexer = lex.Lexer.init(source, .{85 var lexer = lex.Lexer.init(source, .{
85 .default_code_page = options.default_code_page,86 .default_code_page = options.default_code_page,
86 .source_mappings = options.source_mappings,87 .source_mappings = options.source_mappings,
...@@ -148,7 +149,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io...@@ -148,7 +149,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
148 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });149 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });
149 }150 }
150 if (!options.ignore_include_env_var) {151 if (!options.ignore_include_env_var) {
151 const INCLUDE = environ_map.get("INCLUDE") orelse "";152 const INCLUDE = options.include_env_value orelse "";
152153
153 // The only precedence here is llvm-rc which also uses the platform-specific154 // The only precedence here is llvm-rc which also uses the platform-specific
154 // delimiter. There's no precedence set by `rc.exe` since it's Windows-only.155 // delimiter. There's no precedence set by `rc.exe` since it's Windows-only.
...@@ -405,7 +406,7 @@ pub const Compiler = struct {...@@ -405,7 +406,7 @@ pub const Compiler = struct {
405 // `/test.bin` relative to include paths and instead only treats it as406 // `/test.bin` relative to include paths and instead only treats it as
406 // an absolute path.407 // an absolute path.
407 if (std.fs.path.isAbsolute(path)) {408 if (std.fs.path.isAbsolute(path)) {
408 const file = try utils.openFileNotDir(Io.Dir.cwd(), io, path, .{});409 const file = try Io.Dir.cwd().openFile(io, path, .{ .allow_directory = false });
409 errdefer file.close(io);410 errdefer file.close(io);
410411
411 if (self.dependencies) |dependencies| {412 if (self.dependencies) |dependencies| {
...@@ -417,7 +418,7 @@ pub const Compiler = struct {...@@ -417,7 +418,7 @@ pub const Compiler = struct {
417418
418 var first_error: ?(std.Io.File.OpenError || std.Io.File.StatError) = null;419 var first_error: ?(std.Io.File.OpenError || std.Io.File.StatError) = null;
419 for (self.search_dirs) |search_dir| {420 for (self.search_dirs) |search_dir| {
420 if (utils.openFileNotDir(search_dir.dir, io, path, .{})) |file| {421 if (search_dir.dir.openFile(io, path, .{ .allow_directory = false })) |file| {
421 errdefer file.close(io);422 errdefer file.close(io);
422423
423 if (self.dependencies) |dependencies| {424 if (self.dependencies) |dependencies| {
lib/compiler/resinator/errors.zig+3-6
...@@ -24,12 +24,10 @@ pub const Diagnostics = struct {...@@ -24,12 +24,10 @@ pub const Diagnostics = struct {
24 /// Expects to own all strings within the list.24 /// Expects to own all strings within the list.
25 strings: std.ArrayList([]const u8) = .empty,25 strings: std.ArrayList([]const u8) = .empty,
26 allocator: Allocator,26 allocator: Allocator,
27 io: Io,
2827
29 pub fn init(allocator: Allocator, io: Io) Diagnostics {28 pub fn init(allocator: Allocator) Diagnostics {
30 return .{29 return .{
31 .allocator = allocator,30 .allocator = allocator,
32 .io = io,
33 };31 };
34 }32 }
3533
...@@ -67,8 +65,7 @@ pub const Diagnostics = struct {...@@ -67,8 +65,7 @@ pub const Diagnostics = struct {
67 return @intCast(index);65 return @intCast(index);
68 }66 }
6967
70 pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) Io.Cancelable!void {68 pub fn renderToStderr(self: *Diagnostics, io: Io, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) Io.Cancelable!void {
71 const io = self.io;
72 const stderr = try io.lockStderr(&.{}, null);69 const stderr = try io.lockStderr(&.{}, null);
73 defer io.unlockStderr();70 defer io.unlockStderr();
74 for (self.errors.items) |err_details| {71 for (self.errors.items) |err_details| {
...@@ -1120,7 +1117,7 @@ const CorrespondingLines = struct {...@@ -1120,7 +1117,7 @@ const CorrespondingLines = struct {
11201117
1121 var corresponding_lines = CorrespondingLines{1118 var corresponding_lines = CorrespondingLines{
1122 .span = corresponding_span,1119 .span = corresponding_span,
1123 .file = try utils.openFileNotDir(cwd, io, corresponding_file, .{}),1120 .file = try cwd.openFile(io, corresponding_file, .{ .allow_directory = false }),
1124 .code_page = err_details.code_page,1121 .code_page = err_details.code_page,
1125 .file_reader = undefined,1122 .file_reader = undefined,
1126 };1123 };
lib/compiler/resinator/main.zig+12-11
...@@ -12,7 +12,6 @@ const Diagnostics = @import("errors.zig").Diagnostics;...@@ -12,7 +12,6 @@ const Diagnostics = @import("errors.zig").Diagnostics;
12const cli = @import("cli.zig");12const cli = @import("cli.zig");
13const preprocess = @import("preprocess.zig");13const preprocess = @import("preprocess.zig");
14const renderErrorMessage = @import("utils.zig").renderErrorMessage;14const renderErrorMessage = @import("utils.zig").renderErrorMessage;
15const openFileNotDir = @import("utils.zig").openFileNotDir;
16const cvtres = @import("cvtres.zig");15const cvtres = @import("cvtres.zig");
17const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage;16const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage;
18const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType;17const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType;
...@@ -141,7 +140,7 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -141,7 +140,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
141 } };140 } };
142 defer {141 defer {
143 diagnostics.deinit();142 diagnostics.deinit();
144 if (!zig_integration) std.debug.unlockStderr();143 if (!zig_integration) io.unlockStderr();
145 }144 }
146145
147 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd());146 var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, Io.Dir.cwd());
...@@ -152,7 +151,7 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -152,7 +151,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
152151
153 try argv.append(aro_arena, "arocc"); // dummy command name152 try argv.append(aro_arena, "arocc"); // dummy command name
154 const resolved_include_paths = try include_paths.get(&error_handler, &environ_map);153 const resolved_include_paths = try include_paths.get(&error_handler, &environ_map);
155 try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths, &environ_map);154 try preprocess.appendAroArgs(aro_arena, &argv, options, resolved_include_paths, environ_map.get("INCLUDE"));
156 try argv.append(aro_arena, switch (options.input_source) {155 try argv.append(aro_arena, switch (options.input_source) {
157 .stdio => "-",156 .stdio => "-",
158 .filename => |filename| filename,157 .filename => |filename| filename,
...@@ -194,13 +193,13 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -194,13 +193,13 @@ pub fn main(init: std.process.Init.Minimal) !void {
194 .stdio => |file| {193 .stdio => |file| {
195 var file_reader = file.reader(io, &.{});194 var file_reader = file.reader(io, &.{});
196 break :full_input file_reader.interface.allocRemaining(gpa, .unlimited) catch |err| {195 break :full_input file_reader.interface.allocRemaining(gpa, .unlimited) catch |err| {
197 try error_handler.emitMessage(gpa, io, .err, "unable to read input from stdin: {s}", .{@errorName(err)});196 try error_handler.emitMessage(gpa, io, .err, "unable to read input from stdin: {t}", .{file_reader.err orelse err});
198 std.process.exit(1);197 std.process.exit(1);
199 };198 };
200 },199 },
201 .filename => |input_filename| {200 .filename => |input_filename| {
202 break :full_input Io.Dir.cwd().readFileAlloc(io, input_filename, gpa, .unlimited) catch |err| {201 break :full_input Io.Dir.cwd().readFileAlloc(io, input_filename, gpa, .unlimited) catch |err| {
203 try error_handler.emitMessage(gpa, io, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) });202 try error_handler.emitMessage(gpa, io, .err, "unable to read input file path '{s}': {t}", .{ input_filename, err });
204 std.process.exit(1);203 std.process.exit(1);
205 };204 };
206 },205 },
...@@ -271,7 +270,7 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -271,7 +270,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
271270
272 const final_input = try removeComments(mapping_results.result, mapping_results.result, &mapping_results.mappings);271 const final_input = try removeComments(mapping_results.result, mapping_results.result, &mapping_results.mappings);
273272
274 var diagnostics = Diagnostics.init(gpa, io);273 var diagnostics = Diagnostics.init(gpa);
275 defer diagnostics.deinit();274 defer diagnostics.deinit();
276275
277 var output_buffer: [4096]u8 = undefined;276 var output_buffer: [4096]u8 = undefined;
...@@ -295,9 +294,10 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -295,9 +294,10 @@ pub fn main(init: std.process.Init.Minimal) !void {
295 .max_string_literal_codepoints = options.max_string_literal_codepoints,294 .max_string_literal_codepoints = options.max_string_literal_codepoints,
296 .silent_duplicate_control_ids = options.silent_duplicate_control_ids,295 .silent_duplicate_control_ids = options.silent_duplicate_control_ids,
297 .warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page,296 .warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page,
298 }, &environ_map) catch |err| switch (err) {297 .include_env_value = environ_map.get("INCLUDE"),
298 }) catch |err| switch (err) {
299 error.ParseError, error.CompileError => {299 error.ParseError, error.CompileError => {
300 try error_handler.emitDiagnostics(gpa, Io.Dir.cwd(), final_input, &diagnostics, mapping_results.mappings);300 try error_handler.emitDiagnostics(gpa, io, Io.Dir.cwd(), final_input, &diagnostics, mapping_results.mappings);
301 // Delete the output file on error301 // Delete the output file on error
302 res_stream.cleanupAfterError(io);302 res_stream.cleanupAfterError(io);
303 std.process.exit(1);303 std.process.exit(1);
...@@ -309,7 +309,7 @@ pub fn main(init: std.process.Init.Minimal) !void {...@@ -309,7 +309,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
309309
310 // print any warnings/notes310 // print any warnings/notes
311 if (!zig_integration) {311 if (!zig_integration) {
312 try diagnostics.renderToStderr(Io.Dir.cwd(), final_input, mapping_results.mappings);312 try diagnostics.renderToStderr(io, Io.Dir.cwd(), final_input, mapping_results.mappings);
313 }313 }
314314
315 // write the depfile315 // write the depfile
...@@ -460,7 +460,7 @@ const IoStream = struct {...@@ -460,7 +460,7 @@ const IoStream = struct {
460 switch (source) {460 switch (source) {
461 .filename => |filename| return .{461 .filename => |filename| return .{
462 .file = switch (io_direction) {462 .file = switch (io_direction) {
463 .input => try openFileNotDir(Io.Dir.cwd(), io, filename, .{}),463 .input => try Io.Dir.cwd().openFile(io, filename, .{ .allow_directory = false }),
464 .output => try Io.Dir.cwd().createFile(io, filename, .{}),464 .output => try Io.Dir.cwd().createFile(io, filename, .{}),
465 },465 },
466 },466 },
...@@ -733,6 +733,7 @@ const ErrorHandler = union(enum) {...@@ -733,6 +733,7 @@ const ErrorHandler = union(enum) {
733 pub fn emitDiagnostics(733 pub fn emitDiagnostics(
734 self: *ErrorHandler,734 self: *ErrorHandler,
735 allocator: Allocator,735 allocator: Allocator,
736 io: Io,
736 cwd: Io.Dir,737 cwd: Io.Dir,
737 source: []const u8,738 source: []const u8,
738 diagnostics: *Diagnostics,739 diagnostics: *Diagnostics,
...@@ -745,7 +746,7 @@ const ErrorHandler = union(enum) {...@@ -745,7 +746,7 @@ const ErrorHandler = union(enum) {
745746
746 try server.serveErrorBundle(error_bundle);747 try server.serveErrorBundle(error_bundle);
747 },748 },
748 .stderr => return diagnostics.renderToStderr(cwd, source, mappings),749 .stderr => return diagnostics.renderToStderr(io, cwd, source, mappings),
749 }750 }
750 }751 }
751752
lib/compiler/resinator/preprocess.zig+3-3
...@@ -84,9 +84,9 @@ fn hasAnyErrors(comp: *aro.Compilation) bool {...@@ -84,9 +84,9 @@ fn hasAnyErrors(comp: *aro.Compilation) bool {
84 return comp.diagnostics.errors != 0;84 return comp.diagnostics.errors != 0;
85}85}
8686
87/// `arena` is used for temporary -D argument strings and the INCLUDE environment variable.87/// `arena` is used for temporary -D argument strings.
88/// The arena should be kept alive at least as long as `argv`.88/// The arena should be kept alive at least as long as `argv`.
89pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options: cli.Options, system_include_paths: []const []const u8, environ_map: *const std.process.Environ.Map) !void {89pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options: cli.Options, system_include_paths: []const []const u8, include_env_value: ?[]const u8) !void {
90 try argv.appendSlice(arena, &.{90 try argv.appendSlice(arena, &.{
91 "-E",91 "-E",
92 "--comments",92 "--comments",
...@@ -109,7 +109,7 @@ pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options...@@ -109,7 +109,7 @@ pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options
109 }109 }
110110
111 if (!options.ignore_include_env_var) {111 if (!options.ignore_include_env_var) {
112 const INCLUDE = environ_map.get("INCLUDE") orelse "";112 const INCLUDE = include_env_value orelse "";
113113
114 // The only precedence here is llvm-rc which also uses the platform-specific114 // The only precedence here is llvm-rc which also uses the platform-specific
115 // delimiter. There's no precedence set by `rc.exe` since it's Windows-only.115 // delimiter. There's no precedence set by `rc.exe` since it's Windows-only.
lib/compiler/resinator/utils.zig+6-23
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1const builtin = @import("builtin");
2
3const std = @import("std");1const std = @import("std");
4const Io = std.Io;2const Io = std.Io;
53
...@@ -25,27 +23,6 @@ pub const UncheckedSliceWriter = struct {...@@ -25,27 +23,6 @@ pub const UncheckedSliceWriter = struct {
25 }23 }
26};24};
2725
28/// Cross-platform 'Io.Dir.openFile' wrapper that will always return IsDir if
29/// a directory is attempted to be opened.
30/// TODO: Remove once https://github.com/ziglang/zig/issues/5732 is addressed.
31pub fn openFileNotDir(
32 cwd: Io.Dir,
33 io: Io,
34 path: []const u8,
35 flags: Io.File.OpenFlags,
36) (Io.File.OpenError || Io.File.StatError)!Io.File {
37 const file = try cwd.openFile(io, path, flags);
38 errdefer file.close(io);
39 // https://github.com/ziglang/zig/issues/5732
40 if (builtin.os.tag != .windows) {
41 const stat = try file.stat(io);
42
43 if (stat.kind == .directory)
44 return error.IsDir;
45 }
46 return file;
47}
48
49/// Emulates the Windows implementation of `iswdigit`, but only returns true26/// Emulates the Windows implementation of `iswdigit`, but only returns true
50/// for the non-ASCII digits that `iswdigit` on Windows would return true for.27/// for the non-ASCII digits that `iswdigit` on Windows would return true for.
51pub fn isNonAsciiDigit(c: u21) bool {28pub fn isNonAsciiDigit(c: u21) bool {
...@@ -90,6 +67,12 @@ pub fn isNonAsciiDigit(c: u21) bool {...@@ -90,6 +67,12 @@ pub fn isNonAsciiDigit(c: u21) bool {
9067
91pub const ErrorMessageType = enum { err, warning, note };68pub const ErrorMessageType = enum { err, warning, note };
9269
70pub fn renderErrorMessageToStderr(io: std.Io, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void {
71 var stderr = try io.lockStderr(&.{}, null);
72 defer io.unlockStderr();
73 try renderErrorMessage(stderr.terminal(), msg_type, format, args);
74}
75
93/// Used for generic colored errors/warnings/notes, more context-specific error messages76/// Used for generic colored errors/warnings/notes, more context-specific error messages
94/// are handled elsewhere.77/// are handled elsewhere.
95pub fn renderErrorMessage(t: Io.Terminal, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void {78pub fn renderErrorMessage(t: Io.Terminal, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void {