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