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