glx-multithread-texture: Avoid front-buffer rendering.
[piglit.git] / tests / util / msvc / getopt.c
blob8eab136dd9af8d8157f3d9696e206e1eccdf3c90
1 /* Getopt for Microsoft C
2 This code is a modification of the Free Software Foundation, Inc.
3 Getopt library for parsing command line argument the purpose was
4 to provide a Microsoft Visual C friendly derivative. This code
5 provides functionality for both Unicode and Multibyte builds.
7 Date: 02/03/2011 - Ludvik Jerabek - Initial Release
8 Version: 1.0
9 Comment: Supports getopt, getopt_long, and getopt_long_only
10 and POSIXLY_CORRECT environment flag
11 License: LGPL
13 Revisions:
15 02/03/2011 - Ludvik Jerabek - Initial Release
16 02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
17 07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs
18 08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception
19 08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
20 02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file
21 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi
22 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features
23 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
25 **DISCLAIMER**
26 THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
27 EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
28 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
29 PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
30 EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
31 APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
32 DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
33 USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
34 PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
35 YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
36 EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <malloc.h>
41 #include "getopt.h"
43 #define alloca _alloca
45 #ifdef __cplusplus
46 #define _GETOPT_THROW throw()
47 #else
48 #define _GETOPT_THROW
49 #endif
51 int optind = 1;
52 int opterr = 1;
53 int optopt = '?';
54 enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
58 // Ansi structures and functions follow
59 //
62 static struct _getopt_data_a
64 int optind;
65 int opterr;
66 int optopt;
67 char *optarg;
68 int __initialized;
69 char *__nextchar;
70 enum ENUM_ORDERING __ordering;
71 int __posixly_correct;
72 int __first_nonopt;
73 int __last_nonopt;
74 } getopt_data_a;
75 char *optarg_a;
77 static void exchange_a(char **argv, struct _getopt_data_a *d)
79 int bottom = d->__first_nonopt;
80 int middle = d->__last_nonopt;
81 int top = d->optind;
82 char *tem;
83 while (top > middle && middle > bottom)
85 if (top - middle > middle - bottom)
87 int len = middle - bottom;
88 register int i;
89 for (i = 0; i < len; i++)
91 tem = argv[bottom + i];
92 argv[bottom + i] = argv[top - (middle - bottom) + i];
93 argv[top - (middle - bottom) + i] = tem;
95 top -= len;
97 else
99 int len = top - middle;
100 register int i;
101 for (i = 0; i < len; i++)
103 tem = argv[bottom + i];
104 argv[bottom + i] = argv[middle + i];
105 argv[middle + i] = tem;
107 bottom += len;
110 d->__first_nonopt += (d->optind - d->__last_nonopt);
111 d->__last_nonopt = d->optind;
113 static const char *_getopt_initialize_a (const char *optstring, struct _getopt_data_a *d, int posixly_correct)
115 d->__first_nonopt = d->__last_nonopt = d->optind;
116 d->__nextchar = NULL;
117 d->__posixly_correct = posixly_correct | !!getenv("POSIXLY_CORRECT");
118 if (optstring[0] == '-')
120 d->__ordering = RETURN_IN_ORDER;
121 ++optstring;
123 else if (optstring[0] == '+')
125 d->__ordering = REQUIRE_ORDER;
126 ++optstring;
128 else if (d->__posixly_correct)
129 d->__ordering = REQUIRE_ORDER;
130 else
131 d->__ordering = PERMUTE;
132 return optstring;
134 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)
136 int print_errors = d->opterr;
137 if (argc < 1)
138 return -1;
139 d->optarg = NULL;
140 if (d->optind == 0 || !d->__initialized)
142 if (d->optind == 0)
143 d->optind = 1;
144 optstring = _getopt_initialize_a (optstring, d, posixly_correct);
145 d->__initialized = 1;
147 else if (optstring[0] == '-' || optstring[0] == '+')
148 optstring++;
149 if (optstring[0] == ':')
150 print_errors = 0;
151 if (d->__nextchar == NULL || *d->__nextchar == '\0')
153 if (d->__last_nonopt > d->optind)
154 d->__last_nonopt = d->optind;
155 if (d->__first_nonopt > d->optind)
156 d->__first_nonopt = d->optind;
157 if (d->__ordering == PERMUTE)
159 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
160 exchange_a ((char **) argv, d);
161 else if (d->__last_nonopt != d->optind)
162 d->__first_nonopt = d->optind;
163 while (d->optind < argc && (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
164 d->optind++;
165 d->__last_nonopt = d->optind;
167 if (d->optind != argc && !strcmp(argv[d->optind], "--"))
169 d->optind++;
170 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
171 exchange_a((char **) argv, d);
172 else if (d->__first_nonopt == d->__last_nonopt)
173 d->__first_nonopt = d->optind;
174 d->__last_nonopt = argc;
175 d->optind = argc;
177 if (d->optind == argc)
179 if (d->__first_nonopt != d->__last_nonopt)
180 d->optind = d->__first_nonopt;
181 return -1;
183 if ((argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
185 if (d->__ordering == REQUIRE_ORDER)
186 return -1;
187 d->optarg = argv[d->optind++];
188 return 1;
190 d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == '-'));
192 if (longopts != NULL && (argv[d->optind][1] == '-' || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1])))))
194 char *nameend;
195 unsigned int namelen;
196 const struct option_a *p;
197 const struct option_a *pfound = NULL;
198 struct option_list
200 const struct option_a *p;
201 struct option_list *next;
202 } *ambig_list = NULL;
203 int exact = 0;
204 int indfound = -1;
205 int option_index;
206 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++);
207 namelen = (unsigned int)(nameend - d->__nextchar);
208 for (p = longopts, option_index = 0; p->name; p++, option_index++)
209 if (!strncmp(p->name, d->__nextchar, namelen))
211 if (namelen == (unsigned int)strlen(p->name))
213 pfound = p;
214 indfound = option_index;
215 exact = 1;
216 break;
218 else if (pfound == NULL)
220 pfound = p;
221 indfound = option_index;
223 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
225 struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
226 newp->p = p;
227 newp->next = ambig_list;
228 ambig_list = newp;
231 if (ambig_list != NULL && !exact)
233 if (print_errors)
235 struct option_list first;
236 first.p = pfound;
237 first.next = ambig_list;
238 ambig_list = &first;
239 fprintf (stderr, "%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]);
242 fprintf (stderr, " '--%s'", ambig_list->p->name);
243 ambig_list = ambig_list->next;
245 while (ambig_list != NULL);
246 fputc ('\n', stderr);
248 d->__nextchar += strlen(d->__nextchar);
249 d->optind++;
250 d->optopt = 0;
251 return '?';
253 if (pfound != NULL)
255 option_index = indfound;
256 d->optind++;
257 if (*nameend)
259 if (pfound->has_arg)
260 d->optarg = nameend + 1;
261 else
263 if (print_errors)
265 if (argv[d->optind - 1][1] == '-')
267 fprintf(stderr, "%s: option '--%s' doesn't allow an argument\n",argv[0], pfound->name);
269 else
271 fprintf(stderr, "%s: option '%c%s' doesn't allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
274 d->__nextchar += strlen(d->__nextchar);
275 d->optopt = pfound->val;
276 return '?';
279 else if (pfound->has_arg == 1)
281 if (d->optind < argc)
282 d->optarg = argv[d->optind++];
283 else
285 if (print_errors)
287 fprintf(stderr,"%s: option '--%s' requires an argument\n",argv[0], pfound->name);
289 d->__nextchar += strlen(d->__nextchar);
290 d->optopt = pfound->val;
291 return optstring[0] == ':' ? ':' : '?';
294 d->__nextchar += strlen(d->__nextchar);
295 if (longind != NULL)
296 *longind = option_index;
297 if (pfound->flag)
299 *(pfound->flag) = pfound->val;
300 return 0;
302 return pfound->val;
304 if (!long_only || argv[d->optind][1] == '-' || strchr(optstring, *d->__nextchar) == NULL)
306 if (print_errors)
308 if (argv[d->optind][1] == '-')
310 fprintf(stderr, "%s: unrecognized option '--%s'\n",argv[0], d->__nextchar);
312 else
314 fprintf(stderr, "%s: unrecognized option '%c%s'\n",argv[0], argv[d->optind][0], d->__nextchar);
317 d->__nextchar = (char *)"";
318 d->optind++;
319 d->optopt = 0;
320 return '?';
324 char c = *d->__nextchar++;
325 char *temp = (char*)strchr(optstring, c);
326 if (*d->__nextchar == '\0')
327 ++d->optind;
328 if (temp == NULL || c == ':' || c == ';')
330 if (print_errors)
332 fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], c);
334 d->optopt = c;
335 return '?';
337 if (temp[0] == 'W' && temp[1] == ';')
339 char *nameend;
340 const struct option_a *p;
341 const struct option_a *pfound = NULL;
342 int exact = 0;
343 int ambig = 0;
344 int indfound = 0;
345 int option_index;
346 if (longopts == NULL)
347 goto no_longs;
348 if (*d->__nextchar != '\0')
350 d->optarg = d->__nextchar;
351 d->optind++;
353 else if (d->optind == argc)
355 if (print_errors)
357 fprintf(stderr,"%s: option requires an argument -- '%c'\n",argv[0], c);
359 d->optopt = c;
360 if (optstring[0] == ':')
361 c = ':';
362 else
363 c = '?';
364 return c;
366 else
367 d->optarg = argv[d->optind++];
368 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; nameend++);
369 for (p = longopts, option_index = 0; p->name; p++, option_index++)
370 if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar))
372 if ((unsigned int) (nameend - d->__nextchar) == strlen(p->name))
374 pfound = p;
375 indfound = option_index;
376 exact = 1;
377 break;
379 else if (pfound == NULL)
381 pfound = p;
382 indfound = option_index;
384 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
385 ambig = 1;
387 if (ambig && !exact)
389 if (print_errors)
391 fprintf(stderr, "%s: option '-W %s' is ambiguous\n",argv[0], d->optarg);
393 d->__nextchar += strlen(d->__nextchar);
394 d->optind++;
395 return '?';
397 if (pfound != NULL)
399 option_index = indfound;
400 if (*nameend)
402 if (pfound->has_arg)
403 d->optarg = nameend + 1;
404 else
406 if (print_errors)
408 fprintf(stderr, "%s: option '-W %s' doesn't allow an argument\n",argv[0], pfound->name);
410 d->__nextchar += strlen(d->__nextchar);
411 return '?';
414 else if (pfound->has_arg == 1)
416 if (d->optind < argc)
417 d->optarg = argv[d->optind++];
418 else
420 if (print_errors)
422 fprintf(stderr, "%s: option '-W %s' requires an argument\n",argv[0], pfound->name);
424 d->__nextchar += strlen(d->__nextchar);
425 return optstring[0] == ':' ? ':' : '?';
428 else
429 d->optarg = NULL;
430 d->__nextchar += strlen(d->__nextchar);
431 if (longind != NULL)
432 *longind = option_index;
433 if (pfound->flag)
435 *(pfound->flag) = pfound->val;
436 return 0;
438 return pfound->val;
440 no_longs:
441 d->__nextchar = NULL;
442 return 'W';
444 if (temp[1] == ':')
446 if (temp[2] == ':')
448 if (*d->__nextchar != '\0')
450 d->optarg = d->__nextchar;
451 d->optind++;
453 else
454 d->optarg = NULL;
455 d->__nextchar = NULL;
457 else
459 if (*d->__nextchar != '\0')
461 d->optarg = d->__nextchar;
462 d->optind++;
464 else if (d->optind == argc)
466 if (print_errors)
468 fprintf(stderr,"%s: option requires an argument -- '%c'\n",argv[0], c);
470 d->optopt = c;
471 if (optstring[0] == ':')
472 c = ':';
473 else
474 c = '?';
476 else
477 d->optarg = argv[d->optind++];
478 d->__nextchar = NULL;
481 return c;
484 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)
486 int result;
487 getopt_data_a.optind = optind;
488 getopt_data_a.opterr = opterr;
489 result = _getopt_internal_r_a (argc, argv, optstring, longopts,longind, long_only, &getopt_data_a,posixly_correct);
490 optind = getopt_data_a.optind;
491 optarg_a = getopt_data_a.optarg;
492 optopt = getopt_data_a.optopt;
493 return result;
495 int getopt_a (int argc, char *const *argv, const char *optstring) _GETOPT_THROW
497 return _getopt_internal_a (argc, argv, optstring, (const struct option_a *) 0, (int *) 0, 0, 0);
499 int getopt_long_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
501 return _getopt_internal_a (argc, argv, options, long_options, opt_index, 0, 0);
503 int getopt_long_only_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
505 return _getopt_internal_a (argc, argv, options, long_options, opt_index, 1, 0);
507 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)
509 return _getopt_internal_r_a (argc, argv, options, long_options, opt_index,0, d, 0);
511 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)
513 return _getopt_internal_r_a (argc, argv, options, long_options, opt_index, 1, d, 0);
518 // Unicode Structures and Functions
522 static struct _getopt_data_w
524 int optind;
525 int opterr;
526 int optopt;
527 wchar_t *optarg;
528 int __initialized;
529 wchar_t *__nextchar;
530 enum ENUM_ORDERING __ordering;
531 int __posixly_correct;
532 int __first_nonopt;
533 int __last_nonopt;
534 } getopt_data_w;
535 wchar_t *optarg_w;
537 static void exchange_w(wchar_t **argv, struct _getopt_data_w *d)
539 int bottom = d->__first_nonopt;
540 int middle = d->__last_nonopt;
541 int top = d->optind;
542 wchar_t *tem;
543 while (top > middle && middle > bottom)
545 if (top - middle > middle - bottom)
547 int len = middle - bottom;
548 register int i;
549 for (i = 0; i < len; i++)
551 tem = argv[bottom + i];
552 argv[bottom + i] = argv[top - (middle - bottom) + i];
553 argv[top - (middle - bottom) + i] = tem;
555 top -= len;
557 else
559 int len = top - middle;
560 register int i;
561 for (i = 0; i < len; i++)
563 tem = argv[bottom + i];
564 argv[bottom + i] = argv[middle + i];
565 argv[middle + i] = tem;
567 bottom += len;
570 d->__first_nonopt += (d->optind - d->__last_nonopt);
571 d->__last_nonopt = d->optind;
573 static const wchar_t *_getopt_initialize_w (const wchar_t *optstring, struct _getopt_data_w *d, int posixly_correct)
575 d->__first_nonopt = d->__last_nonopt = d->optind;
576 d->__nextchar = NULL;
577 d->__posixly_correct = posixly_correct | !!_wgetenv(L"POSIXLY_CORRECT");
578 if (optstring[0] == L'-')
580 d->__ordering = RETURN_IN_ORDER;
581 ++optstring;
583 else if (optstring[0] == L'+')
585 d->__ordering = REQUIRE_ORDER;
586 ++optstring;
588 else if (d->__posixly_correct)
589 d->__ordering = REQUIRE_ORDER;
590 else
591 d->__ordering = PERMUTE;
592 return optstring;
594 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)
596 int print_errors = d->opterr;
597 if (argc < 1)
598 return -1;
599 d->optarg = NULL;
600 if (d->optind == 0 || !d->__initialized)
602 if (d->optind == 0)
603 d->optind = 1;
604 optstring = _getopt_initialize_w (optstring, d, posixly_correct);
605 d->__initialized = 1;
607 else if (optstring[0] == L'-' || optstring[0] == L'+')
608 optstring++;
609 if (optstring[0] == L':')
610 print_errors = 0;
611 if (d->__nextchar == NULL || *d->__nextchar == L'\0')
613 if (d->__last_nonopt > d->optind)
614 d->__last_nonopt = d->optind;
615 if (d->__first_nonopt > d->optind)
616 d->__first_nonopt = d->optind;
617 if (d->__ordering == PERMUTE)
619 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
620 exchange_w((wchar_t **) argv, d);
621 else if (d->__last_nonopt != d->optind)
622 d->__first_nonopt = d->optind;
623 while (d->optind < argc && (argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0'))
624 d->optind++;
625 d->__last_nonopt = d->optind;
627 if (d->optind != argc && !wcscmp(argv[d->optind], L"--"))
629 d->optind++;
630 if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
631 exchange_w((wchar_t **) argv, d);
632 else if (d->__first_nonopt == d->__last_nonopt)
633 d->__first_nonopt = d->optind;
634 d->__last_nonopt = argc;
635 d->optind = argc;
637 if (d->optind == argc)
639 if (d->__first_nonopt != d->__last_nonopt)
640 d->optind = d->__first_nonopt;
641 return -1;
643 if ((argv[d->optind][0] != L'-' || argv[d->optind][1] == L'\0'))
645 if (d->__ordering == REQUIRE_ORDER)
646 return -1;
647 d->optarg = argv[d->optind++];
648 return 1;
650 d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == L'-'));
652 if (longopts != NULL && (argv[d->optind][1] == L'-' || (long_only && (argv[d->optind][2] || !wcschr(optstring, argv[d->optind][1])))))
654 wchar_t *nameend;
655 unsigned int namelen;
656 const struct option_w *p;
657 const struct option_w *pfound = NULL;
658 struct option_list
660 const struct option_w *p;
661 struct option_list *next;
662 } *ambig_list = NULL;
663 int exact = 0;
664 int indfound = -1;
665 int option_index;
666 for (nameend = d->__nextchar; *nameend && *nameend != L'='; nameend++);
667 namelen = (unsigned int)(nameend - d->__nextchar);
668 for (p = longopts, option_index = 0; p->name; p++, option_index++)
669 if (!wcsncmp(p->name, d->__nextchar, namelen))
671 if (namelen == (unsigned int)wcslen(p->name))
673 pfound = p;
674 indfound = option_index;
675 exact = 1;
676 break;
678 else if (pfound == NULL)
680 pfound = p;
681 indfound = option_index;
683 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
685 struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
686 newp->p = p;
687 newp->next = ambig_list;
688 ambig_list = newp;
691 if (ambig_list != NULL && !exact)
693 if (print_errors)
695 struct option_list first;
696 first.p = pfound;
697 first.next = ambig_list;
698 ambig_list = &first;
699 fwprintf(stderr, L"%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind]);
702 fwprintf (stderr, L" '--%s'", ambig_list->p->name);
703 ambig_list = ambig_list->next;
705 while (ambig_list != NULL);
706 fputwc (L'\n', stderr);
708 d->__nextchar += wcslen(d->__nextchar);
709 d->optind++;
710 d->optopt = 0;
711 return L'?';
713 if (pfound != NULL)
715 option_index = indfound;
716 d->optind++;
717 if (*nameend)
719 if (pfound->has_arg)
720 d->optarg = nameend + 1;
721 else
723 if (print_errors)
725 if (argv[d->optind - 1][1] == L'-')
727 fwprintf(stderr, L"%s: option '--%s' doesn't allow an argument\n",argv[0], pfound->name);
729 else
731 fwprintf(stderr, L"%s: option '%c%s' doesn't allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
734 d->__nextchar += wcslen(d->__nextchar);
735 d->optopt = pfound->val;
736 return L'?';
739 else if (pfound->has_arg == 1)
741 if (d->optind < argc)
742 d->optarg = argv[d->optind++];
743 else
745 if (print_errors)
747 fwprintf(stderr,L"%s: option '--%s' requires an argument\n",argv[0], pfound->name);
749 d->__nextchar += wcslen(d->__nextchar);
750 d->optopt = pfound->val;
751 return optstring[0] == L':' ? L':' : L'?';
754 d->__nextchar += wcslen(d->__nextchar);
755 if (longind != NULL)
756 *longind = option_index;
757 if (pfound->flag)
759 *(pfound->flag) = pfound->val;
760 return 0;
762 return pfound->val;
764 if (!long_only || argv[d->optind][1] == L'-' || wcschr(optstring, *d->__nextchar) == NULL)
766 if (print_errors)
768 if (argv[d->optind][1] == L'-')
770 fwprintf(stderr, L"%s: unrecognized option '--%s'\n",argv[0], d->__nextchar);
772 else
774 fwprintf(stderr, L"%s: unrecognized option '%c%s'\n",argv[0], argv[d->optind][0], d->__nextchar);
777 d->__nextchar = (wchar_t *)L"";
778 d->optind++;
779 d->optopt = 0;
780 return L'?';
784 wchar_t c = *d->__nextchar++;
785 wchar_t *temp = (wchar_t*)wcschr(optstring, c);
786 if (*d->__nextchar == L'\0')
787 ++d->optind;
788 if (temp == NULL || c == L':' || c == L';')
790 if (print_errors)
792 fwprintf(stderr, L"%s: invalid option -- '%c'\n", argv[0], c);
794 d->optopt = c;
795 return L'?';
797 if (temp[0] == L'W' && temp[1] == L';')
799 wchar_t *nameend;
800 const struct option_w *p;
801 const struct option_w *pfound = NULL;
802 int exact = 0;
803 int ambig = 0;
804 int indfound = 0;
805 int option_index;
806 if (longopts == NULL)
807 goto no_longs;
808 if (*d->__nextchar != L'\0')
810 d->optarg = d->__nextchar;
811 d->optind++;
813 else if (d->optind == argc)
815 if (print_errors)
817 fwprintf(stderr,L"%s: option requires an argument -- '%c'\n",argv[0], c);
819 d->optopt = c;
820 if (optstring[0] == L':')
821 c = L':';
822 else
823 c = L'?';
824 return c;
826 else
827 d->optarg = argv[d->optind++];
828 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != L'='; nameend++);
829 for (p = longopts, option_index = 0; p->name; p++, option_index++)
830 if (!wcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
832 if ((unsigned int) (nameend - d->__nextchar) == wcslen(p->name))
834 pfound = p;
835 indfound = option_index;
836 exact = 1;
837 break;
839 else if (pfound == NULL)
841 pfound = p;
842 indfound = option_index;
844 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
845 ambig = 1;
847 if (ambig && !exact)
849 if (print_errors)
851 fwprintf(stderr, L"%s: option '-W %s' is ambiguous\n",argv[0], d->optarg);
853 d->__nextchar += wcslen(d->__nextchar);
854 d->optind++;
855 return L'?';
857 if (pfound != NULL)
859 option_index = indfound;
860 if (*nameend)
862 if (pfound->has_arg)
863 d->optarg = nameend + 1;
864 else
866 if (print_errors)
868 fwprintf(stderr, L"%s: option '-W %s' doesn't allow an argument\n",argv[0], pfound->name);
870 d->__nextchar += wcslen(d->__nextchar);
871 return L'?';
874 else if (pfound->has_arg == 1)
876 if (d->optind < argc)
877 d->optarg = argv[d->optind++];
878 else
880 if (print_errors)
882 fwprintf(stderr, L"%s: option '-W %s' requires an argument\n",argv[0], pfound->name);
884 d->__nextchar += wcslen(d->__nextchar);
885 return optstring[0] == L':' ? L':' : L'?';
888 else
889 d->optarg = NULL;
890 d->__nextchar += wcslen(d->__nextchar);
891 if (longind != NULL)
892 *longind = option_index;
893 if (pfound->flag)
895 *(pfound->flag) = pfound->val;
896 return 0;
898 return pfound->val;
900 no_longs:
901 d->__nextchar = NULL;
902 return L'W';
904 if (temp[1] == L':')
906 if (temp[2] == L':')
908 if (*d->__nextchar != L'\0')
910 d->optarg = d->__nextchar;
911 d->optind++;
913 else
914 d->optarg = NULL;
915 d->__nextchar = NULL;
917 else
919 if (*d->__nextchar != L'\0')
921 d->optarg = d->__nextchar;
922 d->optind++;
924 else if (d->optind == argc)
926 if (print_errors)
928 fwprintf(stderr,L"%s: option requires an argument -- '%c'\n",argv[0], c);
930 d->optopt = c;
931 if (optstring[0] == L':')
932 c = L':';
933 else
934 c = L'?';
936 else
937 d->optarg = argv[d->optind++];
938 d->__nextchar = NULL;
941 return c;
944 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)
946 int result;
947 getopt_data_w.optind = optind;
948 getopt_data_w.opterr = opterr;
949 result = _getopt_internal_r_w (argc, argv, optstring, longopts,longind, long_only, &getopt_data_w,posixly_correct);
950 optind = getopt_data_w.optind;
951 optarg_w = getopt_data_w.optarg;
952 optopt = getopt_data_w.optopt;
953 return result;
955 int getopt_w (int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW
957 return _getopt_internal_w (argc, argv, optstring, (const struct option_w *) 0, (int *) 0, 0, 0);
959 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
961 return _getopt_internal_w (argc, argv, options, long_options, opt_index, 0, 0);
963 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
965 return _getopt_internal_w (argc, argv, options, long_options, opt_index, 1, 0);
967 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)
969 return _getopt_internal_r_w (argc, argv, options, long_options, opt_index,0, d, 0);
971 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)
973 return _getopt_internal_r_w (argc, argv, options, long_options, opt_index, 1, d, 0);