diff options
Diffstat (limited to 'src/root.zig')
| -rw-r--r-- | src/root.zig | 86 |
1 files changed, 57 insertions, 29 deletions
diff --git a/src/root.zig b/src/root.zig index 3a7c134..30386e9 100644 --- a/src/root.zig +++ b/src/root.zig @@ -2,12 +2,14 @@ const std = @import("std"); const builtin = @import("builtin"); const Allocator = std.mem.Allocator; const parser = @import("parser.zig"); +const Element = @import("eval/Element.zig"); pub const Document = parser.Document; pub const Error = parser.Error; /// Parse the content. /// /// Use typdown_parse if you are not in Zig. pub const parse = parser.parse; +pub const parseReader = parser.parseReader; inline fn getErrorCode(err: Error) u8 { return switch (err) { @@ -43,6 +45,40 @@ export fn typdown_getErrorString(code: u8) [*:0]const u8 { }; } +/// typdown_Document is a Document for the C ABI. +const typdown_Document = extern struct { + root: ?*anyopaque = null, + errors: ?[*]typdown_Error = null, + errors_len: usize = 0, + + const typdown_Error = extern struct { + code: u8, + location: extern struct { beg: usize, end: usize }, + }; +}; + +fn from(alloc: Allocator, doc: Document) typdown_Document { + var res = typdown_Document{ .root = doc.root }; + if (doc.errors) |errors| { + defer alloc.free(errors); + res.errors = (alloc.alloc(typdown_Document.typdown_Error, errors.len) catch |err| @panic(@errorName(err))).ptr; + for (errors) |err| { + res.errors.?[0] = .{ + .code = getErrorCode(err.err), + .location = .{ .beg = err.location.beg, .end = err.location.end }, + }; + } + res.errors_len = errors.len; + } + return res; +} + +fn fromError(alloc: Allocator, err: Error) typdown_Document { + var v = alloc.alloc(typdown_Document.typdown_Error, 1) catch |e| @panic(@errorName(e)); + v[0] = .{ .code = getErrorCode(err), .location = .{ .beg = 0, .end = 0 } }; + return .{ .errors = v.ptr, .errors_len = 1 }; +} + var default_alloc: std.mem.Allocator = if (builtin.target.isWasiLibC()) std.heap.wasm_allocator @@ -52,31 +88,29 @@ var default_alloc: std.mem.Allocator = std.heap.c_allocator; /// Parse the content. -/// Code is a pointer to an u8 populated with an error code > 0. -/// -/// Returns a non-null void pointer containing the document and set the code to 0 if everything is fine. -/// Else, it returns null and set an error code above 0. -/// Use typdown_getErrorString to retrieve the string linked with the error code. -/// Use parse if you are in Zig. /// /// You must free the document with typdown_free. -export fn typdown_parse(content: [*:0]const u8, code: *u8) ?*anyopaque { - return parse(default_alloc, std.mem.span(content)) catch |err| { - code.* = getErrorCode(err); - return null; - }; +export fn typdown_parse(content: [*:0]const u8) typdown_Document { + const alloc = default_alloc; + return from(alloc, parse(alloc, std.mem.span(content)) catch |err| { + return fromError(alloc, err); + }); } /// Free the document. -export fn typdown_free(document: *anyopaque) void { - const doc: *Document = @ptrCast(@alignCast(document)); - doc.deinit(); +export fn typdown_free(self: typdown_Document) void { + const alloc = default_alloc; + if (self.root) |r| { + const root: *Element.Root = @ptrCast(@alignCast(r)); + root.deinit(); + } + if (self.errors) |errors| alloc.free(errors[0..self.errors_len]); } /// Render an HTML from the document. -export fn typdown_renderHTML(document: *anyopaque, code: *u8) ?[*:0]const u8 { - const doc: *Document = @ptrCast(@alignCast(document)); - const res = doc.renderHTML(default_alloc) catch |err| { +export fn typdown_renderHTML(document: typdown_Document, code: *u8) ?[*:0]const u8 { + const root: *Element.Root = @ptrCast(@alignCast(document.root)); + const res = root.renderHTML(default_alloc) catch |err| { code.* = getErrorCode(err); return null; }; @@ -88,10 +122,6 @@ export fn typdown_renderHTML(document: *anyopaque, code: *u8) ?[*:0]const u8 { }; } -pub fn parseReader(alloc: std.mem.Allocator, r: *std.io.Reader) (Error || std.io.Reader.Error)!*Document { - return parser.parseReader(alloc, r); -} - test { std.testing.refAllDeclsRecursive(@This()); } @@ -99,15 +129,13 @@ test { fn doTest(content: [*:0]const u8, exp: []const u8, comptime exp_code: u8) !void { const expect = std.testing.expect; - var code: u8 = undefined; - const doc = typdown_parse(content, &code) orelse { - expect(code == exp_code) catch |err| { - std.debug.print("{}\n", .{code}); - return err; - }; - return; - }; + const doc = typdown_parse(content); defer typdown_free(doc); + if (doc.errors) |errors| { + for (0..doc.errors_len) |i| if (errors[i].code == exp_code) return; + return try expect(false); + } + var code: u8 = undefined; const raw = typdown_renderHTML(doc, &code) orelse { expect(code == exp_code) catch |err| { std.debug.print("{}\n", .{code}); |
