Mercurial > pmdwin
diff getopt.c @ 0:c55ea9478c80
Hello Gensokyo!
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 21 May 2013 10:29:21 +0200 |
parents | |
children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/getopt.c @@ -0,0 +1,85 @@ +/* + * getopt - get option letter from argv + * + * This is a version of the public domain getopt() implementation by + * Henry Spencer, changed for 4.3BSD compatibility (in addition to System V). + * It allows rescanning of an option list by setting optind to 0 before + * calling, which is why we use it even if the system has its own (in fact, + * this one has a unique name so as not to conflict with the system's). + * Thanks to Dennis Ferguson for the appropriate modifications. + * + * This file is in the Public Domain. + */ + +#include <string.h> +#include <unistd.h> + +char *optarg; /* Global argument pointer. */ +int optind = 0; /* Global argv index. */ +int opterr = 1; /* for compatibility, should error be printed? */ +int optopt; /* for compatibility, option character checked */ + +static char *scan = NULL; /* Private scan pointer. */ + +/* + * Print message about a bad option. + */ +static int badopt(const char *msg, int ch) +{ + if (opterr) { + write(2, msg, strlen(msg)); + write(2, &ch, 1); + write(2, "\n", 1); + } + return ('?'); +} + +int getopt(int argc, char *const argv[], const char *optstring) +{ + register char c; + register const char *place; + optarg = NULL; + + if (optind == 0) { + scan = NULL; + optind++; + } + + if (scan == NULL || *scan == '\0') { + if (optind >= argc + || argv[optind][0] != '-' + || argv[optind][1] == '\0') { + return (-1); + } + if (argv[optind][1] == '-' + && argv[optind][2] == '\0') { + optind++; + return (-1); + } + scan = argv[optind++]+1; + } + + c = *scan++; + optopt = c & 0377; + for (place = optstring; place != NULL && *place != '\0'; ++place) + if (*place == c) + break; + + if (place == NULL || *place == '\0' || c == ':' || c == '?') { + return (badopt("getopt: unknown option -", c)); + } + + place++; + if (*place == ':') { + if (*scan != '\0') { + optarg = scan; + scan = NULL; + } else if (optind >= argc) { + return (badopt("getopt: option requires argument -", c)); + } else { + optarg = argv[optind++]; + } + } + return (c & 0377); +} +