init
handroll some libyaml bindings. I was originally going to use yaml-cpp, but C++ sucks tremendously and looking at the libyaml documentation, the event-based parser API probably works the way I want it to so let's try it out.
This commit is contained in:
commit
ca1fdb053d
33
build.zig
Normal file
33
build.zig
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const libyaml_build = @import("./libyaml.build.zig");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
const yaml_zig = b.addModule("libyaml", .{
|
||||||
|
.source_file = .{ .path = "src/libyaml.zig" },
|
||||||
|
});
|
||||||
|
// yaml_zig.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
|
||||||
|
// _ = yaml_zig;
|
||||||
|
|
||||||
|
const libyaml = libyaml_build.libyamlLib(b, .{
|
||||||
|
.name = "libyaml",
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const exe = b.addExecutable(.{
|
||||||
|
.name = "yamltest",
|
||||||
|
.root_source_file = .{ .path = "src/main.zig" },
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
});
|
||||||
|
exe.linkLibrary(libyaml);
|
||||||
|
exe.addModule("yaml", yaml_zig);
|
||||||
|
|
||||||
|
b.installArtifact(exe);
|
||||||
|
}
|
15
build.zig.zon
Normal file
15
build.zig.zon
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
.{
|
||||||
|
.name = "zaye",
|
||||||
|
.version = "0.0.1",
|
||||||
|
.paths = .{
|
||||||
|
"src",
|
||||||
|
"deps/libyaml/src",
|
||||||
|
"deps/libyaml/include",
|
||||||
|
"deps/libyaml/License",
|
||||||
|
"build.zig",
|
||||||
|
"build.zig.zon",
|
||||||
|
"libyaml.build.zig",
|
||||||
|
"LICENSE",
|
||||||
|
},
|
||||||
|
.dependencies = .{},
|
||||||
|
}
|
57
libyaml.build.zig
Normal file
57
libyaml.build.zig
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// This file is licensed under the CC0 1.0 license.
|
||||||
|
// See: https://creativecommons.org/publicdomain/zero/1.0/legalcode
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const LibyamlOptions = struct {
|
||||||
|
name: []const u8,
|
||||||
|
target: std.zig.CrossTarget,
|
||||||
|
optimize: std.builtin.OptimizeMode,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn libyamlLib(
|
||||||
|
b: *std.Build,
|
||||||
|
options: LibyamlOptions,
|
||||||
|
) *std.Build.Step.Compile {
|
||||||
|
const lib = b.addStaticLibrary(.{
|
||||||
|
.name = options.name,
|
||||||
|
.target = options.target,
|
||||||
|
.optimize = options.optimize,
|
||||||
|
});
|
||||||
|
|
||||||
|
const cflags = [_][]const u8{};
|
||||||
|
|
||||||
|
lib.linkLibC();
|
||||||
|
lib.addIncludePath(.{ .path = include_prefix });
|
||||||
|
lib.addCSourceFiles(&sources, &cflags);
|
||||||
|
lib.defineCMacro("YAML_VERSION_MAJOR", "0");
|
||||||
|
lib.defineCMacro("YAML_VERSION_MINOR", "2");
|
||||||
|
lib.defineCMacro("YAML_VERSION_PATCH", "5");
|
||||||
|
lib.defineCMacro("YAML_VERSION_STRING", "\"0.2.5\"");
|
||||||
|
|
||||||
|
b.installArtifact(lib);
|
||||||
|
|
||||||
|
return lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
_ = libyamlLib(b, .{ .name = "libyaml", .target = target, .optimize = optimize });
|
||||||
|
}
|
||||||
|
|
||||||
|
const libyaml_prefix = "deps/libyaml/";
|
||||||
|
const src_prefix = libyaml_prefix ++ "src/";
|
||||||
|
const include_prefix = libyaml_prefix ++ "include/";
|
||||||
|
|
||||||
|
const sources = [_][]const u8{
|
||||||
|
src_prefix ++ "api.c",
|
||||||
|
src_prefix ++ "dumper.c",
|
||||||
|
src_prefix ++ "emitter.c",
|
||||||
|
src_prefix ++ "loader.c",
|
||||||
|
src_prefix ++ "parser.c",
|
||||||
|
src_prefix ++ "reader.c",
|
||||||
|
src_prefix ++ "scanner.c",
|
||||||
|
src_prefix ++ "writer.c",
|
||||||
|
};
|
419
src/libyaml.zig
Normal file
419
src/libyaml.zig
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
pub const libyaml = struct {
|
||||||
|
pub const Encoding = enum(c_int) {
|
||||||
|
any,
|
||||||
|
utf8,
|
||||||
|
utf16le,
|
||||||
|
utf16be,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const VersionDirective = extern struct {
|
||||||
|
major: c_int,
|
||||||
|
minor: c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TagDirective = extern struct {
|
||||||
|
handle: ?[*:0]u8,
|
||||||
|
prefix: ?[*:0]u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const LineBreak = enum(c_int) {
|
||||||
|
any,
|
||||||
|
cr,
|
||||||
|
lf,
|
||||||
|
crlf,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ErrorType = enum(c_int) {
|
||||||
|
okay,
|
||||||
|
alloc_error,
|
||||||
|
read_error,
|
||||||
|
scanner_error,
|
||||||
|
parser_error,
|
||||||
|
composer_error,
|
||||||
|
writer_error,
|
||||||
|
emitter_error,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Mark = extern struct {
|
||||||
|
index: usize,
|
||||||
|
line: usize,
|
||||||
|
column: usize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ScalarStyle = enum(c_int) {
|
||||||
|
any,
|
||||||
|
plain,
|
||||||
|
single_quoted,
|
||||||
|
double_quoted,
|
||||||
|
literal,
|
||||||
|
folded,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const SequenceStyle = enum(c_int) {
|
||||||
|
any,
|
||||||
|
block,
|
||||||
|
flow,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MappingStyle = enum(c_int) {
|
||||||
|
any,
|
||||||
|
block,
|
||||||
|
flow,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const TokenType = enum(c_int) {
|
||||||
|
none,
|
||||||
|
stream_start,
|
||||||
|
stream_end,
|
||||||
|
version_directive,
|
||||||
|
tag_directive,
|
||||||
|
document_start,
|
||||||
|
document_end,
|
||||||
|
block_sequence_start,
|
||||||
|
block_mapping_start,
|
||||||
|
block_end,
|
||||||
|
flow_sequence_start,
|
||||||
|
flow_sequence_end,
|
||||||
|
flow_mapping_start,
|
||||||
|
flow_mapping_end,
|
||||||
|
block_entry,
|
||||||
|
flow_entry,
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
alias,
|
||||||
|
anchor,
|
||||||
|
tag,
|
||||||
|
scalar,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Token = extern struct {
|
||||||
|
type: TokenType,
|
||||||
|
data: extern union {
|
||||||
|
stream_start: extern struct {
|
||||||
|
encoding: Encoding,
|
||||||
|
},
|
||||||
|
alias: extern struct {
|
||||||
|
value: ?[*:0]u8,
|
||||||
|
},
|
||||||
|
anchor: extern struct {
|
||||||
|
value: ?[*:0]u8,
|
||||||
|
},
|
||||||
|
tag: extern struct {
|
||||||
|
handle: ?[*:0]u8,
|
||||||
|
suffix: ?[*:0]u8,
|
||||||
|
},
|
||||||
|
scalar: extern struct {
|
||||||
|
value: [*]u8,
|
||||||
|
length: usize,
|
||||||
|
style: ScalarStyle,
|
||||||
|
},
|
||||||
|
version_directive: VersionDirective,
|
||||||
|
tag_directive: TagDirective,
|
||||||
|
},
|
||||||
|
start_mark: Mark,
|
||||||
|
end_mark: Mark,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const EventType = enum(c_int) {
|
||||||
|
empty,
|
||||||
|
stream_start,
|
||||||
|
stream_end,
|
||||||
|
document_start,
|
||||||
|
document_end,
|
||||||
|
alias,
|
||||||
|
scalar,
|
||||||
|
sequence_start,
|
||||||
|
sequence_end,
|
||||||
|
mapping_start,
|
||||||
|
mapping_end,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Event = extern struct {
|
||||||
|
type: EventType,
|
||||||
|
data: extern union {
|
||||||
|
stream_start: extern struct {
|
||||||
|
encoding: Encoding,
|
||||||
|
},
|
||||||
|
document_start: extern struct {
|
||||||
|
version_directive: ?*VersionDirective,
|
||||||
|
tag_directives: extern struct {
|
||||||
|
start: ?*TagDirective,
|
||||||
|
end: ?*TagDirective,
|
||||||
|
},
|
||||||
|
implicit: c_int,
|
||||||
|
},
|
||||||
|
document_end: extern struct { implicit: c_int },
|
||||||
|
alias: extern struct { anchor: [*:0]u8 },
|
||||||
|
scalar: extern struct {
|
||||||
|
anchor: ?[*:0]u8,
|
||||||
|
tag: ?[*:0]u8,
|
||||||
|
value: [*]u8,
|
||||||
|
length: usize,
|
||||||
|
plain_implicit: c_int,
|
||||||
|
quoted_implicit: c_int,
|
||||||
|
style: ScalarStyle,
|
||||||
|
},
|
||||||
|
sequence_start: extern struct {
|
||||||
|
anchor: ?[*:0]u8,
|
||||||
|
tag: ?[*:0]u8,
|
||||||
|
implicit: c_int,
|
||||||
|
style: SequenceStyle,
|
||||||
|
},
|
||||||
|
mapping_start: extern struct {
|
||||||
|
anchor: ?[*:0]u8,
|
||||||
|
tag: ?[*:0]u8,
|
||||||
|
implicit: c_int,
|
||||||
|
style: MappingStyle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
start_mark: Mark,
|
||||||
|
end_mark: Mark,
|
||||||
|
|
||||||
|
pub fn deinit(self: *Event) void {
|
||||||
|
yaml_event_delete(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn yaml_event_delete(event: *Event) void;
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const SimpleKey = extern struct {
|
||||||
|
possible: c_int,
|
||||||
|
required: c_int,
|
||||||
|
token_number: usize,
|
||||||
|
mark: Mark,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const NodeType = enum(c_int) {
|
||||||
|
none,
|
||||||
|
scalar,
|
||||||
|
sequence,
|
||||||
|
mapping,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const NodeItem = c_int;
|
||||||
|
|
||||||
|
pub const NodePair = extern struct {
|
||||||
|
key: c_int,
|
||||||
|
value: c_int,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Node = extern struct {
|
||||||
|
type: NodeType,
|
||||||
|
tag: ?[*:0]u8,
|
||||||
|
data: extern union {
|
||||||
|
scalar: extern struct {
|
||||||
|
value: ?[*:0]u8,
|
||||||
|
length: usize,
|
||||||
|
style: ScalarStyle,
|
||||||
|
},
|
||||||
|
sequence: extern struct {
|
||||||
|
items: extern struct {
|
||||||
|
start: ?*NodeItem,
|
||||||
|
end: ?*NodeItem,
|
||||||
|
top: ?*NodeItem,
|
||||||
|
},
|
||||||
|
style: SequenceStyle,
|
||||||
|
},
|
||||||
|
mapping: extern struct {
|
||||||
|
pairs: extern struct {
|
||||||
|
start: ?*NodePair,
|
||||||
|
end: ?*NodePair,
|
||||||
|
top: ?*NodePair,
|
||||||
|
},
|
||||||
|
style: MappingStyle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
start_mark: Mark,
|
||||||
|
end_mark: Mark,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Document = extern struct {
|
||||||
|
nodes: extern struct {
|
||||||
|
start: ?*Node,
|
||||||
|
end: ?*Node,
|
||||||
|
top: ?*Node,
|
||||||
|
},
|
||||||
|
version_directive: ?*VersionDirective,
|
||||||
|
tag_directives: extern struct {
|
||||||
|
start: ?*TagDirective,
|
||||||
|
end: ?*TagDirective,
|
||||||
|
},
|
||||||
|
start_implicit: c_int,
|
||||||
|
end_implicit: c_int,
|
||||||
|
start_mark: Mark,
|
||||||
|
end_mark: Mark,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const AliasData = extern struct {
|
||||||
|
anchor: ?[*]u8,
|
||||||
|
index: c_int,
|
||||||
|
mark: Mark,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ReadHandler = *const fn (ctx: ?*anyopaque, buffer: [*]u8, buffer_size: usize, bytes_read: *usize) callconv(.C) c_int;
|
||||||
|
|
||||||
|
pub const ParserState = enum(c_int) {
|
||||||
|
stream_start,
|
||||||
|
implicit_document_start,
|
||||||
|
document_start,
|
||||||
|
document_content,
|
||||||
|
document_end,
|
||||||
|
block_node,
|
||||||
|
block_node_or_indentless_sequence,
|
||||||
|
flow_node,
|
||||||
|
block_sequence_first_entry,
|
||||||
|
block_sequence_entry,
|
||||||
|
indentless_sequence_entry,
|
||||||
|
block_mapping_first_key,
|
||||||
|
block_mapping_key,
|
||||||
|
block_mapping_value,
|
||||||
|
flow_sequence_first_entry,
|
||||||
|
flow_sequence_entry,
|
||||||
|
flow_sequence_entry_mapping_key,
|
||||||
|
flow_sequence_entry_mapping_value,
|
||||||
|
flow_sequence_entry_mapping_end,
|
||||||
|
flow_mapping_first_key,
|
||||||
|
flow_mapping_key,
|
||||||
|
flow_mapping_value,
|
||||||
|
flow_mapping_empty_value,
|
||||||
|
end,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Parser = extern struct {
|
||||||
|
@"error": ErrorType,
|
||||||
|
problem: ?[*:0]const u8,
|
||||||
|
problem_offset: usize,
|
||||||
|
problem_value: c_int,
|
||||||
|
problem_mark: Mark,
|
||||||
|
context: ?[*:0]const u8,
|
||||||
|
context_mark: Mark,
|
||||||
|
read_handler: ?ReadHandler,
|
||||||
|
read_handler_data: ?*anyopaque,
|
||||||
|
input: extern union {
|
||||||
|
string: extern struct {
|
||||||
|
start: ?[*]const u8,
|
||||||
|
end: ?[*]const u8,
|
||||||
|
current: ?[*]const u8,
|
||||||
|
},
|
||||||
|
file: ?*anyopaque,
|
||||||
|
},
|
||||||
|
eof: c_int,
|
||||||
|
buffer: extern struct {
|
||||||
|
start: ?[*]u8,
|
||||||
|
end: ?[*]u8,
|
||||||
|
pointer: ?[*]u8,
|
||||||
|
last: ?[*]u8,
|
||||||
|
},
|
||||||
|
unread: usize,
|
||||||
|
raw_buffer: extern struct {
|
||||||
|
start: ?[*]u8,
|
||||||
|
end: ?[*]u8,
|
||||||
|
pointer: ?[*]u8,
|
||||||
|
last: ?[*]u8,
|
||||||
|
},
|
||||||
|
encoding: Encoding,
|
||||||
|
offset: usize,
|
||||||
|
mark: Mark,
|
||||||
|
stream_start_produced: c_int,
|
||||||
|
stream_end_produced: c_int,
|
||||||
|
flow_level: c_int,
|
||||||
|
tokens: extern struct {
|
||||||
|
start: ?*Token,
|
||||||
|
end: ?*Token,
|
||||||
|
head: ?*Token,
|
||||||
|
tail: ?*Token,
|
||||||
|
},
|
||||||
|
tokens_parsed: usize,
|
||||||
|
token_available: c_int,
|
||||||
|
indents: extern struct {
|
||||||
|
start: ?*c_int,
|
||||||
|
end: ?*c_int,
|
||||||
|
top: ?*c_int,
|
||||||
|
},
|
||||||
|
indent: c_int,
|
||||||
|
simple_key_allowed: c_int,
|
||||||
|
simple_keys: extern struct {
|
||||||
|
start: ?*SimpleKey,
|
||||||
|
end: ?*SimpleKey,
|
||||||
|
top: ?*SimpleKey,
|
||||||
|
},
|
||||||
|
states: extern struct {
|
||||||
|
start: ?*SimpleKey,
|
||||||
|
end: ?*SimpleKey,
|
||||||
|
top: ?*SimpleKey,
|
||||||
|
},
|
||||||
|
state: ParserState,
|
||||||
|
marks: extern struct {
|
||||||
|
start: ?*Mark,
|
||||||
|
end: ?*Mark,
|
||||||
|
top: ?*Mark,
|
||||||
|
},
|
||||||
|
tag_directives: extern struct {
|
||||||
|
start: ?*TagDirective,
|
||||||
|
end: ?*TagDirective,
|
||||||
|
top: ?*TagDirective,
|
||||||
|
},
|
||||||
|
aliases: extern struct {
|
||||||
|
start: ?*AliasData,
|
||||||
|
end: ?*AliasData,
|
||||||
|
top: ?*AliasData,
|
||||||
|
},
|
||||||
|
document: ?*Document,
|
||||||
|
|
||||||
|
pub fn init() !Parser {
|
||||||
|
var parser: Parser = undefined;
|
||||||
|
if (yaml_parser_initialize(&parser) == 0) return error.Failed;
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Parser) void {
|
||||||
|
yaml_parser_delete(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setInputString(self: *Parser, input: []const u8) void {
|
||||||
|
yaml_parser_set_input_string(self, input.ptr, input.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(self: *Parser, event: *Event) !void {
|
||||||
|
if (yaml_parser_parse(self, event) == 0) return error.Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub extern fn yaml_parser_initialize(parser: *Parser) c_int;
|
||||||
|
pub extern fn yaml_parser_delete(parser: *Parser) void;
|
||||||
|
pub extern fn yaml_parser_set_input_string(parser: *Parser, input: [*]const u8, size: usize) void;
|
||||||
|
pub extern fn yaml_parser_set_input(parser: *Parser, handler: ReadHandler, data: ?*anyopaque) void;
|
||||||
|
pub extern fn yaml_parser_set_encoding(parser: *Parser, encoding: Encoding) void;
|
||||||
|
pub extern fn yaml_parser_scan(parser: *Parser, token: *Token) c_int;
|
||||||
|
pub extern fn yaml_parser_parse(parser: *Parser, event: *Event) c_int;
|
||||||
|
pub extern fn yaml_parser_load(parser: *Parser, document: *Document) c_int;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
pub fn loadString(data: []const u8) bool {
|
||||||
|
// return api.load_string(data.ptr, data.len);
|
||||||
|
|
||||||
|
var parser = libyaml.Parser.init() catch {
|
||||||
|
std.debug.print("noinit\n", .{});
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
defer parser.deinit();
|
||||||
|
|
||||||
|
parser.setInputString(data);
|
||||||
|
|
||||||
|
var done = false;
|
||||||
|
while (!done) {
|
||||||
|
var event: libyaml.Event = undefined;
|
||||||
|
parser.parse(&event) catch {
|
||||||
|
std.debug.print("noparse\n", .{});
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
defer event.deinit();
|
||||||
|
|
||||||
|
std.debug.print("event: {s}\n", .{@tagName(event.type)});
|
||||||
|
|
||||||
|
done = event.type == .stream_end;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
8
src/main.zig
Normal file
8
src/main.zig
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const yaml = @import("yaml");
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
if (yaml.loadString("[1,2,3]"))
|
||||||
|
std.debug.print("its a list\n", .{});
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user