One thing we decided to do with libguestfs was to take a particular stand on so-called boilerplate code. The rule is that we are only going to write something in one place, and everything possible will be generated from there.
To take a specific example, let’s look at the guestfs_checksum API call. First, this is what I wrote to implement this:
Link #1 – click: Implementation of guestfs_checksum command
The important line is near the bottom, where we describe the function:
("checksum", (RString "checksum", [String "csumtype"; String "path"]), ...
In plain English this says that the command
checksum returns a string which is the checksum result (
RString "checksum"). And it takes two parameters, the string which is the checksum type, and the string which is the path to the file that we want to operate on. (Note that although in this case all the parameters are strings, we support many more complex types).
From just that one line, we will generate:
- C API (header files, implementation etc.)
- RPC code to marshal the parameters into and out of the guestfs daemon
- stubs in the daemon
- shell program
- Perl bindings
- Python bindings
- OCaml bindings
- Ruby bindings
The rest of the description includes tests and documentation, from which we will generate tests (in C) and documentation in multiple formats including the website.
Link #2 – click: Here is the generated code (which we also check into git because we want people to be able to build without running the generator).
Finally, we want the generated code to be readable, so you can trace through it with gdb when there’s an error. So the generated code looks like it was written by hand, including helpful comments in many places.
6 responses to “Generating code”
I read about this technique in the Pragmatic Programmer, and it rocked my world. I show what I’m doing to people and they are like, “Holy shit!”, and I’m like, “I know, right?” Awesome.
Pingback: Contributing a libguestfs enhancement (with examples) « Richard WM Jones
Pingback: Sell, sell! « Richard WM Jones
That violates the “never check generated files into $VCS” rule. I strongly suggest that you do not do this. Please build from source only! Generated .c files are not source.
We don’t do this now.
Pingback: My rant about Haskell | Richard WM Jones