Add recursive ref all decls test, fix errors

Breaking change: Object.interface() renamed to Object.getInterface() for
consistency and to avoid shadowing.

Note: this test doesn't function properly with zig 0.7.0, this issue has
been fixed in https://github.com/ziglang/zig/pull/7178
This commit is contained in:
Isaac Freund
2020-11-20 20:23:56 +01:00
parent 181f9344b2
commit 61e3a8d54e
7 changed files with 123 additions and 67 deletions
+14
View File
@@ -28,6 +28,20 @@ pub fn build(b: *zbs.Builder) void {
test_step.dependOn(&t.step);
}
{
const ref_all = b.addTest("src/ref_all.zig");
ref_all.setTarget(target);
ref_all.setBuildMode(mode);
ref_all.step.dependOn(&scanner.step);
ref_all.addPackage(scanner.getPkg());
scanner.addCSource(ref_all);
ref_all.linkLibC();
ref_all.linkSystemLibrary("wayland-client");
ref_all.linkSystemLibrary("wayland-server");
test_step.dependOn(&ref_all.step);
}
}
pub const ScanProtocolsStep = struct {
+1 -1
View File
@@ -15,7 +15,7 @@ pub fn main() !void {
fn listener(registry: *wl.Registry, event: wl.Registry.Event, running: *bool) void {
switch (event) {
.global => |global| {
if (std.cstr.cmp(global.interface, wl.Seat.interface().name) == 0) {
if (std.cstr.cmp(global.interface, wl.Seat.getInterface().name) == 0) {
const seat = registry.bind(global.name, wl.Seat, 1) catch return;
seat.setListener(*bool, seatListener, running) catch return;
}
+2 -2
View File
@@ -119,7 +119,7 @@ pub fn roundtripQueue(display: *Display, queue: *client.wl.EventQueue) !u32 {
extern fn wl_display_flush(display: *Display) c_int;
pub fn flush(display: *Display) error{WouldBlock}!u32 {
const rc = wl_display_dispatch_queue_pending(display, queue);
const rc = wl_display_flush(display);
return switch (os.errno(rc)) {
0 => @intCast(u32, rc),
os.EAGAIN => error.WouldBlock,
@@ -127,7 +127,7 @@ pub fn flush(display: *Display) error{WouldBlock}!u32 {
};
}
extern fn wl_display_create_queue(display: *Display) *client.wl.EventQueue;
extern fn wl_display_create_queue(display: *Display) ?*client.wl.EventQueue;
pub fn createQueue(display: *Display) error{OutOfMemory}!*client.wl.EventQueue {
return wl_display_create_queue(display) orelse error.OutOfMemory;
}
+21
View File
@@ -0,0 +1,21 @@
// Note: this requires the fix made in https://github.com/ziglang/zig/pull/7178
// to work properly with zig-wayland's use of usingnamespace
fn refAllDeclsRecursive(comptime T: type) void {
const decls = switch (@typeInfo(T)) {
.Struct => |info| info.decls,
.Union => |info| info.decls,
.Enum => |info| info.decls,
.Opaque => |info| info.decls,
else => return,
};
inline for (decls) |decl| {
switch (decl.data) {
.Type => |T2| refAllDeclsRecursive(T2),
else => _ = decl,
}
}
}
test "" {
refAllDeclsRecursive(@import("wayland"));
}
+50 -31
View File
@@ -253,7 +253,7 @@ const Interface = struct {
try writer.print(
\\pub const {} = opaque {{
\\ pub const interface = common.{}.{}.interface;
\\ pub const getInterface = common.{}.{}.getInterface;
, .{ title_case, namespace, snake_case });
for (interface.enums.items) |e| {
@@ -294,12 +294,30 @@ const Interface = struct {
\\}}
, .{ title_case, title_case, title_case });
for ([_][]const u8{ "destroy", "getId", "fromLink", "getLink", "getClient", "getVersion" }) |func|
try writer.print(
\\pub fn destroy({}: *{}) void {{
\\ return @ptrCast(*server.wl.Resource, {}).destroy();
\\}}
, .{ snake_case, title_case, snake_case });
try writer.print(
\\pub fn fromLink(link: *server.wl.list.Link) *{} {{
\\ return @ptrCast(*{}, server.wl.Resource.fromLink(link));
\\}}
, .{ title_case, title_case });
for ([_][2][]const u8{
.{ "getLink", "*server.wl.list.Link" },
.{ "getClient", "*server.wl.Client" },
.{ "getId", "u32" },
.{ "getVersion", "u32" },
}) |func|
try writer.print(
\\pub fn {}({}: *{}) void {{
\\ @ptrCast(*server.wl.Resource, {}).{}();
\\pub fn {}({}: *{}) {} {{
\\ return @ptrCast(*server.wl.Resource, {}).{}();
\\}}
, .{ func, snake_case, title_case, snake_case, func });
, .{ func[0], snake_case, title_case, func[1], snake_case, func[0] });
if (interface.requests.items.len > 0) {
try writer.writeAll("pub const Request = union(enum) {");
for (interface.requests.items) |request| try request.emitField(.server, writer);
@@ -400,7 +418,7 @@ const Interface = struct {
try writer.print(
\\ = struct {{
\\ extern const {}_interface: common.Interface;
\\ pub inline fn interface() *const common.Interface {{
\\ pub inline fn getInterface() *const common.Interface {{
\\ return &{}_interface;
\\ }}
, .{ interface.name, interface.name });
@@ -465,34 +483,35 @@ const Message = struct {
return error.UnexpectedEndOfFile;
}
fn emitMessage(message: Message, writer: anytype) !void {
try writer.print(".{{ .name = \"{}\", .signature = \"", .{message.name});
for (message.args.items) |arg| try arg.emitSignature(writer);
try writer.writeAll("\", .types = ");
if (message.args.items.len > 0) {
try writer.writeAll("&[_]?*const common.Interface{");
for (message.args.items) |arg| {
switch (arg.kind) {
.object, .new_id => |interface| if (interface) |i|
try writer.print("&common.{}.{}.interface,", .{ prefix(i), trimPrefix(i) })
else
try writer.writeAll("null,"),
else => try writer.writeAll("null,"),
}
}
try writer.writeAll("},");
} else {
try writer.writeAll("null,");
}
try writer.writeAll("},");
}
// TODO: restore this code when zig issue #131 is resoleved
//fn emitMessage(message: Message, writer: anytype) !void {
// try writer.print(".{{ .name = \"{}\", .signature = \"", .{message.name});
// for (message.args.items) |arg| try arg.emitSignature(writer);
// try writer.writeAll("\", .types = ");
// if (message.args.items.len > 0) {
// try writer.writeAll("&[_]?*const common.Interface{");
// for (message.args.items) |arg| {
// switch (arg.kind) {
// .object, .new_id => |interface| if (interface) |i|
// try writer.print("&common.{}.{}.interface,", .{ prefix(i), trimPrefix(i) })
// else
// try writer.writeAll("null,"),
// else => try writer.writeAll("null,"),
// }
// }
// try writer.writeAll("},");
// } else {
// try writer.writeAll("null,");
// }
// try writer.writeAll("},");
//}
fn emitField(message: Message, side: Side, writer: anytype) !void {
try printIdentifier(writer, message.name);
try writer.writeAll(": struct {");
for (message.args.items) |arg| {
if (side == .server and arg.kind == .new_id and arg.kind.new_id == null) {
try writer.writeAll("interface: [*:0]const u8, version: u32,");
try writer.writeAll("interface_name: [*:0]const u8, version: u32,");
try printIdentifier(writer, arg.name);
try writer.writeAll(": u32");
} else if (side == .client and arg.kind == .new_id) {
@@ -601,7 +620,7 @@ const Message = struct {
} else {
if (new_iface == null) {
try writer.writeAll(
\\.{ .s = T.interface().name },
\\.{ .s = T.getInterface().name },
\\.{ .u = version },
);
}
@@ -626,9 +645,9 @@ const Message = struct {
try printIdentifier(writer, case(.title, trimPrefix(i)));
try writer.print(", try proxy.marshalConstructor({}, &args, ", .{opcode});
try printIdentifier(writer, case(.title, trimPrefix(i)));
try writer.writeAll(".interface()));");
try writer.writeAll(".getInterface()));");
} else {
try writer.print("return @ptrCast(*T, try proxy.marshalConstructorVersioned({}, &args, T.interface(), version));", .{opcode});
try writer.print("return @ptrCast(*T, try proxy.marshalConstructorVersioned({}, &args, T.getInterface(), version));", .{opcode});
}
},
}
+2 -2
View File
@@ -7,9 +7,9 @@ pub const Fixed = common.Fixed;
pub const Argument = common.Argument;
pub const Proxy = opaque {
extern fn wl_proxy_create(factory: *Proxy, interface: *const Interface) *Proxy;
extern fn wl_proxy_create(factory: *Proxy, interface: *const Interface) ?*Proxy;
pub fn create(factory: *Proxy, interface: *const Interface) error{OutOfMemory}!*Proxy {
return wl_proxy_create(factory.impl, interface) orelse error.OutOfMemory;
return wl_proxy_create(factory, interface) orelse error.OutOfMemory;
}
extern fn wl_proxy_destroy(proxy: *Proxy) void;
+33 -31
View File
@@ -76,12 +76,13 @@ pub const Server = opaque {
extern fn wl_display_add_client_created_listener(server: *Server, listener: *Listener(*Client)) void;
pub const addClientCreatedListener = wl_display_add_client_created_listener;
extern fn wl_display_get_destroy_listener(server: *Server, notify: @TypeOf(Listener(*Server).notify)) ?*Listener(*Server);
pub const getDestroyListener = wl_display_get_destroy_listener;
// Doesn't really make sense with our Listener API as we would need to
// pass a pointer to the wrapper function
//extern fn wl_display_get_destroy_listener(server: *Server, notify: @TypeOf(Listener(*Server).notify)) ?*Listener(*Server);
extern fn wl_display_set_global_filter(
server: *Server,
filter: fn (client: *const Client, global: *const Global, data: ?*c_void) bool,
filter: fn (client: *const Client, global: *const Global, data: ?*c_void) callconv(.C) bool,
data: ?*c_void,
) void;
pub fn setGlobalFilter(
@@ -98,24 +99,23 @@ pub const Server = opaque {
extern fn wl_display_init_shm(server: *Server) c_int;
pub fn initShm(server: *Server) !void {
if (wl_display_init_shm(display) == -1)
return error.GlobalCreateFailed;
if (wl_display_init_shm(server) == -1) return error.OutOfMemory;
}
extern fn wl_display_add_shm_format(server: *Server, format: u32) ?*u32;
pub fn addShmFormat(server: *Server, format: u32) !*u32 {
return wl_display_add_shm_format(display, format) orelse error.OutOfMemory;
return wl_display_add_shm_format(server, format) orelse error.OutOfMemory;
}
extern fn wl_display_add_protocol_logger(
server: *Server,
func: fn (data: ?*c_void, direction: ProtocolLogger.Type, message: *const ProtocolLogger.Message) void,
func: fn (data: ?*c_void, direction: ProtocolLogger.Type, message: *const ProtocolLogger.LogMessage) callconv(.C) void,
data: ?*c_void,
) void;
pub fn addProtocolLogger(
server: *Server,
comptime T: type,
func: fn (data: T, direction: ProtocolLogger.Type, message: *const ProtocolLogger.Message) callconv(.C) void,
func: fn (data: T, direction: ProtocolLogger.Type, message: *const ProtocolLogger.LogMessage) callconv(.C) void,
data: T,
) void {
wl_display_add_protocol_logger(display, func, data);
@@ -153,8 +153,9 @@ pub const Client = opaque {
extern fn wl_client_add_destroy_listener(client: *Client, listener: *Listener(*Client)) void;
pub const addDestroyListener = wl_client_add_destroy_listener;
extern fn wl_client_get_destroy_listener(client: *Client, notify: @TypeOf(Listener(*Client).notify)) ?*Listener(*Client);
pub const getDestroyListener = wl_client_get_destroy_listener;
// Doesn't really make sense with our Listener API as we would need to
// pass a pointer to the wrapper function
//extern fn wl_client_get_destroy_listener(client: *Client, notify: @TypeOf(Listener(*Client).notify)) ?*Listener(*Client);
extern fn wl_client_get_object(client: *Client, id: u32) ?*Resource;
pub const getObject = wl_client_get_object;
@@ -171,7 +172,7 @@ pub const Client = opaque {
const IteratorResult = extern enum { stop, cont };
extern fn wl_client_for_each_resource(
client: *Client,
iterator: fn (resource: *Resource, data: ?*c_void) IteratorResult,
iterator: fn (resource: *Resource, data: ?*c_void) callconv(.C) IteratorResult,
data: ?*c_void,
) void;
pub fn forEachResource(
@@ -206,7 +207,7 @@ pub const Global = opaque {
data: T,
bind: fn (client: *Client, data: T, version: u32, id: u32) callconv(.C) void,
) !*Global {
return wl_global_create(display, Object.interface, version, data, bind) orelse
return wl_global_create(display, Object.getInterface(), version, data, bind) orelse
error.GlobalCreateFailed;
}
@@ -228,19 +229,19 @@ pub const Global = opaque {
pub const Resource = opaque {
extern fn wl_resource_create(client: *Client, interface: *const Interface, version: c_int, id: u32) ?*Resource;
pub fn create(client: *Client, comptime Object: type, version: u32, id: u32) !*Resource {
pub fn create(client: *Client, comptime T: type, version: u32, id: u32) !*Resource {
// This is only a c_int because of legacy libwayland reasons. Negative versions are invalid.
// Version is a u32 on the wire and for wl_global, wl_proxy, etc.
return wl_resource_create(client, Object.interface, @intCast(c_int, version), id) orelse error.ResourceCreateFailed;
return wl_resource_create(client, T.getInterface(), @intCast(c_int, version), id) orelse error.ResourceCreateFailed;
}
extern fn wl_resource_destroy(resource: *Resource) void;
pub const destroy = wl_resource_destroy;
extern fn wl_resource_post_event_array(resource: *Resource, opcode: u32, args: [*]Argument) void;
extern fn wl_resource_post_event_array(resource: *Resource, opcode: u32, args: ?[*]Argument) void;
pub const postEvent = wl_resource_post_event_array;
extern fn wl_resource_queue_event_array(resource: *Resource, opcode: u32, args: [*]Argument) void;
extern fn wl_resource_queue_event_array(resource: *Resource, opcode: u32, args: ?[*]Argument) void;
pub const queueEvent = wl_resource_queue_event_array;
extern fn wl_resource_post_error(resource: *Resource, code: u32, message: [*:0]const u8, ...) void;
@@ -262,14 +263,14 @@ pub const Resource = opaque {
dispatcher: ?DispatcherFn,
implementation: ?*const c_void,
data: ?*c_void,
destroy: ?DestroyFn,
destroy_fn: ?DestroyFn,
) void;
pub fn setDispatcher(
resource: *Resource,
dispatcher: ?DispatcherFn,
implementation: ?*const c_void,
data: ?*c_void,
destroy: ?DestroyFn,
destroy_fn: ?DestroyFn,
) void {
wl_resource_set_dispatcher(resource, dispatcher, implementation, data, destroy);
}
@@ -312,8 +313,9 @@ pub const Resource = opaque {
extern fn wl_resource_add_destroy_listener(resource: *Resource, listener: *Listener(*Resource)) void;
pub const addDestroyListener = wl_resource_add_destroy_listener;
extern fn wl_resource_get_destroy_listener(resource: *Resource, notify: @TypeOf(Listener(*Resource).notify)) ?*Listener(*Resource);
pub const getDestroyListener = wl_resource_get_destroy_listener;
// Doesn't really make sense with our Listener API as we would need to
// pass a pointer to the wrapper function
//extern fn wl_resource_get_destroy_listener(resource: *Resource, notify: @TypeOf(Listener(*Resource).notify)) ?*Listener(*Resource);
};
pub const ProtocolLogger = opaque {
@@ -322,7 +324,7 @@ pub const ProtocolLogger = opaque {
event,
};
pub const Message = extern struct {
pub const LogMessage = extern struct {
resource: *Resource,
message_opcode: c_int,
message: *Message,
@@ -512,7 +514,7 @@ pub fn Signal(comptime T: type) type {
pub const EventLoop = opaque {
extern fn wl_event_loop_create() ?*EventLoop;
pub fn create() *EventLoop {
pub fn create() !*EventLoop {
return wl_event_loop_create() orelse error.EventLoopCreateFailed;
}
@@ -523,7 +525,7 @@ pub const EventLoop = opaque {
loop: *EventLoop,
fd: os.fd_t,
mask: u32,
func: fn (fd: os.fd_t, mask: u32, data: ?*c_void) c_int,
func: fn (fd: os.fd_t, mask: u32, data: ?*c_void) callconv(.C) c_int,
data: ?*c_void,
) ?*EventSource;
pub fn addFd(
@@ -539,7 +541,7 @@ pub const EventLoop = opaque {
extern fn wl_event_loop_add_timer(
loop: *EventLoop,
func: fn (data: ?*c_void) c_int,
func: fn (data: ?*c_void) callconv(.C) c_int,
data: ?*c_void,
) ?*EventSource;
pub fn addTimer(
@@ -554,7 +556,7 @@ pub const EventLoop = opaque {
extern fn wl_event_loop_add_signal(
loop: *EventLoop,
signal_number: c_int,
func: fn (c_int, ?*c_void) c_int,
func: fn (c_int, ?*c_void) callconv(.C) c_int,
data: ?*c_void,
) ?*EventSource;
pub fn addSignal(
@@ -569,7 +571,7 @@ pub const EventLoop = opaque {
extern fn wl_event_loop_add_idle(
loop: *EventLoop,
func: fn (data: ?*c_void) c_int,
func: fn (data: ?*c_void) callconv(.C) c_int,
data: ?*c_void,
) ?*EventSource;
pub fn addIdle(
@@ -587,7 +589,7 @@ pub const EventLoop = opaque {
switch (os.errno(rc)) {
0 => return,
// TODO
else => |err| os.unexpectedErrno(err),
else => |err| return os.unexpectedErrno(err),
}
}
@@ -600,8 +602,8 @@ pub const EventLoop = opaque {
extern fn wl_event_loop_add_destroy_listener(loop: *EventLoop, listener: *Listener(*EventLoop)) void;
pub const addDestroyListener = wl_event_loop_add_destroy_listener;
extern fn wl_event_loop_get_destroy_listener(loop: *EventLoop, notify: @TypeOf(Listener(*EventLoop).notify)) ?*Listener;
pub const getDestroyListener = wl_event_loop_get_destroy_listener;
//extern fn wl_event_loop_get_destroy_listener(loop: *EventLoop, notify: @TypeOf(Listener(*EventLoop).notify)) ?*Listener;
//pub const getDestroyListener = wl_event_loop_get_destroy_listener;
};
pub const EventSource = opaque {
@@ -619,7 +621,7 @@ pub const EventSource = opaque {
switch (os.errno(rc)) {
0 => return,
// TODO
else => |err| os.unexpectedErrno(err),
else => |err| return os.unexpectedErrno(err),
}
}
@@ -629,7 +631,7 @@ pub const EventSource = opaque {
switch (os.errno(rc)) {
0 => return,
// TODO
else => |err| os.unexpectedErrno(err),
else => |err| return os.unexpectedErrno(err),
}
}
};