Commit 4174ac18e9
Changed files (5)
lib
compiler
lib/compiler/resinator/compile.zig
@@ -1,6 +1,12 @@
-const std = @import("std");
const builtin = @import("builtin");
+const native_endian = builtin.cpu.arch.endian();
+
+const std = @import("std");
+const Io = std.Io;
const Allocator = std.mem.Allocator;
+const WORD = std.os.windows.WORD;
+const DWORD = std.os.windows.DWORD;
+
const Node = @import("ast.zig").Node;
const lex = @import("lex.zig");
const Parser = @import("parse.zig").Parser;
@@ -17,8 +23,6 @@ const res = @import("res.zig");
const ico = @import("ico.zig");
const ani = @import("ani.zig");
const bmp = @import("bmp.zig");
-const WORD = std.os.windows.WORD;
-const DWORD = std.os.windows.DWORD;
const utils = @import("utils.zig");
const NameOrOrdinal = res.NameOrOrdinal;
const SupportedCodePage = @import("code_pages.zig").SupportedCodePage;
@@ -28,7 +32,6 @@ const windows1252 = @import("windows1252.zig");
const lang = @import("lang.zig");
const code_pages = @import("code_pages.zig");
const errors = @import("errors.zig");
-const native_endian = builtin.cpu.arch.endian();
pub const CompileOptions = struct {
cwd: std.fs.Dir,
@@ -77,7 +80,7 @@ pub const Dependencies = struct {
}
};
-pub fn compile(allocator: Allocator, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void {
+pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions) !void {
var lexer = lex.Lexer.init(source, .{
.default_code_page = options.default_code_page,
.source_mappings = options.source_mappings,
@@ -166,10 +169,11 @@ pub fn compile(allocator: Allocator, source: []const u8, writer: *std.Io.Writer,
defer arena_allocator.deinit();
const arena = arena_allocator.allocator();
- var compiler = Compiler{
+ var compiler: Compiler = .{
.source = source,
.arena = arena,
.allocator = allocator,
+ .io = io,
.cwd = options.cwd,
.diagnostics = options.diagnostics,
.dependencies = options.dependencies,
@@ -191,6 +195,7 @@ pub const Compiler = struct {
source: []const u8,
arena: Allocator,
allocator: Allocator,
+ io: Io,
cwd: std.fs.Dir,
state: State = .{},
diagnostics: *Diagnostics,
@@ -409,7 +414,7 @@ pub const Compiler = struct {
}
}
- var first_error: ?std.fs.File.OpenError = null;
+ var first_error: ?(std.fs.File.OpenError || std.fs.File.StatError) = null;
for (self.search_dirs) |search_dir| {
if (utils.openFileNotDir(search_dir.dir, path, .{})) |file| {
errdefer file.close();
@@ -496,6 +501,8 @@ pub const Compiler = struct {
}
pub fn writeResourceExternal(self: *Compiler, node: *Node.ResourceExternal, writer: *std.Io.Writer) !void {
+ const io = self.io;
+
// Init header with data size zero for now, will need to fill it in later
var header = try self.resourceHeader(node.id, node.type, .{});
defer header.deinit(self.allocator);
@@ -582,7 +589,7 @@ pub const Compiler = struct {
};
defer file_handle.close();
var file_buffer: [2048]u8 = undefined;
- var file_reader = file_handle.reader(&file_buffer);
+ var file_reader = file_handle.reader(io, &file_buffer);
if (maybe_predefined_type) |predefined_type| {
switch (predefined_type) {
lib/compiler/resinator/cvtres.zig
@@ -1,5 +1,7 @@
const std = @import("std");
+const Io = std.Io;
const Allocator = std.mem.Allocator;
+
const res = @import("res.zig");
const NameOrOrdinal = res.NameOrOrdinal;
const MemoryFlags = res.MemoryFlags;
@@ -169,8 +171,7 @@ pub fn parseNameOrOrdinal(allocator: Allocator, reader: *std.Io.Reader) !NameOrO
pub const CoffOptions = struct {
target: std.coff.IMAGE.FILE.MACHINE = .AMD64,
- /// If true, zeroes will be written to all timestamp fields
- reproducible: bool = true,
+ timestamp: i64 = 0,
/// If true, the MEM_WRITE flag will not be set in the .rsrc section header
read_only: bool = false,
/// If non-null, a symbol with this name and storage class EXTERNAL will be added to the symbol table.
@@ -188,7 +189,13 @@ pub const Diagnostics = union {
overflow_resource: usize,
};
-pub fn writeCoff(allocator: Allocator, writer: *std.Io.Writer, resources: []const Resource, options: CoffOptions, diagnostics: ?*Diagnostics) !void {
+pub fn writeCoff(
+ allocator: Allocator,
+ writer: *std.Io.Writer,
+ resources: []const Resource,
+ options: CoffOptions,
+ diagnostics: ?*Diagnostics,
+) !void {
var resource_tree = ResourceTree.init(allocator, options);
defer resource_tree.deinit();
@@ -215,7 +222,7 @@ pub fn writeCoff(allocator: Allocator, writer: *std.Io.Writer, resources: []cons
const pointer_to_rsrc02_data = pointer_to_relocations + relocations_len;
const pointer_to_symbol_table = pointer_to_rsrc02_data + lengths.rsrc02;
- const timestamp: i64 = if (options.reproducible) 0 else std.time.timestamp();
+ const timestamp: i64 = options.timestamp;
const size_of_optional_header = 0;
const machine_type: std.coff.IMAGE.FILE.MACHINE = options.target;
const flags = std.coff.Header.Flags{
lib/compiler/resinator/errors.zig
@@ -1,5 +1,11 @@
+const builtin = @import("builtin");
+const native_endian = builtin.cpu.arch.endian();
+
const std = @import("std");
+const Io = std.Io;
const assert = std.debug.assert;
+const Allocator = std.mem.Allocator;
+
const Token = @import("lex.zig").Token;
const SourceMappings = @import("source_mapping.zig").SourceMappings;
const utils = @import("utils.zig");
@@ -11,19 +17,19 @@ const parse = @import("parse.zig");
const lang = @import("lang.zig");
const code_pages = @import("code_pages.zig");
const SupportedCodePage = code_pages.SupportedCodePage;
-const builtin = @import("builtin");
-const native_endian = builtin.cpu.arch.endian();
pub const Diagnostics = struct {
errors: std.ArrayList(ErrorDetails) = .empty,
/// Append-only, cannot handle removing strings.
/// Expects to own all strings within the list.
strings: std.ArrayList([]const u8) = .empty,
- allocator: std.mem.Allocator,
+ allocator: Allocator,
+ io: Io,
- pub fn init(allocator: std.mem.Allocator) Diagnostics {
+ pub fn init(allocator: Allocator, io: Io) Diagnostics {
return .{
.allocator = allocator,
+ .io = io,
};
}
@@ -62,10 +68,11 @@ pub const Diagnostics = struct {
}
pub fn renderToStdErr(self: *Diagnostics, cwd: std.fs.Dir, source: []const u8, tty_config: std.Io.tty.Config, source_mappings: ?SourceMappings) void {
+ const io = self.io;
const stderr = std.debug.lockStderrWriter(&.{});
defer std.debug.unlockStderrWriter();
for (self.errors.items) |err_details| {
- renderErrorMessage(stderr, tty_config, cwd, err_details, source, self.strings.items, source_mappings) catch return;
+ renderErrorMessage(io, stderr, tty_config, cwd, err_details, source, self.strings.items, source_mappings) catch return;
}
}
@@ -167,9 +174,9 @@ pub const ErrorDetails = struct {
filename_string_index: FilenameStringIndex,
pub const FilenameStringIndex = std.meta.Int(.unsigned, 32 - @bitSizeOf(FileOpenErrorEnum));
- pub const FileOpenErrorEnum = std.meta.FieldEnum(std.fs.File.OpenError);
+ pub const FileOpenErrorEnum = std.meta.FieldEnum(std.fs.File.OpenError || std.fs.File.StatError);
- pub fn enumFromError(err: std.fs.File.OpenError) FileOpenErrorEnum {
+ pub fn enumFromError(err: (std.fs.File.OpenError || std.fs.File.StatError)) FileOpenErrorEnum {
return switch (err) {
inline else => |e| @field(ErrorDetails.FileOpenError.FileOpenErrorEnum, @errorName(e)),
};
@@ -894,7 +901,16 @@ fn cellCount(code_page: SupportedCodePage, source: []const u8, start_index: usiz
const truncated_str = "<...truncated...>";
-pub fn renderErrorMessage(writer: *std.Io.Writer, tty_config: std.Io.tty.Config, cwd: std.fs.Dir, err_details: ErrorDetails, source: []const u8, strings: []const []const u8, source_mappings: ?SourceMappings) !void {
+pub fn renderErrorMessage(
+ io: Io,
+ writer: *std.Io.Writer,
+ tty_config: std.Io.tty.Config,
+ cwd: std.fs.Dir,
+ err_details: ErrorDetails,
+ source: []const u8,
+ strings: []const []const u8,
+ source_mappings: ?SourceMappings,
+) !void {
if (err_details.type == .hint) return;
const source_line_start = err_details.token.getLineStartForErrorDisplay(source);
@@ -989,6 +1005,7 @@ pub fn renderErrorMessage(writer: *std.Io.Writer, tty_config: std.Io.tty.Config,
var initial_lines_err: ?anyerror = null;
var file_reader_buf: [max_source_line_bytes * 2]u8 = undefined;
var corresponding_lines: ?CorrespondingLines = CorrespondingLines.init(
+ io,
cwd,
err_details,
source_line_for_display.line,
@@ -1084,6 +1101,7 @@ const CorrespondingLines = struct {
code_page: SupportedCodePage,
pub fn init(
+ io: Io,
cwd: std.fs.Dir,
err_details: ErrorDetails,
line_for_comparison: []const u8,
@@ -1108,7 +1126,7 @@ const CorrespondingLines = struct {
.code_page = err_details.code_page,
.file_reader = undefined,
};
- corresponding_lines.file_reader = corresponding_lines.file.reader(file_reader_buf);
+ corresponding_lines.file_reader = corresponding_lines.file.reader(io, file_reader_buf);
errdefer corresponding_lines.deinit();
try corresponding_lines.writeLineFromStreamVerbatim(
lib/compiler/resinator/main.zig
@@ -1,5 +1,9 @@
-const std = @import("std");
const builtin = @import("builtin");
+
+const std = @import("std");
+const Io = std.Io;
+const Allocator = std.mem.Allocator;
+
const removeComments = @import("comments.zig").removeComments;
const parseAndRemoveLineCommands = @import("source_mapping.zig").parseAndRemoveLineCommands;
const compile = @import("compile.zig").compile;
@@ -16,19 +20,18 @@ const aro = @import("aro");
const compiler_util = @import("../util.zig");
pub fn main() !void {
- var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
- defer std.debug.assert(gpa.deinit() == .ok);
- const allocator = gpa.allocator();
+ var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
+ defer std.debug.assert(debug_allocator.deinit() == .ok);
+ const gpa = debug_allocator.allocator();
- var arena_state = std.heap.ArenaAllocator.init(allocator);
+ var arena_state = std.heap.ArenaAllocator.init(gpa);
defer arena_state.deinit();
const arena = arena_state.allocator();
const stderr = std.fs.File.stderr();
const stderr_config = std.Io.tty.detectConfig(stderr);
- const args = try std.process.argsAlloc(allocator);
- defer std.process.argsFree(allocator, args);
+ const args = try std.process.argsAlloc(arena);
if (args.len < 2) {
try renderErrorMessage(std.debug.lockStderrWriter(&.{}), stderr_config, .err, "expected zig lib dir as first argument", .{});
@@ -59,11 +62,11 @@ pub fn main() !void {
};
var options = options: {
- var cli_diagnostics = cli.Diagnostics.init(allocator);
+ var cli_diagnostics = cli.Diagnostics.init(gpa);
defer cli_diagnostics.deinit();
- var options = cli.parse(allocator, cli_args, &cli_diagnostics) catch |err| switch (err) {
+ var options = cli.parse(gpa, cli_args, &cli_diagnostics) catch |err| switch (err) {
error.ParseError => {
- try error_handler.emitCliDiagnostics(allocator, cli_args, &cli_diagnostics);
+ try error_handler.emitCliDiagnostics(gpa, cli_args, &cli_diagnostics);
std.process.exit(1);
},
else => |e| return e,
@@ -84,6 +87,10 @@ pub fn main() !void {
};
defer options.deinit();
+ var threaded: std.Io.Threaded = .init(gpa);
+ defer threaded.deinit();
+ const io = threaded.io();
+
if (options.print_help_and_exit) {
try cli.writeUsage(stdout, "zig rc");
try stdout.flush();
@@ -99,12 +106,13 @@ pub fn main() !void {
try stdout.flush();
}
- var dependencies = Dependencies.init(allocator);
+ var dependencies = Dependencies.init(gpa);
defer dependencies.deinit();
const maybe_dependencies: ?*Dependencies = if (options.depfile_path != null) &dependencies else null;
var include_paths = LazyIncludePaths{
.arena = arena,
+ .io = io,
.auto_includes_option = options.auto_includes,
.zig_lib_dir = zig_lib_dir,
.target_machine_type = options.coff_options.target,
@@ -112,12 +120,12 @@ pub fn main() !void {
const full_input = full_input: {
if (options.input_format == .rc and options.preprocess != .no) {
- var preprocessed_buf: std.Io.Writer.Allocating = .init(allocator);
+ var preprocessed_buf: std.Io.Writer.Allocating = .init(gpa);
errdefer preprocessed_buf.deinit();
// We're going to throw away everything except the final preprocessed output anyway,
// so we can use a scoped arena for everything else.
- var aro_arena_state = std.heap.ArenaAllocator.init(allocator);
+ var aro_arena_state = std.heap.ArenaAllocator.init(gpa);
defer aro_arena_state.deinit();
const aro_arena = aro_arena_state.allocator();
@@ -129,12 +137,12 @@ pub fn main() !void {
.color = stderr_config,
} } },
true => .{ .output = .{ .to_list = .{
- .arena = .init(allocator),
+ .arena = .init(gpa),
} } },
};
defer diagnostics.deinit();
- var comp = aro.Compilation.init(aro_arena, aro_arena, &diagnostics, std.fs.cwd());
+ var comp = aro.Compilation.init(aro_arena, aro_arena, io, &diagnostics, std.fs.cwd());
defer comp.deinit();
var argv: std.ArrayList([]const u8) = .empty;
@@ -159,20 +167,20 @@ pub fn main() !void {
preprocess.preprocess(&comp, &preprocessed_buf.writer, argv.items, maybe_dependencies) catch |err| switch (err) {
error.GeneratedSourceError => {
- try error_handler.emitAroDiagnostics(allocator, "failed during preprocessor setup (this is always a bug)", &comp);
+ try error_handler.emitAroDiagnostics(gpa, "failed during preprocessor setup (this is always a bug)", &comp);
std.process.exit(1);
},
// ArgError can occur if e.g. the .rc file is not found
error.ArgError, error.PreprocessError => {
- try error_handler.emitAroDiagnostics(allocator, "failed during preprocessing", &comp);
+ try error_handler.emitAroDiagnostics(gpa, "failed during preprocessing", &comp);
std.process.exit(1);
},
error.FileTooBig => {
- try error_handler.emitMessage(allocator, .err, "failed during preprocessing: maximum file size exceeded", .{});
+ try error_handler.emitMessage(gpa, .err, "failed during preprocessing: maximum file size exceeded", .{});
std.process.exit(1);
},
error.WriteFailed => {
- try error_handler.emitMessage(allocator, .err, "failed during preprocessing: error writing the preprocessed output", .{});
+ try error_handler.emitMessage(gpa, .err, "failed during preprocessing: error writing the preprocessed output", .{});
std.process.exit(1);
},
error.OutOfMemory => |e| return e,
@@ -182,22 +190,22 @@ pub fn main() !void {
} else {
switch (options.input_source) {
.stdio => |file| {
- var file_reader = file.reader(&.{});
- break :full_input file_reader.interface.allocRemaining(allocator, .unlimited) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to read input from stdin: {s}", .{@errorName(err)});
+ var file_reader = file.reader(io, &.{});
+ break :full_input file_reader.interface.allocRemaining(gpa, .unlimited) catch |err| {
+ try error_handler.emitMessage(gpa, .err, "unable to read input from stdin: {s}", .{@errorName(err)});
std.process.exit(1);
};
},
.filename => |input_filename| {
- break :full_input std.fs.cwd().readFileAlloc(input_filename, allocator, .unlimited) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) });
+ break :full_input std.fs.cwd().readFileAlloc(input_filename, gpa, .unlimited) catch |err| {
+ try error_handler.emitMessage(gpa, .err, "unable to read input file path '{s}': {s}", .{ input_filename, @errorName(err) });
std.process.exit(1);
};
},
}
}
};
- defer allocator.free(full_input);
+ defer gpa.free(full_input);
if (options.preprocess == .only) {
switch (options.output_source) {
@@ -221,55 +229,55 @@ pub fn main() !void {
}
else if (options.input_format == .res)
IoStream.fromIoSource(options.input_source, .input) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) });
+ try error_handler.emitMessage(gpa, .err, "unable to read res file path '{s}': {s}", .{ options.input_source.filename, @errorName(err) });
std.process.exit(1);
}
else
IoStream.fromIoSource(options.output_source, .output) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) });
+ try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) });
std.process.exit(1);
};
- defer res_stream.deinit(allocator);
+ defer res_stream.deinit(gpa);
const res_data = res_data: {
if (options.input_format != .res) {
// Note: We still want to run this when no-preprocess is set because:
// 1. We want to print accurate line numbers after removing multiline comments
// 2. We want to be able to handle an already-preprocessed input with #line commands in it
- var mapping_results = parseAndRemoveLineCommands(allocator, full_input, full_input, .{ .initial_filename = options.input_source.filename }) catch |err| switch (err) {
+ var mapping_results = parseAndRemoveLineCommands(gpa, full_input, full_input, .{ .initial_filename = options.input_source.filename }) catch |err| switch (err) {
error.InvalidLineCommand => {
// TODO: Maybe output the invalid line command
- try error_handler.emitMessage(allocator, .err, "invalid line command in the preprocessed source", .{});
+ try error_handler.emitMessage(gpa, .err, "invalid line command in the preprocessed source", .{});
if (options.preprocess == .no) {
- try error_handler.emitMessage(allocator, .note, "line commands must be of the format: #line <num> \"<path>\"", .{});
+ try error_handler.emitMessage(gpa, .note, "line commands must be of the format: #line <num> \"<path>\"", .{});
} else {
- try error_handler.emitMessage(allocator, .note, "this is likely to be a bug, please report it", .{});
+ try error_handler.emitMessage(gpa, .note, "this is likely to be a bug, please report it", .{});
}
std.process.exit(1);
},
error.LineNumberOverflow => {
// TODO: Better error message
- try error_handler.emitMessage(allocator, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)});
+ try error_handler.emitMessage(gpa, .err, "line number count exceeded maximum of {}", .{std.math.maxInt(usize)});
std.process.exit(1);
},
error.OutOfMemory => |e| return e,
};
- defer mapping_results.mappings.deinit(allocator);
+ defer mapping_results.mappings.deinit(gpa);
const default_code_page = options.default_code_page orelse .windows1252;
const has_disjoint_code_page = hasDisjointCodePage(mapping_results.result, &mapping_results.mappings, default_code_page);
const final_input = try removeComments(mapping_results.result, mapping_results.result, &mapping_results.mappings);
- var diagnostics = Diagnostics.init(allocator);
+ var diagnostics = Diagnostics.init(gpa, io);
defer diagnostics.deinit();
var output_buffer: [4096]u8 = undefined;
- var res_stream_writer = res_stream.source.writer(allocator, &output_buffer);
+ var res_stream_writer = res_stream.source.writer(gpa, &output_buffer);
defer res_stream_writer.deinit(&res_stream.source);
const output_buffered_stream = res_stream_writer.interface();
- compile(allocator, final_input, output_buffered_stream, .{
+ compile(gpa, io, final_input, output_buffered_stream, .{
.cwd = std.fs.cwd(),
.diagnostics = &diagnostics,
.source_mappings = &mapping_results.mappings,
@@ -287,7 +295,7 @@ pub fn main() !void {
.warn_instead_of_error_on_invalid_code_page = options.warn_instead_of_error_on_invalid_code_page,
}) catch |err| switch (err) {
error.ParseError, error.CompileError => {
- try error_handler.emitDiagnostics(allocator, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings);
+ try error_handler.emitDiagnostics(gpa, std.fs.cwd(), final_input, &diagnostics, mapping_results.mappings);
// Delete the output file on error
res_stream.cleanupAfterError();
std.process.exit(1);
@@ -305,7 +313,7 @@ pub fn main() !void {
// write the depfile
if (options.depfile_path) |depfile_path| {
var depfile = std.fs.cwd().createFile(depfile_path, .{}) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) });
+ try error_handler.emitMessage(gpa, .err, "unable to create depfile '{s}': {s}", .{ depfile_path, @errorName(err) });
std.process.exit(1);
};
defer depfile.close();
@@ -332,41 +340,41 @@ pub fn main() !void {
if (options.output_format != .coff) return;
- break :res_data res_stream.source.readAll(allocator) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) });
+ break :res_data res_stream.source.readAll(gpa, io) catch |err| {
+ try error_handler.emitMessage(gpa, .err, "unable to read res from '{s}': {s}", .{ res_stream.name, @errorName(err) });
std.process.exit(1);
};
};
// No need to keep the res_data around after parsing the resources from it
- defer res_data.deinit(allocator);
+ defer res_data.deinit(gpa);
std.debug.assert(options.output_format == .coff);
// TODO: Maybe use a buffered file reader instead of reading file into memory -> fbs
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| {
+ break :resources cvtres.parseRes(gpa, &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) });
+ try error_handler.emitMessage(gpa, .err, "unable to parse res from '{s}': {s}", .{ res_stream.name, @errorName(err) });
std.process.exit(1);
};
};
defer resources.deinit();
var coff_stream = IoStream.fromIoSource(options.output_source, .output) catch |err| {
- try error_handler.emitMessage(allocator, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) });
+ try error_handler.emitMessage(gpa, .err, "unable to create output file '{s}': {s}", .{ options.output_source.filename, @errorName(err) });
std.process.exit(1);
};
- defer coff_stream.deinit(allocator);
+ defer coff_stream.deinit(gpa);
var coff_output_buffer: [4096]u8 = undefined;
- var coff_output_buffered_stream = coff_stream.source.writer(allocator, &coff_output_buffer);
+ var coff_output_buffered_stream = coff_stream.source.writer(gpa, &coff_output_buffer);
var cvtres_diagnostics: cvtres.Diagnostics = .{ .none = {} };
- cvtres.writeCoff(allocator, coff_output_buffered_stream.interface(), resources.list.items, options.coff_options, &cvtres_diagnostics) catch |err| {
+ cvtres.writeCoff(gpa, coff_output_buffered_stream.interface(), resources.list.items, options.coff_options, &cvtres_diagnostics) catch |err| {
switch (err) {
error.DuplicateResource => {
const duplicate_resource = resources.list.items[cvtres_diagnostics.duplicate_resource];
- try error_handler.emitMessage(allocator, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{
+ try error_handler.emitMessage(gpa, .err, "duplicate resource [id: {f}, type: {f}, language: {f}]", .{
duplicate_resource.name_value,
fmtResourceType(duplicate_resource.type_value),
duplicate_resource.language,
@@ -374,8 +382,8 @@ pub fn main() !void {
},
error.ResourceDataTooLong => {
const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource];
- try error_handler.emitMessage(allocator, .err, "resource has a data length that is too large to be written into a coff section", .{});
- try error_handler.emitMessage(allocator, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{
+ try error_handler.emitMessage(gpa, .err, "resource has a data length that is too large to be written into a coff section", .{});
+ try error_handler.emitMessage(gpa, .note, "the resource with the invalid size is [id: {f}, type: {f}, language: {f}]", .{
overflow_resource.name_value,
fmtResourceType(overflow_resource.type_value),
overflow_resource.language,
@@ -383,15 +391,15 @@ pub fn main() !void {
},
error.TotalResourceDataTooLong => {
const overflow_resource = resources.list.items[cvtres_diagnostics.duplicate_resource];
- try error_handler.emitMessage(allocator, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{});
- try error_handler.emitMessage(allocator, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{
+ try error_handler.emitMessage(gpa, .err, "total resource data exceeds the maximum of the coff 'size of raw data' field", .{});
+ try error_handler.emitMessage(gpa, .note, "size overflow occurred when attempting to write this resource: [id: {f}, type: {f}, language: {f}]", .{
overflow_resource.name_value,
fmtResourceType(overflow_resource.type_value),
overflow_resource.language,
});
},
else => {
- try error_handler.emitMessage(allocator, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) });
+ try error_handler.emitMessage(gpa, .err, "unable to write coff output file '{s}': {s}", .{ coff_stream.name, @errorName(err) });
},
}
// Delete the output file on error
@@ -423,7 +431,7 @@ const IoStream = struct {
};
}
- pub fn deinit(self: *IoStream, allocator: std.mem.Allocator) void {
+ pub fn deinit(self: *IoStream, allocator: Allocator) void {
self.source.deinit(allocator);
}
@@ -458,7 +466,7 @@ const IoStream = struct {
}
}
- pub fn deinit(self: *Source, allocator: std.mem.Allocator) void {
+ pub fn deinit(self: *Source, allocator: Allocator) void {
switch (self.*) {
.file => |file| file.close(),
.stdio => {},
@@ -471,18 +479,18 @@ const IoStream = struct {
bytes: []const u8,
needs_free: bool,
- pub fn deinit(self: Data, allocator: std.mem.Allocator) void {
+ pub fn deinit(self: Data, allocator: Allocator) void {
if (self.needs_free) {
allocator.free(self.bytes);
}
}
};
- pub fn readAll(self: Source, allocator: std.mem.Allocator) !Data {
+ pub fn readAll(self: Source, allocator: Allocator, io: Io) !Data {
return switch (self) {
inline .file, .stdio => |file| .{
.bytes = b: {
- var file_reader = file.reader(&.{});
+ var file_reader = file.reader(io, &.{});
break :b try file_reader.interface.allocRemaining(allocator, .unlimited);
},
.needs_free = true,
@@ -496,7 +504,7 @@ const IoStream = struct {
file: std.fs.File.Writer,
allocating: std.Io.Writer.Allocating,
- pub const Error = std.mem.Allocator.Error || std.fs.File.WriteError;
+ pub const Error = Allocator.Error || std.fs.File.WriteError;
pub fn interface(this: *@This()) *std.Io.Writer {
return switch (this.*) {
@@ -514,7 +522,7 @@ const IoStream = struct {
}
};
- pub fn writer(source: *Source, allocator: std.mem.Allocator, buffer: []u8) Writer {
+ pub fn writer(source: *Source, allocator: Allocator, buffer: []u8) Writer {
return switch (source.*) {
.file, .stdio => |file| .{ .file = file.writer(buffer) },
.memory => |*list| .{ .allocating = .fromArrayList(allocator, list) },
@@ -525,17 +533,20 @@ const IoStream = struct {
};
const LazyIncludePaths = struct {
- arena: std.mem.Allocator,
+ arena: Allocator,
+ io: Io,
auto_includes_option: cli.Options.AutoIncludes,
zig_lib_dir: []const u8,
target_machine_type: std.coff.IMAGE.FILE.MACHINE,
resolved_include_paths: ?[]const []const u8 = null,
pub fn get(self: *LazyIncludePaths, error_handler: *ErrorHandler) ![]const []const u8 {
+ const io = self.io;
+
if (self.resolved_include_paths) |include_paths|
return include_paths;
- return getIncludePaths(self.arena, self.auto_includes_option, self.zig_lib_dir, self.target_machine_type) catch |err| switch (err) {
+ return getIncludePaths(self.arena, io, self.auto_includes_option, self.zig_lib_dir, self.target_machine_type) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
else => |e| {
switch (e) {
@@ -556,7 +567,13 @@ const LazyIncludePaths = struct {
}
};
-fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.AutoIncludes, zig_lib_dir: []const u8, target_machine_type: std.coff.IMAGE.FILE.MACHINE) ![]const []const u8 {
+fn getIncludePaths(
+ arena: Allocator,
+ io: Io,
+ auto_includes_option: cli.Options.AutoIncludes,
+ zig_lib_dir: []const u8,
+ target_machine_type: std.coff.IMAGE.FILE.MACHINE,
+) ![]const []const u8 {
if (auto_includes_option == .none) return &[_][]const u8{};
const includes_arch: std.Target.Cpu.Arch = switch (target_machine_type) {
@@ -626,7 +643,7 @@ fn getIncludePaths(arena: std.mem.Allocator, auto_includes_option: cli.Options.A
.cpu_arch = includes_arch,
.abi = .gnu,
};
- const target = std.zig.resolveTargetQueryOrFatal(target_query);
+ const target = std.zig.resolveTargetQueryOrFatal(io, target_query);
const is_native_abi = target_query.isNativeAbi();
const detected_libc = std.zig.LibCDirs.detect(arena, zig_lib_dir, &target, is_native_abi, true, null) catch |err| switch (err) {
error.OutOfMemory => |e| return e,
@@ -647,7 +664,7 @@ const ErrorHandler = union(enum) {
pub fn emitCliDiagnostics(
self: *ErrorHandler,
- allocator: std.mem.Allocator,
+ allocator: Allocator,
args: []const []const u8,
diagnostics: *cli.Diagnostics,
) !void {
@@ -666,7 +683,7 @@ const ErrorHandler = union(enum) {
pub fn emitAroDiagnostics(
self: *ErrorHandler,
- allocator: std.mem.Allocator,
+ allocator: Allocator,
fail_msg: []const u8,
comp: *aro.Compilation,
) !void {
@@ -692,7 +709,7 @@ const ErrorHandler = union(enum) {
pub fn emitDiagnostics(
self: *ErrorHandler,
- allocator: std.mem.Allocator,
+ allocator: Allocator,
cwd: std.fs.Dir,
source: []const u8,
diagnostics: *Diagnostics,
@@ -713,7 +730,7 @@ const ErrorHandler = union(enum) {
pub fn emitMessage(
self: *ErrorHandler,
- allocator: std.mem.Allocator,
+ allocator: Allocator,
msg_type: @import("utils.zig").ErrorMessageType,
comptime format: []const u8,
args: anytype,
@@ -738,7 +755,7 @@ const ErrorHandler = union(enum) {
};
fn cliDiagnosticsToErrorBundle(
- gpa: std.mem.Allocator,
+ gpa: Allocator,
diagnostics: *cli.Diagnostics,
) !ErrorBundle {
@branchHint(.cold);
@@ -783,7 +800,7 @@ fn cliDiagnosticsToErrorBundle(
}
fn diagnosticsToErrorBundle(
- gpa: std.mem.Allocator,
+ gpa: Allocator,
source: []const u8,
diagnostics: *Diagnostics,
mappings: SourceMappings,
@@ -870,7 +887,7 @@ fn diagnosticsToErrorBundle(
return try bundle.toOwnedBundle("");
}
-fn errorStringToErrorBundle(allocator: std.mem.Allocator, comptime format: []const u8, args: anytype) !ErrorBundle {
+fn errorStringToErrorBundle(allocator: Allocator, comptime format: []const u8, args: anytype) !ErrorBundle {
@branchHint(.cold);
var bundle: ErrorBundle.Wip = undefined;
try bundle.init(allocator);
lib/compiler/resinator/utils.zig
@@ -26,7 +26,11 @@ pub const UncheckedSliceWriter = struct {
/// Cross-platform 'std.fs.Dir.openFile' wrapper that will always return IsDir if
/// a directory is attempted to be opened.
/// TODO: Remove once https://github.com/ziglang/zig/issues/5732 is addressed.
-pub fn openFileNotDir(cwd: std.fs.Dir, path: []const u8, flags: std.fs.File.OpenFlags) std.fs.File.OpenError!std.fs.File {
+pub fn openFileNotDir(
+ cwd: std.fs.Dir,
+ path: []const u8,
+ flags: std.fs.File.OpenFlags,
+) (std.fs.File.OpenError || std.fs.File.StatError)!std.fs.File {
const file = try cwd.openFile(path, flags);
errdefer file.close();
// https://github.com/ziglang/zig/issues/5732