[PATCH hare-wayland] Implement WAYLAND_DEBUG env variable debugging
Export this patch
Signed-off-by: Willow Barraco <contact@willowbarraco.fr>
---
cmd/scanner/main.ha | 14 ++++++
wayland/client/client.ha | 7 +++
wayland/debug.ha | 100 +++++++++++++++++++++++++++++++++++++++
wayland/types.ha | 1 +
4 files changed, 122 insertions(+)
create mode 100644 wayland/debug.ha
diff --git a/cmd/scanner/main.ha b/cmd/scanner/main.ha
index e744148..3c3ba72 100644
--- a/cmd/scanner/main.ha
+++ b/cmd/scanner/main.ha
@@ -167,6 +167,9 @@ def arg_src: str = `
def request_function_src: str = `
export fn $ifname_$name(obj: *$ifname$fnargs) $rettype = {
let buf = memio::dynamic();$inner
+ if (obj.object.client.debug) {
+ wayland::debug_request(obj, "$name"$args);
+ };
match (wayland::queue_request(obj, $opcode, memio::buffer(&buf))) {
case void => void;
case let e: io::error => fmt::fatal("I/O error: {}", io::strerror(e));
@@ -190,6 +193,9 @@ export fn $ifname_$evname_unmarshal(id: wayland::object_id, conn: *wayland::clie
case let l: *$ifname_listener =>
match (l.$evname) {
case let cb: *$ifname_$evname_cb =>
+ if (conn.debug) {
+ wayland::debug_cb(obj, "$evname"$evargs);
+ };
cb(obj.userdata, obj$evargs);
case null =>
yield;
@@ -373,6 +379,8 @@ fn request_function(
let inner = memio::dynamic();
defer io::close(&inner)!;
+ let args = memio::dynamic();
+ defer io::close(&args)!;
if (iface_out != "") {
if (iface_out != "wayland::object") {
@@ -386,15 +394,20 @@ fn request_function(
switch (req.args[i].type_) {
case wayland::scanner::argtype::NEW_ID =>
if (req.args[i].interface == "") {
+ fmt::fprintf(&args, ", iface.name")!;
fmt::fprintf(&inner, "\n\twayland::marshal_str(obj.object.client, &buf, iface.name);")!;
+ fmt::fprintf(&args, ", version")!;
fmt::fprintf(&inner, "\n\twayland::marshal_u32(obj.object.client, &buf, version);")!;
};
+ fmt::fprintf(&args, ", robj: *wayland::new_object")!;
fmt::fprintf(&inner, "\n\twayland::marshal_u32(obj.object.client, &buf, (robj: *wayland::object).id);")!;
case wayland::scanner::argtype::OBJECT =>
+ fmt::fprintf(&args, ", {}_: *wayland::object", req.args[i].name)!;
fmt::fprintf(&inner, "\n\twayland::marshal_u32(obj.object.client, &buf, ({}_: *wayland::object).id);", req.args[i].name)!;
case =>
const argt = argtype_type(req.args[i].type_);
const marshal = argtype_marshal(req.args[i].type_);
+ fmt::fprintf(&args, ", {}_", req.args[i].name)!;
fmt::fprintf(&inner, "\n\twayland::{}(obj.object.client, &buf, {}_);", marshal, req.args[i].name)!;
};
};
@@ -411,6 +424,7 @@ fn request_function(
("opcode", opcode),
("fnargs", memio::string(&fnargs)!),
("inner", memio::string(&inner)!),
+ ("args", memio::string(&args)!),
("rettype", rettype),
("return", ret),
)!;
diff --git a/wayland/client/client.ha b/wayland/client/client.ha
index 5a4a313..bf233d8 100644
--- a/wayland/client/client.ha
+++ b/wayland/client/client.ha
@@ -125,11 +125,18 @@ fn display_error(
};
fn client_new(conn: net::socket) *wayland::client = {
+ const debug = match (os::getenv("WAYLAND_DEBUG")) {
+ case void =>
+ yield false;
+ case let s: str =>
+ yield s == "1";
+ };
return alloc(wayland::client {
conn = conn,
registry = wayland::newregistry(),
msghdr = net::newmsg(),
wbuf = memio::dynamic(),
+ debug = debug,
...
});
};
diff --git a/wayland/debug.ha b/wayland/debug.ha
new file mode 100644
index 0000000..35f3503
--- /dev/null
+++ b/wayland/debug.ha
@@ -0,0 +1,100 @@
+
+use fmt;
+use io;
+use strconv;
+use strings;
+use time;
+
+export type cbargfield = (u32 | i32 | io::file | f64 | str);
+export type new_object = object;
+export type reqargfield = (*object | *new_object | u32 | i32 | f64 | str);
+
+export fn debug_cb(
+ obj: *object,
+ evname: str,
+ args: cbargfield...
+) void = {
+ const now = time::now(time::clock::BOOT);
+ fmt::errorf(
+ "[{}.{:-7}] {}@{}.{}(",
+ now.sec,
+ now.nsec / 100,
+ obj.iface.name,
+ obj.id: u32,
+ evname,
+ )!;
+ for (let i = 0z; i < len(args); i+=1) {
+ if (i > 0) {
+ fmt::errorf(", ")!;
+ };
+ const printable = cb_args_tos(args[i]);
+ defer free(printable);
+ fmt::errorf(printable)!;
+ };
+ fmt::errorfln(")")!;
+};
+
+fn cb_args_tos(arg: cbargfield) str = {
+ match (arg) {
+ case let arg: u32 =>
+ return strings::dup(strconv::u32tos(arg));
+ case let arg: i32 =>
+ return strings::dup(strconv::i32tos(arg));
+ case let arg: io::file =>
+ return strings::dup(strconv::itos(arg));
+ case let arg: f64 =>
+ return strings::dup(strconv::f64tos(arg));
+ case let arg: str =>
+ return fmt::asprintf("\"{}\"", arg);
+ };
+};
+
+export fn debug_request(
+ obj: *object,
+ reqname: str,
+ args: reqargfield...
+) void = {
+ const now = time::now(time::clock::BOOT);
+ fmt::errorf(
+ "[{}.{:-7}] -> {}@{}.{}(",
+ now.sec,
+ now.nsec / 100,
+ obj.iface.name,
+ obj.id: u32,
+ reqname,
+ )!;
+ for (let i = 0z; i < len(args); i+=1) {
+ if (i > 0) {
+ fmt::errorf(", ")!;
+ };
+ const printable = req_arg_tos(args[i]);
+ defer free(printable);
+ fmt::errorf(printable)!;
+ };
+ fmt::errorfln(")")!;
+};
+
+fn req_arg_tos(arg: reqargfield) str = {
+ match (arg) {
+ case let arg: *new_object =>
+ return fmt::asprintf(
+ "new id {}@{}",
+ arg.iface.name,
+ strconv::u32tos(arg.id)
+ );
+ case let arg: *object =>
+ return fmt::asprintf(
+ "{}@{}",
+ arg.iface.name,
+ strconv::u32tos(arg.id)
+ );
+ case let arg: u32 =>
+ return strings::dup(strconv::u32tos(arg));
+ case let arg: i32 =>
+ return strings::dup(strconv::i32tos(arg));
+ case let arg: f64 =>
+ return strings::dup(strconv::f64tos(arg));
+ case let arg: str =>
+ return fmt::asprintf("\"{}\"", arg);
+ };
+};
diff --git a/wayland/types.ha b/wayland/types.ha
index fa91b69..bb502b7 100644
--- a/wayland/types.ha
+++ b/wayland/types.ha
@@ -27,6 +27,7 @@ export type client = struct {
mbuf: []u8,
rbuf: [65536]u8,
wbuf: memio::stream,
+ debug: bool,
};
export type object = struct {
--
2.42.0
Thanks!
To git@git.sr.ht:~sircmpwn/hare-wayland
8458a27..765958c master -> master