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