summaryrefslogtreecommitdiffstats
path: root/gl/getopt.c
diff options
context:
space:
mode:
authorRincewindsHat <12514511+RincewindsHat@users.noreply.github.com>2023-02-19 13:39:08 (GMT)
committerRincewindsHat <12514511+RincewindsHat@users.noreply.github.com>2023-02-19 13:39:08 (GMT)
commit74b6984047d330a3cc7cb7f63645849fe7676c63 (patch)
tree65a26800103d8d66f7e6cb4acfbfc9f315ec750b /gl/getopt.c
parent423284edfa980fc3fdb51ab20af96685a988ba97 (diff)
parentc07206f2ccc2356aa74bc6813a94c2190017d44e (diff)
downloadmonitoring-plugins-74b6984047d330a3cc7cb7f63645849fe7676c63.tar.gz
Merge branch 'master' into check_icmp_cleanuprefs/pull/1807/head
Diffstat (limited to 'gl/getopt.c')
-rw-r--r--gl/getopt.c1442
1 files changed, 504 insertions, 938 deletions
diff --git a/gl/getopt.c b/gl/getopt.c
index ef0f4ce..1e2441c 100644
--- a/gl/getopt.c
+++ b/gl/getopt.c
@@ -1,23 +1,21 @@
1/* Getopt for GNU. 1/* Getopt for GNU.
2 NOTE: getopt is part of the C library, so if you don't know what 2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
3 "Keep this file name-space clean" means, talk to drepper@gnu.org 3 This file is part of the GNU C Library and is also part of gnulib.
4 before changing it! 4 Patches to this file should be submitted to both projects.
5 Copyright (C) 1987-1996, 1998-2004, 2006, 2008-2013 Free Software 5
6 Foundation, Inc. 6 The GNU C Library is free software; you can redistribute it and/or
7 This file is part of the GNU C Library. 7 modify it under the terms of the GNU Lesser General Public
8 8 License as published by the Free Software Foundation; either
9 This program is free software: you can redistribute it and/or modify 9 version 2.1 of the License, or (at your option) any later version.
10 it under the terms of the GNU General Public License as published by 10
11 the Free Software Foundation; either version 3 of the License, or 11 The GNU C Library is distributed in the hope that it will be useful,
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 GNU General Public License for more details. 14 Lesser General Public License for more details.
18 15
19 You should have received a copy of the GNU General Public License 16 You should have received a copy of the GNU Lesser General Public
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
21 19
22#ifndef _LIBC 20#ifndef _LIBC
23# include <config.h> 21# include <config.h>
@@ -31,30 +29,54 @@
31#include <unistd.h> 29#include <unistd.h>
32 30
33#ifdef _LIBC 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. */
34# include <libintl.h> 39# include <libintl.h>
40# define fprintf __fxprintf_nocancel
41# define flockfile(fp) _IO_flockfile (fp)
42# define funlockfile(fp) _IO_funlockfile (fp)
35#else 43#else
36# include "gettext.h" 44# include "gettext.h"
37# define _(msgid) gettext (msgid) 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)
38#endif 57#endif
39 58
40#if defined _LIBC && defined USE_IN_LIBIO 59/* This implementation of 'getopt' has three modes for handling
41# include <wchar.h> 60 options interspersed with non-option arguments. It can stop
42#endif 61 scanning for options at the first non-option argument encountered,
43 62 as POSIX specifies. It can continue scanning for options after the
44/* This version of 'getopt' appears to the caller like standard Unix 'getopt' 63 first non-option argument, but permute 'argv' as it goes so that,
45 but it behaves differently for the user, since it allows the user 64 after 'getopt' is done, all the options precede all the non-option
46 to intersperse the options with the other arguments. 65 arguments and 'optind' points to the first non-option argument.
47 66 Or, it can report non-option arguments as if they were arguments to
48 As 'getopt_long' works, it permutes the elements of ARGV so that, 67 the option character '\x01'.
49 when it is done, all the options precede everything else. Thus 68
50 all application programs are extended to handle flexible argument order. 69 The default behavior of 'getopt_long' is to permute the argument list.
51 70 When this implementation is used standalone, the default behavior of
52 Using 'getopt' or setting the environment variable POSIXLY_CORRECT 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
53 disables permutation. 74 disables permutation.
54 Then the behavior is completely standard.
55 75
56 GNU application programs can use a third alternative mode in which 76 If the first character of the OPTSTRING argument to 'getopt' or
57 they can distinguish the relative order of options and other arguments. */ 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'. */
58 80
59#include "getopt_int.h" 81#include "getopt_int.h"
60 82
@@ -95,42 +117,7 @@ int optopt = '?';
95/* Keep a global copy of all internal members of getopt_data. */ 117/* Keep a global copy of all internal members of getopt_data. */
96 118
97static struct _getopt_data getopt_data; 119static struct _getopt_data getopt_data;
98
99
100#if defined HAVE_DECL_GETENV && !HAVE_DECL_GETENV
101extern char *getenv ();
102#endif
103 120
104#ifdef _LIBC
105/* Stored original parameters.
106 XXX This is no good solution. We should rather copy the args so
107 that we can compare them later. But we must not use malloc(3). */
108extern int __libc_argc;
109extern char **__libc_argv;
110
111/* Bash 2.0 gives us an environment variable containing flags
112 indicating ARGV elements that should not be considered arguments. */
113
114# ifdef USE_NONOPTION_FLAGS
115/* Defined in getopt_init.c */
116extern char *__getopt_nonoption_flags;
117# endif
118
119# ifdef USE_NONOPTION_FLAGS
120# define SWAP_FLAGS(ch1, ch2) \
121 if (d->__nonoption_flags_len > 0) \
122 { \
123 char __tmp = __getopt_nonoption_flags[ch1]; \
124 __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
125 __getopt_nonoption_flags[ch2] = __tmp; \
126 }
127# else
128# define SWAP_FLAGS(ch1, ch2)
129# endif
130#else /* !_LIBC */
131# define SWAP_FLAGS(ch1, ch2)
132#endif /* _LIBC */
133
134/* Exchange two adjacent subsequences of ARGV. 121/* Exchange two adjacent subsequences of ARGV.
135 One subsequence is elements [first_nonopt,last_nonopt) 122 One subsequence is elements [first_nonopt,last_nonopt)
136 which contains all the non-options that have been skipped so far. 123 which contains all the non-options that have been skipped so far.
@@ -153,64 +140,40 @@ exchange (char **argv, struct _getopt_data *d)
153 It leaves the longer segment in the right place overall, 140 It leaves the longer segment in the right place overall,
154 but it consists of two parts that need to be swapped next. */ 141 but it consists of two parts that need to be swapped next. */
155 142
156#if defined _LIBC && defined USE_NONOPTION_FLAGS
157 /* First make sure the handling of the '__getopt_nonoption_flags'
158 string can work normally. Our top argument must be in the range
159 of the string. */
160 if (d->__nonoption_flags_len > 0 && top >= d->__nonoption_flags_max_len)
161 {
162 /* We must extend the array. The user plays games with us and
163 presents new arguments. */
164 char *new_str = malloc (top + 1);
165 if (new_str == NULL)
166 d->__nonoption_flags_len = d->__nonoption_flags_max_len = 0;
167 else
168 {
169 memset (__mempcpy (new_str, __getopt_nonoption_flags,
170 d->__nonoption_flags_max_len),
171 '\0', top + 1 - d->__nonoption_flags_max_len);
172 d->__nonoption_flags_max_len = top + 1;
173 __getopt_nonoption_flags = new_str;
174 }
175 }
176#endif
177
178 while (top > middle && middle > bottom) 143 while (top > middle && middle > bottom)
179 { 144 {
180 if (top - middle > middle - bottom) 145 if (top - middle > middle - bottom)
181 { 146 {
182 /* Bottom segment is the short one. */ 147 /* Bottom segment is the short one. */
183 int len = middle - bottom; 148 int len = middle - bottom;
184 register int i; 149 int i;
185 150
186 /* Swap it with the top part of the top segment. */ 151 /* Swap it with the top part of the top segment. */
187 for (i = 0; i < len; i++) 152 for (i = 0; i < len; i++)
188 { 153 {
189 tem = argv[bottom + i]; 154 tem = argv[bottom + i];
190 argv[bottom + i] = argv[top - (middle - bottom) + i]; 155 argv[bottom + i] = argv[top - (middle - bottom) + i];
191 argv[top - (middle - bottom) + i] = tem; 156 argv[top - (middle - bottom) + i] = tem;
192 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); 157 }
193 } 158 /* Exclude the moved bottom segment from further swapping. */
194 /* Exclude the moved bottom segment from further swapping. */ 159 top -= len;
195 top -= len; 160 }
196 }
197 else 161 else
198 { 162 {
199 /* Top segment is the short one. */ 163 /* Top segment is the short one. */
200 int len = top - middle; 164 int len = top - middle;
201 register int i; 165 int i;
202 166
203 /* Swap it with the bottom part of the bottom segment. */ 167 /* Swap it with the bottom part of the bottom segment. */
204 for (i = 0; i < len; i++) 168 for (i = 0; i < len; i++)
205 { 169 {
206 tem = argv[bottom + i]; 170 tem = argv[bottom + i];
207 argv[bottom + i] = argv[middle + i]; 171 argv[bottom + i] = argv[middle + i];
208 argv[middle + i] = tem; 172 argv[middle + i] = tem;
209 SWAP_FLAGS (bottom + i, middle + i); 173 }
210 } 174 /* Exclude the moved top segment from further swapping. */
211 /* Exclude the moved top segment from further swapping. */ 175 bottom += len;
212 bottom += len; 176 }
213 }
214 } 177 }
215 178
216 /* Update records for the slots the non-options now occupy. */ 179 /* Update records for the slots the non-options now occupy. */
@@ -219,25 +182,216 @@ exchange (char **argv, struct _getopt_data *d)
219 d->__last_nonopt = d->optind; 182 d->__last_nonopt = d->optind;
220} 183}
221 184
222/* Initialize the internal data when the first call is made. */ 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. */
193static int
194process_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 (n_options))
254 ambig_set = alloca (n_options);
255 else if ((ambig_set = malloc (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, " '%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, "\n");
296 funlockfile (stderr);
297 }
298 }
299 if (ambig_malloced)
300 free (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. */
223 379
224static const char * 380static const char *
225_getopt_initialize (int argc _GL_UNUSED, 381_getopt_initialize (_GL_UNUSED int argc,
226 char **argv _GL_UNUSED, const char *optstring, 382 _GL_UNUSED char **argv, const char *optstring,
227 struct _getopt_data *d, int posixly_correct) 383 struct _getopt_data *d, int posixly_correct)
228{ 384{
229 /* Start processing options with ARGV-element 1 (since ARGV-element 0 385 /* Start processing options with ARGV-element 1 (since ARGV-element 0
230 is the program name); the sequence of previously skipped 386 is the program name); the sequence of previously skipped
231 non-option ARGV-elements is empty. */ 387 non-option ARGV-elements is empty. */
388 if (d->optind == 0)
389 d->optind = 1;
232 390
233 d->__first_nonopt = d->__last_nonopt = d->optind; 391 d->__first_nonopt = d->__last_nonopt = d->optind;
234
235 d->__nextchar = NULL; 392 d->__nextchar = NULL;
236 393
237 d->__posixly_correct = posixly_correct || !!getenv ("POSIXLY_CORRECT");
238
239 /* Determine how to handle the ordering of options and nonoptions. */ 394 /* Determine how to handle the ordering of options and nonoptions. */
240
241 if (optstring[0] == '-') 395 if (optstring[0] == '-')
242 { 396 {
243 d->__ordering = RETURN_IN_ORDER; 397 d->__ordering = RETURN_IN_ORDER;
@@ -248,41 +402,12 @@ _getopt_initialize (int argc _GL_UNUSED,
248 d->__ordering = REQUIRE_ORDER; 402 d->__ordering = REQUIRE_ORDER;
249 ++optstring; 403 ++optstring;
250 } 404 }
251 else if (d->__posixly_correct) 405 else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
252 d->__ordering = REQUIRE_ORDER; 406 d->__ordering = REQUIRE_ORDER;
253 else 407 else
254 d->__ordering = PERMUTE; 408 d->__ordering = PERMUTE;
255 409
256#if defined _LIBC && defined USE_NONOPTION_FLAGS 410 d->__initialized = 1;
257 if (!d->__posixly_correct
258 && argc == __libc_argc && argv == __libc_argv)
259 {
260 if (d->__nonoption_flags_max_len == 0)
261 {
262 if (__getopt_nonoption_flags == NULL
263 || __getopt_nonoption_flags[0] == '\0')
264 d->__nonoption_flags_max_len = -1;
265 else
266 {
267 const char *orig_str = __getopt_nonoption_flags;
268 int len = d->__nonoption_flags_max_len = strlen (orig_str);
269 if (d->__nonoption_flags_max_len < argc)
270 d->__nonoption_flags_max_len = argc;
271 __getopt_nonoption_flags =
272 (char *) malloc (d->__nonoption_flags_max_len);
273 if (__getopt_nonoption_flags == NULL)
274 d->__nonoption_flags_max_len = -1;
275 else
276 memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
277 '\0', d->__nonoption_flags_max_len - len);
278 }
279 }
280 d->__nonoption_flags_len = d->__nonoption_flags_max_len;
281 }
282 else
283 d->__nonoption_flags_len = 0;
284#endif
285
286 return optstring; 411 return optstring;
287} 412}
288 413
@@ -344,8 +469,8 @@ _getopt_initialize (int argc _GL_UNUSED,
344 469
345int 470int
346_getopt_internal_r (int argc, char **argv, const char *optstring, 471_getopt_internal_r (int argc, char **argv, const char *optstring,
347 const struct option *longopts, int *longind, 472 const struct option *longopts, int *longind,
348 int long_only, struct _getopt_data *d, int posixly_correct) 473 int long_only, struct _getopt_data *d, int posixly_correct)
349{ 474{
350 int print_errors = d->opterr; 475 int print_errors = d->opterr;
351 476
@@ -355,431 +480,129 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
355 d->optarg = NULL; 480 d->optarg = NULL;
356 481
357 if (d->optind == 0 || !d->__initialized) 482 if (d->optind == 0 || !d->__initialized)
358 { 483 optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
359 if (d->optind == 0)
360 d->optind = 1; /* Don't scan ARGV[0], the program name. */
361 optstring = _getopt_initialize (argc, argv, optstring, d,
362 posixly_correct);
363 d->__initialized = 1;
364 }
365 else if (optstring[0] == '-' || optstring[0] == '+') 484 else if (optstring[0] == '-' || optstring[0] == '+')
366 optstring++; 485 optstring++;
486
367 if (optstring[0] == ':') 487 if (optstring[0] == ':')
368 print_errors = 0; 488 print_errors = 0;
369 489
370 /* Test whether ARGV[optind] points to a non-option argument. 490 /* Test whether ARGV[optind] points to a non-option argument. */
371 Either it does not have option syntax, or there is an environment flag 491#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
372 from the shell indicating it is not an option. The later information
373 is only used when the used in the GNU libc. */
374#if defined _LIBC && defined USE_NONOPTION_FLAGS
375# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' \
376 || (d->optind < d->__nonoption_flags_len \
377 && __getopt_nonoption_flags[d->optind] == '1'))
378#else
379# define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
380#endif
381 492
382 if (d->__nextchar == NULL || *d->__nextchar == '\0') 493 if (d->__nextchar == NULL || *d->__nextchar == '\0')
383 { 494 {
384 /* Advance to the next ARGV-element. */ 495 /* Advance to the next ARGV-element. */
385 496
386 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been 497 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
387 moved back by the user (who may also have changed the arguments). */ 498 moved back by the user (who may also have changed the arguments). */
388 if (d->__last_nonopt > d->optind) 499 if (d->__last_nonopt > d->optind)
389 d->__last_nonopt = d->optind; 500 d->__last_nonopt = d->optind;
390 if (d->__first_nonopt > d->optind) 501 if (d->__first_nonopt > d->optind)
391 d->__first_nonopt = d->optind; 502 d->__first_nonopt = d->optind;
392 503
393 if (d->__ordering == PERMUTE) 504 if (d->__ordering == PERMUTE)
394 { 505 {
395 /* If we have just processed some options following some non-options, 506 /* If we have just processed some options following some non-options,
396 exchange them so that the options come first. */ 507 exchange them so that the options come first. */
397 508
398 if (d->__first_nonopt != d->__last_nonopt 509 if (d->__first_nonopt != d->__last_nonopt
399 && d->__last_nonopt != d->optind) 510 && d->__last_nonopt != d->optind)
400 exchange ((char **) argv, d); 511 exchange (argv, d);
401 else if (d->__last_nonopt != d->optind) 512 else if (d->__last_nonopt != d->optind)
402 d->__first_nonopt = d->optind; 513 d->__first_nonopt = d->optind;
403 514
404 /* Skip any additional non-options 515 /* Skip any additional non-options
405 and extend the range of non-options previously skipped. */ 516 and extend the range of non-options previously skipped. */
406 517
407 while (d->optind < argc && NONOPTION_P) 518 while (d->optind < argc && NONOPTION_P)
408 d->optind++; 519 d->optind++;
409 d->__last_nonopt = d->optind; 520 d->__last_nonopt = d->optind;
410 } 521 }
411 522
412 /* The special ARGV-element '--' means premature end of options. 523 /* The special ARGV-element '--' means premature end of options.
413 Skip it like a null option, 524 Skip it like a null option,
414 then exchange with previous non-options as if it were an option, 525 then exchange with previous non-options as if it were an option,
415 then skip everything else like a non-option. */ 526 then skip everything else like a non-option. */
416 527
417 if (d->optind != argc && !strcmp (argv[d->optind], "--")) 528 if (d->optind != argc && !strcmp (argv[d->optind], "--"))
418 { 529 {
419 d->optind++; 530 d->optind++;
420 531
421 if (d->__first_nonopt != d->__last_nonopt 532 if (d->__first_nonopt != d->__last_nonopt
422 && d->__last_nonopt != d->optind) 533 && d->__last_nonopt != d->optind)
423 exchange ((char **) argv, d); 534 exchange (argv, d);
424 else if (d->__first_nonopt == d->__last_nonopt) 535 else if (d->__first_nonopt == d->__last_nonopt)
425 d->__first_nonopt = d->optind; 536 d->__first_nonopt = d->optind;
426 d->__last_nonopt = argc; 537 d->__last_nonopt = argc;
427 538
428 d->optind = argc; 539 d->optind = argc;
429 } 540 }
430 541
431 /* If we have done all the ARGV-elements, stop the scan 542 /* If we have done all the ARGV-elements, stop the scan
432 and back over any non-options that we skipped and permuted. */ 543 and back over any non-options that we skipped and permuted. */
433 544
434 if (d->optind == argc) 545 if (d->optind == argc)
435 { 546 {
436 /* Set the next-arg-index to point at the non-options 547 /* Set the next-arg-index to point at the non-options
437 that we previously skipped, so the caller will digest them. */ 548 that we previously skipped, so the caller will digest them. */
438 if (d->__first_nonopt != d->__last_nonopt) 549 if (d->__first_nonopt != d->__last_nonopt)
439 d->optind = d->__first_nonopt; 550 d->optind = d->__first_nonopt;
440 return -1; 551 return -1;
441 } 552 }
442 553
443 /* If we have come to a non-option and did not permute it, 554 /* If we have come to a non-option and did not permute it,
444 either stop the scan or describe it to the caller and pass it by. */ 555 either stop the scan or describe it to the caller and pass it by. */
445 556
446 if (NONOPTION_P) 557 if (NONOPTION_P)
447 { 558 {
448 if (d->__ordering == REQUIRE_ORDER) 559 if (d->__ordering == REQUIRE_ORDER)
449 return -1; 560 return -1;
450 d->optarg = argv[d->optind++]; 561 d->optarg = argv[d->optind++];
451 return 1; 562 return 1;
452 } 563 }
453 564
454 /* We have found another option-ARGV-element. 565 /* We have found another option-ARGV-element.
455 Skip the initial punctuation. */ 566 Check whether it might be a long option. */
456 567 if (longopts)
457 d->__nextchar = (argv[d->optind] + 1 568 {
458 + (longopts != NULL && argv[d->optind][1] == '-')); 569 if (argv[d->optind][1] == '-')
459 } 570 {
460 571 /* "--foo" is always a long option. The special option
461 /* Decode the current option-ARGV-element. */ 572 "--" was handled above. */
462 573 d->__nextchar = argv[d->optind] + 2;
463 /* Check whether the ARGV-element is a long option. 574 return process_long_option (argc, argv, optstring, longopts,
464 575 longind, long_only, d,
465 If long_only and the ARGV-element has the form "-f", where f is 576 print_errors, "--");
466 a valid short option, don't consider it an abbreviated form of 577 }
467 a long option that starts with f. Otherwise there would be no 578
468 way to give the -f short option. 579 /* If long_only and the ARGV-element has the form "-f",
469 580 where f is a valid short option, don't consider it an
470 On the other hand, if there's a long option "fubar" and 581 abbreviated form of a long option that starts with f.
471 the ARGV-element is "-fu", do consider that an abbreviation of 582 Otherwise there would be no way to give the -f short
472 the long option, just like "--fu", and not "-f" with arg "u". 583 option.
473 584
474 This distinction seems to be the most useful approach. */ 585 On the other hand, if there's a long option "fubar" and
475 586 the ARGV-element is "-fu", do consider that an
476 if (longopts != NULL 587 abbreviation of the long option, just like "--fu", and
477 && (argv[d->optind][1] == '-' 588 not "-f" with arg "u".
478 || (long_only && (argv[d->optind][2] 589
479 || !strchr (optstring, argv[d->optind][1]))))) 590 This distinction seems to be the most useful approach. */
480 { 591 if (long_only && (argv[d->optind][2]
481 char *nameend; 592 || !strchr (optstring, argv[d->optind][1])))
482 unsigned int namelen; 593 {
483 const struct option *p; 594 int code;
484 const struct option *pfound = NULL; 595 d->__nextchar = argv[d->optind] + 1;
485 struct option_list 596 code = process_long_option (argc, argv, optstring, longopts,
486 { 597 longind, long_only, d,
487 const struct option *p; 598 print_errors, "-");
488 struct option_list *next; 599 if (code != -1)
489 } *ambig_list = NULL; 600 return code;
490 int exact = 0; 601 }
491 int indfound = -1; 602 }
492 int option_index; 603
493 604 /* It is not a long option. Skip the initial punctuation. */
494 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++) 605 d->__nextchar = argv[d->optind] + 1;
495 /* Do nothing. */ ;
496 namelen = nameend - d->__nextchar;
497
498 /* Test all long options for either exact match
499 or abbreviated matches. */
500 for (p = longopts, option_index = 0; p->name; p++, option_index++)
501 if (!strncmp (p->name, d->__nextchar, namelen))
502 {
503 if (namelen == (unsigned int) strlen (p->name))
504 {
505 /* Exact match found. */
506 pfound = p;
507 indfound = option_index;
508 exact = 1;
509 break;
510 }
511 else if (pfound == NULL)
512 {
513 /* First nonexact match found. */
514 pfound = p;
515 indfound = option_index;
516 }
517 else if (long_only
518 || pfound->has_arg != p->has_arg
519 || pfound->flag != p->flag
520 || pfound->val != p->val)
521 {
522 /* Second or later nonexact match found. */
523 struct option_list *newp = malloc (sizeof (*newp));
524 newp->p = p;
525 newp->next = ambig_list;
526 ambig_list = newp;
527 }
528 }
529
530 if (ambig_list != NULL && !exact)
531 {
532 if (print_errors)
533 {
534 struct option_list first;
535 first.p = pfound;
536 first.next = ambig_list;
537 ambig_list = &first;
538
539#if defined _LIBC && defined USE_IN_LIBIO
540 char *buf = NULL;
541 size_t buflen = 0;
542
543 FILE *fp = open_memstream (&buf, &buflen);
544 if (fp != NULL)
545 {
546 fprintf (fp,
547 _("%s: option '%s' is ambiguous; possibilities:"),
548 argv[0], argv[d->optind]);
549
550 do
551 {
552 fprintf (fp, " '--%s'", ambig_list->p->name);
553 ambig_list = ambig_list->next;
554 }
555 while (ambig_list != NULL);
556
557 fputc_unlocked ('\n', fp);
558
559 if (__builtin_expect (fclose (fp) != EOF, 1))
560 {
561 _IO_flockfile (stderr);
562
563 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
564 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
565
566 __fxprintf (NULL, "%s", buf);
567
568 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
569 _IO_funlockfile (stderr);
570
571 free (buf);
572 }
573 }
574#else
575 fprintf (stderr,
576 _("%s: option '%s' is ambiguous; possibilities:"),
577 argv[0], argv[d->optind]);
578 do
579 {
580 fprintf (stderr, " '--%s'", ambig_list->p->name);
581 ambig_list = ambig_list->next;
582 }
583 while (ambig_list != NULL);
584
585 fputc ('\n', stderr);
586#endif
587 }
588 d->__nextchar += strlen (d->__nextchar);
589 d->optind++;
590 d->optopt = 0;
591 return '?';
592 }
593
594 while (ambig_list != NULL)
595 {
596 struct option_list *pn = ambig_list->next;
597 free (ambig_list);
598 ambig_list = pn;
599 }
600
601 if (pfound != NULL)
602 {
603 option_index = indfound;
604 d->optind++;
605 if (*nameend)
606 {
607 /* Don't test has_arg with >, because some C compilers don't
608 allow it to be used on enums. */
609 if (pfound->has_arg)
610 d->optarg = nameend + 1;
611 else
612 {
613 if (print_errors)
614 {
615#if defined _LIBC && defined USE_IN_LIBIO
616 char *buf;
617 int n;
618#endif
619
620 if (argv[d->optind - 1][1] == '-')
621 {
622 /* --option */
623#if defined _LIBC && defined USE_IN_LIBIO
624 n = __asprintf (&buf, _("\
625%s: option '--%s' doesn't allow an argument\n"),
626 argv[0], pfound->name);
627#else
628 fprintf (stderr, _("\
629%s: option '--%s' doesn't allow an argument\n"),
630 argv[0], pfound->name);
631#endif
632 }
633 else
634 {
635 /* +option or -option */
636#if defined _LIBC && defined USE_IN_LIBIO
637 n = __asprintf (&buf, _("\
638%s: option '%c%s' doesn't allow an argument\n"),
639 argv[0], argv[d->optind - 1][0],
640 pfound->name);
641#else
642 fprintf (stderr, _("\
643%s: option '%c%s' doesn't allow an argument\n"),
644 argv[0], argv[d->optind - 1][0],
645 pfound->name);
646#endif
647 }
648
649#if defined _LIBC && defined USE_IN_LIBIO
650 if (n >= 0)
651 {
652 _IO_flockfile (stderr);
653
654 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
655 ((_IO_FILE *) stderr)->_flags2
656 |= _IO_FLAGS2_NOTCANCEL;
657
658 __fxprintf (NULL, "%s", buf);
659
660 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
661 _IO_funlockfile (stderr);
662
663 free (buf);
664 }
665#endif
666 }
667
668 d->__nextchar += strlen (d->__nextchar);
669
670 d->optopt = pfound->val;
671 return '?';
672 }
673 }
674 else if (pfound->has_arg == 1)
675 {
676 if (d->optind < argc)
677 d->optarg = argv[d->optind++];
678 else
679 {
680 if (print_errors)
681 {
682#if defined _LIBC && defined USE_IN_LIBIO
683 char *buf;
684
685 if (__asprintf (&buf, _("\
686%s: option '--%s' requires an argument\n"),
687 argv[0], pfound->name) >= 0)
688 {
689 _IO_flockfile (stderr);
690
691 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
692 ((_IO_FILE *) stderr)->_flags2
693 |= _IO_FLAGS2_NOTCANCEL;
694
695 __fxprintf (NULL, "%s", buf);
696
697 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
698 _IO_funlockfile (stderr);
699
700 free (buf);
701 }
702#else
703 fprintf (stderr,
704 _("%s: option '--%s' requires an argument\n"),
705 argv[0], pfound->name);
706#endif
707 }
708 d->__nextchar += strlen (d->__nextchar);
709 d->optopt = pfound->val;
710 return optstring[0] == ':' ? ':' : '?';
711 }
712 }
713 d->__nextchar += strlen (d->__nextchar);
714 if (longind != NULL)
715 *longind = option_index;
716 if (pfound->flag)
717 {
718 *(pfound->flag) = pfound->val;
719 return 0;
720 }
721 return pfound->val;
722 }
723
724 /* Can't find it as a long option. If this is not getopt_long_only,
725 or the option starts with '--' or is not a valid short
726 option, then it's an error.
727 Otherwise interpret it as a short option. */
728 if (!long_only || argv[d->optind][1] == '-'
729 || strchr (optstring, *d->__nextchar) == NULL)
730 {
731 if (print_errors)
732 {
733#if defined _LIBC && defined USE_IN_LIBIO
734 char *buf;
735 int n;
736#endif
737
738 if (argv[d->optind][1] == '-')
739 {
740 /* --option */
741#if defined _LIBC && defined USE_IN_LIBIO
742 n = __asprintf (&buf, _("%s: unrecognized option '--%s'\n"),
743 argv[0], d->__nextchar);
744#else
745 fprintf (stderr, _("%s: unrecognized option '--%s'\n"),
746 argv[0], d->__nextchar);
747#endif
748 }
749 else
750 {
751 /* +option or -option */
752#if defined _LIBC && defined USE_IN_LIBIO
753 n = __asprintf (&buf, _("%s: unrecognized option '%c%s'\n"),
754 argv[0], argv[d->optind][0], d->__nextchar);
755#else
756 fprintf (stderr, _("%s: unrecognized option '%c%s'\n"),
757 argv[0], argv[d->optind][0], d->__nextchar);
758#endif
759 }
760
761#if defined _LIBC && defined USE_IN_LIBIO
762 if (n >= 0)
763 {
764 _IO_flockfile (stderr);
765
766 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
767 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
768
769 __fxprintf (NULL, "%s", buf);
770
771 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
772 _IO_funlockfile (stderr);
773
774 free (buf);
775 }
776#endif
777 }
778 d->__nextchar = (char *) "";
779 d->optind++;
780 d->optopt = 0;
781 return '?';
782 }
783 } 606 }
784 607
785 /* Look at and handle the next short option-character. */ 608 /* Look at and handle the next short option-character. */
@@ -794,331 +617,83 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
794 617
795 if (temp == NULL || c == ':' || c == ';') 618 if (temp == NULL || c == ':' || c == ';')
796 { 619 {
797 if (print_errors) 620 if (print_errors)
798 { 621 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
799#if defined _LIBC && defined USE_IN_LIBIO 622 d->optopt = c;
800 char *buf; 623 return '?';
801 int n;
802#endif
803
804#if defined _LIBC && defined USE_IN_LIBIO
805 n = __asprintf (&buf, _("%s: invalid option -- '%c'\n"),
806 argv[0], c);
807#else
808 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
809#endif
810
811#if defined _LIBC && defined USE_IN_LIBIO
812 if (n >= 0)
813 {
814 _IO_flockfile (stderr);
815
816 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
817 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
818
819 __fxprintf (NULL, "%s", buf);
820
821 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
822 _IO_funlockfile (stderr);
823
824 free (buf);
825 }
826#endif
827 }
828 d->optopt = c;
829 return '?';
830 } 624 }
625
831 /* Convenience. Treat POSIX -W foo same as long option --foo */ 626 /* Convenience. Treat POSIX -W foo same as long option --foo */
832 if (temp[0] == 'W' && temp[1] == ';') 627 if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
833 { 628 {
834 char *nameend; 629 /* This is an option that requires an argument. */
835 const struct option *p; 630 if (*d->__nextchar != '\0')
836 const struct option *pfound = NULL; 631 d->optarg = d->__nextchar;
837 int exact = 0; 632 else if (d->optind == argc)
838 int ambig = 0; 633 {
839 int indfound = 0; 634 if (print_errors)
840 int option_index; 635 fprintf (stderr,
841 636 _("%s: option requires an argument -- '%c'\n"),
842 if (longopts == NULL) 637 argv[0], c);
843 goto no_longs; 638
844 639 d->optopt = c;
845 /* This is an option that requires an argument. */ 640 if (optstring[0] == ':')
846 if (*d->__nextchar != '\0') 641 c = ':';
847 { 642 else
848 d->optarg = d->__nextchar; 643 c = '?';
849 /* If we end this ARGV-element by taking the rest as an arg, 644 return c;
850 we must advance to the next element now. */ 645 }
851 d->optind++; 646 else
852 } 647 d->optarg = argv[d->optind];
853 else if (d->optind == argc) 648
854 { 649 d->__nextchar = d->optarg;
855 if (print_errors) 650 d->optarg = NULL;
856 { 651 return process_long_option (argc, argv, optstring, longopts, longind,
857#if defined _LIBC && defined USE_IN_LIBIO 652 0 /* long_only */, d, print_errors, "-W ");
858 char *buf;
859
860 if (__asprintf (&buf,
861 _("%s: option requires an argument -- '%c'\n"),
862 argv[0], c) >= 0)
863 {
864 _IO_flockfile (stderr);
865
866 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
867 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
868
869 __fxprintf (NULL, "%s", buf);
870
871 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
872 _IO_funlockfile (stderr);
873
874 free (buf);
875 }
876#else
877 fprintf (stderr,
878 _("%s: option requires an argument -- '%c'\n"),
879 argv[0], c);
880#endif
881 }
882 d->optopt = c;
883 if (optstring[0] == ':')
884 c = ':';
885 else
886 c = '?';
887 return c;
888 }
889 else
890 /* We already incremented 'd->optind' once;
891 increment it again when taking next ARGV-elt as argument. */
892 d->optarg = argv[d->optind++];
893
894 /* optarg is now the argument, see if it's in the
895 table of longopts. */
896
897 for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '=';
898 nameend++)
899 /* Do nothing. */ ;
900
901 /* Test all long options for either exact match
902 or abbreviated matches. */
903 for (p = longopts, option_index = 0; p->name; p++, option_index++)
904 if (!strncmp (p->name, d->__nextchar, nameend - d->__nextchar))
905 {
906 if ((unsigned int) (nameend - d->__nextchar) == strlen (p->name))
907 {
908 /* Exact match found. */
909 pfound = p;
910 indfound = option_index;
911 exact = 1;
912 break;
913 }
914 else if (pfound == NULL)
915 {
916 /* First nonexact match found. */
917 pfound = p;
918 indfound = option_index;
919 }
920 else if (long_only
921 || pfound->has_arg != p->has_arg
922 || pfound->flag != p->flag
923 || pfound->val != p->val)
924 /* Second or later nonexact match found. */
925 ambig = 1;
926 }
927 if (ambig && !exact)
928 {
929 if (print_errors)
930 {
931#if defined _LIBC && defined USE_IN_LIBIO
932 char *buf;
933
934 if (__asprintf (&buf, _("%s: option '-W %s' is ambiguous\n"),
935 argv[0], d->optarg) >= 0)
936 {
937 _IO_flockfile (stderr);
938
939 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
940 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL;
941
942 __fxprintf (NULL, "%s", buf);
943
944 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
945 _IO_funlockfile (stderr);
946
947 free (buf);
948 }
949#else
950 fprintf (stderr, _("%s: option '-W %s' is ambiguous\n"),
951 argv[0], d->optarg);
952#endif
953 }
954 d->__nextchar += strlen (d->__nextchar);
955 d->optind++;
956 return '?';
957 }
958 if (pfound != NULL)
959 {
960 option_index = indfound;
961 if (*nameend)
962 {
963 /* Don't test has_arg with >, because some C compilers don't
964 allow it to be used on enums. */
965 if (pfound->has_arg)
966 d->optarg = nameend + 1;
967 else
968 {
969 if (print_errors)
970 {
971#if defined _LIBC && defined USE_IN_LIBIO
972 char *buf;
973
974 if (__asprintf (&buf, _("\
975%s: option '-W %s' doesn't allow an argument\n"),
976 argv[0], pfound->name) >= 0)
977 {
978 _IO_flockfile (stderr);
979
980 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
981 ((_IO_FILE *) stderr)->_flags2
982 |= _IO_FLAGS2_NOTCANCEL;
983
984 __fxprintf (NULL, "%s", buf);
985
986 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
987 _IO_funlockfile (stderr);
988
989 free (buf);
990 }
991#else
992 fprintf (stderr, _("\
993%s: option '-W %s' doesn't allow an argument\n"),
994 argv[0], pfound->name);
995#endif
996 }
997
998 d->__nextchar += strlen (d->__nextchar);
999 return '?';
1000 }
1001 }
1002 else if (pfound->has_arg == 1)
1003 {
1004 if (d->optind < argc)
1005 d->optarg = argv[d->optind++];
1006 else
1007 {
1008 if (print_errors)
1009 {
1010#if defined _LIBC && defined USE_IN_LIBIO
1011 char *buf;
1012
1013 if (__asprintf (&buf, _("\
1014%s: option '-W %s' requires an argument\n"),
1015 argv[0], pfound->name) >= 0)
1016 {
1017 _IO_flockfile (stderr);
1018
1019 int old_flags2 = ((_IO_FILE *) stderr)->_flags2;
1020 ((_IO_FILE *) stderr)->_flags2
1021 |= _IO_FLAGS2_NOTCANCEL;
1022
1023 __fxprintf (NULL, "%s", buf);
1024
1025 ((_IO_FILE *) stderr)->_flags2 = old_flags2;
1026 _IO_funlockfile (stderr);
1027
1028 free (buf);
1029 }
1030#else
1031 fprintf (stderr, _("\
1032%s: option '-W %s' requires an argument\n"),
1033 argv[0], pfound->name);
1034#endif
1035 }
1036 d->__nextchar += strlen (d->__nextchar);
1037 return optstring[0] == ':' ? ':' : '?';
1038 }
1039 }
1040 else
1041 d->optarg = NULL;
1042 d->__nextchar += strlen (d->__nextchar);
1043 if (longind != NULL)
1044 *longind = option_index;
1045 if (pfound->flag)
1046 {
1047 *(pfound->flag) = pfound->val;
1048 return 0;
1049 }
1050 return pfound->val;
1051 }
1052
1053 no_longs:
1054 d->__nextchar = NULL;
1055 return 'W'; /* Let the application handle it. */
1056 } 653 }
1057 if (temp[1] == ':') 654 if (temp[1] == ':')
1058 { 655 {
1059 if (temp[2] == ':') 656 if (temp[2] == ':')
1060 { 657 {
1061 /* This is an option that accepts an argument optionally. */ 658 /* This is an option that accepts an argument optionally. */
1062 if (*d->__nextchar != '\0') 659 if (*d->__nextchar != '\0')
1063 { 660 {
1064 d->optarg = d->__nextchar; 661 d->optarg = d->__nextchar;
1065 d->optind++; 662 d->optind++;
1066 } 663 }
1067 else 664 else
1068 d->optarg = NULL; 665 d->optarg = NULL;
1069 d->__nextchar = NULL; 666 d->__nextchar = NULL;
1070 } 667 }
1071 else 668 else
1072 { 669 {
1073 /* This is an option that requires an argument. */ 670 /* This is an option that requires an argument. */
1074 if (*d->__nextchar != '\0') 671 if (*d->__nextchar != '\0')
1075 { 672 {
1076 d->optarg = d->__nextchar; 673 d->optarg = d->__nextchar;
1077 /* If we end this ARGV-element by taking the rest as an arg, 674 /* If we end this ARGV-element by taking the rest as an arg,
1078 we must advance to the next element now. */ 675 we must advance to the next element now. */
1079 d->optind++; 676 d->optind++;
1080 } 677 }
1081 else if (d->optind == argc) 678 else if (d->optind == argc)
1082 { 679 {
1083 if (print_errors) 680 if (print_errors)
1084 { 681 fprintf (stderr,
1085#if defined _LIBC && defined USE_IN_LIBIO 682 _("%s: option requires an argument -- '%c'\n"),
1086 char *buf; 683 argv[0], c);
1087 684
1088 if (__asprintf (&buf, _("\ 685 d->optopt = c;
1089%s: option requires an argument -- '%c'\n"), 686 if (optstring[0] == ':')
1090 argv[0], c) >= 0) 687 c = ':';
1091 { 688 else
1092 _IO_flockfile (stderr); 689 c = '?';
1093 690 }
1094 int old_flags2 = ((_IO_FILE *) stderr)->_flags2; 691 else
1095 ((_IO_FILE *) stderr)->_flags2 |= _IO_FLAGS2_NOTCANCEL; 692 /* We already incremented 'optind' once;
1096 693 increment it again when taking next ARGV-elt as argument. */
1097 __fxprintf (NULL, "%s", buf); 694 d->optarg = argv[d->optind++];
1098 695 d->__nextchar = NULL;
1099 ((_IO_FILE *) stderr)->_flags2 = old_flags2; 696 }
1100 _IO_funlockfile (stderr);
1101
1102 free (buf);
1103 }
1104#else
1105 fprintf (stderr,
1106 _("%s: option requires an argument -- '%c'\n"),
1107 argv[0], c);
1108#endif
1109 }
1110 d->optopt = c;
1111 if (optstring[0] == ':')
1112 c = ':';
1113 else
1114 c = '?';
1115 }
1116 else
1117 /* We already incremented 'optind' once;
1118 increment it again when taking next ARGV-elt as argument. */
1119 d->optarg = argv[d->optind++];
1120 d->__nextchar = NULL;
1121 }
1122 } 697 }
1123 return c; 698 return c;
1124 } 699 }
@@ -1126,8 +701,8 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
1126 701
1127int 702int
1128_getopt_internal (int argc, char **argv, const char *optstring, 703_getopt_internal (int argc, char **argv, const char *optstring,
1129 const struct option *longopts, int *longind, int long_only, 704 const struct option *longopts, int *longind, int long_only,
1130 int posixly_correct) 705 int posixly_correct)
1131{ 706{
1132 int result; 707 int result;
1133 708
@@ -1135,8 +710,8 @@ _getopt_internal (int argc, char **argv, const char *optstring,
1135 getopt_data.opterr = opterr; 710 getopt_data.opterr = opterr;
1136 711
1137 result = _getopt_internal_r (argc, argv, optstring, longopts, 712 result = _getopt_internal_r (argc, argv, optstring, longopts,
1138 longind, long_only, &getopt_data, 713 longind, long_only, &getopt_data,
1139 posixly_correct); 714 posixly_correct);
1140 715
1141 optind = getopt_data.optind; 716 optind = getopt_data.optind;
1142 optarg = getopt_data.optarg; 717 optarg = getopt_data.optarg;
@@ -1145,32 +720,23 @@ _getopt_internal (int argc, char **argv, const char *optstring,
1145 return result; 720 return result;
1146} 721}
1147 722
1148/* glibc gets a LSB-compliant getopt. 723/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
1149 Standalone applications get a POSIX-compliant getopt. */ 724 Standalone applications just get a POSIX-compliant getopt.
1150#if _LIBC 725 POSIX and LSB both require these functions to take 'char *const *argv'
1151enum { POSIXLY_CORRECT = 0 }; 726 even though this is incorrect (because of the permutation). */
1152#else 727#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \
1153enum { POSIXLY_CORRECT = 1 }; 728 int \
1154#endif 729 NAME (int argc, char *const *argv, const char *optstring) \
1155 730 { \
1156int 731 return _getopt_internal (argc, (char **)argv, optstring, \
1157getopt (int argc, char *const *argv, const char *optstring) 732 0, 0, 0, POSIXLY_CORRECT); \
1158{ 733 }
1159 return _getopt_internal (argc, (char **) argv, optstring,
1160 (const struct option *) 0,
1161 (int *) 0,
1162 0, POSIXLY_CORRECT);
1163}
1164 734
1165#ifdef _LIBC 735#ifdef _LIBC
1166int 736GETOPT_ENTRY(getopt, 0)
1167__posix_getopt (int argc, char *const *argv, const char *optstring) 737GETOPT_ENTRY(__posix_getopt, 1)
1168{ 738#else
1169 return _getopt_internal (argc, argv, optstring, 739GETOPT_ENTRY(getopt, 1)
1170 (const struct option *) 0,
1171 (int *) 0,
1172 0, 1);
1173}
1174#endif 740#endif
1175 741
1176 742
@@ -1191,51 +757,51 @@ main (int argc, char **argv)
1191 757
1192 c = getopt (argc, argv, "abc:d:0123456789"); 758 c = getopt (argc, argv, "abc:d:0123456789");
1193 if (c == -1) 759 if (c == -1)
1194 break; 760 break;
1195 761
1196 switch (c) 762 switch (c)
1197 { 763 {
1198 case '0': 764 case '0':
1199 case '1': 765 case '1':
1200 case '2': 766 case '2':
1201 case '3': 767 case '3':
1202 case '4': 768 case '4':
1203 case '5': 769 case '5':
1204 case '6': 770 case '6':
1205 case '7': 771 case '7':
1206 case '8': 772 case '8':
1207 case '9': 773 case '9':
1208 if (digit_optind != 0 && digit_optind != this_option_optind) 774 if (digit_optind != 0 && digit_optind != this_option_optind)
1209 printf ("digits occur in two different argv-elements.\n"); 775 printf ("digits occur in two different argv-elements.\n");
1210 digit_optind = this_option_optind; 776 digit_optind = this_option_optind;
1211 printf ("option %c\n", c); 777 printf ("option %c\n", c);
1212 break; 778 break;
1213 779
1214 case 'a': 780 case 'a':
1215 printf ("option a\n"); 781 printf ("option a\n");
1216 break; 782 break;
1217 783
1218 case 'b': 784 case 'b':
1219 printf ("option b\n"); 785 printf ("option b\n");
1220 break; 786 break;
1221 787
1222 case 'c': 788 case 'c':
1223 printf ("option c with value '%s'\n", optarg); 789 printf ("option c with value '%s'\n", optarg);
1224 break; 790 break;
1225 791
1226 case '?': 792 case '?':
1227 break; 793 break;
1228 794
1229 default: 795 default:
1230 printf ("?? getopt returned character code 0%o ??\n", c); 796 printf ("?? getopt returned character code 0%o ??\n", c);
1231 } 797 }
1232 } 798 }
1233 799
1234 if (optind < argc) 800 if (optind < argc)
1235 { 801 {
1236 printf ("non-option ARGV-elements: "); 802 printf ("non-option ARGV-elements: ");
1237 while (optind < argc) 803 while (optind < argc)
1238 printf ("%s ", argv[optind++]); 804 printf ("%s ", argv[optind++]);
1239 printf ("\n"); 805 printf ("\n");
1240 } 806 }
1241 807