Transforming GObject Introspection data with XSLT

GObject Introspection was always a project that caught my interest. Its a unique solution to an interesting problem – how can we provide frameworks like language bindings and documentation that aren’t just based on static analysis (with little understanding of the runtime framework behind the code) and also doesn’t involve lots of laborious hand-editing which results in out-of-date bindings.

What GObject Introspection is, is effectively a series of tools (g-ir-scannerg-ir-compiler) which generates some semantic data about the static (C-level) and runtime level details of your code if it uses the GObject framework. By combining the two data sets, it can provide structured information about the objects and interfaces defined in a library, their C-function signatures, properties, signals, methods and also finer details like object ownership when passed between function boundaries.

The first output for GIR data is in a structured XML-like format. This means that it is possible to transform that information into something more useful using XSLT. XSLT is a turing-complete functional-template language often used by the web to transform the data contained by XML documents into a more desired format, such as HTML, or as another XML document with restructured data. It can also output plain-text using the data contained in the XML file. This is what is used in a number of places in compiz to generate glue that would otherwise be a pain to do by hand – such as GSettings and GConf schemas as well as the glue .cpp and .h code to directly address and manipulate options.

I’m looking into doing a small project with GIR data (which I will talk about more once its done), and one of the main things is to transform this GIR data. XSLT seemed like a natural way to immediately evaluate the document tree and produce information from it. Since this hasn’t been done before as far as I can tell, here’s some information on how to do it. I am omitting information on how to use g-ir-scanner as that is a different topic in and of itself.

First of all, looking at a sample GObject Introspection file, there are a number of different XML namespaces in use:

<repository version="1.2"
 xmlns="http://www.gtk.org/introspection/core/"
 xmlns:c="http://www.gtk.org/introspection/c/1.0"
 xmlns:glib="http://www.gtk.org/introspection/glib/1.0">

We need to ensure that those are defined in our XSLT file like so:

<xsl:stylesheet version="1.0"
xmlns:gi="http://www.gtk.org/introspection/core/1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:c="http://www.gtk.org/introspection/c/1.0"
xmlns:glib="http://www.gtk.org/introspection/glib/1.0">

The line

xmlns:gi="http://www.gtk.org/introspection/core/1.0"

is really important, because GIR sits in the http://gtk.org/introspection/core/1.0 namespace (as indicated by):

xmlns="http://www.gtk.org/introspection/core/1.0"

That one is easy to miss, and will cause the template match on /repository to silently fail if not defined somewhere.

Now we can start matching stuff:

<!-- This file is released under the terms of the GPL v3 licence -->
<xsl:stylesheet version="1.0"
<xsl:stylesheet version="1.0"
                xmlns:gi="http://www.gtk.org/introspection/core/1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:c="http://www.gtk.org/introspection/c/1.0"
                xmlns:glib="http://www.gtk.org/introspection/glib/1.0">

    <xsl:output method="text"/>

    <xsl:template name="processArgument">
        <xsl:text> parameter type: </xsl:text><xsl:value-of select="gi:type/@c:type"/>
        <xsl:value-of select="$newline"/>
        <xsl:text> parameter name: </xsl:text><xsl:value-of select="@name"/>
        <xsl:value-of select="$newline"/>
    </xsl:template>

    <xsl:template name="processVirtualMethod">
        <xsl:text>Found virtual method: </xsl:text><xsl:value-of select="@name"/>
        <xsl:value-of select="$newline"/>
        <xsl:text> returns: </xsl:text><xsl:value-of select="gi:return-value/gi:type/@c:type"/>
        <xsl:value-of select="$newline"/>
        <xsl:for-each select="gi:parameters/gi:parameter">
            <xsl:call-template name="processArgument"/>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="processInterface">
        <xsl:text>Found interface: </xsl:text><xsl:value-of select="@name"/>
        <xsl:value-of select="$newline"/>
        <xsl:for-each select="gi:virtual-method">
            <xsl:call-template name="processVirtualMethod"/>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="processNamespace">
        <xsl:text>Found namespace: </xsl:text><xsl:value-of select="@name"/>
        <xsl:value-of select="$newline"/>
        <xsl:for-each select="gi:interface">
            <xsl:call-template name="processInterface"/>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="/gi:repository">
        <xsl:for-each select="gi:namespace">
            <xsl:call-template name="processNamespace"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

That sample stylesheet will match every namespace, every interface within that namespace and every virtual function that interface provides and provide some data on it.
Perhaps it will be of some use?

About these ads

3 thoughts on “Transforming GObject Introspection data with XSLT

  1. I know it is considered rude to post comments under articles that have nothing to do with the article itself, but there is something I want you to know and this is probably the easiest way to reach you. I promise I will try to avoid this reply’s in future.

    There are a few high priority bugs in terms of usability (imho) in compiz, that really interfere with effective working and annoy power users. I know you just posted about the Introduction of PolySquare and I can understand that a highly skilled developer wants to do more exciting things, but if you find yourself in the mood of bug fixing these bugs would be really important to make Ubuntu 13.04 a quality product:

    https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/1115341

    https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/1115343

    https://bugs.launchpad.net/compiz/+bug/1115344

    https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/1115350

    https://bugs.launchpad.net/compiz/+bug/1082001

    https://bugs.launchpad.net/compiz/+bug/1115351

    https://bugs.launchpad.net/ubuntu/+source/compiz/+bug/1115353

    https://bugs.launchpad.net/unity/+bug/1104236

    and of course the problem with minimizing (729979): I have sucessfully compiled and installed your compiz and unity branch. If I login I only get to see the wallpaper, so I changed to a virtual terminal and typed:
    env DISPLAY=:0 –replace composite opengl move resize decor compiztoolbox mousepoll wall expo animation switcher unityshell
    After that Launcher, panel and dash are there and work as expected, but I cannot snap windows, workspaces are all in a row and the minimize animation is not the unity one (I get the mac -like effect, which works perfect). How to set everything to default?
    I noticed that activating all the plugins as in default compiz in ccsm does not work.

    I am working very intense on my programming skills and I have already checked out the source (for the grid bugs) but my knowledge of compiz is too little to fix one of this bugs at the moment.

    Thank you very much!

    1. As you mentioned, blog posts really aren’t the best place to get a hold of me. You’ll have better success if you ping me on IRC or send me an email. Thanks for filing those reports, I’ll look at them soon enough.

      When you compile compiz from source you’ll get the upstream compiz settings and not the ubuntu settings, because we don’t apply any ubuntu patches to it. “snap windows” is provided by the grid plugin. If you want to activate plugins in CCSM, you will need to run compiz with : compiz –replace ccp &

    2. A further note: if you have lots of links on your comment, they get caught in the spam filter.

      Better to just email me.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s