| ... | ... | @@ -2,6 +2,12 @@ |
| 2 | 2 | //! source lives here. These APIs are provided as-is and have absolutely no API |
| 3 | 3 | //! guarantees whatsoever. |
| 4 | 4 | |
| 5 | const std = @import("std.zig"); |
| 6 | const tokenizer = @import("zig/tokenizer.zig"); |
| 7 | const assert = std.debug.assert; |
| 8 | const Allocator = std.mem.Allocator; |
| 9 | const Writer = std.Io.Writer; |
| 10 | |
| 5 | 11 | pub const ErrorBundle = @import("zig/ErrorBundle.zig"); |
| 6 | 12 | pub const Server = @import("zig/Server.zig"); |
| 7 | 13 | pub const Client = @import("zig/Client.zig"); |
| ... | ... | @@ -355,11 +361,6 @@ pub fn serializeCpuAlloc(ally: Allocator, cpu: std.Target.Cpu) Allocator.Error![ |
| 355 | 361 | return buffer.toOwnedSlice(); |
| 356 | 362 | } |
| 357 | 363 | |
| 358 | | const std = @import("std.zig"); |
| 359 | | const tokenizer = @import("zig/tokenizer.zig"); |
| 360 | | const assert = std.debug.assert; |
| 361 | | const Allocator = std.mem.Allocator; |
| 362 | | |
| 363 | 364 | /// Return a Formatter for a Zig identifier, escaping it with `@""` syntax if needed. |
| 364 | 365 | /// |
| 365 | 366 | /// See also `fmtIdFlags`. |
| ... | ... | @@ -425,7 +426,7 @@ pub const FormatId = struct { |
| 425 | 426 | }; |
| 426 | 427 | |
| 427 | 428 | /// Print the string as a Zig identifier, escaping it with `@""` syntax if needed. |
| 428 | | fn render(ctx: FormatId, writer: *std.io.Writer) std.io.Writer.Error!void { |
| 429 | fn render(ctx: FormatId, writer: *Writer) Writer.Error!void { |
| 429 | 430 | const bytes = ctx.bytes; |
| 430 | 431 | if (isValidId(bytes) and |
| 431 | 432 | (ctx.flags.allow_primitive or !std.zig.isPrimitive(bytes)) and |
| ... | ... | @@ -463,7 +464,7 @@ test fmtChar { |
| 463 | 464 | } |
| 464 | 465 | |
| 465 | 466 | /// Print the string as escaped contents of a double quoted string. |
| 466 | | pub fn stringEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!void { |
| 467 | pub fn stringEscape(bytes: []const u8, w: *Writer) Writer.Error!void { |
| 467 | 468 | for (bytes) |byte| switch (byte) { |
| 468 | 469 | '\n' => try w.writeAll("\\n"), |
| 469 | 470 | '\r' => try w.writeAll("\\r"), |
| ... | ... | @@ -480,7 +481,7 @@ pub fn stringEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!vo |
| 480 | 481 | } |
| 481 | 482 | |
| 482 | 483 | /// Print the string as escaped contents of a single-quoted string. |
| 483 | | pub fn charEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!void { |
| 484 | pub fn charEscape(bytes: []const u8, w: *Writer) Writer.Error!void { |
| 484 | 485 | for (bytes) |byte| switch (byte) { |
| 485 | 486 | '\n' => try w.writeAll("\\n"), |
| 486 | 487 | '\r' => try w.writeAll("\\r"), |
| ... | ... | @@ -529,20 +530,18 @@ test isUnderscore { |
| 529 | 530 | try std.testing.expect(!isUnderscore("\\x5f")); |
| 530 | 531 | } |
| 531 | 532 | |
| 532 | | pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: ?usize) ![:0]u8 { |
| 533 | | const source_code = input.readToEndAllocOptions( |
| 534 | | gpa, |
| 535 | | max_src_size, |
| 536 | | size_hint, |
| 537 | | .of(u8), |
| 538 | | 0, |
| 539 | | ) catch |err| switch (err) { |
| 533 | pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: usize) ![:0]u8 { |
| 534 | var buffer: std.ArrayListAlignedUnmanaged(u8, .@"2") = .empty; |
| 535 | defer buffer.deinit(gpa); |
| 536 | |
| 537 | try buffer.ensureUnusedCapacity(gpa, size_hint); |
| 538 | |
| 539 | input.readIntoArrayList(gpa, .limited(max_src_size), .@"2", &buffer) catch |err| switch (err) { |
| 540 | 540 | error.ConnectionResetByPeer => unreachable, |
| 541 | 541 | error.ConnectionTimedOut => unreachable, |
| 542 | 542 | error.NotOpenForReading => unreachable, |
| 543 | 543 | else => |e| return e, |
| 544 | 544 | }; |
| 545 | | errdefer gpa.free(source_code); |
| 546 | 545 | |
| 547 | 546 | // Detect unsupported file types with their Byte Order Mark |
| 548 | 547 | const unsupported_boms = [_][]const u8{ |
| ... | ... | @@ -551,30 +550,23 @@ pub fn readSourceFileToEndAlloc(gpa: Allocator, input: std.fs.File, size_hint: ? |
| 551 | 550 | "\xfe\xff", // UTF-16 big endian |
| 552 | 551 | }; |
| 553 | 552 | for (unsupported_boms) |bom| { |
| 554 | | if (std.mem.startsWith(u8, source_code, bom)) { |
| 553 | if (std.mem.startsWith(u8, buffer.items, bom)) { |
| 555 | 554 | return error.UnsupportedEncoding; |
| 556 | 555 | } |
| 557 | 556 | } |
| 558 | 557 | |
| 559 | 558 | // If the file starts with a UTF-16 little endian BOM, translate it to UTF-8 |
| 560 | | if (std.mem.startsWith(u8, source_code, "\xff\xfe")) { |
| 561 | | if (source_code.len % 2 != 0) return error.InvalidEncoding; |
| 562 | | // TODO: after wrangle-writer-buffering branch is merged, |
| 563 | | // avoid this unnecessary allocation |
| 564 | | const aligned_copy = try gpa.alloc(u16, source_code.len / 2); |
| 565 | | defer gpa.free(aligned_copy); |
| 566 | | @memcpy(std.mem.sliceAsBytes(aligned_copy), source_code); |
| 567 | | const source_code_utf8 = std.unicode.utf16LeToUtf8AllocZ(gpa, aligned_copy) catch |err| switch (err) { |
| 559 | if (std.mem.startsWith(u8, buffer.items, "\xff\xfe")) { |
| 560 | if (buffer.items.len % 2 != 0) return error.InvalidEncoding; |
| 561 | return std.unicode.utf16LeToUtf8AllocZ(gpa, @ptrCast(buffer.items)) catch |err| switch (err) { |
| 568 | 562 | error.DanglingSurrogateHalf => error.UnsupportedEncoding, |
| 569 | 563 | error.ExpectedSecondSurrogateHalf => error.UnsupportedEncoding, |
| 570 | 564 | error.UnexpectedSecondSurrogateHalf => error.UnsupportedEncoding, |
| 571 | 565 | else => |e| return e, |
| 572 | 566 | }; |
| 573 | | gpa.free(source_code); |
| 574 | | return source_code_utf8; |
| 575 | 567 | } |
| 576 | 568 | |
| 577 | | return source_code; |
| 569 | return buffer.toOwnedSliceSentinel(gpa, 0); |
| 578 | 570 | } |
| 579 | 571 | |
| 580 | 572 | pub fn printAstErrorsToStderr(gpa: Allocator, tree: Ast, path: []const u8, color: Color) !void { |
| ... | ... | @@ -621,7 +613,7 @@ pub fn parseTargetQueryOrReportFatalError( |
| 621 | 613 | var help_text = std.ArrayList(u8).init(allocator); |
| 622 | 614 | defer help_text.deinit(); |
| 623 | 615 | for (diags.arch.?.allCpuModels()) |cpu| { |
| 624 | | help_text.writer().print(" {s}\n", .{cpu.name}) catch break :help; |
| 616 | help_text.print(" {s}\n", .{cpu.name}) catch break :help; |
| 625 | 617 | } |
| 626 | 618 | std.log.info("available CPUs for architecture '{s}':\n{s}", .{ |
| 627 | 619 | @tagName(diags.arch.?), help_text.items, |
| ... | ... | @@ -634,7 +626,7 @@ pub fn parseTargetQueryOrReportFatalError( |
| 634 | 626 | var help_text = std.ArrayList(u8).init(allocator); |
| 635 | 627 | defer help_text.deinit(); |
| 636 | 628 | for (diags.arch.?.allFeaturesList()) |feature| { |
| 637 | | help_text.writer().print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help; |
| 629 | help_text.print(" {s}: {s}\n", .{ feature.name, feature.description }) catch break :help; |
| 638 | 630 | } |
| 639 | 631 | std.log.info("available CPU features for architecture '{s}':\n{s}", .{ |
| 640 | 632 | @tagName(diags.arch.?), help_text.items, |
| ... | ... | @@ -647,7 +639,7 @@ pub fn parseTargetQueryOrReportFatalError( |
| 647 | 639 | var help_text = std.ArrayList(u8).init(allocator); |
| 648 | 640 | defer help_text.deinit(); |
| 649 | 641 | inline for (@typeInfo(std.Target.ObjectFormat).@"enum".fields) |field| { |
| 650 | | help_text.writer().print(" {s}\n", .{field.name}) catch break :help; |
| 642 | help_text.print(" {s}\n", .{field.name}) catch break :help; |
| 651 | 643 | } |
| 652 | 644 | std.log.info("available object formats:\n{s}", .{help_text.items}); |
| 653 | 645 | } |
| ... | ... | @@ -658,7 +650,7 @@ pub fn parseTargetQueryOrReportFatalError( |
| 658 | 650 | var help_text = std.ArrayList(u8).init(allocator); |
| 659 | 651 | defer help_text.deinit(); |
| 660 | 652 | inline for (@typeInfo(std.Target.Cpu.Arch).@"enum".fields) |field| { |
| 661 | | help_text.writer().print(" {s}\n", .{field.name}) catch break :help; |
| 653 | help_text.print(" {s}\n", .{field.name}) catch break :help; |
| 662 | 654 | } |
| 663 | 655 | std.log.info("available architectures:\n{s} native\n", .{help_text.items}); |
| 664 | 656 | } |