60#pragma warning(disable : 4996)
84#define optreset __mingw_optreset
89#define PRINT_ERROR ((opterr) && (*options != ':'))
91#define FLAG_PERMUTE 0x01
92#define FLAG_ALLARGS 0x02
93#define FLAG_LONGONLY 0x04
97#define BADARG ((*options == ':') ? (int)':' : (int)'?')
101#define __progname __argv[0]
103extern char __declspec(dllimport) * __progname;
107static char EMSG[] =
"";
112static int getopt_internal(
int,
char *
const *,
const char *,
113 const struct option *,
int *,
int);
114static int parse_long_options(
char *
const *,
const char *,
115 const struct option *,
int *,
int);
116static int gcd(
int,
int);
117static void permute_args(
int,
int,
int,
char *
const *);
119static char *place = EMSG;
122static int nonopt_start = -1;
123static int nonopt_end = -1;
126static const char recargchar[] =
"option requires an argument -- %c";
127static const char recargstring[] =
"option requires an argument -- %s";
128static const char ambig[] =
"ambiguous option -- %.*s";
129static const char noarg[] =
"option doesn't take an argument -- %.*s";
130static const char illoptchar[] =
"unknown option -- %c";
131static const char illoptstring[] =
"unknown option -- %s";
133static void _vwarnx(
const char *fmt, va_list ap) {
134 (void)fprintf(stderr,
"%s: ", __progname);
136 (void)vfprintf(stderr, fmt, ap);
137 (void)fprintf(stderr,
"\n");
140static void warnx(
const char *fmt, ...) {
150static int gcd(
int a,
int b) {
168static void permute_args(
int panonopt_start,
int panonopt_end,
int opt_end,
169 char *
const *nargv) {
170 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
176 nnonopts = panonopt_end - panonopt_start;
177 nopts = opt_end - panonopt_end;
178 ncycle = gcd(nnonopts, nopts);
179 cyclelen = (opt_end - panonopt_start) / ncycle;
181 for (i = 0; i < ncycle; i++) {
182 cstart = panonopt_end + i;
184 for (j = 0; j < cyclelen; j++) {
185 if (pos >= panonopt_end)
191 ((
char **)nargv)[pos] = nargv[cstart];
193 ((
char **)nargv)[cstart] = swap;
205int getopt(
int nargc,
char *
const *nargv,
const char *options) {
215 return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
228#define optreset __mingw_optreset
245#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
246#define __GETOPT_LONG_H__
272static int parse_long_options(
char *
const *nargv,
const char *options,
273 const struct option *long_options,
int *idx,
275 char *current_argv, *has_equal;
276 size_t current_argv_len;
277 int i, ambiguous, match;
279#define IDENTICAL_INTERPRETATION(_x, _y) \
280 (long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
281 long_options[(_x)].flag == long_options[(_y)].flag && \
282 long_options[(_x)].val == long_options[(_y)].val)
284 current_argv = place;
290 if ((has_equal = strchr(current_argv,
'=')) != NULL) {
292 current_argv_len = has_equal - current_argv;
295 current_argv_len = strlen(current_argv);
297 for (i = 0; long_options[i].name; i++) {
299 if (strncmp(current_argv, long_options[i].name, current_argv_len))
302 if (strlen(long_options[i].name) == current_argv_len) {
312 if (short_too && current_argv_len == 1)
317 else if (!IDENTICAL_INTERPRETATION(i, match))
323 warnx(ambig, (
int)current_argv_len, current_argv);
328 if (long_options[match].has_arg == no_argument && has_equal) {
330 warnx(noarg, (
int)current_argv_len, current_argv);
334 if (long_options[match].flag == NULL)
335 optopt = long_options[match].val;
340 if (long_options[match].has_arg == required_argument ||
341 long_options[match].has_arg == optional_argument) {
344 else if (long_options[match].has_arg == required_argument) {
348 optarg = nargv[optind++];
351 if ((long_options[match].has_arg == required_argument) &&
358 warnx(recargstring, current_argv);
362 if (long_options[match].flag == NULL)
363 optopt = long_options[match].val;
375 warnx(illoptstring, current_argv);
381 if (long_options[match].flag) {
382 *long_options[match].flag = long_options[match].val;
385 return (long_options[match].val);
386#undef IDENTICAL_INTERPRETATION
393static int getopt_internal(
int nargc,
char *
const *nargv,
const char *options,
394 const struct option *long_options,
int *idx,
397 int optchar, short_too;
398 static int posixly_correct = -1;
408 optind = optreset = 1;
417 if (posixly_correct == -1 || optreset != 0)
418 posixly_correct = (getenv(
"POSIXLY_CORRECT") != NULL);
420 flags |= FLAG_ALLARGS;
421 else if (posixly_correct || *options ==
'+')
422 flags &= ~FLAG_PERMUTE;
423 if (*options ==
'+' || *options ==
'-')
428 nonopt_start = nonopt_end = -1;
430 if (optreset || !*place) {
432 if (optind >= nargc) {
434 if (nonopt_end != -1) {
436 permute_args(nonopt_start, nonopt_end, optind, nargv);
437 optind -= nonopt_end - nonopt_start;
438 }
else if (nonopt_start != -1) {
443 optind = nonopt_start;
445 nonopt_start = nonopt_end = -1;
448 if (*(place = nargv[optind]) !=
'-' ||
449 (place[1] ==
'\0' && strchr(options,
'-') == NULL)) {
451 if (flags & FLAG_ALLARGS) {
456 optarg = nargv[optind++];
459 if (!(flags & FLAG_PERMUTE)) {
467 if (nonopt_start == -1)
468 nonopt_start = optind;
469 else if (nonopt_end != -1) {
470 permute_args(nonopt_start, nonopt_end, optind, nargv);
471 nonopt_start = optind - (nonopt_end - nonopt_start);
478 if (nonopt_start != -1 && nonopt_end == -1)
484 if (place[1] !=
'\0' && *++place ==
'-' && place[1] ==
'\0') {
491 if (nonopt_end != -1) {
492 permute_args(nonopt_start, nonopt_end, optind, nargv);
493 optind -= nonopt_end - nonopt_start;
495 nonopt_start = nonopt_end = -1;
506 if (long_options != NULL && place != nargv[optind] &&
507 (*place ==
'-' || (flags & FLAG_LONGONLY))) {
511 else if (*place !=
':' && strchr(options, *place) != NULL)
514 optchar = parse_long_options(nargv, options, long_options, idx, short_too);
521 if ((optchar = (
int)*place++) == (
int)
':' ||
522 (optchar == (
int)
'-' && *place !=
'\0') ||
523 (oli = (
char *)strchr(options, optchar)) == NULL) {
529 if (optchar == (
int)
'-' && *place ==
'\0')
534 warnx(illoptchar, optchar);
538 if (long_options != NULL && optchar ==
'W' && oli[1] ==
';') {
542 else if (++optind >= nargc) {
545 warnx(recargchar, optchar);
549 place = nargv[optind];
550 optchar = parse_long_options(nargv, options, long_options, idx, 0);
561 else if (oli[1] !=
':') {
562 if (++optind >= nargc) {
565 warnx(recargchar, optchar);
569 optarg = nargv[optind];
582int getopt_long(
int nargc,
char *
const *nargv,
const char *options,
583 const struct option *long_options,
int *idx) {
586 getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE));
593int getopt_long_only(
int nargc,
char *
const *nargv,
const char *options,
594 const struct option *long_options,
int *idx) {
596 return (getopt_internal(nargc, nargv, options, long_options, idx,
597 FLAG_PERMUTE | FLAG_LONGONLY));
607#ifndef HAVE_DECL_GETOPT
611#define HAVE_DECL_GETOPT 1