Skip to content

Commit a361f37

Browse files
authored
Merge pull request #17608 from squeek502/resinator-fixes
resinator: Fix `INCLUDE` var handling and sync with upstream
2 parents db18b56 + 8ec04b5 commit a361f37

File tree

9 files changed

+129
-80
lines changed

9 files changed

+129
-80
lines changed

lib/std/Build/Step/Compile.zig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ pub const RcSourceFile = struct {
244244
file: LazyPath,
245245
/// Any option that rc.exe accepts will work here, with the exception of:
246246
/// - `/fo`: The output filename is set by the build system
247+
/// - `/p`: Only running the preprocessor is not supported in this context
248+
/// - `/:no-preprocess` (non-standard option): Not supported in this context
247249
/// - Any MUI-related option
248250
/// https://learn.microsoft.com/en-us/windows/win32/menurc/using-rc-the-rc-command-line-
249251
///

src/Compilation.zig

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4766,11 +4766,21 @@ fn updateWin32Resource(comp: *Compilation, win32_resource: *Win32Resource, win32
47664766
};
47674767
defer options.deinit();
47684768

4769+
// We never want to read the INCLUDE environment variable, so
4770+
// unconditionally set `ignore_include_env_var` to true
4771+
options.ignore_include_env_var = true;
4772+
4773+
if (options.preprocess != .yes) {
4774+
return comp.failWin32Resource(win32_resource, "the '{s}' option is not supported in this context", .{switch (options.preprocess) {
4775+
.no => "/:no-preprocess",
4776+
.only => "/p",
4777+
.yes => unreachable,
4778+
}});
4779+
}
4780+
47694781
var argv = std.ArrayList([]const u8).init(comp.gpa);
47704782
defer argv.deinit();
47714783

4772-
// TODO: support options.preprocess == .no and .only
4773-
// alternatively, error if those options are used
47744784
try argv.appendSlice(&[_][]const u8{ self_exe_path, "clang" });
47754785

47764786
try resinator.preprocess.appendClangArgs(arena, &argv, options, .{

src/introspect.zig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,6 @@ pub const EnvVar = enum {
157157
NO_COLOR,
158158
XDG_CACHE_HOME,
159159
HOME,
160-
/// https://github.com/ziglang/zig/issues/17585
161-
INCLUDE,
162160

163161
pub fn isSet(comptime ev: EnvVar) bool {
164162
return std.process.hasEnvVarConstant(@tagName(ev));

src/resinator/compile.zig

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ const windows1252 = @import("windows1252.zig");
2828
const lang = @import("lang.zig");
2929
const code_pages = @import("code_pages.zig");
3030
const errors = @import("errors.zig");
31-
const introspect = @import("../introspect.zig");
3231

3332
pub const CompileOptions = struct {
3433
cwd: std.fs.Dir,
@@ -89,10 +88,23 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option
8988
}
9089
}
9190
// Re-open the passed in cwd since we want to be able to close it (std.fs.cwd() shouldn't be closed)
92-
// `catch unreachable` since `options.cwd` is expected to be a valid dir handle, so opening
93-
// a new handle to it should be fine as well.
94-
// TODO: Maybe catch and return an error instead
95-
const cwd_dir = options.cwd.openDir(".", .{}) catch @panic("unable to open dir");
91+
const cwd_dir = options.cwd.openDir(".", .{}) catch |err| {
92+
try options.diagnostics.append(.{
93+
.err = .failed_to_open_cwd,
94+
.token = .{
95+
.id = .invalid,
96+
.start = 0,
97+
.end = 0,
98+
.line_number = 1,
99+
},
100+
.print_source_line = false,
101+
.extra = .{ .file_open_error = .{
102+
.err = ErrorDetails.FileOpenError.enumFromError(err),
103+
.filename_string_index = undefined,
104+
} },
105+
});
106+
return error.CompileError;
107+
};
96108
try search_dirs.append(.{ .dir = cwd_dir, .path = null });
97109
for (options.extra_include_paths) |extra_include_path| {
98110
var dir = openSearchPathDir(options.cwd, extra_include_path) catch {
@@ -111,11 +123,16 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: anytype, option
111123
try search_dirs.append(.{ .dir = dir, .path = try allocator.dupe(u8, system_include_path) });
112124
}
113125
if (!options.ignore_include_env_var) {
114-
const INCLUDE = (introspect.EnvVar.INCLUDE.get(allocator) catch @panic("OOM")) orelse "";
126+
const INCLUDE = std.process.getEnvVarOwned(allocator, "INCLUDE") catch "";
115127
defer allocator.free(INCLUDE);
116128

117-
// TODO: Should this be platform-specific? How does windres/llvm-rc handle this (if at all)?
118-
var it = std.mem.tokenize(u8, INCLUDE, ";");
129+
// The only precedence here is llvm-rc which also uses the platform-specific
130+
// delimiter. There's no precedence set by `rc.exe` since it's Windows-only.
131+
const delimiter = switch (builtin.os.tag) {
132+
.windows => ';',
133+
else => ':',
134+
};
135+
var it = std.mem.tokenizeScalar(u8, INCLUDE, delimiter);
119136
while (it.next()) |search_path| {
120137
var dir = openSearchPathDir(options.cwd, search_path) catch continue;
121138
errdefer dir.close();

src/resinator/errors.zig

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ pub const ErrorDetails = struct {
395395
// General (used in various places)
396396
/// `number` is populated and contains the value that the ordinal would have in the Win32 RC compiler implementation
397397
win32_non_ascii_ordinal,
398+
399+
// Initialization
400+
/// `file_open_error` is populated, but `filename_string_index` is not
401+
failed_to_open_cwd,
398402
};
399403

400404
pub fn render(self: ErrorDetails, writer: anytype, source: []const u8, strings: []const []const u8) !void {
@@ -766,6 +770,9 @@ pub const ErrorDetails = struct {
766770
.note => return writer.print("the Win32 RC compiler would accept this as an ordinal but its value would be {}", .{self.extra.number}),
767771
.hint => return,
768772
},
773+
.failed_to_open_cwd => {
774+
try writer.print("failed to open CWD for compilation: {s}", .{@tagName(self.extra.file_open_error.err)});
775+
},
769776
}
770777
}
771778

@@ -804,7 +811,8 @@ pub const ErrorDetails = struct {
804811
.point_offset = self.token.start - source_line_start,
805812
.after_len = after: {
806813
const end = @min(source_line_end, if (self.token_span_end) |span_end| span_end.end else self.token.end);
807-
if (end == self.token.start) break :after 0;
814+
// end may be less than start when pointing to EOF
815+
if (end <= self.token.start) break :after 0;
808816
break :after end - self.token.start - 1;
809817
},
810818
},
@@ -816,13 +824,18 @@ pub fn renderErrorMessage(allocator: std.mem.Allocator, writer: anytype, tty_con
816824
if (err_details.type == .hint) return;
817825

818826
const source_line_start = err_details.token.getLineStart(source);
819-
const column = err_details.token.calculateColumn(source, 1, source_line_start);
820-
821-
// var counting_writer_container = std.io.countingWriter(writer);
822-
// const counting_writer = counting_writer_container.writer();
823-
824-
const corresponding_span: ?SourceMappings.SourceSpan = if (source_mappings) |mappings| mappings.get(err_details.token.line_number) else null;
825-
const corresponding_file: ?[]const u8 = if (source_mappings) |mappings| mappings.files.get(corresponding_span.?.filename_offset) else null;
827+
// Treat tab stops as 1 column wide for error display purposes,
828+
// and add one to get a 1-based column
829+
const column = err_details.token.calculateColumn(source, 1, source_line_start) + 1;
830+
831+
const corresponding_span: ?SourceMappings.SourceSpan = if (source_mappings != null and source_mappings.?.has(err_details.token.line_number))
832+
source_mappings.?.get(err_details.token.line_number)
833+
else
834+
null;
835+
const corresponding_file: ?[]const u8 = if (source_mappings != null and corresponding_span != null)
836+
source_mappings.?.files.get(corresponding_span.?.filename_offset)
837+
else
838+
null;
826839

827840
const err_line = if (corresponding_span) |span| span.start_line else err_details.token.line_number;
828841

@@ -897,7 +910,7 @@ pub fn renderErrorMessage(allocator: std.mem.Allocator, writer: anytype, tty_con
897910
try writer.writeByte('\n');
898911
try tty_config.setColor(writer, .reset);
899912

900-
if (source_mappings) |_| {
913+
if (corresponding_span != null and corresponding_file != null) {
901914
var corresponding_lines = try CorrespondingLines.init(allocator, cwd, err_details, source_line_for_display_buf.items, corresponding_span.?, corresponding_file.?);
902915
defer corresponding_lines.deinit(allocator);
903916

0 commit comments

Comments
 (0)