diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig index 323f974255..94593fe7cb 100644 --- a/lib/std/fs/path.zig +++ b/lib/std/fs/path.zig @@ -12,13 +12,13 @@ const fs = std.fs; const process = std.process; const native_os = builtin.target.os.tag; -pub const sep_windows = '\\'; +pub const sep_windows_uefi = '\\'; pub const sep_posix = '/'; -pub const sep = if (native_os == .windows) sep_windows else sep_posix; +pub const sep = if (native_os == .windows or native_os == .uefi) sep_windows_uefi else sep_posix; -pub const sep_str_windows = "\\"; +pub const sep_str_windows_uefi = "\\"; pub const sep_str_posix = "/"; -pub const sep_str = if (native_os == .windows) sep_str_windows else sep_str_posix; +pub const sep_str = if (native_os == .windows or native_os == .uefi) sep_str_windows_uefi else sep_str_posix; pub const delimiter_windows = ';'; pub const delimiter_posix = ':'; @@ -26,11 +26,11 @@ pub const delimiter = if (native_os == .windows) delimiter_windows else delimite /// Returns if the given byte is a valid path separator pub fn isSep(byte: u8) bool { - if (native_os == .windows) { - return byte == '/' or byte == '\\'; - } else { - return byte == '/'; - } + return switch (native_os) { + .windows => byte == '/' or byte == '\\', + .uefi => byte == '\\', + else => byte == '/', + }; } /// This is different from mem.join in that the separator will not be repeated if @@ -110,13 +110,24 @@ pub fn joinZ(allocator: Allocator, paths: []const []const u8) ![:0]u8 { return out[0 .. out.len - 1 :0]; } +fn testJoinMaybeZUefi(paths: []const []const u8, expected: []const u8, zero: bool) !void { + const uefiIsSep = struct { + fn isSep(byte: u8) bool { + return byte == '\\'; + } + }.isSep; + const actual = try joinSepMaybeZ(testing.allocator, sep_windows_uefi, uefiIsSep, paths, zero); + defer testing.allocator.free(actual); + try testing.expectEqualSlices(u8, expected, if (zero) actual[0 .. actual.len - 1 :0] else actual); +} + fn testJoinMaybeZWindows(paths: []const []const u8, expected: []const u8, zero: bool) !void { const windowsIsSep = struct { fn isSep(byte: u8) bool { return byte == '/' or byte == '\\'; } }.isSep; - const actual = try joinSepMaybeZ(testing.allocator, sep_windows, windowsIsSep, paths, zero); + const actual = try joinSepMaybeZ(testing.allocator, sep_windows_uefi, windowsIsSep, paths, zero); defer testing.allocator.free(actual); try testing.expectEqualSlices(u8, expected, if (zero) actual[0 .. actual.len - 1 :0] else actual); } @@ -158,6 +169,11 @@ test "join" { zero, ); + try testJoinMaybeZUefi(&[_][]const u8{ "EFI", "Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero); + try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero); + try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\", "\\Boot", "bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero); + try testJoinMaybeZUefi(&[_][]const u8{ "EFI\\", "\\Boot\\", "\\bootx64.efi" }, "EFI\\Boot\\bootx64.efi", zero); + try testJoinMaybeZWindows(&[_][]const u8{ "c:\\", "a", "b/", "c" }, "c:\\a\\b/c", zero); try testJoinMaybeZWindows(&[_][]const u8{ "c:\\a/", "b\\", "/c" }, "c:\\a/b\\c", zero); @@ -588,7 +604,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 { result[0] = asciiUpper(result[0]); // Remove the trailing slash if present, eg. if the cwd is a root // directory. - if (cwd.len > 0 and cwd[cwd.len - 1] == sep_windows) { + if (cwd.len > 0 and cwd[cwd.len - 1] == sep_windows_uefi) { result_index -= 1; } } @@ -625,7 +641,7 @@ pub fn resolveWindows(allocator: Allocator, paths: []const []const u8) ![]u8 { break; } } else { - result[result_index] = sep_windows; + result[result_index] = sep_windows_uefi; result_index += 1; mem.copy(u8, result[result_index..], component); result_index += component.len;