diff --git a/lib/std/dynamic_library.zig b/lib/std/dynamic_library.zig index 110d476b1..70e26cc71 100644 --- a/lib/std/dynamic_library.zig +++ b/lib/std/dynamic_library.zig @@ -328,14 +328,14 @@ pub const WindowsDynLib = struct { pub fn open(path: []const u8) !WindowsDynLib { const path_w = try windows.sliceToPrefixedFileW(path); - return openW(&path_w); + return openW(path_w.span().ptr); } pub const openC = @compileError("deprecated: renamed to openZ"); pub fn openZ(path_c: [*:0]const u8) !WindowsDynLib { const path_w = try windows.cStrToPrefixedFileW(path_c); - return openW(&path_w); + return openW(path_w.span().ptr); } pub fn openW(path_w: [*:0]const u16) !WindowsDynLib { diff --git a/lib/std/fs.zig b/lib/std/fs.zig index 7dcfc9261..efcad99f4 100644 --- a/lib/std/fs.zig +++ b/lib/std/fs.zig @@ -199,7 +199,7 @@ pub const AtomicFile = struct { if (std.Target.current.os.tag == .windows) { const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_basename); const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf); - try os.renameatW(self.dir.fd, &tmp_path_w, self.dir.fd, &dest_path_w, os.windows.TRUE); + try os.renameatW(self.dir.fd, tmp_path_w.span(), self.dir.fd, dest_path_w.span(), os.windows.TRUE); self.file_exists = false; } else { const dest_path_c = try os.toPosixPath(self.dest_basename); @@ -582,7 +582,7 @@ pub const Dir = struct { pub fn openFile(self: Dir, sub_path: []const u8, flags: File.OpenFlags) File.OpenError!File { if (builtin.os.tag == .windows) { const path_w = try os.windows.sliceToPrefixedFileW(sub_path); - return self.openFileW(&path_w, flags); + return self.openFileW(path_w.span(), flags); } const path_c = try os.toPosixPath(sub_path); return self.openFileZ(&path_c, flags); @@ -594,7 +594,7 @@ pub const Dir = struct { pub fn openFileZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) File.OpenError!File { if (builtin.os.tag == .windows) { const path_w = try os.windows.cStrToPrefixedFileW(sub_path); - return self.openFileW(&path_w, flags); + return self.openFileW(path_w.span(), flags); } // Use the O_ locking flags if the os supports them @@ -669,7 +669,7 @@ pub const Dir = struct { pub fn createFile(self: Dir, sub_path: []const u8, flags: File.CreateFlags) File.OpenError!File { if (builtin.os.tag == .windows) { const path_w = try os.windows.sliceToPrefixedFileW(sub_path); - return self.createFileW(&path_w, flags); + return self.createFileW(path_w.span(), flags); } const path_c = try os.toPosixPath(sub_path); return self.createFileZ(&path_c, flags); @@ -681,7 +681,7 @@ pub const Dir = struct { pub fn createFileZ(self: Dir, sub_path_c: [*:0]const u8, flags: File.CreateFlags) File.OpenError!File { if (builtin.os.tag == .windows) { const path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); - return self.createFileW(&path_w, flags); + return self.createFileW(path_w.span(), flags); } // Use the O_ locking flags if the os supports them @@ -832,7 +832,7 @@ pub const Dir = struct { pub fn openDir(self: Dir, sub_path: []const u8, args: OpenDirOptions) OpenError!Dir { if (builtin.os.tag == .windows) { const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); - return self.openDirW(&sub_path_w, args); + return self.openDirW(sub_path_w.span().ptr, args); } else { const sub_path_c = try os.toPosixPath(sub_path); return self.openDirZ(&sub_path_c, args); @@ -845,7 +845,7 @@ pub const Dir = struct { pub fn openDirZ(self: Dir, sub_path_c: [*:0]const u8, args: OpenDirOptions) OpenError!Dir { if (builtin.os.tag == .windows) { const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path_c); - return self.openDirW(&sub_path_w, args); + return self.openDirW(sub_path_w.span().ptr, args); } else if (!args.iterate) { const O_PATH = if (@hasDecl(os, "O_PATH")) os.O_PATH else 0; return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | O_PATH); @@ -987,7 +987,7 @@ pub const Dir = struct { pub fn deleteDir(self: Dir, sub_path: []const u8) DeleteDirError!void { if (builtin.os.tag == .windows) { const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); - return self.deleteDirW(&sub_path_w); + return self.deleteDirW(sub_path_w.span().ptr); } const sub_path_c = try os.toPosixPath(sub_path); return self.deleteDirZ(&sub_path_c); @@ -1246,7 +1246,7 @@ pub const Dir = struct { pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void { if (builtin.os.tag == .windows) { const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path); - return self.accessW(&sub_path_w, flags); + return self.accessW(sub_path_w.span().ptr, flags); } const path_c = try os.toPosixPath(sub_path); return self.accessZ(&path_c, flags); @@ -1256,7 +1256,7 @@ pub const Dir = struct { pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void { if (builtin.os.tag == .windows) { const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path); - return self.accessW(&sub_path_w, flags); + return self.accessW(sub_path_w.span().ptr, flags); } const os_mode = if (flags.write and flags.read) @as(u32, os.R_OK | os.W_OK) @@ -1596,7 +1596,7 @@ pub fn openSelfExe() OpenSelfExeError!File { if (builtin.os.tag == .windows) { const wide_slice = selfExePathW(); const prefixed_path_w = try os.windows.wToPrefixedFileW(wide_slice); - return cwd().openFileW(&prefixed_path_w, .{}); + return cwd().openFileW(prefixed_path_w.span(), .{}); } var buf: [MAX_PATH_BYTES]u8 = undefined; const self_exe_path = try selfExePath(&buf); diff --git a/lib/std/os.zig b/lib/std/os.zig index 39f5d36dd..a1b0dc199 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -857,7 +857,7 @@ pub const OpenError = error{ pub fn open(file_path: []const u8, flags: u32, perm: usize) OpenError!fd_t { if (std.Target.current.os.tag == .windows) { const file_path_w = try windows.sliceToPrefixedFileW(file_path); - return openW(&file_path_w, flags, perm); + return openW(file_path_w.span(), flags, perm); } const file_path_c = try toPosixPath(file_path); return openZ(&file_path_c, flags, perm); @@ -870,7 +870,7 @@ pub const openC = @compileError("deprecated: renamed to openZ"); pub fn openZ(file_path: [*:0]const u8, flags: u32, perm: usize) OpenError!fd_t { if (std.Target.current.os.tag == .windows) { const file_path_w = try windows.cStrToPrefixedFileW(file_path); - return openW(&file_path_w, flags, perm); + return openW(file_path_w.span(), flags, perm); } while (true) { const rc = system.open(file_path, flags, perm); @@ -1317,7 +1317,7 @@ pub fn symlink(target_path: []const u8, sym_link_path: []const u8) SymLinkError! if (builtin.os.tag == .windows) { const target_path_w = try windows.sliceToPrefixedFileW(target_path); const sym_link_path_w = try windows.sliceToPrefixedFileW(sym_link_path); - return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); + return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0); } else { const target_path_c = try toPosixPath(target_path); const sym_link_path_c = try toPosixPath(sym_link_path); @@ -1333,7 +1333,7 @@ pub fn symlinkZ(target_path: [*:0]const u8, sym_link_path: [*:0]const u8) SymLin if (builtin.os.tag == .windows) { const target_path_w = try windows.cStrToPrefixedFileW(target_path); const sym_link_path_w = try windows.cStrToPrefixedFileW(sym_link_path); - return windows.CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, 0); + return windows.CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, 0); } switch (errno(system.symlink(target_path, sym_link_path))) { 0 => return, @@ -1409,7 +1409,7 @@ pub const UnlinkError = error{ pub fn unlink(file_path: []const u8) UnlinkError!void { if (builtin.os.tag == .windows) { const file_path_w = try windows.sliceToPrefixedFileW(file_path); - return windows.DeleteFileW(&file_path_w); + return windows.DeleteFileW(file_path_w.span().ptr); } else { const file_path_c = try toPosixPath(file_path); return unlinkZ(&file_path_c); @@ -1422,7 +1422,7 @@ pub const unlinkC = @compileError("deprecated: renamed to unlinkZ"); pub fn unlinkZ(file_path: [*:0]const u8) UnlinkError!void { if (builtin.os.tag == .windows) { const file_path_w = try windows.cStrToPrefixedFileW(file_path); - return windows.DeleteFileW(&file_path_w); + return windows.DeleteFileW(file_path_w.span().ptr); } switch (errno(system.unlink(file_path))) { 0 => return, @@ -1453,7 +1453,7 @@ pub const UnlinkatError = UnlinkError || error{ pub fn unlinkat(dirfd: fd_t, file_path: []const u8, flags: u32) UnlinkatError!void { if (builtin.os.tag == .windows) { const file_path_w = try windows.sliceToPrefixedFileW(file_path); - return unlinkatW(dirfd, &file_path_w, flags); + return unlinkatW(dirfd, file_path_w.span().ptr, flags); } const file_path_c = try toPosixPath(file_path); return unlinkatZ(dirfd, &file_path_c, flags); @@ -1465,7 +1465,7 @@ pub const unlinkatC = @compileError("deprecated: renamed to unlinkatZ"); pub fn unlinkatZ(dirfd: fd_t, file_path_c: [*:0]const u8, flags: u32) UnlinkatError!void { if (builtin.os.tag == .windows) { const file_path_w = try windows.cStrToPrefixedFileW(file_path_c); - return unlinkatW(dirfd, &file_path_w, flags); + return unlinkatW(dirfd, file_path_w.span().ptr, flags); } switch (errno(system.unlinkat(dirfd, file_path_c, flags))) { 0 => return, @@ -1580,7 +1580,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { if (builtin.os.tag == .windows) { const old_path_w = try windows.sliceToPrefixedFileW(old_path); const new_path_w = try windows.sliceToPrefixedFileW(new_path); - return renameW(&old_path_w, &new_path_w); + return renameW(old_path_w.span().ptr, new_path_w.span().ptr); } else { const old_path_c = try toPosixPath(old_path); const new_path_c = try toPosixPath(new_path); @@ -1595,7 +1595,7 @@ pub fn renameZ(old_path: [*:0]const u8, new_path: [*:0]const u8) RenameError!voi if (builtin.os.tag == .windows) { const old_path_w = try windows.cStrToPrefixedFileW(old_path); const new_path_w = try windows.cStrToPrefixedFileW(new_path); - return renameW(&old_path_w, &new_path_w); + return renameW(old_path_w.span().ptr, new_path_w.span().ptr); } switch (errno(system.rename(old_path, new_path))) { 0 => return, @@ -1638,7 +1638,7 @@ pub fn renameat( if (builtin.os.tag == .windows) { const old_path_w = try windows.sliceToPrefixedFileW(old_path); const new_path_w = try windows.sliceToPrefixedFileW(new_path); - return renameatW(old_dir_fd, &old_path_w, new_dir_fd, &new_path_w, windows.TRUE); + return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE); } else { const old_path_c = try toPosixPath(old_path); const new_path_c = try toPosixPath(new_path); @@ -1656,7 +1656,7 @@ pub fn renameatZ( if (builtin.os.tag == .windows) { const old_path_w = try windows.cStrToPrefixedFileW(old_path); const new_path_w = try windows.cStrToPrefixedFileW(new_path); - return renameatW(old_dir_fd, &old_path_w, new_dir_fd, &new_path_w, windows.TRUE); + return renameatW(old_dir_fd, old_path_w.span(), new_dir_fd, new_path_w.span(), windows.TRUE); } switch (errno(system.renameat(old_dir_fd, old_path, new_dir_fd, new_path))) { @@ -1760,7 +1760,7 @@ pub const MakeDirError = error{ pub fn mkdirat(dir_fd: fd_t, sub_dir_path: []const u8, mode: u32) MakeDirError!void { if (builtin.os.tag == .windows) { const sub_dir_path_w = try windows.sliceToPrefixedFileW(sub_dir_path); - return mkdiratW(dir_fd, &sub_dir_path_w, mode); + return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); } else { const sub_dir_path_c = try toPosixPath(sub_dir_path); return mkdiratZ(dir_fd, &sub_dir_path_c, mode); @@ -1772,7 +1772,7 @@ pub const mkdiratC = @compileError("deprecated: renamed to mkdiratZ"); pub fn mkdiratZ(dir_fd: fd_t, sub_dir_path: [*:0]const u8, mode: u32) MakeDirError!void { if (builtin.os.tag == .windows) { const sub_dir_path_w = try windows.cStrToPrefixedFileW(sub_dir_path); - return mkdiratW(dir_fd, &sub_dir_path_w, mode); + return mkdiratW(dir_fd, sub_dir_path_w.span().ptr, mode); } switch (errno(system.mkdirat(dir_fd, sub_dir_path, mode))) { 0 => return, @@ -1816,7 +1816,7 @@ pub fn mkdir(dir_path: []const u8, mode: u32) MakeDirError!void { pub fn mkdirZ(dir_path: [*:0]const u8, mode: u32) MakeDirError!void { if (builtin.os.tag == .windows) { const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); - const sub_dir_handle = try windows.CreateDirectoryW(null, &dir_path_w, null); + const sub_dir_handle = try windows.CreateDirectoryW(null, dir_path_w.span().ptr, null); windows.CloseHandle(sub_dir_handle); return; } @@ -1857,7 +1857,7 @@ pub const DeleteDirError = error{ pub fn rmdir(dir_path: []const u8) DeleteDirError!void { if (builtin.os.tag == .windows) { const dir_path_w = try windows.sliceToPrefixedFileW(dir_path); - return windows.RemoveDirectoryW(&dir_path_w); + return windows.RemoveDirectoryW(dir_path_w.span().ptr); } else { const dir_path_c = try toPosixPath(dir_path); return rmdirZ(&dir_path_c); @@ -1870,7 +1870,7 @@ pub const rmdirC = @compileError("deprecated: renamed to rmdirZ"); pub fn rmdirZ(dir_path: [*:0]const u8) DeleteDirError!void { if (builtin.os.tag == .windows) { const dir_path_w = try windows.cStrToPrefixedFileW(dir_path); - return windows.RemoveDirectoryW(&dir_path_w); + return windows.RemoveDirectoryW(dir_path_w.span().ptr); } switch (errno(system.rmdir(dir_path))) { 0 => return, @@ -2880,7 +2880,7 @@ pub const AccessError = error{ pub fn access(path: []const u8, mode: u32) AccessError!void { if (builtin.os.tag == .windows) { const path_w = try windows.sliceToPrefixedFileW(path); - _ = try windows.GetFileAttributesW(&path_w); + _ = try windows.GetFileAttributesW(path_w.span().ptr); return; } const path_c = try toPosixPath(path); @@ -2893,7 +2893,7 @@ pub const accessC = @compileError("Deprecated in favor of `accessZ`"); pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void { if (builtin.os.tag == .windows) { const path_w = try windows.cStrToPrefixedFileW(path); - _ = try windows.GetFileAttributesW(&path_w); + _ = try windows.GetFileAttributesW(path_w.span().ptr); return; } switch (errno(system.access(path, mode))) { @@ -2934,7 +2934,7 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void { if (builtin.os.tag == .windows) { const path_w = try windows.sliceToPrefixedFileW(path); - return faccessatW(dirfd, &path_w, mode, flags); + return faccessatW(dirfd, path_w.span().ptr, mode, flags); } const path_c = try toPosixPath(path); return faccessatZ(dirfd, &path_c, mode, flags); @@ -2944,7 +2944,7 @@ pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessErr pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void { if (builtin.os.tag == .windows) { const path_w = try windows.cStrToPrefixedFileW(path); - return faccessatW(dirfd, &path_w, mode, flags); + return faccessatW(dirfd, path_w.span().ptr, mode, flags); } switch (errno(system.faccessat(dirfd, path, mode, flags))) { 0 => return, @@ -3299,7 +3299,7 @@ pub const RealPathError = error{ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { if (builtin.os.tag == .windows) { const pathname_w = try windows.sliceToPrefixedFileW(pathname); - return realpathW(&pathname_w, out_buffer); + return realpathW(pathname_w.span().ptr, out_buffer); } const pathname_c = try toPosixPath(pathname); return realpathZ(&pathname_c, out_buffer); @@ -3311,7 +3311,7 @@ pub const realpathC = @compileError("deprecated: renamed realpathZ"); pub fn realpathZ(pathname: [*:0]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 { if (builtin.os.tag == .windows) { const pathname_w = try windows.cStrToPrefixedFileW(pathname); - return realpathW(&pathname_w, out_buffer); + return realpathW(pathname_w.span().ptr, out_buffer); } if (builtin.os.tag == .linux and !builtin.link_libc) { const fd = openZ(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0) catch |err| switch (err) { diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index 3ef3b6308..ff10c0886 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -59,7 +59,7 @@ pub fn CreateFile( hTemplateFile: ?HANDLE, ) CreateFileError!HANDLE { const file_path_w = try sliceToPrefixedFileW(file_path); - return CreateFileW(&file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile); + return CreateFileW(file_path_w.span().ptr, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile); } pub fn CreateFileW( @@ -116,10 +116,10 @@ pub const OpenFileOptions = struct { /// TODO when share_access_nonblocking is false, this implementation uses /// untinterruptible sleep() to block. This is not the final iteration of the API. pub fn OpenFile(sub_path_w: []const u16, options: OpenFileOptions) OpenError!HANDLE { - if (mem.eql(u16, sub_path_w, ".")) { + if (mem.eql(u16, sub_path_w, &[_]u16{'.'})) { return error.IsDir; } - if (mem.eql(u16, sub_path_w, "..")) { + if (mem.eql(u16, sub_path_w, &[_]u16{ '.', '.' })) { return error.IsDir; } @@ -199,7 +199,7 @@ pub fn CreatePipe(rd: *HANDLE, wr: *HANDLE, sattr: *const SECURITY_ATTRIBUTES) C pub fn CreateEventEx(attributes: ?*SECURITY_ATTRIBUTES, name: []const u8, flags: DWORD, desired_access: DWORD) !HANDLE { const nameW = try sliceToPrefixedFileW(name); - return CreateEventExW(attributes, &nameW, flags, desired_access); + return CreateEventExW(attributes, nameW.span().ptr, flags, desired_access); } pub fn CreateEventExW(attributes: ?*SECURITY_ATTRIBUTES, nameW: [*:0]const u16, flags: DWORD, desired_access: DWORD) !HANDLE { @@ -332,42 +332,6 @@ pub fn WaitForMultipleObjectsEx(handles: []const HANDLE, waitAll: bool, millisec } } -pub const FindFirstFileError = error{ - FileNotFound, - InvalidUtf8, - BadPathName, - NameTooLong, - Unexpected, -}; - -pub fn FindFirstFile(dir_path: []const u8, find_file_data: *WIN32_FIND_DATAW) FindFirstFileError!HANDLE { - const dir_path_w = try sliceToPrefixedSuffixedFileW(dir_path, [_]u16{ '\\', '*' }); - const handle = kernel32.FindFirstFileW(&dir_path_w, find_file_data); - - if (handle == INVALID_HANDLE_VALUE) { - switch (kernel32.GetLastError()) { - .FILE_NOT_FOUND => return error.FileNotFound, - .PATH_NOT_FOUND => return error.FileNotFound, - else => |err| return unexpectedError(err), - } - } - - return handle; -} - -pub const FindNextFileError = error{Unexpected}; - -/// Returns `true` if there was another file, `false` otherwise. -pub fn FindNextFile(handle: HANDLE, find_file_data: *WIN32_FIND_DATAW) FindNextFileError!bool { - if (kernel32.FindNextFileW(handle, find_file_data) == 0) { - switch (kernel32.GetLastError()) { - .NO_MORE_FILES => return false, - else => |err| return unexpectedError(err), - } - } - return true; -} - pub const CreateIoCompletionPortError = error{Unexpected}; pub fn CreateIoCompletionPort( @@ -644,7 +608,7 @@ pub fn CreateSymbolicLink( ) CreateSymbolicLinkError!void { const sym_link_path_w = try sliceToPrefixedFileW(sym_link_path); const target_path_w = try sliceToPrefixedFileW(target_path); - return CreateSymbolicLinkW(&sym_link_path_w, &target_path_w, flags); + return CreateSymbolicLinkW(sym_link_path_w.span().ptr, target_path_w.span().ptr, flags); } pub fn CreateSymbolicLinkW( @@ -669,7 +633,7 @@ pub const DeleteFileError = error{ pub fn DeleteFile(filename: []const u8) DeleteFileError!void { const filename_w = try sliceToPrefixedFileW(filename); - return DeleteFileW(&filename_w); + return DeleteFileW(filename_w.span().ptr); } pub fn DeleteFileW(filename: [*:0]const u16) DeleteFileError!void { @@ -691,7 +655,7 @@ pub const MoveFileError = error{Unexpected}; pub fn MoveFileEx(old_path: []const u8, new_path: []const u8, flags: DWORD) MoveFileError!void { const old_path_w = try sliceToPrefixedFileW(old_path); const new_path_w = try sliceToPrefixedFileW(new_path); - return MoveFileExW(&old_path_w, &new_path_w, flags); + return MoveFileExW(old_path_w.span().ptr, new_path_w.span().ptr, flags); } pub fn MoveFileExW(old_path: [*:0]const u16, new_path: [*:0]const u16, flags: DWORD) MoveFileError!void { @@ -716,7 +680,7 @@ pub const CreateDirectoryError = error{ /// Returns an open directory handle which the caller is responsible for closing with `CloseHandle`. pub fn CreateDirectory(dir: ?HANDLE, pathname: []const u8, sa: ?*SECURITY_ATTRIBUTES) CreateDirectoryError!HANDLE { const pathname_w = try sliceToPrefixedFileW(pathname); - return CreateDirectoryW(dir, &pathname_w, sa); + return CreateDirectoryW(dir, pathname_w.span().ptr, sa); } /// Same as `CreateDirectory` except takes a WTF-16 encoded path. @@ -784,7 +748,7 @@ pub const RemoveDirectoryError = error{ pub fn RemoveDirectory(dir_path: []const u8) RemoveDirectoryError!void { const dir_path_w = try sliceToPrefixedFileW(dir_path); - return RemoveDirectoryW(&dir_path_w); + return RemoveDirectoryW(dir_path_w.span().ptr); } pub fn RemoveDirectoryW(dir_path_w: [*:0]const u16) RemoveDirectoryError!void { @@ -913,7 +877,7 @@ pub const GetFileAttributesError = error{ pub fn GetFileAttributes(filename: []const u8) GetFileAttributesError!DWORD { const filename_w = try sliceToPrefixedFileW(filename); - return GetFileAttributesW(&filename_w); + return GetFileAttributesW(filename_w.span().ptr); } pub fn GetFileAttributesW(lpFileName: [*:0]const u16) GetFileAttributesError!DWORD { @@ -1253,34 +1217,22 @@ pub fn nanoSecondsToFileTime(ns: i64) FILETIME { }; } -pub fn cStrToPrefixedFileW(s: [*:0]const u8) ![PATH_MAX_WIDE:0]u16 { +pub const PathSpace = struct { + data: [PATH_MAX_WIDE:0]u16, + len: usize, + + pub fn span(self: PathSpace) [:0]const u16 { + return self.data[0..self.len :0]; + } +}; + +pub fn cStrToPrefixedFileW(s: [*:0]const u8) !PathSpace { return sliceToPrefixedFileW(mem.spanZ(s)); } -pub fn sliceToPrefixedFileW(s: []const u8) ![PATH_MAX_WIDE:0]u16 { - return sliceToPrefixedSuffixedFileW(s, &[_]u16{}); -} - -/// Assumes an absolute path. -pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 { +pub fn sliceToPrefixedFileW(s: []const u8) !PathSpace { // TODO https://github.com/ziglang/zig/issues/2765 - var result: [PATH_MAX_WIDE:0]u16 = undefined; - - const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: { - const prefix = [_]u16{ '\\', '?', '?', '\\' }; - mem.copy(u16, result[0..], &prefix); - break :blk prefix.len; - }; - const end_index = start_index + s.len; - if (end_index + 1 > result.len) return error.NameTooLong; - mem.copy(u16, result[start_index..], s); - result[end_index] = 0; - return result; -} - -pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len:0]u16 { - // TODO https://github.com/ziglang/zig/issues/2765 - var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined; + var path_space: PathSpace = undefined; for (s) |byte| { switch (byte) { '*', '?', '"', '<', '>', '|' => return error.BadPathName, @@ -1289,25 +1241,46 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) } const start_index = if (mem.startsWith(u8, s, "\\?") or !std.fs.path.isAbsolute(s)) 0 else blk: { const prefix = [_]u16{ '\\', '?', '?', '\\' }; - mem.copy(u16, result[0..], &prefix); + mem.copy(u16, path_space.data[0..], &prefix); break :blk prefix.len; }; - const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s); - if (end_index + suffix.len > result.len) return error.NameTooLong; + path_space.len = start_index + try std.unicode.utf8ToUtf16Le(path_space.data[start_index..], s); + if (path_space.len > path_space.data.len) return error.NameTooLong; // > File I/O functions in the Windows API convert "/" to "\" as part of // > converting the name to an NT-style name, except when using the "\\?\" // > prefix as detailed in the following sections. // from https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#maximum-path-length-limitation // Because we want the larger maximum path length for absolute paths, we // convert forward slashes to backward slashes here. - for (result[0..end_index]) |*elem| { + for (path_space.data[0..path_space.len]) |*elem| { if (elem.* == '/') { elem.* = '\\'; } } - mem.copy(u16, result[end_index..], suffix); - result[end_index + suffix.len] = 0; - return result; + path_space.data[path_space.len] = 0; + return path_space; +} + +/// Assumes an absolute path. +pub fn wToPrefixedFileW(s: []const u16) !PathSpace { + // TODO https://github.com/ziglang/zig/issues/2765 + var path_space: PathSpace = undefined; + + const start_index = if (mem.startsWith(u16, s, &[_]u16{ '\\', '?' })) 0 else blk: { + const prefix = [_]u16{ '\\', '?', '?', '\\' }; + mem.copy(u16, path_space.data[0..], &prefix); + break :blk prefix.len; + }; + path_space.len = start_index + s.len; + if (path_space.len > path_space.data.len) return error.NameTooLong; + mem.copy(u16, path_space.data[start_index..], s); + for (path_space.data[0..path_space.len]) |*elem| { + if (elem.* == '/') { + elem.* = '\\'; + } + } + path_space.data[path_space.len] = 0; + return path_space; } inline fn MAKELANGID(p: c_ushort, s: c_ushort) LANGID {