summaryrefslogtreecommitdiffstats
path: root/gl/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/getopt.c')
-rw-r--r--gl/getopt.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/gl/getopt.c b/gl/getopt.c
index 1e2441c4..6b155e6c 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-2025 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>
@@ -42,7 +42,7 @@
42# define funlockfile(fp) _IO_funlockfile (fp) 42# define funlockfile(fp) _IO_funlockfile (fp)
43#else 43#else
44# include "gettext.h" 44# include "gettext.h"
45# define _(msgid) gettext (msgid) 45# define _(msgid) dgettext ("gnulib", msgid)
46/* When used standalone, flockfile and funlockfile might not be 46/* When used standalone, flockfile and funlockfile might not be
47 available. */ 47 available. */
48# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \ 48# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
@@ -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;
@@ -720,7 +723,7 @@ _getopt_internal (int argc, char **argv, const char *optstring,
720 return result; 723 return result;
721} 724}
722 725
723/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt. 726/* glibc gets a LSB-compliant getopt and a POSIX-compliant __posix_getopt.
724 Standalone applications just get a POSIX-compliant getopt. 727 Standalone applications just get a POSIX-compliant getopt.
725 POSIX and LSB both require these functions to take 'char *const *argv' 728 POSIX and LSB both require these functions to take 'char *const *argv'
726 even though this is incorrect (because of the permutation). */ 729 even though this is incorrect (because of the permutation). */
@@ -729,7 +732,7 @@ _getopt_internal (int argc, char **argv, const char *optstring,
729 NAME (int argc, char *const *argv, const char *optstring) \ 732 NAME (int argc, char *const *argv, const char *optstring) \
730 { \ 733 { \
731 return _getopt_internal (argc, (char **)argv, optstring, \ 734 return _getopt_internal (argc, (char **)argv, optstring, \
732 0, 0, 0, POSIXLY_CORRECT); \ 735 NULL, NULL, 0, POSIXLY_CORRECT); \
733 } 736 }
734 737
735#ifdef _LIBC 738#ifdef _LIBC