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 drepper@gnu.org
4    before changing it!
5    Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
6    	Free Software Foundation, Inc.
7    This file is part of the GNU C Library.
8 
9    The GNU C Library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2.1 of the License, or (at your option) any later version.
13 
14    The GNU C Library 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 GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with the GNU C Library; if not, write to the Free
21    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22    02111-1307 USA.  */
23 
24 /* Excessive comments removed by Wojtek Kaniewski <wojtekka@irc.pl> */
25 
26 #ifndef _NO_PROTO
27 # define _NO_PROTO
28 #endif
29 
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33 
34 #if !defined __STDC__ || !__STDC__
35 # ifndef const
36 #  define const
37 # endif
38 #endif
39 
40 #include <stdio.h>
41 
42 #define GETOPT_INTERFACE_VERSION 2
43 #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
44 # include <gnu-versions.h>
45 # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
46 #  define ELIDE_CODE
47 # endif
48 #endif
49 
50 #ifndef ELIDE_CODE
51 
52 #ifdef	__GNU_LIBRARY__
53 # include <stdlib.h>
54 # include <unistd.h>
55 #endif	/* GNU C library.  */
56 
57 #ifdef VMS
58 # include <unixlib.h>
59 # if HAVE_STRING_H - 0
60 #  include <string.h>
61 # endif
62 #endif
63 
64 #ifndef _
65 # if defined HAVE_LIBINTL_H || defined _LIBC
66 #  include <libintl.h>
67 #  ifndef _
68 #   define _(msgid)	gettext (msgid)
69 #  endif
70 # else
71 #  define _(msgid)	(msgid)
72 # endif
73 #endif
74 
75 #include "getopt.h"
76 
77 char *optarg;
78 
79 int optind = 1;
80 
81 int __getopt_initialized;
82 
83 static char *nextchar;
84 
85 int opterr = 1;
86 
87 int optopt = '?';
88 
89 static enum
90 {
91   REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
92 } ordering;
93 
94 static char *posixly_correct;
95 
96 #ifdef	__GNU_LIBRARY__
97 # include <string.h>
98 # define my_index	strchr
99 #else
100 
101 # if HAVE_STRING_H
102 #  include <string.h>
103 # else
104 #  include <strings.h>
105 # endif
106 
107 #ifndef getenv
108 extern char *getenv ();
109 #endif
110 
111 static char *
my_index(str,chr)112 my_index (str, chr)
113      const char *str;
114      int chr;
115 {
116   while (*str)
117     {
118       if (*str == chr)
119 	return (char *) str;
120       str++;
121     }
122   return 0;
123 }
124 
125 #ifdef __GNUC__
126 # if (!defined __STDC__ || !__STDC__) && !defined strlen
127 extern int strlen (const char *);
128 # endif /* not __STDC__ */
129 #endif /* __GNUC__ */
130 
131 #endif /* not __GNU_LIBRARY__ */
132 
133 static int first_nonopt;
134 static int last_nonopt;
135 
136 #ifdef _LIBC
137 extern int __libc_argc;
138 extern char **__libc_argv;
139 
140 # ifdef USE_NONOPTION_FLAGS
141 /* Defined in getopt_init.c  */
142 extern char *__getopt_nonoption_flags;
143 
144 static int nonoption_flags_max_len;
145 static int nonoption_flags_len;
146 # endif
147 
148 # ifdef USE_NONOPTION_FLAGS
149 #  define SWAP_FLAGS(ch1, ch2) \
150   if (nonoption_flags_len > 0)						      \
151     {									      \
152       char __tmp = __getopt_nonoption_flags[ch1];			      \
153       __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
154       __getopt_nonoption_flags[ch2] = __tmp;				      \
155     }
156 # else
157 #  define SWAP_FLAGS(ch1, ch2)
158 # endif
159 #else	/* !_LIBC */
160 # define SWAP_FLAGS(ch1, ch2)
161 #endif	/* _LIBC */
162 
163 #if defined __STDC__ && __STDC__
164 static void exchange (char **);
165 #endif
166 
167 static void
exchange(argv)168 exchange (argv)
169      char **argv;
170 {
171   int bottom = first_nonopt;
172   int middle = last_nonopt;
173   int top = optind;
174   char *tem;
175 
176 #if defined _LIBC && defined USE_NONOPTION_FLAGS
177   if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
178     {
179       char *new_str = malloc (top + 1);
180       if (new_str == NULL)
181 	nonoption_flags_len = nonoption_flags_max_len = 0;
182       else
183 	{
184 	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
185 			     nonoption_flags_max_len),
186 		  '\0', top + 1 - nonoption_flags_max_len);
187 	  nonoption_flags_max_len = top + 1;
188 	  __getopt_nonoption_flags = new_str;
189 	}
190     }
191 #endif
192 
193   while (top > middle && middle > bottom)
194     {
195       if (top - middle > middle - bottom)
196 	{
197 	  /* Bottom segment is the short one.  */
198 	  int len = middle - bottom;
199 	  register int i;
200 
201 	  /* Swap it with the top part of the top segment.  */
202 	  for (i = 0; i < len; i++)
203 	    {
204 	      tem = argv[bottom + i];
205 	      argv[bottom + i] = argv[top - (middle - bottom) + i];
206 	      argv[top - (middle - bottom) + i] = tem;
207 	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
208 	    }
209 	  /* Exclude the moved bottom segment from further swapping.  */
210 	  top -= len;
211 	}
212       else
213 	{
214 	  /* Top segment is the short one.  */
215 	  int len = top - middle;
216 	  register int i;
217 
218 	  /* Swap it with the bottom part of the bottom segment.  */
219 	  for (i = 0; i < len; i++)
220 	    {
221 	      tem = argv[bottom + i];
222 	      argv[bottom + i] = argv[middle + i];
223 	      argv[middle + i] = tem;
224 	      SWAP_FLAGS (bottom + i, middle + i);
225 	    }
226 	  /* Exclude the moved top segment from further swapping.  */
227 	  bottom += len;
228 	}
229     }
230 
231   /* Update records for the slots the non-options now occupy.  */
232 
233   first_nonopt += (optind - last_nonopt);
234   last_nonopt = optind;
235 }
236 
237 /* Initialize the internal data when the first call is made.  */
238 
239 #if defined __STDC__ && __STDC__
240 static const char *_getopt_initialize (int, char *const *, const char *);
241 #endif
242 static const char *
_getopt_initialize(argc,argv,optstring)243 _getopt_initialize (argc, argv, optstring)
244      int argc;
245      char *const *argv;
246      const char *optstring;
247 {
248   first_nonopt = last_nonopt = optind;
249 
250   nextchar = NULL;
251 
252   posixly_correct = getenv ("POSIXLY_CORRECT");
253 
254   if (optstring[0] == '-')
255     {
256       ordering = RETURN_IN_ORDER;
257       ++optstring;
258     }
259   else if (optstring[0] == '+')
260     {
261       ordering = REQUIRE_ORDER;
262       ++optstring;
263     }
264   else if (posixly_correct != NULL)
265     ordering = REQUIRE_ORDER;
266   else
267     ordering = PERMUTE;
268 
269 #if defined _LIBC && defined USE_NONOPTION_FLAGS
270   if (posixly_correct == NULL
271       && argc == __libc_argc && argv == __libc_argv)
272     {
273       if (nonoption_flags_max_len == 0)
274 	{
275 	  if (__getopt_nonoption_flags == NULL
276 	      || __getopt_nonoption_flags[0] == '\0')
277 	    nonoption_flags_max_len = -1;
278 	  else
279 	    {
280 	      const char *orig_str = __getopt_nonoption_flags;
281 	      int len = nonoption_flags_max_len = strlen (orig_str);
282 	      if (nonoption_flags_max_len < argc)
283 		nonoption_flags_max_len = argc;
284 	      __getopt_nonoption_flags =
285 		(char *) malloc (nonoption_flags_max_len);
286 	      if (__getopt_nonoption_flags == NULL)
287 		nonoption_flags_max_len = -1;
288 	      else
289 		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
290 			'\0', nonoption_flags_max_len - len);
291 	    }
292 	}
293       nonoption_flags_len = nonoption_flags_max_len;
294     }
295   else
296     nonoption_flags_len = 0;
297 #endif
298 
299   return optstring;
300 }
301 
302 int
_getopt_internal(argc,argv,optstring,longopts,longind,long_only)303 _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
304      int argc;
305      char *const *argv;
306      const char *optstring;
307      const struct option *longopts;
308      int *longind;
309      int long_only;
310 {
311   int print_errors = opterr;
312   if (optstring[0] == ':')
313     print_errors = 0;
314 
315   if (argc < 1)
316     return -1;
317 
318   optarg = NULL;
319 
320   if (optind == 0 || !__getopt_initialized)
321     {
322       if (optind == 0)
323 	optind = 1;	/* Don't scan ARGV[0], the program name.  */
324       optstring = _getopt_initialize (argc, argv, optstring);
325       __getopt_initialized = 1;
326     }
327 
328 #if defined _LIBC && defined USE_NONOPTION_FLAGS
329 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
330 		      || (optind < nonoption_flags_len			      \
331 			  && __getopt_nonoption_flags[optind] == '1'))
332 #else
333 # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
334 #endif
335 
336   if (nextchar == NULL || *nextchar == '\0')
337     {
338       if (last_nonopt > optind)
339 	last_nonopt = optind;
340       if (first_nonopt > optind)
341 	first_nonopt = optind;
342 
343       if (ordering == PERMUTE)
344 	{
345 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
346 	    exchange ((char **) argv);
347 	  else if (last_nonopt != optind)
348 	    first_nonopt = optind;
349 
350 	  while (optind < argc && NONOPTION_P)
351 	    optind++;
352 	  last_nonopt = optind;
353 	}
354 
355       if (optind != argc && !strcmp (argv[optind], "--"))
356 	{
357 	  optind++;
358 
359 	  if (first_nonopt != last_nonopt && last_nonopt != optind)
360 	    exchange ((char **) argv);
361 	  else if (first_nonopt == last_nonopt)
362 	    first_nonopt = optind;
363 	  last_nonopt = argc;
364 
365 	  optind = argc;
366 	}
367 
368       if (optind == argc)
369 	{
370 	  if (first_nonopt != last_nonopt)
371 	    optind = first_nonopt;
372 	  return -1;
373 	}
374 
375       if (NONOPTION_P)
376 	{
377 	  if (ordering == REQUIRE_ORDER)
378 	    return -1;
379 	  optarg = argv[optind++];
380 	  return 1;
381 	}
382 
383       nextchar = (argv[optind] + 1
384 		  + (longopts != NULL && argv[optind][1] == '-'));
385     }
386   if (longopts != NULL
387       && (argv[optind][1] == '-'
388 	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
389     {
390       char *nameend;
391       const struct option *p;
392       const struct option *pfound = NULL;
393       int exact = 0;
394       int ambig = 0;
395       int indfound = -1;
396       int option_index;
397 
398       for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
399 	/* Do nothing.  */ ;
400 
401       for (p = longopts, option_index = 0; p->name; p++, option_index++)
402 	if (!strncmp (p->name, nextchar, nameend - nextchar))
403 	  {
404 	    if ((unsigned int) (nameend - nextchar)
405 		== (unsigned int) strlen (p->name))
406 	      {
407 		/* Exact match found.  */
408 		pfound = p;
409 		indfound = option_index;
410 		exact = 1;
411 		break;
412 	      }
413 	    else if (pfound == NULL)
414 	      {
415 		/* First nonexact match found.  */
416 		pfound = p;
417 		indfound = option_index;
418 	      }
419 	    else if (long_only
420 		     || pfound->has_arg != p->has_arg
421 		     || pfound->flag != p->flag
422 		     || pfound->val != p->val)
423 	      /* Second or later nonexact match found.  */
424 	      ambig = 1;
425 	  }
426 
427       if (ambig && !exact)
428 	{
429 	  if (print_errors)
430 	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
431 		     argv[0], argv[optind]);
432 	  nextchar += strlen (nextchar);
433 	  optind++;
434 	  optopt = 0;
435 	  return '?';
436 	}
437 
438       if (pfound != NULL)
439 	{
440 	  option_index = indfound;
441 	  optind++;
442 	  if (*nameend)
443 	    {
444 	      if (pfound->has_arg)
445 		optarg = nameend + 1;
446 	      else
447 		{
448 		  if (print_errors)
449 		    {
450 		      if (argv[optind - 1][1] == '-')
451 			/* --option */
452 			fprintf (stderr,
453 				 _("%s: option `--%s' doesn't allow an argument\n"),
454 				 argv[0], pfound->name);
455 		      else
456 			/* +option or -option */
457 			fprintf (stderr,
458 				 _("%s: option `%c%s' doesn't allow an argument\n"),
459 				 argv[0], argv[optind - 1][0], pfound->name);
460 		    }
461 
462 		  nextchar += strlen (nextchar);
463 
464 		  optopt = pfound->val;
465 		  return '?';
466 		}
467 	    }
468 	  else if (pfound->has_arg == 1)
469 	    {
470 	      if (optind < argc)
471 		optarg = argv[optind++];
472 	      else
473 		{
474 		  if (print_errors)
475 		    fprintf (stderr,
476 			   _("%s: option `%s' requires an argument\n"),
477 			   argv[0], argv[optind - 1]);
478 		  nextchar += strlen (nextchar);
479 		  optopt = pfound->val;
480 		  return optstring[0] == ':' ? ':' : '?';
481 		}
482 	    }
483 	  nextchar += strlen (nextchar);
484 	  if (longind != NULL)
485 	    *longind = option_index;
486 	  if (pfound->flag)
487 	    {
488 	      *(pfound->flag) = pfound->val;
489 	      return 0;
490 	    }
491 	  return pfound->val;
492 	}
493 
494       if (!long_only || argv[optind][1] == '-'
495 	  || my_index (optstring, *nextchar) == NULL)
496 	{
497 	  if (print_errors)
498 	    {
499 	      if (argv[optind][1] == '-')
500 		/* --option */
501 		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
502 			 argv[0], nextchar);
503 	      else
504 		/* +option or -option */
505 		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
506 			 argv[0], argv[optind][0], nextchar);
507 	    }
508 	  nextchar = (char *) "";
509 	  optind++;
510 	  optopt = 0;
511 	  return '?';
512 	}
513     }
514 
515   {
516     char c = *nextchar++;
517     char *temp = my_index (optstring, c);
518 
519     if (*nextchar == '\0')
520       ++optind;
521 
522     if (temp == NULL || c == ':')
523       {
524 	if (print_errors)
525 	  {
526 	    if (posixly_correct)
527 	      /* 1003.2 specifies the format of this message.  */
528 	      fprintf (stderr, _("%s: illegal option -- %c\n"),
529 		       argv[0], c);
530 	    else
531 	      fprintf (stderr, _("%s: invalid option -- %c\n"),
532 		       argv[0], c);
533 	  }
534 	optopt = c;
535 	return '?';
536       }
537     /* Convenience. Treat POSIX -W foo same as long option --foo */
538     if (temp[0] == 'W' && temp[1] == ';')
539       {
540 	char *nameend;
541 	const struct option *p;
542 	const struct option *pfound = NULL;
543 	int exact = 0;
544 	int ambig = 0;
545 	int indfound = 0;
546 	int option_index;
547 
548 	if (*nextchar != '\0')
549 	  {
550 	    optarg = nextchar;
551 	    optind++;
552 	  }
553 	else if (optind == argc)
554 	  {
555 	    if (print_errors)
556 	      {
557 		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
558 			 argv[0], c);
559 	      }
560 	    optopt = c;
561 	    if (optstring[0] == ':')
562 	      c = ':';
563 	    else
564 	      c = '?';
565 	    return c;
566 	  }
567 	else
568 	  optarg = argv[optind++];
569 
570 	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
571 	  /* Do nothing.  */ ;
572 
573 	for (p = longopts, option_index = 0; p->name; p++, option_index++)
574 	  if (!strncmp (p->name, nextchar, nameend - nextchar))
575 	    {
576 	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
577 		{
578 		  /* Exact match found.  */
579 		  pfound = p;
580 		  indfound = option_index;
581 		  exact = 1;
582 		  break;
583 		}
584 	      else if (pfound == NULL)
585 		{
586 		  /* First nonexact match found.  */
587 		  pfound = p;
588 		  indfound = option_index;
589 		}
590 	      else
591 		/* Second or later nonexact match found.  */
592 		ambig = 1;
593 	    }
594 	if (ambig && !exact)
595 	  {
596 	    if (print_errors)
597 	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
598 		       argv[0], argv[optind]);
599 	    nextchar += strlen (nextchar);
600 	    optind++;
601 	    return '?';
602 	  }
603 	if (pfound != NULL)
604 	  {
605 	    option_index = indfound;
606 	    if (*nameend)
607 	      {
608 		if (pfound->has_arg)
609 		  optarg = nameend + 1;
610 		else
611 		  {
612 		    if (print_errors)
613 		      fprintf (stderr, _("\
614 %s: option `-W %s' doesn't allow an argument\n"),
615 			       argv[0], pfound->name);
616 
617 		    nextchar += strlen (nextchar);
618 		    return '?';
619 		  }
620 	      }
621 	    else if (pfound->has_arg == 1)
622 	      {
623 		if (optind < argc)
624 		  optarg = argv[optind++];
625 		else
626 		  {
627 		    if (print_errors)
628 		      fprintf (stderr,
629 			       _("%s: option `%s' requires an argument\n"),
630 			       argv[0], argv[optind - 1]);
631 		    nextchar += strlen (nextchar);
632 		    return optstring[0] == ':' ? ':' : '?';
633 		  }
634 	      }
635 	    nextchar += strlen (nextchar);
636 	    if (longind != NULL)
637 	      *longind = option_index;
638 	    if (pfound->flag)
639 	      {
640 		*(pfound->flag) = pfound->val;
641 		return 0;
642 	      }
643 	    return pfound->val;
644 	  }
645 	  nextchar = NULL;
646 	  return 'W';	/* Let the application handle it.   */
647       }
648     if (temp[1] == ':')
649       {
650 	if (temp[2] == ':')
651 	  {
652 	    /* This is an option that accepts an argument optionally.  */
653 	    if (*nextchar != '\0')
654 	      {
655 		optarg = nextchar;
656 		optind++;
657 	      }
658 	    else
659 	      optarg = NULL;
660 	    nextchar = NULL;
661 	  }
662 	else
663 	  {
664 	    if (*nextchar != '\0')
665 	      {
666 		optarg = nextchar;
667 		optind++;
668 	      }
669 	    else if (optind == argc)
670 	      {
671 		if (print_errors)
672 		  {
673 		    fprintf (stderr,
674 			     _("%s: option requires an argument -- %c\n"),
675 			     argv[0], c);
676 		  }
677 		optopt = c;
678 		if (optstring[0] == ':')
679 		  c = ':';
680 		else
681 		  c = '?';
682 	      }
683 	    else
684 	      /* We already incremented `optind' once;
685 		 increment it again when taking next ARGV-elt as argument.  */
686 	      optarg = argv[optind++];
687 	    nextchar = NULL;
688 	  }
689       }
690     return c;
691   }
692 }
693 
694 int
getopt(argc,argv,optstring)695 getopt (argc, argv, optstring)
696      int argc;
697      char *const *argv;
698      const char *optstring;
699 {
700   return _getopt_internal (argc, argv, optstring,
701 			   (const struct option *) 0,
702 			   (int *) 0,
703 			   0);
704 }
705 
706 #endif	/* Not ELIDE_CODE.  */
707 
708 
709