Hash :
0d1077ab
Author :
Date :
2025-06-27T15:27:24
options: New module. * lib/options.h: New file. * lib/options.c: New file. * modules/options: New file. * doc/glibc-functions/getopt_long.texi: Mention the new module.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
@node getopt_long
@subsection @code{getopt_long}
@findex getopt_long
LSB specification:@* @url{https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib-getopt-long-3.html}
Documentation:
@itemize
@item
@ifinfo
@ref{Getopt Long Options,,Parsing Long Options with getopt_long,libc},
@end ifinfo
@ifnotinfo
@url{https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html},
@end ifnotinfo
@item
@uref{https://www.kernel.org/doc/man-pages/online/pages/man3/getopt_long.3.html,,man getopt_long}.
@end itemize
Gnulib module: getopt-gnu
@mindex getopt-gnu
Portability problems fixed by Gnulib:
@itemize
@item
This function is missing on some platforms:
AIX 5.1, HP-UX 11, MSVC 14.
@item
The function @code{getopt_long} does not obey the combination of
@samp{+} and @samp{:} flags in the options string on some platforms:
glibc 2.11.
@item
The use of @samp{W;} in the optstring argument to does not always
allow @code{-W foo} to behave synonymously with @code{--foo}:
glibc 2.11.
@item
The function @code{getopt_long} does not support the @samp{+} flag in
the options string on some platforms:
macOS 14, AIX 5.2, Solaris 10.
@item
The value of @code{optind} after a missing required argument is wrong
on some platforms:
macOS 14.
@item
The function @code{getopt_long} does not obey the @samp{-} flag in the
options string when @env{POSIXLY_CORRECT} is set on some platforms:
Cygwin 1.7.0.
@item
Some implementations fail to reset state, including re-checking
@env{POSIXLY_CORRECT}, when @code{optind} is set to @samp{0}:
NetBSD, Cygwin 1.7.0.
@item
The function @code{getopt_long} does not support options with optional
arguments on some platforms:
macOS 14, OpenBSD 4.0, AIX 5.2, Solaris 11 2010-11, Cygwin 1.5.x.
@item
This function crashes if the option string includes @code{W;} but
there are no long options, on some platforms:
glibc 2.14.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@end itemize
@mindex options
Gnulib provides also a module @code{options}, that
fixes the following shortcomings of the @code{getopt_long} API.
These shortcomings are best illustrated with an example:
@example
static struct option const long_options[] =
@{
@{ "width", required_argument, NULL, 'w' @},
@{ "help", no_argument, &show_help, 1 @},
@{ "version", no_argument, &show_version, 1 @},
@{ NULL, 0, NULL, 0 @}
@};
while ((optchar = getopt_long (argc, argv, "w:xhV", long_options, NULL))
!= -1)
switch (optchar)
@{
case '\0': /* Long option with flag != NULL. */
break;
case 'w':
set_width (optarg);
break;
case 'x':
do_x = true;
break;
case 'h':
show_help = 1; /* Action code duplication! */
break;
case 'V':
show_version = 1; /* Action code duplication! */
break;
default:
usage (EXIT_FAILURE);
@}
@end example
@itemize
@item
The information whether an option takes a required vs.@: optional argument
needs to be specified twice:
in the @code{option[]} array for the long option
and in the string argument for the short option.
It is too easy to forget to
add the @code{":"} or @code{"::"} part in the string argument
and thus get inconsistent behaviour
between the long option and the short option.
@item
This information needs to be specified twice, but in different ways:
@multitable @columnfractions .3 .3
@headitem In the array @tab In the string
@item @code{no_argument} @tab @code{""}
@item @code{required_argument} @tab @code{":"}
@item @code{optional_argument} @tab @code{"::"}
@end multitable
@item
For an action that merely sets an @code{int}-typed variable to a value,
you can specify this action in the @code{options[]} array,
and thus omit the handling in the @code{switch} statement.
But this works only for options that are
long options without a corresponding short option.
As soon as the option has a corresponding short option,
you do need to handle it in the @code{switch} statement.
Here again, there is the opportunity for
inconsistent behaviour between the long option and the short option.
@item
The @code{val} field in a @code{struct option} has different meanings,
depending on another field:
If the @code{flag} field is non-NULL,
@code{val} is a value to be stored in a variable.
If the @code{flag} field is NULL,
@code{val} is a key to be returned from @code{getopt_long}
and subject to the @code{switch} statement.
@item
The handling of non-option arguments is specified by
prepending a certain character (@samp{+} or @samp{-}) to the string argument.
This is not one of the usual ways to specify things in an API.
The conventional way in an API is
an argument of @code{enum} type, or a flags word.
@item
The handling of errors consists of two independent flags,
and each of the flags has to be specified in a different way:
one flag is specified by
prepending a certain character (@samp{:}) to the string argument;
the other flag is specified through the global variable @code{opterr}.
@item
The @code{struct option} is a misnomer:
It cannot encode short options.
Therefore, it would have better been called @code{struct long_option}.
@item
The @code{getopt_long} function is expected to
receive the same arguments in each call, in the @code{while} loop.
The effects are undefined if you don't follow this (unwritten!) constraint.
@item
The fifth argument to @code{getopt_long}, @var{indexptr}, is redundant, because
when the @code{flag} is non-NULL,
the @code{switch} statement does not need to handle the option,
and when the @code{flag} is NULL,
@code{getopt_long} returns the value of @code{val},
as a way to identify which option was seen.
@end itemize