arg/arg.c

51 lines
1.6 KiB
C
Raw Normal View History

2019-02-14 19:17:02 -08:00
/*
* 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>
int main(int argc, char **argv)
{
char *flag = argv[1];
if (!flag || flag[0] != '-') {
fprintf(stderr, "Usage: arg [-<f> | --<flag>] ...\n");
return 1;
}
size_t n = 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, n) != 0) continue;
if (arg[n] == '\0') { // --flag
if (argv[i+1] && argv[i+1][0] != '-')
puts(argv[i+1]); // value of flag, if any
return 0;
} else if (arg[n] == '=') { // --flag=...
puts(&arg[n+1]);
return 0;
}
}
// If flag is single-character, e.g. -f, look for it among other single
// character flags like -xfy, in which case the next argument will not
// be considered its value.
if (n == 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 0;
}
}
}
return 1;
}