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 {
128128 pub fn renderToStderr(self: *Diagnostics, io: Io, args: []const []const u8) Io.Cancelable!void {
129129 const stderr = try io.lockStderr(&.{}, null);
130130 defer io.unlockStderr();
131 self.renderToWriter(args, stderr.terminal()) catch return;
131 self.renderToTerminal(stderr.terminal(), args) catch return;
132132 }
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 {
135135 for (self.errors.items) |err_details| {
136 try renderErrorMessage(t, err_details, args);
136 try renderErrorMessage(terminal, err_details, args);
137137 }
138138 }
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
140144 pub fn hasError(self: *const Diagnostics) bool {
141145 for (self.errors.items) |err| {
142146 if (err.type == .err) return true;
......@@ -1475,9 +1479,9 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti
14751479 var output: std.Io.Writer.Allocating = .init(std.testing.allocator);
14761480 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) {
14791483 error.ParseError => {
1480 try diagnostics.renderToWriter(args, &output.writer, .no_color);
1484 try diagnostics.renderToWriter(&output.writer, args);
14811485 try std.testing.expectEqualStrings(expected_output, output.written());
14821486 return null;
14831487 },
......@@ -1485,7 +1489,7 @@ fn testParseOutput(args: []const []const u8, expected_output: []const u8) !?Opti
14851489 };
14861490 errdefer options.deinit();
14871491
1488 try diagnostics.renderToWriter(args, &output.writer, .no_color);
1492 try diagnostics.renderToWriter(&output.writer, args);
14891493 try std.testing.expectEqualStrings(expected_output, output.written());
14901494 return options;
14911495}
lib/compiler/resinator/compile.zig+5-4
......@@ -59,6 +59,7 @@ pub const CompileOptions = struct {
5959 max_string_literal_codepoints: u15 = lex.default_max_string_literal_codepoints,
6060 silent_duplicate_control_ids: bool = false,
6161 warn_instead_of_error_on_invalid_code_page: bool = false,
62 include_env_value: ?[]const u8 = null,
6263};
6364
6465pub const Dependencies = struct {
......@@ -80,7 +81,7 @@ pub const Dependencies = struct {
8081 }
8182};
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 {
8485 var lexer = lex.Lexer.init(source, .{
8586 .default_code_page = options.default_code_page,
8687 .source_mappings = options.source_mappings,
......@@ -148,7 +149,7 @@ pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io
148149 try search_dirs.append(allocator, .{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });
149150 }
150151 if (!options.ignore_include_env_var) {
151 const INCLUDE = environ_map.get("INCLUDE") orelse "";
152 const INCLUDE = options.include_env_value orelse "";
152153
153154 // The only precedence here is llvm-rc which also uses the platform-specific
154155 // delimiter. There's no precedence set by `rc.exe` since it's Windows-only.
......@@ -405,7 +406,7 @@ pub const Compiler = struct {
405406 // `/test.bin` relative to include paths and instead only treats it as
406407 // an absolute path.
407408 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 });
409410 errdefer file.close(io);
410411
411412 if (self.dependencies) |dependencies| {
......@@ -417,7 +418,7 @@ pub const Compiler = struct {
417418
418419 var first_error: ?(std.Io.File.OpenError || std.Io.File.StatError) = null;
419420 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| {
421422 errdefer file.close(io);
422423
423424 if (self.dependencies) |dependencies| {
lib/compiler/resinator/errors.zig+3-6
......@@ -24,12 +24,10 @@ pub const Diagnostics = struct {
2424 /// Expects to own all strings within the list.
2525 strings: std.ArrayList([]const u8) = .empty,
2626 allocator: Allocator,
27 io: Io,
2827
29 pub fn init(allocator: Allocator, io: Io) Diagnostics {
28 pub fn init(allocator: Allocator) Diagnostics {
3029 return .{
3130 .allocator = allocator,
32 .io = io,
3331 };
3432 }
3533
......@@ -67,8 +65,7 @@ pub const Diagnostics = struct {
6765 return @intCast(index);
6866 }
6967
70 pub fn renderToStderr(self: *Diagnostics, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) Io.Cancelable!void {
71 const io = self.io;
68 pub fn renderToStderr(self: *Diagnostics, io: Io, cwd: Io.Dir, source: []const u8, source_mappings: ?SourceMappings) Io.Cancelable!void {
7269 const stderr = try io.lockStderr(&.{}, null);
7370 defer io.unlockStderr();
7471 for (self.errors.items) |err_details| {
......@@ -1120,7 +1117,7 @@ const CorrespondingLines = struct {
11201117
11211118 var corresponding_lines = CorrespondingLines{
11221119 .span = corresponding_span,
1123 .file = try utils.openFileNotDir(cwd, io, corresponding_file, .{}),
1120 .file = try cwd.openFile(io, corresponding_file, .{ .allow_directory = false }),
11241121 .code_page = err_details.code_page,
11251122 .file_reader = undefined,
11261123 };
lib/compiler/resinator/main.zig+12-11
......@@ -12,7 +12,6 @@ const Diagnostics = @import("errors.zig").Diagnostics;
1212const cli = @import("cli.zig");
1313const preprocess = @import("preprocess.zig");
1414const renderErrorMessage = @import("utils.zig").renderErrorMessage;
15const openFileNotDir = @import("utils.zig").openFileNotDir;
1615const cvtres = @import("cvtres.zig");
1716const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage;
1817const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType;
......@@ -141,7 +140,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
141140 } };
142141 defer {
143142 diagnostics.deinit();
144 if (!zig_integration) std.debug.unlockStderr();
143 if (!zig_integration) io.unlockStderr();
145144 }
146145
147146 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 {
152151
153152 try argv.append(aro_arena, "arocc"); // dummy command name
154153 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"));
156155 try argv.append(aro_arena, switch (options.input_source) {
157156 .stdio => "-",
158157 .filename => |filename| filename,
......@@ -194,13 +193,13 @@ pub fn main(init: std.process.Init.Minimal) !void {
194193 .stdio => |file| {
195194 var file_reader = file.reader(io, &.{});
196195 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});
198197 std.process.exit(1);
199198 };
200199 },
201200 .filename => |input_filename| {
202201 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 });
204203 std.process.exit(1);
205204 };
206205 },
......@@ -271,7 +270,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
271270
272271 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);
275274 defer diagnostics.deinit();
276275
277276 var output_buffer: [4096]u8 = undefined;
......@@ -295,9 +294,10 @@ pub fn main(init: std.process.Init.Minimal) !void {
295294 .max_string_literal_codepoints = options.max_string_literal_codepoints,
296295 .silent_duplicate_control_ids = options.silent_duplicate_control_ids,
297296 .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) {
299299 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);
301301 // Delete the output file on error
302302 res_stream.cleanupAfterError(io);
303303 std.process.exit(1);
......@@ -309,7 +309,7 @@ pub fn main(init: std.process.Init.Minimal) !void {
309309
310310 // print any warnings/notes
311311 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);
313313 }
314314
315315 // write the depfile
......@@ -460,7 +460,7 @@ const IoStream = struct {
460460 switch (source) {
461461 .filename => |filename| return .{
462462 .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 }),
464464 .output => try Io.Dir.cwd().createFile(io, filename, .{}),
465465 },
466466 },
......@@ -733,6 +733,7 @@ const ErrorHandler = union(enum) {
733733 pub fn emitDiagnostics(
734734 self: *ErrorHandler,
735735 allocator: Allocator,
736 io: Io,
736737 cwd: Io.Dir,
737738 source: []const u8,
738739 diagnostics: *Diagnostics,
......@@ -745,7 +746,7 @@ const ErrorHandler = union(enum) {
745746
746747 try server.serveErrorBundle(error_bundle);
747748 },
748 .stderr => return diagnostics.renderToStderr(cwd, source, mappings),
749 .stderr => return diagnostics.renderToStderr(io, cwd, source, mappings),
749750 }
750751 }
751752
lib/compiler/resinator/preprocess.zig+3-3
......@@ -84,9 +84,9 @@ fn hasAnyErrors(comp: *aro.Compilation) bool {
8484 return comp.diagnostics.errors != 0;
8585}
8686
87/// `arena` is used for temporary -D argument strings and the INCLUDE environment variable.
87/// `arena` is used for temporary -D argument strings.
8888/// 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 {
9090 try argv.appendSlice(arena, &.{
9191 "-E",
9292 "--comments",
......@@ -109,7 +109,7 @@ pub fn appendAroArgs(arena: Allocator, argv: *std.ArrayList([]const u8), options
109109 }
110110
111111 if (!options.ignore_include_env_var) {
112 const INCLUDE = environ_map.get("INCLUDE") orelse "";
112 const INCLUDE = include_env_value orelse "";
113113
114114 // The only precedence here is llvm-rc which also uses the platform-specific
115115 // 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 @@
1const builtin = @import("builtin");
2
31const std = @import("std");
42const Io = std.Io;
53
......@@ -25,27 +23,6 @@ pub const UncheckedSliceWriter = struct {
2523 }
2624};
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
4926/// Emulates the Windows implementation of `iswdigit`, but only returns true
5027/// for the non-ASCII digits that `iswdigit` on Windows would return true for.
5128pub fn isNonAsciiDigit(c: u21) bool {
......@@ -90,6 +67,12 @@ pub fn isNonAsciiDigit(c: u21) bool {
9067
9168pub 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
9376/// Used for generic colored errors/warnings/notes, more context-specific error messages
9477/// are handled elsewhere.
9578pub fn renderErrorMessage(t: Io.Terminal, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void {