/[public]/psiconv/trunk/compat/getopt.c
ViewVC logotype

Annotation of /psiconv/trunk/compat/getopt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations)
Tue Nov 30 00:20:57 1999 UTC (25 years ago) by frodo
File MIME type: text/plain
File size: 30063 byte(s)
(Frodo) Added several files that were forgotten in the compat section...

1 frodo 30 /* 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 drepper@gnu.org
4     before changing it!
5    
6     Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
7     Free Software Foundation, Inc.
8    
9     The GNU C Library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Library General Public License as
11     published by the Free Software Foundation; either version 2 of the
12     License, or (at your option) any later version.
13    
14     The GNU C Library 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 the GNU C Library; see the file COPYING.LIB. If not,
21     write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22     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     #define GETOPT_INTERFACE_VERSION 2
53     #if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
54     # include <gnu-versions.h>
55     # if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
56     # define ELIDE_CODE
57     # endif
58     #endif
59    
60     #ifndef ELIDE_CODE
61    
62    
63     /* This needs to come after some library #include
64     to get __GNU_LIBRARY__ defined. */
65     #ifdef __GNU_LIBRARY__
66     /* Don't include stdlib.h for non-GNU C libraries because some of them
67     contain conflicting prototypes for getopt. */
68     # include <stdlib.h>
69     # include <unistd.h>
70     #endif /* GNU C library. */
71    
72     #ifdef VMS
73     # include <unixlib.h>
74     # if HAVE_STRING_H - 0
75     # include <string.h>
76     # endif
77     #endif
78    
79     #ifndef _
80     /* This is for other GNU distributions with internationalized messages.
81     When compiling libc, the _ macro is predefined. */
82     # ifdef HAVE_LIBINTL_H
83     # include <libintl.h>
84     # define _(msgid) gettext (msgid)
85     # else
86     # define _(msgid) (msgid)
87     # endif
88     #endif
89    
90     /* This version of `getopt' appears to the caller like standard Unix `getopt'
91     but it behaves differently for the user, since it allows the user
92     to intersperse the options with the other arguments.
93    
94     As `getopt' works, it permutes the elements of ARGV so that,
95     when it is done, all the options precede everything else. Thus
96     all application programs are extended to handle flexible argument order.
97    
98     Setting the environment variable POSIXLY_CORRECT disables permutation.
99     Then the behavior is completely standard.
100    
101     GNU application programs can use a third alternative mode in which
102     they can distinguish the relative order of options and other arguments. */
103    
104     #include "getopt.h"
105    
106     /* For communication from `getopt' to the caller.
107     When `getopt' finds an option that takes an argument,
108     the argument value is returned here.
109     Also, when `ordering' is RETURN_IN_ORDER,
110     each non-option ARGV-element is returned here. */
111    
112     char *optarg;
113    
114     /* Index in ARGV of the next element to be scanned.
115     This is used for communication to and from the caller
116     and for communication between successive calls to `getopt'.
117    
118     On entry to `getopt', zero means this is the first call; initialize.
119    
120     When `getopt' returns -1, this is the index of the first of the
121     non-option elements that the caller should itself scan.
122    
123     Otherwise, `optind' communicates from one call to the next
124     how much of ARGV has been scanned so far. */
125    
126     /* 1003.2 says this must be 1 before any call. */
127     int optind = 1;
128    
129     /* Formerly, initialization of getopt depended on optind==0, which
130     causes problems with re-calling getopt as programs generally don't
131     know that. */
132    
133     int __getopt_initialized;
134    
135     /* The next char to be scanned in the option-element
136     in which the last option character we returned was found.
137     This allows us to pick up the scan where we left off.
138    
139     If this is zero, or a null string, it means resume the scan
140     by advancing to the next ARGV-element. */
141    
142     static char *nextchar;
143    
144     /* Callers store zero here to inhibit the error message
145     for unrecognized options. */
146    
147     int opterr = 1;
148    
149     /* Set to an option character which was unrecognized.
150     This must be initialized on some systems to avoid linking in the
151     system's own getopt implementation. */
152    
153     int optopt = '?';
154    
155     /* Describe how to deal with options that follow non-option ARGV-elements.
156    
157     If the caller did not specify anything,
158     the default is REQUIRE_ORDER if the environment variable
159     POSIXLY_CORRECT is defined, PERMUTE otherwise.
160    
161     REQUIRE_ORDER means don't recognize them as options;
162     stop option processing when the first non-option is seen.
163     This is what Unix does.
164     This mode of operation is selected by either setting the environment
165     variable POSIXLY_CORRECT, or using `+' as the first character
166     of the list of option characters.
167    
168     PERMUTE is the default. We permute the contents of ARGV as we scan,
169     so that eventually all the non-options are at the end. This allows options
170     to be given in any order, even with programs that were not written to
171     expect this.
172    
173     RETURN_IN_ORDER is an option available to programs that were written
174     to expect options and other ARGV-elements in any order and that care about
175     the ordering of the two. We describe each non-option ARGV-element
176     as if it were the argument of an option with character code 1.
177     Using `-' as the first character of the list of option characters
178     selects this mode of operation.
179    
180     The special argument `--' forces an end of option-scanning regardless
181     of the value of `ordering'. In the case of RETURN_IN_ORDER, only
182     `--' can cause `getopt' to return -1 with `optind' != ARGC. */
183    
184     static enum
185     {
186     REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
187     } ordering;
188    
189     /* Value of POSIXLY_CORRECT environment variable. */
190     static char *posixly_correct;
191    
192     #ifdef __GNU_LIBRARY__
193     /* We want to avoid inclusion of string.h with non-GNU libraries
194     because there are many ways it can cause trouble.
195     On some systems, it contains special magic macros that don't work
196     in GCC. */
197     # include <string.h>
198     # define my_index strchr
199     #else
200    
201     # if HAVE_STRING_H
202     # include <string.h>
203     # else
204     # include <strings.h>
205     # endif
206    
207     /* Avoid depending on library functions or files
208     whose names are inconsistent. */
209    
210     #ifndef getenv
211     extern char *getenv ();
212     #endif
213    
214     static char *
215     my_index (str, chr)
216     const char *str;
217     int chr;
218     {
219     while (*str)
220     {
221     if (*str == chr)
222     return (char *) str;
223     str++;
224     }
225     return 0;
226     }
227    
228     /* If using GCC, we can safely declare strlen this way.
229     If not using GCC, it is ok not to declare it. */
230     #ifdef __GNUC__
231     /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
232     That was relevant to code that was here before. */
233     # if (!defined __STDC__ || !__STDC__) && !defined strlen
234     /* gcc with -traditional declares the built-in strlen to return int,
235     and has done so at least since version 2.4.5. -- rms. */
236     extern int strlen (const char *);
237     # endif /* not __STDC__ */
238     #endif /* __GNUC__ */
239    
240     #endif /* not __GNU_LIBRARY__ */
241    
242     /* Handle permutation of arguments. */
243    
244     /* Describe the part of ARGV that contains non-options that have
245     been skipped. `first_nonopt' is the index in ARGV of the first of them;
246     `last_nonopt' is the index after the last of them. */
247    
248     static int first_nonopt;
249     static int last_nonopt;
250    
251     #ifdef _LIBC
252     /* Bash 2.0 gives us an environment variable containing flags
253     indicating ARGV elements that should not be considered arguments. */
254    
255     /* Defined in getopt_init.c */
256     extern char *__getopt_nonoption_flags;
257    
258     static int nonoption_flags_max_len;
259     static int nonoption_flags_len;
260    
261     static int original_argc;
262     static char *const *original_argv;
263    
264     /* Make sure the environment variable bash 2.0 puts in the environment
265     is valid for the getopt call we must make sure that the ARGV passed
266     to getopt is that one passed to the process. */
267     static void
268     __attribute__ ((unused))
269     store_args_and_env (int argc, char *const *argv)
270     {
271     /* XXX This is no good solution. We should rather copy the args so
272     that we can compare them later. But we must not use malloc(3). */
273     original_argc = argc;
274     original_argv = argv;
275     }
276     # ifdef text_set_element
277     text_set_element (__libc_subinit, store_args_and_env);
278     # endif /* text_set_element */
279    
280     # define SWAP_FLAGS(ch1, ch2) \
281     if (nonoption_flags_len > 0) \
282     { \
283     char __tmp = __getopt_nonoption_flags[ch1]; \
284     __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
285     __getopt_nonoption_flags[ch2] = __tmp; \
286     }
287     #else /* !_LIBC */
288     # define SWAP_FLAGS(ch1, ch2)
289     #endif /* _LIBC */
290    
291     /* Exchange two adjacent subsequences of ARGV.
292     One subsequence is elements [first_nonopt,last_nonopt)
293     which contains all the non-options that have been skipped so far.
294     The other is elements [last_nonopt,optind), which contains all
295     the options processed since those non-options were skipped.
296    
297     `first_nonopt' and `last_nonopt' are relocated so that they describe
298     the new indices of the non-options in ARGV after they are moved. */
299    
300     #if defined __STDC__ && __STDC__
301     static void exchange (char **);
302     #endif
303    
304     static void
305     exchange (argv)
306     char **argv;
307     {
308     int bottom = first_nonopt;
309     int middle = last_nonopt;
310     int top = optind;
311     char *tem;
312    
313     /* Exchange the shorter segment with the far end of the longer segment.
314     That puts the shorter segment into the right place.
315     It leaves the longer segment in the right place overall,
316     but it consists of two parts that need to be swapped next. */
317    
318     #ifdef _LIBC
319     /* First make sure the handling of the `__getopt_nonoption_flags'
320     string can work normally. Our top argument must be in the range
321     of the string. */
322     if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
323     {
324     /* We must extend the array. The user plays games with us and
325     presents new arguments. */
326     char *new_str = malloc (top + 1);
327     if (new_str == NULL)
328     nonoption_flags_len = nonoption_flags_max_len = 0;
329     else
330     {
331     memset (__mempcpy (new_str, __getopt_nonoption_flags,
332     nonoption_flags_max_len),
333     '\0', top + 1 - nonoption_flags_max_len);
334     nonoption_flags_max_len = top + 1;
335     __getopt_nonoption_flags = new_str;
336     }
337     }
338     #endif
339    
340     while (top > middle && middle > bottom)
341     {
342     if (top - middle > middle - bottom)
343     {
344     /* Bottom segment is the short one. */
345     int len = middle - bottom;
346     register int i;
347    
348     /* Swap it with the top part of the top segment. */
349     for (i = 0; i < len; i++)
350     {
351     tem = argv[bottom + i];
352     argv[bottom + i] = argv[top - (middle - bottom) + i];
353     argv[top - (middle - bottom) + i] = tem;
354     SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
355     }
356     /* Exclude the moved bottom segment from further swapping. */
357     top -= len;
358     }
359     else
360     {
361     /* Top segment is the short one. */
362     int len = top - middle;
363     register int i;
364    
365     /* Swap it with the bottom part of the bottom segment. */
366     for (i = 0; i < len; i++)
367     {
368     tem = argv[bottom + i];
369     argv[bottom + i] = argv[middle + i];
370     argv[middle + i] = tem;
371     SWAP_FLAGS (bottom + i, middle + i);
372     }
373     /* Exclude the moved top segment from further swapping. */
374     bottom += len;
375     }
376     }
377    
378     /* Update records for the slots the non-options now occupy. */
379    
380     first_nonopt += (optind - last_nonopt);
381     last_nonopt = optind;
382     }
383    
384     /* Initialize the internal data when the first call is made. */
385    
386     #if defined __STDC__ && __STDC__
387     static const char *_getopt_initialize (int, char *const *, const char *);
388     #endif
389     static const char *
390     _getopt_initialize (argc, argv, optstring)
391     int argc;
392     char *const *argv;
393     const char *optstring;
394     {
395     /* Start processing options with ARGV-element 1 (since ARGV-element 0
396     is the program name); the sequence of previously skipped
397     non-option ARGV-elements is empty. */
398    
399     first_nonopt = last_nonopt = optind;
400    
401     nextchar = NULL;
402    
403     posixly_correct = getenv ("POSIXLY_CORRECT");
404    
405     /* Determine how to handle the ordering of options and nonoptions. */
406    
407     if (optstring[0] == '-')
408     {
409     ordering = RETURN_IN_ORDER;
410     ++optstring;
411     }
412     else if (optstring[0] == '+')
413     {
414     ordering = REQUIRE_ORDER;
415     ++optstring;
416     }
417     else if (posixly_correct != NULL)
418     ordering = REQUIRE_ORDER;
419     else
420     ordering = PERMUTE;
421    
422     #ifdef _LIBC
423     if (posixly_correct == NULL
424     && argc == original_argc && argv == original_argv)
425     {
426     if (nonoption_flags_max_len == 0)
427     {
428     if (__getopt_nonoption_flags == NULL
429     || __getopt_nonoption_flags[0] == '\0')
430     nonoption_flags_max_len = -1;
431     else
432     {
433     const char *orig_str = __getopt_nonoption_flags;
434     int len = nonoption_flags_max_len = strlen (orig_str);
435     if (nonoption_flags_max_len < argc)
436     nonoption_flags_max_len = argc;
437     __getopt_nonoption_flags =
438     (char *) malloc (nonoption_flags_max_len);
439     if (__getopt_nonoption_flags == NULL)
440     nonoption_flags_max_len = -1;
441     else
442     memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
443     '\0', nonoption_flags_max_len - len);
444     }
445     }
446     nonoption_flags_len = nonoption_flags_max_len;
447     }
448     else
449     nonoption_flags_len = 0;
450     #endif
451    
452     return optstring;
453     }
454    
455     /* Scan elements of ARGV (whose length is ARGC) for option characters
456     given in OPTSTRING.
457    
458     If an element of ARGV starts with '-', and is not exactly "-" or "--",
459     then it is an option element. The characters of this element
460     (aside from the initial '-') are option characters. If `getopt'
461     is called repeatedly, it returns successively each of the option characters
462     from each of the option elements.
463    
464     If `getopt' finds another option character, it returns that character,
465     updating `optind' and `nextchar' so that the next call to `getopt' can
466     resume the scan with the following option character or ARGV-element.
467    
468     If there are no more option characters, `getopt' returns -1.
469     Then `optind' is the index in ARGV of the first ARGV-element
470     that is not an option. (The ARGV-elements have been permuted
471     so that those that are not options now come last.)
472    
473     OPTSTRING is a string containing the legitimate option characters.
474     If an option character is seen that is not listed in OPTSTRING,
475     return '?' after printing an error message. If you set `opterr' to
476     zero, the error message is suppressed but we still return '?'.
477    
478     If a char in OPTSTRING is followed by a colon, that means it wants an arg,
479     so the following text in the same ARGV-element, or the text of the following
480     ARGV-element, is returned in `optarg'. Two colons mean an option that
481     wants an optional arg; if there is text in the current ARGV-element,
482     it is returned in `optarg', otherwise `optarg' is set to zero.
483    
484     If OPTSTRING starts with `-' or `+', it requests different methods of
485     handling the non-option ARGV-elements.
486     See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
487    
488     Long-named options begin with `--' instead of `-'.
489     Their names may be abbreviated as long as the abbreviation is unique
490     or is an exact match for some defined option. If they have an
491     argument, it follows the option name in the same ARGV-element, separated
492     from the option name by a `=', or else the in next ARGV-element.
493     When `getopt' finds a long-named option, it returns 0 if that option's
494     `flag' field is nonzero, the value of the option's `val' field
495     if the `flag' field is zero.
496    
497     The elements of ARGV aren't really const, because we permute them.
498     But we pretend they're const in the prototype to be compatible
499     with other systems.
500    
501     LONGOPTS is a vector of `struct option' terminated by an
502     element containing a name which is zero.
503    
504     LONGIND returns the index in LONGOPT of the long-named option found.
505     It is only valid when a long-named option has been found by the most
506     recent call.
507    
508     If LONG_ONLY is nonzero, '-' as well as '--' can introduce
509     long-named options. */
510    
511     int
512     _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
513     int argc;
514     char *const *argv;
515     const char *optstring;
516     const struct option *longopts;
517     int *longind;
518     int long_only;
519     {
520     optarg = NULL;
521    
522     if (optind == 0 || !__getopt_initialized)
523     {
524     if (optind == 0)
525     optind = 1; /* Don't scan ARGV[0], the program name. */
526     optstring = _getopt_initialize (argc, argv, optstring);
527     __getopt_initialized = 1;
528     }
529    
530     /* Test whether ARGV[optind] points to a non-option argument.
531     Either it does not have option syntax, or there is an environment flag
532     from the shell indicating it is not an option. The later information
533     is only used when the used in the GNU libc. */
534     #ifdef _LIBC
535     # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
536     || (optind < nonoption_flags_len \
537     && __getopt_nonoption_flags[optind] == '1'))
538     #else
539     # define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
540     #endif
541    
542     if (nextchar == NULL || *nextchar == '\0')
543     {
544     /* Advance to the next ARGV-element. */
545    
546     /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
547     moved back by the user (who may also have changed the arguments). */
548     if (last_nonopt > optind)
549     last_nonopt = optind;
550     if (first_nonopt > optind)
551     first_nonopt = optind;
552    
553     if (ordering == PERMUTE)
554     {
555     /* If we have just processed some options following some non-options,
556     exchange them so that the options come first. */
557    
558     if (first_nonopt != last_nonopt && last_nonopt != optind)
559     exchange ((char **) argv);
560     else if (last_nonopt != optind)
561     first_nonopt = optind;
562    
563     /* Skip any additional non-options
564     and extend the range of non-options previously skipped. */
565    
566     while (optind < argc && NONOPTION_P)
567     optind++;
568     last_nonopt = optind;
569     }
570    
571     /* The special ARGV-element `--' means premature end of options.
572     Skip it like a null option,
573     then exchange with previous non-options as if it were an option,
574     then skip everything else like a non-option. */
575    
576     if (optind != argc && !strcmp (argv[optind], "--"))
577     {
578     optind++;
579    
580     if (first_nonopt != last_nonopt && last_nonopt != optind)
581     exchange ((char **) argv);
582     else if (first_nonopt == last_nonopt)
583     first_nonopt = optind;
584     last_nonopt = argc;
585    
586     optind = argc;
587     }
588    
589     /* If we have done all the ARGV-elements, stop the scan
590     and back over any non-options that we skipped and permuted. */
591    
592     if (optind == argc)
593     {
594     /* Set the next-arg-index to point at the non-options
595     that we previously skipped, so the caller will digest them. */
596     if (first_nonopt != last_nonopt)
597     optind = first_nonopt;
598     return -1;
599     }
600    
601     /* If we have come to a non-option and did not permute it,
602     either stop the scan or describe it to the caller and pass it by. */
603    
604     if (NONOPTION_P)
605     {
606     if (ordering == REQUIRE_ORDER)
607     return -1;
608     optarg = argv[optind++];
609     return 1;
610     }
611    
612     /* We have found another option-ARGV-element.
613     Skip the initial punctuation. */
614    
615     nextchar = (argv[optind] + 1
616     + (longopts != NULL && argv[optind][1] == '-'));
617     }
618    
619     /* Decode the current option-ARGV-element. */
620    
621     /* Check whether the ARGV-element is a long option.
622    
623     If long_only and the ARGV-element has the form "-f", where f is
624     a valid short option, don't consider it an abbreviated form of
625     a long option that starts with f. Otherwise there would be no
626     way to give the -f short option.
627    
628     On the other hand, if there's a long option "fubar" and
629     the ARGV-element is "-fu", do consider that an abbreviation of
630     the long option, just like "--fu", and not "-f" with arg "u".
631    
632     This distinction seems to be the most useful approach. */
633    
634     if (longopts != NULL
635     && (argv[optind][1] == '-'
636     || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
637     {
638     char *nameend;
639     const struct option *p;
640     const struct option *pfound = NULL;
641     int exact = 0;
642     int ambig = 0;
643     int indfound = -1;
644     int option_index;
645    
646     for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
647     /* Do nothing. */ ;
648    
649     /* Test all long options for either exact match
650     or abbreviated matches. */
651     for (p = longopts, option_index = 0; p->name; p++, option_index++)
652     if (!strncmp (p->name, nextchar, nameend - nextchar))
653     {
654     if ((unsigned int) (nameend - nextchar)
655     == (unsigned int) strlen (p->name))
656     {
657     /* Exact match found. */
658     pfound = p;
659     indfound = option_index;
660     exact = 1;
661     break;
662     }
663     else if (pfound == NULL)
664     {
665     /* First nonexact match found. */
666     pfound = p;
667     indfound = option_index;
668     }
669     else
670     /* Second or later nonexact match found. */
671     ambig = 1;
672     }
673    
674     if (ambig && !exact)
675     {
676     if (opterr)
677     fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
678     argv[0], argv[optind]);
679     nextchar += strlen (nextchar);
680     optind++;
681     optopt = 0;
682     return '?';
683     }
684    
685     if (pfound != NULL)
686     {
687     option_index = indfound;
688     optind++;
689     if (*nameend)
690     {
691     /* Don't test has_arg with >, because some C compilers don't
692     allow it to be used on enums. */
693     if (pfound->has_arg)
694     optarg = nameend + 1;
695     else
696     {
697     if (opterr)
698     {
699     if (argv[optind - 1][1] == '-')
700     /* --option */
701     fprintf (stderr,
702     _("%s: option `--%s' doesn't allow an argument\n"),
703     argv[0], pfound->name);
704     else
705     /* +option or -option */
706     fprintf (stderr,
707     _("%s: option `%c%s' doesn't allow an argument\n"),
708     argv[0], argv[optind - 1][0], pfound->name);
709     }
710    
711     nextchar += strlen (nextchar);
712    
713     optopt = pfound->val;
714     return '?';
715     }
716     }
717     else if (pfound->has_arg == 1)
718     {
719     if (optind < argc)
720     optarg = argv[optind++];
721     else
722     {
723     if (opterr)
724     fprintf (stderr,
725     _("%s: option `%s' requires an argument\n"),
726     argv[0], argv[optind - 1]);
727     nextchar += strlen (nextchar);
728     optopt = pfound->val;
729     return optstring[0] == ':' ? ':' : '?';
730     }
731     }
732     nextchar += strlen (nextchar);
733     if (longind != NULL)
734     *longind = option_index;
735     if (pfound->flag)
736     {
737     *(pfound->flag) = pfound->val;
738     return 0;
739     }
740     return pfound->val;
741     }
742    
743     /* Can't find it as a long option. If this is not getopt_long_only,
744     or the option starts with '--' or is not a valid short
745     option, then it's an error.
746     Otherwise interpret it as a short option. */
747     if (!long_only || argv[optind][1] == '-'
748     || my_index (optstring, *nextchar) == NULL)
749     {
750     if (opterr)
751     {
752     if (argv[optind][1] == '-')
753     /* --option */
754     fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
755     argv[0], nextchar);
756     else
757     /* +option or -option */
758     fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
759     argv[0], argv[optind][0], nextchar);
760     }
761     nextchar = (char *) "";
762     optind++;
763     optopt = 0;
764     return '?';
765     }
766     }
767    
768     /* Look at and handle the next short option-character. */
769    
770     {
771     char c = *nextchar++;
772     char *temp = my_index (optstring, c);
773    
774     /* Increment `optind' when we start to process its last character. */
775     if (*nextchar == '\0')
776     ++optind;
777    
778     if (temp == NULL || c == ':')
779     {
780     if (opterr)
781     {
782     if (posixly_correct)
783     /* 1003.2 specifies the format of this message. */
784     fprintf (stderr, _("%s: illegal option -- %c\n"),
785     argv[0], c);
786     else
787     fprintf (stderr, _("%s: invalid option -- %c\n"),
788     argv[0], c);
789     }
790     optopt = c;
791     return '?';
792     }
793     /* Convenience. Treat POSIX -W foo same as long option --foo */
794     if (temp[0] == 'W' && temp[1] == ';')
795     {
796     char *nameend;
797     const struct option *p;
798     const struct option *pfound = NULL;
799     int exact = 0;
800     int ambig = 0;
801     int indfound = 0;
802     int option_index;
803    
804     /* This is an option that requires an argument. */
805     if (*nextchar != '\0')
806     {
807     optarg = nextchar;
808     /* If we end this ARGV-element by taking the rest as an arg,
809     we must advance to the next element now. */
810     optind++;
811     }
812     else if (optind == argc)
813     {
814     if (opterr)
815     {
816     /* 1003.2 specifies the format of this message. */
817     fprintf (stderr, _("%s: option requires an argument -- %c\n"),
818     argv[0], c);
819     }
820     optopt = c;
821     if (optstring[0] == ':')
822     c = ':';
823     else
824     c = '?';
825     return c;
826     }
827     else
828     /* We already incremented `optind' once;
829     increment it again when taking next ARGV-elt as argument. */
830     optarg = argv[optind++];
831    
832     /* optarg is now the argument, see if it's in the
833     table of longopts. */
834    
835     for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
836     /* Do nothing. */ ;
837    
838     /* Test all long options for either exact match
839     or abbreviated matches. */
840     for (p = longopts, option_index = 0; p->name; p++, option_index++)
841     if (!strncmp (p->name, nextchar, nameend - nextchar))
842     {
843     if ((unsigned int) (nameend - nextchar) == strlen (p->name))
844     {
845     /* Exact match found. */
846     pfound = p;
847     indfound = option_index;
848     exact = 1;
849     break;
850     }
851     else if (pfound == NULL)
852     {
853     /* First nonexact match found. */
854     pfound = p;
855     indfound = option_index;
856     }
857     else
858     /* Second or later nonexact match found. */
859     ambig = 1;
860     }
861     if (ambig && !exact)
862     {
863     if (opterr)
864     fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
865     argv[0], argv[optind]);
866     nextchar += strlen (nextchar);
867     optind++;
868     return '?';
869     }
870     if (pfound != NULL)
871     {
872     option_index = indfound;
873     if (*nameend)
874     {
875     /* Don't test has_arg with >, because some C compilers don't
876     allow it to be used on enums. */
877     if (pfound->has_arg)
878     optarg = nameend + 1;
879     else
880     {
881     if (opterr)
882     fprintf (stderr, _("\
883     %s: option `-W %s' doesn't allow an argument\n"),
884     argv[0], pfound->name);
885    
886     nextchar += strlen (nextchar);
887     return '?';
888     }
889     }
890     else if (pfound->has_arg == 1)
891     {
892     if (optind < argc)
893     optarg = argv[optind++];
894     else
895     {
896     if (opterr)
897     fprintf (stderr,
898     _("%s: option `%s' requires an argument\n"),
899     argv[0], argv[optind - 1]);
900     nextchar += strlen (nextchar);
901     return optstring[0] == ':' ? ':' : '?';
902     }
903     }
904     nextchar += strlen (nextchar);
905     if (longind != NULL)
906     *longind = option_index;
907     if (pfound->flag)
908     {
909     *(pfound->flag) = pfound->val;
910     return 0;
911     }
912     return pfound->val;
913     }
914     nextchar = NULL;
915     return 'W'; /* Let the application handle it. */
916     }
917     if (temp[1] == ':')
918     {
919     if (temp[2] == ':')
920     {
921     /* This is an option that accepts an argument optionally. */
922     if (*nextchar != '\0')
923     {
924     optarg = nextchar;
925     optind++;
926     }
927     else
928     optarg = NULL;
929     nextchar = NULL;
930     }
931     else
932     {
933     /* This is an option that requires an argument. */
934     if (*nextchar != '\0')
935     {
936     optarg = nextchar;
937     /* If we end this ARGV-element by taking the rest as an arg,
938     we must advance to the next element now. */
939     optind++;
940     }
941     else if (optind == argc)
942     {
943     if (opterr)
944     {
945     /* 1003.2 specifies the format of this message. */
946     fprintf (stderr,
947     _("%s: option requires an argument -- %c\n"),
948     argv[0], c);
949     }
950     optopt = c;
951     if (optstring[0] == ':')
952     c = ':';
953     else
954     c = '?';
955     }
956     else
957     /* We already incremented `optind' once;
958     increment it again when taking next ARGV-elt as argument. */
959     optarg = argv[optind++];
960     nextchar = NULL;
961     }
962     }
963     return c;
964     }
965     }
966    
967     int
968     getopt (argc, argv, optstring)
969     int argc;
970     char *const *argv;
971     const char *optstring;
972     {
973     return _getopt_internal (argc, argv, optstring,
974     (const struct option *) 0,
975     (int *) 0,
976     0);
977     }
978    
979     #endif /* Not ELIDE_CODE. */
980    
981     #ifdef TEST
982    
983     /* Compile with -DTEST to make an executable for use in testing
984     the above definition of `getopt'. */
985    
986     int
987     main (argc, argv)
988     int argc;
989     char **argv;
990     {
991     int c;
992     int digit_optind = 0;
993    
994     while (1)
995     {
996     int this_option_optind = optind ? optind : 1;
997    
998     c = getopt (argc, argv, "abc:d:0123456789");
999     if (c == -1)
1000     break;
1001    
1002     switch (c)
1003     {
1004     case '0':
1005     case '1':
1006     case '2':
1007     case '3':
1008     case '4':
1009     case '5':
1010     case '6':
1011     case '7':
1012     case '8':
1013     case '9':
1014     if (digit_optind != 0 && digit_optind != this_option_optind)
1015     printf ("digits occur in two different argv-elements.\n");
1016     digit_optind = this_option_optind;
1017     printf ("option %c\n", c);
1018     break;
1019    
1020     case 'a':
1021     printf ("option a\n");
1022     break;
1023    
1024     case 'b':
1025     printf ("option b\n");
1026     break;
1027    
1028     case 'c':
1029     printf ("option c with value `%s'\n", optarg);
1030     break;
1031    
1032     case '?':
1033     break;
1034    
1035     default:
1036     printf ("?? getopt returned character code 0%o ??\n", c);
1037     }
1038     }
1039    
1040     if (optind < argc)
1041     {
1042     printf ("non-option ARGV-elements: ");
1043     while (optind < argc)
1044     printf ("%s ", argv[optind++]);
1045     printf ("\n");
1046     }
1047    
1048     exit (0);
1049     }
1050    
1051     #endif /* TEST */

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26