OSDN Git Service

fixed unused warning
[uclinux-h8/uClibc.git] / libc / unistd / getopt.c
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 drepper@gnu.org
4    before changing it!
5    Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6         Free Software Foundation, Inc.
7    This file is part of the GNU C Library.
8
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13
14    The GNU C Library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307 USA.  */
23
24 /*
25  * Modified for uClibc by Manuel Novoa III on 1/5/01.
26  * Modified once again for uClibc by Erik Andersen 8/7/02
27  */
28
29 #include <features.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
34 #include <libintl.h>
35 #endif
36
37 #ifdef __UCLIBC_MJN3_ONLY__
38 #warning TODO: Enable gettext awareness.
39 #endif /* __UCLIBC_MJN3_ONLY__ */
40
41 #undef _
42 #define _(X)   X
43
44 /* Treat '-W foo' the same as the long option '--foo',
45  * disabled for the moment since it costs about 2k... */
46 #undef SPECIAL_TREATMENT_FOR_W
47
48 /* This version of `getopt' appears to the caller like standard Unix `getopt'
49    but it behaves differently for the user, since it allows the user
50    to intersperse the options with the other arguments.
51
52    As `getopt' works, it permutes the elements of ARGV so that,
53    when it is done, all the options precede everything else.  Thus
54    all application programs are extended to handle flexible argument order.
55
56    Setting the environment variable POSIXLY_CORRECT disables permutation.
57    Then the behavior is completely standard.
58
59    GNU application programs can use a third alternative mode in which
60    they can distinguish the relative order of options and other arguments.  */
61
62 #include "getopt.h"
63
64 extern int _getopt_internal (int argc, char *const *argv, const char *optstring, 
65         const struct option *longopts, int *longind, int long_only) attribute_hidden;
66
67
68 /* For communication from `getopt' to the caller.
69    When `getopt' finds an option that takes an argument,
70    the argument value is returned here.
71    Also, when `ordering' is RETURN_IN_ORDER,
72    each non-option ARGV-element is returned here.  */
73
74 char *optarg = NULL;
75
76 /* Index in ARGV of the next element to be scanned.
77    This is used for communication to and from the caller
78    and for communication between successive calls to `getopt'.
79
80    On entry to `getopt', zero means this is the first call; initialize.
81
82    When `getopt' returns -1, this is the index of the first of the
83    non-option elements that the caller should itself scan.
84
85    Otherwise, `optind' communicates from one call to the next
86    how much of ARGV has been scanned so far.  */
87
88 /* 1003.2 says this must be 1 before any call.  */
89 int optind = 1;
90
91 /* Callers store zero here to inhibit the error message
92    for unrecognized options.  */
93
94 int opterr = 1;
95
96 /* Set to an option character which was unrecognized.
97    This must be initialized on some systems to avoid linking in the
98    system's own getopt implementation.  */
99
100 int optopt = '?';
101
102 /* The next char to be scanned in the option-element
103    in which the last option character we returned was found.
104    This allows us to pick up the scan where we left off.
105
106    If this is zero, or a null string, it means resume the scan
107    by advancing to the next ARGV-element.  */
108
109 static char *nextchar;
110
111 /* Formerly, initialization of getopt depended on optind==0, which
112    causes problems with re-calling getopt as programs generally don't
113    know that. */
114
115 static int __getopt_initialized;
116
117 /* Describe how to deal with options that follow non-option ARGV-elements.
118
119    If the caller did not specify anything,
120    the default is REQUIRE_ORDER if the environment variable
121    POSIXLY_CORRECT is defined, PERMUTE otherwise.
122
123    REQUIRE_ORDER means don't recognize them as options;
124    stop option processing when the first non-option is seen.
125    This is what Unix does.
126    This mode of operation is selected by either setting the environment
127    variable POSIXLY_CORRECT, or using `+' as the first character
128    of the list of option characters.
129
130    PERMUTE is the default.  We permute the contents of ARGV as we scan,
131    so that eventually all the non-options are at the end.  This allows options
132    to be given in any order, even with programs that were not written to
133    expect this.
134
135    RETURN_IN_ORDER is an option available to programs that were written
136    to expect options and other ARGV-elements in any order and that care about
137    the ordering of the two.  We describe each non-option ARGV-element
138    as if it were the argument of an option with character code 1.
139    Using `-' as the first character of the list of option characters
140    selects this mode of operation.
141
142    The special argument `--' forces an end of option-scanning regardless
143    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
144    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
145
146 static enum
147 {
148   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
149 } ordering;
150
151 # include <string.h>
152 # define my_index       __strchr
153 \f
154 /* Handle permutation of arguments.  */
155
156 /* Describe the part of ARGV that contains non-options that have
157    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
158    `last_nonopt' is the index after the last of them.  */
159
160 static int first_nonopt;
161 static int last_nonopt;
162
163 /* Exchange two adjacent subsequences of ARGV.
164    One subsequence is elements [first_nonopt,last_nonopt)
165    which contains all the non-options that have been skipped so far.
166    The other is elements [last_nonopt,optind), which contains all
167    the options processed since those non-options were skipped.
168
169    `first_nonopt' and `last_nonopt' are relocated so that they describe
170    the new indices of the non-options in ARGV after they are moved.  */
171
172 static void exchange (char **argv)
173 {
174     int bottom = first_nonopt;
175     int middle = last_nonopt;
176     int top = optind;
177     char *tem;
178
179     /* Exchange the shorter segment with the far end of the longer segment.
180        That puts the shorter segment into the right place.
181        It leaves the longer segment in the right place overall,
182        but it consists of two parts that need to be swapped next.  */
183
184     while (top > middle && middle > bottom)
185     {
186         if (top - middle > middle - bottom)
187         {
188             /* Bottom segment is the short one.  */
189             int len = middle - bottom;
190             register int i;
191
192             /* Swap it with the top part of the top segment.  */
193             for (i = 0; i < len; i++)
194             {
195                 tem = argv[bottom + i];
196                 argv[bottom + i] = argv[top - (middle - bottom) + i];
197                 argv[top - (middle - bottom) + i] = tem;
198             }
199             /* Exclude the moved bottom segment from further swapping.  */
200             top -= len;
201         }
202         else
203         {
204             /* Top segment is the short one.  */
205             int len = top - middle;
206             register int i;
207
208             /* Swap it with the bottom part of the bottom segment.  */
209             for (i = 0; i < len; i++)
210             {
211                 tem = argv[bottom + i];
212                 argv[bottom + i] = argv[middle + i];
213                 argv[middle + i] = tem;
214             }
215             /* Exclude the moved top segment from further swapping.  */
216             bottom += len;
217         }
218     }
219
220     /* Update records for the slots the non-options now occupy.  */
221
222     first_nonopt += (optind - last_nonopt);
223     last_nonopt = optind;
224 }
225
226 /* Initialize the internal data when the first call is made.  */
227
228 static const char *_getopt_initialize (attribute_unused int argc, attribute_unused char *const * argv, const char *optstring)
229 {
230     /* Start processing options with ARGV-element 1 (since ARGV-element 0
231        is the program name); the sequence of previously skipped
232        non-option ARGV-elements is empty.  */
233
234     first_nonopt = last_nonopt = optind;
235
236     nextchar = NULL;
237
238     /* Determine how to handle the ordering of options and nonoptions.  */
239
240     if (optstring[0] == '-')
241     {
242         ordering = RETURN_IN_ORDER;
243         ++optstring;
244     }
245     else if (optstring[0] == '+')
246     {
247         ordering = REQUIRE_ORDER;
248         ++optstring;
249     }
250     else if (__getenv ("POSIXLY_CORRECT") != NULL)
251         ordering = REQUIRE_ORDER;
252     else
253         ordering = PERMUTE;
254
255     return optstring;
256 }
257 \f
258 /* Scan elements of ARGV (whose length is ARGC) for option characters
259    given in OPTSTRING.
260
261    If an element of ARGV starts with '-', and is not exactly "-" or "--",
262    then it is an option element.  The characters of this element
263    (aside from the initial '-') are option characters.  If `getopt'
264    is called repeatedly, it returns successively each of the option characters
265    from each of the option elements.
266
267    If `getopt' finds another option character, it returns that character,
268    updating `optind' and `nextchar' so that the next call to `getopt' can
269    resume the scan with the following option character or ARGV-element.
270
271    If there are no more option characters, `getopt' returns -1.
272    Then `optind' is the index in ARGV of the first ARGV-element
273    that is not an option.  (The ARGV-elements have been permuted
274    so that those that are not options now come last.)
275
276    OPTSTRING is a string containing the legitimate option characters.
277    If an option character is seen that is not listed in OPTSTRING,
278    return '?' after printing an error message.  If you set `opterr' to
279    zero, the error message is suppressed but we still return '?'.
280
281    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
282    so the following text in the same ARGV-element, or the text of the following
283    ARGV-element, is returned in `optarg'.  Two colons mean an option that
284    wants an optional arg; if there is text in the current ARGV-element,
285    it is returned in `optarg', otherwise `optarg' is set to zero.
286
287    If OPTSTRING starts with `-' or `+', it requests different methods of
288    handling the non-option ARGV-elements.
289    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
290
291    Long-named options begin with `--' instead of `-'.
292    Their names may be abbreviated as long as the abbreviation is unique
293    or is an exact match for some defined option.  If they have an
294    argument, it follows the option name in the same ARGV-element, separated
295    from the option name by a `=', or else the in next ARGV-element.
296    When `getopt' finds a long-named option, it returns 0 if that option's
297    `flag' field is nonzero, the value of the option's `val' field
298    if the `flag' field is zero.
299
300    The elements of ARGV aren't really const, because we permute them.
301    But we pretend they're const in the prototype to be compatible
302    with other systems.
303
304    LONGOPTS is a vector of `struct option' terminated by an
305    element containing a name which is zero.
306
307    LONGIND returns the index in LONGOPT of the long-named option found.
308    It is only valid when a long-named option has been found by the most
309    recent call.
310
311    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
312    long-named options.  */
313
314 int attribute_hidden _getopt_internal (int argc, char *const *argv, const char *optstring, 
315         const struct option *longopts, int *longind, int long_only)
316 {
317     int print_errors = opterr;
318     if (optstring[0] == ':')
319         print_errors = 0;
320
321     if (argc < 1)
322         return -1;
323
324     optarg = NULL;
325
326     if (optind == 0 || !__getopt_initialized)
327     {
328         if (optind == 0)
329             optind = 1; /* Don't scan ARGV[0], the program name.  */
330         optstring = _getopt_initialize (argc, argv, optstring);
331         __getopt_initialized = 1;
332     }
333
334     /* Test whether ARGV[optind] points to a non-option argument.
335        Either it does not have option syntax, or there is an environment flag
336        from the shell indicating it is not an option.  The later information
337        is only used when the used in the GNU libc.  */
338 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
339
340     if (nextchar == NULL || *nextchar == '\0')
341     {
342         /* Advance to the next ARGV-element.  */
343
344         /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
345            moved back by the user (who may also have changed the arguments).  */
346         if (last_nonopt > optind)
347             last_nonopt = optind;
348         if (first_nonopt > optind)
349             first_nonopt = optind;
350
351         if (ordering == PERMUTE)
352         {
353             /* If we have just processed some options following some non-options,
354                exchange them so that the options come first.  */
355
356             if (first_nonopt != last_nonopt && last_nonopt != optind)
357                 exchange ((char **) argv);
358             else if (last_nonopt != optind)
359                 first_nonopt = optind;
360
361             /* Skip any additional non-options
362                and extend the range of non-options previously skipped.  */
363
364             while (optind < argc && NONOPTION_P)
365                 optind++;
366             last_nonopt = optind;
367         }
368
369         /* The special ARGV-element `--' means premature end of options.
370            Skip it like a null option,
371            then exchange with previous non-options as if it were an option,
372            then skip everything else like a non-option.  */
373
374         if (optind != argc && !__strcmp (argv[optind], "--"))
375         {
376             optind++;
377
378             if (first_nonopt != last_nonopt && last_nonopt != optind)
379                 exchange ((char **) argv);
380             else if (first_nonopt == last_nonopt)
381                 first_nonopt = optind;
382             last_nonopt = argc;
383
384             optind = argc;
385         }
386
387         /* If we have done all the ARGV-elements, stop the scan
388            and back over any non-options that we skipped and permuted.  */
389
390         if (optind == argc)
391         {
392             /* Set the next-arg-index to point at the non-options
393                that we previously skipped, so the caller will digest them.  */
394             if (first_nonopt != last_nonopt)
395                 optind = first_nonopt;
396             return -1;
397         }
398
399         /* If we have come to a non-option and did not permute it,
400            either stop the scan or describe it to the caller and pass it by.  */
401
402         if (NONOPTION_P)
403         {
404             if (ordering == REQUIRE_ORDER)
405                 return -1;
406             optarg = argv[optind++];
407             return 1;
408         }
409
410         /* We have found another option-ARGV-element.
411            Skip the initial punctuation.  */
412
413         nextchar = (argv[optind] + 1
414                 + (longopts != NULL && argv[optind][1] == '-'));
415     }
416
417     /* Decode the current option-ARGV-element.  */
418
419     /* Check whether the ARGV-element is a long option.
420
421        If long_only and the ARGV-element has the form "-f", where f is
422        a valid short option, don't consider it an abbreviated form of
423        a long option that starts with f.  Otherwise there would be no
424        way to give the -f short option.
425
426        On the other hand, if there's a long option "fubar" and
427        the ARGV-element is "-fu", do consider that an abbreviation of
428        the long option, just like "--fu", and not "-f" with arg "u".
429
430        This distinction seems to be the most useful approach.  */
431
432     if (longopts != NULL
433             && (argv[optind][1] == '-'
434                 || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
435     {
436         char *nameend;
437         const struct option *p;
438         const struct option *pfound = NULL;
439         int exact = 0;
440         int ambig = 0;
441         int indfound = -1;
442         int option_index;
443
444         for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
445             /* Do nothing.  */ ;
446
447         /* Test all long options for either exact match
448            or abbreviated matches.  */
449         for (p = longopts, option_index = 0; p->name; p++, option_index++)
450             if (!__strncmp (p->name, nextchar, nameend - nextchar))
451             {
452                 if ((unsigned int) (nameend - nextchar)
453                         == (unsigned int) __strlen (p->name))
454                 {
455                     /* Exact match found.  */
456                     pfound = p;
457                     indfound = option_index;
458                     exact = 1;
459                     break;
460                 }
461                 else if (pfound == NULL)
462                 {
463                     /* First nonexact match found.  */
464                     pfound = p;
465                     indfound = option_index;
466                 }
467                 else if (long_only
468                         || pfound->has_arg != p->has_arg
469                         || pfound->flag != p->flag
470                         || pfound->val != p->val)
471                     /* Second or later nonexact match found.  */
472                     ambig = 1;
473             }
474
475         if (ambig && !exact)
476         {
477             if (print_errors)
478             {
479                 fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
480                         argv[0], argv[optind]);
481             }
482             nextchar += __strlen (nextchar);
483             optind++;
484             optopt = 0;
485             return '?';
486         }
487
488         if (pfound != NULL)
489         {
490             option_index = indfound;
491             optind++;
492             if (*nameend)
493             {
494                 /* Don't test has_arg with >, because some C compilers don't
495                    allow it to be used on enums.  */
496                 if (pfound->has_arg)
497                     optarg = nameend + 1;
498                 else
499                 {
500                     if (print_errors)
501                     {
502
503                         if (argv[optind - 1][1] == '-')
504                         {
505                             /* --option */
506                             fprintf (stderr, _("\
507                                         %s: option `--%s' doesn't allow an argument\n"),
508                                     argv[0], pfound->name);
509                         }
510                         else
511                         {
512                             /* +option or -option */
513                             fprintf (stderr, _("\
514                                         %s: option `%c%s' doesn't allow an argument\n"),
515                                     argv[0], argv[optind - 1][0], pfound->name);
516                         }
517
518                     }
519
520                     nextchar += __strlen (nextchar);
521
522                     optopt = pfound->val;
523                     return '?';
524                 }
525             }
526             else if (pfound->has_arg == 1)
527             {
528                 if (optind < argc)
529                     optarg = argv[optind++];
530                 else
531                 {
532                     if (print_errors)
533                     {
534                         fprintf (stderr,
535                                 _("%s: option `%s' requires an argument\n"),
536                                 argv[0], argv[optind - 1]);
537                     }
538                     nextchar += __strlen (nextchar);
539                     optopt = pfound->val;
540                     return optstring[0] == ':' ? ':' : '?';
541                 }
542             }
543             nextchar += __strlen (nextchar);
544             if (longind != NULL)
545                 *longind = option_index;
546             if (pfound->flag)
547             {
548                 *(pfound->flag) = pfound->val;
549                 return 0;
550             }
551             return pfound->val;
552         }
553
554         /* Can't find it as a long option.  If this is not getopt_long_only,
555            or the option starts with '--' or is not a valid short
556            option, then it's an error.
557            Otherwise interpret it as a short option.  */
558         if (!long_only || argv[optind][1] == '-'
559                 || my_index (optstring, *nextchar) == NULL)
560         {
561             if (print_errors)
562             {
563
564                 if (argv[optind][1] == '-')
565                 {
566                     /* --option */
567                     fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
568                             argv[0], nextchar);
569                 }
570                 else
571                 {
572                     /* +option or -option */
573                     fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
574                             argv[0], argv[optind][0], nextchar);
575                 }
576
577             }
578             nextchar = (char *) "";
579             optind++;
580             optopt = 0;
581             return '?';
582         }
583     }
584
585     /* Look at and handle the next short option-character.  */
586
587     {
588         char c = *nextchar++;
589         char *temp = my_index (optstring, c);
590
591         /* Increment `optind' when we start to process its last character.  */
592         if (*nextchar == '\0')
593             ++optind;
594
595         if (temp == NULL || c == ':')
596         {
597             if (print_errors)
598             {
599                     /* 1003.2 specifies the format of this message.  */
600                     fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
601             }
602             optopt = c;
603             return '?';
604         }
605 #ifdef SPECIAL_TREATMENT_FOR_W
606         /* Convenience. Treat POSIX -W foo same as long option --foo */
607         if (temp[0] == 'W' && temp[1] == ';')
608         {
609             char *nameend;
610             const struct option *p;
611             const struct option *pfound = NULL;
612             int exact = 0;
613             int ambig = 0;
614             int indfound = 0;
615             int option_index;
616
617             /* This is an option that requires an argument.  */
618             if (*nextchar != '\0')
619             {
620                 optarg = nextchar;
621                 /* If we end this ARGV-element by taking the rest as an arg,
622                    we must advance to the next element now.  */
623                 optind++;
624             }
625             else if (optind == argc)
626             {
627                 if (print_errors)
628                 {
629                     /* 1003.2 specifies the format of this message.  */
630                     fprintf (stderr, _("%s: option requires an argument -- %c\n"),
631                             argv[0], c);
632                 }
633                 optopt = c;
634                 if (optstring[0] == ':')
635                     c = ':';
636                 else
637                     c = '?';
638                 return c;
639             }
640             else
641                 /* We already incremented `optind' once;
642                    increment it again when taking next ARGV-elt as argument.  */
643                 optarg = argv[optind++];
644
645             /* optarg is now the argument, see if it's in the
646                table of longopts.  */
647
648             for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
649                 /* Do nothing.  */ ;
650
651             /* Test all long options for either exact match
652                or abbreviated matches.  */
653             for (p = longopts, option_index = 0; p->name; p++, option_index++)
654                 if (!__strncmp (p->name, nextchar, nameend - nextchar))
655                 {
656                     if ((unsigned int) (nameend - nextchar) == __strlen (p->name))
657                     {
658                         /* Exact match found.  */
659                         pfound = p;
660                         indfound = option_index;
661                         exact = 1;
662                         break;
663                     }
664                     else if (pfound == NULL)
665                     {
666                         /* First nonexact match found.  */
667                         pfound = p;
668                         indfound = option_index;
669                     }
670                     else
671                         /* Second or later nonexact match found.  */
672                         ambig = 1;
673                 }
674             if (ambig && !exact)
675             {
676                 if (print_errors)
677                 {
678                     fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
679                             argv[0], argv[optind]);
680                 }
681                 nextchar += __strlen (nextchar);
682                 optind++;
683                 return '?';
684             }
685             if (pfound != NULL)
686             {
687                 option_index = indfound;
688                 if (*nameend)
689                 {
690                     /* Don't test has_arg with >, because some C compilers don't
691                        allow it to be used on enums.  */
692                     if (pfound->has_arg)
693                         optarg = nameend + 1;
694                     else
695                     {
696                         if (print_errors)
697                         {
698                             fprintf (stderr, _("\
699                                         %s: option `-W %s' doesn't allow an argument\n"),
700                                     argv[0], pfound->name);
701                         }
702
703                         nextchar += __strlen (nextchar);
704                         return '?';
705                     }
706                 }
707                 else if (pfound->has_arg == 1)
708                 {
709                     if (optind < argc)
710                         optarg = argv[optind++];
711                     else
712                     {
713                         if (print_errors)
714                         {
715                             fprintf (stderr,
716                                     _("%s: option `%s' requires an argument\n"),
717                                     argv[0], argv[optind - 1]);
718                         }
719                         nextchar += __strlen (nextchar);
720                         return optstring[0] == ':' ? ':' : '?';
721                     }
722                 }
723                 nextchar += __strlen (nextchar);
724                 if (longind != NULL)
725                     *longind = option_index;
726                 if (pfound->flag)
727                 {
728                     *(pfound->flag) = pfound->val;
729                     return 0;
730                 }
731                 return pfound->val;
732             }
733             nextchar = NULL;
734             return 'W'; /* Let the application handle it.   */
735         }
736 #endif
737         if (temp[1] == ':')
738         {
739             if (temp[2] == ':')
740             {
741                 /* This is an option that accepts an argument optionally.  */
742                 if (*nextchar != '\0')
743                 {
744                     optarg = nextchar;
745                     optind++;
746                 }
747                 else
748                     optarg = NULL;
749                 nextchar = NULL;
750             }
751             else
752             {
753                 /* This is an option that requires an argument.  */
754                 if (*nextchar != '\0')
755                 {
756                     optarg = nextchar;
757                     /* If we end this ARGV-element by taking the rest as an arg,
758                        we must advance to the next element now.  */
759                     optind++;
760                 }
761                 else if (optind == argc)
762                 {
763                     if (print_errors)
764                     {
765                         /* 1003.2 specifies the format of this message.  */
766                         fprintf (stderr,
767                                 _("%s: option requires an argument -- %c\n"),
768                                 argv[0], c);
769                     }
770                     optopt = c;
771                     if (optstring[0] == ':')
772                         c = ':';
773                     else
774                         c = '?';
775                 }
776                 else
777                     /* We already incremented `optind' once;
778                        increment it again when taking next ARGV-elt as argument.  */
779                     optarg = argv[optind++];
780                 nextchar = NULL;
781             }
782         }
783         return c;
784     }
785 }
786
787 int getopt (int argc, char *const *argv, const char *optstring)
788 {
789     return _getopt_internal (argc, argv, optstring, 
790             (const struct option *) 0, (int *) 0, 0);
791 }
792
793 int getopt_long (int argc, char *const *argv, const char *options, 
794         const struct option *long_options, int *opt_index)
795 {
796     return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
797 }
798
799 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
800    If an option that starts with '-' (not '--') doesn't match a long option,
801    but does match a short option, it is parsed as a short option
802    instead.  */
803
804 int getopt_long_only (int argc, char *const *argv, const char *options, 
805         const struct option *long_options, int *opt_index)
806 {
807     return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
808 }
809