| 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 | 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 | 166 | pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite); |
| 167 | 167 | |
| 168 | 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 | 278 | |
| 279 | 279 | // TODO extensions |
| 280 | 280 | pub const keywords = std.ComptimeStringMap(Id, .{ |
| 281 | .{"auto", .Keyword_auto}, | |
| 282 | .{"break", .Keyword_break}, | |
| 283 | .{"case", .Keyword_case}, | |
| 284 | .{"char", .Keyword_char}, | |
| 285 | .{"const", .Keyword_const}, | |
| 286 | .{"continue", .Keyword_continue}, | |
| 287 | .{"default", .Keyword_default}, | |
| 288 | .{"do", .Keyword_do}, | |
| 289 | .{"double", .Keyword_double}, | |
| 290 | .{"else", .Keyword_else}, | |
| 291 | .{"enum", .Keyword_enum}, | |
| 292 | .{"extern", .Keyword_extern}, | |
| 293 | .{"float", .Keyword_float}, | |
| 294 | .{"for", .Keyword_for}, | |
| 295 | .{"goto", .Keyword_goto}, | |
| 296 | .{"if", .Keyword_if}, | |
| 297 | .{"int", .Keyword_int}, | |
| 298 | .{"long", .Keyword_long}, | |
| 299 | .{"register", .Keyword_register}, | |
| 300 | .{"return", .Keyword_return}, | |
| 301 | .{"short", .Keyword_short}, | |
| 302 | .{"signed", .Keyword_signed}, | |
| 303 | .{"sizeof", .Keyword_sizeof}, | |
| 304 | .{"static", .Keyword_static}, | |
| 305 | .{"struct", .Keyword_struct}, | |
| 306 | .{"switch", .Keyword_switch}, | |
| 307 | .{"typedef", .Keyword_typedef}, | |
| 308 | .{"union", .Keyword_union}, | |
| 309 | .{"unsigned", .Keyword_unsigned}, | |
| 310 | .{"void", .Keyword_void}, | |
| 311 | .{"volatile", .Keyword_volatile}, | |
| 312 | .{"while", .Keyword_while}, | |
| 281 | .{ "auto", .Keyword_auto }, | |
| 282 | .{ "break", .Keyword_break }, | |
| 283 | .{ "case", .Keyword_case }, | |
| 284 | .{ "char", .Keyword_char }, | |
| 285 | .{ "const", .Keyword_const }, | |
| 286 | .{ "continue", .Keyword_continue }, | |
| 287 | .{ "default", .Keyword_default }, | |
| 288 | .{ "do", .Keyword_do }, | |
| 289 | .{ "double", .Keyword_double }, | |
| 290 | .{ "else", .Keyword_else }, | |
| 291 | .{ "enum", .Keyword_enum }, | |
| 292 | .{ "extern", .Keyword_extern }, | |
| 293 | .{ "float", .Keyword_float }, | |
| 294 | .{ "for", .Keyword_for }, | |
| 295 | .{ "goto", .Keyword_goto }, | |
| 296 | .{ "if", .Keyword_if }, | |
| 297 | .{ "int", .Keyword_int }, | |
| 298 | .{ "long", .Keyword_long }, | |
| 299 | .{ "register", .Keyword_register }, | |
| 300 | .{ "return", .Keyword_return }, | |
| 301 | .{ "short", .Keyword_short }, | |
| 302 | .{ "signed", .Keyword_signed }, | |
| 303 | .{ "sizeof", .Keyword_sizeof }, | |
| 304 | .{ "static", .Keyword_static }, | |
| 305 | .{ "struct", .Keyword_struct }, | |
| 306 | .{ "switch", .Keyword_switch }, | |
| 307 | .{ "typedef", .Keyword_typedef }, | |
| 308 | .{ "union", .Keyword_union }, | |
| 309 | .{ "unsigned", .Keyword_unsigned }, | |
| 310 | .{ "void", .Keyword_void }, | |
| 311 | .{ "volatile", .Keyword_volatile }, | |
| 312 | .{ "while", .Keyword_while }, | |
| 313 | 313 | |
| 314 | 314 | // ISO C99 |
| 315 | .{"_Bool", .Keyword_bool}, | |
| 316 | .{"_Complex", .Keyword_complex}, | |
| 317 | .{"_Imaginary", .Keyword_imaginary}, | |
| 318 | .{"inline", .Keyword_inline}, | |
| 319 | .{"restrict", .Keyword_restrict}, | |
| 315 | .{ "_Bool", .Keyword_bool }, | |
| 316 | .{ "_Complex", .Keyword_complex }, | |
| 317 | .{ "_Imaginary", .Keyword_imaginary }, | |
| 318 | .{ "inline", .Keyword_inline }, | |
| 319 | .{ "restrict", .Keyword_restrict }, | |
| 320 | 320 | |
| 321 | 321 | // ISO C11 |
| 322 | .{"_Alignas", .Keyword_alignas}, | |
| 323 | .{"_Alignof", .Keyword_alignof}, | |
| 324 | .{"_Atomic", .Keyword_atomic}, | |
| 325 | .{"_Generic", .Keyword_generic}, | |
| 326 | .{"_Noreturn", .Keyword_noreturn}, | |
| 327 | .{"_Static_assert", .Keyword_static_assert}, | |
| 328 | .{"_Thread_local", .Keyword_thread_local}, | |
| 322 | .{ "_Alignas", .Keyword_alignas }, | |
| 323 | .{ "_Alignof", .Keyword_alignof }, | |
| 324 | .{ "_Atomic", .Keyword_atomic }, | |
| 325 | .{ "_Generic", .Keyword_generic }, | |
| 326 | .{ "_Noreturn", .Keyword_noreturn }, | |
| 327 | .{ "_Static_assert", .Keyword_static_assert }, | |
| 328 | .{ "_Thread_local", .Keyword_thread_local }, | |
| 329 | 329 | |
| 330 | 330 | // Preprocessor directives |
| 331 | .{"include", .Keyword_include}, | |
| 332 | .{"define", .Keyword_define}, | |
| 333 | .{"ifdef", .Keyword_ifdef}, | |
| 334 | .{"ifndef", .Keyword_ifndef}, | |
| 335 | .{"error", .Keyword_error}, | |
| 336 | .{"pragma", .Keyword_pragma}, | |
| 331 | .{ "include", .Keyword_include }, | |
| 332 | .{ "define", .Keyword_define }, | |
| 333 | .{ "ifdef", .Keyword_ifdef }, | |
| 334 | .{ "ifndef", .Keyword_ifndef }, | |
| 335 | .{ "error", .Keyword_error }, | |
| 336 | .{ "pragma", .Keyword_pragma }, | |
| 337 | 337 | }); |
| 338 | 338 | |
| 339 | 339 | // TODO do this in the preprocessor |
lib/std/fs.zig+15-14| ... | ... | @@ -261,17 +261,7 @@ pub const Dir = struct { |
| 261 | 261 | name: []const u8, |
| 262 | 262 | kind: Kind, |
| 263 | 263 | |
| 264 | pub const Kind = enum { | |
| 265 | BlockDevice, | |
| 266 | CharacterDevice, | |
| 267 | Directory, | |
| 268 | NamedPipe, | |
| 269 | SymLink, | |
| 270 | File, | |
| 271 | UnixDomainSocket, | |
| 272 | Whiteout, | |
| 273 | Unknown, | |
| 274 | }; | |
| 264 | pub const Kind = File.Kind; | |
| 275 | 265 | }; |
| 276 | 266 | |
| 277 | 267 | const IteratorError = error{AccessDenied} || os.UnexpectedError; |
| ... | ... | @@ -1527,9 +1517,9 @@ pub const Dir = struct { |
| 1527 | 1517 | |
| 1528 | 1518 | var size: ?u64 = null; |
| 1529 | 1519 | const mode = options.override_mode orelse blk: { |
| 1530 | const stat = try in_file.stat(); | |
| 1531 | size = stat.size; | |
| 1532 | break :blk stat.mode; | |
| 1520 | const st = try in_file.stat(); | |
| 1521 | size = st.size; | |
| 1522 | break :blk st.mode; | |
| 1533 | 1523 | }; |
| 1534 | 1524 | |
| 1535 | 1525 | var atomic_file = try dest_dir.atomicFile(dest_path, .{ .mode = mode }); |
| ... | ... | @@ -1555,6 +1545,17 @@ pub const Dir = struct { |
| 1555 | 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 | 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 | 29 | pub const Mode = os.mode_t; |
| 30 | 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 | 44 | pub const default_mode = switch (builtin.os.tag) { |
| 33 | 45 | .windows => 0, |
| 34 | 46 | .wasi => 0, |
| ... | ... | @@ -219,13 +231,14 @@ pub const File = struct { |
| 219 | 231 | /// unique across time, as some file systems may reuse an inode after its file has been deleted. |
| 220 | 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 | 235 | /// you see here: the index number of the inode. |
| 224 | 236 | /// |
| 225 | 237 | /// The FileIndex on Windows is similar. It is a number for a file that is unique to each filesystem. |
| 226 | 238 | inode: INode, |
| 227 | 239 | size: u64, |
| 228 | 240 | mode: Mode, |
| 241 | kind: Kind, | |
| 229 | 242 | |
| 230 | 243 | /// Access time in nanoseconds, relative to UTC 1970-01-01. |
| 231 | 244 | atime: i128, |
| ... | ... | @@ -254,6 +267,7 @@ pub const File = struct { |
| 254 | 267 | .inode = info.InternalInformation.IndexNumber, |
| 255 | 268 | .size = @bitCast(u64, info.StandardInformation.EndOfFile), |
| 256 | 269 | .mode = 0, |
| 270 | .kind = if (info.StandardInformation.Directory == 0) .File else .Directory, | |
| 257 | 271 | .atime = windows.fromSysTime(info.BasicInformation.LastAccessTime), |
| 258 | 272 | .mtime = windows.fromSysTime(info.BasicInformation.LastWriteTime), |
| 259 | 273 | .ctime = windows.fromSysTime(info.BasicInformation.CreationTime), |
| ... | ... | @@ -268,6 +282,27 @@ pub const File = struct { |
| 268 | 282 | .inode = st.ino, |
| 269 | 283 | .size = @bitCast(u64, st.size), |
| 270 | 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 | 306 | .atime = @as(i128, atime.tv_sec) * std.time.ns_per_s + atime.tv_nsec, |
| 272 | 307 | .mtime = @as(i128, mtime.tv_sec) * std.time.ns_per_s + mtime.tv_nsec, |
| 273 | 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 | 2 | pub const BufferedOutStream = @import("./buffered_writer.zig").BufferedWriter; |
| 3 | 3 | |
| 4 | 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 | 2576 | }, |
| 2577 | 2577 | .Array => return stringify(&value, options, out_stream), |
| 2578 | 2578 | .Vector => |info| { |
| 2579 | const array: [info.len]info.child = value; | |
| 2580 | return stringify(&array, options, out_stream); | |
| 2579 | const array: [info.len]info.child = value; | |
| 2580 | return stringify(&array, options, out_stream); | |
| 2581 | 2581 | }, |
| 2582 | 2582 | else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"), |
| 2583 | 2583 | } |
| ... | ... | @@ -2770,4 +2770,3 @@ test "stringify struct with custom stringifier" { |
| 2770 | 2770 | test "stringify vector" { |
| 2771 | 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 | 163 | pub const IPPROTO_ICMPV6 = 58; |
| 164 | 164 | pub const IPPROTO_RM = 113; |
| 165 | 165 | |
| 166 | pub const AI_PASSIVE = 0x00001; | |
| 167 | pub const AI_CANONNAME = 0x00002; | |
| 168 | pub const AI_NUMERICHOST = 0x00004; | |
| 169 | pub const AI_NUMERICSERV = 0x00008; | |
| 170 | pub const AI_ADDRCONFIG = 0x00400; | |
| 171 | pub const AI_V4MAPPED = 0x00800; | |
| 172 | pub const AI_NON_AUTHORITATIVE = 0x04000; | |
| 173 | pub const AI_SECURE = 0x08000; | |
| 166 | pub const AI_PASSIVE = 0x00001; | |
| 167 | pub const AI_CANONNAME = 0x00002; | |
| 168 | pub const AI_NUMERICHOST = 0x00004; | |
| 169 | pub const AI_NUMERICSERV = 0x00008; | |
| 170 | pub const AI_ADDRCONFIG = 0x00400; | |
| 171 | pub const AI_V4MAPPED = 0x00800; | |
| 172 | pub const AI_NON_AUTHORITATIVE = 0x04000; | |
| 173 | pub const AI_SECURE = 0x08000; | |
| 174 | 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 | 177 | pub const FIONBIO = -2147195266; |
| 178 | 178 |
lib/std/zig/parse.zig-1| ... | ... | @@ -937,7 +937,6 @@ const Parser = struct { |
| 937 | 937 | return node; |
| 938 | 938 | } |
| 939 | 939 | |
| 940 | ||
| 941 | 940 | while_prefix.body = try p.expectNode(parseAssignExpr, .{ |
| 942 | 941 | .ExpectedBlockOrAssignment = .{ .token = p.tok_i }, |
| 943 | 942 | }); |
src-self-hosted/main.zig+86-52| ... | ... | @@ -546,8 +546,9 @@ const Fmt = struct { |
| 546 | 546 | any_error: bool, |
| 547 | 547 | color: Color, |
| 548 | 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 | 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 | 642 | .seen = Fmt.SeenMap.init(gpa), |
| 642 | 643 | .any_error = false, |
| 643 | 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 | 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 | 660 | if (fmt.any_error) { |
| 650 | 661 | process.exit(1); |
| ... | ... | @@ -670,61 +681,79 @@ const FmtError = error{ |
| 670 | 681 | ReadOnlyFileSystem, |
| 671 | 682 | LinkQuotaExceeded, |
| 672 | 683 | FileBusy, |
| 684 | EndOfStream, | |
| 673 | 685 | } || fs.File.OpenError; |
| 674 | 686 | |
| 675 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { | |
| 676 | // get the real path here to avoid Windows failing on relative file paths with . or .. in them | |
| 677 | var real_path = fs.realpathAlloc(fmt.gpa, file_path) catch |err| { | |
| 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 | }, | |
| 687 | fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) FmtError!void { | |
| 688 | fmtPathFile(fmt, file_path, check_mode, dir, sub_path) catch |err| switch (err) { | |
| 689 | error.IsDir, error.AccessDenied => return fmtPathDir(fmt, file_path, check_mode, dir, sub_path), | |
| 702 | 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 | 692 | fmt.any_error = true; |
| 705 | 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 | 739 | defer source_file.close(); |
| 709 | 740 | |
| 710 | const stat = source_file.stat() catch |err| { | |
| 711 | std.debug.warn("unable to stat '{}': {}\n", .{ file_path, err }); | |
| 712 | fmt.any_error = true; | |
| 713 | return; | |
| 714 | }; | |
| 741 | const stat = try source_file.stat(); | |
| 715 | 742 | |
| 716 | const source_code = source_file.readAllAlloc(fmt.gpa, stat.size, max_src_size) catch |err| { | |
| 717 | std.debug.warn("unable to read '{}': {}\n", .{ file_path, err }); | |
| 718 | fmt.any_error = true; | |
| 719 | return; | |
| 743 | if (stat.kind == .Directory) | |
| 744 | return error.IsDir; | |
| 745 | ||
| 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 | 751 | defer fmt.gpa.free(source_code); |
| 722 | 752 | |
| 723 | const tree = std.zig.parse(fmt.gpa, source_code) catch |err| { | |
| 724 | std.debug.warn("error parsing file '{}': {}\n", .{ file_path, err }); | |
| 725 | fmt.any_error = true; | |
| 726 | return; | |
| 727 | }; | |
| 753 | // Add to set after no longer possible to get error.IsDir. | |
| 754 | if (try fmt.seen.put(stat.inode, {})) |_| return; | |
| 755 | ||
| 756 | const tree = try std.zig.parse(fmt.gpa, source_code); | |
| 728 | 757 | defer tree.deinit(); |
| 729 | 758 | |
| 730 | 759 | for (tree.errors) |parse_error| { |
| ... | ... | @@ -742,14 +771,19 @@ fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void { |
| 742 | 771 | fmt.any_error = true; |
| 743 | 772 | } |
| 744 | 773 | } else { |
| 745 | const baf = try io.BufferedAtomicFile.create(fmt.gpa, fs.cwd(), real_path, .{ .mode = stat.mode }); | |
| 746 | defer baf.destroy(); | |
| 747 | ||
| 748 | const anything_changed = try std.zig.render(fmt.gpa, baf.stream(), tree); | |
| 749 | if (anything_changed) { | |
| 750 | std.debug.warn("{}\n", .{file_path}); | |
| 751 | try baf.finish(); | |
| 752 | } | |
| 774 | // As a heuristic, we make enough capacity for the same as the input source. | |
| 775 | try fmt.out_buffer.ensureCapacity(source_code.len); | |
| 776 | fmt.out_buffer.items.len = 0; | |
| 777 | const anything_changed = try std.zig.render(fmt.gpa, fmt.out_buffer.writer(), tree); | |
| 778 | if (!anything_changed) | |
| 779 | return; // Good thing we didn't waste any file system access on this. | |
| 780 | ||
| 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 |