Skip to content

fugalh/opg

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

opg - option parser generator for C

Synopsis
--------
Input looks like this:

   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.

Output is a C 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)
    {
        ...
    }

Requirements
------------
opg is written in Ruby. The generated parser is ANSI C using getopt_long().

Details
-------
Input fields are split by whitespace. Recognized types are bool, char*, int,
float.  Parameter names are included in help text. A question mark after the
type indicates an optional argument. Any line not starting with a dash is
copied to the help message verbatim.

Here is a simple example main():

    #include "opts.h"
    #include <stdio.h>
    
    int main(int argc, char *const *argv)
    {
        struct options opts = {};
        parse_options(&argc, &argv, &opts);

        printf("f %d\nb %s\nz %d\nq %f\n", opts.f, opts.b, opts.z, opts.q);

        /* argc has been decremented and argv rearranged.
           Do things with the rest of the arguments. */
    }

Help (-h, --help) is automatic and reserved, but if you want it displayed in
the help message you need to put it there yourself.

Author
------
Hans Fugal <hans@fugal.net>
Patches welcome.

The generator is GPLv2, the generated code is your own to license as you
wish (within the requirements of your getopt_long() license, etc.).