Download
50 lines 1.6 KiBCModified 2019-03-02 raw
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
/* 
 * arg - A simple C program by Bruce Hill for parsing command line arguments
 *   Licensed under the MIT license (see LICENSE for details).
 *
 *   Example: arg --foo a b --foo=blah --baz -xyz
 *     - Prints "blah" and exits with success
 *   Example: arg --nope a b --foo=blah --baz -xyz
 *     - Prints nothing and exits with failure
 *   Example: arg -y a b --foo=blah --baz -xyz
 *     - Prints nothing and exits with success
 */
#include <stdio.h>
#include <string.h>

const int EXIT_SUCCESS = 0;
const int EXIT_NO_MATCH = 1;
const int EXIT_BAD_USAGE = -1;

int main(int argc, char **argv)
{
    char *flag = argv[1];
    if (!flag) {
        fprintf(stderr, "Usage: arg <flag> ...\n");
        return EXIT_BAD_USAGE;
    }
    size_t flaglen = strlen(flag);
    int ischarflag = flag[0] == '-' && flaglen == 2;
    for (int i = 2; i < argc; i++) {
        char *arg = argv[i];
        if (strncmp(arg, flag, flaglen) == 0) {
            if (arg[flaglen] == '\0') { // --flag ...
                if (argv[i+1] && argv[i+1][0] != '-') // --flag <value>
                    puts(argv[i+1]); // value of the flag
                return EXIT_SUCCESS;
            } else if (arg[flaglen] == '=') { // --flag=<value>
                puts(&arg[flaglen+1]);
                return EXIT_SUCCESS;
            }
        }
        if (ischarflag && arg[0] == '-' && arg[1] != '-') {
            // If flag is single-character, e.g. -f, look for it among other
            // single character flags like -xfy.
            for (char *c = &arg[1]; *c; c++) {
                if (*c == flag[1])
                    return EXIT_SUCCESS;
            }
        }
    }
    return EXIT_NO_MATCH;
}