Merge pull request #5187 from ziglang/squeek502-windows-fmt-relative
zig fmt: Fix relative paths with . and .. on Windows as well as forward slashesmaster
commit
ecdf75d04e
|
@ -15,8 +15,12 @@ pub const BufferedAtomicFile = struct {
|
||||||
|
|
||||||
/// TODO when https://github.com/ziglang/zig/issues/2761 is solved
|
/// TODO when https://github.com/ziglang/zig/issues/2761 is solved
|
||||||
/// this API will not need an allocator
|
/// this API will not need an allocator
|
||||||
/// TODO integrate this with Dir API
|
pub fn create(
|
||||||
pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile {
|
allocator: *mem.Allocator,
|
||||||
|
dir: fs.Dir,
|
||||||
|
dest_path: []const u8,
|
||||||
|
atomic_file_options: fs.Dir.AtomicFileOptions,
|
||||||
|
) !*BufferedAtomicFile {
|
||||||
var self = try allocator.create(BufferedAtomicFile);
|
var self = try allocator.create(BufferedAtomicFile);
|
||||||
self.* = BufferedAtomicFile{
|
self.* = BufferedAtomicFile{
|
||||||
.atomic_file = undefined,
|
.atomic_file = undefined,
|
||||||
|
@ -26,7 +30,7 @@ pub const BufferedAtomicFile = struct {
|
||||||
};
|
};
|
||||||
errdefer allocator.destroy(self);
|
errdefer allocator.destroy(self);
|
||||||
|
|
||||||
self.atomic_file = try fs.cwd().atomicFile(dest_path, .{});
|
self.atomic_file = try dir.atomicFile(dest_path, atomic_file_options);
|
||||||
errdefer self.atomic_file.deinit();
|
errdefer self.atomic_file.deinit();
|
||||||
|
|
||||||
self.file_stream = self.atomic_file.file.outStream();
|
self.file_stream = self.atomic_file.file.outStream();
|
||||||
|
|
|
@ -1260,15 +1260,9 @@ pub fn wToPrefixedFileW(s: []const u16) ![PATH_MAX_WIDE:0]u16 {
|
||||||
pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16) ![PATH_MAX_WIDE + suffix.len:0]u16 {
|
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
|
// TODO https://github.com/ziglang/zig/issues/2765
|
||||||
var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined;
|
var result: [PATH_MAX_WIDE + suffix.len:0]u16 = undefined;
|
||||||
// > 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
|
|
||||||
// disallow forward slashes in zig std lib file functions on Windows.
|
|
||||||
for (s) |byte| {
|
for (s) |byte| {
|
||||||
switch (byte) {
|
switch (byte) {
|
||||||
'/', '*', '?', '"', '<', '>', '|' => return error.BadPathName,
|
'*', '?', '"', '<', '>', '|' => return error.BadPathName,
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1279,6 +1273,17 @@ pub fn sliceToPrefixedSuffixedFileW(s: []const u8, comptime suffix: []const u16)
|
||||||
};
|
};
|
||||||
const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);
|
const end_index = start_index + try std.unicode.utf8ToUtf16Le(result[start_index..], s);
|
||||||
if (end_index + suffix.len > result.len) return error.NameTooLong;
|
if (end_index + suffix.len > result.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| {
|
||||||
|
if (elem.* == '/') {
|
||||||
|
elem.* = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
mem.copy(u16, result[end_index..], suffix);
|
mem.copy(u16, result[end_index..], suffix);
|
||||||
result[end_index + suffix.len] = 0;
|
result[end_index + suffix.len] = 0;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -318,11 +318,18 @@ const FmtError = error{
|
||||||
} || fs.File.OpenError;
|
} || fs.File.OpenError;
|
||||||
|
|
||||||
fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
|
fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
|
||||||
if (fmt.seen.exists(file_path)) return;
|
// get the real path here to avoid Windows failing on relative file paths with . or .. in them
|
||||||
try fmt.seen.put(file_path);
|
var real_path = fs.realpathAlloc(fmt.allocator, file_path) catch |err| {
|
||||||
|
try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
|
||||||
|
fmt.any_error = true;
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
defer fmt.allocator.free(real_path);
|
||||||
|
|
||||||
const max = std.math.maxInt(usize);
|
if (fmt.seen.exists(real_path)) return;
|
||||||
const source_code = fs.cwd().readFileAlloc(fmt.allocator, file_path, max) catch |err| switch (err) {
|
try fmt.seen.put(real_path);
|
||||||
|
|
||||||
|
const source_code = fs.cwd().readFileAlloc(fmt.allocator, real_path, self_hosted_main.max_src_size) catch |err| switch (err) {
|
||||||
error.IsDir, error.AccessDenied => {
|
error.IsDir, error.AccessDenied => {
|
||||||
// TODO make event based (and dir.next())
|
// TODO make event based (and dir.next())
|
||||||
var dir = try fs.cwd().openDir(file_path, .{ .iterate = true });
|
var dir = try fs.cwd().openDir(file_path, .{ .iterate = true });
|
||||||
|
@ -370,7 +377,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
|
||||||
fmt.any_error = true;
|
fmt.any_error = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
|
const baf = try io.BufferedAtomicFile.create(fmt.allocator, fs.cwd(), real_path, .{});
|
||||||
defer baf.destroy();
|
defer baf.destroy();
|
||||||
|
|
||||||
const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
|
const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
|
||||||
|
|
Loading…
Reference in New Issue