xref: /386bsd/usr/src/usr.bin/cpio/getopt.c (revision a2142627)
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 #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 
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 #else
163 
164 /* Avoid depending on library functions or files
165    whose names are inconsistent.  */
166 
167 char *getenv ();
168 
169 static char *
my_index(str,chr)170 my_index (str, chr)
171      const char *str;
172      int chr;
173 {
174   while (*str)
175     {
176       if (*str == chr)
177 	return (char *) str;
178       str++;
179     }
180   return 0;
181 }
182 
183 /* If using GCC, we can safely declare strlen this way.
184    If not using GCC, it is ok not to declare it.  */
185 #ifdef __GNUC__
186 #ifdef IN_GCC
187 #include "gstddef.h"
188 #else
189 #include <stddef.h>
190 #endif
191 extern size_t strlen (const char *);
192 #endif
193 
194 #endif				/* GNU C library.  */
195 
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
exchange(argv)215 exchange (argv)
216      char **argv;
217 {
218   int bottom = first_nonopt;
219   int middle = last_nonopt;
220   int top = optind;
221   char *tem;
222 
223   /* Exchange the shorter segment with the far end of the longer segment.
224      That puts the shorter segment into the right place.
225      It leaves the longer segment in the right place overall,
226      but it consists of two parts that need to be swapped next.  */
227 
228   while (top > middle && middle > bottom)
229     {
230       if (top - middle > middle - bottom)
231 	{
232 	  /* Bottom segment is the short one.  */
233 	  int len = middle - bottom;
234 	  register int i;
235 
236 	  /* Swap it with the top part of the top segment.  */
237 	  for (i = 0; i < len; i++)
238 	    {
239 	      tem = argv[bottom + i];
240 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
241 	      argv[top - (middle - bottom) + i] = tem;
242 	    }
243 	  /* Exclude the moved bottom segment from further swapping.  */
244 	  top -= len;
245 	}
246       else
247 	{
248 	  /* Top segment is the short one.  */
249 	  int len = top - middle;
250 	  register int i;
251 
252 	  /* Swap it with the bottom part of the bottom segment.  */
253 	  for (i = 0; i < len; i++)
254 	    {
255 	      tem = argv[bottom + i];
256 	      argv[bottom + i] = argv[middle + i];
257 	      argv[middle + i] = tem;
258 	    }
259 	  /* Exclude the moved top segment from further swapping.  */
260 	  bottom += len;
261 	}
262     }
263 
264   /* Update records for the slots the non-options now occupy.  */
265 
266   first_nonopt += (optind - last_nonopt);
267   last_nonopt = optind;
268 }
269 
270 /* Scan elements of ARGV (whose length is ARGC) for option characters
271    given in OPTSTRING.
272 
273    If an element of ARGV starts with '-', and is not exactly "-" or "--",
274    then it is an option element.  The characters of this element
275    (aside from the initial '-') are option characters.  If `getopt'
276    is called repeatedly, it returns successively each of the option characters
277    from each of the option elements.
278 
279    If `getopt' finds another option character, it returns that character,
280    updating `optind' and `nextchar' so that the next call to `getopt' can
281    resume the scan with the following option character or ARGV-element.
282 
283    If there are no more option characters, `getopt' returns `EOF'.
284    Then `optind' is the index in ARGV of the first ARGV-element
285    that is not an option.  (The ARGV-elements have been permuted
286    so that those that are not options now come last.)
287 
288    OPTSTRING is a string containing the legitimate option characters.
289    If an option character is seen that is not listed in OPTSTRING,
290    return '?' after printing an error message.  If you set `opterr' to
291    zero, the error message is suppressed but we still return '?'.
292 
293    If a char in OPTSTRING is followed by a colon, that means it wants an arg,
294    so the following text in the same ARGV-element, or the text of the following
295    ARGV-element, is returned in `optarg'.  Two colons mean an option that
296    wants an optional arg; if there is text in the current ARGV-element,
297    it is returned in `optarg', otherwise `optarg' is set to zero.
298 
299    If OPTSTRING starts with `-' or `+', it requests different methods of
300    handling the non-option ARGV-elements.
301    See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
302 
303    Long-named options begin with `--' instead of `-'.
304    Their names may be abbreviated as long as the abbreviation is unique
305    or is an exact match for some defined option.  If they have an
306    argument, it follows the option name in the same ARGV-element, separated
307    from the option name by a `=', or else the in next ARGV-element.
308    When `getopt' finds a long-named option, it returns 0 if that option's
309    `flag' field is nonzero, the value of the option's `val' field
310    if the `flag' field is zero.
311 
312    The elements of ARGV aren't really const, because we permute them.
313    But we pretend they're const in the prototype to be compatible
314    with other systems.
315 
316    LONGOPTS is a vector of `struct option' terminated by an
317    element containing a name which is zero.
318 
319    LONGIND returns the index in LONGOPT of the long-named option found.
320    It is only valid when a long-named option has been found by the most
321    recent call.
322 
323    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
324    long-named options.  */
325 
326 int
_getopt_internal(argc,argv,optstring,longopts,longind,long_only)327 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
328      int argc;
329      char *const *argv;
330      const char *optstring;
331      const struct option *longopts;
332      int *longind;
333      int long_only;
334 {
335   int option_index;
336 
337   optarg = 0;
338 
339   /* Initialize the internal data when the first call is made.
340      Start processing options with ARGV-element 1 (since ARGV-element 0
341      is the program name); the sequence of previously skipped
342      non-option ARGV-elements is empty.  */
343 
344   if (optind == 0)
345     {
346       first_nonopt = last_nonopt = optind = 1;
347 
348       nextchar = NULL;
349 
350       /* Determine how to handle the ordering of options and nonoptions.  */
351 
352       if (optstring[0] == '-')
353 	{
354 	  ordering = RETURN_IN_ORDER;
355 	  ++optstring;
356 	}
357       else if (optstring[0] == '+')
358 	{
359 	  ordering = REQUIRE_ORDER;
360 	  ++optstring;
361 	}
362       else if (getenv ("POSIXLY_CORRECT") != NULL)
363 	ordering = REQUIRE_ORDER;
364       else
365 	ordering = PERMUTE;
366     }
367 
368   if (nextchar == NULL || *nextchar == '\0')
369     {
370       if (ordering == PERMUTE)
371 	{
372 	  /* If we have just processed some options following some non-options,
373 	     exchange them so that the options come first.  */
374 
375 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
376 	    exchange ((char **) argv);
377 	  else if (last_nonopt != optind)
378 	    first_nonopt = optind;
379 
380 	  /* Now skip any additional non-options
381 	     and extend the range of non-options previously skipped.  */
382 
383 	  while (optind < argc
384 		 && (argv[optind][0] != '-' || argv[optind][1] == '\0')
385 #ifdef GETOPT_COMPAT
386 		 && (longopts == NULL
387 		     || argv[optind][0] != '+' || argv[optind][1] == '\0')
388 #endif				/* GETOPT_COMPAT */
389 		 )
390 	    optind++;
391 	  last_nonopt = optind;
392 	}
393 
394       /* Special ARGV-element `--' means premature end of options.
395 	 Skip it like a null option,
396 	 then exchange with previous non-options as if it were an option,
397 	 then skip everything else like a non-option.  */
398 
399       if (optind != argc && !strcmp (argv[optind], "--"))
400 	{
401 	  optind++;
402 
403 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
404 	    exchange ((char **) argv);
405 	  else if (first_nonopt == last_nonopt)
406 	    first_nonopt = optind;
407 	  last_nonopt = argc;
408 
409 	  optind = argc;
410 	}
411 
412       /* If we have done all the ARGV-elements, stop the scan
413 	 and back over any non-options that we skipped and permuted.  */
414 
415       if (optind == argc)
416 	{
417 	  /* Set the next-arg-index to point at the non-options
418 	     that we previously skipped, so the caller will digest them.  */
419 	  if (first_nonopt != last_nonopt)
420 	    optind = first_nonopt;
421 	  return EOF;
422 	}
423 
424       /* If we have come to a non-option and did not permute it,
425 	 either stop the scan or describe it to the caller and pass it by.  */
426 
427       if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
428 #ifdef GETOPT_COMPAT
429 	  && (longopts == NULL
430 	      || argv[optind][0] != '+' || argv[optind][1] == '\0')
431 #endif				/* GETOPT_COMPAT */
432 	  )
433 	{
434 	  if (ordering == REQUIRE_ORDER)
435 	    return EOF;
436 	  optarg = argv[optind++];
437 	  return 1;
438 	}
439 
440       /* We have found another option-ARGV-element.
441 	 Start decoding its characters.  */
442 
443       nextchar = (argv[optind] + 1
444 		  + (longopts != NULL && argv[optind][1] == '-'));
445     }
446 
447   if (longopts != NULL
448       && ((argv[optind][0] == '-'
449 	   && (argv[optind][1] == '-' || long_only))
450 #ifdef GETOPT_COMPAT
451 	  || argv[optind][0] == '+'
452 #endif				/* GETOPT_COMPAT */
453 	  ))
454     {
455       const struct option *p;
456       char *s = nextchar;
457       int exact = 0;
458       int ambig = 0;
459       const struct option *pfound = NULL;
460       int indfound;
461 
462       while (*s && *s != '=')
463 	s++;
464 
465       /* Test all options for either exact match or abbreviated matches.  */
466       for (p = longopts, option_index = 0; p->name;
467 	   p++, option_index++)
468 	if (!strncmp (p->name, nextchar, s - nextchar))
469 	  {
470 	    if (s - nextchar == strlen (p->name))
471 	      {
472 		/* Exact match found.  */
473 		pfound = p;
474 		indfound = option_index;
475 		exact = 1;
476 		break;
477 	      }
478 	    else if (pfound == NULL)
479 	      {
480 		/* First nonexact match found.  */
481 		pfound = p;
482 		indfound = option_index;
483 	      }
484 	    else
485 	      /* Second nonexact match found.  */
486 	      ambig = 1;
487 	  }
488 
489       if (ambig && !exact)
490 	{
491 	  if (opterr)
492 	    fprintf (stderr, "%s: option `%s' is ambiguous\n",
493 		     argv[0], argv[optind]);
494 	  nextchar += strlen (nextchar);
495 	  optind++;
496 	  return '?';
497 	}
498 
499       if (pfound != NULL)
500 	{
501 	  option_index = indfound;
502 	  optind++;
503 	  if (*s)
504 	    {
505 	      /* Don't test has_arg with >, because some C compilers don't
506 		 allow it to be used on enums.  */
507 	      if (pfound->has_arg)
508 		optarg = s + 1;
509 	      else
510 		{
511 		  if (opterr)
512 		    {
513 		      if (argv[optind - 1][1] == '-')
514 			/* --option */
515 			fprintf (stderr,
516 				 "%s: option `--%s' doesn't allow an argument\n",
517 				 argv[0], pfound->name);
518 		      else
519 			/* +option or -option */
520 			fprintf (stderr,
521 			     "%s: option `%c%s' doesn't allow an argument\n",
522 			     argv[0], argv[optind - 1][0], pfound->name);
523 		    }
524 		  nextchar += strlen (nextchar);
525 		  return '?';
526 		}
527 	    }
528 	  else if (pfound->has_arg == 1)
529 	    {
530 	      if (optind < argc)
531 		optarg = argv[optind++];
532 	      else
533 		{
534 		  if (opterr)
535 		    fprintf (stderr, "%s: option `%s' requires an argument\n",
536 			     argv[0], argv[optind - 1]);
537 		  nextchar += strlen (nextchar);
538 		  return optstring[0] == ':' ? ':' : '?';
539 		}
540 	    }
541 	  nextchar += strlen (nextchar);
542 	  if (longind != NULL)
543 	    *longind = option_index;
544 	  if (pfound->flag)
545 	    {
546 	      *(pfound->flag) = pfound->val;
547 	      return 0;
548 	    }
549 	  return pfound->val;
550 	}
551       /* Can't find it as a long option.  If this is not getopt_long_only,
552 	 or the option starts with '--' or is not a valid short
553 	 option, then it's an error.
554 	 Otherwise interpret it as a short option.  */
555       if (!long_only || argv[optind][1] == '-'
556 #ifdef GETOPT_COMPAT
557 	  || argv[optind][0] == '+'
558 #endif				/* GETOPT_COMPAT */
559 	  || my_index (optstring, *nextchar) == NULL)
560 	{
561 	  if (opterr)
562 	    {
563 	      if (argv[optind][1] == '-')
564 		/* --option */
565 		fprintf (stderr, "%s: unrecognized option `--%s'\n",
566 			 argv[0], nextchar);
567 	      else
568 		/* +option or -option */
569 		fprintf (stderr, "%s: unrecognized option `%c%s'\n",
570 			 argv[0], argv[optind][0], nextchar);
571 	    }
572 	  nextchar = (char *) "";
573 	  optind++;
574 	  return '?';
575 	}
576     }
577 
578   /* Look at and handle the next option-character.  */
579 
580   {
581     char c = *nextchar++;
582     char *temp = my_index (optstring, c);
583 
584     /* Increment `optind' when we start to process its last character.  */
585     if (*nextchar == '\0')
586       ++optind;
587 
588     if (temp == NULL || c == ':')
589       {
590 	if (opterr)
591 	  {
592 #if 0
593 	    if (c < 040 || c >= 0177)
594 	      fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
595 		       argv[0], c);
596 	    else
597 	      fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
598 #else
599 	    /* 1003.2 specifies the format of this message.  */
600 	    fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
601 #endif
602 	  }
603 	optopt = c;
604 	return '?';
605       }
606     if (temp[1] == ':')
607       {
608 	if (temp[2] == ':')
609 	  {
610 	    /* This is an option that accepts an argument optionally.  */
611 	    if (*nextchar != '\0')
612 	      {
613 		optarg = nextchar;
614 		optind++;
615 	      }
616 	    else
617 	      optarg = 0;
618 	    nextchar = NULL;
619 	  }
620 	else
621 	  {
622 	    /* This is an option that requires an argument.  */
623 	    if (*nextchar != '\0')
624 	      {
625 		optarg = nextchar;
626 		/* If we end this ARGV-element by taking the rest as an arg,
627 		   we must advance to the next element now.  */
628 		optind++;
629 	      }
630 	    else if (optind == argc)
631 	      {
632 		if (opterr)
633 		  {
634 #if 0
635 		    fprintf (stderr, "%s: option `-%c' requires an argument\n",
636 			     argv[0], c);
637 #else
638 		    /* 1003.2 specifies the format of this message.  */
639 		    fprintf (stderr, "%s: option requires an argument -- %c\n",
640 			     argv[0], c);
641 #endif
642 		  }
643 		optopt = c;
644 		if (optstring[0] == ':')
645 		  c = ':';
646 		else
647 		  c = '?';
648 	      }
649 	    else
650 	      /* We already incremented `optind' once;
651 		 increment it again when taking next ARGV-elt as argument.  */
652 	      optarg = argv[optind++];
653 	    nextchar = NULL;
654 	  }
655       }
656     return c;
657   }
658 }
659 
660 int
getopt(argc,argv,optstring)661 getopt (argc, argv, optstring)
662      int argc;
663      char *const *argv;
664      const char *optstring;
665 {
666   return _getopt_internal (argc, argv, optstring,
667 			   (const struct option *) 0,
668 			   (int *) 0,
669 			   0);
670 }
671 
672 #endif	/* _LIBC or not __GNU_LIBRARY__.  */
673 
674 #ifdef TEST
675 
676 /* Compile with -DTEST to make an executable for use in testing
677    the above definition of `getopt'.  */
678 
679 int
main(argc,argv)680 main (argc, argv)
681      int argc;
682      char **argv;
683 {
684   int c;
685   int digit_optind = 0;
686 
687   while (1)
688     {
689       int this_option_optind = optind ? optind : 1;
690 
691       c = getopt (argc, argv, "abc:d:0123456789");
692       if (c == EOF)
693 	break;
694 
695       switch (c)
696 	{
697 	case '0':
698 	case '1':
699 	case '2':
700 	case '3':
701 	case '4':
702 	case '5':
703 	case '6':
704 	case '7':
705 	case '8':
706 	case '9':
707 	  if (digit_optind != 0 && digit_optind != this_option_optind)
708 	    printf ("digits occur in two different argv-elements.\n");
709 	  digit_optind = this_option_optind;
710 	  printf ("option %c\n", c);
711 	  break;
712 
713 	case 'a':
714 	  printf ("option a\n");
715 	  break;
716 
717 	case 'b':
718 	  printf ("option b\n");
719 	  break;
720 
721 	case 'c':
722 	  printf ("option c with value `%s'\n", optarg);
723 	  break;
724 
725 	case '?':
726 	  break;
727 
728 	default:
729 	  printf ("?? getopt returned character code 0%o ??\n", c);
730 	}
731     }
732 
733   if (optind < argc)
734     {
735       printf ("non-option ARGV-elements: ");
736       while (optind < argc)
737 	printf ("%s ", argv[optind++]);
738       printf ("\n");
739     }
740 
741   exit (0);
742 }
743 
744 #endif /* TEST */
745