diff options
Diffstat (limited to 'gl/getopt.c')
-rw-r--r-- | gl/getopt.c | 35 |
1 files changed, 19 insertions, 16 deletions
diff --git a/gl/getopt.c b/gl/getopt.c index 1e2441c..f66f119 100644 --- a/gl/getopt.c +++ b/gl/getopt.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Getopt for GNU. | 1 | /* Getopt for GNU. |
2 | Copyright (C) 1987-2023 Free Software Foundation, Inc. | 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. | 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. | 4 | Patches to this file should be submitted to both projects. |
5 | 5 | ||
@@ -21,7 +21,7 @@ | |||
21 | # include <config.h> | 21 | # include <config.h> |
22 | #endif | 22 | #endif |
23 | 23 | ||
24 | #include "getopt.h" | 24 | #include <getopt.h> |
25 | 25 | ||
26 | #include <stdio.h> | 26 | #include <stdio.h> |
27 | #include <stdlib.h> | 27 | #include <stdlib.h> |
@@ -223,8 +223,9 @@ process_long_option (int argc, char **argv, const char *optstring, | |||
223 | { | 223 | { |
224 | /* Didn't find an exact match, so look for abbreviations. */ | 224 | /* Didn't find an exact match, so look for abbreviations. */ |
225 | unsigned char *ambig_set = NULL; | 225 | unsigned char *ambig_set = NULL; |
226 | int ambig_malloced = 0; | 226 | /* Use simpler fallback diagnostic if ambig_set == &ambig_fallback. */ |
227 | int ambig_fallback = 0; | 227 | unsigned char ambig_fallback; |
228 | void *ambig_malloced = NULL; | ||
228 | int indfound = -1; | 229 | int indfound = -1; |
229 | 230 | ||
230 | for (p = longopts, option_index = 0; p->name; p++, option_index++) | 231 | for (p = longopts, option_index = 0; p->name; p++, option_index++) |
@@ -242,39 +243,42 @@ process_long_option (int argc, char **argv, const char *optstring, | |||
242 | || pfound->val != p->val) | 243 | || pfound->val != p->val) |
243 | { | 244 | { |
244 | /* Second or later nonexact match found. */ | 245 | /* Second or later nonexact match found. */ |
245 | if (!ambig_fallback) | 246 | if (ambig_set != &ambig_fallback) |
246 | { | 247 | { |
247 | if (!print_errors) | 248 | if (!print_errors) |
248 | /* Don't waste effort tracking the ambig set if | 249 | /* Don't waste effort tracking the ambig set if |
249 | we're not going to print it anyway. */ | 250 | we're not going to print it anyway. */ |
250 | ambig_fallback = 1; | 251 | ambig_set = &ambig_fallback; |
251 | else if (!ambig_set) | 252 | else if (!ambig_set) |
252 | { | 253 | { |
253 | if (__libc_use_alloca (n_options)) | 254 | if (__libc_use_alloca (n_options)) |
254 | ambig_set = alloca (n_options); | 255 | 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 | 256 | else |
259 | ambig_malloced = 1; | 257 | { |
258 | ambig_malloced = malloc (n_options); | ||
259 | /* Fall back to simpler diagnostic if | ||
260 | memory allocation fails. */ | ||
261 | ambig_set = (ambig_malloced ? ambig_malloced | ||
262 | : &ambig_fallback); | ||
263 | } | ||
260 | 264 | ||
261 | if (ambig_set) | 265 | if (ambig_set != &ambig_fallback) |
262 | { | 266 | { |
263 | memset (ambig_set, 0, n_options); | 267 | memset (ambig_set, 0, n_options); |
264 | ambig_set[indfound] = 1; | 268 | ambig_set[indfound] = 1; |
265 | } | 269 | } |
266 | } | 270 | } |
267 | if (ambig_set) | 271 | if (ambig_set && ambig_set != &ambig_fallback) |
268 | ambig_set[option_index] = 1; | 272 | ambig_set[option_index] = 1; |
269 | } | 273 | } |
270 | } | 274 | } |
271 | } | 275 | } |
272 | 276 | ||
273 | if (ambig_set || ambig_fallback) | 277 | if (ambig_set) |
274 | { | 278 | { |
275 | if (print_errors) | 279 | if (print_errors) |
276 | { | 280 | { |
277 | if (ambig_fallback) | 281 | if (ambig_set == &ambig_fallback) |
278 | fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), | 282 | fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"), |
279 | argv[0], prefix, d->__nextchar); | 283 | argv[0], prefix, d->__nextchar); |
280 | else | 284 | else |
@@ -296,8 +300,7 @@ process_long_option (int argc, char **argv, const char *optstring, | |||
296 | funlockfile (stderr); | 300 | funlockfile (stderr); |
297 | } | 301 | } |
298 | } | 302 | } |
299 | if (ambig_malloced) | 303 | free (ambig_malloced); |
300 | free (ambig_set); | ||
301 | d->__nextchar += strlen (d->__nextchar); | 304 | d->__nextchar += strlen (d->__nextchar); |
302 | d->optind++; | 305 | d->optind++; |
303 | d->optopt = 0; | 306 | d->optopt = 0; |