[Xcb] Using Coccinelle to automatically transform Xlib-based code to use XCB

Josh Triplett josh at joshtriplett.org
Sun Jun 13 15:08:54 PDT 2010


[CCing the Coccinelle list for interest.]

I've done some experiments with transforming Xlib-based code to use XCB
by using Coccinelle, the "semantic patch" tool.

I've managed to successfully handle common usage of XOpenDisplay,
XCloseDisplay, and the error-handling around them.  I can also
automatically transform Display * variables into xcb_connection_t *
variables, and transform functions that pass around a Display * to pass
around an xcb_connection_t * instead.

Note that these transformations target applications based on Xlib, using
the assumption that no function signatures have a fixed API.
Transforming library code would require a different set of
transformations, using XGetXCBConnection.  I can do that kind of
transformation too, though, making an arbitrary function that takes a
dpy argument define an xcb_connection_t *conn at the top and set it
equal to XGetXCBConnection(dpy).

I've attached my work-in-progress Coccinelle patch.  You can use it like
this:

spatch -sp_file xcb.cocci xlib-app.c

Actually transforming requests and (in particular) responses will
require more work to figure out the right equivalences, and these
sometimes involve several different cases, particularly to make
efficient translations (avoiding extra data copies, for instance).
However, if we can come up with the right general rules to apply, we can
probably express those rules in Coccinelle.

- Josh Triplett
-------------- next part --------------
@@
identifier dpy;
@@
(
-static Display *dpy;
+static xcb_connection_t *conn;
|
-Display *dpy = NULL;
+xcb_connection_t *conn = NULL;
|
-Display *dpy;
+xcb_connection_t *conn;
)

@localfunc@
identifier dpy;
identifier f;
@@
 f(...,
-Display *dpy
+xcb_connection_t *conn
 ,...) { ... }

@@
identifier localfunc.f;
Display *dpy;
@@
 f(...,
-dpy
+conn
 ,...)

@@
Display *dpy;
identifier displayname;
identifier screen;
@@
(
-dpy = XOpenDisplay(displayname);
+conn = xcb_connect(displayname, &screen);
... when != screen
-screen = DefaultScreen(dpy);
|
-dpy = XOpenDisplay(displayname);
+conn = xcb_connect(displayname, NULL);
)

@@
identifier displayname;
@@
(
-XDisplayName(NULL)
+getenv("DISPLAY")
|
-XDisplayName(displayname)
+displayname ? displayname : getenv("DISPLAY")
)

@@
Display *dpy;
@@
(
-if (dpy) { XCloseDisplay(dpy); }
+if (conn) xcb_disconnect(conn);
|
 if (
-    !dpy
+    xcb_connection_has_error(conn)
    ) { ... }
)


More information about the Xcb mailing list