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

# User Rev Content
1 root 1.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 */