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