X_getopt() – processes long options.
#include <basis/options.h>
struct x_option {
    int  optval;
    char flag;
    char *name;
    char *has_argument;
    char *description;
};
int x_getopt(int argc, char **argv, int optcount, struct x_option *opts);
extern char *x_optarg;
extern int x_optind, x_opterr, x_optopt;
The x_getopt() function returns the next option in argv
that matches an option in opts.  The opts argument is an
array of option definitions containing the following fields:
optvalx_getopt() returns to the program.flagnamehas_argumentsdescriptionThe x_getopt() function places the argv index of the next
argument to be processed into the x_optind variable.  x_optind
is external and is initialized to 1 every time you call
x_getopt() with a different argc/argv pair.  When all options
have been processed, x_getopt() returns EOF.  The special
option “--” is used to tell x_getopt() that no further
options are to be found in argv.  This is useful for delimiting
non-option arguments that begin with a “-”.
When x_getopt() encounters an option not listed in opts, it returns
NULL.  In addition, if the x_opterr variable is nonzero, it also
prints an error message to stderr.
#include <stdio.h>
#include <basis/options.h>
struct x_option options[] = {
    { 'a', 'a', "opta",        0, "Option A" },
    { 'b', 'b', "optb",        0, "Option B" },
    { 'o', 'o', "output", "FILE", "Write output to FILE" },
    { 'h', 0  , "help",        0, "Print this help message" },
};
#define NROPTS (sizeof options/sizeof options[0])
main(int argc, char **argv)
{
    int c;
    int aflag = 0,
        bflag = 0;
    char *output = "-";
    while ( (c = x_getopt(argc, argv, NROPTS, options)) != EOF) {
        switch (c) {
        case 'a':
            aflag++;
            break;
        case 'b':
            bflag++;
            break;
        case 'f':
            output = x_optarg;
            break;
        case 0:
        case 'h':
            fprintf(stderr, "usage: program [-ab] [-o file] ...\n");
            exit(  (c == 'h') ? 0 : 1 );
        }
    }
    for ( ; x_optind < argc; x_optind++)
        printf("%d: %s\n", x_optind, argv[x_optind]);
}
I put the header file
in /usr/include/basis, to avoid collisions
with the seventy or so other options.h files out there.
I usually just build options.c as part
of the objects list of the programs I build it with, but I’ve
also built it into the libraries liboptions.a and libc.a