4. Argument Parsing

Based on constructs found in worgmap, a project found in worgle.

4.1. Argparse entry table

Every subcommand is stored inside of a table. This gets dynamically populated with Worgle via a code block called orgparse_entries.

<<argparse>>=
typedef struct {
    const char *name;
    int len;
    int (*fun)(int, char **);
    const char *desc;
} argparse_entry;

argparse_entry commands[] = {
<<argparse_entries>>
};

4.2. Argparse Run

The function argparse_match_and_run will attempt find and run the proper subcommand. It will return the error code. Any non-zero value will be considered an error.

This function assumes that argc is greater than 1. Do checks beforehand.

<<static_funcdefs>>=
static int argparse_match_and_run(int argc, char *argv[]);
<<functions>>=
static int match(const char *s1,
                 int sz1,
                 const char *s2,
                 int sz2)
{
    return sz1 == sz2 && !strncmp(s1, s2, sz2);
}


static int argparse_match_and_run(int argc, char *argv[])
{
    size_t len;
    int rc;
    int nitems;
    int i;
    argparse_entry *cmd;

    rc = 0;

    nitems = sizeof(commands) / sizeof(*commands);

    len = strlen(argv[1]);

    cmd = commands;

    for (i = 0; i < nitems; i++) {
        if (match(argv[1], len, cmd[i].name, cmd[i].len)) {
            argc--;
            argv++;
            return cmd[i].fun(argc, argv);
        }
    }

    fprintf(stderr, "Could not find command '%s'\n", argv[1]);

    return rc;
}

4.3. Print Arguments

Done with argparse_print.

<<static_funcdefs>>=
static void argparse_print(FILE *fp);
<<functions>>=
static void argparse_print(FILE *fp)
{
    int nitems;
    int i;

    fprintf(fp, "Available commands:\n\n");
    nitems = sizeof(commands) / sizeof(*commands);

    for (i = 0; i < nitems; i++) {
        fprintf(fp, "%s\n", commands[i].name);
    }
}



prev | home | next