| author | |
| committer | |
| log | 9b47dd2028deb45324ca19d909d0cee69f51f1b9 |
| tree | 1b9cd7bbe8b1f09c77bc8b38458a0c5f745c2934 |
| parent | 8023f3dcebff06cbf3563bdd09b07462ed43509f |
6 files changed, 97 insertions(+), 93 deletions(-)
lib/docs/wasm/Decl.zig+5-4| ... | ... | @@ -6,6 +6,7 @@ const gpa = std.heap.wasm_allocator; |
| 6 | 6 | const assert = std.debug.assert; |
| 7 | 7 | const log = std.log; |
| 8 | 8 | const Oom = error{OutOfMemory}; |
| 9 | const ArrayList = std.ArrayList; | |
| 9 | 10 | |
| 10 | 11 | ast_node: Ast.Node.Index, |
| 11 | 12 | file: Walk.File.Index, |
| ... | ... | @@ -189,7 +190,7 @@ pub fn lookup(decl: *const Decl, name: []const u8) ?Decl.Index { |
| 189 | 190 | } |
| 190 | 191 | |
| 191 | 192 | /// Appends the fully qualified name to `out`. |
| 192 | pub fn fqn(decl: *const Decl, out: *std.ArrayListUnmanaged(u8)) Oom!void { | |
| 193 | pub fn fqn(decl: *const Decl, out: *ArrayList(u8)) Oom!void { | |
| 193 | 194 | try decl.append_path(out); |
| 194 | 195 | if (decl.parent != .none) { |
| 195 | 196 | try append_parent_ns(out, decl.parent); |
| ... | ... | @@ -199,12 +200,12 @@ pub fn fqn(decl: *const Decl, out: *std.ArrayListUnmanaged(u8)) Oom!void { |
| 199 | 200 | } |
| 200 | 201 | } |
| 201 | 202 | |
| 202 | pub fn reset_with_path(decl: *const Decl, list: *std.ArrayListUnmanaged(u8)) Oom!void { | |
| 203 | pub fn reset_with_path(decl: *const Decl, list: *ArrayList(u8)) Oom!void { | |
| 203 | 204 | list.clearRetainingCapacity(); |
| 204 | 205 | try append_path(decl, list); |
| 205 | 206 | } |
| 206 | 207 | |
| 207 | pub fn append_path(decl: *const Decl, list: *std.ArrayListUnmanaged(u8)) Oom!void { | |
| 208 | pub fn append_path(decl: *const Decl, list: *ArrayList(u8)) Oom!void { | |
| 208 | 209 | const start = list.items.len; |
| 209 | 210 | // Prefer the module name alias. |
| 210 | 211 | for (Walk.modules.keys(), Walk.modules.values()) |pkg_name, pkg_file| { |
| ... | ... | @@ -230,7 +231,7 @@ pub fn append_path(decl: *const Decl, list: *std.ArrayListUnmanaged(u8)) Oom!voi |
| 230 | 231 | } |
| 231 | 232 | } |
| 232 | 233 | |
| 233 | pub fn append_parent_ns(list: *std.ArrayListUnmanaged(u8), parent: Decl.Index) Oom!void { | |
| 234 | pub fn append_parent_ns(list: *ArrayList(u8), parent: Decl.Index) Oom!void { | |
| 234 | 235 | assert(parent != .none); |
| 235 | 236 | const decl = parent.get(); |
| 236 | 237 | if (decl.parent != .none) { |
lib/docs/wasm/html_render.zig+10-8| ... | ... | @@ -1,6 +1,8 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Ast = std.zig.Ast; |
| 3 | 3 | const assert = std.debug.assert; |
| 4 | const ArrayList = std.ArrayList; | |
| 5 | const Writer = std.Io.Writer; | |
| 4 | 6 | |
| 5 | 7 | const Walk = @import("Walk"); |
| 6 | 8 | const Decl = Walk.Decl; |
| ... | ... | @@ -30,7 +32,7 @@ pub const Annotation = struct { |
| 30 | 32 | |
| 31 | 33 | pub fn fileSourceHtml( |
| 32 | 34 | file_index: Walk.File.Index, |
| 33 | out: *std.ArrayListUnmanaged(u8), | |
| 35 | out: *ArrayList(u8), | |
| 34 | 36 | root_node: Ast.Node.Index, |
| 35 | 37 | options: RenderSourceOptions, |
| 36 | 38 | ) !void { |
| ... | ... | @@ -38,7 +40,7 @@ pub fn fileSourceHtml( |
| 38 | 40 | const file = file_index.get(); |
| 39 | 41 | |
| 40 | 42 | const g = struct { |
| 41 | var field_access_buffer: std.ArrayListUnmanaged(u8) = .empty; | |
| 43 | var field_access_buffer: ArrayList(u8) = .empty; | |
| 42 | 44 | }; |
| 43 | 45 | |
| 44 | 46 | const start_token = ast.firstToken(root_node); |
| ... | ... | @@ -88,7 +90,7 @@ pub fn fileSourceHtml( |
| 88 | 90 | if (next_annotate_index >= options.source_location_annotations.len) break; |
| 89 | 91 | const next_annotation = options.source_location_annotations[next_annotate_index]; |
| 90 | 92 | if (cursor <= next_annotation.file_byte_offset) break; |
| 91 | try out.writer(gpa).print("<span id=\"{s}{d}\"></span>", .{ | |
| 93 | try out.print(gpa, "<span id=\"{s}{d}\"></span>", .{ | |
| 92 | 94 | options.annotation_prefix, next_annotation.dom_id, |
| 93 | 95 | }); |
| 94 | 96 | next_annotate_index += 1; |
| ... | ... | @@ -318,7 +320,7 @@ pub fn fileSourceHtml( |
| 318 | 320 | } |
| 319 | 321 | } |
| 320 | 322 | |
| 321 | fn appendUnindented(out: *std.ArrayListUnmanaged(u8), s: []const u8, indent: usize) !void { | |
| 323 | fn appendUnindented(out: *ArrayList(u8), s: []const u8, indent: usize) !void { | |
| 322 | 324 | var it = std.mem.splitScalar(u8, s, '\n'); |
| 323 | 325 | var is_first_line = true; |
| 324 | 326 | while (it.next()) |line| { |
| ... | ... | @@ -332,7 +334,7 @@ fn appendUnindented(out: *std.ArrayListUnmanaged(u8), s: []const u8, indent: usi |
| 332 | 334 | } |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | pub fn appendEscaped(out: *std.ArrayListUnmanaged(u8), s: []const u8) !void { | |
| 337 | pub fn appendEscaped(out: *ArrayList(u8), s: []const u8) !void { | |
| 336 | 338 | for (s) |c| { |
| 337 | 339 | try out.ensureUnusedCapacity(gpa, 6); |
| 338 | 340 | switch (c) { |
| ... | ... | @@ -347,7 +349,7 @@ pub fn appendEscaped(out: *std.ArrayListUnmanaged(u8), s: []const u8) !void { |
| 347 | 349 | |
| 348 | 350 | fn walkFieldAccesses( |
| 349 | 351 | file_index: Walk.File.Index, |
| 350 | out: *std.ArrayListUnmanaged(u8), | |
| 352 | out: *ArrayList(u8), | |
| 351 | 353 | node: Ast.Node.Index, |
| 352 | 354 | ) Oom!void { |
| 353 | 355 | const ast = file_index.get_ast(); |
| ... | ... | @@ -371,7 +373,7 @@ fn walkFieldAccesses( |
| 371 | 373 | |
| 372 | 374 | fn resolveIdentLink( |
| 373 | 375 | file_index: Walk.File.Index, |
| 374 | out: *std.ArrayListUnmanaged(u8), | |
| 376 | out: *ArrayList(u8), | |
| 375 | 377 | ident_token: Ast.TokenIndex, |
| 376 | 378 | ) Oom!void { |
| 377 | 379 | const decl_index = file_index.get().lookup_token(ident_token); |
| ... | ... | @@ -391,7 +393,7 @@ fn unindent(s: []const u8, indent: usize) []const u8 { |
| 391 | 393 | return s[indent_idx..]; |
| 392 | 394 | } |
| 393 | 395 | |
| 394 | pub fn resolveDeclLink(decl_index: Decl.Index, out: *std.ArrayListUnmanaged(u8)) Oom!void { | |
| 396 | pub fn resolveDeclLink(decl_index: Decl.Index, out: *ArrayList(u8)) Oom!void { | |
| 395 | 397 | const decl = decl_index.get(); |
| 396 | 398 | switch (decl.categorize()) { |
| 397 | 399 | .alias => |alias_decl| try alias_decl.get().fqn(out), |
lib/docs/wasm/main.zig+30-24| ... | ... | @@ -5,6 +5,8 @@ const Ast = std.zig.Ast; |
| 5 | 5 | const Walk = @import("Walk"); |
| 6 | 6 | const markdown = @import("markdown.zig"); |
| 7 | 7 | const Decl = Walk.Decl; |
| 8 | const ArrayList = std.ArrayList; | |
| 9 | const Writer = std.Io.Writer; | |
| 8 | 10 | |
| 9 | 11 | const fileSourceHtml = @import("html_render.zig").fileSourceHtml; |
| 10 | 12 | const appendEscaped = @import("html_render.zig").appendEscaped; |
| ... | ... | @@ -66,8 +68,8 @@ export fn unpack(tar_ptr: [*]u8, tar_len: usize) void { |
| 66 | 68 | }; |
| 67 | 69 | } |
| 68 | 70 | |
| 69 | var query_string: std.ArrayListUnmanaged(u8) = .empty; | |
| 70 | var query_results: std.ArrayListUnmanaged(Decl.Index) = .empty; | |
| 71 | var query_string: ArrayList(u8) = .empty; | |
| 72 | var query_results: ArrayList(Decl.Index) = .empty; | |
| 71 | 73 | |
| 72 | 74 | /// Resizes the query string to be the correct length; returns the pointer to |
| 73 | 75 | /// the query string. |
| ... | ... | @@ -99,11 +101,11 @@ fn query_exec_fallible(query: []const u8, ignore_case: bool) !void { |
| 99 | 101 | segments: u16, |
| 100 | 102 | }; |
| 101 | 103 | const g = struct { |
| 102 | var full_path_search_text: std.ArrayListUnmanaged(u8) = .empty; | |
| 103 | var full_path_search_text_lower: std.ArrayListUnmanaged(u8) = .empty; | |
| 104 | var doc_search_text: std.ArrayListUnmanaged(u8) = .empty; | |
| 104 | var full_path_search_text: ArrayList(u8) = .empty; | |
| 105 | var full_path_search_text_lower: ArrayList(u8) = .empty; | |
| 106 | var doc_search_text: ArrayList(u8) = .empty; | |
| 105 | 107 | /// Each element matches a corresponding query_results element. |
| 106 | var scores: std.ArrayListUnmanaged(Score) = .empty; | |
| 108 | var scores: ArrayList(Score) = .empty; | |
| 107 | 109 | }; |
| 108 | 110 | |
| 109 | 111 | // First element stores the size of the list. |
| ... | ... | @@ -234,7 +236,7 @@ const ErrorIdentifier = packed struct(u64) { |
| 234 | 236 | return ast.tokenTag(token_index - 1) == .doc_comment; |
| 235 | 237 | } |
| 236 | 238 | |
| 237 | fn html(ei: ErrorIdentifier, base_decl: Decl.Index, out: *std.ArrayListUnmanaged(u8)) Oom!void { | |
| 239 | fn html(ei: ErrorIdentifier, base_decl: Decl.Index, out: *ArrayList(u8)) Oom!void { | |
| 238 | 240 | const decl_index = ei.decl_index; |
| 239 | 241 | const ast = decl_index.get().file.get_ast(); |
| 240 | 242 | const name = ast.tokenSlice(ei.token_index); |
| ... | ... | @@ -260,7 +262,7 @@ const ErrorIdentifier = packed struct(u64) { |
| 260 | 262 | } |
| 261 | 263 | }; |
| 262 | 264 | |
| 263 | var string_result: std.ArrayListUnmanaged(u8) = .empty; | |
| 265 | var string_result: ArrayList(u8) = .empty; | |
| 264 | 266 | var error_set_result: std.StringArrayHashMapUnmanaged(ErrorIdentifier) = .empty; |
| 265 | 267 | |
| 266 | 268 | export fn decl_error_set(decl_index: Decl.Index) Slice(ErrorIdentifier) { |
| ... | ... | @@ -411,7 +413,7 @@ fn decl_fields_fallible(decl_index: Decl.Index) ![]Ast.Node.Index { |
| 411 | 413 | |
| 412 | 414 | fn ast_decl_fields_fallible(ast: *Ast, ast_index: Ast.Node.Index) ![]Ast.Node.Index { |
| 413 | 415 | const g = struct { |
| 414 | var result: std.ArrayListUnmanaged(Ast.Node.Index) = .empty; | |
| 416 | var result: ArrayList(Ast.Node.Index) = .empty; | |
| 415 | 417 | }; |
| 416 | 418 | g.result.clearRetainingCapacity(); |
| 417 | 419 | var buf: [2]Ast.Node.Index = undefined; |
| ... | ... | @@ -429,7 +431,7 @@ fn ast_decl_fields_fallible(ast: *Ast, ast_index: Ast.Node.Index) ![]Ast.Node.In |
| 429 | 431 | |
| 430 | 432 | fn decl_params_fallible(decl_index: Decl.Index) ![]Ast.Node.Index { |
| 431 | 433 | const g = struct { |
| 432 | var result: std.ArrayListUnmanaged(Ast.Node.Index) = .empty; | |
| 434 | var result: ArrayList(Ast.Node.Index) = .empty; | |
| 433 | 435 | }; |
| 434 | 436 | g.result.clearRetainingCapacity(); |
| 435 | 437 | const decl = decl_index.get(); |
| ... | ... | @@ -460,7 +462,7 @@ export fn decl_param_html(decl_index: Decl.Index, param_node: Ast.Node.Index) St |
| 460 | 462 | } |
| 461 | 463 | |
| 462 | 464 | fn decl_field_html_fallible( |
| 463 | out: *std.ArrayListUnmanaged(u8), | |
| 465 | out: *ArrayList(u8), | |
| 464 | 466 | decl_index: Decl.Index, |
| 465 | 467 | field_node: Ast.Node.Index, |
| 466 | 468 | ) !void { |
| ... | ... | @@ -480,7 +482,7 @@ fn decl_field_html_fallible( |
| 480 | 482 | } |
| 481 | 483 | |
| 482 | 484 | fn decl_param_html_fallible( |
| 483 | out: *std.ArrayListUnmanaged(u8), | |
| 485 | out: *ArrayList(u8), | |
| 484 | 486 | decl_index: Decl.Index, |
| 485 | 487 | param_node: Ast.Node.Index, |
| 486 | 488 | ) !void { |
| ... | ... | @@ -649,7 +651,7 @@ export fn decl_docs_html(decl_index: Decl.Index, short: bool) String { |
| 649 | 651 | } |
| 650 | 652 | |
| 651 | 653 | fn collect_docs( |
| 652 | list: *std.ArrayListUnmanaged(u8), | |
| 654 | list: *ArrayList(u8), | |
| 653 | 655 | ast: *const Ast, |
| 654 | 656 | first_doc_comment: Ast.TokenIndex, |
| 655 | 657 | ) Oom!void { |
| ... | ... | @@ -667,7 +669,7 @@ fn collect_docs( |
| 667 | 669 | } |
| 668 | 670 | |
| 669 | 671 | fn render_docs( |
| 670 | out: *std.ArrayListUnmanaged(u8), | |
| 672 | out: *ArrayList(u8), | |
| 671 | 673 | decl_index: Decl.Index, |
| 672 | 674 | first_doc_comment: Ast.TokenIndex, |
| 673 | 675 | short: bool, |
| ... | ... | @@ -691,11 +693,10 @@ fn render_docs( |
| 691 | 693 | defer parsed_doc.deinit(gpa); |
| 692 | 694 | |
| 693 | 695 | const g = struct { |
| 694 | var link_buffer: std.ArrayListUnmanaged(u8) = .empty; | |
| 696 | var link_buffer: ArrayList(u8) = .empty; | |
| 695 | 697 | }; |
| 696 | 698 | |
| 697 | const Writer = std.ArrayListUnmanaged(u8).Writer; | |
| 698 | const Renderer = markdown.Renderer(Writer, Decl.Index); | |
| 699 | const Renderer = markdown.Renderer(Decl.Index); | |
| 699 | 700 | const renderer: Renderer = .{ |
| 700 | 701 | .context = decl_index, |
| 701 | 702 | .renderFn = struct { |
| ... | ... | @@ -703,8 +704,8 @@ fn render_docs( |
| 703 | 704 | r: Renderer, |
| 704 | 705 | doc: markdown.Document, |
| 705 | 706 | node: markdown.Document.Node.Index, |
| 706 | writer: Writer, | |
| 707 | ) !void { | |
| 707 | writer: *Writer, | |
| 708 | ) Writer.Error!void { | |
| 708 | 709 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
| 709 | 710 | switch (doc.nodes.items(.tag)[@intFromEnum(node)]) { |
| 710 | 711 | .code_span => { |
| ... | ... | @@ -712,7 +713,7 @@ fn render_docs( |
| 712 | 713 | const content = doc.string(data.text.content); |
| 713 | 714 | if (resolve_decl_path(r.context, content)) |resolved_decl_index| { |
| 714 | 715 | g.link_buffer.clearRetainingCapacity(); |
| 715 | try resolveDeclLink(resolved_decl_index, &g.link_buffer); | |
| 716 | resolveDeclLink(resolved_decl_index, &g.link_buffer) catch return error.WriteFailed; | |
| 716 | 717 | |
| 717 | 718 | try writer.writeAll("<a href=\"#"); |
| 718 | 719 | _ = missing_feature_url_escape; |
| ... | ... | @@ -730,7 +731,12 @@ fn render_docs( |
| 730 | 731 | } |
| 731 | 732 | }.render, |
| 732 | 733 | }; |
| 733 | try renderer.render(parsed_doc, out.writer(gpa)); | |
| 734 | ||
| 735 | var allocating = Writer.Allocating.fromArrayList(gpa, out); | |
| 736 | defer out.* = allocating.toArrayList(); | |
| 737 | renderer.render(parsed_doc, &allocating.writer) catch |err| switch (err) { | |
| 738 | error.WriteFailed => return error.OutOfMemory, | |
| 739 | }; | |
| 734 | 740 | } |
| 735 | 741 | |
| 736 | 742 | fn resolve_decl_path(decl_index: Decl.Index, path: []const u8) ?Decl.Index { |
| ... | ... | @@ -827,7 +833,7 @@ export fn find_module_root(pkg: Walk.ModuleIndex) Decl.Index { |
| 827 | 833 | } |
| 828 | 834 | |
| 829 | 835 | /// Set by `set_input_string`. |
| 830 | var input_string: std.ArrayListUnmanaged(u8) = .empty; | |
| 836 | var input_string: ArrayList(u8) = .empty; | |
| 831 | 837 | |
| 832 | 838 | export fn set_input_string(len: usize) [*]u8 { |
| 833 | 839 | input_string.resize(gpa, len) catch @panic("OOM"); |
| ... | ... | @@ -849,7 +855,7 @@ export fn find_decl() Decl.Index { |
| 849 | 855 | if (result != .none) return result; |
| 850 | 856 | |
| 851 | 857 | const g = struct { |
| 852 | var match_fqn: std.ArrayListUnmanaged(u8) = .empty; | |
| 858 | var match_fqn: ArrayList(u8) = .empty; | |
| 853 | 859 | }; |
| 854 | 860 | for (Walk.decls.items, 0..) |*decl, decl_index| { |
| 855 | 861 | g.match_fqn.clearRetainingCapacity(); |
| ... | ... | @@ -905,7 +911,7 @@ export fn type_fn_members(parent: Decl.Index, include_private: bool) Slice(Decl. |
| 905 | 911 | |
| 906 | 912 | export fn namespace_members(parent: Decl.Index, include_private: bool) Slice(Decl.Index) { |
| 907 | 913 | const g = struct { |
| 908 | var members: std.ArrayListUnmanaged(Decl.Index) = .empty; | |
| 914 | var members: ArrayList(Decl.Index) = .empty; | |
| 909 | 915 | }; |
| 910 | 916 | |
| 911 | 917 | g.members.clearRetainingCapacity(); |
lib/docs/wasm/markdown/renderer.zig+15-16| ... | ... | @@ -2,25 +2,26 @@ const std = @import("std"); |
| 2 | 2 | const Document = @import("Document.zig"); |
| 3 | 3 | const Node = Document.Node; |
| 4 | 4 | const assert = std.debug.assert; |
| 5 | const Writer = std.Io.Writer; | |
| 5 | 6 | |
| 6 | 7 | /// A Markdown document renderer. |
| 7 | 8 | /// |
| 8 | 9 | /// Each concrete `Renderer` type has a `renderDefault` function, with the |
| 9 | 10 | /// intention that custom `renderFn` implementations can call `renderDefault` |
| 10 | 11 | /// for node types for which they require no special rendering. |
| 11 | pub fn Renderer(comptime Writer: type, comptime Context: type) type { | |
| 12 | pub fn Renderer(comptime Context: type) type { | |
| 12 | 13 | return struct { |
| 13 | 14 | renderFn: *const fn ( |
| 14 | 15 | r: Self, |
| 15 | 16 | doc: Document, |
| 16 | 17 | node: Node.Index, |
| 17 | writer: Writer, | |
| 18 | writer: *Writer, | |
| 18 | 19 | ) Writer.Error!void = renderDefault, |
| 19 | 20 | context: Context, |
| 20 | 21 | |
| 21 | 22 | const Self = @This(); |
| 22 | 23 | |
| 23 | pub fn render(r: Self, doc: Document, writer: Writer) Writer.Error!void { | |
| 24 | pub fn render(r: Self, doc: Document, writer: *Writer) Writer.Error!void { | |
| 24 | 25 | try r.renderFn(r, doc, .root, writer); |
| 25 | 26 | } |
| 26 | 27 | |
| ... | ... | @@ -28,7 +29,7 @@ pub fn Renderer(comptime Writer: type, comptime Context: type) type { |
| 28 | 29 | r: Self, |
| 29 | 30 | doc: Document, |
| 30 | 31 | node: Node.Index, |
| 31 | writer: Writer, | |
| 32 | writer: *Writer, | |
| 32 | 33 | ) Writer.Error!void { |
| 33 | 34 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
| 34 | 35 | switch (doc.nodes.items(.tag)[@intFromEnum(node)]) { |
| ... | ... | @@ -188,8 +189,8 @@ pub fn Renderer(comptime Writer: type, comptime Context: type) type { |
| 188 | 189 | pub fn renderInlineNodeText( |
| 189 | 190 | doc: Document, |
| 190 | 191 | node: Node.Index, |
| 191 | writer: anytype, | |
| 192 | ) @TypeOf(writer).Error!void { | |
| 192 | writer: *Writer, | |
| 193 | ) Writer.Error!void { | |
| 193 | 194 | const data = doc.nodes.items(.data)[@intFromEnum(node)]; |
| 194 | 195 | switch (doc.nodes.items(.tag)[@intFromEnum(node)]) { |
| 195 | 196 | .root, |
| ... | ... | @@ -234,14 +235,12 @@ pub fn fmtHtml(bytes: []const u8) std.fmt.Formatter([]const u8, formatHtml) { |
| 234 | 235 | return .{ .data = bytes }; |
| 235 | 236 | } |
| 236 | 237 | |
| 237 | fn formatHtml(bytes: []const u8, writer: *std.io.Writer) std.io.Writer.Error!void { | |
| 238 | for (bytes) |b| { | |
| 239 | switch (b) { | |
| 240 | '<' => try writer.writeAll("&lt;"), | |
| 241 | '>' => try writer.writeAll("&gt;"), | |
| 242 | '&' => try writer.writeAll("&amp;"), | |
| 243 | '"' => try writer.writeAll("&quot;"), | |
| 244 | else => try writer.writeByte(b), | |
| 245 | } | |
| 246 | } | |
| 238 | fn formatHtml(bytes: []const u8, w: *Writer) Writer.Error!void { | |
| 239 | for (bytes) |b| switch (b) { | |
| 240 | '<' => try w.writeAll("&lt;"), | |
| 241 | '>' => try w.writeAll("&gt;"), | |
| 242 | '&' => try w.writeAll("&amp;"), | |
| 243 | '"' => try w.writeAll("&quot;"), | |
| 244 | else => try w.writeByte(b), | |
| 245 | }; | |
| 247 | 246 | } |
tools/docgen.zig+21-21| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const io = std.io; | |
| 4 | 3 | const fs = std.fs; |
| 5 | 4 | const process = std.process; |
| 6 | 5 | const Progress = std.Progress; |
| ... | ... | @@ -8,8 +7,10 @@ const print = std.debug.print; |
| 8 | 7 | const mem = std.mem; |
| 9 | 8 | const testing = std.testing; |
| 10 | 9 | const Allocator = std.mem.Allocator; |
| 10 | const ArrayList = std.ArrayList; | |
| 11 | 11 | const getExternalExecutor = std.zig.system.getExternalExecutor; |
| 12 | 12 | const fatal = std.process.fatal; |
| 13 | const Writer = std.Io.Writer; | |
| 13 | 14 | |
| 14 | 15 | const max_doc_file_size = 10 * 1024 * 1024; |
| 15 | 16 | |
| ... | ... | @@ -344,10 +345,10 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { |
| 344 | 345 | var last_action: Action = .open; |
| 345 | 346 | var last_columns: ?u8 = null; |
| 346 | 347 | |
| 347 | var toc_buf = std.array_list.Managed(u8).init(allocator); | |
| 348 | var toc_buf: Writer.Allocating = .init(allocator); | |
| 348 | 349 | defer toc_buf.deinit(); |
| 349 | 350 | |
| 350 | var toc = toc_buf.writer(); | |
| 351 | const toc = &toc_buf.writer; | |
| 351 | 352 | |
| 352 | 353 | var nodes = std.array_list.Managed(Node).init(allocator); |
| 353 | 354 | defer nodes.deinit(); |
| ... | ... | @@ -422,7 +423,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { |
| 422 | 423 | } |
| 423 | 424 | if (last_action == .open) { |
| 424 | 425 | try toc.writeByte('\n'); |
| 425 | try toc.writeByteNTimes(' ', header_stack_size * 4); | |
| 426 | try toc.splatByteAll(' ', header_stack_size * 4); | |
| 426 | 427 | if (last_columns) |n| { |
| 427 | 428 | try toc.print("<ul style=\"columns: {d}\">\n", .{n}); |
| 428 | 429 | } else { |
| ... | ... | @@ -432,7 +433,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { |
| 432 | 433 | last_action = .open; |
| 433 | 434 | } |
| 434 | 435 | last_columns = columns; |
| 435 | try toc.writeByteNTimes(' ', 4 + header_stack_size * 4); | |
| 436 | try toc.splatByteAll(' ', 4 + header_stack_size * 4); | |
| 436 | 437 | try toc.print("<li><a id=\"toc-{s}\" href=\"#{s}\">{s}</a>", .{ urlized, urlized, content }); |
| 437 | 438 | } else if (mem.eql(u8, tag_name, "header_close")) { |
| 438 | 439 | if (header_stack_size == 0) { |
| ... | ... | @@ -442,7 +443,7 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { |
| 442 | 443 | _ = try eatToken(tokenizer, .bracket_close); |
| 443 | 444 | |
| 444 | 445 | if (last_action == .close) { |
| 445 | try toc.writeByteNTimes(' ', 8 + header_stack_size * 4); | |
| 446 | try toc.splatByteAll(' ', 8 + header_stack_size * 4); | |
| 446 | 447 | try toc.writeAll("</ul></li>\n"); |
| 447 | 448 | } else { |
| 448 | 449 | try toc.writeAll("</li>\n"); |
| ... | ... | @@ -591,30 +592,29 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc { |
| 591 | 592 | } |
| 592 | 593 | } |
| 593 | 594 | |
| 594 | return Toc{ | |
| 595 | return .{ | |
| 595 | 596 | .nodes = try nodes.toOwnedSlice(), |
| 596 | 597 | .toc = try toc_buf.toOwnedSlice(), |
| 597 | 598 | .urls = urls, |
| 598 | 599 | }; |
| 599 | 600 | } |
| 600 | 601 | |
| 601 | fn urlize(allocator: Allocator, input: []const u8) ![]u8 { | |
| 602 | var buf = std.array_list.Managed(u8).init(allocator); | |
| 603 | defer buf.deinit(); | |
| 602 | fn urlize(gpa: Allocator, input: []const u8) ![]u8 { | |
| 603 | var buf: ArrayList(u8) = .empty; | |
| 604 | defer buf.deinit(gpa); | |
| 604 | 605 | |
| 605 | const out = buf.writer(); | |
| 606 | 606 | for (input) |c| { |
| 607 | 607 | switch (c) { |
| 608 | 608 | 'a'...'z', 'A'...'Z', '_', '-', '0'...'9' => { |
| 609 | try out.writeByte(c); | |
| 609 | try buf.append(gpa, c); | |
| 610 | 610 | }, |
| 611 | 611 | ' ' => { |
| 612 | try out.writeByte('-'); | |
| 612 | try buf.append(gpa, '-'); | |
| 613 | 613 | }, |
| 614 | 614 | else => {}, |
| 615 | 615 | } |
| 616 | 616 | } |
| 617 | return try buf.toOwnedSlice(); | |
| 617 | return try buf.toOwnedSlice(gpa); | |
| 618 | 618 | } |
| 619 | 619 | |
| 620 | 620 | fn escapeHtml(allocator: Allocator, input: []const u8) ![]u8 { |
| ... | ... | @@ -626,7 +626,7 @@ fn escapeHtml(allocator: Allocator, input: []const u8) ![]u8 { |
| 626 | 626 | return try buf.toOwnedSlice(); |
| 627 | 627 | } |
| 628 | 628 | |
| 629 | fn writeEscaped(out: anytype, input: []const u8) !void { | |
| 629 | fn writeEscaped(out: *Writer, input: []const u8) !void { | |
| 630 | 630 | for (input) |c| { |
| 631 | 631 | try switch (c) { |
| 632 | 632 | '&' => out.writeAll("&amp;"), |
| ... | ... | @@ -662,14 +662,14 @@ fn isType(name: []const u8) bool { |
| 662 | 662 | return false; |
| 663 | 663 | } |
| 664 | 664 | |
| 665 | fn writeEscapedLines(out: anytype, text: []const u8) !void { | |
| 665 | fn writeEscapedLines(out: *Writer, text: []const u8) !void { | |
| 666 | 666 | return writeEscaped(out, text); |
| 667 | 667 | } |
| 668 | 668 | |
| 669 | 669 | fn tokenizeAndPrintRaw( |
| 670 | 670 | allocator: Allocator, |
| 671 | 671 | docgen_tokenizer: *Tokenizer, |
| 672 | out: anytype, | |
| 672 | out: *Writer, | |
| 673 | 673 | source_token: Token, |
| 674 | 674 | raw_src: []const u8, |
| 675 | 675 | ) !void { |
| ... | ... | @@ -907,14 +907,14 @@ fn tokenizeAndPrintRaw( |
| 907 | 907 | fn tokenizeAndPrint( |
| 908 | 908 | allocator: Allocator, |
| 909 | 909 | docgen_tokenizer: *Tokenizer, |
| 910 | out: anytype, | |
| 910 | out: *Writer, | |
| 911 | 911 | source_token: Token, |
| 912 | 912 | ) !void { |
| 913 | 913 | const raw_src = docgen_tokenizer.buffer[source_token.start..source_token.end]; |
| 914 | 914 | return tokenizeAndPrintRaw(allocator, docgen_tokenizer, out, source_token, raw_src); |
| 915 | 915 | } |
| 916 | 916 | |
| 917 | fn printSourceBlock(allocator: Allocator, docgen_tokenizer: *Tokenizer, out: anytype, syntax_block: SyntaxBlock) !void { | |
| 917 | fn printSourceBlock(allocator: Allocator, docgen_tokenizer: *Tokenizer, out: *Writer, syntax_block: SyntaxBlock) !void { | |
| 918 | 918 | const source_type = @tagName(syntax_block.source_type); |
| 919 | 919 | |
| 920 | 920 | try out.print("<figure><figcaption class=\"{s}-cap\"><cite class=\"file\">{s}</cite></figcaption><pre>", .{ source_type, syntax_block.name }); |
| ... | ... | @@ -932,7 +932,7 @@ fn printSourceBlock(allocator: Allocator, docgen_tokenizer: *Tokenizer, out: any |
| 932 | 932 | try out.writeAll("</pre></figure>"); |
| 933 | 933 | } |
| 934 | 934 | |
| 935 | fn printShell(out: anytype, shell_content: []const u8, escape: bool) !void { | |
| 935 | fn printShell(out: *Writer, shell_content: []const u8, escape: bool) !void { | |
| 936 | 936 | const trimmed_shell_content = mem.trim(u8, shell_content, " \r\n"); |
| 937 | 937 | try out.writeAll("<figure><figcaption class=\"shell-cap\">Shell</figcaption><pre><samp>"); |
| 938 | 938 | var cmd_cont: bool = false; |
| ... | ... | @@ -984,7 +984,7 @@ fn genHtml( |
| 984 | 984 | tokenizer: *Tokenizer, |
| 985 | 985 | toc: *Toc, |
| 986 | 986 | code_dir: std.fs.Dir, |
| 987 | out: anytype, | |
| 987 | out: *Writer, | |
| 988 | 988 | ) !void { |
| 989 | 989 | for (toc.nodes) |node| { |
| 990 | 990 | switch (node) { |
tools/doctest.zig+16-20| ... | ... | @@ -127,9 +127,9 @@ fn printOutput( |
| 127 | 127 | const obj_ext = builtin.object_format.fileExt(builtin.cpu.arch); |
| 128 | 128 | const print = std.debug.print; |
| 129 | 129 | |
| 130 | var shell_buffer = std.array_list.Managed(u8).init(arena); | |
| 130 | var shell_buffer: std.Io.Writer.Allocating = .init(arena); | |
| 131 | 131 | defer shell_buffer.deinit(); |
| 132 | var shell_out = shell_buffer.writer(); | |
| 132 | const shell_out = &shell_buffer.writer; | |
| 133 | 133 | |
| 134 | 134 | const code_name = std.fs.path.stem(input_path); |
| 135 | 135 | |
| ... | ... | @@ -600,7 +600,7 @@ fn printOutput( |
| 600 | 600 | } |
| 601 | 601 | |
| 602 | 602 | if (!code.just_check_syntax) { |
| 603 | try printShell(out, shell_buffer.items, false); | |
| 603 | try printShell(out, shell_buffer.written(), false); | |
| 604 | 604 | } |
| 605 | 605 | } |
| 606 | 606 | |
| ... | ... | @@ -975,25 +975,21 @@ fn skipPrefix(line: []const u8) []const u8 { |
| 975 | 975 | return line[3..]; |
| 976 | 976 | } |
| 977 | 977 | |
| 978 | fn escapeHtml(allocator: Allocator, input: []const u8) ![]u8 { | |
| 979 | var buf = std.array_list.Managed(u8).init(allocator); | |
| 980 | defer buf.deinit(); | |
| 981 | ||
| 982 | const out = buf.writer(); | |
| 983 | try writeEscaped(out, input); | |
| 984 | return try buf.toOwnedSlice(); | |
| 978 | fn escapeHtml(gpa: Allocator, input: []const u8) ![]u8 { | |
| 979 | var allocating: Writer.Allocating = .init(gpa); | |
| 980 | defer allocating.deinit(); | |
| 981 | try writeEscaped(&allocating.writer, input); | |
| 982 | return allocating.toOwnedSlice(); | |
| 985 | 983 | } |
| 986 | 984 | |
| 987 | fn writeEscaped(out: *Writer, input: []const u8) !void { | |
| 988 | for (input) |c| { | |
| 989 | try switch (c) { | |
| 990 | '&' => out.writeAll("&amp;"), | |
| 991 | '<' => out.writeAll("&lt;"), | |
| 992 | '>' => out.writeAll("&gt;"), | |
| 993 | '"' => out.writeAll("&quot;"), | |
| 994 | else => out.writeByte(c), | |
| 995 | }; | |
| 996 | } | |
| 985 | fn writeEscaped(w: *Writer, input: []const u8) !void { | |
| 986 | for (input) |c| try switch (c) { | |
| 987 | '&' => w.writeAll("&amp;"), | |
| 988 | '<' => w.writeAll("&lt;"), | |
| 989 | '>' => w.writeAll("&gt;"), | |
| 990 | '"' => w.writeAll("&quot;"), | |
| 991 | else => w.writeByte(c), | |
| 992 | }; | |
| 997 | 993 | } |
| 998 | 994 | |
| 999 | 995 | fn termColor(allocator: Allocator, input: []const u8) ![]u8 { |