Create the AHCI branch for Aman's work
[reactos.git] / sdk / tools / widl / getopt.c
1 /*
2 * Copyright (c) 1987, 1993, 1994, 1996
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdio.h>
37
38 struct option {
39 const char *name;
40 int has_arg;
41 int *flag;
42 int val;
43 };
44
45 int opterr = 1;
46 int optind = 1;
47 int optopt = '?';
48 int optreset;
49 char *optarg;
50
51 #define my_index strchr
52
53 #ifdef _LIBC
54 # ifdef USE_NONOPTION_FLAGS
55 # define SWAP_FLAGS(ch1, ch2) \
56 if (nonoption_flags_len > 0) \
57 { \
58 char __tmp = __getopt_nonoption_flags[ch1]; \
59 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
60 __getopt_nonoption_flags[ch2] = __tmp; \
61 }
62 # else
63 # define SWAP_FLAGS(ch1, ch2)
64 # endif
65 #else /* !_LIBC */
66 # define SWAP_FLAGS(ch1, ch2)
67 #endif /* _LIBC */
68
69 int __getopt_initialized;
70
71 static int first_nonopt = -1;
72 static int last_nonopt = -1;
73
74 static char *nextchar;
75
76 static char *posixly_correct;
77
78 static enum
79 {
80 REQUIRE_ORDER,
81 PERMUTE,
82 RETURN_IN_ORDER
83 } ordering;
84
85 static void
86 exchange (argv)
87 char **argv;
88 {
89 int bottom = first_nonopt;
90 int middle = last_nonopt;
91 int top = optind;
92 char *tem;
93
94 /* Exchange the shorter segment with the far end of the longer segment.
95 That puts the shorter segment into the right place.
96 It leaves the longer segment in the right place overall,
97 but it consists of two parts that need to be swapped next. */
98
99 #if defined _LIBC && defined USE_NONOPTION_FLAGS
100 /* First make sure the handling of the `__getopt_nonoption_flags'
101 string can work normally. Our top argument must be in the range
102 of the string. */
103 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
104 {
105 /* We must extend the array. The user plays games with us and
106 presents new arguments. */
107 char *new_str = malloc (top + 1);
108 if (new_str == NULL)
109 nonoption_flags_len = nonoption_flags_max_len = 0;
110 else
111 {
112 memset (__mempcpy (new_str, __getopt_nonoption_flags,
113 nonoption_flags_max_len),
114 '\0', top + 1 - nonoption_flags_max_len);
115 nonoption_flags_max_len = top + 1;
116 __getopt_nonoption_flags = new_str;
117 }
118 }
119 #endif
120
121 while (top > middle && middle > bottom)
122 {
123 if (top - middle > middle - bottom)
124 {
125 /* Bottom segment is the short one. */
126 int len = middle - bottom;
127 register int i;
128
129 /* Swap it with the top part of the top segment. */
130 for (i = 0; i < len; i++)
131 {
132 tem = argv[bottom + i];
133 argv[bottom + i] = argv[top - (middle - bottom) + i];
134 argv[top - (middle - bottom) + i] = tem;
135 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
136 }
137 /* Exclude the moved bottom segment from further swapping. */
138 top -= len;
139 }
140 else
141 {
142 /* Top segment is the short one. */
143 int len = top - middle;
144 register int i;
145
146 /* Swap it with the bottom part of the bottom segment. */
147 for (i = 0; i < len; i++)
148 {
149 tem = argv[bottom + i];
150 argv[bottom + i] = argv[middle + i];
151 argv[middle + i] = tem;
152 SWAP_FLAGS (bottom + i, middle + i);
153 }
154 /* Exclude the moved top segment from further swapping. */
155 bottom += len;
156 }
157 }
158
159 /* Update records for the slots the non-options now occupy. */
160
161 first_nonopt += (optind - last_nonopt);
162 last_nonopt = optind;
163 }
164
165 static const char *
166 _getopt_initialize (argc, argv, optstring)
167 int argc;
168 char *const *argv;
169 const char *optstring;
170 {
171 /* Start processing options with ARGV-element 1 (since ARGV-element 0
172 is the program name); the sequence of previously skipped
173 non-option ARGV-elements is empty. */
174
175 first_nonopt = last_nonopt = optind;
176
177 nextchar = NULL;
178
179 posixly_correct = getenv ("POSIXLY_CORRECT");
180
181 /* Determine how to handle the ordering of options and nonoptions. */
182
183 if (optstring[0] == '-')
184 {
185 ordering = RETURN_IN_ORDER;
186 ++optstring;
187 }
188 else if (optstring[0] == '+')
189 {
190 ordering = REQUIRE_ORDER;
191 ++optstring;
192 }
193 else if (posixly_correct != NULL)
194 ordering = REQUIRE_ORDER;
195 else
196 ordering = PERMUTE;
197
198 #if defined _LIBC && defined USE_NONOPTION_FLAGS
199 if (posixly_correct == NULL
200 && argc == __libc_argc && argv == __libc_argv)
201 {
202 if (nonoption_flags_max_len == 0)
203 {
204 if (__getopt_nonoption_flags == NULL
205 || __getopt_nonoption_flags[0] == '\0')
206 nonoption_flags_max_len = -1;
207 else
208 {
209 const char *orig_str = __getopt_nonoption_flags;
210 int len = nonoption_flags_max_len = strlen (orig_str);
211 if (nonoption_flags_max_len < argc)
212 nonoption_flags_max_len = argc;
213 __getopt_nonoption_flags = malloc (nonoption_flags_max_len);
214 if (__getopt_nonoption_flags == NULL)
215 nonoption_flags_max_len = -1;
216 else
217 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
218 '\0', nonoption_flags_max_len - len);
219 }
220 }
221 nonoption_flags_len = nonoption_flags_max_len;
222 }
223 else
224 nonoption_flags_len = 0;
225 #endif
226
227 return optstring;
228 }
229
230 int
231 getopt_long_only (int argc, char * const *argv, const char *options, const struct option *long_options, int *opt_index)
232 {
233 return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
234 }
235
236 int
237 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
238 int argc;
239 char *const *argv;
240 const char *optstring;
241 const struct option *longopts;
242 int *longind;
243 int long_only;
244 {
245 int print_errors = opterr;
246 if (optstring[0] == ':')
247 print_errors = 0;
248
249 if (argc < 1)
250 return -1;
251
252 optarg = NULL;
253
254 if (optind == 0 || !__getopt_initialized)
255 {
256 if (optind == 0)
257 optind = 1; /* Don't scan ARGV[0], the program name. */
258 optstring = _getopt_initialize (argc, argv, optstring);
259 __getopt_initialized = 1;
260 }
261
262 /* Test whether ARGV[optind] points to a non-option argument.
263 Either it does not have option syntax, or there is an environment flag
264 from the shell indicating it is not an option. The later information
265 is only used when the used in the GNU libc. */
266 #if defined _LIBC && defined USE_NONOPTION_FLAGS
267 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
268 || (optind < nonoption_flags_len \
269 && __getopt_nonoption_flags[optind] == '1'))
270 #else
271 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
272 #endif
273
274 if (nextchar == NULL || *nextchar == '\0')
275 {
276 /* Advance to the next ARGV-element. */
277
278 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
279 moved back by the user (who may also have changed the arguments). */
280 if (last_nonopt > optind)
281 last_nonopt = optind;
282 if (first_nonopt > optind)
283 first_nonopt = optind;
284
285 if (ordering == PERMUTE)
286 {
287 /* If we have just processed some options following some non-options,
288 exchange them so that the options come first. */
289
290 if (first_nonopt != last_nonopt && last_nonopt != optind)
291 exchange ((char **) argv);
292 else if (last_nonopt != optind)
293 first_nonopt = optind;
294
295 /* Skip any additional non-options
296 and extend the range of non-options previously skipped. */
297
298 while (optind < argc && NONOPTION_P)
299 optind++;
300 last_nonopt = optind;
301 }
302
303 /* The special ARGV-element `--' means premature end of options.
304 Skip it like a null option,
305 then exchange with previous non-options as if it were an option,
306 then skip everything else like a non-option. */
307
308 if (optind != argc && !strcmp (argv[optind], "--"))
309 {
310 optind++;
311
312 if (first_nonopt != last_nonopt && last_nonopt != optind)
313 exchange ((char **) argv);
314 else if (first_nonopt == last_nonopt)
315 first_nonopt = optind;
316 last_nonopt = argc;
317
318 optind = argc;
319 }
320
321 /* If we have done all the ARGV-elements, stop the scan
322 and back over any non-options that we skipped and permuted. */
323
324 if (optind == argc)
325 {
326 /* Set the next-arg-index to point at the non-options
327 that we previously skipped, so the caller will digest them. */
328 if (first_nonopt != last_nonopt)
329 optind = first_nonopt;
330 return -1;
331 }
332
333 /* If we have come to a non-option and did not permute it,
334 either stop the scan or describe it to the caller and pass it by. */
335
336 if (NONOPTION_P)
337 {
338 if (ordering == REQUIRE_ORDER)
339 return -1;
340 optarg = argv[optind++];
341 return 1;
342 }
343
344 /* We have found another option-ARGV-element.
345 Skip the initial punctuation. */
346
347 nextchar = (argv[optind] + 1
348 + (longopts != NULL && argv[optind][1] == '-'));
349 }
350
351 /* Decode the current option-ARGV-element. */
352
353 /* Check whether the ARGV-element is a long option.
354
355 If long_only and the ARGV-element has the form "-f", where f is
356 a valid short option, don't consider it an abbreviated form of
357 a long option that starts with f. Otherwise there would be no
358 way to give the -f short option.
359
360 On the other hand, if there's a long option "fubar" and
361 the ARGV-element is "-fu", do consider that an abbreviation of
362 the long option, just like "--fu", and not "-f" with arg "u".
363
364 This distinction seems to be the most useful approach. */
365
366 if (longopts != NULL
367 && (argv[optind][1] == '-'
368 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
369 {
370 char *nameend;
371 const struct option *p;
372 const struct option *pfound = NULL;
373 int exact = 0;
374 int ambig = 0;
375 int indfound = -1;
376 int option_index;
377
378 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
379 /* Do nothing. */ ;
380
381 /* Test all long options for either exact match
382 or abbreviated matches. */
383 for (p = longopts, option_index = 0; p->name; p++, option_index++)
384 if (!strncmp (p->name, nextchar, nameend - nextchar))
385 {
386 if ((unsigned int) (nameend - nextchar)
387 == (unsigned int) strlen (p->name))
388 {
389 /* Exact match found. */
390 pfound = p;
391 indfound = option_index;
392 exact = 1;
393 break;
394 }
395 else if (pfound == NULL)
396 {
397 /* First nonexact match found. */
398 pfound = p;
399 indfound = option_index;
400 }
401 else if (long_only
402 || pfound->has_arg != p->has_arg
403 || pfound->flag != p->flag
404 || pfound->val != p->val)
405 /* Second or later nonexact match found. */
406 ambig = 1;
407 }
408
409 if (ambig && !exact)
410 {
411 if (print_errors)
412 {
413 #if defined _LIBC && defined USE_IN_LIBIO
414 char *buf;
415
416 if (__asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
417 argv[0], argv[optind]) >= 0)
418 {
419
420 if (_IO_fwide (stderr, 0) > 0)
421 __fwprintf (stderr, L"%s", buf);
422 else
423 fputs (buf, stderr);
424
425 free (buf);
426 }
427 #else
428 fprintf (stderr, "%s: option `%s' is ambiguous\n",
429 argv[0], argv[optind]);
430 #endif
431 }
432 nextchar += strlen (nextchar);
433 optind++;
434 optopt = 0;
435 return '?';
436 }
437
438 if (pfound != NULL)
439 {
440 option_index = indfound;
441 optind++;
442 if (*nameend)
443 {
444 /* Don't test has_arg with >, because some C compilers don't
445 allow it to be used on enums. */
446 if (pfound->has_arg)
447 optarg = nameend + 1;
448 else
449 {
450 if (print_errors)
451 {
452 #if defined _LIBC && defined USE_IN_LIBIO
453 char *buf;
454 int n;
455 #endif
456
457 if (argv[optind - 1][1] == '-')
458 {
459 /* --option */
460 #if defined _LIBC && defined USE_IN_LIBIO
461 n = __asprintf (&buf, "\
462 %s: option `--%s' doesn't allow an argument\n",
463 argv[0], pfound->name);
464 #else
465 fprintf (stderr, "\
466 %s: option `--%s' doesn't allow an argument\n",
467 argv[0], pfound->name);
468 #endif
469 }
470 else
471 {
472 /* +option or -option */
473 #if defined _LIBC && defined USE_IN_LIBIO
474 n = __asprintf (&buf, "\
475 %s: option `%c%s' doesn't allow an argument\n",
476 argv[0], argv[optind - 1][0],
477 pfound->name);
478 #else
479 fprintf (stderr, "\
480 %s: option `%c%s' doesn't allow an argument\n",
481 argv[0], argv[optind - 1][0], pfound->name);
482 #endif
483 }
484
485 #if defined _LIBC && defined USE_IN_LIBIO
486 if (n >= 0)
487 {
488 if (_IO_fwide (stderr, 0) > 0)
489 __fwprintf (stderr, L"%s", buf);
490 else
491 fputs (buf, stderr);
492
493 free (buf);
494 }
495 #endif
496 }
497
498 nextchar += strlen (nextchar);
499
500 optopt = pfound->val;
501 return '?';
502 }
503 }
504 else if (pfound->has_arg == 1)
505 {
506 if (optind < argc)
507 optarg = argv[optind++];
508 else
509 {
510 if (print_errors)
511 {
512 #if defined _LIBC && defined USE_IN_LIBIO
513 char *buf;
514
515 if (__asprintf (&buf, _("\
516 %s: option `%s' requires an argument\n"),
517 argv[0], argv[optind - 1]) >= 0)
518 {
519 if (_IO_fwide (stderr, 0) > 0)
520 __fwprintf (stderr, L"%s", buf);
521 else
522 fputs (buf, stderr);
523
524 free (buf);
525 }
526 #else
527 fprintf (stderr,
528 "%s: option `%s' requires an argument\n",
529 argv[0], argv[optind - 1]);
530 #endif
531 }
532 nextchar += strlen (nextchar);
533 optopt = pfound->val;
534 return optstring[0] == ':' ? ':' : '?';
535 }
536 }
537 nextchar += strlen (nextchar);
538 if (longind != NULL)
539 *longind = option_index;
540 if (pfound->flag)
541 {
542 *(pfound->flag) = pfound->val;
543 return 0;
544 }
545 return pfound->val;
546 }
547
548 /* Can't find it as a long option. If this is not getopt_long_only,
549 or the option starts with '--' or is not a valid short
550 option, then it's an error.
551 Otherwise interpret it as a short option. */
552 if (!long_only || argv[optind][1] == '-'
553 || my_index (optstring, *nextchar) == NULL)
554 {
555 if (print_errors)
556 {
557 #if defined _LIBC && defined USE_IN_LIBIO
558 char *buf;
559 int n;
560 #endif
561
562 if (argv[optind][1] == '-')
563 {
564 /* --option */
565 #if defined _LIBC && defined USE_IN_LIBIO
566 n = __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
567 argv[0], nextchar);
568 #else
569 fprintf (stderr, "%s: unrecognized option `--%s'\n",
570 argv[0], nextchar);
571 #endif
572 }
573 else
574 {
575 /* +option or -option */
576 #if defined _LIBC && defined USE_IN_LIBIO
577 n = __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
578 argv[0], argv[optind][0], nextchar);
579 #else
580 fprintf (stderr, "%s: unrecognized option `%c%s'\n",
581 argv[0], argv[optind][0], nextchar);
582 #endif
583 }
584
585 #if defined _LIBC && defined USE_IN_LIBIO
586 if (n >= 0)
587 {
588 if (_IO_fwide (stderr, 0) > 0)
589 __fwprintf (stderr, L"%s", buf);
590 else
591 fputs (buf, stderr);
592
593 free (buf);
594 }
595 #endif
596 }
597 nextchar = (char *) "";
598 optind++;
599 optopt = 0;
600 return '?';
601 }
602 }
603
604 /* Look at and handle the next short option-character. */
605
606 {
607 char c = *nextchar++;
608 char *temp = my_index (optstring, c);
609
610 /* Increment `optind' when we start to process its last character. */
611 if (*nextchar == '\0')
612 ++optind;
613
614 if (temp == NULL || c == ':')
615 {
616 if (print_errors)
617 {
618 #if defined _LIBC && defined USE_IN_LIBIO
619 char *buf;
620 int n;
621 #endif
622
623 if (posixly_correct)
624 {
625 /* 1003.2 specifies the format of this message. */
626 #if defined _LIBC && defined USE_IN_LIBIO
627 n = __asprintf (&buf, _("%s: illegal option -- %c\n"),
628 argv[0], c);
629 #else
630 fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
631 #endif
632 }
633 else
634 {
635 #if defined _LIBC && defined USE_IN_LIBIO
636 n = __asprintf (&buf, _("%s: invalid option -- %c\n"),
637 argv[0], c);
638 #else
639 fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
640 #endif
641 }
642
643 #if defined _LIBC && defined USE_IN_LIBIO
644 if (n >= 0)
645 {
646 if (_IO_fwide (stderr, 0) > 0)
647 __fwprintf (stderr, L"%s", buf);
648 else
649 fputs (buf, stderr);
650
651 free (buf);
652 }
653 #endif
654 }
655 optopt = c;
656 return '?';
657 }
658 /* Convenience. Treat POSIX -W foo same as long option --foo */
659 if (temp[0] == 'W' && temp[1] == ';')
660 {
661 char *nameend;
662 const struct option *p;
663 const struct option *pfound = NULL;
664 int exact = 0;
665 int ambig = 0;
666 int indfound = 0;
667 int option_index;
668
669 /* This is an option that requires an argument. */
670 if (*nextchar != '\0')
671 {
672 optarg = nextchar;
673 /* If we end this ARGV-element by taking the rest as an arg,
674 we must advance to the next element now. */
675 optind++;
676 }
677 else if (optind == argc)
678 {
679 if (print_errors)
680 {
681 /* 1003.2 specifies the format of this message. */
682 #if defined _LIBC && defined USE_IN_LIBIO
683 char *buf;
684
685 if (__asprintf (&buf,
686 _("%s: option requires an argument -- %c\n"),
687 argv[0], c) >= 0)
688 {
689 if (_IO_fwide (stderr, 0) > 0)
690 __fwprintf (stderr, L"%s", buf);
691 else
692 fputs (buf, stderr);
693
694 free (buf);
695 }
696 #else
697 fprintf (stderr, "%s: option requires an argument -- %c\n",
698 argv[0], c);
699 #endif
700 }
701 optopt = c;
702 if (optstring[0] == ':')
703 c = ':';
704 else
705 c = '?';
706 return c;
707 }
708 else
709 /* We already incremented `optind' once;
710 increment it again when taking next ARGV-elt as argument. */
711 optarg = argv[optind++];
712
713 /* optarg is now the argument, see if it's in the
714 table of longopts. */
715
716 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
717 /* Do nothing. */ ;
718
719 /* Test all long options for either exact match
720 or abbreviated matches. */
721 for (p = longopts, option_index = 0; p->name; p++, option_index++)
722 if (!strncmp (p->name, nextchar, nameend - nextchar))
723 {
724 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
725 {
726 /* Exact match found. */
727 pfound = p;
728 indfound = option_index;
729 exact = 1;
730 break;
731 }
732 else if (pfound == NULL)
733 {
734 /* First nonexact match found. */
735 pfound = p;
736 indfound = option_index;
737 }
738 else
739 /* Second or later nonexact match found. */
740 ambig = 1;
741 }
742 if (ambig && !exact)
743 {
744 if (print_errors)
745 {
746 #if defined _LIBC && defined USE_IN_LIBIO
747 char *buf;
748
749 if (__asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
750 argv[0], argv[optind]) >= 0)
751 {
752 if (_IO_fwide (stderr, 0) > 0)
753 __fwprintf (stderr, L"%s", buf);
754 else
755 fputs (buf, stderr);
756
757 free (buf);
758 }
759 #else
760 fprintf (stderr, "%s: option `-W %s' is ambiguous\n",
761 argv[0], argv[optind]);
762 #endif
763 }
764 nextchar += strlen (nextchar);
765 optind++;
766 return '?';
767 }
768 if (pfound != NULL)
769 {
770 option_index = indfound;
771 if (*nameend)
772 {
773 /* Don't test has_arg with >, because some C compilers don't
774 allow it to be used on enums. */
775 if (pfound->has_arg)
776 optarg = nameend + 1;
777 else
778 {
779 if (print_errors)
780 {
781 #if defined _LIBC && defined USE_IN_LIBIO
782 char *buf;
783
784 if (__asprintf (&buf, _("\
785 %s: option `-W %s' doesn't allow an argument\n"),
786 argv[0], pfound->name) >= 0)
787 {
788 if (_IO_fwide (stderr, 0) > 0)
789 __fwprintf (stderr, L"%s", buf);
790 else
791 fputs (buf, stderr);
792
793 free (buf);
794 }
795 #else
796 fprintf (stderr, "\
797 %s: option `-W %s' doesn't allow an argument\n",
798 argv[0], pfound->name);
799 #endif
800 }
801
802 nextchar += strlen (nextchar);
803 return '?';
804 }
805 }
806 else if (pfound->has_arg == 1)
807 {
808 if (optind < argc)
809 optarg = argv[optind++];
810 else
811 {
812 if (print_errors)
813 {
814 #if defined _LIBC && defined USE_IN_LIBIO
815 char *buf;
816
817 if (__asprintf (&buf, _("\
818 %s: option `%s' requires an argument\n"),
819 argv[0], argv[optind - 1]) >= 0)
820 {
821 if (_IO_fwide (stderr, 0) > 0)
822 __fwprintf (stderr, L"%s", buf);
823 else
824 fputs (buf, stderr);
825
826 free (buf);
827 }
828 #else
829 fprintf (stderr,
830 "%s: option `%s' requires an argument\n",
831 argv[0], argv[optind - 1]);
832 #endif
833 }
834 nextchar += strlen (nextchar);
835 return optstring[0] == ':' ? ':' : '?';
836 }
837 }
838 nextchar += strlen (nextchar);
839 if (longind != NULL)
840 *longind = option_index;
841 if (pfound->flag)
842 {
843 *(pfound->flag) = pfound->val;
844 return 0;
845 }
846 return pfound->val;
847 }
848 nextchar = NULL;
849 return 'W'; /* Let the application handle it. */
850 }
851 if (temp[1] == ':')
852 {
853 if (temp[2] == ':')
854 {
855 /* This is an option that accepts an argument optionally. */
856 if (*nextchar != '\0')
857 {
858 optarg = nextchar;
859 optind++;
860 }
861 else
862 optarg = NULL;
863 nextchar = NULL;
864 }
865 else
866 {
867 /* This is an option that requires an argument. */
868 if (*nextchar != '\0')
869 {
870 optarg = nextchar;
871 /* If we end this ARGV-element by taking the rest as an arg,
872 we must advance to the next element now. */
873 optind++;
874 }
875 else if (optind == argc)
876 {
877 if (print_errors)
878 {
879 /* 1003.2 specifies the format of this message. */
880 #if defined _LIBC && defined USE_IN_LIBIO
881 char *buf;
882
883 if (__asprintf (&buf, _("\
884 %s: option requires an argument -- %c\n"),
885 argv[0], c) >= 0)
886 {
887 if (_IO_fwide (stderr, 0) > 0)
888 __fwprintf (stderr, L"%s", buf);
889 else
890 fputs (buf, stderr);
891
892 free (buf);
893 }
894 #else
895 fprintf (stderr,
896 "%s: option requires an argument -- %c\n",
897 argv[0], c);
898 #endif
899 }
900 optopt = c;
901 if (optstring[0] == ':')
902 c = ':';
903 else
904 c = '?';
905 }
906 else
907 /* We already incremented `optind' once;
908 increment it again when taking next ARGV-elt as argument. */
909 optarg = argv[optind++];
910 nextchar = NULL;
911 }
912 }
913 return c;
914 }
915 }