opg ftw

Few things about programming (in most languages) are less enjoyable than
writing option parsing code. On the other hand, few things are more irritating
to users than no -h and no options where options are needed (or
underdeveloped option parsers). In few languages is it more painful to do
option parsing than it is in C.

So I did what any sane lunatic would do. I wrote an option parser generator. I think it’s quite nice. This input:

usage: foo [options] other stuff
-f --foo          bool     Short name, long name, type, help text.
-b --bar=name     char*    This has a required string argument.
-z --baz=decibels int?     Optional integer argument
-q --quux=MACH    float    char*, int, and float are the recognized types

Any line not starting with a dash is copied into the help message verbatim.

becomes this output (a header and source file):

/* This file is automatically generated by opg */
#ifndef _OPG_H
#define _OPG_H

struct options {
    int   f; /* foo */
    char* b; /* bar */
    int   z; /* baz */
    float q; /* quux */
};

/* Print usage and exit(1) */
void usage(void);

/* Parse options, populate opts, adjust argc/argv */
void parse_options(int *argc, char * const *argv, struct options *opts);

#endif

/* This file is automatically generated by opg */
#include "opts.h"

...

void usage(void)
{
    puts("usage: foo [options] other stuff");
    puts("  -f  --foo             Short name, long name, type, help text.");
    puts("  -b  --bar=name        This has a required string argument.");
    puts("  -z  --baz[=decibels]  Optional integer argument");
    puts("  -q  --quux=MACH       char*, int, and float are the recognized types");
    puts("");
    puts("Any line not starting with a dash is copied to the help message verbatim.");

    exit(1);
}

void parse_options(int *argc, char * const *argv, struct options *opts)
{
    ...
}

http://hans.fugal.net/src/opg. Enjoy.


Leave a Reply