/* * 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 #include #define EXIT_SUCCESS 0 #define EXIT_NO_MATCH 1 #define EXIT_BAD_USAGE -1 int main(int argc, char **argv) { char *flag = argv[1]; if (!flag) { fprintf(stderr, "Usage: arg ...\n"); return EXIT_BAD_USAGE; } size_t flaglen = strlen(flag); // Look for: --flag=val, --flag val, --flag, -f=val, -f val, or -f for (int i = 2; i < argc; i++) { char *arg = argv[i]; if (strncmp(arg, flag, flaglen) != 0) continue; if (arg[flaglen] == '\0') { // --flag ... if (argv[i+1] && argv[i+1][0] != '-') // --flag puts(argv[i+1]); // value of the flag return EXIT_SUCCESS; } else if (arg[flaglen] == '=') { // --flag=... puts(&arg[flaglen+1]); return EXIT_SUCCESS; } } // If flag is single-character without a value, e.g. -f, look for it // among other single character flags like -xfy. if (flag[0] == '-' && flaglen == 2) { for (int i = 2; i < argc; i++) { char *arg = argv[i]; if (arg[0] != '-' || arg[1] == '-') continue; // skip foo and --foo for (char *c = &arg[1]; *c; c++) { if (*c == flag[1]) return EXIT_SUCCESS; } } } return EXIT_NO_MATCH; }