| author | |
| committer | |
| log | 9d1a39c50ffeca1e42ed5f1b75a05d92eec869db |
| tree | 03c56dae947600041d0b0f52287db87e7b5b6ef9 |
| parent | 3da6e671997442df44df3257e882819eae649c8d |
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 | } |
| 133 | 133 | ||
| 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 | } |
| 139 | 139 | ||
| 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(); |
| 1477 | 1481 | ||
| 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(); |
| 1487 | 1491 | ||
| 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 | }; |
| 63 | 64 | ||
| 64 | pub const Dependencies = struct { | 65 | pub const Dependencies = struct { |
| ... | @@ -80,7 +81,7 @@ pub const Dependencies = struct { | ... | @@ -80,7 +81,7 @@ pub const Dependencies = struct { |
| 80 | } | 81 | } |
| 81 | }; | 82 | }; |
| 82 | 83 | ||
| 83 | pub fn compile(allocator: Allocator, io: Io, source: []const u8, writer: *std.Io.Writer, options: CompileOptions, environ_map: *const std.process.Environ.Map) !void { | 84 | pub 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 ""; |
| 152 | 153 | ||
| 153 | // The only precedence here is llvm-rc which also uses the platform-specific | 154 | // 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 as | 406 | // `/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); |
| 410 | 411 | ||
| 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 { |
| 417 | 418 | ||
| 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); |
| 422 | 423 | ||
| 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, | ||
| 28 | 27 | ||
| 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 | } |
| 35 | 33 | ||
| ... | @@ -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 | } |
| 69 | 67 | ||
| 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 { |
| 1120 | 1117 | ||
| 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; |
| 12 | const cli = @import("cli.zig"); | 12 | const cli = @import("cli.zig"); |
| 13 | const preprocess = @import("preprocess.zig"); | 13 | const preprocess = @import("preprocess.zig"); |
| 14 | const renderErrorMessage = @import("utils.zig").renderErrorMessage; | 14 | const renderErrorMessage = @import("utils.zig").renderErrorMessage; |
| 15 | const openFileNotDir = @import("utils.zig").openFileNotDir; | ||
| 16 | const cvtres = @import("cvtres.zig"); | 15 | const cvtres = @import("cvtres.zig"); |
| 17 | const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage; | 16 | const hasDisjointCodePage = @import("disjoint_code_page.zig").hasDisjointCodePage; |
| 18 | const fmtResourceType = @import("res.zig").NameOrOrdinal.fmtResourceType; | 17 | const 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 | } |
| 146 | 145 | ||
| 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 { |
| 152 | 151 | ||
| 153 | try argv.append(aro_arena, "arocc"); // dummy command name | 152 | 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 { |
| 271 | 270 | ||
| 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); |
| 273 | 272 | ||
| 274 | var diagnostics = Diagnostics.init(gpa, io); | 273 | var diagnostics = Diagnostics.init(gpa); |
| 275 | defer diagnostics.deinit(); | 274 | defer diagnostics.deinit(); |
| 276 | 275 | ||
| 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 error | 301 | // 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 { |
| 309 | 309 | ||
| 310 | // print any warnings/notes | 310 | // 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 | } |
| 314 | 314 | ||
| 315 | // write the depfile | 315 | // 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) { |
| 745 | 746 | ||
| 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 | } |
| 751 | 752 |
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 | } |
| 86 | 86 | ||
| 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`. |
| 89 | pub 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 { | 89 | pub 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 | } |
| 110 | 110 | ||
| 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 ""; |
| 113 | 113 | ||
| 114 | // The only precedence here is llvm-rc which also uses the platform-specific | 114 | // 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 @@ |
| 1 | const builtin = @import("builtin"); | ||
| 2 | |||
| 3 | const std = @import("std"); | 1 | const std = @import("std"); |
| 4 | const Io = std.Io; | 2 | const Io = std.Io; |
| 5 | 3 | ||
| ... | @@ -25,27 +23,6 @@ pub const UncheckedSliceWriter = struct { | ... | @@ -25,27 +23,6 @@ pub const UncheckedSliceWriter = struct { |
| 25 | } | 23 | } |
| 26 | }; | 24 | }; |
| 27 | 25 | ||
| 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. | ||
| 31 | pub 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 true | 26 | /// 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. |
| 51 | pub fn isNonAsciiDigit(c: u21) bool { | 28 | pub 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 { |
| 90 | 67 | ||
| 91 | pub const ErrorMessageType = enum { err, warning, note }; | 68 | pub const ErrorMessageType = enum { err, warning, note }; |
| 92 | 69 | ||
| 70 | pub 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 messages | 76 | /// Used for generic colored errors/warnings/notes, more context-specific error messages |
| 94 | /// are handled elsewhere. | 77 | /// are handled elsewhere. |
| 95 | pub fn renderErrorMessage(t: Io.Terminal, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void { | 78 | pub fn renderErrorMessage(t: Io.Terminal, msg_type: ErrorMessageType, comptime format: []const u8, args: anytype) !void { |