85 lines
2.3 KiB
C
85 lines
2.3 KiB
C
/* 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
|
|
*/
|
|
#ifndef GETOPT_H
|
|
#define GETOPT_H
|
|
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <string.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);
|
|
if (!arg[++optpos]) {
|
|
optind++;
|
|
optpos = 1;
|
|
}
|
|
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);
|
|
if (!arg[++optpos]) {
|
|
optind++;
|
|
optpos = 1;
|
|
}
|
|
return *optstring == ':' ? ':' : '?';
|
|
}
|
|
} else {
|
|
if (!arg[++optpos]) {
|
|
optind++;
|
|
optpos = 1;
|
|
}
|
|
return optopt;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|