| author | |
| committer | |
| log | a2bd9f8912ade5149855dc6e2371aaae49093660 |
| tree | 04dab23f1d6d730b5266506422daf820124fa139 |
| parent | e7bf8f3f04efc280a76a3a38b4e6d470d279e41a |
Before we accepted a nullable allocator for some stuff like
opening files. Now we require an allocator.
Use the mem.FixedBufferAllocator pattern if a bound on the amount
to allocate is known.
This also establishes the pattern that usually an allocator is the
first argument to a function (possibly after "self").
fix docs for std.cstr.addNullByte
self hosted compiler:
* only build docs when explicitly asked to
* clean up main
* stub out zig fmt15 files changed, 103 insertions(+), 136 deletions(-)
build.zig-1| ... | @@ -78,7 +78,6 @@ pub fn build(b: &Builder) !void { | ... | @@ -78,7 +78,6 @@ pub fn build(b: &Builder) !void { |
| 78 | exe.linkSystemLibrary("c"); | 78 | exe.linkSystemLibrary("c"); |
| 79 | 79 | ||
| 80 | b.default_step.dependOn(&exe.step); | 80 | b.default_step.dependOn(&exe.step); |
| 81 | b.default_step.dependOn(docs_step); | ||
| 82 | 81 | ||
| 83 | const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") ?? false; | 82 | const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") ?? false; |
| 84 | if (!skip_self_hosted) { | 83 | if (!skip_self_hosted) { |
doc/docgen.zig+3-3| ... | @@ -31,10 +31,10 @@ pub fn main() !void { | ... | @@ -31,10 +31,10 @@ pub fn main() !void { |
| 31 | const out_file_name = try (args_it.next(allocator) ?? @panic("expected output arg")); | 31 | const out_file_name = try (args_it.next(allocator) ?? @panic("expected output arg")); |
| 32 | defer allocator.free(out_file_name); | 32 | defer allocator.free(out_file_name); |
| 33 | 33 | ||
| 34 | var in_file = try io.File.openRead(in_file_name, allocator); | 34 | var in_file = try io.File.openRead(allocator, in_file_name); |
| 35 | defer in_file.close(); | 35 | defer in_file.close(); |
| 36 | 36 | ||
| 37 | var out_file = try io.File.openWrite(out_file_name, allocator); | 37 | var out_file = try io.File.openWrite(allocator, out_file_name); |
| 38 | defer out_file.close(); | 38 | defer out_file.close(); |
| 39 | 39 | ||
| 40 | var file_in_stream = io.FileInStream.init(&in_file); | 40 | var file_in_stream = io.FileInStream.init(&in_file); |
| ... | @@ -723,7 +723,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var | ... | @@ -723,7 +723,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var |
| 723 | try out.print("<pre><code class=\"zig\">{}</code></pre>", escaped_source); | 723 | try out.print("<pre><code class=\"zig\">{}</code></pre>", escaped_source); |
| 724 | const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name); | 724 | const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name); |
| 725 | const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext); | 725 | const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext); |
| 726 | try io.writeFile(tmp_source_file_name, trimmed_raw_source, null); | 726 | try io.writeFile(allocator, tmp_source_file_name, trimmed_raw_source); |
| 727 | 727 | ||
| 728 | switch (code.id) { | 728 | switch (code.id) { |
| 729 | Code.Id.Exe => |expected_outcome| { | 729 | Code.Id.Exe => |expected_outcome| { |
example/cat/main.zig+1-1| ... | @@ -20,7 +20,7 @@ pub fn main() !void { | ... | @@ -20,7 +20,7 @@ pub fn main() !void { |
| 20 | } else if (arg[0] == '-') { | 20 | } else if (arg[0] == '-') { |
| 21 | return usage(exe); | 21 | return usage(exe); |
| 22 | } else { | 22 | } else { |
| 23 | var file = io.File.openRead(arg, null) catch |err| { | 23 | var file = io.File.openRead(allocator, arg) catch |err| { |
| 24 | warn("Unable to open file: {}\n", @errorName(err)); | 24 | warn("Unable to open file: {}\n", @errorName(err)); |
| 25 | return err; | 25 | return err; |
| 26 | }; | 26 | }; |
src-self-hosted/main.zig+35-30| ... | @@ -16,15 +16,6 @@ const c = @import("c.zig"); | ... | @@ -16,15 +16,6 @@ const c = @import("c.zig"); |
| 16 | 16 | ||
| 17 | const default_zig_cache_name = "zig-cache"; | 17 | const default_zig_cache_name = "zig-cache"; |
| 18 | 18 | ||
| 19 | pub fn main() !void { | ||
| 20 | main2() catch |err| { | ||
| 21 | if (err != error.InvalidCommandLineArguments) { | ||
| 22 | warn("{}\n", @errorName(err)); | ||
| 23 | } | ||
| 24 | return err; | ||
| 25 | }; | ||
| 26 | } | ||
| 27 | |||
| 28 | const Cmd = enum { | 19 | const Cmd = enum { |
| 29 | None, | 20 | None, |
| 30 | Build, | 21 | Build, |
| ... | @@ -35,21 +26,25 @@ const Cmd = enum { | ... | @@ -35,21 +26,25 @@ const Cmd = enum { |
| 35 | Targets, | 26 | Targets, |
| 36 | }; | 27 | }; |
| 37 | 28 | ||
| 38 | fn badArgs(comptime format: []const u8, args: ...) error { | 29 | fn badArgs(comptime format: []const u8, args: ...) noreturn { |
| 39 | var stderr = try io.getStdErr(); | 30 | var stderr = io.getStdErr() catch std.os.exit(1); |
| 40 | var stderr_stream_adapter = io.FileOutStream.init(&stderr); | 31 | var stderr_stream_adapter = io.FileOutStream.init(&stderr); |
| 41 | const stderr_stream = &stderr_stream_adapter.stream; | 32 | const stderr_stream = &stderr_stream_adapter.stream; |
| 42 | try stderr_stream.print(format ++ "\n\n", args); | 33 | stderr_stream.print(format ++ "\n\n", args) catch std.os.exit(1); |
| 43 | try printUsage(&stderr_stream_adapter.stream); | 34 | printUsage(&stderr_stream_adapter.stream) catch std.os.exit(1); |
| 44 | return error.InvalidCommandLineArguments; | 35 | std.os.exit(1); |
| 45 | } | 36 | } |
| 46 | 37 | ||
| 47 | pub fn main2() !void { | 38 | pub fn main() !void { |
| 48 | const allocator = std.heap.c_allocator; | 39 | const allocator = std.heap.c_allocator; |
| 49 | 40 | ||
| 50 | const args = try os.argsAlloc(allocator); | 41 | const args = try os.argsAlloc(allocator); |
| 51 | defer os.argsFree(allocator, args); | 42 | defer os.argsFree(allocator, args); |
| 52 | 43 | ||
| 44 | if (args.len >= 2 and mem.eql(u8, args[1], "fmt")) { | ||
| 45 | return fmtMain(allocator, args[2..]); | ||
| 46 | } | ||
| 47 | |||
| 53 | var cmd = Cmd.None; | 48 | var cmd = Cmd.None; |
| 54 | var build_kind: Module.Kind = undefined; | 49 | var build_kind: Module.Kind = undefined; |
| 55 | var build_mode: builtin.Mode = builtin.Mode.Debug; | 50 | var build_mode: builtin.Mode = builtin.Mode.Debug; |
| ... | @@ -169,7 +164,7 @@ pub fn main2() !void { | ... | @@ -169,7 +164,7 @@ pub fn main2() !void { |
| 169 | } else if (mem.eql(u8, arg, "--pkg-end")) { | 164 | } else if (mem.eql(u8, arg, "--pkg-end")) { |
| 170 | @panic("TODO --pkg-end"); | 165 | @panic("TODO --pkg-end"); |
| 171 | } else if (arg_i + 1 >= args.len) { | 166 | } else if (arg_i + 1 >= args.len) { |
| 172 | return badArgs("expected another argument after {}", arg); | 167 | badArgs("expected another argument after {}", arg); |
| 173 | } else { | 168 | } else { |
| 174 | arg_i += 1; | 169 | arg_i += 1; |
| 175 | if (mem.eql(u8, arg, "--output")) { | 170 | if (mem.eql(u8, arg, "--output")) { |
| ... | @@ -184,7 +179,7 @@ pub fn main2() !void { | ... | @@ -184,7 +179,7 @@ pub fn main2() !void { |
| 184 | } else if (mem.eql(u8, args[arg_i], "off")) { | 179 | } else if (mem.eql(u8, args[arg_i], "off")) { |
| 185 | color = ErrColor.Off; | 180 | color = ErrColor.Off; |
| 186 | } else { | 181 | } else { |
| 187 | return badArgs("--color options are 'auto', 'on', or 'off'"); | 182 | badArgs("--color options are 'auto', 'on', or 'off'"); |
| 188 | } | 183 | } |
| 189 | } else if (mem.eql(u8, arg, "--emit")) { | 184 | } else if (mem.eql(u8, arg, "--emit")) { |
| 190 | if (mem.eql(u8, args[arg_i], "asm")) { | 185 | if (mem.eql(u8, args[arg_i], "asm")) { |
| ... | @@ -194,7 +189,7 @@ pub fn main2() !void { | ... | @@ -194,7 +189,7 @@ pub fn main2() !void { |
| 194 | } else if (mem.eql(u8, args[arg_i], "llvm-ir")) { | 189 | } else if (mem.eql(u8, args[arg_i], "llvm-ir")) { |
| 195 | emit_file_type = Emit.LlvmIr; | 190 | emit_file_type = Emit.LlvmIr; |
| 196 | } else { | 191 | } else { |
| 197 | return badArgs("--emit options are 'asm', 'bin', or 'llvm-ir'"); | 192 | badArgs("--emit options are 'asm', 'bin', or 'llvm-ir'"); |
| 198 | } | 193 | } |
| 199 | } else if (mem.eql(u8, arg, "--name")) { | 194 | } else if (mem.eql(u8, arg, "--name")) { |
| 200 | out_name_arg = args[arg_i]; | 195 | out_name_arg = args[arg_i]; |
| ... | @@ -262,7 +257,7 @@ pub fn main2() !void { | ... | @@ -262,7 +257,7 @@ pub fn main2() !void { |
| 262 | } else if (mem.eql(u8, arg, "--test-cmd")) { | 257 | } else if (mem.eql(u8, arg, "--test-cmd")) { |
| 263 | @panic("TODO --test-cmd"); | 258 | @panic("TODO --test-cmd"); |
| 264 | } else { | 259 | } else { |
| 265 | return badArgs("invalid argument: {}", arg); | 260 | badArgs("invalid argument: {}", arg); |
| 266 | } | 261 | } |
| 267 | } | 262 | } |
| 268 | } else if (cmd == Cmd.None) { | 263 | } else if (cmd == Cmd.None) { |
| ... | @@ -285,18 +280,18 @@ pub fn main2() !void { | ... | @@ -285,18 +280,18 @@ pub fn main2() !void { |
| 285 | cmd = Cmd.Test; | 280 | cmd = Cmd.Test; |
| 286 | build_kind = Module.Kind.Exe; | 281 | build_kind = Module.Kind.Exe; |
| 287 | } else { | 282 | } else { |
| 288 | return badArgs("unrecognized command: {}", arg); | 283 | badArgs("unrecognized command: {}", arg); |
| 289 | } | 284 | } |
| 290 | } else switch (cmd) { | 285 | } else switch (cmd) { |
| 291 | Cmd.Build, Cmd.TranslateC, Cmd.Test => { | 286 | Cmd.Build, Cmd.TranslateC, Cmd.Test => { |
| 292 | if (in_file_arg == null) { | 287 | if (in_file_arg == null) { |
| 293 | in_file_arg = arg; | 288 | in_file_arg = arg; |
| 294 | } else { | 289 | } else { |
| 295 | return badArgs("unexpected extra parameter: {}", arg); | 290 | badArgs("unexpected extra parameter: {}", arg); |
| 296 | } | 291 | } |
| 297 | }, | 292 | }, |
| 298 | Cmd.Version, Cmd.Zen, Cmd.Targets => { | 293 | Cmd.Version, Cmd.Zen, Cmd.Targets => { |
| 299 | return badArgs("unexpected extra parameter: {}", arg); | 294 | badArgs("unexpected extra parameter: {}", arg); |
| 300 | }, | 295 | }, |
| 301 | Cmd.None => unreachable, | 296 | Cmd.None => unreachable, |
| 302 | } | 297 | } |
| ... | @@ -333,15 +328,15 @@ pub fn main2() !void { | ... | @@ -333,15 +328,15 @@ pub fn main2() !void { |
| 333 | // } | 328 | // } |
| 334 | 329 | ||
| 335 | switch (cmd) { | 330 | switch (cmd) { |
| 336 | Cmd.None => return badArgs("expected command"), | 331 | Cmd.None => badArgs("expected command"), |
| 337 | Cmd.Zen => return printZen(), | 332 | Cmd.Zen => return printZen(), |
| 338 | Cmd.Build, Cmd.Test, Cmd.TranslateC => { | 333 | Cmd.Build, Cmd.Test, Cmd.TranslateC => { |
| 339 | if (cmd == Cmd.Build and in_file_arg == null and objects.len == 0 and asm_files.len == 0) { | 334 | if (cmd == Cmd.Build and in_file_arg == null and objects.len == 0 and asm_files.len == 0) { |
| 340 | return badArgs("expected source file argument or at least one --object or --assembly argument"); | 335 | badArgs("expected source file argument or at least one --object or --assembly argument"); |
| 341 | } else if ((cmd == Cmd.TranslateC or cmd == Cmd.Test) and in_file_arg == null) { | 336 | } else if ((cmd == Cmd.TranslateC or cmd == Cmd.Test) and in_file_arg == null) { |
| 342 | return badArgs("expected source file argument"); | 337 | badArgs("expected source file argument"); |
| 343 | } else if (cmd == Cmd.Build and build_kind == Module.Kind.Obj and objects.len != 0) { | 338 | } else if (cmd == Cmd.Build and build_kind == Module.Kind.Obj and objects.len != 0) { |
| 344 | return badArgs("When building an object file, --object arguments are invalid"); | 339 | badArgs("When building an object file, --object arguments are invalid"); |
| 345 | } | 340 | } |
| 346 | 341 | ||
| 347 | const root_name = switch (cmd) { | 342 | const root_name = switch (cmd) { |
| ... | @@ -351,9 +346,9 @@ pub fn main2() !void { | ... | @@ -351,9 +346,9 @@ pub fn main2() !void { |
| 351 | } else if (in_file_arg) |in_file_path| { | 346 | } else if (in_file_arg) |in_file_path| { |
| 352 | const basename = os.path.basename(in_file_path); | 347 | const basename = os.path.basename(in_file_path); |
| 353 | var it = mem.split(basename, "."); | 348 | var it = mem.split(basename, "."); |
| 354 | break :x it.next() ?? return badArgs("file name cannot be empty"); | 349 | break :x it.next() ?? badArgs("file name cannot be empty"); |
| 355 | } else { | 350 | } else { |
| 356 | return badArgs("--name [name] not provided and unable to infer"); | 351 | badArgs("--name [name] not provided and unable to infer"); |
| 357 | } | 352 | } |
| 358 | }, | 353 | }, |
| 359 | Cmd.Test => "test", | 354 | Cmd.Test => "test", |
| ... | @@ -428,7 +423,7 @@ pub fn main2() !void { | ... | @@ -428,7 +423,7 @@ pub fn main2() !void { |
| 428 | module.linker_rdynamic = rdynamic; | 423 | module.linker_rdynamic = rdynamic; |
| 429 | 424 | ||
| 430 | if (mmacosx_version_min != null and mios_version_min != null) { | 425 | if (mmacosx_version_min != null and mios_version_min != null) { |
| 431 | return badArgs("-mmacosx-version-min and -mios-version-min options not allowed together"); | 426 | badArgs("-mmacosx-version-min and -mios-version-min options not allowed together"); |
| 432 | } | 427 | } |
| 433 | 428 | ||
| 434 | if (mmacosx_version_min) |ver| { | 429 | if (mmacosx_version_min) |ver| { |
| ... | @@ -477,6 +472,7 @@ fn printUsage(stream: var) !void { | ... | @@ -477,6 +472,7 @@ fn printUsage(stream: var) !void { |
| 477 | \\ build-exe [source] create executable from source or object files | 472 | \\ build-exe [source] create executable from source or object files |
| 478 | \\ build-lib [source] create library from source or object files | 473 | \\ build-lib [source] create library from source or object files |
| 479 | \\ build-obj [source] create object from source or assembly | 474 | \\ build-obj [source] create object from source or assembly |
| 475 | \\ fmt [file] parse file and render in canonical zig format | ||
| 480 | \\ translate-c [source] convert c code to zig code | 476 | \\ translate-c [source] convert c code to zig code |
| 481 | \\ targets list available compilation targets | 477 | \\ targets list available compilation targets |
| 482 | \\ test [source] create and run a test build | 478 | \\ test [source] create and run a test build |
| ... | @@ -564,6 +560,15 @@ fn printZen() !void { | ... | @@ -564,6 +560,15 @@ fn printZen() !void { |
| 564 | ); | 560 | ); |
| 565 | } | 561 | } |
| 566 | 562 | ||
| 563 | fn fmtMain(allocator: &mem.Allocator, file_paths: []const []const u8) !void { | ||
| 564 | for (file_paths) |file_path| { | ||
| 565 | var file = try io.File.openRead(allocator, file_path); | ||
| 566 | defer file.close(); | ||
| 567 | |||
| 568 | warn("opened {} (todo tokenize and parse and render)\n", file_path); | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 567 | /// Caller must free result | 572 | /// Caller must free result |
| 568 | fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) ![]u8 { | 573 | fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) ![]u8 { |
| 569 | if (zig_install_prefix_arg) |zig_install_prefix| { | 574 | if (zig_install_prefix_arg) |zig_install_prefix| { |
| ... | @@ -588,7 +593,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) ![]u8 | ... | @@ -588,7 +593,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) ![]u8 |
| 588 | const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig"); | 593 | const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig"); |
| 589 | defer allocator.free(test_index_file); | 594 | defer allocator.free(test_index_file); |
| 590 | 595 | ||
| 591 | var file = try io.File.openRead(test_index_file, allocator); | 596 | var file = try io.File.openRead(allocator, test_index_file); |
| 592 | file.close(); | 597 | file.close(); |
| 593 | 598 | ||
| 594 | return test_zig_dir; | 599 | return test_zig_dir; |
src-self-hosted/module.zig+1-1| ... | @@ -213,7 +213,7 @@ pub const Module = struct { | ... | @@ -213,7 +213,7 @@ pub const Module = struct { |
| 213 | }; | 213 | }; |
| 214 | errdefer self.allocator.free(root_src_real_path); | 214 | errdefer self.allocator.free(root_src_real_path); |
| 215 | 215 | ||
| 216 | const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| { | 216 | const source_code = io.readFileAllocExtra(self.allocator, root_src_real_path, 3) catch |err| { |
| 217 | try printError("unable to open '{}': {}", root_src_real_path, err); | 217 | try printError("unable to open '{}': {}", root_src_real_path, err); |
| 218 | return err; | 218 | return err; |
| 219 | }; | 219 | }; |
std/build.zig+1-1| ... | @@ -1890,7 +1890,7 @@ pub const WriteFileStep = struct { | ... | @@ -1890,7 +1890,7 @@ pub const WriteFileStep = struct { |
| 1890 | warn("unable to make path {}: {}\n", full_path_dir, @errorName(err)); | 1890 | warn("unable to make path {}: {}\n", full_path_dir, @errorName(err)); |
| 1891 | return err; | 1891 | return err; |
| 1892 | }; | 1892 | }; |
| 1893 | io.writeFile(full_path, self.data, self.builder.allocator) catch |err| { | 1893 | io.writeFile(self.builder.allocator, full_path, self.data) catch |err| { |
| 1894 | warn("unable to write {}: {}\n", full_path, @errorName(err)); | 1894 | warn("unable to write {}: {}\n", full_path, @errorName(err)); |
| 1895 | return err; | 1895 | return err; |
| 1896 | }; | 1896 | }; |
std/cstr.zig+1-2| ... | @@ -39,8 +39,7 @@ fn testCStrFnsImpl() void { | ... | @@ -39,8 +39,7 @@ fn testCStrFnsImpl() void { |
| 39 | assert(len(c"123456789") == 9); | 39 | assert(len(c"123456789") == 9); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | /// Returns a mutable slice with exactly the same size which is guaranteed to | 42 | /// Returns a mutable slice with 1 more byte of length which is a null byte. |
| 43 | /// have a null byte after it. | ||
| 44 | /// Caller owns the returned memory. | 43 | /// Caller owns the returned memory. |
| 45 | pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) ![]u8 { | 44 | pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) ![]u8 { |
| 46 | const result = try allocator.alloc(u8, slice.len + 1); | 45 | const result = try allocator.alloc(u8, slice.len + 1); |
std/debug/index.zig+1-1| ... | @@ -265,7 +265,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace { | ... | @@ -265,7 +265,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) !&ElfStackTrace { |
| 265 | } | 265 | } |
| 266 | 266 | ||
| 267 | fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &const LineInfo) !void { | 267 | fn printLineFromFile(allocator: &mem.Allocator, out_stream: var, line_info: &const LineInfo) !void { |
| 268 | var f = try io.File.openRead(line_info.file_name, allocator); | 268 | var f = try io.File.openRead(allocator, line_info.file_name); |
| 269 | defer f.close(); | 269 | defer f.close(); |
| 270 | // TODO fstat and make sure that the file has the correct size | 270 | // TODO fstat and make sure that the file has the correct size |
| 271 | 271 |
std/io.zig+19-28| ... | @@ -110,19 +110,16 @@ pub const File = struct { | ... | @@ -110,19 +110,16 @@ pub const File = struct { |
| 110 | 110 | ||
| 111 | const OpenError = os.WindowsOpenError || os.PosixOpenError; | 111 | const OpenError = os.WindowsOpenError || os.PosixOpenError; |
| 112 | 112 | ||
| 113 | /// `path` may need to be copied in memory to add a null terminating byte. In this case | 113 | /// `path` needs to be copied in memory to add a null terminating byte, hence the allocator. |
| 114 | /// a fixed size buffer of size std.os.max_noalloc_path_len is an attempted solution. If the fixed | ||
| 115 | /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned. | ||
| 116 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | ||
| 117 | /// Call close to clean up. | 114 | /// Call close to clean up. |
| 118 | pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) OpenError!File { | 115 | pub fn openRead(allocator: &mem.Allocator, path: []const u8) OpenError!File { |
| 119 | if (is_posix) { | 116 | if (is_posix) { |
| 120 | const flags = system.O_LARGEFILE|system.O_RDONLY; | 117 | const flags = system.O_LARGEFILE|system.O_RDONLY; |
| 121 | const fd = try os.posixOpen(path, flags, 0, allocator); | 118 | const fd = try os.posixOpen(allocator, path, flags, 0); |
| 122 | return openHandle(fd); | 119 | return openHandle(fd); |
| 123 | } else if (is_windows) { | 120 | } else if (is_windows) { |
| 124 | const handle = try os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ, | 121 | const handle = try os.windowsOpen(allocator, path, system.GENERIC_READ, system.FILE_SHARE_READ, |
| 125 | system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL, allocator); | 122 | system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL); |
| 126 | return openHandle(handle); | 123 | return openHandle(handle); |
| 127 | } else { | 124 | } else { |
| 128 | unreachable; | 125 | unreachable; |
| ... | @@ -130,25 +127,22 @@ pub const File = struct { | ... | @@ -130,25 +127,22 @@ pub const File = struct { |
| 130 | } | 127 | } |
| 131 | 128 | ||
| 132 | /// Calls `openWriteMode` with 0o666 for the mode. | 129 | /// Calls `openWriteMode` with 0o666 for the mode. |
| 133 | pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) !File { | 130 | pub fn openWrite(allocator: &mem.Allocator, path: []const u8) !File { |
| 134 | return openWriteMode(path, 0o666, allocator); | 131 | return openWriteMode(allocator, path, 0o666); |
| 135 | 132 | ||
| 136 | } | 133 | } |
| 137 | 134 | ||
| 138 | /// `path` may need to be copied in memory to add a null terminating byte. In this case | 135 | /// `path` needs to be copied in memory to add a null terminating byte, hence the allocator. |
| 139 | /// a fixed size buffer of size std.os.max_noalloc_path_len is an attempted solution. If the fixed | ||
| 140 | /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned. | ||
| 141 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | ||
| 142 | /// Call close to clean up. | 136 | /// Call close to clean up. |
| 143 | pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) !File { | 137 | pub fn openWriteMode(allocator: &mem.Allocator, path: []const u8, mode: usize) !File { |
| 144 | if (is_posix) { | 138 | if (is_posix) { |
| 145 | const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC; | 139 | const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC; |
| 146 | const fd = try os.posixOpen(path, flags, mode, allocator); | 140 | const fd = try os.posixOpen(allocator, path, flags, mode); |
| 147 | return openHandle(fd); | 141 | return openHandle(fd); |
| 148 | } else if (is_windows) { | 142 | } else if (is_windows) { |
| 149 | const handle = try os.windowsOpen(path, system.GENERIC_WRITE, | 143 | const handle = try os.windowsOpen(allocator, path, system.GENERIC_WRITE, |
| 150 | system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE, | 144 | system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE, |
| 151 | system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL, allocator); | 145 | system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL); |
| 152 | return openHandle(handle); | 146 | return openHandle(handle); |
| 153 | } else { | 147 | } else { |
| 154 | unreachable; | 148 | unreachable; |
| ... | @@ -521,24 +515,21 @@ pub fn OutStream(comptime Error: type) type { | ... | @@ -521,24 +515,21 @@ pub fn OutStream(comptime Error: type) type { |
| 521 | }; | 515 | }; |
| 522 | } | 516 | } |
| 523 | 517 | ||
| 524 | /// `path` may need to be copied in memory to add a null terminating byte. In this case | 518 | /// `path` needs to be copied in memory to add a null terminating byte, hence the allocator. |
| 525 | /// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed | 519 | pub fn writeFile(allocator: &mem.Allocator, path: []const u8, data: []const u8) !void { |
| 526 | /// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned. | 520 | var file = try File.openWrite(allocator, path); |
| 527 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | ||
| 528 | pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) !void { | ||
| 529 | var file = try File.openWrite(path, allocator); | ||
| 530 | defer file.close(); | 521 | defer file.close(); |
| 531 | try file.write(data); | 522 | try file.write(data); |
| 532 | } | 523 | } |
| 533 | 524 | ||
| 534 | /// On success, caller owns returned buffer. | 525 | /// On success, caller owns returned buffer. |
| 535 | pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) ![]u8 { | 526 | pub fn readFileAlloc(allocator: &mem.Allocator, path: []const u8) ![]u8 { |
| 536 | return readFileAllocExtra(path, allocator, 0); | 527 | return readFileAllocExtra(allocator, path, 0); |
| 537 | } | 528 | } |
| 538 | /// On success, caller owns returned buffer. | 529 | /// On success, caller owns returned buffer. |
| 539 | /// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized. | 530 | /// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized. |
| 540 | pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) ![]u8 { | 531 | pub fn readFileAllocExtra(allocator: &mem.Allocator, path: []const u8, extra_len: usize) ![]u8 { |
| 541 | var file = try File.openRead(path, allocator); | 532 | var file = try File.openRead(allocator, path); |
| 542 | defer file.close(); | 533 | defer file.close(); |
| 543 | 534 | ||
| 544 | const size = try file.getEndPos(); | 535 | const size = try file.getEndPos(); |
std/io_test.zig+2-2| ... | @@ -13,7 +13,7 @@ test "write a file, read it, then delete it" { | ... | @@ -13,7 +13,7 @@ test "write a file, read it, then delete it" { |
| 13 | rng.fillBytes(data[0..]); | 13 | rng.fillBytes(data[0..]); |
| 14 | const tmp_file_name = "temp_test_file.txt"; | 14 | const tmp_file_name = "temp_test_file.txt"; |
| 15 | { | 15 | { |
| 16 | var file = try io.File.openWrite(tmp_file_name, allocator); | 16 | var file = try io.File.openWrite(allocator, tmp_file_name); |
| 17 | defer file.close(); | 17 | defer file.close(); |
| 18 | 18 | ||
| 19 | var file_out_stream = io.FileOutStream.init(&file); | 19 | var file_out_stream = io.FileOutStream.init(&file); |
| ... | @@ -25,7 +25,7 @@ test "write a file, read it, then delete it" { | ... | @@ -25,7 +25,7 @@ test "write a file, read it, then delete it" { |
| 25 | try buf_stream.flush(); | 25 | try buf_stream.flush(); |
| 26 | } | 26 | } |
| 27 | { | 27 | { |
| 28 | var file = try io.File.openRead(tmp_file_name, allocator); | 28 | var file = try io.File.openRead(allocator, tmp_file_name); |
| 29 | defer file.close(); | 29 | defer file.close(); |
| 30 | 30 | ||
| 31 | const file_size = try file.getEndPos(); | 31 | const file_size = try file.getEndPos(); |
std/os/child_process.zig+17-11| ... | @@ -360,11 +360,14 @@ pub const ChildProcess = struct { | ... | @@ -360,11 +360,14 @@ pub const ChildProcess = struct { |
| 360 | errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; | 360 | errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; |
| 361 | 361 | ||
| 362 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); | 362 | const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); |
| 363 | const dev_null_fd = if (any_ignore) | 363 | const dev_null_fd = if (any_ignore) blk: { |
| 364 | try os.posixOpen("/dev/null", posix.O_RDWR, 0, null) | 364 | const dev_null_path = "/dev/null"; |
| 365 | else | 365 | var fixed_buffer_mem: [dev_null_path.len + 1]u8 = undefined; |
| 366 | undefined | 366 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 367 | ; | 367 | break :blk try os.posixOpen(&fixed_allocator.allocator, "/dev/null", posix.O_RDWR, 0); |
| 368 | } else blk: { | ||
| 369 | break :blk undefined; | ||
| 370 | }; | ||
| 368 | defer { if (any_ignore) os.close(dev_null_fd); } | 371 | defer { if (any_ignore) os.close(dev_null_fd); } |
| 369 | 372 | ||
| 370 | var env_map_owned: BufMap = undefined; | 373 | var env_map_owned: BufMap = undefined; |
| ... | @@ -466,12 +469,15 @@ pub const ChildProcess = struct { | ... | @@ -466,12 +469,15 @@ pub const ChildProcess = struct { |
| 466 | self.stdout_behavior == StdIo.Ignore or | 469 | self.stdout_behavior == StdIo.Ignore or |
| 467 | self.stderr_behavior == StdIo.Ignore); | 470 | self.stderr_behavior == StdIo.Ignore); |
| 468 | 471 | ||
| 469 | const nul_handle = if (any_ignore) | 472 | const nul_handle = if (any_ignore) blk: { |
| 470 | try os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, | 473 | const nul_file_path = "NUL"; |
| 471 | windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null) | 474 | var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined; |
| 472 | else | 475 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 473 | undefined | 476 | break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, |
| 474 | ; | 477 | windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL); |
| 478 | } else blk: { | ||
| 479 | break :blk undefined; | ||
| 480 | }; | ||
| 475 | defer { if (any_ignore) os.close(nul_handle); } | 481 | defer { if (any_ignore) os.close(nul_handle); } |
| 476 | if (any_ignore) { | 482 | if (any_ignore) { |
| 477 | try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); | 483 | try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0); |
std/os/index.zig+14-30| ... | @@ -15,7 +15,6 @@ pub const posix = switch(builtin.os) { | ... | @@ -15,7 +15,6 @@ pub const posix = switch(builtin.os) { |
| 15 | else => @compileError("Unsupported OS"), | 15 | else => @compileError("Unsupported OS"), |
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | pub const max_noalloc_path_len = 1024; | ||
| 19 | pub const ChildProcess = @import("child_process.zig").ChildProcess; | 18 | pub const ChildProcess = @import("child_process.zig").ChildProcess; |
| 20 | pub const path = @import("path.zig"); | 19 | pub const path = @import("path.zig"); |
| 21 | 20 | ||
| ... | @@ -265,32 +264,14 @@ pub const PosixOpenError = error { | ... | @@ -265,32 +264,14 @@ pub const PosixOpenError = error { |
| 265 | Unexpected, | 264 | Unexpected, |
| 266 | }; | 265 | }; |
| 267 | 266 | ||
| 268 | /// ::file_path may need to be copied in memory to add a null terminating byte. In this case | 267 | /// ::file_path needs to be copied in memory to add a null terminating byte. |
| 269 | /// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed | ||
| 270 | /// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned. | ||
| 271 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | ||
| 272 | /// Calls POSIX open, keeps trying if it gets interrupted, and translates | 268 | /// Calls POSIX open, keeps trying if it gets interrupted, and translates |
| 273 | /// the return value into zig errors. | 269 | /// the return value into zig errors. |
| 274 | pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) PosixOpenError!i32 { | 270 | pub fn posixOpen(allocator: &Allocator, file_path: []const u8, flags: u32, perm: usize) PosixOpenError!i32 { |
| 275 | var stack_buf: [max_noalloc_path_len]u8 = undefined; | 271 | const path_with_null = try cstr.addNullByte(allocator, file_path); |
| 276 | var path0: []u8 = undefined; | 272 | defer allocator.free(path_with_null); |
| 277 | var need_free = false; | ||
| 278 | |||
| 279 | if (file_path.len < stack_buf.len) { | ||
| 280 | path0 = stack_buf[0..file_path.len + 1]; | ||
| 281 | } else if (allocator) |a| { | ||
| 282 | path0 = try a.alloc(u8, file_path.len + 1); | ||
| 283 | need_free = true; | ||
| 284 | } else { | ||
| 285 | return error.NameTooLong; | ||
| 286 | } | ||
| 287 | defer if (need_free) { | ||
| 288 | (??allocator).free(path0); | ||
| 289 | }; | ||
| 290 | mem.copy(u8, path0, file_path); | ||
| 291 | path0[file_path.len] = 0; | ||
| 292 | 273 | ||
| 293 | return posixOpenC(path0.ptr, flags, perm); | 274 | return posixOpenC(path_with_null.ptr, flags, perm); |
| 294 | } | 275 | } |
| 295 | 276 | ||
| 296 | pub fn posixOpenC(file_path: &const u8, flags: u32, perm: usize) !i32 { | 277 | pub fn posixOpenC(file_path: &const u8, flags: u32, perm: usize) !i32 { |
| ... | @@ -784,11 +765,11 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [ | ... | @@ -784,11 +765,11 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [ |
| 784 | try getRandomBytes(rand_buf[0..]); | 765 | try getRandomBytes(rand_buf[0..]); |
| 785 | b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); | 766 | b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf); |
| 786 | 767 | ||
| 787 | var out_file = try io.File.openWriteMode(tmp_path, mode, allocator); | 768 | var out_file = try io.File.openWriteMode(allocator, tmp_path, mode); |
| 788 | defer out_file.close(); | 769 | defer out_file.close(); |
| 789 | errdefer _ = deleteFile(allocator, tmp_path); | 770 | errdefer _ = deleteFile(allocator, tmp_path); |
| 790 | 771 | ||
| 791 | var in_file = try io.File.openRead(source_path, allocator); | 772 | var in_file = try io.File.openRead(allocator, source_path); |
| 792 | defer in_file.close(); | 773 | defer in_file.close(); |
| 793 | 774 | ||
| 794 | var buf: [page_size]u8 = undefined; | 775 | var buf: [page_size]u8 = undefined; |
| ... | @@ -1074,7 +1055,7 @@ pub const Dir = struct { | ... | @@ -1074,7 +1055,7 @@ pub const Dir = struct { |
| 1074 | }; | 1055 | }; |
| 1075 | 1056 | ||
| 1076 | pub fn open(allocator: &Allocator, dir_path: []const u8) !Dir { | 1057 | pub fn open(allocator: &Allocator, dir_path: []const u8) !Dir { |
| 1077 | const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator); | 1058 | const fd = try posixOpen(allocator, dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0); |
| 1078 | return Dir { | 1059 | return Dir { |
| 1079 | .allocator = allocator, | 1060 | .allocator = allocator, |
| 1080 | .fd = fd, | 1061 | .fd = fd, |
| ... | @@ -1642,13 +1623,16 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) (error{Unexpected}) { | ... | @@ -1642,13 +1623,16 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) (error{Unexpected}) { |
| 1642 | pub fn openSelfExe() !io.File { | 1623 | pub fn openSelfExe() !io.File { |
| 1643 | switch (builtin.os) { | 1624 | switch (builtin.os) { |
| 1644 | Os.linux => { | 1625 | Os.linux => { |
| 1645 | return io.File.openRead("/proc/self/exe", null); | 1626 | const proc_file_path = "/proc/self/exe"; |
| 1627 | var fixed_buffer_mem: [proc_file_path.len + 1]u8 = undefined; | ||
| 1628 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); | ||
| 1629 | return io.File.openRead(&fixed_allocator.allocator, proc_file_path); | ||
| 1646 | }, | 1630 | }, |
| 1647 | Os.macosx, Os.ios => { | 1631 | Os.macosx, Os.ios => { |
| 1648 | var fixed_buffer_mem: [darwin.PATH_MAX]u8 = undefined; | 1632 | var fixed_buffer_mem: [darwin.PATH_MAX * 2]u8 = undefined; |
| 1649 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); | 1633 | var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]); |
| 1650 | const self_exe_path = try selfExePath(&fixed_allocator.allocator); | 1634 | const self_exe_path = try selfExePath(&fixed_allocator.allocator); |
| 1651 | return io.File.openRead(self_exe_path, null); | 1635 | return io.File.openRead(&fixed_allocator.allocator, self_exe_path); |
| 1652 | }, | 1636 | }, |
| 1653 | else => @compileError("Unsupported OS"), | 1637 | else => @compileError("Unsupported OS"), |
| 1654 | } | 1638 | } |
std/os/path.zig+1-1| ... | @@ -1161,7 +1161,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 { | ... | @@ -1161,7 +1161,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 { |
| 1161 | return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); | 1161 | return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr)); |
| 1162 | }, | 1162 | }, |
| 1163 | Os.linux => { | 1163 | Os.linux => { |
| 1164 | const fd = try os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator); | 1164 | const fd = try os.posixOpen(allocator, pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0); |
| 1165 | defer os.close(fd); | 1165 | defer os.close(fd); |
| 1166 | 1166 | ||
| 1167 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; | 1167 | var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined; |
std/os/windows/util.zig+6-23| ... | @@ -89,34 +89,17 @@ pub const OpenError = error { | ... | @@ -89,34 +89,17 @@ pub const OpenError = error { |
| 89 | PipeBusy, | 89 | PipeBusy, |
| 90 | Unexpected, | 90 | Unexpected, |
| 91 | OutOfMemory, | 91 | OutOfMemory, |
| 92 | NameTooLong, | ||
| 93 | }; | 92 | }; |
| 94 | 93 | ||
| 95 | /// `file_path` may need to be copied in memory to add a null terminating byte. In this case | 94 | /// `file_path` needs to be copied in memory to add a null terminating byte, hence the allocator. |
| 96 | /// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed | 95 | pub fn windowsOpen(allocator: &mem.Allocator, file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD, |
| 97 | /// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned. | 96 | creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD) |
| 98 | /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory. | ||
| 99 | pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD, | ||
| 100 | creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&mem.Allocator) | ||
| 101 | OpenError!windows.HANDLE | 97 | OpenError!windows.HANDLE |
| 102 | { | 98 | { |
| 103 | var stack_buf: [os.max_noalloc_path_len]u8 = undefined; | 99 | const path_with_null = try cstr.addNullByte(allocator, file_path); |
| 104 | var path0: []u8 = undefined; | 100 | defer allocator.free(path_with_null); |
| 105 | var need_free = false; | ||
| 106 | defer if (need_free) (??allocator).free(path0); | ||
| 107 | |||
| 108 | if (file_path.len < stack_buf.len) { | ||
| 109 | path0 = stack_buf[0..file_path.len + 1]; | ||
| 110 | } else if (allocator) |a| { | ||
| 111 | path0 = try a.alloc(u8, file_path.len + 1); | ||
| 112 | need_free = true; | ||
| 113 | } else { | ||
| 114 | return error.NameTooLong; | ||
| 115 | } | ||
| 116 | mem.copy(u8, path0, file_path); | ||
| 117 | path0[file_path.len] = 0; | ||
| 118 | 101 | ||
| 119 | const result = windows.CreateFileA(path0.ptr, desired_access, share_mode, null, creation_disposition, | 102 | const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition, |
| 120 | flags_and_attrs, null); | 103 | flags_and_attrs, null); |
| 121 | 104 | ||
| 122 | if (result == windows.INVALID_HANDLE_VALUE) { | 105 | if (result == windows.INVALID_HANDLE_VALUE) { |
test/tests.zig+1-1| ... | @@ -1049,7 +1049,7 @@ pub const GenHContext = struct { | ... | @@ -1049,7 +1049,7 @@ pub const GenHContext = struct { |
| 1049 | warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); | 1049 | warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name); |
| 1050 | 1050 | ||
| 1051 | const full_h_path = b.pathFromRoot(self.h_path); | 1051 | const full_h_path = b.pathFromRoot(self.h_path); |
| 1052 | const actual_h = try io.readFileAlloc(full_h_path, b.allocator); | 1052 | const actual_h = try io.readFileAlloc(b.allocator, full_h_path); |
| 1053 | 1053 | ||
| 1054 | for (self.case.expected_lines.toSliceConst()) |expected_line| { | 1054 | for (self.case.expected_lines.toSliceConst()) |expected_line| { |
| 1055 | if (mem.indexOf(u8, actual_h, expected_line) == null) { | 1055 | if (mem.indexOf(u8, actual_h, expected_line) == null) { |