]> sjero.net Git - wget/blob - src/getopt.c
[svn] Initial revision
[wget] / src / 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 roland@gnu.ai.mit.edu
4    before changing it!
5
6    Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
7            Free Software Foundation, Inc.
8
9    This program is free software; you can redistribute it and/or modify it
10    under the terms of the GNU General Public License as published by the
11    Free Software Foundation; either version 2, or (at your option) any
12    later version.
13
14    This program 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
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
22
23
24 \f
25 /* NOTE!!!  AIX requires this to be the first thing in the file.
26    Do not put ANYTHING before it!  */
27
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif /* HAVE_CONFIG_H */
31 #include "wget.h"
32
33 #if !__STDC__ && !defined(const) && IN_GCC
34 #define const
35 #endif
36
37 /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.  */
38 #ifndef _NO_PROTO
39 #define _NO_PROTO
40 #endif
41
42 #include <stdio.h>
43 #ifdef HAVE_STRING_H
44 # include <string.h>
45 #else
46 # include <strings.h>
47 #endif
48
49 /* Comment out all this code if we are using the GNU C Library, and are not
50    actually compiling the library itself.  This code is part of the GNU C
51    Library, but also included in many other GNU distributions.  Compiling
52    and linking in this code is a waste when using the GNU C library
53    (especially if it is a shared library).  Rather than having every GNU
54    program understand `configure --with-gnu-libc' and omit the object files,
55    it is simpler to just do this in the source for each such file.  */
56
57 #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
58
59
60 #include <stdlib.h>
61
62 /* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
63    long-named option.  Because this is not POSIX.2 compliant, it is
64    being phased out.  */
65 /* #define GETOPT_COMPAT */
66
67 /* This version of `getopt' appears to the caller like standard Unix `getopt'
68    but it behaves differently for the user, since it allows the user
69    to intersperse the options with the other arguments.
70
71    As `getopt' works, it permutes the elements of ARGV so that,
72    when it is done, all the options precede everything else.  Thus
73    all application programs are extended to handle flexible argument order.
74
75    Setting the environment variable POSIXLY_CORRECT disables permutation.
76    Then the behavior is completely standard.
77
78    GNU application programs can use a third alternative mode in which
79    they can distinguish the relative order of options and other arguments.  */
80
81 #include "getopt.h"
82
83 /* For communication from `getopt' to the caller.
84    When `getopt' finds an option that takes an argument,
85    the argument value is returned here.
86    Also, when `ordering' is RETURN_IN_ORDER,
87    each non-option ARGV-element is returned here.  */
88
89 char *optarg = 0;
90
91 /* Index in ARGV of the next element to be scanned.
92    This is used for communication to and from the caller
93    and for communication between successive calls to `getopt'.
94
95    On entry to `getopt', zero means this is the first call; initialize.
96
97    When `getopt' returns EOF, this is the index of the first of the
98    non-option elements that the caller should itself scan.
99
100    Otherwise, `optind' communicates from one call to the next
101    how much of ARGV has been scanned so far.  */
102
103 /* XXX 1003.2 says this must be 1 before any call.  */
104 int optind = 0;
105
106 /* The next char to be scanned in the option-element
107    in which the last option character we returned was found.
108    This allows us to pick up the scan where we left off.
109
110    If this is zero, or a null string, it means resume the scan
111    by advancing to the next ARGV-element.  */
112
113 static char *nextchar;
114
115 /* Callers store zero here to inhibit the error message
116    for unrecognized options.  */
117
118 int opterr = 1;
119
120 /* Set to an option character which was unrecognized.
121    This must be initialized on some systems to avoid linking in the
122    system's own getopt implementation.  */
123
124 int optopt = '?';
125
126 /* Describe how to deal with options that follow non-option ARGV-elements.
127
128    If the caller did not specify anything,
129    the default is REQUIRE_ORDER if the environment variable
130    POSIXLY_CORRECT is defined, PERMUTE otherwise.
131
132    REQUIRE_ORDER means don't recognize them as options;
133    stop option processing when the first non-option is seen.
134    This is what Unix does.
135    This mode of operation is selected by either setting the environment
136    variable POSIXLY_CORRECT, or using `+' as the first character
137    of the list of option characters.
138
139    PERMUTE is the default.  We permute the contents of ARGV as we scan,
140    so that eventually all the non-options are at the end.  This allows options
141    to be given in any order, even with programs that were not written to
142    expect this.
143
144    RETURN_IN_ORDER is an option available to programs that were written
145    to expect options and other ARGV-elements in any order and that care about
146    the ordering of the two.  We describe each non-option ARGV-element
147    as if it were the argument of an option with character code 1.
148    Using `-' as the first character of the list of option characters
149    selects this mode of operation.
150
151    The special argument `--' forces an end of option-scanning regardless
152    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
153    `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
154
155 static enum
156 {
157   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
158 } ordering;
159 \f
160 #ifdef        __GNU_LIBRARY__
161 /* We want to avoid inclusion of string.h with non-GNU libraries
162    because there are many ways it can cause trouble.
163    On some systems, it contains special magic macros that don't work
164    in GCC.  */
165 #include <string.h>
166 #define        my_index        strchr
167 #define        my_bcopy(src, dst, n)        memcpy ((dst), (src), (n))
168 #else
169
170 /* Avoid depending on library functions or files
171    whose names are inconsistent.  */
172
173 char *getenv ();
174
175 static char *
176 my_index (const char *str, int chr)
177 {
178   while (*str)
179     {
180       if (*str == chr)
181         return (char *) str;
182       str++;
183     }
184   return 0;
185 }
186
187 static void
188 my_bcopy (const char *from, char *to, int size)
189 {
190   int i;
191   for (i = 0; i < size; i++)
192     to[i] = from[i];
193 }
194 #endif                                /* GNU C library.  */
195 \f
196 /* Handle permutation of arguments.  */
197
198 /* Describe the part of ARGV that contains non-options that have
199    been skipped.  `first_nonopt' is the index in ARGV of the first of them;
200    `last_nonopt' is the index after the last of them.  */
201
202 static int first_nonopt;
203 static int last_nonopt;
204
205 /* Exchange two adjacent subsequences of ARGV.
206    One subsequence is elements [first_nonopt,last_nonopt)
207    which contains all the non-options that have been skipped so far.
208    The other is elements [last_nonopt,optind), which contains all
209    the options processed since those non-options were skipped.
210
211    `first_nonopt' and `last_nonopt' are relocated so that they describe
212    the new indices of the non-options in ARGV after they are moved.  */
213
214 static void
215 exchange (char **argv)
216 {
217   int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
218   char **temp = (char **) alloca (nonopts_size);
219
220   /* Interchange the two blocks of data in ARGV.  */
221
222   my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size);
223   my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt],
224             (optind - last_nonopt) * sizeof (char *));
225   my_bcopy ((char *) temp,
226             (char *) &argv[first_nonopt + optind - last_nonopt],
227             nonopts_size);
228
229   /* Update records for the slots the non-options now occupy.  */
230
231   first_nonopt += (optind - last_nonopt);
232   last_nonopt = optind;
233 }
234 \f
235 /* Scan elements of ARGV (whose length is ARGC) for option characters
236    given in OPTSTRING.
237
238    If an element of ARGV starts with '-', and is not exactly "-" or "--",
239    then it is an option element.  The characters of this element
240    (aside from the initial '-') are option characters.  If `getopt'
241    is called repeatedly, it returns successively each of the option characters
242    from each of the option elements.
243
244    If `getopt' finds another option character, it returns that character,
245    updating `optind' and `nextchar' so that the next call to `getopt' can
246    resume the scan with the following option character or ARGV-element.
247
248    If there are no more option characters, `getopt' returns `EOF'.
249    Then `optind' is the index in ARGV of the first ARGV-element
250    that is not an option.  (The ARGV-elements have been permuted
251    so that those that are not options now come last.)
252
253    OPTSTRING is a string containing the legitimate option characters.
254    If an option character is seen that is not listed in OPTSTRING,
255    return '?' after printing an error message.  If you set `opterr' to
256    zero, the error message is suppressed but we still return '?'.
257
258    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
259    so the following text in the same ARGV-element, or the text of the following
260    ARGV-element, is returned in `optarg'.  Two colons mean an option that
261    wants an optional arg; if there is text in the current ARGV-element,
262    it is returned in `optarg', otherwise `optarg' is set to zero.
263
264    If OPTSTRING starts with `-' or `+', it requests different methods of
265    handling the non-option ARGV-elements.
266    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
267
268    Long-named options begin with `--' instead of `-'.
269    Their names may be abbreviated as long as the abbreviation is unique
270    or is an exact match for some defined option.  If they have an
271    argument, it follows the option name in the same ARGV-element, separated
272    from the option name by a `=', or else the in next ARGV-element.
273    When `getopt' finds a long-named option, it returns 0 if that option's
274    `flag' field is nonzero, the value of the option's `val' field
275    if the `flag' field is zero.
276
277    The elements of ARGV aren't really const, because we permute them.
278    But we pretend they're const in the prototype to be compatible
279    with other systems.
280
281    LONGOPTS is a vector of `struct option' terminated by an
282    element containing a name which is zero.
283
284    LONGIND returns the index in LONGOPT of the long-named option found.
285    It is only valid when a long-named option has been found by the most
286    recent call.
287
288    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
289    long-named options.  */
290
291 int
292 _getopt_internal (int argc, char *const *argv, const char *optstring,
293                   const struct option *longopts, int *longind, int long_only)
294 {
295   int option_index;
296
297   optarg = 0;
298
299   /* Initialize the internal data when the first call is made.
300      Start processing options with ARGV-element 1 (since ARGV-element 0
301      is the program name); the sequence of previously skipped
302      non-option ARGV-elements is empty.  */
303
304   if (optind == 0)
305     {
306       first_nonopt = last_nonopt = optind = 1;
307
308       nextchar = NULL;
309
310       /* Determine how to handle the ordering of options and nonoptions.  */
311
312       if (optstring[0] == '-')
313         {
314           ordering = RETURN_IN_ORDER;
315           ++optstring;
316         }
317       else if (optstring[0] == '+')
318         {
319           ordering = REQUIRE_ORDER;
320           ++optstring;
321         }
322       else if (getenv ("POSIXLY_CORRECT") != NULL)
323         ordering = REQUIRE_ORDER;
324       else
325         ordering = PERMUTE;
326     }
327
328   if (nextchar == NULL || *nextchar == '\0')
329     {
330       if (ordering == PERMUTE)
331         {
332           /* If we have just processed some options following some non-options,
333              exchange them so that the options come first.  */
334
335           if (first_nonopt != last_nonopt && last_nonopt != optind)
336             exchange ((char **) argv);
337           else if (last_nonopt != optind)
338             first_nonopt = optind;
339
340           /* Now skip any additional non-options
341              and extend the range of non-options previously skipped.  */
342
343           while (optind < argc
344                  && (argv[optind][0] != '-' || argv[optind][1] == '\0')
345 #ifdef GETOPT_COMPAT
346                  && (longopts == NULL
347                      || argv[optind][0] != '+' || argv[optind][1] == '\0')
348 #endif                                /* GETOPT_COMPAT */
349                  )
350             optind++;
351           last_nonopt = optind;
352         }
353
354       /* Special ARGV-element `--' means premature end of options.
355          Skip it like a null option,
356          then exchange with previous non-options as if it were an option,
357          then skip everything else like a non-option.  */
358
359       if (optind != argc && !strcmp (argv[optind], "--"))
360         {
361           optind++;
362
363           if (first_nonopt != last_nonopt && last_nonopt != optind)
364             exchange ((char **) argv);
365           else if (first_nonopt == last_nonopt)
366             first_nonopt = optind;
367           last_nonopt = argc;
368
369           optind = argc;
370         }
371
372       /* If we have done all the ARGV-elements, stop the scan
373          and back over any non-options that we skipped and permuted.  */
374
375       if (optind == argc)
376         {
377           /* Set the next-arg-index to point at the non-options
378              that we previously skipped, so the caller will digest them.  */
379           if (first_nonopt != last_nonopt)
380             optind = first_nonopt;
381           return EOF;
382         }
383
384       /* If we have come to a non-option and did not permute it,
385          either stop the scan or describe it to the caller and pass it by.  */
386
387       if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
388 #ifdef GETOPT_COMPAT
389           && (longopts == NULL
390               || argv[optind][0] != '+' || argv[optind][1] == '\0')
391 #endif                                /* GETOPT_COMPAT */
392           )
393         {
394           if (ordering == REQUIRE_ORDER)
395             return EOF;
396           optarg = argv[optind++];
397           return 1;
398         }
399
400       /* We have found another option-ARGV-element.
401          Start decoding its characters.  */
402
403       nextchar = (argv[optind] + 1
404                   + (longopts != NULL && argv[optind][1] == '-'));
405     }
406
407   if (longopts != NULL
408       && ((argv[optind][0] == '-'
409            && (argv[optind][1] == '-' || long_only))
410 #ifdef GETOPT_COMPAT
411           || argv[optind][0] == '+'
412 #endif                                /* GETOPT_COMPAT */
413           ))
414     {
415       const struct option *p;
416       char *s = nextchar;
417       int exact = 0;
418       int ambig = 0;
419       const struct option *pfound = NULL;
420       int indfound;
421
422       indfound = 0;             /* To silence the compiler.  */
423
424       while (*s && *s != '=')
425         s++;
426
427       /* Test all options for either exact match or abbreviated matches.  */
428       for (p = longopts, option_index = 0; p->name;
429            p++, option_index++)
430         if (!strncmp (p->name, nextchar, s - nextchar))
431           {
432             if (s - nextchar == strlen (p->name))
433               {
434                 /* Exact match found.  */
435                 pfound = p;
436                 indfound = option_index;
437                 exact = 1;
438                 break;
439               }
440             else if (pfound == NULL)
441               {
442                 /* First nonexact match found.  */
443                 pfound = p;
444                 indfound = option_index;
445               }
446             else
447               /* Second nonexact match found.  */
448               ambig = 1;
449           }
450
451       if (ambig && !exact)
452         {
453           if (opterr)
454             fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
455                      exec_name, argv[optind]);
456           nextchar += strlen (nextchar);
457           optind++;
458           return '?';
459         }
460
461       if (pfound != NULL)
462         {
463           option_index = indfound;
464           optind++;
465           if (*s)
466             {
467               /* Don't test has_arg with >, because some C compilers don't
468                  allow it to be used on enums.  */
469               if (pfound->has_arg)
470                 optarg = s + 1;
471               else
472                 {
473                   if (opterr)
474                     {
475                       if (argv[optind - 1][1] == '-')
476                         /* --option */
477                         fprintf (stderr,
478                                  _("%s: option `--%s' doesn't allow an argument\n"),
479                                  exec_name, pfound->name);
480                       else
481                         /* +option or -option */
482                         fprintf (stderr,
483                                  _("%s: option `%c%s' doesn't allow an argument\n"),
484                                  exec_name, argv[optind - 1][0], pfound->name);
485                     }
486                   nextchar += strlen (nextchar);
487                   return '?';
488                 }
489             }
490           else if (pfound->has_arg == 1)
491             {
492               if (optind < argc)
493                 optarg = argv[optind++];
494               else
495                 {
496                   if (opterr)
497                     fprintf (stderr,
498                              _("%s: option `%s' requires an argument\n"),
499                              exec_name, argv[optind - 1]);
500                   nextchar += strlen (nextchar);
501                   return optstring[0] == ':' ? ':' : '?';
502                 }
503             }
504           nextchar += strlen (nextchar);
505           if (longind != NULL)
506             *longind = option_index;
507           if (pfound->flag)
508             {
509               *(pfound->flag) = pfound->val;
510               return 0;
511             }
512           return pfound->val;
513         }
514       /* Can't find it as a long option.  If this is not getopt_long_only,
515          or the option starts with '--' or is not a valid short
516          option, then it's an error.
517          Otherwise interpret it as a short option.  */
518       if (!long_only || argv[optind][1] == '-'
519 #ifdef GETOPT_COMPAT
520           || argv[optind][0] == '+'
521 #endif                                /* GETOPT_COMPAT */
522           || my_index (optstring, *nextchar) == NULL)
523         {
524           if (opterr)
525             {
526               if (argv[optind][1] == '-')
527                 /* --option */
528                 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
529                          exec_name, nextchar);
530               else
531                 /* +option or -option */
532                 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
533                          exec_name, argv[optind][0], nextchar);
534             }
535           nextchar = (char *) "";
536           optind++;
537           return '?';
538         }
539     }
540
541   /* Look at and handle the next option-character.  */
542
543   {
544     char c = *nextchar++;
545     char *temp = my_index (optstring, c);
546
547     /* Increment `optind' when we start to process its last character.  */
548     if (*nextchar == '\0')
549       ++optind;
550
551     if (temp == NULL || c == ':')
552       {
553         if (opterr)
554           {
555 #if 0
556             if (c < 040 || c >= 0177)
557               fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
558                        exec_name, c);
559             else
560               fprintf (stderr, "%s: unrecognized option `-%c'\n", exec_name, c);
561 #else
562             /* 1003.2 specifies the format of this message.  */
563             fprintf (stderr, _("%s: illegal option -- %c\n"), exec_name, c);
564 #endif
565           }
566         optopt = c;
567         return '?';
568       }
569     if (temp[1] == ':')
570       {
571         if (temp[2] == ':')
572           {
573             /* This is an option that accepts an argument optionally.  */
574             if (*nextchar != '\0')
575               {
576                 optarg = nextchar;
577                 optind++;
578               }
579             else
580               optarg = 0;
581             nextchar = NULL;
582           }
583         else
584           {
585             /* This is an option that requires an argument.  */
586             if (*nextchar != '\0')
587               {
588                 optarg = nextchar;
589                 /* If we end this ARGV-element by taking the rest as an arg,
590                    we must advance to the next element now.  */
591                 optind++;
592               }
593             else if (optind == argc)
594               {
595                 if (opterr)
596                   {
597 #if 0
598                     fprintf (stderr, "%s: option `-%c' requires an argument\n",
599                              exec_name, c);
600 #else
601                     /* 1003.2 specifies the format of this message.  */
602                     fprintf (stderr, _("%s: option requires an argument -- %c\n"),
603                              exec_name, c);
604 #endif
605                   }
606                 optopt = c;
607                 if (optstring[0] == ':')
608                   c = ':';
609                 else
610                   c = '?';
611               }
612             else
613               /* We already incremented `optind' once;
614                  increment it again when taking next ARGV-elt as argument.  */
615               optarg = argv[optind++];
616             nextchar = NULL;
617           }
618       }
619     return c;
620   }
621 }
622
623 /* Calls internal getopt function to enable long option names.  */
624 int
625 getopt_long (int argc, char *const *argv, const char *shortopts,
626              const struct option *longopts, int *longind)
627 {
628   return _getopt_internal (argc, argv, shortopts, longopts, longind, 0);
629 }
630
631 int
632 getopt (int argc, char *const *argv, const char *optstring)
633 {
634   return _getopt_internal (argc, argv, optstring,
635                            (const struct option *) 0,
636                            (int *) 0,
637                            0);
638 }
639
640 #endif        /* _LIBC or not __GNU_LIBRARY__.  */
641 \f
642 #ifdef TEST
643
644 /* Compile with -DTEST to make an executable for use in testing
645    the above definition of `getopt'.  */
646
647 int
648 main (argc, argv)
649      int argc;
650      char **argv;
651 {
652   int c;
653   int digit_optind = 0;
654
655   while (1)
656     {
657       int this_option_optind = optind ? optind : 1;
658
659       c = getopt (argc, argv, "abc:d:0123456789");
660       if (c == EOF)
661         break;
662
663       switch (c)
664         {
665         case '0':
666         case '1':
667         case '2':
668         case '3':
669         case '4':
670         case '5':
671         case '6':
672         case '7':
673         case '8':
674         case '9':
675           if (digit_optind != 0 && digit_optind != this_option_optind)
676             printf ("digits occur in two different argv-elements.\n");
677           digit_optind = this_option_optind;
678           printf ("option %c\n", c);
679           break;
680
681         case 'a':
682           printf ("option a\n");
683           break;
684
685         case 'b':
686           printf ("option b\n");
687           break;
688
689         case 'c':
690           printf ("option c with value `%s'\n", optarg);
691           break;
692
693         case '?':
694           break;
695
696         default:
697           printf ("?? getopt returned character code 0%o ??\n", c);
698         }
699     }
700
701   if (optind < argc)
702     {
703       printf ("non-option ARGV-elements: ");
704       while (optind < argc)
705         printf ("%s ", argv[optind++]);
706       printf ("\n");
707     }
708
709   exit (0);
710 }
711
712 #endif /* TEST */