ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/fcrackzip/getopt.c
Revision: 1.1
Committed: Mon Aug 4 07:09:51 2008 UTC (15 years, 9 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
initial check-in, also 1.0 check-in

File Contents

# Content
1 /* Getopt for GNU.
2 NOTE: getopt is now part of the C library, so if you don't know what
3 "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
4 before changing it!
5
6 Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 1996
7 Free Software Foundation, Inc.
8
9 This file is part of the GNU C Library. Its master source is NOT part of
10 the C library, however. The master source lives in /gd/gnu/lib.
11
12 The GNU C Library is free software; you can redistribute it and/or
13 modify it under the terms of the GNU Library General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 The GNU C Library is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 Library General Public License for more details.
21
22 You should have received a copy of the GNU Library General Public
23 License along with the GNU C Library; see the file COPYING.LIB. If
24 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
25 Cambridge, MA 02139, USA. */
26
27 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
28 Ditto for AIX 3.2 and <stdlib.h>. */
29 #ifndef _NO_PROTO
30 #define _NO_PROTO
31 #endif
32
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36
37 #if !defined (__STDC__) || !__STDC__
38 /* This is a separate conditional since some stdc systems
39 reject `defined (const)'. */
40 #ifndef const
41 #define const
42 #endif
43 #endif
44
45 #include <stdio.h>
46
47 /* Comment out all this code if we are using the GNU C Library, and are not
48 actually compiling the library itself. This code is part of the GNU C
49 Library, but also included in many other GNU distributions. Compiling
50 and linking in this code is a waste when using the GNU C library
51 (especially if it is a shared library). Rather than having every GNU
52 program understand `configure --with-gnu-libc' and omit the object files,
53 it is simpler to just do this in the source for each such file. */
54
55 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
56
57
58 /* This needs to come after some library #include
59 to get __GNU_LIBRARY__ defined. */
60 #ifdef __GNU_LIBRARY__
61 /* Don't include stdlib.h for non-GNU C libraries because some of them
62 contain conflicting prototypes for getopt. */
63 #include <stdlib.h>
64 #include <unistd.h>
65 #endif /* GNU C library. */
66
67 #ifdef VMS
68 #include <unixlib.h>
69 #if HAVE_STRING_H - 0
70 #include <string.h>
71 #endif
72 #endif
73
74 #if defined (WIN32) && !defined (__CYGWIN32__)
75 /* It's not Unix, really. See? Capital letters. */
76 #include <windows.h>
77 #define getpid() GetCurrentProcessId()
78 #endif
79
80 #define _(msgid) (msgid)
81 #define gettext(msgid) (msgid)
82
83 /* This version of `getopt' appears to the caller like standard Unix `getopt'
84 but it behaves differently for the user, since it allows the user
85 to intersperse the options with the other arguments.
86
87 As `getopt' works, it permutes the elements of ARGV so that,
88 when it is done, all the options precede everything else. Thus
89 all application programs are extended to handle flexible argument order.
90
91 Setting the environment variable POSIXLY_CORRECT disables permutation.
92 Then the behavior is completely standard.
93
94 GNU application programs can use a third alternative mode in which
95 they can distinguish the relative order of options and other arguments. */
96
97 #include "getopt.h"
98
99 /* For communication from `getopt' to the caller.
100 When `getopt' finds an option that takes an argument,
101 the argument value is returned here.
102 Also, when `ordering' is RETURN_IN_ORDER,
103 each non-option ARGV-element is returned here. */
104
105 char *optarg = NULL;
106
107 /* Index in ARGV of the next element to be scanned.
108 This is used for communication to and from the caller
109 and for communication between successive calls to `getopt'.
110
111 On entry to `getopt', zero means this is the first call; initialize.
112
113 When `getopt' returns EOF, this is the index of the first of the
114 non-option elements that the caller should itself scan.
115
116 Otherwise, `optind' communicates from one call to the next
117 how much of ARGV has been scanned so far. */
118
119 /* XXX 1003.2 says this must be 1 before any call. */
120 int optind = 0;
121
122 /* The next char to be scanned in the option-element
123 in which the last option character we returned was found.
124 This allows us to pick up the scan where we left off.
125
126 If this is zero, or a null string, it means resume the scan
127 by advancing to the next ARGV-element. */
128
129 static char *nextchar;
130
131 /* Callers store zero here to inhibit the error message
132 for unrecognized options. */
133
134 int opterr = 1;
135
136 /* Set to an option character which was unrecognized.
137 This must be initialized on some systems to avoid linking in the
138 system's own getopt implementation. */
139
140 int optopt = '?';
141
142 /* Describe how to deal with options that follow non-option ARGV-elements.
143
144 If the caller did not specify anything,
145 the default is REQUIRE_ORDER if the environment variable
146 POSIXLY_CORRECT is defined, PERMUTE otherwise.
147
148 REQUIRE_ORDER means don't recognize them as options;
149 stop option processing when the first non-option is seen.
150 This is what Unix does.
151 This mode of operation is selected by either setting the environment
152 variable POSIXLY_CORRECT, or using `+' as the first character
153 of the list of option characters.
154
155 PERMUTE is the default. We permute the contents of ARGV as we scan,
156 so that eventually all the non-options are at the end. This allows options
157 to be given in any order, even with programs that were not written to
158 expect this.
159
160 RETURN_IN_ORDER is an option available to programs that were written
161 to expect options and other ARGV-elements in any order and that care about
162 the ordering of the two. We describe each non-option ARGV-element
163 as if it were the argument of an option with character code 1.
164 Using `-' as the first character of the list of option characters
165 selects this mode of operation.
166
167 The special argument `--' forces an end of option-scanning regardless
168 of the value of `ordering'. In the case of RETURN_IN_ORDER, only
169 `--' can cause `getopt' to return EOF with `optind' != ARGC. */
170
171 static enum
172 {
173 REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
174 } ordering;
175
176 /* Value of POSIXLY_CORRECT environment variable. */
177 static char *posixly_correct;
178
179 #ifdef __GNU_LIBRARY__
180 /* We want to avoid inclusion of string.h with non-GNU libraries
181 because there are many ways it can cause trouble.
182 On some systems, it contains special magic macros that don't work
183 in GCC. */
184 #include <string.h>
185 #define my_index strchr
186 #else
187
188 /* Avoid depending on library functions or files
189 whose names are inconsistent. */
190
191 char *getenv ();
192
193 static char *
194 my_index (str, chr)
195 const char *str;
196 int chr;
197 {
198 while (*str)
199 {
200 if (*str == chr)
201 return (char *) str;
202 str++;
203 }
204 return 0;
205 }
206
207 /* If using GCC, we can safely declare strlen this way.
208 If not using GCC, it is ok not to declare it. */
209 #ifdef __GNUC__
210 /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
211 That was relevant to code that was here before. */
212 #if !defined (__STDC__) || !__STDC__
213 /* gcc with -traditional declares the built-in strlen to return int,
214 and has done so at least since version 2.4.5. -- rms. */
215 extern int strlen (const char *);
216 #endif /* not __STDC__ */
217 #endif /* __GNUC__ */
218
219 #endif /* not __GNU_LIBRARY__ */
220
221 /* Handle permutation of arguments. */
222
223 /* Describe the part of ARGV that contains non-options that have
224 been skipped. `first_nonopt' is the index in ARGV of the first of them;
225 `last_nonopt' is the index after the last of them. */
226
227 static int first_nonopt;
228 static int last_nonopt;
229
230 /* Bash 2.0 gives us an environment variable containing flags
231 indicating ARGV elements that should not be considered arguments. */
232
233 static const char *nonoption_flags;
234 static int nonoption_flags_len;
235
236 /* Exchange two adjacent subsequences of ARGV.
237 One subsequence is elements [first_nonopt,last_nonopt)
238 which contains all the non-options that have been skipped so far.
239 The other is elements [last_nonopt,optind), which contains all
240 the options processed since those non-options were skipped.
241
242 `first_nonopt' and `last_nonopt' are relocated so that they describe
243 the new indices of the non-options in ARGV after they are moved. */
244
245 #if defined (__STDC__) && __STDC__
246 static void exchange (char **);
247 #endif
248
249 static void
250 exchange (argv)
251 char **argv;
252 {
253 int bottom = first_nonopt;
254 int middle = last_nonopt;
255 int top = optind;
256 char *tem;
257
258 /* Exchange the shorter segment with the far end of the longer segment.
259 That puts the shorter segment into the right place.
260 It leaves the longer segment in the right place overall,
261 but it consists of two parts that need to be swapped next. */
262
263 while (top > middle && middle > bottom)
264 {
265 if (top - middle > middle - bottom)
266 {
267 /* Bottom segment is the short one. */
268 int len = middle - bottom;
269 register int i;
270
271 /* Swap it with the top part of the top segment. */
272 for (i = 0; i < len; i++)
273 {
274 tem = argv[bottom + i];
275 argv[bottom + i] = argv[top - (middle - bottom) + i];
276 argv[top - (middle - bottom) + i] = tem;
277 }
278 /* Exclude the moved bottom segment from further swapping. */
279 top -= len;
280 }
281 else
282 {
283 /* Top segment is the short one. */
284 int len = top - middle;
285 register int i;
286
287 /* Swap it with the bottom part of the bottom segment. */
288 for (i = 0; i < len; i++)
289 {
290 tem = argv[bottom + i];
291 argv[bottom + i] = argv[middle + i];
292 argv[middle + i] = tem;
293 }
294 /* Exclude the moved top segment from further swapping. */
295 bottom += len;
296 }
297 }
298
299 /* Update records for the slots the non-options now occupy. */
300
301 first_nonopt += (optind - last_nonopt);
302 last_nonopt = optind;
303 }
304
305 /* Initialize the internal data when the first call is made. */
306
307 #if defined (__STDC__) && __STDC__
308 static const char *_getopt_initialize (const char *);
309 #endif
310 static const char *
311 _getopt_initialize (optstring)
312 const char *optstring;
313 {
314 /* Start processing options with ARGV-element 1 (since ARGV-element 0
315 is the program name); the sequence of previously skipped
316 non-option ARGV-elements is empty. */
317
318 first_nonopt = last_nonopt = optind = 1;
319
320 nextchar = NULL;
321
322 posixly_correct = getenv ("POSIXLY_CORRECT");
323
324 /* Determine how to handle the ordering of options and nonoptions. */
325
326 if (optstring[0] == '-')
327 {
328 ordering = RETURN_IN_ORDER;
329 ++optstring;
330 }
331 else if (optstring[0] == '+')
332 {
333 ordering = REQUIRE_ORDER;
334 ++optstring;
335 }
336 else if (posixly_correct != NULL)
337 ordering = REQUIRE_ORDER;
338 else
339 ordering = PERMUTE;
340
341 if (posixly_correct == NULL)
342 {
343 /* Bash 2.0 puts a special variable in the environment for each
344 command it runs, specifying which ARGV elements are the results of
345 file name wildcard expansion and therefore should not be
346 considered as options. */
347 char var[100];
348 sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
349 nonoption_flags = getenv (var);
350 if (nonoption_flags == NULL)
351 nonoption_flags_len = 0;
352 else
353 nonoption_flags_len = strlen (nonoption_flags);
354 }
355
356 return optstring;
357 }
358
359 /* Scan elements of ARGV (whose length is ARGC) for option characters
360 given in OPTSTRING.
361
362 If an element of ARGV starts with '-', and is not exactly "-" or "--",
363 then it is an option element. The characters of this element
364 (aside from the initial '-') are option characters. If `getopt'
365 is called repeatedly, it returns successively each of the option characters
366 from each of the option elements.
367
368 If `getopt' finds another option character, it returns that character,
369 updating `optind' and `nextchar' so that the next call to `getopt' can
370 resume the scan with the following option character or ARGV-element.
371
372 If there are no more option characters, `getopt' returns `EOF'.
373 Then `optind' is the index in ARGV of the first ARGV-element
374 that is not an option. (The ARGV-elements have been permuted
375 so that those that are not options now come last.)
376
377 OPTSTRING is a string containing the legitimate option characters.
378 If an option character is seen that is not listed in OPTSTRING,
379 return '?' after printing an error message. If you set `opterr' to
380 zero, the error message is suppressed but we still return '?'.
381
382 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
383 so the following text in the same ARGV-element, or the text of the following
384 ARGV-element, is returned in `optarg'. Two colons mean an option that
385 wants an optional arg; if there is text in the current ARGV-element,
386 it is returned in `optarg', otherwise `optarg' is set to zero.
387
388 If OPTSTRING starts with `-' or `+', it requests different methods of
389 handling the non-option ARGV-elements.
390 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
391
392 Long-named options begin with `--' instead of `-'.
393 Their names may be abbreviated as long as the abbreviation is unique
394 or is an exact match for some defined option. If they have an
395 argument, it follows the option name in the same ARGV-element, separated
396 from the option name by a `=', or else the in next ARGV-element.
397 When `getopt' finds a long-named option, it returns 0 if that option's
398 `flag' field is nonzero, the value of the option's `val' field
399 if the `flag' field is zero.
400
401 The elements of ARGV aren't really const, because we permute them.
402 But we pretend they're const in the prototype to be compatible
403 with other systems.
404
405 LONGOPTS is a vector of `struct option' terminated by an
406 element containing a name which is zero.
407
408 LONGIND returns the index in LONGOPT of the long-named option found.
409 It is only valid when a long-named option has been found by the most
410 recent call.
411
412 If LONG_ONLY is nonzero, '-' as well as '--' can introduce
413 long-named options. */
414
415 int
416 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
417 int argc;
418 char *const *argv;
419 const char *optstring;
420 const struct option *longopts;
421 int *longind;
422 int long_only;
423 {
424 optarg = NULL;
425
426 if (optind == 0)
427 {
428 optstring = _getopt_initialize (optstring);
429 optind = 1; /* Don't scan ARGV[0], the program name. */
430 }
431
432 /* Test whether ARGV[optind] points to a non-option argument.
433 Either it does not have option syntax, or there is an environment flag
434 from the shell indicating it is not an option. */
435 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
436 || (optind < nonoption_flags_len \
437 && nonoption_flags[optind] == '1'))
438
439 if (nextchar == NULL || *nextchar == '\0')
440 {
441 /* Advance to the next ARGV-element. */
442
443 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
444 moved back by the user (who may also have changed the arguments). */
445 if (last_nonopt > optind)
446 last_nonopt = optind;
447 if (first_nonopt > optind)
448 first_nonopt = optind;
449
450 if (ordering == PERMUTE)
451 {
452 /* If we have just processed some options following some non-options,
453 exchange them so that the options come first. */
454
455 if (first_nonopt != last_nonopt && last_nonopt != optind)
456 exchange ((char **) argv);
457 else if (last_nonopt != optind)
458 first_nonopt = optind;
459
460 /* Skip any additional non-options
461 and extend the range of non-options previously skipped. */
462
463 while (optind < argc && NONOPTION_P)
464 optind++;
465 last_nonopt = optind;
466 }
467
468 /* The special ARGV-element `--' means premature end of options.
469 Skip it like a null option,
470 then exchange with previous non-options as if it were an option,
471 then skip everything else like a non-option. */
472
473 if (optind != argc && !strcmp (argv[optind], "--"))
474 {
475 optind++;
476
477 if (first_nonopt != last_nonopt && last_nonopt != optind)
478 exchange ((char **) argv);
479 else if (first_nonopt == last_nonopt)
480 first_nonopt = optind;
481 last_nonopt = argc;
482
483 optind = argc;
484 }
485
486 /* If we have done all the ARGV-elements, stop the scan
487 and back over any non-options that we skipped and permuted. */
488
489 if (optind == argc)
490 {
491 /* Set the next-arg-index to point at the non-options
492 that we previously skipped, so the caller will digest them. */
493 if (first_nonopt != last_nonopt)
494 optind = first_nonopt;
495 return EOF;
496 }
497
498 /* If we have come to a non-option and did not permute it,
499 either stop the scan or describe it to the caller and pass it by. */
500
501 if (NONOPTION_P)
502 {
503 if (ordering == REQUIRE_ORDER)
504 return EOF;
505 optarg = argv[optind++];
506 return 1;
507 }
508
509 /* We have found another option-ARGV-element.
510 Skip the initial punctuation. */
511
512 nextchar = (argv[optind] + 1
513 + (longopts != NULL && argv[optind][1] == '-'));
514 }
515
516 /* Decode the current option-ARGV-element. */
517
518 /* Check whether the ARGV-element is a long option.
519
520 If long_only and the ARGV-element has the form "-f", where f is
521 a valid short option, don't consider it an abbreviated form of
522 a long option that starts with f. Otherwise there would be no
523 way to give the -f short option.
524
525 On the other hand, if there's a long option "fubar" and
526 the ARGV-element is "-fu", do consider that an abbreviation of
527 the long option, just like "--fu", and not "-f" with arg "u".
528
529 This distinction seems to be the most useful approach. */
530
531 if (longopts != NULL
532 && (argv[optind][1] == '-'
533 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
534 {
535 char *nameend;
536 const struct option *p;
537 const struct option *pfound = NULL;
538 int exact = 0;
539 int ambig = 0;
540 int indfound = -1;
541 int option_index;
542
543 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
544 /* Do nothing. */ ;
545
546 /* Test all long options for either exact match
547 or abbreviated matches. */
548 for (p = longopts, option_index = 0; p->name; p++, option_index++)
549 if (!strncmp (p->name, nextchar, nameend - nextchar))
550 {
551 if ((unsigned int) (nameend - nextchar)
552 == (unsigned int) strlen (p->name))
553 {
554 /* Exact match found. */
555 pfound = p;
556 indfound = option_index;
557 exact = 1;
558 break;
559 }
560 else if (pfound == NULL)
561 {
562 /* First nonexact match found. */
563 pfound = p;
564 indfound = option_index;
565 }
566 else
567 /* Second or later nonexact match found. */
568 ambig = 1;
569 }
570
571 if (ambig && !exact)
572 {
573 if (opterr)
574 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
575 argv[0], argv[optind]);
576 nextchar += strlen (nextchar);
577 optind++;
578 optopt = 0;
579 return '?';
580 }
581
582 if (pfound != NULL)
583 {
584 option_index = indfound;
585 optind++;
586 if (*nameend)
587 {
588 /* Don't test has_arg with >, because some C compilers don't
589 allow it to be used on enums. */
590 if (pfound->has_arg)
591 optarg = nameend + 1;
592 else
593 {
594 if (opterr)
595 if (argv[optind - 1][1] == '-')
596 /* --option */
597 fprintf (stderr,
598 _("%s: option `--%s' doesn't allow an argument\n"),
599 argv[0], pfound->name);
600 else
601 /* +option or -option */
602 fprintf (stderr,
603 _("%s: option `%c%s' doesn't allow an argument\n"),
604 argv[0], argv[optind - 1][0], pfound->name);
605
606 nextchar += strlen (nextchar);
607
608 optopt = pfound->val;
609 return '?';
610 }
611 }
612 else if (pfound->has_arg == 1)
613 {
614 if (optind < argc)
615 optarg = argv[optind++];
616 else
617 {
618 if (opterr)
619 fprintf (stderr,
620 _("%s: option `%s' requires an argument\n"),
621 argv[0], argv[optind - 1]);
622 nextchar += strlen (nextchar);
623 optopt = pfound->val;
624 return optstring[0] == ':' ? ':' : '?';
625 }
626 }
627 nextchar += strlen (nextchar);
628 if (longind != NULL)
629 *longind = option_index;
630 if (pfound->flag)
631 {
632 *(pfound->flag) = pfound->val;
633 return 0;
634 }
635 return pfound->val;
636 }
637
638 /* Can't find it as a long option. If this is not getopt_long_only,
639 or the option starts with '--' or is not a valid short
640 option, then it's an error.
641 Otherwise interpret it as a short option. */
642 if (!long_only || argv[optind][1] == '-'
643 || my_index (optstring, *nextchar) == NULL)
644 {
645 if (opterr)
646 {
647 if (argv[optind][1] == '-')
648 /* --option */
649 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
650 argv[0], nextchar);
651 else
652 /* +option or -option */
653 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
654 argv[0], argv[optind][0], nextchar);
655 }
656 nextchar = (char *) "";
657 optind++;
658 optopt = 0;
659 return '?';
660 }
661 }
662
663 /* Look at and handle the next short option-character. */
664
665 {
666 char c = *nextchar++;
667 char *temp = my_index (optstring, c);
668
669 /* Increment `optind' when we start to process its last character. */
670 if (*nextchar == '\0')
671 ++optind;
672
673 if (temp == NULL || c == ':')
674 {
675 if (opterr)
676 {
677 if (posixly_correct)
678 /* 1003.2 specifies the format of this message. */
679 fprintf (stderr, _("%s: illegal option -- %c\n"),
680 argv[0], c);
681 else
682 fprintf (stderr, _("%s: invalid option -- %c\n"),
683 argv[0], c);
684 }
685 optopt = c;
686 return '?';
687 }
688 /* Convenience. Treat POSIX -W foo same as long option --foo */
689 if (temp[0] == 'W' && temp[1] == ';')
690 {
691 char *nameend;
692 const struct option *p;
693 const struct option *pfound = NULL;
694 int exact = 0;
695 int ambig = 0;
696 int indfound = 0;
697 int option_index;
698
699 /* This is an option that requires an argument. */
700 if (*nextchar != '\0')
701 {
702 optarg = nextchar;
703 /* If we end this ARGV-element by taking the rest as an arg,
704 we must advance to the next element now. */
705 optind++;
706 }
707 else if (optind == argc)
708 {
709 if (opterr)
710 {
711 /* 1003.2 specifies the format of this message. */
712 fprintf (stderr,
713 gettext ("%s: option requires an argument -- %c\n"),
714 argv[0], c);
715 }
716 optopt = c;
717 if (optstring[0] == ':')
718 c = ':';
719 else
720 c = '?';
721 }
722 else
723 /* We already incremented `optind' once;
724 increment it again when taking next ARGV-elt as argument. */
725 optarg = argv[optind++];
726
727 /* optarg is now the argument, see if it's in the
728 table of longopts. */
729
730 for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
731 /* Do nothing. */ ;
732
733 /* Test all long options for either exact match
734 or abbreviated matches. */
735 for (p = longopts, option_index = 0; p->name; p++, option_index++)
736 if (!strncmp (p->name, nextchar, nameend - nextchar))
737 {
738 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
739 {
740 /* Exact match found. */
741 pfound = p;
742 indfound = option_index;
743 exact = 1;
744 break;
745 }
746 else if (pfound == NULL)
747 {
748 /* First nonexact match found. */
749 pfound = p;
750 indfound = option_index;
751 }
752 else
753 /* Second or later nonexact match found. */
754 ambig = 1;
755 }
756 if (ambig && !exact)
757 {
758 if (opterr)
759 fprintf (stderr, gettext ("%s: option `-W %s' is ambiguous\n"),
760 argv[0], argv[optind]);
761 nextchar += strlen (nextchar);
762 optind++;
763 return '?';
764 }
765 if (pfound != NULL)
766 {
767 option_index = indfound;
768 if (*nameend)
769 {
770 /* Don't test has_arg with >, because some C compilers don't
771 allow it to be used on enums. */
772 if (pfound->has_arg)
773 optarg = nameend + 1;
774 else
775 {
776 if (opterr)
777 fprintf (stderr,
778 gettext ("%s: option `-W %s' doesn't allow an argument\n"),
779 argv[0], pfound->name);
780
781 nextchar += strlen (nextchar);
782 return '?';
783 }
784 }
785 else if (pfound->has_arg == 1)
786 {
787 if (optind < argc)
788 optarg = argv[optind++];
789 else
790 {
791 if (opterr)
792 fprintf (stderr,
793 gettext ("%s: option `%s' requires an argument\n"),
794 argv[0], argv[optind - 1]);
795 nextchar += strlen (nextchar);
796 return optstring[0] == ':' ? ':' : '?';
797 }
798 }
799 nextchar += strlen (nextchar);
800 if (longind != NULL)
801 *longind = option_index;
802 if (pfound->flag)
803 {
804 *(pfound->flag) = pfound->val;
805 return 0;
806 }
807 return pfound->val;
808 }
809 nextchar = NULL;
810 return 'W'; /* Let the application handle it. */
811 }
812 if (temp[1] == ':')
813 {
814 if (temp[2] == ':')
815 {
816 /* This is an option that accepts an argument optionally. */
817 if (*nextchar != '\0')
818 {
819 optarg = nextchar;
820 optind++;
821 }
822 else
823 optarg = NULL;
824 nextchar = NULL;
825 }
826 else
827 {
828 /* This is an option that requires an argument. */
829 if (*nextchar != '\0')
830 {
831 optarg = nextchar;
832 /* If we end this ARGV-element by taking the rest as an arg,
833 we must advance to the next element now. */
834 optind++;
835 }
836 else if (optind == argc)
837 {
838 if (opterr)
839 {
840 /* 1003.2 specifies the format of this message. */
841 fprintf (stderr,
842 _("%s: option requires an argument -- %c\n"),
843 argv[0], c);
844 }
845 optopt = c;
846 if (optstring[0] == ':')
847 c = ':';
848 else
849 c = '?';
850 }
851 else
852 /* We already incremented `optind' once;
853 increment it again when taking next ARGV-elt as argument. */
854 optarg = argv[optind++];
855 nextchar = NULL;
856 }
857 }
858 return c;
859 }
860 }
861
862 int
863 getopt (argc, argv, optstring)
864 int argc;
865 char *const *argv;
866 const char *optstring;
867 {
868 return _getopt_internal (argc, argv, optstring,
869 (const struct option *) 0,
870 (int *) 0,
871 0);
872 }
873
874 #endif /* _LIBC or not __GNU_LIBRARY__. */
875
876 #ifdef TEST
877
878 /* Compile with -DTEST to make an executable for use in testing
879 the above definition of `getopt'. */
880
881 int
882 main (argc, argv)
883 int argc;
884 char **argv;
885 {
886 int c;
887 int digit_optind = 0;
888
889 while (1)
890 {
891 int this_option_optind = optind ? optind : 1;
892
893 c = getopt (argc, argv, "abc:d:0123456789");
894 if (c == EOF)
895 break;
896
897 switch (c)
898 {
899 case '0':
900 case '1':
901 case '2':
902 case '3':
903 case '4':
904 case '5':
905 case '6':
906 case '7':
907 case '8':
908 case '9':
909 if (digit_optind != 0 && digit_optind != this_option_optind)
910 printf ("digits occur in two different argv-elements.\n");
911 digit_optind = this_option_optind;
912 printf ("option %c\n", c);
913 break;
914
915 case 'a':
916 printf ("option a\n");
917 break;
918
919 case 'b':
920 printf ("option b\n");
921 break;
922
923 case 'c':
924 printf ("option c with value `%s'\n", optarg);
925 break;
926
927 case '?':
928 break;
929
930 default:
931 printf ("?? getopt returned character code 0%o ??\n", c);
932 }
933 }
934
935 if (optind < argc)
936 {
937 printf ("non-option ARGV-elements: ");
938 while (optind < argc)
939 printf ("%s ", argv[optind++]);
940 printf ("\n");
941 }
942
943 exit (0);
944 }
945
946 #endif /* TEST */