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