Rather than developing another ugly little language to save and restore calculator state in Nonpareil, I decided that I’d try using xml, via the libxml2 library, which I’ve never used before. The last time I wrote any software to do anything with XML was six years ago, when I hand-coded routines to emit and parse XML. That was a pain. I was pleased to discover that libxml2 provides fairly clean, easy-to-use APIs. For parsing, you can either let it build an entire parse tree in memory (DOM style), or give it callback functions to invoke as it reads the various XML elements, attributes, entities, and user data (SAX style). For Nonpareil, SAX is clearly the right thing.
For writing XML files, the simplest API provided by libxml2 is xmlTextWriter. This particular API appears to only be suited to single-threaded use, but that’s fine for Nonpareil. (Nonpareil has multiple threads, but only one will ever be reading or writing a particular XML file at any given time.)
It’s also nice that there is support for doing gzip compression and decompression on the fly.
It only took me three hours to come up with a suitable DTD, study the libxml2 documentation and write and debug a mockup consisting of one program that writes a Nonpareil save state file and one that parses it.
In fact, this worked so well that I’m considering replacing the use of (modified) KML files for configuring Nonpareil with another XML file. In this case, I’d probably want the XML file to come out of a ZIP file, so I’d have to write a little bit of glue to get the libxml2 parser to read from a gsfInput stream.