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