summaryrefslogtreecommitdiffstats
path: root/gl/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getopt.c')
-rw-r--r--gl/getopt.c35
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;