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