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