1 | /* Getopt for GNU. |
2 | Copyright (C) 1987-2021 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 | # ifndef _POSIX_THREAD_SAFE_FUNCTIONS |
49 | # define flockfile(fp) /* nop */ |
50 | # define funlockfile(fp) /* nop */ |
51 | # endif |
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) |
56 | #endif |
57 | |
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'. */ |
79 | |
80 | #include "getopt_int.h" |
81 | |
82 | /* For communication from 'getopt' to the caller. |
83 | When 'getopt' finds an option that takes an argument, |
84 | the argument value is returned here. |
85 | Also, when 'ordering' is RETURN_IN_ORDER, |
86 | each non-option ARGV-element is returned here. */ |
87 | |
88 | char *optarg; |
89 | |
90 | /* Index in ARGV of the next element to be scanned. |
91 | This is used for communication to and from the caller |
92 | and for communication between successive calls to 'getopt'. |
93 | |
94 | On entry to 'getopt', zero means this is the first call; initialize. |
95 | |
96 | When 'getopt' returns -1, this is the index of the first of the |
97 | non-option elements that the caller should itself scan. |
98 | |
99 | Otherwise, 'optind' communicates from one call to the next |
100 | how much of ARGV has been scanned so far. */ |
101 | |
102 | /* 1003.2 says this must be 1 before any call. */ |
103 | int optind = 1; |
104 | |
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 | |
116 | /* Keep a global copy of all internal members of getopt_data. */ |
117 | |
118 | static struct _getopt_data getopt_data; |
119 | |
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 | |
126 | 'first_nonopt' and 'last_nonopt' are relocated so that they describe |
127 | the new indices of the non-options in ARGV after they are moved. */ |
128 | |
129 | static void |
130 | exchange (char **argv, struct _getopt_data *d) |
131 | { |
132 | int bottom = d->__first_nonopt; |
133 | int middle = d->__last_nonopt; |
134 | int top = d->optind; |
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; |
148 | int i; |
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; |
164 | int i; |
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 | |
180 | d->__first_nonopt += (d->optind - d->__last_nonopt); |
181 | d->__last_nonopt = d->optind; |
182 | } |
183 | |
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; |
202 | int n_options; |
203 | int option_index; |
204 | |
205 | for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) |
206 | /* Do nothing. */ ; |
207 | namelen = nameend - d->__nextchar; |
208 | |
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)) |
214 | { |
215 | /* Exact match found. */ |
216 | pfound = p; |
217 | option_index = n_options; |
218 | break; |
219 | } |
220 | |
221 | if (pfound == NULL) |
222 | { |
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; |
307 | } |
308 | |
309 | if (pfound == NULL) |
310 | { |
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; |
329 | } |
330 | |
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) |
352 | { |
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 | } |
365 | } |
366 | |
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; |
375 | } |
376 | |
377 | /* Initialize internal data upon the first call to getopt. */ |
378 | |
379 | static const char * |
380 | _getopt_initialize (int argc _GL_UNUSED, |
381 | char **argv _GL_UNUSED, const char *optstring, |
382 | struct _getopt_data *d, int posixly_correct) |
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. */ |
387 | if (d->optind == 0) |
388 | d->optind = 1; |
389 | |
390 | d->__first_nonopt = d->__last_nonopt = d->optind; |
391 | d->__nextchar = NULL; |
392 | |
393 | /* Determine how to handle the ordering of options and nonoptions. */ |
394 | if (optstring[0] == '-') |
395 | { |
396 | d->__ordering = RETURN_IN_ORDER; |
397 | ++optstring; |
398 | } |
399 | else if (optstring[0] == '+') |
400 | { |
401 | d->__ordering = REQUIRE_ORDER; |
402 | ++optstring; |
403 | } |
404 | else if (posixly_correct || !!getenv ("POSIXLY_CORRECT" )) |
405 | d->__ordering = REQUIRE_ORDER; |
406 | else |
407 | d->__ordering = PERMUTE; |
408 | |
409 | d->__initialized = 1; |
410 | return optstring; |
411 | } |
412 | |
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 |
418 | (aside from the initial '-') are option characters. If 'getopt' |
419 | is called repeatedly, it returns successively each of the option characters |
420 | from each of the option elements. |
421 | |
422 | If 'getopt' finds another option character, it returns that character, |
423 | updating 'optind' and 'nextchar' so that the next call to 'getopt' can |
424 | resume the scan with the following option character or ARGV-element. |
425 | |
426 | If there are no more option characters, 'getopt' returns -1. |
427 | Then 'optind' is the index in ARGV of the first ARGV-element |
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, |
433 | return '?' after printing an error message. If you set 'opterr' to |
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 |
438 | ARGV-element, is returned in 'optarg'. Two colons mean an option that |
439 | wants an optional arg; if there is text in the current ARGV-element, |
440 | it is returned in 'optarg', otherwise 'optarg' is set to zero. |
441 | |
442 | If OPTSTRING starts with '-' or '+', it requests different methods of |
443 | handling the non-option ARGV-elements. |
444 | See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. |
445 | |
446 | Long-named options begin with '--' instead of '-'. |
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 |
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. |
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 | |
459 | LONGOPTS is a vector of 'struct option' terminated by an |
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 |
470 | _getopt_internal_r (int argc, char **argv, const char *optstring, |
471 | const struct option *longopts, int *longind, |
472 | int long_only, struct _getopt_data *d, int posixly_correct) |
473 | { |
474 | int print_errors = d->opterr; |
475 | |
476 | if (argc < 1) |
477 | return -1; |
478 | |
479 | d->optarg = NULL; |
480 | |
481 | if (d->optind == 0 || !d->__initialized) |
482 | optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct); |
483 | else if (optstring[0] == '-' || optstring[0] == '+') |
484 | optstring++; |
485 | |
486 | if (optstring[0] == ':') |
487 | print_errors = 0; |
488 | |
489 | /* Test whether ARGV[optind] points to a non-option argument. */ |
490 | #define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0') |
491 | |
492 | if (d->__nextchar == NULL || *d->__nextchar == '\0') |
493 | { |
494 | /* Advance to the next ARGV-element. */ |
495 | |
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). */ |
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; |
502 | |
503 | if (d->__ordering == PERMUTE) |
504 | { |
505 | /* If we have just processed some options following some non-options, |
506 | exchange them so that the options come first. */ |
507 | |
508 | if (d->__first_nonopt != d->__last_nonopt |
509 | && d->__last_nonopt != d->optind) |
510 | exchange (argv, d); |
511 | else if (d->__last_nonopt != d->optind) |
512 | d->__first_nonopt = d->optind; |
513 | |
514 | /* Skip any additional non-options |
515 | and extend the range of non-options previously skipped. */ |
516 | |
517 | while (d->optind < argc && NONOPTION_P) |
518 | d->optind++; |
519 | d->__last_nonopt = d->optind; |
520 | } |
521 | |
522 | /* The special ARGV-element '--' means premature end of options. |
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 | |
527 | if (d->optind != argc && !strcmp (argv[d->optind], "--" )) |
528 | { |
529 | d->optind++; |
530 | |
531 | if (d->__first_nonopt != d->__last_nonopt |
532 | && d->__last_nonopt != d->optind) |
533 | exchange (argv, d); |
534 | else if (d->__first_nonopt == d->__last_nonopt) |
535 | d->__first_nonopt = d->optind; |
536 | d->__last_nonopt = argc; |
537 | |
538 | d->optind = argc; |
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 | |
544 | if (d->optind == argc) |
545 | { |
546 | /* Set the next-arg-index to point at the non-options |
547 | that we previously skipped, so the caller will digest them. */ |
548 | if (d->__first_nonopt != d->__last_nonopt) |
549 | d->optind = d->__first_nonopt; |
550 | return -1; |
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 | |
556 | if (NONOPTION_P) |
557 | { |
558 | if (d->__ordering == REQUIRE_ORDER) |
559 | return -1; |
560 | d->optarg = argv[d->optind++]; |
561 | return 1; |
562 | } |
563 | |
564 | /* We have found another option-ARGV-element. |
565 | Check whether it might be a long option. */ |
566 | if (longopts) |
567 | { |
568 | if (argv[d->optind][1] == '-') |
569 | { |
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 | } |
577 | |
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. |
583 | |
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". |
588 | |
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]))) |
592 | { |
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; |
600 | } |
601 | } |
602 | |
603 | /* It is not a long option. Skip the initial punctuation. */ |
604 | d->__nextchar = argv[d->optind] + 1; |
605 | } |
606 | |
607 | /* Look at and handle the next short option-character. */ |
608 | |
609 | { |
610 | char c = *d->__nextchar++; |
611 | const char *temp = strchr (optstring, c); |
612 | |
613 | /* Increment 'optind' when we start to process its last character. */ |
614 | if (*d->__nextchar == '\0') |
615 | ++d->optind; |
616 | |
617 | if (temp == NULL || c == ':' || c == ';') |
618 | { |
619 | if (print_errors) |
620 | fprintf (stderr, _("%s: invalid option -- '%c'\n" ), argv[0], c); |
621 | d->optopt = c; |
622 | return '?'; |
623 | } |
624 | |
625 | /* Convenience. Treat POSIX -W foo same as long option --foo */ |
626 | if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL) |
627 | { |
628 | /* This is an option that requires an argument. */ |
629 | if (*d->__nextchar != '\0') |
630 | d->optarg = d->__nextchar; |
631 | else if (d->optind == argc) |
632 | { |
633 | if (print_errors) |
634 | fprintf (stderr, |
635 | _("%s: option requires an argument -- '%c'\n" ), |
636 | argv[0], c); |
637 | |
638 | d->optopt = c; |
639 | if (optstring[0] == ':') |
640 | c = ':'; |
641 | else |
642 | c = '?'; |
643 | return c; |
644 | } |
645 | else |
646 | d->optarg = argv[d->optind]; |
647 | |
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 " ); |
652 | } |
653 | if (temp[1] == ':') |
654 | { |
655 | if (temp[2] == ':') |
656 | { |
657 | /* This is an option that accepts an argument optionally. */ |
658 | if (*d->__nextchar != '\0') |
659 | { |
660 | d->optarg = d->__nextchar; |
661 | d->optind++; |
662 | } |
663 | else |
664 | d->optarg = NULL; |
665 | d->__nextchar = NULL; |
666 | } |
667 | else |
668 | { |
669 | /* This is an option that requires an argument. */ |
670 | if (*d->__nextchar != '\0') |
671 | { |
672 | d->optarg = d->__nextchar; |
673 | /* If we end this ARGV-element by taking the rest as an arg, |
674 | we must advance to the next element now. */ |
675 | d->optind++; |
676 | } |
677 | else if (d->optind == argc) |
678 | { |
679 | if (print_errors) |
680 | fprintf (stderr, |
681 | _("%s: option requires an argument -- '%c'\n" ), |
682 | argv[0], c); |
683 | |
684 | d->optopt = c; |
685 | if (optstring[0] == ':') |
686 | c = ':'; |
687 | else |
688 | c = '?'; |
689 | } |
690 | else |
691 | /* We already incremented 'optind' once; |
692 | increment it again when taking next ARGV-elt as argument. */ |
693 | d->optarg = argv[d->optind++]; |
694 | d->__nextchar = NULL; |
695 | } |
696 | } |
697 | return c; |
698 | } |
699 | } |
700 | |
701 | int |
702 | _getopt_internal (int argc, char **argv, const char *optstring, |
703 | const struct option *longopts, int *longind, int long_only, |
704 | int posixly_correct) |
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, |
712 | longind, long_only, &getopt_data, |
713 | posixly_correct); |
714 | |
715 | optind = getopt_data.optind; |
716 | optarg = getopt_data.optarg; |
717 | optopt = getopt_data.optopt; |
718 | |
719 | return result; |
720 | } |
721 | |
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 | } |
733 | |
734 | #ifdef _LIBC |
735 | GETOPT_ENTRY(getopt, 0) |
736 | GETOPT_ENTRY(__posix_getopt, 1) |
737 | #else |
738 | GETOPT_ENTRY(getopt, 1) |
739 | #endif |
740 | |
741 | |
742 | #ifdef TEST |
743 | |
744 | /* Compile with -DTEST to make an executable for use in testing |
745 | the above definition of 'getopt'. */ |
746 | |
747 | int |
748 | main (int argc, char **argv) |
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" ); |
758 | if (c == -1) |
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': |
788 | printf ("option c with value '%s'\n" , optarg); |
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 */ |
811 | |