comparison lib-src/getopt.c @ 0:376386a54a3c r19-14

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