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