Steps
Write a file called USAGE using the docopt standard. Example:
pearldb - a key value server
Usage:
pearldb [--daemonize]
pearldb --version
pearldb --help
Options:
-d --daemonize Run as a daemon.
-v --version Display version.
-h --help Prints a short usage summary.
Get docopt2ragel
pip install docopt2ragel
Install Ragel
brew install ragel
Compile the USAGE file into a Ragel state machine:
docopt2ragel USAGE > usage.rl
Compile the Ragel state machine into a C source file
ragel usage.rl
Include the C source file into your project:
#include "usage.c"
int main(int argc, char **argv)
{
int e, i;
options_t opts;
e = parse_options(argc, argv, &opts);
if (-1 == e)
exit(-1);
else if (opts.help)
{
show_usage();
exit(0);
}
else if (opts.version)
{
fprintf(stdout, "%s\n", VERSION);
exit(0);
}
}
What’s going on?
docopt2ragel parses the Docopt usage string using Docopt. The output of this is a Ragel state machine which defines the grammar of our argument parser. Ragel takes this state machine and generates the C code we need. We include the generated C code into our project.Notes
- This uses an alternative method from the official implementation.
- The option parsing code that Ragel generates is robust
- Docopt is an elegant way of documenting and defining your project’s command line interface
- It would be great if Ragel could accept it’s input on STDIN
- docopt2ragel as of writing supports the majority of the docopt standard
- For a real life example see https://github.com/willemt/pearldb