| author | |
| committer | |
| log | edea7a46e5484e30c338699207c8f4b4d8370c97 |
| tree | af5d6b5650fe48c56d22a38e54db74e3871c98a8 |
| parent | 5229f6ec68708c3e66393a50ad9f9032ee7f4257 |
| parent | faf783e5959a09fb2a1680f8bb7558db96dcbed9 |
closes #56489 files changed, 200 insertions(+), 132 deletions(-)
lib/std/array_list.zig+1-1| ... | @@ -162,7 +162,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { | ... | @@ -162,7 +162,7 @@ pub fn ArrayListAligned(comptime T: type, comptime alignment: ?u29) type { |
| 162 | mem.copy(T, self.items[oldlen..], items); | 162 | mem.copy(T, self.items[oldlen..], items); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | pub usingnamespace if (T != u8) struct { } else struct { | 165 | pub usingnamespace if (T != u8) struct {} else struct { |
| 166 | pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite); | 166 | pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite); |
| 167 | 167 | ||
| 168 | /// Initializes a Writer which will append to the list. | 168 | /// Initializes a Writer which will append to the list. |
lib/std/c/tokenizer.zig+50-50| ... | @@ -278,62 +278,62 @@ pub const Token = struct { | ... | @@ -278,62 +278,62 @@ pub const Token = struct { |
| 278 | 278 | ||
| 279 | // TODO extensions | 279 | // TODO extensions |
| 280 | pub const keywords = std.ComptimeStringMap(Id, .{ | 280 | pub const keywords = std.ComptimeStringMap(Id, .{ |
| 281 | .{"auto", .Keyword_auto}, | 281 | .{ "auto", .Keyword_auto }, |
| 282 | .{"break", .Keyword_break}, | 282 | .{ "break", .Keyword_break }, |
| 283 | .{"case", .Keyword_case}, | 283 | .{ "case", .Keyword_case }, |
| 284 | .{"char", .Keyword_char}, | 284 | .{ "char", .Keyword_char }, |
| 285 | .{"const", .Keyword_const}, | 285 | .{ "const", .Keyword_const }, |
| 286 | .{"continue", .Keyword_continue}, | 286 | .{ "continue", .Keyword_continue }, |
| 287 | .{"default", .Keyword_default}, | 287 | .{ "default", .Keyword_default }, |
| 288 | .{"do", .Keyword_do}, | 288 | .{ "do", .Keyword_do }, |
| 289 | .{"double", .Keyword_double}, | 289 | .{ "double", .Keyword_double }, |
| 290 | .{"else", .Keyword_else}, | 290 | .{ "else", .Keyword_else }, |
| 291 | .{"enum", .Keyword_enum}, | 291 | .{ "enum", .Keyword_enum }, |
| 292 | .{"extern", .Keyword_extern}, | 292 | .{ "extern", .Keyword_extern }, |
| 293 | .{"float", .Keyword_float}, | 293 | .{ "float", .Keyword_float }, |
| 294 | .{"for", .Keyword_for}, | 294 | .{ "for", .Keyword_for }, |
| 295 | .{"goto", .Keyword_goto}, | 295 | .{ "goto", .Keyword_goto }, |
| 296 | .{"if", .Keyword_if}, | 296 | .{ "if", .Keyword_if }, |
| 297 | .{"int", .Keyword_int}, | 297 | .{ "int", .Keyword_int }, |
| 298 | .{"long", .Keyword_long}, | 298 | .{ "long", .Keyword_long }, |
| 299 | .{"register", .Keyword_register}, | 299 | .{ "register", .Keyword_register }, |
| 300 | .{"return", .Keyword_return}, | 300 | .{ "return", .Keyword_return }, |
| 301 | .{"short", .Keyword_short}, | 301 | .{ "short", .Keyword_short }, |
| 302 | .{"signed", .Keyword_signed}, | 302 | .{ "signed", .Keyword_signed }, |
| 303 | .{"sizeof", .Keyword_sizeof}, | 303 | .{ "sizeof", .Keyword_sizeof }, |
| 304 | .{"static", .Keyword_static}, | 304 | .{ "static", .Keyword_static }, |
| 305 | .{"struct", .Keyword_struct}, | 305 | .{ "struct", .Keyword_struct }, |
| 306 | .{"switch", .Keyword_switch}, | 306 | .{ "switch", .Keyword_switch }, |
| 307 | .{"typedef", .Keyword_typedef}, | 307 | .{ "typedef", .Keyword_typedef }, |
| 308 | .{"union", .Keyword_union}, | 308 | .{ "union", .Keyword_union }, |
| 309 | .{"unsigned", .Keyword_unsigned}, | 309 | .{ "unsigned", .Keyword_unsigned }, |
| 310 | .{"void", .Keyword_void}, | 310 | .{ "void", .Keyword_void }, |
| 311 | .{"volatile", .Keyword_volatile}, | 311 | .{ "volatile", .Keyword_volatile }, |
| 312 | .{"while", .Keyword_while}, | 312 | .{ "while", .Keyword_while }, |
| 313 | 313 | ||
| 314 | // ISO C99 | 314 | // ISO C99 |
| 315 | .{"_Bool", .Keyword_bool}, | 315 | .{ "_Bool", .Keyword_bool }, |
| 316 | .{"_Complex", .Keyword_complex}, | 316 | .{ "_Complex", .Keyword_complex }, |
| 317 | .{"_Imaginary", .Keyword_imaginary}, | 317 | .{ "_Imaginary", .Keyword_imaginary }, |
| 318 | .{"inline", .Keyword_inline}, | 318 | .{ "inline", .Keyword_inline }, |
| 319 | .{"restrict", .Keyword_restrict}, | 319 | .{ "restrict", .Keyword_restrict }, |
| 320 | 320 | ||
| 321 | // ISO C11 | 321 | // ISO C11 |
| 322 | .{"_Alignas", .Keyword_alignas}, | 322 | .{ "_Alignas", .Keyword_alignas }, |
| 323 | .{"_Alignof", .Keyword_alignof}, | 323 | .{ "_Alignof", .Keyword_alignof }, |
| 324 | .{"_Atomic", .Keyword_atomic}, | 324 | .{ "_Atomic", .Keyword_atomic }, |
| 325 | .{"_Generic", .Keyword_generic}, | 325 | .{ "_Generic", .Keyword_generic }, |
| 326 | .{"_Noreturn", .Keyword_noreturn}, | 326 | .{ "_Noreturn", .Keyword_noreturn }, |
| 327 | .{"_Static_assert", .Keyword_static_assert}, | 327 | .{ "_Static_assert", .Keyword_static_assert }, |
| 328 | .{"_Thread_local", .Keyword_thread_local}, | 328 | .{ "_Thread_local", .Keyword_thread_local }, |
| 329 | 329 | ||
| 330 | // Preprocessor directives | 330 | // Preprocessor directives |
| 331 | .{"include", .Keyword_include}, | 331 | .{ "include", .Keyword_include }, |
| 332 | .{"define", .Keyword_define}, | 332 | .{ "define", .Keyword_define }, |
| 333 | .{"ifdef", .Keyword_ifdef}, | 333 | .{ "ifdef", .Keyword_ifdef }, |
| 334 | .{"ifndef", .Keyword_ifndef}, | 334 | .{ "ifndef", .Keyword_ifndef }, |
| 335 | .{"error", .Keyword_error}, | 335 | .{ "error", .Keyword_error }, |
| 336 | .{"pragma", .Keyword_pragma}, | 336 | .{ "pragma", .Keyword_pragma }, |
| 337 | }); | 337 | }); |
| 338 | 338 | ||
| 339 | // TODO do this in the preprocessor | 339 | // TODO do this in the preprocessor |
lib/std/fs.zig+15-14| ... | @@ -261,17 +261,7 @@ pub const Dir = struct { | ... | @@ -261,17 +261,7 @@ pub const Dir = struct { |
| 261 | name: []const u8, | 261 | name: []const u8, |
| 262 | kind: Kind, | 262 | kind: Kind, |
| 263 | 263 | ||
| 264 | pub const Kind = enum { | 264 | pub const Kind = File.Kind; |
| 265 | BlockDevice, | ||
| 266 | CharacterDevice, | ||
| 267 | Directory, | ||
| 268 | NamedPipe, | ||
| 269 | SymLink, | ||
| 270 | File, | ||
| 271 | UnixDomainSocket, | ||
| 272 | Whiteout, | ||
| 273 | Unknown, | ||
| 274 | }; | ||
| 275 | }; | 265 | }; |
| 276 | 266 | ||
| 277 | const IteratorError = error{AccessDenied} || os.UnexpectedError; | 267 | const IteratorError = error{AccessDenied} || os.UnexpectedError; |
| ... | @@ -1527,9 +1517,9 @@ pub const Dir = struct { | ... | @@ -1527,9 +1517,9 @@ pub const Dir = struct { |
| 1527 | 1517 | ||
| 1528 | var size: ?u64 = null; | 1518 | var size: ?u64 = null; |
| 1529 | const mode = options.override_mode orelse blk: { | 1519 | const mode = options.override_mode orelse blk: { |
| 1530 | const stat = try in_file.stat(); | 1520 | const st = try in_file.stat(); |
| 1531 | size = stat.size; | 1521 | size = st.size; |
| 1532 | break :blk stat.mode; | 1522 | break :blk st.mode; |
| 1533 | }; | 1523 | }; |
| 1534 | 1524 | ||
| 1535 | var atomic_file = try dest_dir.atomicFile(dest_path, .{ .mode = mode }); | 1525 | var atomic_file = try dest_dir.atomicFile(dest_path, .{ .mode = mode }); |
| ... | @@ -1555,6 +1545,17 @@ pub const Dir = struct { | ... | @@ -1555,6 +1545,17 @@ pub const Dir = struct { |
| 1555 | return AtomicFile.init(dest_path, options.mode, self, false); | 1545 | return AtomicFile.init(dest_path, options.mode, self, false); |
| 1556 | } | 1546 | } |
| 1557 | } | 1547 | } |
| 1548 | |||
| 1549 | pub const Stat = File.Stat; | ||
| 1550 | pub const StatError = File.StatError; | ||
| 1551 | |||
| 1552 | pub fn stat(self: Dir) StatError!Stat { | ||
| 1553 | const file: File = .{ | ||
| 1554 | .handle = self.fd, | ||
| 1555 | .capable_io_mode = .blocking, | ||
| 1556 | }; | ||
| 1557 | return file.stat(); | ||
| 1558 | } | ||
| 1558 | }; | 1559 | }; |
| 1559 | 1560 | ||
| 1560 | /// Returns an handle to the current working directory. It is not opened with iteration capability. | 1561 | /// Returns an handle to the current working directory. It is not opened with iteration capability. |
lib/std/fs/file.zig+36-1| ... | @@ -29,6 +29,18 @@ pub const File = struct { | ... | @@ -29,6 +29,18 @@ pub const File = struct { |
| 29 | pub const Mode = os.mode_t; | 29 | pub const Mode = os.mode_t; |
| 30 | pub const INode = os.ino_t; | 30 | pub const INode = os.ino_t; |
| 31 | 31 | ||
| 32 | pub const Kind = enum { | ||
| 33 | BlockDevice, | ||
| 34 | CharacterDevice, | ||
| 35 | Directory, | ||
| 36 | NamedPipe, | ||
| 37 | SymLink, | ||
| 38 | File, | ||
| 39 | UnixDomainSocket, | ||
| 40 | Whiteout, | ||
| 41 | Unknown, | ||
| 42 | }; | ||
| 43 | |||
| 32 | pub const default_mode = switch (builtin.os.tag) { | 44 | pub const default_mode = switch (builtin.os.tag) { |
| 33 | .windows => 0, | 45 | .windows => 0, |
| 34 | .wasi => 0, | 46 | .wasi => 0, |
| ... | @@ -219,13 +231,14 @@ pub const File = struct { | ... | @@ -219,13 +231,14 @@ pub const File = struct { |
| 219 | /// unique across time, as some file systems may reuse an inode after its file has been deleted. | 231 | /// unique across time, as some file systems may reuse an inode after its file has been deleted. |
| 220 | /// Some systems may change the inode of a file over time. | 232 | /// Some systems may change the inode of a file over time. |
| 221 | /// | 233 | /// |
| 222 | /// On Linux, the inode _is_ structure that stores the metadata, and the inode _number_ is what | 234 | /// On Linux, the inode is a structure that stores the metadata, and the inode _number_ is what |
| 223 | /// you see here: the index number of the inode. | 235 | /// you see here: the index number of the inode. |
| 224 | /// | 236 | /// |
| 225 | /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. | 237 | /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. |
| 226 | inode: INode, | 238 | inode: INode, |
| 227 | size: u64, | 239 | size: u64, |
| 228 | mode: Mode, | 240 | mode: Mode, |
| 241 | kind: Kind, | ||
| 229 | 242 | ||
| 230 | /// Access time in nanoseconds, relative to UTC 1970-01-01. | 243 | /// Access time in nanoseconds, relative to UTC 1970-01-01. |
| 231 | atime: i128, | 244 | atime: i128, |
| ... | @@ -254,6 +267,7 @@ pub const File = struct { | ... | @@ -254,6 +267,7 @@ pub const File = struct { |
| 254 | .inode = info.InternalInformation.IndexNumber, | 267 | .inode = info.InternalInformation.IndexNumber, |
| 255 | .size = @bitCast(u64, info.StandardInformation.EndOfFile), | 268 | .size = @bitCast(u64, info.StandardInformation.EndOfFile), |
| 256 | .mode = 0, | 269 | .mode = 0, |
| 270 | .kind = if (info.StandardInformation.Directory == 0) .File else .Directory, | ||
| 257 | .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime), | 271 | .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime), |
| 258 | .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime), | 272 | .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime), |
| 259 | .ctime = windows.fromSysTime(info.BasicInformation.CreationTime), | 273 | .ctime = windows.fromSysTime(info.BasicInformation.CreationTime), |
| ... | @@ -268,6 +282,27 @@ pub const File = struct { | ... | @@ -268,6 +282,27 @@ pub const File = struct { |
| 268 | .inode = st.ino, | 282 | .inode = st.ino, |
| 269 | .size = @bitCast(u64, st.size), | 283 | .size = @bitCast(u64, st.size), |
| 270 | .mode = st.mode, | 284 | .mode = st.mode, |
| 285 | .kind = switch (builtin.os.tag) { | ||
| 286 | .wasi => switch (st.filetype) { | ||
| 287 | os.FILETYPE_BLOCK_DEVICE => Kind.BlockDevice, | ||
| 288 | os.FILETYPE_CHARACTER_DEVICE => Kind.CharacterDevice, | ||
| 289 | os.FILETYPE_DIRECTORY => Kind.Directory, | ||
| 290 | os.FILETYPE_SYMBOLIC_LINK => Kind.SymLink, | ||
| 291 | os.FILETYPE_REGULAR_FILE => Kind.File, | ||
| 292 | os.FILETYPE_SOCKET_STREAM, os.FILETYPE_SOCKET_DGRAM => Kind.UnixDomainSocket, | ||
| 293 | else => Kind.Unknown, | ||
| 294 | }, | ||
| 295 | else => switch (st.mode & os.S_IFMT) { | ||
| 296 | os.S_IFBLK => Kind.BlockDevice, | ||
| 297 | os.S_IFCHR => Kind.CharacterDevice, | ||
| 298 | os.S_IFDIR => Kind.Directory, | ||
| 299 | os.S_IFIFO => Kind.NamedPipe, | ||
| 300 | os.S_IFLNK => Kind.SymLink, | ||
| 301 | os.S_IFREG => Kind.File, | ||
| 302 | os.S_IFSOCK => Kind.UnixDomainSocket, | ||
| 303 | else => Kind.Unknown, | ||
| 304 | }, | ||
| 305 | }, | ||
| 271 | .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, | 306 | .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, |
| 272 | .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, | 307 | .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, |
| 273 | .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec, | 308 | .ctime = @as(i128, ctime.tv_sec) * std.time.ns_per_s + ctime.tv_nsec, |
lib/std/io/buffered_out_stream.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | pub const BufferedOutStream = @import("./buffered_writer.zig").BufferedWriter; | 2 | pub const BufferedOutStream = @import("./buffered_writer.zig").BufferedWriter; |
| 3 | 3 | ||
| 4 | /// Deprecated: use `std.io.buffered_writer.bufferedWriter` | 4 | /// Deprecated: use `std.io.buffered_writer.bufferedWriter` |
| 5 | pub const bufferedOutStream = @import("./buffered_writer.zig").bufferedWriter | 5 | pub const bufferedOutStream = @import("./buffered_writer.zig").bufferedWriter; |
lib/std/json.zig+2-3| ... | @@ -2576,8 +2576,8 @@ pub fn stringify( | ... | @@ -2576,8 +2576,8 @@ pub fn stringify( |
| 2576 | }, | 2576 | }, |
| 2577 | .Array => return stringify(&value, options, out_stream), | 2577 | .Array => return stringify(&value, options, out_stream), |
| 2578 | .Vector => |info| { | 2578 | .Vector => |info| { |
| 2579 | const array: [info.len]info.child = value; | 2579 | const array: [info.len]info.child = value; |
| 2580 | return stringify(&array, options, out_stream); | 2580 | return stringify(&array, options, out_stream); |
| 2581 | }, | 2581 | }, |
| 2582 | else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"), | 2582 | else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"), |
| 2583 | } | 2583 | } |
| ... | @@ -2770,4 +2770,3 @@ test "stringify struct with custom stringifier" { | ... | @@ -2770,4 +2770,3 @@ test "stringify struct with custom stringifier" { |
| 2770 | test "stringify vector" { | 2770 | test "stringify vector" { |
| 2771 | try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); | 2771 | try teststringify("[1,1]", @splat(2, @as(u32, 1)), StringifyOptions{}); |
| 2772 | } | 2772 | } |
| 2773 |
lib/std/os/windows/ws2_32.zig+9-9| ... | @@ -163,16 +163,16 @@ pub const IPPROTO_UDP = 17; | ... | @@ -163,16 +163,16 @@ pub const IPPROTO_UDP = 17; |
| 163 | pub const IPPROTO_ICMPV6 = 58; | 163 | pub const IPPROTO_ICMPV6 = 58; |
| 164 | pub const IPPROTO_RM = 113; | 164 | pub const IPPROTO_RM = 113; |
| 165 | 165 | ||
| 166 | pub const AI_PASSIVE = 0x00001; | 166 | pub const AI_PASSIVE = 0x00001; |
| 167 | pub const AI_CANONNAME = 0x00002; | 167 | pub const AI_CANONNAME = 0x00002; |
| 168 | pub const AI_NUMERICHOST = 0x00004; | 168 | pub const AI_NUMERICHOST = 0x00004; |
| 169 | pub const AI_NUMERICSERV = 0x00008; | 169 | pub const AI_NUMERICSERV = 0x00008; |
| 170 | pub const AI_ADDRCONFIG = 0x00400; | 170 | pub const AI_ADDRCONFIG = 0x00400; |
| 171 | pub const AI_V4MAPPED = 0x00800; | 171 | pub const AI_V4MAPPED = 0x00800; |
| 172 | pub const AI_NON_AUTHORITATIVE = 0x04000; | 172 | pub const AI_NON_AUTHORITATIVE = 0x04000; |
| 173 | pub const AI_SECURE = 0x08000; | 173 | pub const AI_SECURE = 0x08000; |
| 174 | pub const AI_RETURN_PREFERRED_NAMES = 0x10000; | 174 | pub const AI_RETURN_PREFERRED_NAMES = 0x10000; |
| 175 | pub const AI_DISABLE_IDN_ENCODING = 0x80000; | 175 | pub const AI_DISABLE_IDN_ENCODING = 0x80000; |
| 176 | 176 | ||
| 177 | pub const FIONBIO = -2147195266; | 177 | pub const FIONBIO = -2147195266; |
| 178 | 178 |
lib/std/zig/parse.zig-1| ... | @@ -937,7 +937,6 @@ const Parser = struct { | ... | @@ -937,7 +937,6 @@ const Parser = struct { |
| 937 | return node; | 937 | return node; |
| 938 | } | 938 | } |
| 939 | 939 | ||
| 940 | |||
| 941 | while_prefix.body = try p.expectNode(parseAssignExpr, .{ | 940 | while_prefix.body = try p.expectNode(parseAssignExpr, .{ |
| 942 | .ExpectedBlockOrAssignment = .{ .token = p.tok_i }, | 941 | .ExpectedBlockOrAssignment = .{ .token = p.tok_i }, |
| 943 | }); | 942 | }); |
src-self-hosted/main.zig+86-52| ... | @@ -546,8 +546,9 @@ const Fmt = struct { | ... | @@ -546,8 +546,9 @@ const Fmt = struct { |
| 546 | any_error: bool, | 546 | any_error: bool, |
| 547 | color: Color, | 547 | color: Color, |
| 548 | gpa: *Allocator, | 548 | gpa: *Allocator, |
| 549 | out_buffer: std.ArrayList(u8), | ||
| 549 | 550 | ||
| 550 | const SeenMap = std.BufSet; | 551 | const SeenMap = std.AutoHashMap(fs.File.INode, void); |
| 551 | }; | 552 | }; |
| 552 | 553 | ||
| 553 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | 554 | pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| ... | @@ -641,10 +642,20 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { | ... | @@ -641,10 +642,20 @@ pub fn cmdFmt(gpa: *Allocator, args: []const []const u8) !void { |
| 641 | .seen = Fmt.SeenMap.init(gpa), | 642 | .seen = Fmt.SeenMap.init(gpa), |
| 642 | .any_error = false, | 643 | .any_error = false, |
| 643 | .color = color, | 644 | .color = color, |
| 645 | .out_buffer = std.ArrayList(u8).init(gpa), | ||
| 644 | }; | 646 | }; |
| 647 | defer fmt.seen.deinit(); | ||
| 648 | defer fmt.out_buffer.deinit(); | ||
| 645 | 649 | ||
| 646 | for (input_files.span()) |file_path| { | 650 | for (input_files.span()) |file_path| { |
| 647 | try fmtPath(&fmt, file_path, check_flag); | 651 | // Get the real path here to avoid Windows failing on relative file paths with . or .. in them. |
| 652 | const real_path = fs.realpathAlloc(gpa, file_path) catch |err| { | ||
| 653 | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); | ||
| 654 | process.exit(1); | ||
| 655 | }; | ||
| 656 | defer gpa.free(real_path); | ||
| 657 | |||
| 658 | try fmtPath(&fmt, file_path, check_flag, fs.cwd(), real_path); | ||
| 648 | } | 659 | } |
| 649 | if (fmt.any_error) { | 660 | if (fmt.any_error) { |
| 650 | process.exit(1); | 661 | process.exit(1); |
| ... | @@ -670,61 +681,79 @@ const FmtError = error{ | ... | @@ -670,61 +681,79 @@ const FmtError = error{ |
| 670 | ReadOnlyFileSystem, | 681 | ReadOnlyFileSystem, |
| 671 | LinkQuotaExceeded, | 682 | LinkQuotaExceeded, |
| 672 | FileBusy, | 683 | FileBusy, |
| 684 | EndOfStream, | ||
| 673 | } || fs.File.OpenError; | 685 | } || fs.File.OpenError; |
| 674 | 686 | ||
| 675 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | 687 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) FmtError!void { |
| 676 | // get the real path here to avoid Windows failing on relative file paths with . or .. in them | 688 | fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) { |
| 677 | var real_path = fs.realpathAlloc(fmt.gpa, file_path) catch |err| { | 689 | error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path), |
| 678 | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); | ||
| 679 | fmt.any_error = true; | ||
| 680 | return; | ||
| 681 | }; | ||
| 682 | defer fmt.gpa.free(real_path); | ||
| 683 | |||
| 684 | if (fmt.seen.exists(real_path)) return; | ||
| 685 | try fmt.seen.put(real_path); | ||
| 686 | |||
| 687 | const source_file = fs.cwd().openFile(real_path, .{}) catch |err| switch (err) { | ||
| 688 | error.IsDir, error.AccessDenied => { | ||
| 689 | var dir = try fs.cwd().openDir(file_path, .{ .iterate = true }); | ||
| 690 | defer dir.close(); | ||
| 691 | |||
| 692 | var dir_it = dir.iterate(); | ||
| 693 | |||
| 694 | while (try dir_it.next()) |entry| { | ||
| 695 | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { | ||
| 696 | const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); | ||
| 697 | try fmtPath(fmt, full_path, check_mode); | ||
| 698 | } | ||
| 699 | } | ||
| 700 | return; | ||
| 701 | }, | ||
| 702 | else => { | 690 | else => { |
| 703 | std.debug.warn("unable to open '{}': {}\n", .{ file_path, err }); | 691 | std.debug.warn("unable to format '{}': {}\n", .{ file_path, err }); |
| 704 | fmt.any_error = true; | 692 | fmt.any_error = true; |
| 705 | return; | 693 | return; |
| 706 | }, | 694 | }, |
| 707 | }; | 695 | }; |
| 696 | } | ||
| 697 | |||
| 698 | fn fmtPathDir( | ||
| 699 | fmt: *Fmt, | ||
| 700 | file_path: []const u8, | ||
| 701 | check_mode: bool, | ||
| 702 | parent_dir: fs.Dir, | ||
| 703 | parent_sub_path: []const u8, | ||
| 704 | ) FmtError!void { | ||
| 705 | var dir = try parent_dir.openDir(parent_sub_path, .{ .iterate = true }); | ||
| 706 | defer dir.close(); | ||
| 707 | |||
| 708 | const stat = try dir.stat(); | ||
| 709 | if (try fmt.seen.put(stat.inode, {})) |_| return; | ||
| 710 | |||
| 711 | var dir_it = dir.iterate(); | ||
| 712 | while (try dir_it.next()) |entry| { | ||
| 713 | const is_dir = entry.kind == .Directory; | ||
| 714 | if (is_dir or mem.endsWith(u8, entry.name, ".zig")) { | ||
| 715 | const full_path = try fs.path.join(fmt.gpa, &[_][]const u8{ file_path, entry.name }); | ||
| 716 | defer fmt.gpa.free(full_path); | ||
| 717 | |||
| 718 | if (is_dir) { | ||
| 719 | try fmtPathDir(fmt, full_path, check_mode, dir, entry.name); | ||
| 720 | } else { | ||
| 721 | fmtPathFile(fmt, full_path, check_mode, dir, entry.name) catch |err| { | ||
| 722 | std.debug.warn("unable to format '{}': {}\n", .{ full_path, err }); | ||
| 723 | fmt.any_error = true; | ||
| 724 | return; | ||
| 725 | }; | ||
| 726 | } | ||
| 727 | } | ||
| 728 | } | ||
| 729 | } | ||
| 730 | |||
| 731 | fn fmtPathFile( | ||
| 732 | fmt: *Fmt, | ||
| 733 | file_path: []const u8, | ||
| 734 | check_mode: bool, | ||
| 735 | dir: fs.Dir, | ||
| 736 | sub_path: []const u8, | ||
| 737 | ) FmtError!void { | ||
| 738 | const source_file = try dir.openFile(sub_path, .{}); | ||
| 708 | defer source_file.close(); | 739 | defer source_file.close(); |
| 709 | 740 | ||
| 710 | const stat = source_file.stat() catch |err| { | 741 | const stat = try source_file.stat(); |
| 711 | std.debug.warn("unable to stat '{}': {}\n", .{ file_path, err }); | ||
| 712 | fmt.any_error = true; | ||
| 713 | return; | ||
| 714 | }; | ||
| 715 | 742 | ||
| 716 | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| { | 743 | if (stat.kind == .Directory) |
| 717 | std.debug.warn("unable to read '{}': {}\n", .{ file_path, err }); | 744 | return error.IsDir; |
| 718 | fmt.any_error = true; | 745 | |
| 719 | return; | 746 | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| switch (err) { |
| 747 | error.ConnectionResetByPeer => unreachable, | ||
| 748 | error.ConnectionTimedOut => unreachable, | ||
| 749 | else => |e| return e, | ||
| 720 | }; | 750 | }; |
| 721 | defer fmt.gpa.free(source_code); | 751 | defer fmt.gpa.free(source_code); |
| 722 | 752 | ||
| 723 | const tree = std.zig.parse(fmt.gpa, source_code) catch |err| { | 753 | // Add to set after no longer possible to get error.IsDir. |
| 724 | std.debug.warn("error parsing file '{}': {}\n", .{ file_path, err }); | 754 | if (try fmt.seen.put(stat.inode, {})) |_| return; |
| 725 | fmt.any_error = true; | 755 | |
| 726 | return; | 756 | const tree = try std.zig.parse(fmt.gpa, source_code); |
| 727 | }; | ||
| 728 | defer tree.deinit(); | 757 | defer tree.deinit(); |
| 729 | 758 | ||
| 730 | for (tree.errors) |parse_error| { | 759 | for (tree.errors) |parse_error| { |
| ... | @@ -742,14 +771,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | ... | @@ -742,14 +771,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 742 | fmt.any_error = true; | 771 | fmt.any_error = true; |
| 743 | } | 772 | } |
| 744 | } else { | 773 | } else { |
| 745 | const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{ .mode = stat.mode }); | 774 | // As a heuristic, we make enough capacity for the same as the input source. |
| 746 | defer baf.destroy(); | 775 | try fmt.out_buffer.ensureCapacity(source_code.len); |
| 747 | 776 | fmt.out_buffer.items.len = 0; | |
| 748 | const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree); | 777 | const anything_changed = try std.zig.render(fmt.gpa, fmt.out_buffer.writer(), tree); |
| 749 | if (anything_changed) { | 778 | if (!anything_changed) |
| 750 | std.debug.warn("{}\n", .{file_path}); | 779 | return; // Good thing we didn't waste any file system access on this. |
| 751 | try baf.finish(); | 780 | |
| 752 | } | 781 | var af = try dir.atomicFile(sub_path, .{ .mode = stat.mode }); |
| 782 | defer af.deinit(); | ||
| 783 | |||
| 784 | try af.file.writeAll(fmt.out_buffer.items); | ||
| 785 | try af.finish(); | ||
| 786 | std.debug.warn("{}\n", .{file_path}); | ||
| 753 | } | 787 | } |
| 754 | } | 788 | } |
| 755 | 789 |