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