Welcome to little lamb

Code » comain » release » tree

[release] / tpl / main.c

#include <fcntl.h> /* AT_FDCWD */
#include <limb/autoopt.h>
#include <limb/exitcode.h>
#include <limb/loadopt.h>
#include <limb/output.h>
#include <limb/stralloc.h>
#include "config.h"

const char *PROG = "$name";

struct ctx {
    stralloc sa;
    size_t fileoff;
};

enum {
    OPTID_VERSION = OPTID_FIRST,
    OPTID_DEBUG,
    /* arguments */
    ARGID_FILE,
};

static void
parse_cmdline(int argc, const char *argv[], int dirfd, const char *confdir, struct ctx *ctx)
{
    const char usage[] = "[-h] [OPTION..] FILE";
    const struct option options[] = {
        OPTION_ARG_OPT(  0 , "debug",                   OPT_SKIP,   OPTID_DEBUG),
        OPTION_ARG_NONE('h', "help",                    OPT_SKIP,   OPTID_SHORTOPT),
        OPTION_ARG_REQ( 'O', "log-file",                0,          OPTID_SHORTOPT),
        OPTION_ARG_NONE('q', "quiet",                   0,          OPTID_SHORTOPT),
        OPTION_ARG_NONE('v', "verbose",                 0,          OPTID_SHORTOPT),
        OPTION_ARG_NONE( 0 , "version",                 OPT_SKIP,   OPTID_VERSION),
        LOADOPT_ARGUMENTS,
        ARGUMENT_REQ( "file",                           OPT_PATH,   ARGID_FILE),
        LOADOPT_DONE
    };
    struct loadopt lo = LOADOPT_ZERO;

    int c;
    while ((c = loadopt(&ctx->sa, argc, argv, options, dirfd, confdir, 0, &lo))) switch (c) {
        case OPTID_DEBUG:
            if (!autoopt_debug(&options[LO_IDX(&lo)], LO_ARG(&lo)))
                dieusage(EX_USAGE, usage);
            break;
        case 'h':
            diehelp(0, usage,
"     --debug [[@[level]:]+FD|FILE]     Enable debug output (to FD|FILE)\n"
" -O, --output [@[level]:]+FD|FILE      Set output log to FD|FILE\n"
"\n"
" -q, --quiet                           Enable quiet mode\n"
" -v, --verbose                         Enable verbose mode\n"
"\n"
" -h, --help                            Show this help screen and exit\n"
"     --version                         Show version information and exit\n"
);
        case 'O':
            if (!autoopt_log(&options[LO_IDX(&lo)], LO_ARG(&lo)))
                dieusage(EX_USAGE, usage);
            break;
        case 'q':
            autoopt_quiet(&options[LO_IDX(&lo)], LO_ARG(&lo));
            break;
        case 'v':
            autoopt_verbose(&options[LO_IDX(&lo)], LO_ARG(&lo));
            break;
        case OPTID_VERSION:
            liladieversion($prefix_VERSION, "$year", $prefix_CURYEAR, $prefix_AUTHOR, $prefix_URL, NULL);

        case ARGID_FILE:
            ctx->fileoff = LO_OFF(&lo);
            break;

        case -1:
            dieusage(EX_USAGE, usage);
        default:
            die(EX_SOFTWARE, "unexpected return value ", PMINT(c), " from loadopt");
    };
}

int
main(int argc, const char *argv[])
{
    struct ctx ctx = { STRALLOC_ZERO, 0 };
    const char confdir[] = "/etc/$name/conf";
    parse_cmdline(argc, argv, AT_FDCWD, confdir, &ctx);

    out("file is ", ESC, ctx.sa.s + ctx.fileoff, ESC);

    stralloc_free(&ctx.sa);
    return 0;
}