From e21739dd8caf7d6a9aefe68c37eddb6406bcb810 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Tue, 25 Apr 2023 20:16:39 +0100 Subject: std.fs: selfExePath haiku using constants instead --- lib/std/fs.zig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 9f64387bd8..7327a3a913 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -2999,8 +2999,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { .haiku => { // The only possible issue when looking for the self image path is // when the buffer is too short. - // TODO replace with proper constants - if (os.find_path(null, 1000, null, out_buffer.ptr, out_buffer.len) != 0) + if (os.find_path(os.B_APP_IMAGE_SYMBOL, os.path_base_directory.B_FIND_IMAGE_PATH, null, out_buffer.ptr, out_buffer.len) != 0) return error.Overflow; return mem.sliceTo(out_buffer, 0); }, -- cgit v1.2.3 From 815e53b147a321d0bdb47dc008aa8181f57175ac Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Thu, 4 May 2023 18:05:40 -0700 Subject: Update all std.mem.tokenize calls to their appropriate function Everywhere that can now use `tokenizeScalar` should get a nice little performance boost. --- build.zig | 8 ++++---- lib/std/Build.zig | 2 +- lib/std/Build/Cache.zig | 4 ++-- lib/std/Build/Step/CheckObject.zig | 8 ++++---- lib/std/Build/Step/Compile.zig | 6 +++--- lib/std/Build/Step/ConfigHeader.zig | 4 ++-- lib/std/child_process.zig | 4 ++-- lib/std/fs.zig | 2 +- lib/std/fs/path.zig | 26 ++++++++++++------------ lib/std/http/Client.zig | 4 ++-- lib/std/http/Server.zig | 4 ++-- lib/std/net.zig | 6 +++--- lib/std/os.zig | 2 +- lib/std/process.zig | 2 +- lib/std/zig/system/NativePaths.zig | 10 ++++----- lib/std/zig/system/NativeTargetInfo.zig | 4 ++-- src/arch/x86_64/CodeGen.zig | 6 +++--- src/glibc.zig | 2 +- src/libc_installation.zig | 8 ++++---- src/link/Plan9.zig | 2 +- src/print_zir.zig | 2 +- test/behavior/bugs/6456.zig | 2 +- test/src/Cases.zig | 4 ++-- tools/generate_linux_syscalls.zig | 36 ++++++++++++++++----------------- 24 files changed, 79 insertions(+), 79 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/build.zig b/build.zig index 208d06fe1d..21b323df56 100644 --- a/build.zig +++ b/build.zig @@ -284,7 +284,7 @@ pub fn build(b: *std.Build) !void { // That means we also have to rely on stage1 compiled c++ files. We parse config.h to find // the information passed on to us from cmake. if (cfg.cmake_prefix_path.len > 0) { - var it = mem.tokenize(u8, cfg.cmake_prefix_path, ";"); + var it = mem.tokenizeScalar(u8, cfg.cmake_prefix_path, ';'); while (it.next()) |path| { b.addSearchPrefix(path); } @@ -687,7 +687,7 @@ fn addCxxKnownPath( if (!std.process.can_spawn) return error.RequiredLibraryNotFound; const path_padded = b.exec(&.{ ctx.cxx_compiler, b.fmt("-print-file-name={s}", .{objname}) }); - var tokenizer = mem.tokenize(u8, path_padded, "\r\n"); + var tokenizer = mem.tokenizeAny(u8, path_padded, "\r\n"); const path_unpadded = tokenizer.next().?; if (mem.eql(u8, path_unpadded, objname)) { if (errtxt) |msg| { @@ -710,7 +710,7 @@ fn addCxxKnownPath( } fn addCMakeLibraryList(exe: *std.Build.Step.Compile, list: []const u8) void { - var it = mem.tokenize(u8, list, ";"); + var it = mem.tokenizeScalar(u8, list, ';'); while (it.next()) |lib| { if (mem.startsWith(u8, lib, "-l")) { exe.linkSystemLibrary(lib["-l".len..]); @@ -855,7 +855,7 @@ fn parseConfigH(b: *std.Build, config_h_text: []const u8) ?CMakeConfig { // .prefix = ZIG_LLVM_LINK_MODE parsed manually below }; - var lines_it = mem.tokenize(u8, config_h_text, "\r\n"); + var lines_it = mem.tokenizeAny(u8, config_h_text, "\r\n"); while (lines_it.next()) |line| { inline for (mappings) |mapping| { if (mem.startsWith(u8, line, mapping.prefix)) { diff --git a/lib/std/Build.zig b/lib/std/Build.zig index ca55d23937..4ab5db5c70 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -1358,7 +1358,7 @@ pub fn findProgram(self: *Build, names: []const []const u8, paths: []const []con if (fs.path.isAbsolute(name)) { return name; } - var it = mem.tokenize(u8, PATH, &[_]u8{fs.path.delimiter}); + var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter); while (it.next()) |path| { const full_path = self.pathJoin(&.{ path, diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index 17429c0370..7709e5e26c 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -434,7 +434,7 @@ pub const Manifest = struct { const input_file_count = self.files.items.len; var any_file_changed = false; - var line_iter = mem.tokenize(u8, file_contents, "\n"); + var line_iter = mem.tokenizeScalar(u8, file_contents, '\n'); var idx: usize = 0; if (if (line_iter.next()) |line| !std.mem.eql(u8, line, manifest_header) else true) { if (try self.upgradeToExclusiveLock()) continue; @@ -463,7 +463,7 @@ pub const Manifest = struct { break :blk new; }; - var iter = mem.tokenize(u8, line, " "); + var iter = mem.tokenizeScalar(u8, line, ' '); const size = iter.next() orelse return error.InvalidFormat; const inode = iter.next() orelse return error.InvalidFormat; const mtime_nsec_str = iter.next() orelse return error.InvalidFormat; diff --git a/lib/std/Build/Step/CheckObject.zig b/lib/std/Build/Step/CheckObject.zig index c77dc3de36..24ebfef388 100644 --- a/lib/std/Build/Step/CheckObject.zig +++ b/lib/std/Build/Step/CheckObject.zig @@ -103,8 +103,8 @@ const Action = struct { assert(act.tag == .match or act.tag == .not_present); const phrase = act.phrase.resolve(b, step); var candidate_var: ?struct { name: []const u8, value: u64 } = null; - var hay_it = mem.tokenize(u8, mem.trim(u8, haystack, " "), " "); - var needle_it = mem.tokenize(u8, mem.trim(u8, phrase, " "), " "); + var hay_it = mem.tokenizeScalar(u8, mem.trim(u8, haystack, " "), ' '); + var needle_it = mem.tokenizeScalar(u8, mem.trim(u8, phrase, " "), ' '); while (needle_it.next()) |needle_tok| { const hay_tok = hay_it.next() orelse return false; @@ -155,7 +155,7 @@ const Action = struct { var op_stack = std.ArrayList(enum { add, sub, mod, mul }).init(gpa); var values = std.ArrayList(u64).init(gpa); - var it = mem.tokenize(u8, phrase, " "); + var it = mem.tokenizeScalar(u8, phrase, ' '); while (it.next()) |next| { if (mem.eql(u8, next, "+")) { try op_stack.append(.add); @@ -365,7 +365,7 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { var vars = std.StringHashMap(u64).init(gpa); for (self.checks.items) |chk| { - var it = mem.tokenize(u8, output, "\r\n"); + var it = mem.tokenizeAny(u8, output, "\r\n"); for (chk.actions.items) |act| { switch (act.tag) { .match => { diff --git a/lib/std/Build/Step/Compile.zig b/lib/std/Build/Step/Compile.zig index 2371f49daf..6a05adc1a6 100644 --- a/lib/std/Build/Step/Compile.zig +++ b/lib/std/Build/Step/Compile.zig @@ -777,7 +777,7 @@ fn runPkgConfig(self: *Compile, lib_name: []const u8) ![]const []const u8 { var zig_args = ArrayList([]const u8).init(b.allocator); defer zig_args.deinit(); - var it = mem.tokenize(u8, stdout, " \r\n\t"); + var it = mem.tokenizeAny(u8, stdout, " \r\n\t"); while (it.next()) |tok| { if (mem.eql(u8, tok, "-I")) { const dir = it.next() orelse return error.PkgConfigInvalidOutput; @@ -2017,10 +2017,10 @@ fn execPkgConfigList(self: *std.Build, out_code: *u8) (PkgConfigError || ExecErr const stdout = try self.execAllowFail(&[_][]const u8{ "pkg-config", "--list-all" }, out_code, .Ignore); var list = ArrayList(PkgConfigPkg).init(self.allocator); errdefer list.deinit(); - var line_it = mem.tokenize(u8, stdout, "\r\n"); + var line_it = mem.tokenizeAny(u8, stdout, "\r\n"); while (line_it.next()) |line| { if (mem.trim(u8, line, " \t").len == 0) continue; - var tok_it = mem.tokenize(u8, line, " \t"); + var tok_it = mem.tokenizeAny(u8, line, " \t"); try list.append(PkgConfigPkg{ .name = tok_it.next() orelse return error.PkgConfigInvalidOutput, .desc = tok_it.rest(), diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index f6939e0e38..cd97367218 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -257,7 +257,7 @@ fn render_autoconf( try output.appendSlice("\n"); continue; } - var it = std.mem.tokenize(u8, line[1..], " \t\r"); + var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); const undef = it.next().?; if (!std.mem.eql(u8, undef, "undef")) { try output.appendSlice(line); @@ -304,7 +304,7 @@ fn render_cmake( try output.appendSlice("\n"); continue; } - var it = std.mem.tokenize(u8, line[1..], " \t\r"); + var it = std.mem.tokenizeAny(u8, line[1..], " \t\r"); const cmakedefine = it.next().?; if (!std.mem.eql(u8, cmakedefine, "cmakedefine") and !std.mem.eql(u8, cmakedefine, "cmakedefine01")) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index daaa1689bc..d94f5ea000 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -850,7 +850,7 @@ pub const ChildProcess = struct { return original_err; } - var it = mem.tokenize(u16, PATH, &[_]u16{';'}); + var it = mem.tokenizeScalar(u16, PATH, ';'); while (it.next()) |search_path| { dir_buf.clearRetainingCapacity(); try dir_buf.appendSlice(self.allocator, search_path); @@ -1067,7 +1067,7 @@ fn windowsCreateProcessPathExt( // Now we know that at least *a* file matching the wildcard exists, we can loop // through PATHEXT in order and exec any that exist - var ext_it = mem.tokenize(u16, pathext, &[_]u16{';'}); + var ext_it = mem.tokenizeScalar(u16, pathext, ';'); while (ext_it.next()) |ext| { if (!windowsCreateProcessSupportsExtension(ext)) continue; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 7327a3a913..5aeea8a4aa 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -3021,7 +3021,7 @@ pub fn selfExePath(out_buffer: []u8) SelfExePathError![]u8 { } else if (argv0.len != 0) { // argv[0] is not empty (and not a path): search it inside PATH const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound; - var path_it = mem.tokenize(u8, PATH, &[_]u8{path.delimiter}); + var path_it = mem.tokenizeScalar(u8, PATH, path.delimiter); while (path_it.next()) |a_path| { var resolved_path_buf: [MAX_PATH_BYTES - 1:0]u8 = undefined; const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{ diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 4c320ae5cf..e7a28a7615 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -358,7 +358,7 @@ pub fn windowsParsePath(path: []const u8) WindowsPath { return relative_path; } - var it = mem.tokenize(u8, path, &[_]u8{this_sep}); + var it = mem.tokenizeScalar(u8, path, this_sep); _ = (it.next() orelse return relative_path); _ = (it.next() orelse return relative_path); return WindowsPath{ @@ -420,8 +420,8 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) bool { const sep1 = ns1[0]; const sep2 = ns2[0]; - var it1 = mem.tokenize(u8, ns1, &[_]u8{sep1}); - var it2 = mem.tokenize(u8, ns2, &[_]u8{sep2}); + var it1 = mem.tokenizeScalar(u8, ns1, sep1); + var it2 = mem.tokenizeScalar(u8, ns2, sep2); // TODO ASCII is wrong, we actually need full unicode support to compare paths. return ascii.eqlIgnoreCase(it1.next().?, it2.next().?); @@ -441,8 +441,8 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8 const sep1 = p1[0]; const sep2 = p2[0]; - var it1 = mem.tokenize(u8, p1, &[_]u8{sep1}); - var it2 = mem.tokenize(u8, p2, &[_]u8{sep2}); + var it1 = mem.tokenizeScalar(u8, p1, sep1); + var it2 = mem.tokenizeScalar(u8, p2, sep2); // TODO ASCII is wrong, we actually need full unicode support to compare paths. return ascii.eqlIgnoreCase(it1.next().?, it2.next().?) and ascii.eqlIgnoreCase(it1.next().?, it2.next().?); @@ -535,7 +535,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 { break :l disk_designator.len; }, .NetworkShare => { - var it = mem.tokenize(u8, paths[first_index], "/\\"); + var it = mem.tokenizeAny(u8, paths[first_index], "/\\"); const server_name = it.next().?; const other_name = it.next().?; @@ -570,7 +570,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 { if (!correct_disk_designator) { continue; } - var it = mem.tokenize(u8, p[parsed.disk_designator.len..], "/\\"); + var it = mem.tokenizeAny(u8, p[parsed.disk_designator.len..], "/\\"); while (it.next()) |component| { if (mem.eql(u8, component, ".")) { continue; @@ -657,7 +657,7 @@ pub fn resolvePosix(allocator: Allocator, paths: []const []const u8) Allocator.E negative_count = 0; result.clearRetainingCapacity(); } - var it = mem.tokenize(u8, p, "/"); + var it = mem.tokenizeScalar(u8, p, '/'); while (it.next()) |component| { if (mem.eql(u8, component, ".")) { continue; @@ -1078,8 +1078,8 @@ pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) ! return resolved_to; } - var from_it = mem.tokenize(u8, resolved_from, "/\\"); - var to_it = mem.tokenize(u8, resolved_to, "/\\"); + var from_it = mem.tokenizeAny(u8, resolved_from, "/\\"); + var to_it = mem.tokenizeAny(u8, resolved_to, "/\\"); while (true) { const from_component = from_it.next() orelse return allocator.dupe(u8, to_it.rest()); const to_rest = to_it.rest(); @@ -1102,7 +1102,7 @@ pub fn relativeWindows(allocator: Allocator, from: []const u8, to: []const u8) ! result_index += 3; } - var rest_it = mem.tokenize(u8, to_rest, "/\\"); + var rest_it = mem.tokenizeAny(u8, to_rest, "/\\"); while (rest_it.next()) |to_component| { result[result_index] = '\\'; result_index += 1; @@ -1124,8 +1124,8 @@ pub fn relativePosix(allocator: Allocator, from: []const u8, to: []const u8) ![] const resolved_to = try resolvePosix(allocator, &[_][]const u8{ cwd, to }); defer allocator.free(resolved_to); - var from_it = mem.tokenize(u8, resolved_from, "/"); - var to_it = mem.tokenize(u8, resolved_to, "/"); + var from_it = mem.tokenizeScalar(u8, resolved_from, '/'); + var to_it = mem.tokenizeScalar(u8, resolved_to, '/'); while (true) { const from_component = from_it.next() orelse return allocator.dupe(u8, to_it.rest()); const to_rest = to_it.rest(); diff --git a/lib/std/http/Client.zig b/lib/std/http/Client.zig index 023bdd28bc..5626864ceb 100644 --- a/lib/std/http/Client.zig +++ b/lib/std/http/Client.zig @@ -386,7 +386,7 @@ pub const Response = struct { }; pub fn parse(res: *Response, bytes: []const u8, trailing: bool) ParseError!void { - var it = mem.tokenize(u8, bytes[0 .. bytes.len - 4], "\r\n"); + var it = mem.tokenizeAny(u8, bytes[0 .. bytes.len - 4], "\r\n"); const first_line = it.next() orelse return error.HttpHeadersInvalid; if (first_line.len < 12) @@ -412,7 +412,7 @@ pub const Response = struct { else => {}, } - var line_it = mem.tokenize(u8, line, ": "); + var line_it = mem.tokenizeAny(u8, line, ": "); const header_name = line_it.next() orelse return error.HttpHeadersInvalid; const header_value = line_it.rest(); diff --git a/lib/std/http/Server.zig b/lib/std/http/Server.zig index 6b5db6725f..51ab6c086b 100644 --- a/lib/std/http/Server.zig +++ b/lib/std/http/Server.zig @@ -231,7 +231,7 @@ pub const Request = struct { }; pub fn parse(req: *Request, bytes: []const u8) ParseError!void { - var it = mem.tokenize(u8, bytes[0 .. bytes.len - 4], "\r\n"); + var it = mem.tokenizeAny(u8, bytes[0 .. bytes.len - 4], "\r\n"); const first_line = it.next() orelse return error.HttpHeadersInvalid; if (first_line.len < 10) @@ -265,7 +265,7 @@ pub const Request = struct { else => {}, } - var line_it = mem.tokenize(u8, line, ": "); + var line_it = mem.tokenizeAny(u8, line, ": "); const header_name = line_it.next() orelse return error.HttpHeadersInvalid; const header_value = line_it.rest(); diff --git a/lib/std/net.zig b/lib/std/net.zig index 57e50a7349..4360cc29f4 100644 --- a/lib/std/net.zig +++ b/lib/std/net.zig @@ -1266,7 +1266,7 @@ fn linuxLookupNameFromHosts( var split_it = mem.split(u8, line, "#"); const no_comment_line = split_it.first(); - var line_it = mem.tokenize(u8, no_comment_line, " \t"); + var line_it = mem.tokenizeAny(u8, no_comment_line, " \t"); const ip_text = line_it.next() orelse continue; var first_name_text: ?[]const u8 = null; while (line_it.next()) |name_text| { @@ -1346,7 +1346,7 @@ fn linuxLookupNameFromDnsSearch( @memcpy(canon.items, canon_name); try canon.append('.'); - var tok_it = mem.tokenize(u8, search, " \t"); + var tok_it = mem.tokenizeAny(u8, search, " \t"); while (tok_it.next()) |tok| { canon.shrinkRetainingCapacity(canon_name.len + 1); try canon.appendSlice(tok); @@ -1468,7 +1468,7 @@ fn getResolvConf(allocator: mem.Allocator, rc: *ResolvConf) !void { var split = mem.split(u8, line, "#"); break :no_comment_line split.first(); }; - var line_it = mem.tokenize(u8, no_comment_line, " \t"); + var line_it = mem.tokenizeAny(u8, no_comment_line, " \t"); const token = line_it.next() orelse continue; if (mem.eql(u8, token, "options")) { diff --git a/lib/std/os.zig b/lib/std/os.zig index 779e913230..eac79690b5 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -1878,7 +1878,7 @@ pub fn execvpeZ_expandArg0( // Use of MAX_PATH_BYTES here is valid as the path_buf will be passed // directly to the operating system in execveZ. var path_buf: [MAX_PATH_BYTES]u8 = undefined; - var it = mem.tokenize(u8, PATH, ":"); + var it = mem.tokenizeScalar(u8, PATH, ':'); var seen_eacces = false; var err: ExecveError = error.FileNotFound; diff --git a/lib/std/process.zig b/lib/std/process.zig index 504f9075eb..c33fd92db6 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -1200,7 +1200,7 @@ fn totalSystemMemoryLinux() !usize { var buf: [50]u8 = undefined; const amt = try file.read(&buf); if (amt != 50) return error.Unexpected; - var it = std.mem.tokenize(u8, buf[0..amt], " \n"); + var it = std.mem.tokenizeAny(u8, buf[0..amt], " \n"); const label = it.next().?; if (!std.mem.eql(u8, label, "MemTotal:")) return error.Unexpected; const int_text = it.next() orelse return error.Unexpected; diff --git a/lib/std/zig/system/NativePaths.zig b/lib/std/zig/system/NativePaths.zig index 70c795b0cf..368e3e062d 100644 --- a/lib/std/zig/system/NativePaths.zig +++ b/lib/std/zig/system/NativePaths.zig @@ -31,7 +31,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths defer allocator.free(nix_cflags_compile); is_nix = true; - var it = mem.tokenize(u8, nix_cflags_compile, " "); + var it = mem.tokenizeScalar(u8, nix_cflags_compile, ' '); while (true) { const word = it.next() orelse break; if (mem.eql(u8, word, "-isystem")) { @@ -62,7 +62,7 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths defer allocator.free(nix_ldflags); is_nix = true; - var it = mem.tokenize(u8, nix_ldflags, " "); + var it = mem.tokenizeScalar(u8, nix_ldflags, ' '); while (true) { const word = it.next() orelse break; if (mem.eql(u8, word, "-rpath")) { @@ -147,21 +147,21 @@ pub fn detect(allocator: Allocator, native_info: NativeTargetInfo) !NativePaths // We use os.getenv here since this part won't be executed on // windows, to get rid of unnecessary error handling. if (std.os.getenv("C_INCLUDE_PATH")) |c_include_path| { - var it = mem.tokenize(u8, c_include_path, ":"); + var it = mem.tokenizeScalar(u8, c_include_path, ':'); while (it.next()) |dir| { try self.addIncludeDir(dir); } } if (std.os.getenv("CPLUS_INCLUDE_PATH")) |cplus_include_path| { - var it = mem.tokenize(u8, cplus_include_path, ":"); + var it = mem.tokenizeScalar(u8, cplus_include_path, ':'); while (it.next()) |dir| { try self.addIncludeDir(dir); } } if (std.os.getenv("LIBRARY_PATH")) |library_path| { - var it = mem.tokenize(u8, library_path, ":"); + var it = mem.tokenizeScalar(u8, library_path, ':'); while (it.next()) |dir| { try self.addLibDir(dir); } diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig index 539ad96365..808a1bda8d 100644 --- a/lib/std/zig/system/NativeTargetInfo.zig +++ b/lib/std/zig/system/NativeTargetInfo.zig @@ -354,7 +354,7 @@ fn detectAbiAndDynamicLinker( const newline = mem.indexOfScalar(u8, buffer[0..len], '\n') orelse break :blk file; const line = buffer[0..newline]; if (!mem.startsWith(u8, line, "#!")) break :blk file; - var it = mem.tokenize(u8, line[2..], " "); + var it = mem.tokenizeScalar(u8, line[2..], ' '); file_name = it.next() orelse return defaultAbiAndDynamicLinker(cpu, os, cross_target); file.close(); } @@ -811,7 +811,7 @@ pub fn abiAndDynamicLinkerFromFile( const strtab = strtab_buf[0..strtab_read_len]; const rpath_list = mem.sliceTo(strtab, 0); - var it = mem.tokenize(u8, rpath_list, ":"); + var it = mem.tokenizeScalar(u8, rpath_list, ':'); while (it.next()) |rpath| { if (glibcVerFromRPath(rpath)) |ver| { result.target.os.version_range.linux.glibc = ver; diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 2dc1cc8ee4..be09a33bde 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -8409,9 +8409,9 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { } const asm_source = mem.sliceAsBytes(self.air.extra[extra_i..])[0..extra.data.source_len]; - var line_it = mem.tokenize(u8, asm_source, "\n\r;"); + var line_it = mem.tokenizeAny(u8, asm_source, "\n\r;"); while (line_it.next()) |line| { - var mnem_it = mem.tokenize(u8, line, " \t"); + var mnem_it = mem.tokenizeAny(u8, line, " \t"); const mnem_str = mnem_it.next() orelse continue; if (mem.startsWith(u8, mnem_str, "#")) continue; @@ -8435,7 +8435,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void { return self.fail("Invalid mnemonic: '{s}'", .{mnem_str}); } }; - var op_it = mem.tokenize(u8, mnem_it.rest(), ","); + var op_it = mem.tokenizeScalar(u8, mnem_it.rest(), ','); var ops = [1]encoder.Instruction.Operand{.none} ** 4; for (&ops) |*op| { const op_str = mem.trim(u8, op_it.next() orelse break, " \t"); diff --git a/src/glibc.zig b/src/glibc.zig index 327e4f4bb9..00787381f4 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -109,7 +109,7 @@ pub fn loadMetaData(gpa: Allocator, contents: []const u8) LoadMetaDataError!*ABI const target_name = mem.sliceTo(contents[index..], 0); index += target_name.len + 1; - var component_it = mem.tokenize(u8, target_name, "-"); + var component_it = mem.tokenizeScalar(u8, target_name, '-'); const arch_name = component_it.next() orelse { log.err("abilists: expected arch name", .{}); return error.ZigInstallationCorrupt; diff --git a/src/libc_installation.zig b/src/libc_installation.zig index da877e1291..a62da6b9c7 100644 --- a/src/libc_installation.zig +++ b/src/libc_installation.zig @@ -60,7 +60,7 @@ pub const LibCInstallation = struct { const contents = try std.fs.cwd().readFileAlloc(allocator, libc_file, std.math.maxInt(usize)); defer allocator.free(contents); - var it = std.mem.tokenize(u8, contents, "\n"); + var it = std.mem.tokenizeScalar(u8, contents, '\n'); while (it.next()) |line| { if (line.len == 0 or line[0] == '#') continue; var line_it = std.mem.split(u8, line, "="); @@ -293,7 +293,7 @@ pub const LibCInstallation = struct { }, } - var it = std.mem.tokenize(u8, exec_res.stderr, "\n\r"); + var it = std.mem.tokenizeAny(u8, exec_res.stderr, "\n\r"); var search_paths = std.ArrayList([]const u8).init(allocator); defer search_paths.deinit(); while (it.next()) |line| { @@ -613,7 +613,7 @@ fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 { }, } - var it = std.mem.tokenize(u8, exec_res.stdout, "\n\r"); + var it = std.mem.tokenizeAny(u8, exec_res.stdout, "\n\r"); const line = it.next() orelse return error.LibCRuntimeNotFound; // When this command fails, it returns exit code 0 and duplicates the input file name. // So we detect failure by checking if the output matches exactly the input. @@ -692,7 +692,7 @@ fn appendCcExe(args: *std.ArrayList([]const u8), skip_cc_env_var: bool) !void { return; }; // Respect space-separated flags to the C compiler. - var it = std.mem.tokenize(u8, cc_env_var, " "); + var it = std.mem.tokenizeScalar(u8, cc_env_var, ' '); while (it.next()) |arg| { try args.append(arg); } diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index bef06d1c87..f8ac4e09c1 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -264,7 +264,7 @@ fn putFn(self: *Plan9, decl_index: Module.Decl.Index, out: FnDeclOutput) !void { fn addPathComponents(self: *Plan9, path: []const u8, a: *std.ArrayList(u8)) !void { const sep = std.fs.path.sep; - var it = std.mem.tokenize(u8, path, &.{sep}); + var it = std.mem.tokenizeScalar(u8, path, sep); while (it.next()) |component| { if (self.file_segments.get(component)) |num| { try a.writer().writeIntBig(u16, num); diff --git a/src/print_zir.zig b/src/print_zir.zig index f5e84fcf5b..6ded52ae9f 100644 --- a/src/print_zir.zig +++ b/src/print_zir.zig @@ -2581,7 +2581,7 @@ const Writer = struct { fn writeDocComment(self: *Writer, stream: anytype, doc_comment_index: u32) !void { if (doc_comment_index != 0) { const doc_comment = self.code.nullTerminatedString(doc_comment_index); - var it = std.mem.tokenize(u8, doc_comment, "\n"); + var it = std.mem.tokenizeScalar(u8, doc_comment, '\n'); while (it.next()) |doc_line| { try stream.writeByteNTimes(' ', self.indent); try stream.print("///{s}\n", .{doc_line}); diff --git a/test/behavior/bugs/6456.zig b/test/behavior/bugs/6456.zig index 1eef9c7f75..297c9c7423 100644 --- a/test/behavior/bugs/6456.zig +++ b/test/behavior/bugs/6456.zig @@ -18,7 +18,7 @@ test "issue 6456" { comptime { var fields: []const StructField = &[0]StructField{}; - var it = std.mem.tokenize(u8, text, "\n"); + var it = std.mem.tokenizeScalar(u8, text, '\n'); while (it.next()) |name| { fields = fields ++ &[_]StructField{StructField{ .alignment = 0, diff --git a/test/src/Cases.zig b/test/src/Cases.zig index 68ecebc7bd..aa5369af93 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -846,7 +846,7 @@ const TestManifest = struct { const actual_start = start orelse return error.MissingTestManifest; const manifest_bytes = bytes[actual_start..end]; - var it = std.mem.tokenize(u8, manifest_bytes, "\r\n"); + var it = std.mem.tokenizeAny(u8, manifest_bytes, "\r\n"); // First line is the test type const tt: Type = blk: { @@ -923,7 +923,7 @@ const TestManifest = struct { fn trailing(self: TestManifest) TrailingIterator { return .{ - .inner = std.mem.tokenize(u8, self.trailing_bytes, "\r\n"), + .inner = std.mem.tokenizeAny(u8, self.trailing_bytes, "\r\n"), }; } diff --git a/tools/generate_linux_syscalls.zig b/tools/generate_linux_syscalls.zig index 11b18ae3bf..32e287b434 100644 --- a/tools/generate_linux_syscalls.zig +++ b/tools/generate_linux_syscalls.zig @@ -51,11 +51,11 @@ pub fn main() !void { try writer.writeAll("pub const X86 = enum(usize) {\n"); const table = try linux_dir.readFile("arch/x86/entry/syscalls/syscall_32.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; // abi is always i386 _ = fields.next() orelse return error.Incomplete; @@ -70,11 +70,11 @@ pub fn main() !void { try writer.writeAll("pub const X64 = enum(usize) {\n"); const table = try linux_dir.readFile("arch/x86/entry/syscalls/syscall_64.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; const abi = fields.next() orelse return error.Incomplete; // The x32 abi syscalls are always at the end. @@ -96,11 +96,11 @@ pub fn main() !void { ); const table = try linux_dir.readFile("arch/arm/tools/syscall.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; const abi = fields.next() orelse return error.Incomplete; if (mem.eql(u8, abi, "oabi")) continue; @@ -127,11 +127,11 @@ pub fn main() !void { { try writer.writeAll("pub const Sparc64 = enum(usize) {\n"); const table = try linux_dir.readFile("arch/sparc/kernel/syscalls/syscall.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; const abi = fields.next() orelse return error.Incomplete; if (mem.eql(u8, abi, "32")) continue; @@ -151,11 +151,11 @@ pub fn main() !void { ); const table = try linux_dir.readFile("arch/mips/kernel/syscalls/syscall_o32.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; // abi is always o32 _ = fields.next() orelse return error.Incomplete; @@ -176,11 +176,11 @@ pub fn main() !void { ); const table = try linux_dir.readFile("arch/mips/kernel/syscalls/syscall_n64.tbl", buf); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; // abi is always n64 _ = fields.next() orelse return error.Incomplete; @@ -197,11 +197,11 @@ pub fn main() !void { const table = try linux_dir.readFile("arch/powerpc/kernel/syscalls/syscall.tbl", buf); var list_64 = std.ArrayList(u8).init(allocator); - var lines = mem.tokenize(u8, table, "\n"); + var lines = mem.tokenizeScalar(u8, table, '\n'); while (lines.next()) |line| { if (line[0] == '#') continue; - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const number = fields.next() orelse return error.Incomplete; const abi = fields.next() orelse return error.Incomplete; const name = fields.next() orelse return error.Incomplete; @@ -277,9 +277,9 @@ pub fn main() !void { }, }; - var lines = mem.tokenize(u8, defines, "\n"); + var lines = mem.tokenizeScalar(u8, defines, '\n'); loop: while (lines.next()) |line| { - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const cmd = fields.next() orelse return error.Incomplete; if (!mem.eql(u8, cmd, "#define")) continue; const define = fields.next() orelse return error.Incomplete; @@ -339,9 +339,9 @@ pub fn main() !void { }, }; - var lines = mem.tokenize(u8, defines, "\n"); + var lines = mem.tokenizeScalar(u8, defines, '\n'); loop: while (lines.next()) |line| { - var fields = mem.tokenize(u8, line, " \t"); + var fields = mem.tokenizeAny(u8, line, " \t"); const cmd = fields.next() orelse return error.Incomplete; if (!mem.eql(u8, cmd, "#define")) continue; const define = fields.next() orelse return error.Incomplete; -- cgit v1.2.3 From 40e8c2243c139dc499298645a2b387e30ae09cba Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Tue, 16 May 2023 20:21:31 +0100 Subject: std.c: darwin's *copyfile api update. --- lib/std/c/darwin.zig | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---- lib/std/fs.zig | 2 +- 2 files changed, 60 insertions(+), 6 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index e127bf113c..f0da52a86a 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -163,13 +163,67 @@ pub extern "c" fn _dyld_get_image_header(image_index: u32) ?*mach_header; pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize; pub extern "c" fn _dyld_get_image_name(image_index: u32) [*:0]const u8; -pub const COPYFILE_ACL = 1 << 0; -pub const COPYFILE_STAT = 1 << 1; -pub const COPYFILE_XATTR = 1 << 2; -pub const COPYFILE_DATA = 1 << 3; +pub const COPYFILE = struct { + pub const ACL = 1 << 0; + pub const STAT = 1 << 1; + pub const XATTR = 1 << 2; + pub const DATA = 1 << 3; + pub const SECURITY = COPYFILE.STAT | COPYFILE.ACL; + pub const METADATA = COPYFILE.SECURITY | COPYFILE.XATTR; + pub const ALL = COPYFILE.METADATA | COPYFILE.DATA; + pub const RECURSIVE = 1 << 15; + pub const CHECK = 1 << 16; + pub const EXCL = 1 << 17; + pub const NOFOLLOW_SRC = 1 << 18; + pub const NOFOLLOW_DST = 1 << 19; + pub const MOVE = 1 << 20; + pub const UNLINK = 1 << 21; + pub const NOFOLLOW = COPYFILE.NOFOLLOW_SRC | NOFOLLOW_DST; + pub const PACK = 1 << 22; + pub const UNPACK = 1 << 23; + pub const CLONE = 1 << 24; + pub const CLONE_FORCE = 1 << 25; + pub const RUN_IN_PLACE = 1 << 26; + pub const DATA_SPARSE = 1 << 27; + pub const PRESERVE_DST_TRACKED = 1 << 28; + pub const VERBOSE = 1 << 30; + pub const RECURSE_ERROR = 0; + pub const RECURSE_FILE = 1; + pub const RECURSE_DIR = 2; + pub const RECURSE_DIR_CLEANUP = 3; + pub const COPY_DATA = 4; + pub const COPY_XATTR = 5; + pub const START = 1; + pub const FINISH = 2; + pub const ERR = 3; + pub const PROGRESS = 4; + pub const CONTINUE = 0; + pub const SKIP = 1; + pub const QUIT = 2; + pub const STATE_SRC_FD = 1; + pub const STATE_SRC_FILENAME = 2; + pub const STATE_DST_FD = 3; + pub const STATE_DST_FILENAME = 4; + pub const STATE_QUARANTINE = 5; + pub const STATE_STATUS_CB = 6; + pub const STATE_STATUS_CTX = 7; + pub const STATE_COPIED = 8; + pub const STATE_XATTRNAME = 9; + pub const STATE_WAS_CLONED = 10; + pub const STATE_SRC_BSIZE = 11; + pub const STATE_DST_BSIZE = 12; + pub const STATE_BSIZE = 13; + pub const DISABLE_VAR: [*]u8 = "COPYFILE_DISABLE"; +}; pub const copyfile_state_t = *opaque {}; -pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: u32) c_int; +pub const copyfile_flags_t = u32; +pub extern "c" fn fcopyfile(from: fd_t, to: fd_t, state: ?copyfile_state_t, flags: copyfile_flags_t) c_int; +pub extern "c" fn copyfile(from: [*:0]u8, to: [*:0]u8, state: ?copyfile_state_t, flags: copyfile_flags_t) c_int; +pub extern "c" fn copyfile_state_alloc() copyfile_state_t; +pub extern "c" fn copyfile_state_free(state: copyfile_state_t) void; +pub extern "c" fn copyfile_state_get(s: copyfile_state_t, flag: u32, dst: ?*anyopaque) c_int; +pub extern "c" fn copyfile_state_set(s: copyfile_state_t, flag: u32, dst: ?*const anyopaque) c_int; pub extern "c" fn @"realpath$DARWIN_EXTSN"(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8; pub const realpath = @"realpath$DARWIN_EXTSN"; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 7327a3a913..041e49d549 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -3102,7 +3102,7 @@ const CopyFileRawError = error{SystemResources} || os.CopyFileRangeError || os.S // No metadata is transferred over. fn copy_file(fd_in: os.fd_t, fd_out: os.fd_t, maybe_size: ?u64) CopyFileRawError!void { if (comptime builtin.target.isDarwin()) { - const rc = os.system.fcopyfile(fd_in, fd_out, null, os.system.COPYFILE_DATA); + const rc = os.system.fcopyfile(fd_in, fd_out, null, os.system.COPYFILE.DATA); switch (os.errno(rc)) { .SUCCESS => return, .INVAL => unreachable, -- cgit v1.2.3 From 4159add4abe92e903d8797a005344d8325def2fc Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sat, 20 May 2023 23:06:42 +0100 Subject: std.fs.file: Rename File.Kind enum values to snake case --- lib/std/Build/Step/InstallDir.zig | 4 +- lib/std/crypto/Certificate/Bundle.zig | 2 +- lib/std/fs.zig | 132 +++++++++++++++++----------------- lib/std/fs/file.zig | 120 +++++++++++++++---------------- lib/std/fs/test.zig | 20 +++--- src/Package.zig | 4 +- src/main.zig | 6 +- test/src/Cases.zig | 4 +- tools/process_headers.zig | 4 +- tools/update-linux-headers.zig | 4 +- tools/update_glibc.zig | 4 +- tools/update_spirv_features.zig | 2 +- 12 files changed, 153 insertions(+), 153 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/Build/Step/InstallDir.zig b/lib/std/Build/Step/InstallDir.zig index 28280dcb7f..597601ce4e 100644 --- a/lib/std/Build/Step/InstallDir.zig +++ b/lib/std/Build/Step/InstallDir.zig @@ -80,8 +80,8 @@ fn make(step: *Step, prog_node: *std.Progress.Node) !void { const cwd = fs.cwd(); switch (entry.kind) { - .Directory => try cwd.makePath(dest_path), - .File => { + .directory => try cwd.makePath(dest_path), + .file => { for (self.options.blank_extensions) |ext| { if (mem.endsWith(u8, entry.path, ext)) { try dest_builder.truncateFile(dest_path); diff --git a/lib/std/crypto/Certificate/Bundle.zig b/lib/std/crypto/Certificate/Bundle.zig index fe1ef4c0c3..434de6e0a8 100644 --- a/lib/std/crypto/Certificate/Bundle.zig +++ b/lib/std/crypto/Certificate/Bundle.zig @@ -169,7 +169,7 @@ pub fn addCertsFromDir(cb: *Bundle, gpa: Allocator, iterable_dir: fs.IterableDir var it = iterable_dir.iterate(); while (try it.next()) |entry| { switch (entry.kind) { - .File, .SymLink => {}, + .file, .sym_link => {}, else => continue, } diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 041e49d549..496dbf5f0a 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -385,16 +385,16 @@ pub const IterableDir = struct { continue :start_over; } - const entry_kind = switch (darwin_entry.d_type) { - os.DT.BLK => Entry.Kind.BlockDevice, - os.DT.CHR => Entry.Kind.CharacterDevice, - os.DT.DIR => Entry.Kind.Directory, - os.DT.FIFO => Entry.Kind.NamedPipe, - os.DT.LNK => Entry.Kind.SymLink, - os.DT.REG => Entry.Kind.File, - os.DT.SOCK => Entry.Kind.UnixDomainSocket, - os.DT.WHT => Entry.Kind.Whiteout, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (darwin_entry.d_type) { + os.DT.BLK => .block_device, + os.DT.CHR => .character_device, + os.DT.DIR => .directory, + os.DT.FIFO => .named_pipe, + os.DT.LNK => .sym_link, + os.DT.REG => .file, + os.DT.SOCK => .unix_domain_socket, + os.DT.WHT => .whiteout, + else => .unknown, }; return Entry{ .name = name, @@ -442,17 +442,17 @@ pub const IterableDir = struct { error.FileNotFound => unreachable, // lost the race else => |e| return e, }; - const entry_kind = switch (stat_info.mode & os.S.IFMT) { - os.S.IFIFO => Entry.Kind.NamedPipe, - os.S.IFCHR => Entry.Kind.CharacterDevice, - os.S.IFDIR => Entry.Kind.Directory, - os.S.IFBLK => Entry.Kind.BlockDevice, - os.S.IFREG => Entry.Kind.File, - os.S.IFLNK => Entry.Kind.SymLink, - os.S.IFSOCK => Entry.Kind.UnixDomainSocket, - os.S.IFDOOR => Entry.Kind.Door, - os.S.IFPORT => Entry.Kind.EventPort, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (stat_info.mode & os.S.IFMT) { + os.S.IFIFO => .named_pipe, + os.S.IFCHR => .character_device, + os.S.IFDIR => .directory, + os.S.IFBLK => .block_device, + os.S.IFREG => .file, + os.S.IFLNK => .sym_link, + os.S.IFSOCK => .unix_domain_socket, + os.S.IFDOOR => .door, + os.S.IFPORT => .event_port, + else => .unknown, }; return Entry{ .name = name, @@ -501,16 +501,16 @@ pub const IterableDir = struct { continue :start_over; } - const entry_kind = switch (bsd_entry.d_type) { - os.DT.BLK => Entry.Kind.BlockDevice, - os.DT.CHR => Entry.Kind.CharacterDevice, - os.DT.DIR => Entry.Kind.Directory, - os.DT.FIFO => Entry.Kind.NamedPipe, - os.DT.LNK => Entry.Kind.SymLink, - os.DT.REG => Entry.Kind.File, - os.DT.SOCK => Entry.Kind.UnixDomainSocket, - os.DT.WHT => Entry.Kind.Whiteout, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (bsd_entry.d_type) { + os.DT.BLK => .block_device, + os.DT.CHR => .character_device, + os.DT.DIR => .directory, + os.DT.FIFO => .named_pipe, + os.DT.LNK => .sym_link, + os.DT.REG => .file, + os.DT.SOCK => .unix_domain_socket, + os.DT.WHT => .whiteout, + else => .unknown, }; return Entry{ .name = name, @@ -595,14 +595,14 @@ pub const IterableDir = struct { } const statmode = stat_info.mode & os.S.IFMT; - const entry_kind = switch (statmode) { - os.S.IFDIR => Entry.Kind.Directory, - os.S.IFBLK => Entry.Kind.BlockDevice, - os.S.IFCHR => Entry.Kind.CharacterDevice, - os.S.IFLNK => Entry.Kind.SymLink, - os.S.IFREG => Entry.Kind.File, - os.S.IFIFO => Entry.Kind.NamedPipe, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (statmode) { + os.S.IFDIR => .directory, + os.S.IFBLK => .block_device, + os.S.IFCHR => .character_device, + os.S.IFLNK => .sym_link, + os.S.IFREG => .file, + os.S.IFIFO => .named_pipe, + else => .unknown, }; return Entry{ @@ -679,15 +679,15 @@ pub const IterableDir = struct { continue :start_over; } - const entry_kind = switch (linux_entry.d_type) { - linux.DT.BLK => Entry.Kind.BlockDevice, - linux.DT.CHR => Entry.Kind.CharacterDevice, - linux.DT.DIR => Entry.Kind.Directory, - linux.DT.FIFO => Entry.Kind.NamedPipe, - linux.DT.LNK => Entry.Kind.SymLink, - linux.DT.REG => Entry.Kind.File, - linux.DT.SOCK => Entry.Kind.UnixDomainSocket, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (linux_entry.d_type) { + linux.DT.BLK => .block_device, + linux.DT.CHR => .character_device, + linux.DT.DIR => .directory, + linux.DT.FIFO => .named_pipe, + linux.DT.LNK => .sym_link, + linux.DT.REG => .file, + linux.DT.SOCK => .unix_domain_socket, + else => .unknown, }; return Entry{ .name = name, @@ -761,11 +761,11 @@ pub const IterableDir = struct { // Trust that Windows gives us valid UTF-16LE const name_utf8_len = std.unicode.utf16leToUtf8(self.name_data[0..], name_utf16le) catch unreachable; const name_utf8 = self.name_data[0..name_utf8_len]; - const kind = blk: { + const kind: Entry.Kind = blk: { const attrs = dir_info.FileAttributes; - if (attrs & w.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk Entry.Kind.Directory; - if (attrs & w.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk Entry.Kind.SymLink; - break :blk Entry.Kind.File; + if (attrs & w.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk .directory; + if (attrs & w.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk .sym_link; + break :blk .file; }; return Entry{ .name = name_utf8, @@ -850,14 +850,14 @@ pub const IterableDir = struct { continue :start_over; } - const entry_kind = switch (entry.d_type) { - .BLOCK_DEVICE => Entry.Kind.BlockDevice, - .CHARACTER_DEVICE => Entry.Kind.CharacterDevice, - .DIRECTORY => Entry.Kind.Directory, - .SYMBOLIC_LINK => Entry.Kind.SymLink, - .REGULAR_FILE => Entry.Kind.File, - .SOCKET_STREAM, .SOCKET_DGRAM => Entry.Kind.UnixDomainSocket, - else => Entry.Kind.Unknown, + const entry_kind: Entry.Kind = switch (entry.d_type) { + .BLOCK_DEVICE => .block_device, + .CHARACTER_DEVICE => .character_device, + .DIRECTORY => .directory, + .SYMBOLIC_LINK => .sym_link, + .REGULAR_FILE => .file, + .SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket, + else => .unknown, }; return Entry{ .name = name, @@ -964,7 +964,7 @@ pub const IterableDir = struct { dirname_len += 1; } try self.name_buffer.appendSlice(base.name); - if (base.kind == .Directory) { + if (base.kind == .directory) { var new_dir = top.iter.dir.openIterableDir(base.name, .{}) catch |err| switch (err) { error.NameTooLong => unreachable, // no path sep in base.name else => |e| return e, @@ -2106,7 +2106,7 @@ pub const Dir = struct { /// this function recursively removes its entries and then tries again. /// This operation is not atomic on most file systems. pub fn deleteTree(self: Dir, sub_path: []const u8) DeleteTreeError!void { - var initial_iterable_dir = (try self.deleteTreeOpenInitialSubpath(sub_path, .File)) orelse return; + var initial_iterable_dir = (try self.deleteTreeOpenInitialSubpath(sub_path, .file)) orelse return; const StackItem = struct { name: []const u8, @@ -2130,7 +2130,7 @@ pub const Dir = struct { process_stack: while (stack.len != 0) { var top = &(stack.slice()[stack.len - 1]); while (try top.iter.next()) |entry| { - var treat_as_dir = entry.kind == .Directory; + var treat_as_dir = entry.kind == .directory; handle_entry: while (true) { if (treat_as_dir) { if (stack.ensureUnusedCapacity(1)) { @@ -2291,7 +2291,7 @@ pub const Dir = struct { /// Like `deleteTree`, but only keeps one `Iterator` active at a time to minimize the function's stack size. /// This is slower than `deleteTree` but uses less stack space. pub fn deleteTreeMinStackSize(self: Dir, sub_path: []const u8) DeleteTreeError!void { - return self.deleteTreeMinStackSizeWithKindHint(sub_path, .File); + return self.deleteTreeMinStackSizeWithKindHint(sub_path, .file); } fn deleteTreeMinStackSizeWithKindHint(self: Dir, sub_path: []const u8, kind_hint: File.Kind) DeleteTreeError!void { @@ -2316,7 +2316,7 @@ pub const Dir = struct { scan_dir: while (true) { var dir_it = iterable_dir.iterateAssumeFirstIteration(); dir_it: while (try dir_it.next()) |entry| { - var treat_as_dir = entry.kind == .Directory; + var treat_as_dir = entry.kind == .directory; handle_entry: while (true) { if (treat_as_dir) { const new_dir = iterable_dir.dir.openIterableDir(entry.name, .{ .no_follow = true }) catch |err| switch (err) { @@ -2407,7 +2407,7 @@ pub const Dir = struct { fn deleteTreeOpenInitialSubpath(self: Dir, sub_path: []const u8, kind_hint: File.Kind) !?IterableDir { return iterable_dir: { // Treat as a file by default - var treat_as_dir = kind_hint == .Directory; + var treat_as_dir = kind_hint == .directory; handle_entry: while (true) { if (treat_as_dir) { diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 23021a26f5..83db10ef32 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -35,17 +35,17 @@ pub const File = struct { pub const Gid = os.gid_t; pub const Kind = enum { - BlockDevice, - CharacterDevice, - Directory, - NamedPipe, - SymLink, - File, - UnixDomainSocket, - Whiteout, - Door, - EventPort, - Unknown, + block_device, + character_device, + directory, + named_pipe, + sym_link, + file, + unix_domain_socket, + whiteout, + door, + event_port, + unknown, }; /// This is the default mode given to POSIX operating systems for creating @@ -329,32 +329,32 @@ pub const File = struct { const mtime = st.mtime(); const ctime = st.ctime(); const kind: Kind = if (builtin.os.tag == .wasi and !builtin.link_libc) switch (st.filetype) { - .BLOCK_DEVICE => Kind.BlockDevice, - .CHARACTER_DEVICE => Kind.CharacterDevice, - .DIRECTORY => Kind.Directory, - .SYMBOLIC_LINK => Kind.SymLink, - .REGULAR_FILE => Kind.File, - .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, - else => Kind.Unknown, + .BLOCK_DEVICE => .block_device, + .CHARACTER_DEVICE => .character_device, + .DIRECTORY => .directory, + .SYMBOLIC_LINK => .sym_link, + .REGULAR_FILE => .file, + .SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket, + else => .unknown, } else blk: { const m = st.mode & os.S.IFMT; switch (m) { - os.S.IFBLK => break :blk Kind.BlockDevice, - os.S.IFCHR => break :blk Kind.CharacterDevice, - os.S.IFDIR => break :blk Kind.Directory, - os.S.IFIFO => break :blk Kind.NamedPipe, - os.S.IFLNK => break :blk Kind.SymLink, - os.S.IFREG => break :blk Kind.File, - os.S.IFSOCK => break :blk Kind.UnixDomainSocket, + os.S.IFBLK => break :blk .block_device, + os.S.IFCHR => break :blk .character_device, + os.S.IFDIR => break :blk .directory, + os.S.IFIFO => break :blk .named_pipe, + os.S.IFLNK => break :blk .sym_link, + os.S.IFREG => break :blk .file, + os.S.IFSOCK => break :blk .unix_domain_socket, else => {}, } if (builtin.os.tag == .solaris) switch (m) { - os.S.IFDOOR => break :blk Kind.Door, - os.S.IFPORT => break :blk Kind.EventPort, + os.S.IFDOOR => break :blk .door, + os.S.IFPORT => break :blk .event_port, else => {}, }; - break :blk .Unknown; + break :blk .unknown; }; return Stat{ @@ -391,7 +391,7 @@ pub const File = struct { .inode = info.InternalInformation.IndexNumber, .size = @bitCast(u64, info.StandardInformation.EndOfFile), .mode = 0, - .kind = if (info.StandardInformation.Directory == 0) .File else .Directory, + .kind = if (info.StandardInformation.Directory == 0) .file else .directory, .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime), .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime), .ctime = windows.fromSysTime(info.BasicInformation.CreationTime), @@ -609,7 +609,7 @@ pub const File = struct { } /// Returns the `Kind` of file. - /// On Windows, can only return: `.File`, `.Directory`, `.SymLink` or `.Unknown` + /// On Windows, can only return: `.file`, `.directory`, `.sym_link` or `.unknown` pub fn kind(self: Self) Kind { return self.inner.kind(); } @@ -652,35 +652,35 @@ pub const File = struct { /// Returns the `Kind` of the file pub fn kind(self: Self) Kind { if (builtin.os.tag == .wasi and !builtin.link_libc) return switch (self.stat.filetype) { - .BLOCK_DEVICE => Kind.BlockDevice, - .CHARACTER_DEVICE => Kind.CharacterDevice, - .DIRECTORY => Kind.Directory, - .SYMBOLIC_LINK => Kind.SymLink, - .REGULAR_FILE => Kind.File, - .SOCKET_STREAM, .SOCKET_DGRAM => Kind.UnixDomainSocket, - else => Kind.Unknown, + .BLOCK_DEVICE => .block_device, + .CHARACTER_DEVICE => .character_device, + .DIRECTORY => .directory, + .SYMBOLIC_LINK => .sym_link, + .REGULAR_FILE => .file, + .SOCKET_STREAM, .SOCKET_DGRAM => .unix_domain_socket, + else => .unknown, }; const m = self.stat.mode & os.S.IFMT; switch (m) { - os.S.IFBLK => return Kind.BlockDevice, - os.S.IFCHR => return Kind.CharacterDevice, - os.S.IFDIR => return Kind.Directory, - os.S.IFIFO => return Kind.NamedPipe, - os.S.IFLNK => return Kind.SymLink, - os.S.IFREG => return Kind.File, - os.S.IFSOCK => return Kind.UnixDomainSocket, + os.S.IFBLK => return .block_device, + os.S.IFCHR => return .character_device, + os.S.IFDIR => return .directory, + os.S.IFIFO => return .named_pipe, + os.S.IFLNK => return .sym_link, + os.S.IFREG => return .file, + os.S.IFSOCK => return .unix_domain_socket, else => {}, } if (builtin.os.tag == .solaris) switch (m) { - os.S.IFDOOR => return Kind.Door, - os.S.IFPORT => return Kind.EventPort, + os.S.IFDOOR => return .door, + os.S.IFPORT => return .event_port, else => {}, }; - return .Unknown; + return .unknown; } /// Returns the last time the file was accessed in nanoseconds since UTC 1970-01-01 @@ -738,17 +738,17 @@ pub const File = struct { const m = self.statx.mode & os.S.IFMT; switch (m) { - os.S.IFBLK => return Kind.BlockDevice, - os.S.IFCHR => return Kind.CharacterDevice, - os.S.IFDIR => return Kind.Directory, - os.S.IFIFO => return Kind.NamedPipe, - os.S.IFLNK => return Kind.SymLink, - os.S.IFREG => return Kind.File, - os.S.IFSOCK => return Kind.UnixDomainSocket, + os.S.IFBLK => return .block_device, + os.S.IFCHR => return .character_device, + os.S.IFDIR => return .directory, + os.S.IFIFO => return .named_pipe, + os.S.IFLNK => return .sym_link, + os.S.IFREG => return .file, + os.S.IFSOCK => return .unix_domain_socket, else => {}, } - return .Unknown; + return .unknown; } /// Returns the last time the file was accessed in nanoseconds since UTC 1970-01-01 @@ -790,18 +790,18 @@ pub const File = struct { } /// Returns the `Kind` of the file. - /// Can only return: `.File`, `.Directory`, `.SymLink` or `.Unknown` + /// Can only return: `.file`, `.directory`, `.sym_link` or `.unknown` pub fn kind(self: Self) Kind { if (self.attributes & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) { if (self.reparse_tag & 0x20000000 != 0) { - return .SymLink; + return .sym_link; } } else if (self.attributes & windows.FILE_ATTRIBUTE_DIRECTORY != 0) { - return .Directory; + return .directory; } else { - return .File; + return .file; } - return .Unknown; + return .unknown; } /// Returns the last time the file was accessed in nanoseconds since UTC 1970-01-01 diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 15c8307f58..16677007f9 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -179,8 +179,8 @@ test "Dir.Iterator" { } try testing.expect(entries.items.len == 2); // note that the Iterator skips '.' and '..' - try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .File })); - try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .Directory })); + try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .file })); + try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .directory })); } test "Dir.Iterator many entries" { @@ -214,7 +214,7 @@ test "Dir.Iterator many entries" { i = 0; while (i < num) : (i += 1) { const name = try std.fmt.bufPrint(&buf, "{}", .{i}); - try testing.expect(contains(&entries, .{ .name = name, .kind = .File })); + try testing.expect(contains(&entries, .{ .name = name, .kind = .file })); } } @@ -246,8 +246,8 @@ test "Dir.Iterator twice" { } try testing.expect(entries.items.len == 2); // note that the Iterator skips '.' and '..' - try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .File })); - try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .Directory })); + try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .file })); + try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .directory })); } } @@ -280,8 +280,8 @@ test "Dir.Iterator reset" { } try testing.expect(entries.items.len == 2); // note that the Iterator skips '.' and '..' - try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .File })); - try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .Directory })); + try testing.expect(contains(&entries, .{ .name = "some_file", .kind = .file })); + try testing.expect(contains(&entries, .{ .name = "some_dir", .kind = .directory })); iter.reset(); } @@ -428,7 +428,7 @@ test "directory operations on files" { // ensure the file still exists and is a file as a sanity check file = try tmp_dir.dir.openFile(test_file_name, .{}); const stat = try file.stat(); - try testing.expect(stat.kind == .File); + try testing.expect(stat.kind == .file); file.close(); } @@ -664,7 +664,7 @@ test "renameAbsolute" { try testing.expectError(error.FileNotFound, tmp_dir.dir.openFile(test_file_name, .{})); file = try tmp_dir.dir.openFile(renamed_test_file_name, .{}); const stat = try file.stat(); - try testing.expect(stat.kind == .File); + try testing.expect(stat.kind == .file); file.close(); // Renaming directories @@ -1348,7 +1348,7 @@ test "File.Metadata" { defer file.close(); const metadata = try file.metadata(); - try testing.expect(metadata.kind() == .File); + try testing.expect(metadata.kind() == .file); try testing.expect(metadata.size() == 0); _ = metadata.accessed(); _ = metadata.modified(); diff --git a/src/Package.zig b/src/Package.zig index d3ac71af1a..532439c60c 100644 --- a/src/Package.zig +++ b/src/Package.zig @@ -651,8 +651,8 @@ fn computePackageHash( while (try walker.next()) |entry| { switch (entry.kind) { - .Directory => continue, - .File => {}, + .directory => continue, + .file => {}, else => return error.IllegalFileTypeInPackage, } const hashed_file = try arena.create(HashedFile); diff --git a/src/main.zig b/src/main.zig index afda88cebd..f7afbe767b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -4830,11 +4830,11 @@ fn fmtPathDir( var dir_it = iterable_dir.iterate(); while (try dir_it.next()) |entry| { - const is_dir = entry.kind == .Directory; + const is_dir = entry.kind == .directory; if (is_dir and (mem.eql(u8, entry.name, "zig-cache") or mem.eql(u8, entry.name, "zig-out"))) continue; - if (is_dir or entry.kind == .File and (mem.endsWith(u8, entry.name, ".zig") or mem.endsWith(u8, entry.name, ".zon"))) { + if (is_dir or entry.kind == .file and (mem.endsWith(u8, entry.name, ".zig") or mem.endsWith(u8, entry.name, ".zon"))) { const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); defer fmt.gpa.free(full_path); @@ -4864,7 +4864,7 @@ fn fmtPathFile( const stat = try source_file.stat(); - if (stat.kind == .Directory) + if (stat.kind == .directory) return error.IsDir; const gpa = fmt.gpa; diff --git a/test/src/Cases.zig b/test/src/Cases.zig index e4f3d532ce..589438297d 100644 --- a/test/src/Cases.zig +++ b/test/src/Cases.zig @@ -349,7 +349,7 @@ fn addFromDirInner( var filenames = std.ArrayList([]const u8).init(ctx.arena); while (try it.next()) |entry| { - if (entry.kind != .File) continue; + if (entry.kind != .file) continue; // Ignore stuff such as .swp files switch (Compilation.classifyFileExt(entry.basename)) { @@ -1039,7 +1039,7 @@ pub fn main() !void { const stem = case_file_path[case_dirname.len + 1 .. case_file_path.len - "0.zig".len]; var it = iterable_dir.iterate(); while (try it.next()) |entry| { - if (entry.kind != .File) continue; + if (entry.kind != .file) continue; if (!std.mem.startsWith(u8, entry.name, stem)) continue; try filenames.append(try std.fs.path.join(arena, &.{ case_dirname, entry.name })); } diff --git a/tools/process_headers.zig b/tools/process_headers.zig index 0321c0e0eb..b93cd07a2c 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -393,8 +393,8 @@ pub fn main() !void { while (try dir_it.next()) |entry| { const full_path = try std.fs.path.join(allocator, &[_][]const u8{ full_dir_name, entry.name }); switch (entry.kind) { - .Directory => try dir_stack.append(full_path), - .File => { + .directory => try dir_stack.append(full_path), + .file => { const rel_path = try std.fs.path.relative(allocator, target_include_dir, full_path); const max_size = 2 * 1024 * 1024 * 1024; const raw_bytes = try std.fs.cwd().readFileAlloc(allocator, full_path, max_size); diff --git a/tools/update-linux-headers.zig b/tools/update-linux-headers.zig index 0f31e5e893..d20bc8dd11 100644 --- a/tools/update-linux-headers.zig +++ b/tools/update-linux-headers.zig @@ -193,8 +193,8 @@ pub fn main() !void { while (try dir_it.next()) |entry| { const full_path = try std.fs.path.join(arena, &[_][]const u8{ full_dir_name, entry.name }); switch (entry.kind) { - .Directory => try dir_stack.append(full_path), - .File => { + .directory => try dir_stack.append(full_path), + .file => { const rel_path = try std.fs.path.relative(arena, target_include_dir, full_path); const max_size = 2 * 1024 * 1024 * 1024; const raw_bytes = try std.fs.cwd().readFileAlloc(arena, full_path, max_size); diff --git a/tools/update_glibc.zig b/tools/update_glibc.zig index 24b0f45de7..dcc797f59f 100644 --- a/tools/update_glibc.zig +++ b/tools/update_glibc.zig @@ -57,7 +57,7 @@ pub fn main() !void { defer walker.deinit(); walk: while (try walker.next()) |entry| { - if (entry.kind != .File) continue; + if (entry.kind != .file) continue; if (mem.startsWith(u8, entry.basename, ".")) continue; for (exempt_files) |p| { if (mem.eql(u8, entry.path, p)) continue :walk; @@ -98,7 +98,7 @@ pub fn main() !void { defer walker.deinit(); walk: while (try walker.next()) |entry| { - if (entry.kind != .File) continue; + if (entry.kind != .file) continue; if (mem.startsWith(u8, entry.basename, ".")) continue; for (exempt_files) |p| { if (mem.eql(u8, entry.path, p)) continue :walk; diff --git a/tools/update_spirv_features.zig b/tools/update_spirv_features.zig index 44d8b6a445..31bdf40ef7 100644 --- a/tools/update_spirv_features.zig +++ b/tools/update_spirv_features.zig @@ -227,7 +227,7 @@ fn gather_extensions(allocator: Allocator, spirv_registry_root: []const u8) ![]c var vendor_it = extensions_dir.iterate(); while (try vendor_it.next()) |vendor_entry| { - std.debug.assert(vendor_entry.kind == .Directory); // If this fails, the structure of SPIRV-Registry has changed. + std.debug.assert(vendor_entry.kind == .directory); // If this fails, the structure of SPIRV-Registry has changed. const vendor_dir = try extensions_dir.dir.openIterableDir(vendor_entry.name, .{}); var ext_it = vendor_dir.iterate(); -- cgit v1.2.3 From ba35eeb417e4d54ce4c559871b9330bc95afc053 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sat, 20 May 2023 23:11:53 +0100 Subject: std.fs.file: Rename File.Lock enum values to snake case --- lib/std/Build/Cache.zig | 6 +++--- lib/std/fs.zig | 40 ++++++++++++++++++++-------------------- lib/std/fs/file.zig | 34 +++++++++++++++++++--------------- lib/std/fs/test.zig | 22 +++++++++++----------- src/Module.zig | 8 ++++---- 5 files changed, 57 insertions(+), 53 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index e991aff5b5..4db8f18a31 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -408,7 +408,7 @@ pub const Manifest = struct { if (self.cache.manifest_dir.createFile(&manifest_file_path, .{ .read = true, .truncate = false, - .lock = .Exclusive, + .lock = .exclusive, .lock_nonblocking = self.want_shared_lock, })) |manifest_file| { self.manifest_file = manifest_file; @@ -418,7 +418,7 @@ pub const Manifest = struct { error.WouldBlock => { self.manifest_file = try self.cache.manifest_dir.openFile(&manifest_file_path, .{ .mode = .read_write, - .lock = .Shared, + .lock = .shared, }); break; }, @@ -885,7 +885,7 @@ pub const Manifest = struct { // Here we intentionally have a period where the lock is released, in case there are // other processes holding a shared lock. manifest_file.unlock(); - try manifest_file.lock(.Exclusive); + try manifest_file.lock(.exclusive); } self.have_exclusive_lock = true; return true; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 496dbf5f0a..6ab2dbaa7f 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -1157,9 +1157,9 @@ pub const Dir = struct { else 0; os_flags |= switch (flags.lock) { - .None => @as(u32, 0), - .Shared => os.O.SHLOCK | nonblocking_lock_flag, - .Exclusive => os.O.EXLOCK | nonblocking_lock_flag, + .none => @as(u32, 0), + .shared => os.O.SHLOCK | nonblocking_lock_flag, + .exclusive => os.O.EXLOCK | nonblocking_lock_flag, }; } if (@hasDecl(os.O, "LARGEFILE")) { @@ -1182,13 +1182,13 @@ pub const Dir = struct { // WASI doesn't have os.flock so we intetinally check OS prior to the inner if block // since it is not compiltime-known and we need to avoid undefined symbol in Wasm. if (builtin.target.os.tag != .wasi) { - if (!has_flock_open_flags and flags.lock != .None) { + if (!has_flock_open_flags and flags.lock != .none) { // TODO: integrate async I/O const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK.NB else @as(i32, 0); try os.flock(fd, switch (flags.lock) { - .None => unreachable, - .Shared => os.LOCK.SH | lock_nonblocking, - .Exclusive => os.LOCK.EX | lock_nonblocking, + .none => unreachable, + .shared => os.LOCK.SH | lock_nonblocking, + .exclusive => os.LOCK.EX | lock_nonblocking, }); } } @@ -1241,9 +1241,9 @@ pub const Dir = struct { const range_off: w.LARGE_INTEGER = 0; const range_len: w.LARGE_INTEGER = 1; const exclusive = switch (flags.lock) { - .None => return file, - .Shared => false, - .Exclusive => true, + .none => return file, + .shared => false, + .exclusive => true, }; try w.LockFile( file.handle, @@ -1320,9 +1320,9 @@ pub const Dir = struct { else 0; const lock_flag: u32 = if (has_flock_open_flags) switch (flags.lock) { - .None => @as(u32, 0), - .Shared => os.O.SHLOCK | nonblocking_lock_flag, - .Exclusive => os.O.EXLOCK | nonblocking_lock_flag, + .none => @as(u32, 0), + .shared => os.O.SHLOCK | nonblocking_lock_flag, + .exclusive => os.O.EXLOCK | nonblocking_lock_flag, } else 0; const O_LARGEFILE = if (@hasDecl(os.O, "LARGEFILE")) os.O.LARGEFILE else 0; @@ -1339,13 +1339,13 @@ pub const Dir = struct { // WASI doesn't have os.flock so we intetinally check OS prior to the inner if block // since it is not compiltime-known and we need to avoid undefined symbol in Wasm. if (builtin.target.os.tag != .wasi) { - if (!has_flock_open_flags and flags.lock != .None) { + if (!has_flock_open_flags and flags.lock != .none) { // TODO: integrate async I/O const lock_nonblocking = if (flags.lock_nonblocking) os.LOCK.NB else @as(i32, 0); try os.flock(fd, switch (flags.lock) { - .None => unreachable, - .Shared => os.LOCK.SH | lock_nonblocking, - .Exclusive => os.LOCK.EX | lock_nonblocking, + .none => unreachable, + .shared => os.LOCK.SH | lock_nonblocking, + .exclusive => os.LOCK.EX | lock_nonblocking, }); } } @@ -1402,9 +1402,9 @@ pub const Dir = struct { const range_off: w.LARGE_INTEGER = 0; const range_len: w.LARGE_INTEGER = 1; const exclusive = switch (flags.lock) { - .None => return file, - .Shared => false, - .Exclusive => true, + .none => return file, + .shared => false, + .exclusive => true, }; try w.LockFile( file.handle, diff --git a/lib/std/fs/file.zig b/lib/std/fs/file.zig index 83db10ef32..3ed4b07a3d 100644 --- a/lib/std/fs/file.zig +++ b/lib/std/fs/file.zig @@ -81,7 +81,11 @@ pub const File = struct { read_write, }; - pub const Lock = enum { None, Shared, Exclusive }; + pub const Lock = enum { + none, + shared, + exclusive, + }; pub const OpenFlags = struct { mode: OpenMode = .read_only, @@ -110,7 +114,7 @@ pub const File = struct { /// * Windows /// /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt - lock: Lock = .None, + lock: Lock = .none, /// Sets whether or not to wait until the file is locked to return. If set to true, /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file @@ -174,7 +178,7 @@ pub const File = struct { /// * Windows /// /// [1]: https://www.kernel.org/doc/Documentation/filesystems/mandatory-locking.txt - lock: Lock = .None, + lock: Lock = .none, /// Sets whether or not to wait until the file is locked to return. If set to true, /// `error.WouldBlock` will be returned. Otherwise, the file will wait until the file @@ -1465,9 +1469,9 @@ pub const File = struct { if (is_windows) { var io_status_block: windows.IO_STATUS_BLOCK = undefined; const exclusive = switch (l) { - .None => return, - .Shared => false, - .Exclusive => true, + .none => return, + .shared => false, + .exclusive => true, }; return windows.LockFile( file.handle, @@ -1486,9 +1490,9 @@ pub const File = struct { }; } else { return os.flock(file.handle, switch (l) { - .None => os.LOCK.UN, - .Shared => os.LOCK.SH, - .Exclusive => os.LOCK.EX, + .none => os.LOCK.UN, + .shared => os.LOCK.SH, + .exclusive => os.LOCK.EX, }) catch |err| switch (err) { error.WouldBlock => unreachable, // non-blocking=false else => |e| return e, @@ -1532,9 +1536,9 @@ pub const File = struct { if (is_windows) { var io_status_block: windows.IO_STATUS_BLOCK = undefined; const exclusive = switch (l) { - .None => return, - .Shared => false, - .Exclusive => true, + .none => return, + .shared => false, + .exclusive => true, }; windows.LockFile( file.handle, @@ -1553,9 +1557,9 @@ pub const File = struct { }; } else { os.flock(file.handle, switch (l) { - .None => os.LOCK.UN, - .Shared => os.LOCK.SH | os.LOCK.NB, - .Exclusive => os.LOCK.EX | os.LOCK.NB, + .none => os.LOCK.UN, + .shared => os.LOCK.SH | os.LOCK.NB, + .exclusive => os.LOCK.EX | os.LOCK.NB, }) catch |err| switch (err) { error.WouldBlock => return false, else => |e| return e, diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 16677007f9..88796e8e4c 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -336,7 +336,7 @@ test "Dir.realpath smoke test" { var tmp_dir = tmpDir(.{}); defer tmp_dir.cleanup(); - var file = try tmp_dir.dir.createFile("test_file", .{ .lock = File.Lock.Shared }); + var file = try tmp_dir.dir.createFile("test_file", .{ .lock = .shared }); // We need to close the file immediately as otherwise on Windows we'll end up // with a sharing violation. file.close(); @@ -1035,10 +1035,10 @@ test "open file with exclusive nonblocking lock twice" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file1 = try tmp.dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); + const file1 = try tmp.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(); - const file2 = tmp.dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); + const file2 = tmp.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } @@ -1050,10 +1050,10 @@ test "open file with shared and exclusive nonblocking lock" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file1 = try tmp.dir.createFile(filename, .{ .lock = .Shared, .lock_nonblocking = true }); + const file1 = try tmp.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); defer file1.close(); - const file2 = tmp.dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); + const file2 = tmp.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } @@ -1065,10 +1065,10 @@ test "open file with exclusive and shared nonblocking lock" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file1 = try tmp.dir.createFile(filename, .{ .lock = .Exclusive, .lock_nonblocking = true }); + const file1 = try tmp.dir.createFile(filename, .{ .lock = .exclusive, .lock_nonblocking = true }); defer file1.close(); - const file2 = tmp.dir.createFile(filename, .{ .lock = .Shared, .lock_nonblocking = true }); + const file2 = tmp.dir.createFile(filename, .{ .lock = .shared, .lock_nonblocking = true }); try testing.expectError(error.WouldBlock, file2); } @@ -1085,13 +1085,13 @@ test "open file with exclusive lock twice, make sure second lock waits" { var tmp = tmpDir(.{}); defer tmp.cleanup(); - const file = try tmp.dir.createFile(filename, .{ .lock = .Exclusive }); + const file = try tmp.dir.createFile(filename, .{ .lock = .exclusive }); errdefer file.close(); const S = struct { fn checkFn(dir: *fs.Dir, started: *std.Thread.ResetEvent, locked: *std.Thread.ResetEvent) !void { started.set(); - const file1 = try dir.createFile(filename, .{ .lock = .Exclusive }); + const file1 = try dir.createFile(filename, .{ .lock = .exclusive }); locked.set(); file1.close(); @@ -1138,12 +1138,12 @@ test "open file with exclusive nonblocking lock twice (absolute paths)" { defer gpa.free(filename); const file1 = try fs.createFileAbsolute(filename, .{ - .lock = .Exclusive, + .lock = .exclusive, .lock_nonblocking = true, }); const file2 = fs.createFileAbsolute(filename, .{ - .lock = .Exclusive, + .lock = .exclusive, .lock_nonblocking = true, }); file1.close(); diff --git a/src/Module.zig b/src/Module.zig index c191fd6c7b..61843f5a8f 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -3618,7 +3618,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { file.sub_file_path, want_local_cache, &digest, }); - break :lock .Shared; + break :lock .shared; }, .parse_failure, .astgen_failure, .success_zir => lock: { const unchanged_metadata = @@ -3633,7 +3633,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void { log.debug("metadata changed: {s}", .{file.sub_file_path}); - break :lock .Exclusive; + break :lock .exclusive; }, }; @@ -3715,11 +3715,11 @@ pub fn astGenFile(mod: *Module, file: *File) !void { } // If we already have the exclusive lock then it is our job to update. - if (builtin.os.tag == .wasi or lock == .Exclusive) break; + if (builtin.os.tag == .wasi or lock == .exclusive) break; // Otherwise, unlock to give someone a chance to get the exclusive lock // and then upgrade to an exclusive lock. cache_file.unlock(); - lock = .Exclusive; + lock = .exclusive; try cache_file.lock(lock); } -- cgit v1.2.3 From 4976b58ab16069f8d3267b69ed030f29685c1abe Mon Sep 17 00:00:00 2001 From: mlugg Date: Mon, 29 May 2023 05:07:17 +0100 Subject: Prevent analysis of functions only referenced at comptime The idea here is that there are two ways we can reference a function at runtime: * Through a direct call, i.e. where the function is comptime-known * Through a function pointer This means we can easily perform a form of rudimentary escape analysis on functions. If we ever see a `decl_ref` or `ref` of a function, we have a function pointer, which could "leak" into runtime code, so we emit the function; but for a plain `decl_val`, there's no need to. This change means that `comptime { _ = f; }` no longer forces a function to be emitted, which was used for some things (mainly tests). These use sites have been replaced with `_ = &f;`, which still triggers analysis of the function body, since you're taking a pointer to the function. Resolves: #6256 Resolves: #15353 --- lib/compiler_rt/clear_cache.zig | 2 +- lib/std/fmt.zig | 2 +- lib/std/fs.zig | 10 +-- lib/std/hash_map.zig | 2 +- lib/std/multi_array_list.zig | 4 +- lib/std/os/test.zig | 2 +- lib/std/testing.zig | 4 +- src/Compilation.zig | 7 ++ src/Module.zig | 74 +++++++++++++++++----- src/Sema.zig | 41 ++++++++++-- src/type.zig | 2 +- src/value.zig | 2 +- test/behavior/sizeof_and_typeof.zig | 2 +- .../closure_get_depends_on_failed_decl.zig | 2 +- ...og_of_tagged_enum_doesnt_crash_the_compiler.zig | 5 +- test/cases/compile_errors/compile_log.zig | 11 ++-- test/cases/compile_errors/dereference_slice.zig | 2 +- .../extern_function_with_comptime_parameter.zig | 6 +- .../invalid_address_space_coercion.zig | 2 +- ...ss_space_when_taking_address_of_dereference.zig | 2 +- .../noalias_on_non_pointer_param.zig | 4 +- .../pointer_with_different_address_spaces.zig | 2 +- .../pointers_with_different_address_spaces.zig | 2 +- .../compile_errors/slice_sentinel_mismatch-2.zig | 2 +- ...r_access_chaining_pointer_to_optional_array.zig | 2 +- ...paces_pointer_access_chaining_array_pointer.zig | 2 +- ...ress_spaces_pointer_access_chaining_complex.zig | 2 +- ...aces_pointer_access_chaining_struct_pointer.zig | 2 +- ...hough_multiple_pointers_with_address_spaces.zig | 2 +- test/cases/llvm/pointer_keeps_address_space.zig | 2 +- ...ss_space_when_taking_address_of_dereference.zig | 2 +- ...c_address_space_coerces_to_implicit_pointer.zig | 2 +- test/link/wasm/type/build.zig | 4 +- 33 files changed, 149 insertions(+), 65 deletions(-) (limited to 'lib/std/fs.zig') diff --git a/lib/compiler_rt/clear_cache.zig b/lib/compiler_rt/clear_cache.zig index 93e6846ae5..5038c4061a 100644 --- a/lib/compiler_rt/clear_cache.zig +++ b/lib/compiler_rt/clear_cache.zig @@ -12,7 +12,7 @@ pub const panic = @import("common.zig").panic; // specified range. comptime { - _ = clear_cache; + _ = &clear_cache; } fn clear_cache(start: usize, end: usize) callconv(.C) void { diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index ac1f86cce5..be6ebf20ac 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -1959,7 +1959,7 @@ pub const parseFloat = @import("fmt/parse_float.zig").parseFloat; pub const ParseFloatError = @import("fmt/parse_float.zig").ParseFloatError; test { - _ = parseFloat; + _ = &parseFloat; } pub fn charToDigit(c: u8, radix: u8) (error{InvalidCharacter}!u8) { diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 6ab2dbaa7f..746bfde383 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -3150,12 +3150,12 @@ fn copy_file(fd_in: os.fd_t, fd_out: os.fd_t, maybe_size: ?u64) CopyFileRawError test { if (builtin.os.tag != .wasi) { - _ = makeDirAbsolute; - _ = makeDirAbsoluteZ; - _ = copyFileAbsolute; - _ = updateFileAbsolute; + _ = &makeDirAbsolute; + _ = &makeDirAbsoluteZ; + _ = ©FileAbsolute; + _ = &updateFileAbsolute; } - _ = Dir.copyFile; + _ = &Dir.copyFile; _ = @import("fs/test.zig"); _ = @import("fs/path.zig"); _ = @import("fs/file.zig"); diff --git a/lib/std/hash_map.zig b/lib/std/hash_map.zig index 91f5682831..50ff2f0c94 100644 --- a/lib/std/hash_map.zig +++ b/lib/std/hash_map.zig @@ -1605,7 +1605,7 @@ pub fn HashMapUnmanaged( comptime { if (builtin.mode == .Debug) { - _ = dbHelper; + _ = &dbHelper; } } }; diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 44e226be33..e9011c3c63 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -532,8 +532,8 @@ pub fn MultiArrayList(comptime T: type) type { comptime { if (builtin.mode == .Debug) { - _ = dbHelper; - _ = Slice.dbHelper; + _ = &dbHelper; + _ = &Slice.dbHelper; } } }; diff --git a/lib/std/os/test.zig b/lib/std/os/test.zig index f694ea277a..e7b66c0d55 100644 --- a/lib/std/os/test.zig +++ b/lib/std/os/test.zig @@ -704,7 +704,7 @@ test "signalfd" { .linux, .solaris => {}, else => return error.SkipZigTest, } - _ = os.signalfd; + _ = &os.signalfd; } test "sync" { diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 7986c50eaf..fa131122bb 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -1116,7 +1116,7 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime pub fn refAllDecls(comptime T: type) void { if (!builtin.is_test) return; inline for (comptime std.meta.declarations(T)) |decl| { - if (decl.is_pub) _ = @field(T, decl.name); + if (decl.is_pub) _ = &@field(T, decl.name); } } @@ -1132,7 +1132,7 @@ pub fn refAllDeclsRecursive(comptime T: type) void { else => {}, } } - _ = @field(T, decl.name); + _ = &@field(T, decl.name); } } } diff --git a/src/Compilation.zig b/src/Compilation.zig index cc2e2a916b..956948dd86 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -3193,6 +3193,13 @@ fn processOneJob(comp: *Compilation, job: Job, prog_node: *std.Progress.Node) !v error.OutOfMemory => return error.OutOfMemory, error.AnalysisFail => return, }; + const decl = module.declPtr(decl_index); + if (decl.kind == .@"test" and comp.bin_file.options.is_test) { + // Tests are always emitted in test binaries. The decl_refs are created by + // Module.populateTestFunctions, but this will not queue body analysis, so do + // that now. + try module.ensureFuncBodyAnalysisQueued(decl.val.castTag(.function).?.data); + } }, .update_embed_file => |embed_file| { const named_frame = tracy.namedFrame("update_embed_file"); diff --git a/src/Module.zig b/src/Module.zig index 61843f5a8f..59ee21d8cf 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -1638,6 +1638,10 @@ pub const Fn = struct { inferred_error_sets: InferredErrorSetList = .{}, pub const Analysis = enum { + /// This function has not yet undergone analysis, because we have not + /// seen a potential runtime call. It may be analyzed in future. + none, + /// Analysis for this function has been queued, but not yet completed. queued, /// This function intentionally only has ZIR generated because it is marked /// inline, which means no runtime version of the function will be generated. @@ -4323,7 +4327,7 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void { .complete, .codegen_failure_retryable => { switch (func.state) { .sema_failure, .dependency_failure => return error.AnalysisFail, - .queued => {}, + .none, .queued => {}, .in_progress => unreachable, .inline_only => unreachable, // don't queue work for this .success => return, @@ -4426,6 +4430,60 @@ pub fn ensureFuncBodyAnalyzed(mod: *Module, func: *Fn) SemaError!void { } } +/// Ensure this function's body is or will be analyzed and emitted. This should +/// be called whenever a potential runtime call of a function is seen. +/// +/// The caller is responsible for ensuring the function decl itself is already +/// analyzed, and for ensuring it can exist at runtime (see +/// `sema.fnHasRuntimeBits`). This function does *not* guarantee that the body +/// will be analyzed when it returns: for that, see `ensureFuncBodyAnalyzed`. +pub fn ensureFuncBodyAnalysisQueued(mod: *Module, func: *Fn) !void { + const decl_index = func.owner_decl; + const decl = mod.declPtr(decl_index); + + switch (decl.analysis) { + .unreferenced => unreachable, + .in_progress => unreachable, + .outdated => unreachable, + + .file_failure, + .sema_failure, + .liveness_failure, + .codegen_failure, + .dependency_failure, + .sema_failure_retryable, + .codegen_failure_retryable, + // The function analysis failed, but we've already emitted an error for + // that. The callee doesn't need the function to be analyzed right now, + // so its analysis can safely continue. + => return, + + .complete => {}, + } + + assert(decl.has_tv); + + switch (func.state) { + .none => {}, + .queued => return, + // As above, we don't need to forward errors here. + .sema_failure, .dependency_failure => return, + .in_progress => return, + .inline_only => unreachable, // don't queue work for this + .success => return, + } + + // Decl itself is safely analyzed, and body analysis is not yet queued + + try mod.comp.work_queue.writeItem(.{ .codegen_func = func }); + if (mod.emit_h != null) { + // TODO: we ideally only want to do this if the function's type changed + // since the last update + try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); + } + func.state = .queued; +} + pub fn updateEmbedFile(mod: *Module, embed_file: *EmbedFile) SemaError!void { const tracy = trace(@src()); defer tracy.end(); @@ -4733,20 +4791,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { decl.analysis = .complete; decl.generation = mod.generation; - const has_runtime_bits = try sema.fnHasRuntimeBits(decl.ty); - - if (has_runtime_bits) { - // We don't fully codegen the decl until later, but we do need to reserve a global - // offset table index for it. This allows us to codegen decls out of dependency - // order, increasing how many computations can be done in parallel. - try mod.comp.work_queue.writeItem(.{ .codegen_func = func }); - if (type_changed and mod.emit_h != null) { - try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl_index }); - } - } else if (!prev_is_inline and prev_type_has_bits) { - mod.comp.bin_file.freeDecl(decl_index); - } - const is_inline = decl.ty.fnCallingConvention() == .Inline; if (decl.is_exported) { const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) }; diff --git a/src/Sema.zig b/src/Sema.zig index 4ae928d243..bd146c68fc 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2452,6 +2452,7 @@ fn zirCoerceResultPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE .@"align" = iac.data.alignment, .@"addrspace" = addr_space, }); + try sema.maybeQueueFuncBodyAnalysis(iac.data.decl_index); return sema.addConstant( ptr_ty, try Value.Tag.decl_ref_mut.create(sema.arena, .{ @@ -3709,6 +3710,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com const final_ptr_ty_inst = try sema.addType(final_ptr_ty); sema.air_instructions.items(.data)[ptr_inst].ty_pl.ty = final_ptr_ty_inst; + try sema.maybeQueueFuncBodyAnalysis(decl_index); if (var_is_mut) { sema.air_values.items[value_index] = try Value.Tag.decl_ref_mut.create(sema.arena, .{ .decl_index = decl_index, @@ -3809,6 +3811,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com // Even though we reuse the constant instruction, we still remove it from the // block so that codegen does not see it. block.instructions.shrinkRetainingCapacity(search_index); + try sema.maybeQueueFuncBodyAnalysis(new_decl_index); sema.air_values.items[value_index] = try Value.Tag.decl_ref.create(sema.arena, new_decl_index); // if bitcast ty ref needs to be made const, make_ptr_const // ZIR handles it later, so we can just use the ty ref here. @@ -5747,6 +5750,7 @@ pub fn analyzeExport( // This decl is alive no matter what, since it's being exported mod.markDeclAlive(exported_decl); + try sema.maybeQueueFuncBodyAnalysis(exported_decl_index); const gpa = mod.gpa; @@ -7068,6 +7072,12 @@ fn analyzeCall( sema.owner_func.?.calls_or_awaits_errorable_fn = true; } + if (try sema.resolveMaybeUndefVal(func)) |func_val| { + if (func_val.castTag(.function)) |func_obj| { + try sema.mod.ensureFuncBodyAnalysisQueued(func_obj.data); + } + } + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).Struct.fields.len + args.len); const func_inst = try block.addInst(.{ @@ -7585,6 +7595,8 @@ fn instantiateGenericCall( sema.owner_func.?.calls_or_awaits_errorable_fn = true; } + try sema.mod.ensureFuncBodyAnalysisQueued(callee); + try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Call).Struct.fields.len + runtime_args_len); const result = try block.addInst(.{ @@ -9143,7 +9155,7 @@ fn funcCommon( } const is_inline = fn_ty.fnCallingConvention() == .Inline; - const anal_state: Module.Fn.Analysis = if (is_inline) .inline_only else .queued; + const anal_state: Module.Fn.Analysis = if (is_inline) .inline_only else .none; const comptime_args: ?[*]TypedValue = if (sema.comptime_args_fn_inst == func_inst) blk: { break :blk if (sema.comptime_args.len == 0) null else sema.comptime_args.ptr; @@ -24279,9 +24291,7 @@ fn fieldCallBind( if (concrete_ty.getNamespace()) |namespace| { if (try sema.namespaceLookup(block, src, namespace, field_name)) |decl_idx| { try sema.addReferencedBy(block, src, decl_idx); - const inst = try sema.analyzeDeclRef(decl_idx); - - const decl_val = try sema.analyzeLoad(block, src, inst, src); + const decl_val = try sema.analyzeDeclVal(block, src, decl_idx); const decl_type = sema.typeOf(decl_val); if (decl_type.zigTypeTag() == .Fn and decl_type.fnParamLen() >= 1) @@ -28911,7 +28921,7 @@ fn analyzeDeclVal( if (sema.decl_val_table.get(decl_index)) |result| { return result; } - const decl_ref = try sema.analyzeDeclRef(decl_index); + const decl_ref = try sema.analyzeDeclRefInner(decl_index, false); const result = try sema.analyzeLoad(block, src, decl_ref, src); if (Air.refToIndex(result)) |index| { if (sema.air_instructions.items(.tag)[index] == .constant and !block.is_typeof) { @@ -28970,6 +28980,7 @@ fn refValue(sema: *Sema, block: *Block, ty: Type, val: Value) !Value { try val.copy(anon_decl.arena()), 0, // default alignment ); + try sema.maybeQueueFuncBodyAnalysis(decl); try sema.mod.declareDeclDependency(sema.owner_decl_index, decl); return try Value.Tag.decl_ref.create(sema.arena, decl); } @@ -28982,6 +28993,14 @@ fn optRefValue(sema: *Sema, block: *Block, ty: Type, opt_val: ?Value) !Value { } fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref { + return sema.analyzeDeclRefInner(decl_index, true); +} + +/// Analyze a reference to the decl at the given index. Ensures the underlying decl is analyzed, but +/// only triggers analysis for function bodies if `analyze_fn_body` is true. If it's possible for a +/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps +/// this function with `analyze_fn_body` set to true. +fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref { try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index); try sema.ensureDeclAnalyzed(decl_index); @@ -28997,6 +29016,9 @@ fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref }); return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl_index)); } + if (analyze_fn_body) { + try sema.maybeQueueFuncBodyAnalysis(decl_index); + } return sema.addConstant( try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = decl_tv.ty, @@ -29008,6 +29030,15 @@ fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref ); } +fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: Decl.Index) !void { + const decl = sema.mod.declPtr(decl_index); + const tv = try decl.typedValue(); + if (tv.ty.zigTypeTag() != .Fn) return; + if (!try sema.fnHasRuntimeBits(tv.ty)) return; + const func = tv.val.castTag(.function) orelse return; // undef or extern_fn + try sema.mod.ensureFuncBodyAnalysisQueued(func.data); +} + fn analyzeRef( sema: *Sema, block: *Block, diff --git a/src/type.zig b/src/type.zig index 4023b5ba66..e5b41e717b 100644 --- a/src/type.zig +++ b/src/type.zig @@ -6802,7 +6802,7 @@ pub const Type = extern union { comptime { if (builtin.mode == .Debug) { - _ = dbHelper; + _ = &dbHelper; } } }; diff --git a/src/value.zig b/src/value.zig index b18ba3d834..af2d7b1ca2 100644 --- a/src/value.zig +++ b/src/value.zig @@ -5709,7 +5709,7 @@ pub const Value = extern union { comptime { if (builtin.mode == .Debug) { - _ = dbHelper; + _ = &dbHelper; } } }; diff --git a/test/behavior/sizeof_and_typeof.zig b/test/behavior/sizeof_and_typeof.zig index e463e51753..6f7d420646 100644 --- a/test/behavior/sizeof_and_typeof.zig +++ b/test/behavior/sizeof_and_typeof.zig @@ -48,7 +48,7 @@ fn fn1(alpha: bool) void { } test "lazy @sizeOf result is checked for definedness" { - _ = fn1; + _ = &fn1; } const A = struct { diff --git a/test/cases/compile_errors/closure_get_depends_on_failed_decl.zig b/test/cases/compile_errors/closure_get_depends_on_failed_decl.zig index ccdbf67713..be451d2fc8 100644 --- a/test/cases/compile_errors/closure_get_depends_on_failed_decl.zig +++ b/test/cases/compile_errors/closure_get_depends_on_failed_decl.zig @@ -3,7 +3,7 @@ pub inline fn instanceRequestAdapter() void {} pub inline fn requestAdapter( comptime callbackArg: fn () callconv(.Inline) void, ) void { - _ = (struct { + _ = &(struct { pub fn callback() callconv(.C) void { callbackArg(); } diff --git a/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig b/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig index 55676f9230..f7de8129b7 100644 --- a/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig +++ b/test/cases/compile_errors/compileLog_of_tagged_enum_doesnt_crash_the_compiler.zig @@ -1,5 +1,5 @@ const Bar = union(enum(u32)) { - X: i32 = 1 + X: i32 = 1, }; fn testCompileLog(x: Bar) void { @@ -7,7 +7,8 @@ fn testCompileLog(x: Bar) void { } pub export fn entry() void { - comptime testCompileLog(Bar{.X = 123}); + comptime testCompileLog(Bar{ .X = 123 }); + _ = &testCompileLog; } // error diff --git a/test/cases/compile_errors/compile_log.zig b/test/cases/compile_errors/compile_log.zig index e1ea460dc3..444d091017 100644 --- a/test/cases/compile_errors/compile_log.zig +++ b/test/cases/compile_errors/compile_log.zig @@ -1,10 +1,11 @@ export fn foo() void { - comptime bar(12, "hi",); + comptime bar(12, "hi"); + _ = &bar; } fn bar(a: i32, b: []const u8) void { - @compileLog("begin",); + @compileLog("begin"); @compileLog("a", a, "b", b); - @compileLog("end",); + @compileLog("end"); } export fn baz() void { const S = struct { a: u32 }; @@ -15,8 +16,8 @@ export fn baz() void { // backend=llvm // target=native // -// :5:5: error: found compile log statement -// :11:5: note: also here +// :6:5: error: found compile log statement +// :12:5: note: also here // // Compile Log Output: // @as(*const [5:0]u8, "begin") diff --git a/test/cases/compile_errors/dereference_slice.zig b/test/cases/compile_errors/dereference_slice.zig index 7dba3b55d8..55d6078b22 100644 --- a/test/cases/compile_errors/dereference_slice.zig +++ b/test/cases/compile_errors/dereference_slice.zig @@ -2,7 +2,7 @@ fn entry(x: []i32) i32 { return x.*; } comptime { - _ = entry; + _ = &entry; } // error diff --git a/test/cases/compile_errors/extern_function_with_comptime_parameter.zig b/test/cases/compile_errors/extern_function_with_comptime_parameter.zig index 58f15f7fab..8ade9ca2aa 100644 --- a/test/cases/compile_errors/extern_function_with_comptime_parameter.zig +++ b/test/cases/compile_errors/extern_function_with_comptime_parameter.zig @@ -4,9 +4,9 @@ fn f() i32 { } pub extern fn entry1(b: u32, comptime a: [2]u8, c: i32) void; pub extern fn entry2(b: u32, noalias a: anytype, i43) void; -comptime { _ = f; } -comptime { _ = entry1; } -comptime { _ = entry2; } +comptime { _ = &f; } +comptime { _ = &entry1; } +comptime { _ = &entry2; } // error // backend=stage2 diff --git a/test/cases/compile_errors/invalid_address_space_coercion.zig b/test/cases/compile_errors/invalid_address_space_coercion.zig index 4633b12e0f..baf37cbe37 100644 --- a/test/cases/compile_errors/invalid_address_space_coercion.zig +++ b/test/cases/compile_errors/invalid_address_space_coercion.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) i32) *i32 { return a; } pub fn main() void { - _ = entry; + _ = &entry; } // error diff --git a/test/cases/compile_errors/invalid_pointer_keeps_address_space_when_taking_address_of_dereference.zig b/test/cases/compile_errors/invalid_pointer_keeps_address_space_when_taking_address_of_dereference.zig index 4d7b3c627b..c59238d6a7 100644 --- a/test/cases/compile_errors/invalid_pointer_keeps_address_space_when_taking_address_of_dereference.zig +++ b/test/cases/compile_errors/invalid_pointer_keeps_address_space_when_taking_address_of_dereference.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) i32) *i32 { return &a.*; } pub fn main() void { - _ = entry; + _ = &entry; } // error diff --git a/test/cases/compile_errors/noalias_on_non_pointer_param.zig b/test/cases/compile_errors/noalias_on_non_pointer_param.zig index 806808820f..65e6e141ce 100644 --- a/test/cases/compile_errors/noalias_on_non_pointer_param.zig +++ b/test/cases/compile_errors/noalias_on_non_pointer_param.zig @@ -2,10 +2,10 @@ fn f(noalias x: i32) void { _ = x; } export fn entry() void { f(1234); } fn generic(comptime T: type, noalias _: [*]T, noalias _: [*]const T, _: usize) void {} -comptime { _ = generic; } +comptime { _ = &generic; } fn slice(noalias _: []u8) void {} -comptime { _ = slice; } +comptime { _ = &slice; } // error // backend=stage2 diff --git a/test/cases/compile_errors/pointer_with_different_address_spaces.zig b/test/cases/compile_errors/pointer_with_different_address_spaces.zig index 2bbea3d3b6..7a434cfa8e 100644 --- a/test/cases/compile_errors/pointer_with_different_address_spaces.zig +++ b/test/cases/compile_errors/pointer_with_different_address_spaces.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) i32) *addrspace(.fs) i32 { return a; } export fn entry2() void { - _ = entry; + _ = &entry; } // error diff --git a/test/cases/compile_errors/pointers_with_different_address_spaces.zig b/test/cases/compile_errors/pointers_with_different_address_spaces.zig index e952da2af5..44b1ef8722 100644 --- a/test/cases/compile_errors/pointers_with_different_address_spaces.zig +++ b/test/cases/compile_errors/pointers_with_different_address_spaces.zig @@ -2,7 +2,7 @@ fn entry(a: ?*addrspace(.gs) i32) *i32 { return a.?; } pub fn main() void { - _ = entry; + _ = &entry; } // error diff --git a/test/cases/compile_errors/slice_sentinel_mismatch-2.zig b/test/cases/compile_errors/slice_sentinel_mismatch-2.zig index 3cc5ac4c39..ea34805e32 100644 --- a/test/cases/compile_errors/slice_sentinel_mismatch-2.zig +++ b/test/cases/compile_errors/slice_sentinel_mismatch-2.zig @@ -2,7 +2,7 @@ fn foo() [:0]u8 { var x: []u8 = undefined; return x; } -comptime { _ = foo; } +comptime { _ = &foo; } // error // backend=stage2 diff --git a/test/cases/llvm/address_space_pointer_access_chaining_pointer_to_optional_array.zig b/test/cases/llvm/address_space_pointer_access_chaining_pointer_to_optional_array.zig index 00d4a7ecc9..9ee3fa4de4 100644 --- a/test/cases/llvm/address_space_pointer_access_chaining_pointer_to_optional_array.zig +++ b/test/cases/llvm/address_space_pointer_access_chaining_pointer_to_optional_array.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) ?[1]i32) *addrspace(.gs) i32 { return &a.*.?[0]; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/address_spaces_pointer_access_chaining_array_pointer.zig b/test/cases/llvm/address_spaces_pointer_access_chaining_array_pointer.zig index f23498e955..da90f3ee1d 100644 --- a/test/cases/llvm/address_spaces_pointer_access_chaining_array_pointer.zig +++ b/test/cases/llvm/address_spaces_pointer_access_chaining_array_pointer.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) [1]i32) *addrspace(.gs) i32 { return &a[0]; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/address_spaces_pointer_access_chaining_complex.zig b/test/cases/llvm/address_spaces_pointer_access_chaining_complex.zig index 4f54f38e6b..5be74a0ea5 100644 --- a/test/cases/llvm/address_spaces_pointer_access_chaining_complex.zig +++ b/test/cases/llvm/address_spaces_pointer_access_chaining_complex.zig @@ -3,7 +3,7 @@ fn entry(a: *addrspace(.gs) [1]A) *addrspace(.gs) i32 { return &a[0].a.?[0]; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/address_spaces_pointer_access_chaining_struct_pointer.zig b/test/cases/llvm/address_spaces_pointer_access_chaining_struct_pointer.zig index 84695cb35b..d3182b4745 100644 --- a/test/cases/llvm/address_spaces_pointer_access_chaining_struct_pointer.zig +++ b/test/cases/llvm/address_spaces_pointer_access_chaining_struct_pointer.zig @@ -3,7 +3,7 @@ fn entry(a: *addrspace(.gs) A) *addrspace(.gs) i32 { return &a.a; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/dereferencing_though_multiple_pointers_with_address_spaces.zig b/test/cases/llvm/dereferencing_though_multiple_pointers_with_address_spaces.zig index badab821d3..a4b5d1372a 100644 --- a/test/cases/llvm/dereferencing_though_multiple_pointers_with_address_spaces.zig +++ b/test/cases/llvm/dereferencing_though_multiple_pointers_with_address_spaces.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.fs) *addrspace(.gs) *i32) *i32 { return a.*.*; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/pointer_keeps_address_space.zig b/test/cases/llvm/pointer_keeps_address_space.zig index f894c96d7b..fa1a11a0c5 100644 --- a/test/cases/llvm/pointer_keeps_address_space.zig +++ b/test/cases/llvm/pointer_keeps_address_space.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) i32) *addrspace(.gs) i32 { return a; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/pointer_keeps_address_space_when_taking_address_of_dereference.zig b/test/cases/llvm/pointer_keeps_address_space_when_taking_address_of_dereference.zig index b5803a3076..1fade5ce54 100644 --- a/test/cases/llvm/pointer_keeps_address_space_when_taking_address_of_dereference.zig +++ b/test/cases/llvm/pointer_keeps_address_space_when_taking_address_of_dereference.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.gs) i32) *addrspace(.gs) i32 { return &a.*; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/cases/llvm/pointer_to_explicit_generic_address_space_coerces_to_implicit_pointer.zig b/test/cases/llvm/pointer_to_explicit_generic_address_space_coerces_to_implicit_pointer.zig index b3c0116983..287bc54a18 100644 --- a/test/cases/llvm/pointer_to_explicit_generic_address_space_coerces_to_implicit_pointer.zig +++ b/test/cases/llvm/pointer_to_explicit_generic_address_space_coerces_to_implicit_pointer.zig @@ -2,7 +2,7 @@ fn entry(a: *addrspace(.generic) i32) *i32 { return a; } pub fn main() void { - _ = entry; + _ = &entry; } // compile diff --git a/test/link/wasm/type/build.zig b/test/link/wasm/type/build.zig index 7a779f6c21..72a9261750 100644 --- a/test/link/wasm/type/build.zig +++ b/test/link/wasm/type/build.zig @@ -26,10 +26,10 @@ fn add(b: *std.Build, test_step: *std.Build.Step, optimize: std.builtin.Optimize const check_lib = lib.checkObject(); check_lib.checkStart("Section type"); - // only 3 entries, although we have more functions. + // only 2 entries, although we have more functions. // This is to test functions with the same function signature // have their types deduplicated. - check_lib.checkNext("entries 3"); + check_lib.checkNext("entries 2"); check_lib.checkNext("params 1"); check_lib.checkNext("type i32"); check_lib.checkNext("returns 1"); -- cgit v1.2.3 From 2f188290e203780752597b0263581590af3a69b2 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 7 Jun 2023 22:37:53 -0700 Subject: Use `iterateAssumeFirstIteration` in `Walker.next` to avoid unnecessary lseek calls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since we are opening each directory for iteration, we know that we don't need to reset the cursor's directory before iterating. Using `iterateAssumeFirstIteration` skips the cursor resetting which eliminates an `lseek` syscall for every directory opened on non-Windows platforms. This doesn't seem to actually matter much for performance (1.01 ± 0.02 times faster when walking /home/ on my system) but avoiding unnecessary syscalls is always nice anyway. --- lib/std/fs.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 037f0c81f6..d3c8fb322e 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -972,7 +972,7 @@ pub const IterableDir = struct { { errdefer new_dir.close(); try self.stack.append(StackItem{ - .iter = new_dir.iterate(), + .iter = new_dir.iterateAssumeFirstIteration(), .dirname_len = self.name_buffer.items.len, }); top = &self.stack.items[self.stack.items.len - 1]; -- cgit v1.2.3 From 7555085e6304419c25bb870567eb265bb22d0337 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 7 Jun 2023 22:44:21 -0700 Subject: Directory iteration: handle `EACCES` returned from `getdents64` This can occur for directories that the user does not have the necessary permissions to be able to iterate. --- lib/std/fs.zig | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/std/fs.zig') diff --git a/lib/std/fs.zig b/lib/std/fs.zig index d3c8fb322e..8ce8b74650 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -662,6 +662,7 @@ pub const IterableDir = struct { .NOTDIR => unreachable, .NOENT => return error.DirNotFound, // The directory being iterated was deleted during iteration. .INVAL => return error.Unexpected, // Linux may in some cases return EINVAL when reading /proc/$PID/net. + .ACCES => return error.AccessDenied, // Do not have permission to iterate this directory. else => |err| return os.unexpectedErrno(err), } if (rc == 0) return null; -- cgit v1.2.3 From af835111fa1397578392a4774454ac0d71eca77d Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Wed, 7 Jun 2023 22:50:45 -0700 Subject: Allow recovering from Walker.next errors without continually hitting the same error Before this commit, if Walker.next errored with e.g. `error.AccessDenied` and the caller did something like `while (true) { walker.next() catch continue; }`, then the directory that errored with AccessDenied would be continually iterated in each `next` call and error every time with AccessDenied. After this commit, the directory that errored will be popped off the stack before the error is returned, meaning that in the subsequent `next` call, it won't be retried and the Walker will continue with whatever directories remain on its stack. For a real example, before this commit, walking `/proc/` on my system would infinitely loop due to repeated AccessDenied errors on the same directory. After this commit, I am able to walk `/proc/` on my system fully (skipping over any directories that are unable to be iterated). --- lib/std/fs.zig | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 8ce8b74650..38b94873e6 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -958,7 +958,17 @@ pub const IterableDir = struct { var top = &self.stack.items[self.stack.items.len - 1]; var containing = top; var dirname_len = top.dirname_len; - if (try top.iter.next()) |base| { + if (top.iter.next() catch |err| { + // If we get an error, then we want the user to be able to continue + // walking if they want, which means that we need to pop the directory + // that errored from the stack. Otherwise, all future `next` calls would + // likely just fail with the same error. + var item = self.stack.pop(); + if (self.stack.items.len != 0) { + item.iter.dir.close(); + } + return err; + }) |base| { self.name_buffer.shrinkRetainingCapacity(dirname_len); if (self.name_buffer.items.len != 0) { try self.name_buffer.append(path.sep); -- cgit v1.2.3 From 64ddba955a1f98ab77cfb39844a09f472ebc4609 Mon Sep 17 00:00:00 2001 From: Michael Dusan Date: Thu, 15 Jun 2023 14:48:19 -0400 Subject: freebsd: fix std.c.getdents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - fix getdents return type usize → isize - usize ultimately forced errors to .SUCCESS in std.c.getError New behavior in freebsd 13.2 is to return ENOENT if the directory being iterated is deleted during iteration. We now detect this and treat it consistent with iteration ending. --- lib/std/c/freebsd.zig | 2 +- lib/std/fs.zig | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib/std/fs.zig') diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index b3e6c6769a..b351128b03 100644 --- a/lib/std/c/freebsd.zig +++ b/lib/std/c/freebsd.zig @@ -75,7 +75,7 @@ pub const _errno = __error; pub extern "c" var malloc_options: [*:0]const u8; -pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; +pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) isize; pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize; pub extern "c" fn getentropy(buf_ptr: [*]u8, buf_len: usize) c_int; diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 38b94873e6..bb0890be4b 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -478,6 +478,9 @@ pub const IterableDir = struct { .FAULT => unreachable, .NOTDIR => unreachable, .INVAL => unreachable, + // Introduced in freebsd 13.2: directory unlinked but still open. + // To be consistent, iteration ends if the directory being iterated is deleted during iteration. + .NOENT => return null, else => |err| return os.unexpectedErrno(err), } if (rc == 0) return null; -- cgit v1.2.3