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