forked from mirror/vulkan-zig
Adapt to latest Zig master
See ziglang/zig/pull/10055
This commit is contained in:
@@ -93,7 +93,7 @@ pub const GraphicsContext = struct {
|
|||||||
graphics_queue: Queue,
|
graphics_queue: Queue,
|
||||||
present_queue: Queue,
|
present_queue: Queue,
|
||||||
|
|
||||||
pub fn init(allocator: *Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !GraphicsContext {
|
pub fn init(allocator: Allocator, app_name: [*:0]const u8, window: *c.GLFWwindow) !GraphicsContext {
|
||||||
var self: GraphicsContext = undefined;
|
var self: GraphicsContext = undefined;
|
||||||
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
|
self.vkb = try BaseDispatch.load(c.glfwGetInstanceProcAddress);
|
||||||
|
|
||||||
@@ -236,7 +236,7 @@ const QueueAllocation = struct {
|
|||||||
fn pickPhysicalDevice(
|
fn pickPhysicalDevice(
|
||||||
vki: InstanceDispatch,
|
vki: InstanceDispatch,
|
||||||
instance: vk.Instance,
|
instance: vk.Instance,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
) !DeviceCandidate {
|
) !DeviceCandidate {
|
||||||
var device_count: u32 = undefined;
|
var device_count: u32 = undefined;
|
||||||
@@ -259,7 +259,7 @@ fn pickPhysicalDevice(
|
|||||||
fn checkSuitable(
|
fn checkSuitable(
|
||||||
vki: InstanceDispatch,
|
vki: InstanceDispatch,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
surface: vk.SurfaceKHR,
|
surface: vk.SurfaceKHR,
|
||||||
) !?DeviceCandidate {
|
) !?DeviceCandidate {
|
||||||
const props = vki.getPhysicalDeviceProperties(pdev);
|
const props = vki.getPhysicalDeviceProperties(pdev);
|
||||||
@@ -283,7 +283,7 @@ fn checkSuitable(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: *Allocator, surface: vk.SurfaceKHR) !?QueueAllocation {
|
fn allocateQueues(vki: InstanceDispatch, pdev: vk.PhysicalDevice, allocator: Allocator, surface: vk.SurfaceKHR) !?QueueAllocation {
|
||||||
var family_count: u32 = undefined;
|
var family_count: u32 = undefined;
|
||||||
vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
|
vki.getPhysicalDeviceQueueFamilyProperties(pdev, &family_count, null);
|
||||||
|
|
||||||
@@ -329,7 +329,7 @@ fn checkSurfaceSupport(vki: InstanceDispatch, pdev: vk.PhysicalDevice, surface:
|
|||||||
fn checkExtensionSupport(
|
fn checkExtensionSupport(
|
||||||
vki: InstanceDispatch,
|
vki: InstanceDispatch,
|
||||||
pdev: vk.PhysicalDevice,
|
pdev: vk.PhysicalDevice,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
) !bool {
|
) !bool {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try vki.enumerateDeviceExtensionProperties(pdev, null, &count, null);
|
_ = try vki.enumerateDeviceExtensionProperties(pdev, null, &count, null);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ pub const Swapchain = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
gc: *const GraphicsContext,
|
gc: *const GraphicsContext,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
|
|
||||||
surface_format: vk.SurfaceFormatKHR,
|
surface_format: vk.SurfaceFormatKHR,
|
||||||
present_mode: vk.PresentModeKHR,
|
present_mode: vk.PresentModeKHR,
|
||||||
@@ -21,11 +21,11 @@ pub const Swapchain = struct {
|
|||||||
image_index: u32,
|
image_index: u32,
|
||||||
next_image_acquired: vk.Semaphore,
|
next_image_acquired: vk.Semaphore,
|
||||||
|
|
||||||
pub fn init(gc: *const GraphicsContext, allocator: *Allocator, extent: vk.Extent2D) !Swapchain {
|
pub fn init(gc: *const GraphicsContext, allocator: Allocator, extent: vk.Extent2D) !Swapchain {
|
||||||
return try initRecycle(gc, allocator, extent, .null_handle);
|
return try initRecycle(gc, allocator, extent, .null_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initRecycle(gc: *const GraphicsContext, allocator: *Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain {
|
pub fn initRecycle(gc: *const GraphicsContext, allocator: Allocator, extent: vk.Extent2D, old_handle: vk.SwapchainKHR) !Swapchain {
|
||||||
const caps = try gc.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface);
|
const caps = try gc.vki.getPhysicalDeviceSurfaceCapabilitiesKHR(gc.pdev, gc.surface);
|
||||||
const actual_extent = findActualExtent(caps, extent);
|
const actual_extent = findActualExtent(caps, extent);
|
||||||
if (actual_extent.width == 0 or actual_extent.height == 0) {
|
if (actual_extent.width == 0 or actual_extent.height == 0) {
|
||||||
@@ -243,7 +243,7 @@ const SwapImage = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, format: vk.Format, allocator: *Allocator) ![]SwapImage {
|
fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, format: vk.Format, allocator: Allocator) ![]SwapImage {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try gc.vkd.getSwapchainImagesKHR(gc.dev, swapchain, &count, null);
|
_ = try gc.vkd.getSwapchainImagesKHR(gc.dev, swapchain, &count, null);
|
||||||
const images = try allocator.alloc(vk.Image, count);
|
const images = try allocator.alloc(vk.Image, count);
|
||||||
@@ -264,7 +264,7 @@ fn initSwapchainImages(gc: *const GraphicsContext, swapchain: vk.SwapchainKHR, f
|
|||||||
return swap_images;
|
return swap_images;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn findSurfaceFormat(gc: *const GraphicsContext, allocator: *Allocator) !vk.SurfaceFormatKHR {
|
fn findSurfaceFormat(gc: *const GraphicsContext, allocator: Allocator) !vk.SurfaceFormatKHR {
|
||||||
const preferred = vk.SurfaceFormatKHR{
|
const preferred = vk.SurfaceFormatKHR{
|
||||||
.format = .b8g8r8a8_srgb,
|
.format = .b8g8r8a8_srgb,
|
||||||
.color_space = .srgb_nonlinear_khr,
|
.color_space = .srgb_nonlinear_khr,
|
||||||
@@ -285,7 +285,7 @@ fn findSurfaceFormat(gc: *const GraphicsContext, allocator: *Allocator) !vk.Surf
|
|||||||
return surface_formats[0]; // There must always be at least one supported surface format
|
return surface_formats[0]; // There must always be at least one supported surface format
|
||||||
}
|
}
|
||||||
|
|
||||||
fn findPresentMode(gc: *const GraphicsContext, allocator: *Allocator) !vk.PresentModeKHR {
|
fn findPresentMode(gc: *const GraphicsContext, allocator: Allocator) !vk.PresentModeKHR {
|
||||||
var count: u32 = undefined;
|
var count: u32 = undefined;
|
||||||
_ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);
|
_ = try gc.vki.getPhysicalDeviceSurfacePresentModesKHR(gc.pdev, gc.surface, &count, null);
|
||||||
const present_modes = try allocator.alloc(vk.PresentModeKHR, count);
|
const present_modes = try allocator.alloc(vk.PresentModeKHR, count);
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ fn copyBuffer(gc: *const GraphicsContext, pool: vk.CommandPool, dst: vk.Buffer,
|
|||||||
fn createCommandBuffers(
|
fn createCommandBuffers(
|
||||||
gc: *const GraphicsContext,
|
gc: *const GraphicsContext,
|
||||||
pool: vk.CommandPool,
|
pool: vk.CommandPool,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
buffer: vk.Buffer,
|
buffer: vk.Buffer,
|
||||||
extent: vk.Extent2D,
|
extent: vk.Extent2D,
|
||||||
render_pass: vk.RenderPass,
|
render_pass: vk.RenderPass,
|
||||||
@@ -291,12 +291,12 @@ fn createCommandBuffers(
|
|||||||
return cmdbufs;
|
return cmdbufs;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, allocator: *Allocator, cmdbufs: []vk.CommandBuffer) void {
|
fn destroyCommandBuffers(gc: *const GraphicsContext, pool: vk.CommandPool, allocator: Allocator, cmdbufs: []vk.CommandBuffer) void {
|
||||||
gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr);
|
gc.vkd.freeCommandBuffers(gc.dev, pool, @truncate(u32, cmdbufs.len), cmdbufs.ptr);
|
||||||
allocator.free(cmdbufs);
|
allocator.free(cmdbufs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn createFramebuffers(gc: *const GraphicsContext, allocator: *Allocator, render_pass: vk.RenderPass, swapchain: Swapchain) ![]vk.Framebuffer {
|
fn createFramebuffers(gc: *const GraphicsContext, allocator: Allocator, render_pass: vk.RenderPass, swapchain: Swapchain) ![]vk.Framebuffer {
|
||||||
const framebuffers = try allocator.alloc(vk.Framebuffer, swapchain.swap_images.len);
|
const framebuffers = try allocator.alloc(vk.Framebuffer, swapchain.swap_images.len);
|
||||||
errdefer allocator.free(framebuffers);
|
errdefer allocator.free(framebuffers);
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ fn createFramebuffers(gc: *const GraphicsContext, allocator: *Allocator, render_
|
|||||||
return framebuffers;
|
return framebuffers;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroyFramebuffers(gc: *const GraphicsContext, allocator: *Allocator, framebuffers: []const vk.Framebuffer) void {
|
fn destroyFramebuffers(gc: *const GraphicsContext, allocator: Allocator, framebuffers: []const vk.Framebuffer) void {
|
||||||
for (framebuffers) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
|
for (framebuffers) |fb| gc.vkd.destroyFramebuffer(gc.dev, fb, null);
|
||||||
allocator.free(framebuffers);
|
allocator.free(framebuffers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ pub const IdRenderer = struct {
|
|||||||
tags: []const []const u8,
|
tags: []const []const u8,
|
||||||
text_cache: std.ArrayList(u8),
|
text_cache: std.ArrayList(u8),
|
||||||
|
|
||||||
pub fn init(allocator: *Allocator, tags: []const []const u8) IdRenderer {
|
pub fn init(allocator: Allocator, tags: []const []const u8) IdRenderer {
|
||||||
return .{
|
return .{
|
||||||
.tags = tags,
|
.tags = tags,
|
||||||
.text_cache = std.ArrayList(u8).init(allocator),
|
.text_cache = std.ArrayList(u8).init(allocator),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub fn main() !void {
|
|||||||
|
|
||||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
const allocator = &arena.allocator;
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
var args = std.process.args();
|
var args = std.process.args();
|
||||||
const prog_name = try args.next(allocator) orelse return error.ExecutableNameMissing;
|
const prog_name = try args.next(allocator) orelse return error.ExecutableNameMissing;
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ pub const XmlCTokenizer = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TYPEDEF = kw_typedef DECLARATION ';'
|
// TYPEDEF = kw_typedef DECLARATION ';'
|
||||||
pub fn parseTypedef(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Declaration {
|
pub fn parseTypedef(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Declaration {
|
||||||
_ = try xctok.expect(.kw_typedef);
|
_ = try xctok.expect(.kw_typedef);
|
||||||
const decl = try parseDeclaration(allocator, xctok);
|
const decl = try parseDeclaration(allocator, xctok);
|
||||||
_ = try xctok.expect(.semicolon);
|
_ = try xctok.expect(.semicolon);
|
||||||
@@ -256,7 +256,7 @@ pub fn parseTypedef(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Decl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MEMBER = DECLARATION (':' int)?
|
// MEMBER = DECLARATION (':' int)?
|
||||||
pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Container.Field {
|
pub fn parseMember(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Container.Field {
|
||||||
const decl = try parseDeclaration(allocator, xctok);
|
const decl = try parseDeclaration(allocator, xctok);
|
||||||
var field = registry.Container.Field{
|
var field = registry.Container.Field{
|
||||||
.name = decl.name orelse return error.MissingTypeIdentifier,
|
.name = decl.name orelse return error.MissingTypeIdentifier,
|
||||||
@@ -284,7 +284,7 @@ pub fn parseMember(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Conta
|
|||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parseParamOrProto(allocator: *Allocator, xctok: *XmlCTokenizer) !registry.Declaration {
|
pub fn parseParamOrProto(allocator: Allocator, xctok: *XmlCTokenizer) !registry.Declaration {
|
||||||
const decl = try parseDeclaration(allocator, xctok);
|
const decl = try parseDeclaration(allocator, xctok);
|
||||||
if (try xctok.peek()) |_| {
|
if (try xctok.peek()) |_| {
|
||||||
return error.InvalidSyntax;
|
return error.InvalidSyntax;
|
||||||
@@ -315,7 +315,7 @@ pub const ParseError = error{
|
|||||||
// DECLARATION = kw_const? type_name DECLARATOR
|
// DECLARATION = kw_const? type_name DECLARATOR
|
||||||
// DECLARATOR = POINTERS (id | name)? ('[' ARRAY_DECLARATOR ']')*
|
// DECLARATOR = POINTERS (id | name)? ('[' ARRAY_DECLARATOR ']')*
|
||||||
// | POINTERS '(' FNPTRSUFFIX
|
// | POINTERS '(' FNPTRSUFFIX
|
||||||
fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) ParseError!Declaration {
|
fn parseDeclaration(allocator: Allocator, xctok: *XmlCTokenizer) ParseError!Declaration {
|
||||||
// Parse declaration constness
|
// Parse declaration constness
|
||||||
var tok = try xctok.nextNoEof();
|
var tok = try xctok.nextNoEof();
|
||||||
const inner_is_const = tok.kind == .kw_const;
|
const inner_is_const = tok.kind == .kw_const;
|
||||||
@@ -377,7 +377,7 @@ fn parseDeclaration(allocator: *Allocator, xctok: *XmlCTokenizer) ParseError!Dec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FNPTRSUFFIX = kw_vkapi_ptr '*' name' ')' '(' ('void' | (DECLARATION (',' DECLARATION)*)?) ')'
|
// FNPTRSUFFIX = kw_vkapi_ptr '*' name' ')' '(' ('void' | (DECLARATION (',' DECLARATION)*)?) ')'
|
||||||
fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: TypeInfo) !?Declaration {
|
fn parseFnPtrSuffix(allocator: Allocator, xctok: *XmlCTokenizer, return_type: TypeInfo) !?Declaration {
|
||||||
const lparen = try xctok.peek();
|
const lparen = try xctok.peek();
|
||||||
if (lparen == null or lparen.?.kind != .lparen) {
|
if (lparen == null or lparen.?.kind != .lparen) {
|
||||||
return null;
|
return null;
|
||||||
@@ -445,7 +445,7 @@ fn parseFnPtrSuffix(allocator: *Allocator, xctok: *XmlCTokenizer, return_type: T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// POINTERS = (kw_const? '*')*
|
// POINTERS = (kw_const? '*')*
|
||||||
fn parsePointers(allocator: *Allocator, xctok: *XmlCTokenizer, inner_const: bool, inner: TypeInfo) !TypeInfo {
|
fn parsePointers(allocator: Allocator, xctok: *XmlCTokenizer, inner_const: bool, inner: TypeInfo) !TypeInfo {
|
||||||
var type_info = inner;
|
var type_info = inner;
|
||||||
var first_const = inner_const;
|
var first_const = inner_const;
|
||||||
|
|
||||||
@@ -606,7 +606,7 @@ test "parseTypedef" {
|
|||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
|
|
||||||
var xctok = XmlCTokenizer.init(document.root);
|
var xctok = XmlCTokenizer.init(document.root);
|
||||||
const decl = try parseTypedef(&arena.allocator, &xctok);
|
const decl = try parseTypedef(arena.allocator(), &xctok);
|
||||||
|
|
||||||
try testing.expectEqualSlices(u8, "pythons", decl.name);
|
try testing.expectEqualSlices(u8, "pythons", decl.name);
|
||||||
const array = decl.decl_type.typedef.array;
|
const array = decl.decl_type.typedef.array;
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ const EnumFieldMerger = struct {
|
|||||||
const EnumExtensionMap = std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(reg.Enum.Field));
|
const EnumExtensionMap = std.StringArrayHashMapUnmanaged(std.ArrayListUnmanaged(reg.Enum.Field));
|
||||||
const FieldSet = std.StringArrayHashMapUnmanaged(void);
|
const FieldSet = std.StringArrayHashMapUnmanaged(void);
|
||||||
|
|
||||||
arena: *Allocator,
|
arena: Allocator,
|
||||||
registry: *reg.Registry,
|
registry: *reg.Registry,
|
||||||
enum_extensions: EnumExtensionMap,
|
enum_extensions: EnumExtensionMap,
|
||||||
field_set: FieldSet,
|
field_set: FieldSet,
|
||||||
|
|
||||||
fn init(arena: *Allocator, registry: *reg.Registry) EnumFieldMerger {
|
fn init(arena: Allocator, registry: *reg.Registry) EnumFieldMerger {
|
||||||
return .{
|
return .{
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
.registry = registry,
|
.registry = registry,
|
||||||
@@ -99,7 +99,7 @@ pub const Generator = struct {
|
|||||||
registry: reg.Registry,
|
registry: reg.Registry,
|
||||||
id_renderer: IdRenderer,
|
id_renderer: IdRenderer,
|
||||||
|
|
||||||
fn init(allocator: *Allocator, spec: *xml.Element) !Generator {
|
fn init(allocator: Allocator, spec: *xml.Element) !Generator {
|
||||||
const result = try parseXml(allocator, spec);
|
const result = try parseXml(allocator, spec);
|
||||||
|
|
||||||
const tags = try allocator.alloc([]const u8, result.registry.tags.len);
|
const tags = try allocator.alloc([]const u8, result.registry.tags.len);
|
||||||
@@ -128,13 +128,13 @@ pub const Generator = struct {
|
|||||||
|
|
||||||
// Solve `registry.declarations` according to `registry.extensions` and `registry.features`.
|
// Solve `registry.declarations` according to `registry.extensions` and `registry.features`.
|
||||||
fn mergeEnumFields(self: *Generator) !void {
|
fn mergeEnumFields(self: *Generator) !void {
|
||||||
var merger = EnumFieldMerger.init(&self.arena.allocator, &self.registry);
|
var merger = EnumFieldMerger.init(self.arena.allocator(), &self.registry);
|
||||||
try merger.merge();
|
try merger.merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/KhronosGroup/Vulkan-Docs/pull/1556
|
// https://github.com/KhronosGroup/Vulkan-Docs/pull/1556
|
||||||
fn fixupBitFlags(self: *Generator) !void {
|
fn fixupBitFlags(self: *Generator) !void {
|
||||||
var seen_bits = std.StringArrayHashMap(void).init(&self.arena.allocator);
|
var seen_bits = std.StringArrayHashMap(void).init(self.arena.allocator());
|
||||||
defer seen_bits.deinit();
|
defer seen_bits.deinit();
|
||||||
|
|
||||||
for (self.registry.decls) |decl| {
|
for (self.registry.decls) |decl| {
|
||||||
@@ -166,7 +166,7 @@ pub const Generator = struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(self: *Generator, writer: anytype) !void {
|
fn render(self: *Generator, writer: anytype) !void {
|
||||||
try renderRegistry(writer, &self.arena.allocator, &self.registry, &self.id_renderer);
|
try renderRegistry(writer, self.arena.allocator(), &self.registry, &self.id_renderer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -174,7 +174,7 @@ pub const Generator = struct {
|
|||||||
/// and the resulting binding is written to `writer`. `allocator` will be used to allocate temporary
|
/// and the resulting binding is written to `writer`. `allocator` will be used to allocate temporary
|
||||||
/// internal datastructures - mostly via an ArenaAllocator, but sometimes a hashmap uses this allocator
|
/// internal datastructures - mostly via an ArenaAllocator, but sometimes a hashmap uses this allocator
|
||||||
/// directly.
|
/// directly.
|
||||||
pub fn generate(allocator: *Allocator, spec_xml: []const u8, writer: anytype) !void {
|
pub fn generate(allocator: Allocator, spec_xml: []const u8, writer: anytype) !void {
|
||||||
const spec = try xml.parse(allocator, spec_xml);
|
const spec = try xml.parse(allocator, spec_xml);
|
||||||
defer spec.deinit();
|
defer spec.deinit();
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ pub const ParseResult = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parseXml(backing_allocator: *Allocator, root: *xml.Element) !ParseResult {
|
pub fn parseXml(backing_allocator: Allocator, root: *xml.Element) !ParseResult {
|
||||||
var arena = ArenaAllocator.init(backing_allocator);
|
var arena = ArenaAllocator.init(backing_allocator);
|
||||||
errdefer arena.deinit();
|
errdefer arena.deinit();
|
||||||
|
|
||||||
const allocator = &arena.allocator;
|
const allocator = arena.allocator();
|
||||||
|
|
||||||
var reg = registry.Registry{
|
var reg = registry.Registry{
|
||||||
.copyright = root.getCharData("comment") orelse return error.InvalidRegistry,
|
.copyright = root.getCharData("comment") orelse return error.InvalidRegistry,
|
||||||
@@ -38,7 +38,7 @@ pub fn parseXml(backing_allocator: *Allocator, root: *xml.Element) !ParseResult
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseDeclarations(allocator: *Allocator, root: *xml.Element) ![]registry.Declaration {
|
fn parseDeclarations(allocator: Allocator, root: *xml.Element) ![]registry.Declaration {
|
||||||
var types_elem = root.findChildByTag("types") orelse return error.InvalidRegistry;
|
var types_elem = root.findChildByTag("types") orelse return error.InvalidRegistry;
|
||||||
var commands_elem = root.findChildByTag("commands") orelse return error.InvalidRegistry;
|
var commands_elem = root.findChildByTag("commands") orelse return error.InvalidRegistry;
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ fn parseDeclarations(allocator: *Allocator, root: *xml.Element) ![]registry.Decl
|
|||||||
return allocator.shrink(decls, count);
|
return allocator.shrink(decls, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseTypes(allocator: *Allocator, out: []registry.Declaration, types_elem: *xml.Element) !usize {
|
fn parseTypes(allocator: Allocator, out: []registry.Declaration, types_elem: *xml.Element) !usize {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
var it = types_elem.findChildrenByTag("type");
|
var it = types_elem.findChildrenByTag("type");
|
||||||
while (it.next()) |ty| {
|
while (it.next()) |ty| {
|
||||||
@@ -159,7 +159,7 @@ fn parseHandleType(ty: *xml.Element) !registry.Declaration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration {
|
fn parseBaseType(allocator: Allocator, ty: *xml.Element) !registry.Declaration {
|
||||||
const name = ty.getCharData("name") orelse return error.InvalidRegistry;
|
const name = ty.getCharData("name") orelse return error.InvalidRegistry;
|
||||||
if (ty.getCharData("type")) |_| {
|
if (ty.getCharData("type")) |_| {
|
||||||
var tok = cparse.XmlCTokenizer.init(ty);
|
var tok = cparse.XmlCTokenizer.init(ty);
|
||||||
@@ -174,7 +174,7 @@ fn parseBaseType(allocator: *Allocator, ty: *xml.Element) !registry.Declaration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !registry.Declaration {
|
fn parseContainer(allocator: Allocator, ty: *xml.Element, is_union: bool) !registry.Declaration {
|
||||||
const name = ty.getAttribute("name") orelse return error.InvalidRegistry;
|
const name = ty.getAttribute("name") orelse return error.InvalidRegistry;
|
||||||
|
|
||||||
if (ty.getAttribute("alias")) |alias| {
|
if (ty.getAttribute("alias")) |alias| {
|
||||||
@@ -236,7 +236,7 @@ fn parseContainer(allocator: *Allocator, ty: *xml.Element, is_union: bool) !regi
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseFuncPointer(allocator: *Allocator, ty: *xml.Element) !registry.Declaration {
|
fn parseFuncPointer(allocator: Allocator, ty: *xml.Element) !registry.Declaration {
|
||||||
var xctok = cparse.XmlCTokenizer.init(ty);
|
var xctok = cparse.XmlCTokenizer.init(ty);
|
||||||
return try cparse.parseTypedef(allocator, &xctok);
|
return try cparse.parseTypedef(allocator, &xctok);
|
||||||
}
|
}
|
||||||
@@ -324,7 +324,7 @@ fn parseEnumAlias(elem: *xml.Element) !?registry.Declaration {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseEnums(allocator: *Allocator, out: []registry.Declaration, root: *xml.Element) !usize {
|
fn parseEnums(allocator: Allocator, out: []registry.Declaration, root: *xml.Element) !usize {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
var it = root.findChildrenByTag("enums");
|
var it = root.findChildrenByTag("enums");
|
||||||
while (it.next()) |enums| {
|
while (it.next()) |enums| {
|
||||||
@@ -343,7 +343,7 @@ fn parseEnums(allocator: *Allocator, out: []registry.Declaration, root: *xml.Ele
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseEnumFields(allocator: *Allocator, elem: *xml.Element) !registry.Enum {
|
fn parseEnumFields(allocator: Allocator, elem: *xml.Element) !registry.Enum {
|
||||||
// TODO: `type` was added recently, fall back to checking endswith FlagBits for older versions?
|
// TODO: `type` was added recently, fall back to checking endswith FlagBits for older versions?
|
||||||
const enum_type = elem.getAttribute("type") orelse return error.InvalidRegistry;
|
const enum_type = elem.getAttribute("type") orelse return error.InvalidRegistry;
|
||||||
const is_bitmask = mem.eql(u8, enum_type, "bitmask");
|
const is_bitmask = mem.eql(u8, enum_type, "bitmask");
|
||||||
@@ -410,7 +410,7 @@ fn parseEnumField(field: *xml.Element) !registry.Enum.Field {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseCommands(allocator: *Allocator, out: []registry.Declaration, commands_elem: *xml.Element) !usize {
|
fn parseCommands(allocator: Allocator, out: []registry.Declaration, commands_elem: *xml.Element) !usize {
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
var it = commands_elem.findChildrenByTag("command");
|
var it = commands_elem.findChildrenByTag("command");
|
||||||
while (it.next()) |elem| {
|
while (it.next()) |elem| {
|
||||||
@@ -421,7 +421,7 @@ fn parseCommands(allocator: *Allocator, out: []registry.Declaration, commands_el
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn splitCommaAlloc(allocator: *Allocator, text: []const u8) ![][]const u8 {
|
fn splitCommaAlloc(allocator: Allocator, text: []const u8) ![][]const u8 {
|
||||||
var n_codes: usize = 1;
|
var n_codes: usize = 1;
|
||||||
for (text) |c| {
|
for (text) |c| {
|
||||||
if (c == ',') n_codes += 1;
|
if (c == ',') n_codes += 1;
|
||||||
@@ -436,7 +436,7 @@ fn splitCommaAlloc(allocator: *Allocator, text: []const u8) ![][]const u8 {
|
|||||||
return codes;
|
return codes;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration {
|
fn parseCommand(allocator: Allocator, elem: *xml.Element) !registry.Declaration {
|
||||||
if (elem.getAttribute("alias")) |alias| {
|
if (elem.getAttribute("alias")) |alias| {
|
||||||
const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
|
const name = elem.getAttribute("name") orelse return error.InvalidRegistry;
|
||||||
return registry.Declaration{
|
return registry.Declaration{
|
||||||
@@ -500,7 +500,7 @@ fn parseCommand(allocator: *Allocator, elem: *xml.Element) !registry.Declaration
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseApiConstants(allocator: *Allocator, root: *xml.Element) ![]registry.ApiConstant {
|
fn parseApiConstants(allocator: Allocator, root: *xml.Element) ![]registry.ApiConstant {
|
||||||
var enums = blk: {
|
var enums = blk: {
|
||||||
var it = root.findChildrenByTag("enums");
|
var it = root.findChildrenByTag("enums");
|
||||||
while (it.next()) |child| {
|
while (it.next()) |child| {
|
||||||
@@ -579,7 +579,7 @@ fn parseDefines(types: *xml.Element, out: []registry.ApiConstant) !usize {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseTags(allocator: *Allocator, root: *xml.Element) ![]registry.Tag {
|
fn parseTags(allocator: Allocator, root: *xml.Element) ![]registry.Tag {
|
||||||
var tags_elem = root.findChildByTag("tags") orelse return error.InvalidRegistry;
|
var tags_elem = root.findChildByTag("tags") orelse return error.InvalidRegistry;
|
||||||
const tags = try allocator.alloc(registry.Tag, tags_elem.children.items.len);
|
const tags = try allocator.alloc(registry.Tag, tags_elem.children.items.len);
|
||||||
|
|
||||||
@@ -597,7 +597,7 @@ fn parseTags(allocator: *Allocator, root: *xml.Element) ![]registry.Tag {
|
|||||||
return allocator.shrink(tags, i);
|
return allocator.shrink(tags, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseFeatures(allocator: *Allocator, root: *xml.Element) ![]registry.Feature {
|
fn parseFeatures(allocator: Allocator, root: *xml.Element) ![]registry.Feature {
|
||||||
var it = root.findChildrenByTag("feature");
|
var it = root.findChildrenByTag("feature");
|
||||||
var count: usize = 0;
|
var count: usize = 0;
|
||||||
while (it.next()) |_| count += 1;
|
while (it.next()) |_| count += 1;
|
||||||
@@ -613,7 +613,7 @@ fn parseFeatures(allocator: *Allocator, root: *xml.Element) ![]registry.Feature
|
|||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseFeature(allocator: *Allocator, feature: *xml.Element) !registry.Feature {
|
fn parseFeature(allocator: Allocator, feature: *xml.Element) !registry.Feature {
|
||||||
const name = feature.getAttribute("name") orelse return error.InvalidRegistry;
|
const name = feature.getAttribute("name") orelse return error.InvalidRegistry;
|
||||||
const feature_level = blk: {
|
const feature_level = blk: {
|
||||||
const number = feature.getAttribute("number") orelse return error.InvalidRegistry;
|
const number = feature.getAttribute("number") orelse return error.InvalidRegistry;
|
||||||
@@ -684,7 +684,7 @@ fn enumExtOffsetToValue(extnumber: u31, offset: u31) u31 {
|
|||||||
return extension_value_base + (extnumber - 1) * extension_block + offset;
|
return extension_value_base + (extnumber - 1) * extension_block + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseRequire(allocator: *Allocator, require: *xml.Element, extnumber: ?u31) !registry.Require {
|
fn parseRequire(allocator: Allocator, require: *xml.Element, extnumber: ?u31) !registry.Require {
|
||||||
var n_extends: usize = 0;
|
var n_extends: usize = 0;
|
||||||
var n_types: usize = 0;
|
var n_types: usize = 0;
|
||||||
var n_commands: usize = 0;
|
var n_commands: usize = 0;
|
||||||
@@ -742,7 +742,7 @@ fn parseRequire(allocator: *Allocator, require: *xml.Element, extnumber: ?u31) !
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseExtensions(allocator: *Allocator, root: *xml.Element) ![]registry.Extension {
|
fn parseExtensions(allocator: Allocator, root: *xml.Element) ![]registry.Extension {
|
||||||
const extensions_elem = root.findChildByTag("extensions") orelse return error.InvalidRegistry;
|
const extensions_elem = root.findChildByTag("extensions") orelse return error.InvalidRegistry;
|
||||||
|
|
||||||
const extensions = try allocator.alloc(registry.Extension, extensions_elem.children.items.len);
|
const extensions = try allocator.alloc(registry.Extension, extensions_elem.children.items.len);
|
||||||
@@ -779,7 +779,7 @@ fn findExtVersion(extension: *xml.Element) !u32 {
|
|||||||
return error.InvalidRegistry;
|
return error.InvalidRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseExtension(allocator: *Allocator, extension: *xml.Element) !registry.Extension {
|
fn parseExtension(allocator: Allocator, extension: *xml.Element) !registry.Extension {
|
||||||
const name = extension.getAttribute("name") orelse return error.InvalidRegistry;
|
const name = extension.getAttribute("name") orelse return error.InvalidRegistry;
|
||||||
const platform = extension.getAttribute("platform");
|
const platform = extension.getAttribute("platform");
|
||||||
const version = try findExtVersion(extension);
|
const version = try findExtVersion(extension);
|
||||||
|
|||||||
@@ -179,12 +179,12 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
writer: WriterType,
|
writer: WriterType,
|
||||||
allocator: *Allocator,
|
allocator: Allocator,
|
||||||
registry: *const reg.Registry,
|
registry: *const reg.Registry,
|
||||||
id_renderer: *IdRenderer,
|
id_renderer: *IdRenderer,
|
||||||
declarations_by_name: std.StringHashMap(*const reg.DeclarationType),
|
declarations_by_name: std.StringHashMap(*const reg.DeclarationType),
|
||||||
|
|
||||||
fn init(writer: WriterType, allocator: *Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !Self {
|
fn init(writer: WriterType, allocator: Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !Self {
|
||||||
var declarations_by_name = std.StringHashMap(*const reg.DeclarationType).init(allocator);
|
var declarations_by_name = std.StringHashMap(*const reg.DeclarationType).init(allocator);
|
||||||
errdefer declarations_by_name.deinit();
|
errdefer declarations_by_name.deinit();
|
||||||
|
|
||||||
@@ -1357,7 +1357,7 @@ fn Renderer(comptime WriterType: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(writer: anytype, allocator: *Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !void {
|
pub fn render(writer: anytype, allocator: Allocator, registry: *const reg.Registry, id_renderer: *IdRenderer) !void {
|
||||||
var renderer = try Renderer(@TypeOf(writer)).init(writer, allocator, registry, id_renderer);
|
var renderer = try Renderer(@TypeOf(writer)).init(writer, allocator, registry, id_renderer);
|
||||||
defer renderer.deinit();
|
defer renderer.deinit();
|
||||||
try renderer.render();
|
try renderer.render();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ pub const Element = struct {
|
|||||||
attributes: AttributeList,
|
attributes: AttributeList,
|
||||||
children: ContentList,
|
children: ContentList,
|
||||||
|
|
||||||
fn init(tag: []const u8, alloc: *Allocator) Element {
|
fn init(tag: []const u8, alloc: Allocator) Element {
|
||||||
return .{
|
return .{
|
||||||
.tag = tag,
|
.tag = tag,
|
||||||
.attributes = AttributeList.init(alloc),
|
.attributes = AttributeList.init(alloc),
|
||||||
@@ -314,12 +314,12 @@ pub const ParseError = error{
|
|||||||
OutOfMemory,
|
OutOfMemory,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(backing_allocator: *Allocator, source: []const u8) !Document {
|
pub fn parse(backing_allocator: Allocator, source: []const u8) !Document {
|
||||||
var ctx = ParseContext.init(source);
|
var ctx = ParseContext.init(source);
|
||||||
return try parseDocument(&ctx, backing_allocator);
|
return try parseDocument(&ctx, backing_allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseDocument(ctx: *ParseContext, backing_allocator: *Allocator) !Document {
|
fn parseDocument(ctx: *ParseContext, backing_allocator: Allocator) !Document {
|
||||||
var doc = Document{
|
var doc = Document{
|
||||||
.arena = ArenaAllocator.init(backing_allocator),
|
.arena = ArenaAllocator.init(backing_allocator),
|
||||||
.xml_decl = null,
|
.xml_decl = null,
|
||||||
@@ -328,22 +328,24 @@ fn parseDocument(ctx: *ParseContext, backing_allocator: *Allocator) !Document {
|
|||||||
|
|
||||||
errdefer doc.deinit();
|
errdefer doc.deinit();
|
||||||
|
|
||||||
try trySkipComments(ctx, &doc.arena.allocator);
|
const allocator = doc.arena.allocator();
|
||||||
|
|
||||||
doc.xml_decl = try tryParseProlog(ctx, &doc.arena.allocator);
|
try trySkipComments(ctx, allocator);
|
||||||
_ = ctx.eatWs();
|
|
||||||
try trySkipComments(ctx, &doc.arena.allocator);
|
|
||||||
|
|
||||||
doc.root = (try tryParseElement(ctx, &doc.arena.allocator)) orelse return error.InvalidDocument;
|
doc.xml_decl = try tryParseProlog(ctx, allocator);
|
||||||
_ = ctx.eatWs();
|
_ = ctx.eatWs();
|
||||||
try trySkipComments(ctx, &doc.arena.allocator);
|
try trySkipComments(ctx, allocator);
|
||||||
|
|
||||||
|
doc.root = (try tryParseElement(ctx, allocator)) orelse return error.InvalidDocument;
|
||||||
|
_ = ctx.eatWs();
|
||||||
|
try trySkipComments(ctx, allocator);
|
||||||
|
|
||||||
if (ctx.peek() != null) return error.InvalidDocument;
|
if (ctx.peek() != null) return error.InvalidDocument;
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 {
|
fn parseAttrValue(ctx: *ParseContext, alloc: Allocator) ![]const u8 {
|
||||||
const quote = try ctx.consume();
|
const quote = try ctx.consume();
|
||||||
if (quote != '"' and quote != '\'') return error.UnexpectedCharacter;
|
if (quote != '"' and quote != '\'') return error.UnexpectedCharacter;
|
||||||
|
|
||||||
@@ -359,7 +361,7 @@ fn parseAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 {
|
|||||||
return try dupeAndUnescape(alloc, ctx.source[begin..end]);
|
return try dupeAndUnescape(alloc, ctx.source[begin..end]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseEqAttrValue(ctx: *ParseContext, alloc: *Allocator) ![]const u8 {
|
fn parseEqAttrValue(ctx: *ParseContext, alloc: Allocator) ![]const u8 {
|
||||||
_ = ctx.eatWs();
|
_ = ctx.eatWs();
|
||||||
try ctx.expect('=');
|
try ctx.expect('=');
|
||||||
_ = ctx.eatWs();
|
_ = ctx.eatWs();
|
||||||
@@ -386,7 +388,7 @@ fn parseNameNoDupe(ctx: *ParseContext) ![]const u8 {
|
|||||||
return ctx.source[begin..end];
|
return ctx.source[begin..end];
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tryParseCharData(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
|
fn tryParseCharData(ctx: *ParseContext, alloc: Allocator) !?[]const u8 {
|
||||||
const begin = ctx.offset;
|
const begin = ctx.offset;
|
||||||
|
|
||||||
while (ctx.peek()) |ch| {
|
while (ctx.peek()) |ch| {
|
||||||
@@ -402,7 +404,7 @@ fn tryParseCharData(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
|
|||||||
return try dupeAndUnescape(alloc, ctx.source[begin..end]);
|
return try dupeAndUnescape(alloc, ctx.source[begin..end]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseContent(ctx: *ParseContext, alloc: *Allocator) ParseError!Content {
|
fn parseContent(ctx: *ParseContext, alloc: Allocator) ParseError!Content {
|
||||||
if (try tryParseCharData(ctx, alloc)) |cd| {
|
if (try tryParseCharData(ctx, alloc)) |cd| {
|
||||||
return Content{ .CharData = cd };
|
return Content{ .CharData = cd };
|
||||||
} else if (try tryParseComment(ctx, alloc)) |comment| {
|
} else if (try tryParseComment(ctx, alloc)) |comment| {
|
||||||
@@ -414,7 +416,7 @@ fn parseContent(ctx: *ParseContext, alloc: *Allocator) ParseError!Content {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tryParseAttr(ctx: *ParseContext, alloc: *Allocator) !?*Attribute {
|
fn tryParseAttr(ctx: *ParseContext, alloc: Allocator) !?*Attribute {
|
||||||
const name = parseNameNoDupe(ctx) catch return null;
|
const name = parseNameNoDupe(ctx) catch return null;
|
||||||
_ = ctx.eatWs();
|
_ = ctx.eatWs();
|
||||||
try ctx.expect('=');
|
try ctx.expect('=');
|
||||||
@@ -427,7 +429,7 @@ fn tryParseAttr(ctx: *ParseContext, alloc: *Allocator) !?*Attribute {
|
|||||||
return attr;
|
return attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tryParseElement(ctx: *ParseContext, alloc: *Allocator) !?*Element {
|
fn tryParseElement(ctx: *ParseContext, alloc: Allocator) !?*Element {
|
||||||
const start = ctx.offset;
|
const start = ctx.offset;
|
||||||
if (!ctx.eat('<')) return null;
|
if (!ctx.eat('<')) return null;
|
||||||
const tag = parseNameNoDupe(ctx) catch {
|
const tag = parseNameNoDupe(ctx) catch {
|
||||||
@@ -473,7 +475,7 @@ fn tryParseElement(ctx: *ParseContext, alloc: *Allocator) !?*Element {
|
|||||||
test "tryParseElement" {
|
test "tryParseElement" {
|
||||||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
var alloc = &arena.allocator;
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
{
|
{
|
||||||
var ctx = ParseContext.init("<= a='b'/>");
|
var ctx = ParseContext.init("<= a='b'/>");
|
||||||
@@ -515,7 +517,7 @@ test "tryParseElement" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tryParseProlog(ctx: *ParseContext, alloc: *Allocator) !?*XmlDecl {
|
fn tryParseProlog(ctx: *ParseContext, alloc: Allocator) !?*XmlDecl {
|
||||||
const start = ctx.offset;
|
const start = ctx.offset;
|
||||||
if (!ctx.eatStr("<?") or !mem.eql(u8, try parseNameNoDupe(ctx), "xml")) {
|
if (!ctx.eatStr("<?") or !mem.eql(u8, try parseNameNoDupe(ctx), "xml")) {
|
||||||
ctx.offset = start;
|
ctx.offset = start;
|
||||||
@@ -561,7 +563,7 @@ fn tryParseProlog(ctx: *ParseContext, alloc: *Allocator) !?*XmlDecl {
|
|||||||
test "tryParseProlog" {
|
test "tryParseProlog" {
|
||||||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
var alloc = &arena.allocator;
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
{
|
{
|
||||||
var ctx = ParseContext.init("<?xmla version='aa'?>");
|
var ctx = ParseContext.init("<?xmla version='aa'?>");
|
||||||
@@ -586,13 +588,13 @@ test "tryParseProlog" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trySkipComments(ctx: *ParseContext, alloc: *Allocator) !void {
|
fn trySkipComments(ctx: *ParseContext, alloc: Allocator) !void {
|
||||||
while (try tryParseComment(ctx, alloc)) |_| {
|
while (try tryParseComment(ctx, alloc)) |_| {
|
||||||
_ = ctx.eatWs();
|
_ = ctx.eatWs();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tryParseComment(ctx: *ParseContext, alloc: *Allocator) !?[]const u8 {
|
fn tryParseComment(ctx: *ParseContext, alloc: Allocator) !?[]const u8 {
|
||||||
if (!ctx.eatStr("<!--")) return null;
|
if (!ctx.eatStr("<!--")) return null;
|
||||||
|
|
||||||
const begin = ctx.offset;
|
const begin = ctx.offset;
|
||||||
@@ -622,7 +624,7 @@ fn unescapeEntity(text: []const u8) !u8 {
|
|||||||
return error.InvalidEntity;
|
return error.InvalidEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dupeAndUnescape(alloc: *Allocator, text: []const u8) ![]const u8 {
|
fn dupeAndUnescape(alloc: Allocator, text: []const u8) ![]const u8 {
|
||||||
const str = try alloc.alloc(u8, text.len);
|
const str = try alloc.alloc(u8, text.len);
|
||||||
|
|
||||||
var j: usize = 0;
|
var j: usize = 0;
|
||||||
@@ -644,7 +646,7 @@ fn dupeAndUnescape(alloc: *Allocator, text: []const u8) ![]const u8 {
|
|||||||
test "dupeAndUnescape" {
|
test "dupeAndUnescape" {
|
||||||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
var alloc = &arena.allocator;
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
try testing.expectEqualSlices(u8, "test", try dupeAndUnescape(alloc, "test"));
|
try testing.expectEqualSlices(u8, "test", try dupeAndUnescape(alloc, "test"));
|
||||||
try testing.expectEqualSlices(u8, "a<b&c>d\"e'f<", try dupeAndUnescape(alloc, "a<b&c>d"e'f<"));
|
try testing.expectEqualSlices(u8, "a<b&c>d\"e'f<", try dupeAndUnescape(alloc, "a<b&c>d"e'f<"));
|
||||||
@@ -657,7 +659,7 @@ test "dupeAndUnescape" {
|
|||||||
test "Top level comments" {
|
test "Top level comments" {
|
||||||
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
var arena = std.heap.ArenaAllocator.init(testing.allocator);
|
||||||
defer arena.deinit();
|
defer arena.deinit();
|
||||||
var alloc = &arena.allocator;
|
const alloc = arena.allocator();
|
||||||
|
|
||||||
const doc = try parse(alloc, "<?xml version='aa'?><!--comment--><python color='green'/><!--another comment-->");
|
const doc = try parse(alloc, "<?xml version='aa'?><!--comment--><python color='green'/><!--another comment-->");
|
||||||
try testing.expectEqualSlices(u8, "python", doc.root.tag);
|
try testing.expectEqualSlices(u8, "python", doc.root.tag);
|
||||||
|
|||||||
Reference in New Issue
Block a user