Merge branch 'deingithub-fmt-mode-thingybob'

closes #5617
closes #5616
master
Andrew Kelley 2020-06-18 21:09:32 -04:00
commit b9e3df92db
3 changed files with 45 additions and 10 deletions

View File

@ -1229,14 +1229,9 @@ pub const Dir = struct {
var file = try self.openFile(file_path, .{});
defer file.close();
const size = math.cast(usize, try file.getEndPos()) catch math.maxInt(usize);
if (size > max_bytes) return error.FileTooBig;
const stat_size = try file.getEndPos();
const buf = try allocator.allocWithOptions(u8, size, alignment, optional_sentinel);
errdefer allocator.free(buf);
try file.inStream().readNoEof(buf);
return buf;
return file.readAllAllocOptions(allocator, stat_size, max_bytes, alignment, optional_sentinel);
}
pub const DeleteTreeError = error{

View File

@ -209,7 +209,7 @@ pub const File = struct {
/// TODO: integrate with async I/O
pub fn mode(self: File) ModeError!Mode {
if (builtin.os.tag == .windows) {
return {};
return 0;
}
return (try self.stat()).mode;
}
@ -306,6 +306,33 @@ pub const File = struct {
try os.futimens(self.handle, &times);
}
/// On success, caller owns returned buffer.
/// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
pub fn readAllAlloc(self: File, allocator: *mem.Allocator, stat_size: u64, max_bytes: usize) ![]u8 {
return self.readAllAllocOptions(allocator, stat_size, max_bytes, @alignOf(u8), null);
}
/// On success, caller owns returned buffer.
/// If the file is larger than `max_bytes`, returns `error.FileTooBig`.
/// Allows specifying alignment and a sentinel value.
pub fn readAllAllocOptions(
self: File,
allocator: *mem.Allocator,
stat_size: u64,
max_bytes: usize,
comptime alignment: u29,
comptime optional_sentinel: ?u8,
) !(if (optional_sentinel) |s| [:s]align(alignment) u8 else []align(alignment) u8) {
const size = math.cast(usize, stat_size) catch math.maxInt(usize);
if (size > max_bytes) return error.FileTooBig;
const buf = try allocator.allocWithOptions(u8, size, alignment, optional_sentinel);
errdefer allocator.free(buf);
try self.inStream().readNoEof(buf);
return buf;
}
pub const ReadError = os.ReadError;
pub const PReadError = os.PReadError;

View File

@ -684,7 +684,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
if (fmt.seen.exists(real_path)) return;
try fmt.seen.put(real_path);
const source_code = fs.cwd().readFileAlloc(fmt.gpa, real_path, max_src_size) catch |err| switch (err) {
const source_file = fs.cwd().openFile(real_path, .{}) catch |err| switch (err) {
error.IsDir, error.AccessDenied => {
var dir = try fs.cwd().openDir(file_path, .{ .iterate = true });
defer dir.close();
@ -705,6 +705,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
return;
},
};
defer source_file.close();
const stat = source_file.stat() catch |err| {
std.debug.warn("unable to stat '{}': {}\n", .{ file_path, err });
fmt.any_error = true;
return;
};
const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| {
std.debug.warn("unable to read '{}': {}\n", .{ file_path, err });
fmt.any_error = true;
return;
};
defer fmt.gpa.free(source_code);
const tree = std.zig.parse(fmt.gpa, source_code) catch |err| {
@ -729,7 +742,7 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
fmt.any_error = true;
}
} else {
const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{});
const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{ .mode = stat.mode });
defer baf.destroy();
const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree);