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