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