/[LeafOK_CVS]/pvpgn-1.7.4/src/compat/getopt.c
ViewVC logotype

Annotation of /pvpgn-1.7.4/src/compat/getopt.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

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

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1