/* Adapted from https://github.com/skeeto/getopt by Chris Wellons */ /* A minimal POSIX getopt() implementation in ANSI C * * This is free and unencumbered software released into the public domain. * * This implementation supports the convention of resetting the option * parser by assigning optind to 0. This resets the internal state * appropriately. * * Ref: http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html */ #include #include #include #include "getopt.h" int optind; int opterr = 1; int optopt; char *optarg; int getopt(int argc, char * const argv[], const char *optstring) { static int optpos = 1; const char *arg; /* Reset? */ if (optind == 0) { optind = !!argc; optpos = 1; } arg = argv[optind]; if (arg && strcmp(arg, "--") == 0) { optind++; return -1; } else if (!arg || arg[0] != '-' || !isalnum(arg[1])) { return -1; } else { const char *opt = strchr(optstring, arg[optpos]); optopt = arg[optpos]; if (!opt) { if (opterr && *optstring != ':') fprintf(stderr, "%s: illegal option: %c\n", argv[0], optopt); return '?'; } else if (opt[1] == ':') { if (arg[optpos + 1]) { optarg = (char *)arg + optpos + 1; optind++; optpos = 1; return optopt; } else if (argv[optind + 1]) { optarg = (char *)argv[optind + 1]; optind += 2; optpos = 1; return optopt; } else { if (opterr && *optstring != ':') fprintf(stderr, "%s: option requires an argument: %c\n", argv[0], optopt); return *optstring == ':' ? ':' : '?'; } } else { if (!arg[++optpos]) { optind++; optpos = 1; } return optopt; } } }