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