]>
Commit | Line | Data |
---|---|---|
28f540f4 | 1 | /* Getopt for GNU. |
688903eb | 2 | Copyright (C) 1987-2018 Free Software Foundation, Inc. |
06576cbf ZW |
3 | This file is part of the GNU C Library and is also part of gnulib. |
4 | Patches to this file should be submitted to both projects. | |
28f540f4 | 5 | |
7e3be507 | 6 | The GNU C Library is free software; you can redistribute it and/or |
41bdb6e2 AJ |
7 | modify it under the terms of the GNU Lesser General Public |
8 | License as published by the Free Software Foundation; either | |
9 | version 2.1 of the License, or (at your option) any later version. | |
7e3be507 UD |
10 | |
11 | The GNU C Library is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 14 | Lesser General Public License for more details. |
7e3be507 | 15 | |
41bdb6e2 | 16 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
17 | License along with the GNU C Library; if not, see |
18 | <http://www.gnu.org/licenses/>. */ | |
28f540f4 | 19 | \f |
7f71f9c1 | 20 | #ifndef _LIBC |
8619129f | 21 | # include <config.h> |
28f540f4 RM |
22 | #endif |
23 | ||
7f71f9c1 | 24 | #include "getopt.h" |
28f540f4 | 25 | |
7f71f9c1 ZW |
26 | #include <stdio.h> |
27 | #include <stdlib.h> | |
511676f7 | 28 | #include <string.h> |
544ce845 | 29 | #include <unistd.h> |
511676f7 | 30 | |
511676f7 | 31 | #ifdef _LIBC |
544ce845 ZW |
32 | /* When used as part of glibc, error printing must be done differently |
33 | for standards compliance. getopt is not a cancellation point, so | |
34 | it must not call functions that are, and it is specified by an | |
35 | older standard than stdio locking, so it must not refer to | |
36 | functions in the "user namespace" related to stdio locking. | |
37 | Finally, it must use glibc's internal message translation so that | |
38 | the messages are looked up in the proper text domain. */ | |
511676f7 | 39 | # include <libintl.h> |
544ce845 ZW |
40 | # define fprintf __fxprintf_nocancel |
41 | # define flockfile(fp) _IO_flockfile (fp) | |
42 | # define funlockfile(fp) _IO_funlockfile (fp) | |
511676f7 UD |
43 | #else |
44 | # include "gettext.h" | |
d682a515 | 45 | # define _(msgid) gettext (msgid) |
544ce845 ZW |
46 | /* When used standalone, flockfile and funlockfile might not be |
47 | available. */ | |
48 | # ifndef _POSIX_THREAD_SAFE_FUNCTIONS | |
49 | # define flockfile(fp) /* nop */ | |
50 | # define funlockfile(fp) /* nop */ | |
51 | # endif | |
aeacb9f9 ZW |
52 | /* When used standalone, do not attempt to use alloca. */ |
53 | # define __libc_use_alloca(size) 0 | |
54 | # undef alloca | |
55 | # define alloca(size) (abort (), (void *)0) | |
511676f7 | 56 | #endif |
511676f7 | 57 | |
7f71f9c1 ZW |
58 | /* This implementation of 'getopt' has three modes for handling |
59 | options interspersed with non-option arguments. It can stop | |
60 | scanning for options at the first non-option argument encountered, | |
61 | as POSIX specifies. It can continue scanning for options after the | |
62 | first non-option argument, but permute 'argv' as it goes so that, | |
63 | after 'getopt' is done, all the options precede all the non-option | |
64 | arguments and 'optind' points to the first non-option argument. | |
65 | Or, it can report non-option arguments as if they were arguments to | |
66 | the option character '\x01'. | |
67 | ||
68 | The default behavior of 'getopt_long' is to permute the argument list. | |
69 | When this implementation is used standalone, the default behavior of | |
70 | 'getopt' is to stop at the first non-option argument, but when it is | |
71 | used as part of GNU libc it also permutes the argument list. In both | |
72 | cases, setting the environment variable POSIXLY_CORRECT to any value | |
73 | disables permutation. | |
74 | ||
75 | If the first character of the OPTSTRING argument to 'getopt' or | |
76 | 'getopt_long' is '+', both functions will stop at the first | |
77 | non-option argument. If it is '-', both functions will report | |
78 | non-option arguments as arguments to the option character '\x01'. */ | |
28f540f4 | 79 | |
511676f7 | 80 | #include "getopt_int.h" |
28f540f4 | 81 | |
7784135e ZW |
82 | /* For communication from 'getopt' to the caller. |
83 | When 'getopt' finds an option that takes an argument, | |
28f540f4 | 84 | the argument value is returned here. |
7784135e | 85 | Also, when 'ordering' is RETURN_IN_ORDER, |
28f540f4 RM |
86 | each non-option ARGV-element is returned here. */ |
87 | ||
c4563d2d | 88 | char *optarg; |
28f540f4 RM |
89 | |
90 | /* Index in ARGV of the next element to be scanned. | |
91 | This is used for communication to and from the caller | |
7784135e | 92 | and for communication between successive calls to 'getopt'. |
28f540f4 | 93 | |
7784135e | 94 | On entry to 'getopt', zero means this is the first call; initialize. |
28f540f4 | 95 | |
7784135e | 96 | When 'getopt' returns -1, this is the index of the first of the |
28f540f4 RM |
97 | non-option elements that the caller should itself scan. |
98 | ||
7784135e | 99 | Otherwise, 'optind' communicates from one call to the next |
28f540f4 RM |
100 | how much of ARGV has been scanned so far. */ |
101 | ||
d38cd08c UD |
102 | /* 1003.2 says this must be 1 before any call. */ |
103 | int optind = 1; | |
104 | ||
28f540f4 RM |
105 | /* Callers store zero here to inhibit the error message |
106 | for unrecognized options. */ | |
107 | ||
108 | int opterr = 1; | |
109 | ||
110 | /* Set to an option character which was unrecognized. | |
111 | This must be initialized on some systems to avoid linking in the | |
112 | system's own getopt implementation. */ | |
113 | ||
114 | int optopt = '?'; | |
115 | ||
511676f7 | 116 | /* Keep a global copy of all internal members of getopt_data. */ |
28f540f4 | 117 | |
511676f7 | 118 | static struct _getopt_data getopt_data; |
28f540f4 | 119 | \f |
28f540f4 RM |
120 | /* Exchange two adjacent subsequences of ARGV. |
121 | One subsequence is elements [first_nonopt,last_nonopt) | |
122 | which contains all the non-options that have been skipped so far. | |
123 | The other is elements [last_nonopt,optind), which contains all | |
124 | the options processed since those non-options were skipped. | |
125 | ||
7784135e | 126 | 'first_nonopt' and 'last_nonopt' are relocated so that they describe |
28f540f4 RM |
127 | the new indices of the non-options in ARGV after they are moved. */ |
128 | ||
129 | static void | |
511676f7 | 130 | exchange (char **argv, struct _getopt_data *d) |
28f540f4 | 131 | { |
511676f7 UD |
132 | int bottom = d->__first_nonopt; |
133 | int middle = d->__last_nonopt; | |
134 | int top = d->optind; | |
28f540f4 RM |
135 | char *tem; |
136 | ||
137 | /* Exchange the shorter segment with the far end of the longer segment. | |
138 | That puts the shorter segment into the right place. | |
139 | It leaves the longer segment in the right place overall, | |
140 | but it consists of two parts that need to be swapped next. */ | |
141 | ||
142 | while (top > middle && middle > bottom) | |
143 | { | |
144 | if (top - middle > middle - bottom) | |
145 | { | |
146 | /* Bottom segment is the short one. */ | |
147 | int len = middle - bottom; | |
2e09a79a | 148 | int i; |
28f540f4 RM |
149 | |
150 | /* Swap it with the top part of the top segment. */ | |
151 | for (i = 0; i < len; i++) | |
152 | { | |
153 | tem = argv[bottom + i]; | |
154 | argv[bottom + i] = argv[top - (middle - bottom) + i]; | |
155 | argv[top - (middle - bottom) + i] = tem; | |
156 | } | |
157 | /* Exclude the moved bottom segment from further swapping. */ | |
158 | top -= len; | |
159 | } | |
160 | else | |
161 | { | |
162 | /* Top segment is the short one. */ | |
163 | int len = top - middle; | |
2e09a79a | 164 | int i; |
28f540f4 RM |
165 | |
166 | /* Swap it with the bottom part of the bottom segment. */ | |
167 | for (i = 0; i < len; i++) | |
168 | { | |
169 | tem = argv[bottom + i]; | |
170 | argv[bottom + i] = argv[middle + i]; | |
171 | argv[middle + i] = tem; | |
172 | } | |
173 | /* Exclude the moved top segment from further swapping. */ | |
174 | bottom += len; | |
175 | } | |
176 | } | |
177 | ||
178 | /* Update records for the slots the non-options now occupy. */ | |
179 | ||
511676f7 UD |
180 | d->__first_nonopt += (d->optind - d->__last_nonopt); |
181 | d->__last_nonopt = d->optind; | |
28f540f4 RM |
182 | } |
183 | ||
dfbea09f ZW |
184 | /* Process the argument starting with d->__nextchar as a long option. |
185 | d->optind should *not* have been advanced over this argument. | |
186 | ||
187 | If the value returned is -1, it was not actually a long option, the | |
188 | state is unchanged, and the argument should be processed as a set | |
189 | of short options (this can only happen when long_only is true). | |
190 | Otherwise, the option (and its argument, if any) have been consumed | |
191 | and the return value is the value to return from _getopt_internal_r. */ | |
192 | static int | |
193 | process_long_option (int argc, char **argv, const char *optstring, | |
194 | const struct option *longopts, int *longind, | |
195 | int long_only, struct _getopt_data *d, | |
196 | int print_errors, const char *prefix) | |
197 | { | |
198 | char *nameend; | |
199 | size_t namelen; | |
200 | const struct option *p; | |
201 | const struct option *pfound = NULL; | |
aeacb9f9 | 202 | int n_options; |
dfbea09f ZW |
203 | int option_index; |
204 | ||
205 | for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) | |
206 | /* Do nothing. */ ; | |
207 | namelen = nameend - d->__nextchar; | |
208 | ||
aeacb9f9 ZW |
209 | /* First look for an exact match, counting the options as a side |
210 | effect. */ | |
211 | for (p = longopts, n_options = 0; p->name; p++, n_options++) | |
212 | if (!strncmp (p->name, d->__nextchar, namelen) | |
213 | && namelen == strlen (p->name)) | |
dfbea09f | 214 | { |
aeacb9f9 ZW |
215 | /* Exact match found. */ |
216 | pfound = p; | |
217 | option_index = n_options; | |
218 | break; | |
dfbea09f ZW |
219 | } |
220 | ||
aeacb9f9 | 221 | if (pfound == NULL) |
dfbea09f | 222 | { |
aeacb9f9 ZW |
223 | /* Didn't find an exact match, so look for abbreviations. */ |
224 | unsigned char *ambig_set = NULL; | |
225 | int ambig_malloced = 0; | |
226 | int ambig_fallback = 0; | |
227 | int indfound = -1; | |
228 | ||
229 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | |
230 | if (!strncmp (p->name, d->__nextchar, namelen)) | |
231 | { | |
232 | if (pfound == NULL) | |
233 | { | |
234 | /* First nonexact match found. */ | |
235 | pfound = p; | |
236 | indfound = option_index; | |
237 | } | |
238 | else if (long_only | |
239 | || pfound->has_arg != p->has_arg | |
240 | || pfound->flag != p->flag | |
241 | || pfound->val != p->val) | |
242 | { | |
243 | /* Second or later nonexact match found. */ | |
244 | if (!ambig_fallback) | |
245 | { | |
246 | if (!print_errors) | |
247 | /* Don't waste effort tracking the ambig set if | |
248 | we're not going to print it anyway. */ | |
249 | ambig_fallback = 1; | |
250 | else if (!ambig_set) | |
251 | { | |
252 | if (__libc_use_alloca (n_options)) | |
253 | ambig_set = alloca (n_options); | |
254 | else if ((ambig_set = malloc (n_options)) == NULL) | |
255 | /* Fall back to simpler error message. */ | |
256 | ambig_fallback = 1; | |
257 | else | |
258 | ambig_malloced = 1; | |
259 | ||
260 | if (ambig_set) | |
261 | { | |
262 | memset (ambig_set, 0, n_options); | |
263 | ambig_set[indfound] = 1; | |
264 | } | |
265 | } | |
266 | if (ambig_set) | |
267 | ambig_set[option_index] = 1; | |
268 | } | |
269 | } | |
270 | } | |
271 | ||
272 | if (ambig_set || ambig_fallback) | |
273 | { | |
274 | if (print_errors) | |
275 | { | |
276 | if (ambig_fallback) | |
277 | fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), | |
278 | argv[0], prefix, d->__nextchar); | |
279 | else | |
280 | { | |
281 | flockfile (stderr); | |
282 | fprintf (stderr, | |
283 | _("%s: option '%s%s' is ambiguous; possibilities:"), | |
284 | argv[0], prefix, d->__nextchar); | |
285 | ||
286 | for (option_index = 0; option_index < n_options; option_index++) | |
287 | if (ambig_set[option_index]) | |
288 | fprintf (stderr, " '%s%s'", | |
289 | prefix, longopts[option_index].name); | |
290 | ||
291 | /* This must use 'fprintf' even though it's only | |
292 | printing a single character, so that it goes through | |
293 | __fxprintf_nocancel when compiled as part of glibc. */ | |
294 | fprintf (stderr, "\n"); | |
295 | funlockfile (stderr); | |
296 | } | |
297 | } | |
298 | if (ambig_malloced) | |
299 | free (ambig_set); | |
300 | d->__nextchar += strlen (d->__nextchar); | |
301 | d->optind++; | |
302 | d->optopt = 0; | |
303 | return '?'; | |
304 | } | |
305 | ||
306 | option_index = indfound; | |
dfbea09f ZW |
307 | } |
308 | ||
aeacb9f9 | 309 | if (pfound == NULL) |
dfbea09f | 310 | { |
aeacb9f9 ZW |
311 | /* Can't find it as a long option. If this is not getopt_long_only, |
312 | or the option starts with '--' or is not a valid short option, | |
313 | then it's an error. */ | |
314 | if (!long_only || argv[d->optind][1] == '-' | |
315 | || strchr (optstring, *d->__nextchar) == NULL) | |
316 | { | |
317 | if (print_errors) | |
318 | fprintf (stderr, _("%s: unrecognized option '%s%s'\n"), | |
319 | argv[0], prefix, d->__nextchar); | |
320 | ||
321 | d->__nextchar = NULL; | |
322 | d->optind++; | |
323 | d->optopt = 0; | |
324 | return '?'; | |
325 | } | |
326 | ||
327 | /* Otherwise interpret it as a short option. */ | |
328 | return -1; | |
dfbea09f ZW |
329 | } |
330 | ||
aeacb9f9 ZW |
331 | /* We have found a matching long option. Consume it. */ |
332 | d->optind++; | |
333 | d->__nextchar = NULL; | |
334 | if (*nameend) | |
335 | { | |
336 | /* Don't test has_arg with >, because some C compilers don't | |
337 | allow it to be used on enums. */ | |
338 | if (pfound->has_arg) | |
339 | d->optarg = nameend + 1; | |
340 | else | |
341 | { | |
342 | if (print_errors) | |
343 | fprintf (stderr, | |
344 | _("%s: option '%s%s' doesn't allow an argument\n"), | |
345 | argv[0], prefix, pfound->name); | |
346 | ||
347 | d->optopt = pfound->val; | |
348 | return '?'; | |
349 | } | |
350 | } | |
351 | else if (pfound->has_arg == 1) | |
dfbea09f | 352 | { |
aeacb9f9 ZW |
353 | if (d->optind < argc) |
354 | d->optarg = argv[d->optind++]; | |
355 | else | |
356 | { | |
357 | if (print_errors) | |
358 | fprintf (stderr, | |
359 | _("%s: option '%s%s' requires an argument\n"), | |
360 | argv[0], prefix, pfound->name); | |
361 | ||
362 | d->optopt = pfound->val; | |
363 | return optstring[0] == ':' ? ':' : '?'; | |
364 | } | |
dfbea09f ZW |
365 | } |
366 | ||
aeacb9f9 ZW |
367 | if (longind != NULL) |
368 | *longind = option_index; | |
369 | if (pfound->flag) | |
370 | { | |
371 | *(pfound->flag) = pfound->val; | |
372 | return 0; | |
373 | } | |
374 | return pfound->val; | |
dfbea09f ZW |
375 | } |
376 | ||
377 | /* Initialize internal data upon the first call to getopt. */ | |
28f540f4 RM |
378 | |
379 | static const char * | |
0f3be872 ZW |
380 | _getopt_initialize (int argc _GL_UNUSED, |
381 | char **argv _GL_UNUSED, const char *optstring, | |
2e6d6bac | 382 | struct _getopt_data *d, int posixly_correct) |
28f540f4 RM |
383 | { |
384 | /* Start processing options with ARGV-element 1 (since ARGV-element 0 | |
385 | is the program name); the sequence of previously skipped | |
386 | non-option ARGV-elements is empty. */ | |
c1af8775 ZW |
387 | if (d->optind == 0) |
388 | d->optind = 1; | |
28f540f4 | 389 | |
511676f7 | 390 | d->__first_nonopt = d->__last_nonopt = d->optind; |
511676f7 | 391 | d->__nextchar = NULL; |
28f540f4 | 392 | |
28f540f4 | 393 | /* Determine how to handle the ordering of options and nonoptions. */ |
28f540f4 RM |
394 | if (optstring[0] == '-') |
395 | { | |
511676f7 | 396 | d->__ordering = RETURN_IN_ORDER; |
28f540f4 RM |
397 | ++optstring; |
398 | } | |
399 | else if (optstring[0] == '+') | |
400 | { | |
511676f7 | 401 | d->__ordering = REQUIRE_ORDER; |
28f540f4 RM |
402 | ++optstring; |
403 | } | |
c1af8775 | 404 | else if (posixly_correct || !!getenv ("POSIXLY_CORRECT")) |
511676f7 | 405 | d->__ordering = REQUIRE_ORDER; |
28f540f4 | 406 | else |
511676f7 | 407 | d->__ordering = PERMUTE; |
28f540f4 | 408 | |
c1af8775 | 409 | d->__initialized = 1; |
28f540f4 RM |
410 | return optstring; |
411 | } | |
412 | \f | |
413 | /* Scan elements of ARGV (whose length is ARGC) for option characters | |
414 | given in OPTSTRING. | |
415 | ||
416 | If an element of ARGV starts with '-', and is not exactly "-" or "--", | |
417 | then it is an option element. The characters of this element | |
7784135e | 418 | (aside from the initial '-') are option characters. If 'getopt' |
28f540f4 RM |
419 | is called repeatedly, it returns successively each of the option characters |
420 | from each of the option elements. | |
421 | ||
7784135e ZW |
422 | If 'getopt' finds another option character, it returns that character, |
423 | updating 'optind' and 'nextchar' so that the next call to 'getopt' can | |
28f540f4 RM |
424 | resume the scan with the following option character or ARGV-element. |
425 | ||
7784135e ZW |
426 | If there are no more option characters, 'getopt' returns -1. |
427 | Then 'optind' is the index in ARGV of the first ARGV-element | |
28f540f4 RM |
428 | that is not an option. (The ARGV-elements have been permuted |
429 | so that those that are not options now come last.) | |
430 | ||
431 | OPTSTRING is a string containing the legitimate option characters. | |
432 | If an option character is seen that is not listed in OPTSTRING, | |
7784135e | 433 | return '?' after printing an error message. If you set 'opterr' to |
28f540f4 RM |
434 | zero, the error message is suppressed but we still return '?'. |
435 | ||
436 | If a char in OPTSTRING is followed by a colon, that means it wants an arg, | |
437 | so the following text in the same ARGV-element, or the text of the following | |
7784135e | 438 | ARGV-element, is returned in 'optarg'. Two colons mean an option that |
28f540f4 | 439 | wants an optional arg; if there is text in the current ARGV-element, |
7784135e | 440 | it is returned in 'optarg', otherwise 'optarg' is set to zero. |
28f540f4 | 441 | |
7784135e | 442 | If OPTSTRING starts with '-' or '+', it requests different methods of |
28f540f4 RM |
443 | handling the non-option ARGV-elements. |
444 | See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. | |
445 | ||
7784135e | 446 | Long-named options begin with '--' instead of '-'. |
28f540f4 RM |
447 | Their names may be abbreviated as long as the abbreviation is unique |
448 | or is an exact match for some defined option. If they have an | |
449 | argument, it follows the option name in the same ARGV-element, separated | |
7784135e ZW |
450 | from the option name by a '=', or else the in next ARGV-element. |
451 | When 'getopt' finds a long-named option, it returns 0 if that option's | |
452 | 'flag' field is nonzero, the value of the option's 'val' field | |
453 | if the 'flag' field is zero. | |
28f540f4 RM |
454 | |
455 | The elements of ARGV aren't really const, because we permute them. | |
456 | But we pretend they're const in the prototype to be compatible | |
457 | with other systems. | |
458 | ||
7784135e | 459 | LONGOPTS is a vector of 'struct option' terminated by an |
28f540f4 RM |
460 | element containing a name which is zero. |
461 | ||
462 | LONGIND returns the index in LONGOPT of the long-named option found. | |
463 | It is only valid when a long-named option has been found by the most | |
464 | recent call. | |
465 | ||
466 | If LONG_ONLY is nonzero, '-' as well as '--' can introduce | |
467 | long-named options. */ | |
468 | ||
469 | int | |
7a7be6c9 | 470 | _getopt_internal_r (int argc, char **argv, const char *optstring, |
511676f7 | 471 | const struct option *longopts, int *longind, |
2e6d6bac | 472 | int long_only, struct _getopt_data *d, int posixly_correct) |
28f540f4 | 473 | { |
511676f7 | 474 | int print_errors = d->opterr; |
dcaa768e | 475 | |
05c54d4c UD |
476 | if (argc < 1) |
477 | return -1; | |
478 | ||
511676f7 | 479 | d->optarg = NULL; |
28f540f4 | 480 | |
511676f7 | 481 | if (d->optind == 0 || !d->__initialized) |
c1af8775 | 482 | optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct); |
66b93be7 EB |
483 | else if (optstring[0] == '-' || optstring[0] == '+') |
484 | optstring++; | |
c1af8775 | 485 | |
66b93be7 EB |
486 | if (optstring[0] == ':') |
487 | print_errors = 0; | |
28f540f4 | 488 | |
bf079e19 ZW |
489 | /* Test whether ARGV[optind] points to a non-option argument. */ |
490 | #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') | |
b07c5668 | 491 | |
511676f7 | 492 | if (d->__nextchar == NULL || *d->__nextchar == '\0') |
28f540f4 RM |
493 | { |
494 | /* Advance to the next ARGV-element. */ | |
495 | ||
e335fa38 MB |
496 | /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been |
497 | moved back by the user (who may also have changed the arguments). */ | |
511676f7 UD |
498 | if (d->__last_nonopt > d->optind) |
499 | d->__last_nonopt = d->optind; | |
500 | if (d->__first_nonopt > d->optind) | |
501 | d->__first_nonopt = d->optind; | |
e335fa38 | 502 | |
511676f7 | 503 | if (d->__ordering == PERMUTE) |
28f540f4 RM |
504 | { |
505 | /* If we have just processed some options following some non-options, | |
506 | exchange them so that the options come first. */ | |
507 | ||
511676f7 UD |
508 | if (d->__first_nonopt != d->__last_nonopt |
509 | && d->__last_nonopt != d->optind) | |
7a7be6c9 | 510 | exchange (argv, d); |
511676f7 UD |
511 | else if (d->__last_nonopt != d->optind) |
512 | d->__first_nonopt = d->optind; | |
28f540f4 RM |
513 | |
514 | /* Skip any additional non-options | |
515 | and extend the range of non-options previously skipped. */ | |
516 | ||
511676f7 UD |
517 | while (d->optind < argc && NONOPTION_P) |
518 | d->optind++; | |
519 | d->__last_nonopt = d->optind; | |
28f540f4 RM |
520 | } |
521 | ||
7784135e | 522 | /* The special ARGV-element '--' means premature end of options. |
28f540f4 RM |
523 | Skip it like a null option, |
524 | then exchange with previous non-options as if it were an option, | |
525 | then skip everything else like a non-option. */ | |
526 | ||
511676f7 | 527 | if (d->optind != argc && !strcmp (argv[d->optind], "--")) |
28f540f4 | 528 | { |
511676f7 | 529 | d->optind++; |
28f540f4 | 530 | |
511676f7 UD |
531 | if (d->__first_nonopt != d->__last_nonopt |
532 | && d->__last_nonopt != d->optind) | |
7a7be6c9 | 533 | exchange (argv, d); |
511676f7 UD |
534 | else if (d->__first_nonopt == d->__last_nonopt) |
535 | d->__first_nonopt = d->optind; | |
536 | d->__last_nonopt = argc; | |
28f540f4 | 537 | |
511676f7 | 538 | d->optind = argc; |
28f540f4 RM |
539 | } |
540 | ||
541 | /* If we have done all the ARGV-elements, stop the scan | |
542 | and back over any non-options that we skipped and permuted. */ | |
543 | ||
511676f7 | 544 | if (d->optind == argc) |
28f540f4 RM |
545 | { |
546 | /* Set the next-arg-index to point at the non-options | |
547 | that we previously skipped, so the caller will digest them. */ | |
511676f7 UD |
548 | if (d->__first_nonopt != d->__last_nonopt) |
549 | d->optind = d->__first_nonopt; | |
1ef32c3d | 550 | return -1; |
28f540f4 RM |
551 | } |
552 | ||
553 | /* If we have come to a non-option and did not permute it, | |
554 | either stop the scan or describe it to the caller and pass it by. */ | |
555 | ||
b07c5668 | 556 | if (NONOPTION_P) |
28f540f4 | 557 | { |
511676f7 | 558 | if (d->__ordering == REQUIRE_ORDER) |
1ef32c3d | 559 | return -1; |
511676f7 | 560 | d->optarg = argv[d->optind++]; |
28f540f4 RM |
561 | return 1; |
562 | } | |
563 | ||
564 | /* We have found another option-ARGV-element. | |
dfbea09f ZW |
565 | Check whether it might be a long option. */ |
566 | if (longopts) | |
28f540f4 | 567 | { |
dfbea09f | 568 | if (argv[d->optind][1] == '-') |
51028f34 | 569 | { |
dfbea09f ZW |
570 | /* "--foo" is always a long option. The special option |
571 | "--" was handled above. */ | |
572 | d->__nextchar = argv[d->optind] + 2; | |
573 | return process_long_option (argc, argv, optstring, longopts, | |
574 | longind, long_only, d, | |
575 | print_errors, "--"); | |
576 | } | |
bd25564e | 577 | |
dfbea09f ZW |
578 | /* If long_only and the ARGV-element has the form "-f", |
579 | where f is a valid short option, don't consider it an | |
580 | abbreviated form of a long option that starts with f. | |
581 | Otherwise there would be no way to give the -f short | |
582 | option. | |
8dab36a1 | 583 | |
dfbea09f ZW |
584 | On the other hand, if there's a long option "fubar" and |
585 | the ARGV-element is "-fu", do consider that an | |
586 | abbreviation of the long option, just like "--fu", and | |
587 | not "-f" with arg "u". | |
28f540f4 | 588 | |
dfbea09f ZW |
589 | This distinction seems to be the most useful approach. */ |
590 | if (long_only && (argv[d->optind][2] | |
591 | || !strchr (optstring, argv[d->optind][1]))) | |
28f540f4 | 592 | { |
dfbea09f ZW |
593 | int code; |
594 | d->__nextchar = argv[d->optind] + 1; | |
595 | code = process_long_option (argc, argv, optstring, longopts, | |
596 | longind, long_only, d, | |
597 | print_errors, "-"); | |
598 | if (code != -1) | |
599 | return code; | |
28f540f4 | 600 | } |
28f540f4 RM |
601 | } |
602 | ||
dfbea09f ZW |
603 | /* It is not a long option. Skip the initial punctuation. */ |
604 | d->__nextchar = argv[d->optind] + 1; | |
28f540f4 RM |
605 | } |
606 | ||
607 | /* Look at and handle the next short option-character. */ | |
608 | ||
609 | { | |
511676f7 | 610 | char c = *d->__nextchar++; |
7f71f9c1 | 611 | const char *temp = strchr (optstring, c); |
28f540f4 | 612 | |
7784135e | 613 | /* Increment 'optind' when we start to process its last character. */ |
511676f7 UD |
614 | if (*d->__nextchar == '\0') |
615 | ++d->optind; | |
28f540f4 | 616 | |
cf0b6819 | 617 | if (temp == NULL || c == ':' || c == ';') |
28f540f4 | 618 | { |
dcaa768e | 619 | if (print_errors) |
544ce845 | 620 | fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c); |
511676f7 | 621 | d->optopt = c; |
28f540f4 RM |
622 | return '?'; |
623 | } | |
dfbea09f | 624 | |
11336c16 | 625 | /* Convenience. Treat POSIX -W foo same as long option --foo */ |
dfbea09f | 626 | if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL) |
11336c16 | 627 | { |
11336c16 | 628 | /* This is an option that requires an argument. */ |
511676f7 | 629 | if (*d->__nextchar != '\0') |
dfbea09f | 630 | d->optarg = d->__nextchar; |
511676f7 | 631 | else if (d->optind == argc) |
11336c16 | 632 | { |
dcaa768e | 633 | if (print_errors) |
544ce845 ZW |
634 | fprintf (stderr, |
635 | _("%s: option requires an argument -- '%c'\n"), | |
636 | argv[0], c); | |
8dab36a1 | 637 | |
511676f7 | 638 | d->optopt = c; |
11336c16 UD |
639 | if (optstring[0] == ':') |
640 | c = ':'; | |
641 | else | |
642 | c = '?'; | |
7e3be507 | 643 | return c; |
11336c16 UD |
644 | } |
645 | else | |
dfbea09f | 646 | d->optarg = argv[d->optind]; |
01636b21 | 647 | |
dfbea09f ZW |
648 | d->__nextchar = d->optarg; |
649 | d->optarg = NULL; | |
650 | return process_long_option (argc, argv, optstring, longopts, longind, | |
651 | 0 /* long_only */, d, print_errors, "-W "); | |
11336c16 | 652 | } |
28f540f4 RM |
653 | if (temp[1] == ':') |
654 | { | |
655 | if (temp[2] == ':') | |
656 | { | |
657 | /* This is an option that accepts an argument optionally. */ | |
511676f7 | 658 | if (*d->__nextchar != '\0') |
28f540f4 | 659 | { |
511676f7 UD |
660 | d->optarg = d->__nextchar; |
661 | d->optind++; | |
28f540f4 RM |
662 | } |
663 | else | |
511676f7 UD |
664 | d->optarg = NULL; |
665 | d->__nextchar = NULL; | |
28f540f4 RM |
666 | } |
667 | else | |
668 | { | |
669 | /* This is an option that requires an argument. */ | |
511676f7 | 670 | if (*d->__nextchar != '\0') |
28f540f4 | 671 | { |
511676f7 | 672 | d->optarg = d->__nextchar; |
28f540f4 RM |
673 | /* If we end this ARGV-element by taking the rest as an arg, |
674 | we must advance to the next element now. */ | |
511676f7 | 675 | d->optind++; |
28f540f4 | 676 | } |
511676f7 | 677 | else if (d->optind == argc) |
28f540f4 | 678 | { |
dcaa768e | 679 | if (print_errors) |
544ce845 ZW |
680 | fprintf (stderr, |
681 | _("%s: option requires an argument -- '%c'\n"), | |
682 | argv[0], c); | |
51028f34 | 683 | |
511676f7 | 684 | d->optopt = c; |
28f540f4 RM |
685 | if (optstring[0] == ':') |
686 | c = ':'; | |
687 | else | |
688 | c = '?'; | |
689 | } | |
690 | else | |
7784135e | 691 | /* We already incremented 'optind' once; |
28f540f4 | 692 | increment it again when taking next ARGV-elt as argument. */ |
511676f7 UD |
693 | d->optarg = argv[d->optind++]; |
694 | d->__nextchar = NULL; | |
28f540f4 RM |
695 | } |
696 | } | |
697 | return c; | |
698 | } | |
699 | } | |
700 | ||
701 | int | |
7a7be6c9 | 702 | _getopt_internal (int argc, char **argv, const char *optstring, |
2e6d6bac UD |
703 | const struct option *longopts, int *longind, int long_only, |
704 | int posixly_correct) | |
511676f7 UD |
705 | { |
706 | int result; | |
707 | ||
708 | getopt_data.optind = optind; | |
709 | getopt_data.opterr = opterr; | |
710 | ||
711 | result = _getopt_internal_r (argc, argv, optstring, longopts, | |
2e6d6bac UD |
712 | longind, long_only, &getopt_data, |
713 | posixly_correct); | |
511676f7 UD |
714 | |
715 | optind = getopt_data.optind; | |
716 | optarg = getopt_data.optarg; | |
717 | optopt = getopt_data.optopt; | |
718 | ||
719 | return result; | |
720 | } | |
721 | ||
7a7be6c9 ZW |
722 | /* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. |
723 | Standalone applications just get a POSIX-compliant getopt. | |
724 | POSIX and LSB both require these functions to take 'char *const *argv' | |
725 | even though this is incorrect (because of the permutation). */ | |
726 | #define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \ | |
727 | int \ | |
728 | NAME (int argc, char *const *argv, const char *optstring) \ | |
729 | { \ | |
730 | return _getopt_internal (argc, (char **)argv, optstring, \ | |
731 | 0, 0, 0, POSIXLY_CORRECT); \ | |
732 | } | |
28f540f4 | 733 | |
2e6d6bac | 734 | #ifdef _LIBC |
7a7be6c9 ZW |
735 | GETOPT_ENTRY(getopt, 0) |
736 | GETOPT_ENTRY(__posix_getopt, 1) | |
737 | #else | |
738 | GETOPT_ENTRY(getopt, 1) | |
2e6d6bac UD |
739 | #endif |
740 | ||
28f540f4 RM |
741 | \f |
742 | #ifdef TEST | |
743 | ||
744 | /* Compile with -DTEST to make an executable for use in testing | |
7784135e | 745 | the above definition of 'getopt'. */ |
28f540f4 RM |
746 | |
747 | int | |
511676f7 | 748 | main (int argc, char **argv) |
28f540f4 RM |
749 | { |
750 | int c; | |
751 | int digit_optind = 0; | |
752 | ||
753 | while (1) | |
754 | { | |
755 | int this_option_optind = optind ? optind : 1; | |
756 | ||
757 | c = getopt (argc, argv, "abc:d:0123456789"); | |
1ef32c3d | 758 | if (c == -1) |
28f540f4 RM |
759 | break; |
760 | ||
761 | switch (c) | |
762 | { | |
763 | case '0': | |
764 | case '1': | |
765 | case '2': | |
766 | case '3': | |
767 | case '4': | |
768 | case '5': | |
769 | case '6': | |
770 | case '7': | |
771 | case '8': | |
772 | case '9': | |
773 | if (digit_optind != 0 && digit_optind != this_option_optind) | |
774 | printf ("digits occur in two different argv-elements.\n"); | |
775 | digit_optind = this_option_optind; | |
776 | printf ("option %c\n", c); | |
777 | break; | |
778 | ||
779 | case 'a': | |
780 | printf ("option a\n"); | |
781 | break; | |
782 | ||
783 | case 'b': | |
784 | printf ("option b\n"); | |
785 | break; | |
786 | ||
787 | case 'c': | |
2127a186 | 788 | printf ("option c with value '%s'\n", optarg); |
28f540f4 RM |
789 | break; |
790 | ||
791 | case '?': | |
792 | break; | |
793 | ||
794 | default: | |
795 | printf ("?? getopt returned character code 0%o ??\n", c); | |
796 | } | |
797 | } | |
798 | ||
799 | if (optind < argc) | |
800 | { | |
801 | printf ("non-option ARGV-elements: "); | |
802 | while (optind < argc) | |
803 | printf ("%s ", argv[optind++]); | |
804 | printf ("\n"); | |
805 | } | |
806 | ||
807 | exit (0); | |
808 | } | |
809 | ||
810 | #endif /* TEST */ |