| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #ifdef _MSC_VER |
| #include <malloc.h> |
| #endif |
| #include "getopt.h" |
|
|
| #ifdef __cplusplus |
| #define _GETOPT_THROW throw() |
| #else |
| #define _GETOPT_THROW |
| #endif |
|
|
| int optind = 1; |
| int opterr = 1; |
| int optopt = '?'; |
| enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER }; |
|
|
|
|
| static struct _getopt_data_a |
| { |
| int optind; |
| int opterr; |
| int optopt; |
| char *optarg; |
| int __initialized; |
| char *__nextchar; |
| enum ENUM_ORDERING __ordering; |
| int __posixly_correct; |
| int __first_nonopt; |
| int __last_nonopt; |
| } getopt_data_a; |
| char *optarg_a; |
|
|
| static void exchange_a(char **argv, struct _getopt_data_a *d) |
| { |
| int bottom = d->__first_nonopt; |
| int middle = d->__last_nonopt; |
| int top = d->optind; |
| char *tem; |
| while (top > middle && middle > bottom) |
| { |
| if (top - middle > middle - bottom) |
| { |
| int len = middle - bottom; |
| register int i; |
| for (i = 0; i < len; i++) |
| { |
| tem = argv[bottom + i]; |
| argv[bottom + i] = argv[top - (middle - bottom) + i]; |
| argv[top - (middle - bottom) + i] = tem; |
| } |
| top -= len; |
| } |
| else |
| { |
| int len = top - middle; |
| register int i; |
| for (i = 0; i < len; i++) |
| { |
| tem = argv[bottom + i]; |
| argv[bottom + i] = argv[middle + i]; |
| argv[middle + i] = tem; |
| } |
| bottom += len; |
| } |
| } |
| d->__first_nonopt += (d->optind - d->__last_nonopt); |
| d->__last_nonopt = d->optind; |
| } |
| static const char *_getopt_initialize_a(const char *optstring, struct _getopt_data_a *d, int posixly_correct) |
| { |
| d->__first_nonopt = d->__last_nonopt = d->optind; |
| d->__nextchar = NULL; |
| d->__posixly_correct = posixly_correct | !!getenv("POSIXLY_CORRECT"); |
| if (optstring[0] == '-') |
| { |
| d->__ordering = RETURN_IN_ORDER; |
| ++optstring; |
| } |
| else if (optstring[0] == '+') |
| { |
| d->__ordering = REQUIRE_ORDER; |
| ++optstring; |
| } |
| else if (d->__posixly_correct) |
| d->__ordering = REQUIRE_ORDER; |
| else |
| d->__ordering = PERMUTE; |
| return optstring; |
| } |
| int _getopt_internal_r_a(int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct) |
| { |
| int print_errors = d->opterr; |
| if (argc < 1) |
| return -1; |
| d->optarg = NULL; |
| if (d->optind == 0 || !d->__initialized) |
| { |
| if (d->optind == 0) |
| d->optind = 1; |
| optstring = _getopt_initialize_a(optstring, d, posixly_correct); |
| d->__initialized = 1; |
| } |
| else if (optstring[0] == '-' || optstring[0] == '+') |
| optstring++; |
| if (optstring[0] == ':') |
| print_errors = 0; |
| if (d->__nextchar == NULL || *d->__nextchar == '\0') |
| { |
| if (d->__last_nonopt > d->optind) |
| d->__last_nonopt = d->optind; |
| if (d->__first_nonopt > d->optind) |
| d->__first_nonopt = d->optind; |
| if (d->__ordering == PERMUTE) |
| { |
| if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) |
| exchange_a((char **)argv, d); |
| else if (d->__last_nonopt != d->optind) |
| d->__first_nonopt = d->optind; |
| while (d->optind < argc && (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')) |
| d->optind++; |
| d->__last_nonopt = d->optind; |
| } |
| if (d->optind != argc && !strcmp(argv[d->optind], "--")) |
| { |
| d->optind++; |
| if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) |
| exchange_a((char **)argv, d); |
| else if (d->__first_nonopt == d->__last_nonopt) |
| d->__first_nonopt = d->optind; |
| d->__last_nonopt = argc; |
| d->optind = argc; |
| } |
| if (d->optind == argc) |
| { |
| if (d->__first_nonopt != d->__last_nonopt) |
| d->optind = d->__first_nonopt; |
| return -1; |
| } |
| if ((argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')) |
| { |
| if (d->__ordering == REQUIRE_ORDER) |
| return -1; |
| d->optarg = argv[d->optind++]; |
| return 1; |
| } |
| d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == '-')); |
| } |
| if (longopts != NULL && (argv[d->optind][1] == '-' || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1]))))) |
| { |
| char *nameend; |
| unsigned int namelen; |
| const struct option_a *p; |
| const struct option_a *pfound = NULL; |
| struct option_list |
| { |
| const struct option_a *p; |
| struct option_list *next; |
| } *ambig_list = NULL; |
| int exact = 0; |
| int indfound = -1; |
| int option_index; |
| for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++); |
| namelen = (unsigned int)(nameend - d->__nextchar); |
| for (p = longopts, option_index = 0; p->name; p++, option_index++) |
| if (!strncmp(p->name, d->__nextchar, namelen)) |
| { |
| if (namelen == (unsigned int)strlen(p->name)) |
| { |
| pfound = p; |
| indfound = option_index; |
| exact = 1; |
| break; |
| } |
| else if (pfound == NULL) |
| { |
| pfound = p; |
| indfound = option_index; |
| } |
| else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) |
| { |
| struct option_list *newp = (struct option_list*)alloca(sizeof(*newp)); |
| newp->p = p; |
| newp->next = ambig_list; |
| ambig_list = newp; |
| } |
| } |
| if (ambig_list != NULL && !exact) |
| { |
| if (print_errors) |
| { |
| struct option_list first; |
| first.p = pfound; |
| first.next = ambig_list; |
| ambig_list = &first; |
| fprintf(stderr, "%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]); |
| do |
| { |
| fprintf(stderr, " '--%s'", ambig_list->p->name); |
| ambig_list = ambig_list->next; |
| } while (ambig_list != NULL); |
| fputc('\n', stderr); |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| d->optind++; |
| d->optopt = 0; |
| return '?'; |
| } |
| if (pfound != NULL) |
| { |
| option_index = indfound; |
| d->optind++; |
| if (*nameend) |
| { |
| if (pfound->has_arg) |
| d->optarg = nameend + 1; |
| else |
| { |
| if (print_errors) |
| { |
| if (argv[d->optind - 1][1] == '-') |
| { |
| fprintf(stderr, "%s: option '--%s' doesn't allow an argument\n", argv[0], pfound->name); |
| } |
| else |
| { |
| fprintf(stderr, "%s: option '%c%s' doesn't allow an argument\n", argv[0], argv[d->optind - 1][0], pfound->name); |
| } |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| d->optopt = pfound->val; |
| return '?'; |
| } |
| } |
| else if (pfound->has_arg == 1) |
| { |
| if (d->optind < argc) |
| d->optarg = argv[d->optind++]; |
| else |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option '--%s' requires an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| d->optopt = pfound->val; |
| return optstring[0] == ':' ? ':' : '?'; |
| } |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| if (longind != NULL) |
| *longind = option_index; |
| if (pfound->flag) |
| { |
| *(pfound->flag) = pfound->val; |
| return 0; |
| } |
| return pfound->val; |
| } |
| if (!long_only || argv[d->optind][1] == '-' || strchr(optstring, *d->__nextchar) == NULL) |
| { |
| if (print_errors) |
| { |
| if (argv[d->optind][1] == '-') |
| { |
| fprintf(stderr, "%s: unrecognized option '--%s'\n", argv[0], d->__nextchar); |
| } |
| else |
| { |
| fprintf(stderr, "%s: unrecognized option '%c%s'\n", argv[0], argv[d->optind][0], d->__nextchar); |
| } |
| } |
| d->__nextchar = (char *)""; |
| d->optind++; |
| d->optopt = 0; |
| return '?'; |
| } |
| } |
| { |
| char c = *d->__nextchar++; |
| char *temp = (char*)strchr(optstring, c); |
| if (*d->__nextchar == '\0') |
| ++d->optind; |
| if (temp == NULL || c == ':' || c == ';') |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| return '?'; |
| } |
| if (temp[0] == 'W' && temp[1] == ';') |
| { |
| char *nameend; |
| const struct option_a *p; |
| const struct option_a *pfound = NULL; |
| int exact = 0; |
| int ambig = 0; |
| int indfound = 0; |
| int option_index; |
| if (longopts == NULL) |
| goto no_longs; |
| if (*d->__nextchar != '\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else if (d->optind == argc) |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option requires an argument -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| if (optstring[0] == ':') |
| c = ':'; |
| else |
| c = '?'; |
| return c; |
| } |
| else |
| d->optarg = argv[d->optind++]; |
| for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; nameend++); |
| for (p = longopts, option_index = 0; p->name; p++, option_index++) |
| if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar)) |
| { |
| if ((unsigned int)(nameend - d->__nextchar) == strlen(p->name)) |
| { |
| pfound = p; |
| indfound = option_index; |
| exact = 1; |
| break; |
| } |
| else if (pfound == NULL) |
| { |
| pfound = p; |
| indfound = option_index; |
| } |
| else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) |
| ambig = 1; |
| } |
| if (ambig && !exact) |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option '-W %s' is ambiguous\n", argv[0], d->optarg); |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| d->optind++; |
| return '?'; |
| } |
| if (pfound != NULL) |
| { |
| option_index = indfound; |
| if (*nameend) |
| { |
| if (pfound->has_arg) |
| d->optarg = nameend + 1; |
| else |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option '-W %s' doesn't allow an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| return '?'; |
| } |
| } |
| else if (pfound->has_arg == 1) |
| { |
| if (d->optind < argc) |
| d->optarg = argv[d->optind++]; |
| else |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option '-W %s' requires an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += strlen(d->__nextchar); |
| return optstring[0] == ':' ? ':' : '?'; |
| } |
| } |
| else |
| d->optarg = NULL; |
| d->__nextchar += strlen(d->__nextchar); |
| if (longind != NULL) |
| *longind = option_index; |
| if (pfound->flag) |
| { |
| *(pfound->flag) = pfound->val; |
| return 0; |
| } |
| return pfound->val; |
| } |
| no_longs: |
| d->__nextchar = NULL; |
| return 'W'; |
| } |
| if (temp[1] == ':') |
| { |
| if (temp[2] == ':') |
| { |
| if (*d->__nextchar != '\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else |
| d->optarg = NULL; |
| d->__nextchar = NULL; |
| } |
| else |
| { |
| if (*d->__nextchar != '\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else if (d->optind == argc) |
| { |
| if (print_errors) |
| { |
| fprintf(stderr, "%s: option requires an argument -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| if (optstring[0] == ':') |
| c = ':'; |
| else |
| c = '?'; |
| } |
| else |
| d->optarg = argv[d->optind++]; |
| d->__nextchar = NULL; |
| } |
| } |
| return c; |
| } |
| } |
| int _getopt_internal_a(int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, int posixly_correct) |
| { |
| int result; |
| getopt_data_a.optind = optind; |
| getopt_data_a.opterr = opterr; |
| result = _getopt_internal_r_a(argc, argv, optstring, longopts, longind, long_only, &getopt_data_a, posixly_correct); |
| optind = getopt_data_a.optind; |
| optarg_a = getopt_data_a.optarg; |
| optopt = getopt_data_a.optopt; |
| return result; |
| } |
| int getopt_a(int argc, char *const *argv, const char *optstring) _GETOPT_THROW |
| { |
| return _getopt_internal_a(argc, argv, optstring, (const struct option_a *) 0, (int *)0, 0, 0); |
| } |
| int getopt_long_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW |
| { |
| return _getopt_internal_a(argc, argv, options, long_options, opt_index, 0, 0); |
| } |
| int getopt_long_only_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW |
| { |
| return _getopt_internal_a(argc, argv, options, long_options, opt_index, 1, 0); |
| } |
| int _getopt_long_r_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d) |
| { |
| return _getopt_internal_r_a(argc, argv, options, long_options, opt_index, 0, d, 0); |
| } |
| int _getopt_long_only_r_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d) |
| { |
| return _getopt_internal_r_a(argc, argv, options, long_options, opt_index, 1, d, 0); |
| } |
|
|
|
|
| static struct _getopt_data_w |
| { |
| int optind; |
| int opterr; |
| int optopt; |
| wchar_t *optarg; |
| int __initialized; |
| wchar_t *__nextchar; |
| enum ENUM_ORDERING __ordering; |
| int __posixly_correct; |
| int __first_nonopt; |
| int __last_nonopt; |
| } getopt_data_w; |
| wchar_t *optarg_w; |
|
|
| static void exchange_w(wchar_t **argv, struct _getopt_data_w *d) |
| { |
| int bottom = d->__first_nonopt; |
| int middle = d->__last_nonopt; |
| int top = d->optind; |
| wchar_t *tem; |
| while (top > middle && middle > bottom) |
| { |
| if (top - middle > middle - bottom) |
| { |
| int len = middle - bottom; |
| register int i; |
| for (i = 0; i < len; i++) |
| { |
| tem = argv[bottom + i]; |
| argv[bottom + i] = argv[top - (middle - bottom) + i]; |
| argv[top - (middle - bottom) + i] = tem; |
| } |
| top -= len; |
| } |
| else |
| { |
| int len = top - middle; |
| register int i; |
| for (i = 0; i < len; i++) |
| { |
| tem = argv[bottom + i]; |
| argv[bottom + i] = argv[middle + i]; |
| argv[middle + i] = tem; |
| } |
| bottom += len; |
| } |
| } |
| d->__first_nonopt += (d->optind - d->__last_nonopt); |
| d->__last_nonopt = d->optind; |
| } |
| static const wchar_t *_getopt_initialize_w(const wchar_t *optstring, struct _getopt_data_w *d, int posixly_correct) |
| { |
| d->__first_nonopt = d->__last_nonopt = d->optind; |
| d->__nextchar = NULL; |
| d->__posixly_correct = posixly_correct | !!_wgetenv(L"POSIXLY_CORRECT"); |
| if (optstring[0] == L'-') |
| { |
| d->__ordering = RETURN_IN_ORDER; |
| ++optstring; |
| } |
| else if (optstring[0] == L'+') |
| { |
| d->__ordering = REQUIRE_ORDER; |
| ++optstring; |
| } |
| else if (d->__posixly_correct) |
| d->__ordering = REQUIRE_ORDER; |
| else |
| d->__ordering = PERMUTE; |
| return optstring; |
| } |
| int _getopt_internal_r_w(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, struct _getopt_data_w *d, int posixly_correct) |
| { |
| int print_errors = d->opterr; |
| if (argc < 1) |
| return -1; |
| d->optarg = NULL; |
| if (d->optind == 0 || !d->__initialized) |
| { |
| if (d->optind == 0) |
| d->optind = 1; |
| optstring = _getopt_initialize_w(optstring, d, posixly_correct); |
| d->__initialized = 1; |
| } |
| else if (optstring[0] == L'-' || optstring[0] == L'+') |
| optstring++; |
| if (optstring[0] == L':') |
| print_errors = 0; |
| if (d->__nextchar == NULL || *d->__nextchar == L'\0') |
| { |
| if (d->__last_nonopt > d->optind) |
| d->__last_nonopt = d->optind; |
| if (d->__first_nonopt > d->optind) |
| d->__first_nonopt = d->optind; |
| if (d->__ordering == PERMUTE) |
| { |
| if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) |
| exchange_w((wchar_t **)argv, d); |
| else if (d->__last_nonopt != d->optind) |
| d->__first_nonopt = d->optind; |
| while (d->optind < argc && (argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0')) |
| d->optind++; |
| d->__last_nonopt = d->optind; |
| } |
| if (d->optind != argc && !wcscmp(argv[d->optind], L"--")) |
| { |
| d->optind++; |
| if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind) |
| exchange_w((wchar_t **)argv, d); |
| else if (d->__first_nonopt == d->__last_nonopt) |
| d->__first_nonopt = d->optind; |
| d->__last_nonopt = argc; |
| d->optind = argc; |
| } |
| if (d->optind == argc) |
| { |
| if (d->__first_nonopt != d->__last_nonopt) |
| d->optind = d->__first_nonopt; |
| return -1; |
| } |
| if ((argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0')) |
| { |
| if (d->__ordering == REQUIRE_ORDER) |
| return -1; |
| d->optarg = argv[d->optind++]; |
| return 1; |
| } |
| d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == L'-')); |
| } |
| if (longopts != NULL && (argv[d->optind][1] == L'-' || (long_only && (argv[d->optind][2] || !wcschr(optstring, argv[d->optind][1]))))) |
| { |
| wchar_t *nameend; |
| unsigned int namelen; |
| const struct option_w *p; |
| const struct option_w *pfound = NULL; |
| struct option_list |
| { |
| const struct option_w *p; |
| struct option_list *next; |
| } *ambig_list = NULL; |
| int exact = 0; |
| int indfound = -1; |
| int option_index; |
| for (nameend = d->__nextchar; *nameend && *nameend != L'='; nameend++); |
| namelen = (unsigned int)(nameend - d->__nextchar); |
| for (p = longopts, option_index = 0; p->name; p++, option_index++) |
| if (!wcsncmp(p->name, d->__nextchar, namelen)) |
| { |
| if (namelen == (unsigned int)wcslen(p->name)) |
| { |
| pfound = p; |
| indfound = option_index; |
| exact = 1; |
| break; |
| } |
| else if (pfound == NULL) |
| { |
| pfound = p; |
| indfound = option_index; |
| } |
| else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) |
| { |
| struct option_list *newp = (struct option_list*)alloca(sizeof(*newp)); |
| newp->p = p; |
| newp->next = ambig_list; |
| ambig_list = newp; |
| } |
| } |
| if (ambig_list != NULL && !exact) |
| { |
| if (print_errors) |
| { |
| struct option_list first; |
| first.p = pfound; |
| first.next = ambig_list; |
| ambig_list = &first; |
| fwprintf(stderr, L"%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]); |
| do |
| { |
| fwprintf(stderr, L" '--%s'", ambig_list->p->name); |
| ambig_list = ambig_list->next; |
| } while (ambig_list != NULL); |
| fputwc(L'\n', stderr); |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| d->optind++; |
| d->optopt = 0; |
| return L'?'; |
| } |
| if (pfound != NULL) |
| { |
| option_index = indfound; |
| d->optind++; |
| if (*nameend) |
| { |
| if (pfound->has_arg) |
| d->optarg = nameend + 1; |
| else |
| { |
| if (print_errors) |
| { |
| if (argv[d->optind - 1][1] == L'-') |
| { |
| fwprintf(stderr, L"%s: option '--%s' doesn't allow an argument\n", argv[0], pfound->name); |
| } |
| else |
| { |
| fwprintf(stderr, L"%s: option '%c%s' doesn't allow an argument\n", argv[0], argv[d->optind - 1][0], pfound->name); |
| } |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| d->optopt = pfound->val; |
| return L'?'; |
| } |
| } |
| else if (pfound->has_arg == 1) |
| { |
| if (d->optind < argc) |
| d->optarg = argv[d->optind++]; |
| else |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option '--%s' requires an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| d->optopt = pfound->val; |
| return optstring[0] == L':' ? L':' : L'?'; |
| } |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| if (longind != NULL) |
| *longind = option_index; |
| if (pfound->flag) |
| { |
| *(pfound->flag) = pfound->val; |
| return 0; |
| } |
| return pfound->val; |
| } |
| if (!long_only || argv[d->optind][1] == L'-' || wcschr(optstring, *d->__nextchar) == NULL) |
| { |
| if (print_errors) |
| { |
| if (argv[d->optind][1] == L'-') |
| { |
| fwprintf(stderr, L"%s: unrecognized option '--%s'\n", argv[0], d->__nextchar); |
| } |
| else |
| { |
| fwprintf(stderr, L"%s: unrecognized option '%c%s'\n", argv[0], argv[d->optind][0], d->__nextchar); |
| } |
| } |
| d->__nextchar = (wchar_t *)L""; |
| d->optind++; |
| d->optopt = 0; |
| return L'?'; |
| } |
| } |
| { |
| wchar_t c = *d->__nextchar++; |
| wchar_t *temp = (wchar_t*)wcschr(optstring, c); |
| if (*d->__nextchar == L'\0') |
| ++d->optind; |
| if (temp == NULL || c == L':' || c == L';') |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: invalid option -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| return L'?'; |
| } |
| if (temp[0] == L'W' && temp[1] == L';') |
| { |
| wchar_t *nameend; |
| const struct option_w *p; |
| const struct option_w *pfound = NULL; |
| int exact = 0; |
| int ambig = 0; |
| int indfound = 0; |
| int option_index; |
| if (longopts == NULL) |
| goto no_longs; |
| if (*d->__nextchar != L'\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else if (d->optind == argc) |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option requires an argument -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| if (optstring[0] == L':') |
| c = L':'; |
| else |
| c = L'?'; |
| return c; |
| } |
| else |
| d->optarg = argv[d->optind++]; |
| for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != L'='; nameend++); |
| for (p = longopts, option_index = 0; p->name; p++, option_index++) |
| if (!wcsncmp(p->name, d->__nextchar, nameend - d->__nextchar)) |
| { |
| if ((unsigned int)(nameend - d->__nextchar) == wcslen(p->name)) |
| { |
| pfound = p; |
| indfound = option_index; |
| exact = 1; |
| break; |
| } |
| else if (pfound == NULL) |
| { |
| pfound = p; |
| indfound = option_index; |
| } |
| else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val) |
| ambig = 1; |
| } |
| if (ambig && !exact) |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option '-W %s' is ambiguous\n", argv[0], d->optarg); |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| d->optind++; |
| return L'?'; |
| } |
| if (pfound != NULL) |
| { |
| option_index = indfound; |
| if (*nameend) |
| { |
| if (pfound->has_arg) |
| d->optarg = nameend + 1; |
| else |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option '-W %s' doesn't allow an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| return L'?'; |
| } |
| } |
| else if (pfound->has_arg == 1) |
| { |
| if (d->optind < argc) |
| d->optarg = argv[d->optind++]; |
| else |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option '-W %s' requires an argument\n", argv[0], pfound->name); |
| } |
| d->__nextchar += wcslen(d->__nextchar); |
| return optstring[0] == L':' ? L':' : L'?'; |
| } |
| } |
| else |
| d->optarg = NULL; |
| d->__nextchar += wcslen(d->__nextchar); |
| if (longind != NULL) |
| *longind = option_index; |
| if (pfound->flag) |
| { |
| *(pfound->flag) = pfound->val; |
| return 0; |
| } |
| return pfound->val; |
| } |
| no_longs: |
| d->__nextchar = NULL; |
| return L'W'; |
| } |
| if (temp[1] == L':') |
| { |
| if (temp[2] == L':') |
| { |
| if (*d->__nextchar != L'\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else |
| d->optarg = NULL; |
| d->__nextchar = NULL; |
| } |
| else |
| { |
| if (*d->__nextchar != L'\0') |
| { |
| d->optarg = d->__nextchar; |
| d->optind++; |
| } |
| else if (d->optind == argc) |
| { |
| if (print_errors) |
| { |
| fwprintf(stderr, L"%s: option requires an argument -- '%c'\n", argv[0], c); |
| } |
| d->optopt = c; |
| if (optstring[0] == L':') |
| c = L':'; |
| else |
| c = L'?'; |
| } |
| else |
| d->optarg = argv[d->optind++]; |
| d->__nextchar = NULL; |
| } |
| } |
| return c; |
| } |
| } |
| int _getopt_internal_w(int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, int posixly_correct) |
| { |
| int result; |
| getopt_data_w.optind = optind; |
| getopt_data_w.opterr = opterr; |
| result = _getopt_internal_r_w(argc, argv, optstring, longopts, longind, long_only, &getopt_data_w, posixly_correct); |
| optind = getopt_data_w.optind; |
| optarg_w = getopt_data_w.optarg; |
| optopt = getopt_data_w.optopt; |
| return result; |
| } |
| int getopt_w(int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW |
| { |
| return _getopt_internal_w(argc, argv, optstring, (const struct option_w *) 0, (int *)0, 0, 0); |
| } |
| int getopt_long_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW |
| { |
| return _getopt_internal_w(argc, argv, options, long_options, opt_index, 0, 0); |
| } |
| int getopt_long_only_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW |
| { |
| return _getopt_internal_w(argc, argv, options, long_options, opt_index, 1, 0); |
| } |
| int _getopt_long_r_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d) |
| { |
| return _getopt_internal_r_w(argc, argv, options, long_options, opt_index, 0, d, 0); |
| } |
| int _getopt_long_only_r_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d) |
| { |
| return _getopt_internal_r_w(argc, argv, options, long_options, opt_index, 1, d, 0); |
| } |