Possible bug in argp
Guangxin Yang <[email protected]> Sat, 07 Aug 2021 18:29:22 +0800
| Newsgroups | gmane.comp.gnu.utils.bugs |
|---|---|
| Message-ID | <[email protected]> |
------=_Part_36933_740982792.1628332162750
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Hello there,=C2=A0
There may be a bug on macOS when calling arpg_help() with options having a =
non-NULL arg value in the argp_option.=C2=A0
For the example=C2=A0https://www.gnu.org/software/libc/manual/html_node/Arg=
p-Example-3.html, I added a case like this:=C2=A0
=C2=A0 =C2=A0 case ARGP_KEY_NO_ARGS:
=C2=A0 =C2=A0 =C2=A0 argp_help(state->root_argp,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 stderr,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ARGP_HELP_BUG_ADDR | ARGP_HELP_DOC | ARG=
P_HELP_USAGE | ARGP_HELP_LONG,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 state->name);
=C2=A0 =C2=A0 =C2=A0 exit(1);
Compile and run without providing any arguments, I got a Segmentation fault=
.=C2=A0
The output looks like this:=C2=A0
Usage: t [-qsv?V] [-o FILE] [--output=3DFILE] [--quiet] [--silent] [--verbo=
se]
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 [--help] [--usage] [--version] AR=
G1 ARG2
Argp example #3 -- a program with options and arguments using argp
=C2=A0 -o, --output=3DFILE=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Output to FILE=
instead of standard output
=C2=A0 -q, -s, --quiet, --silent=C2=A0 Don't produce any output
=C2=A0 -v, --verbose=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Produc=
e verbose output
=C2=A0 -?, --help =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 G=
ive this help list
=C2=A0 =C2=A0 =C2=A0 --usage=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0 Give a short usage message
=C2=A0 -V, Segmentation fault: 11
If I comment out these two lines:=C2=A0
21 =C2=A0 {"output", =C2=A0 'o', "FILE", 0,
22=C2=A0 =C2=A0 "Output to FILE instead of standard output" },
Things work perfectly.=C2=A0
On Redhat it is all ok.=C2=A0
I attached the modified example FYI.=C2=A0
Thanks for creating this wonderful piece.=C2=A0 :-0
Regards
Guangxin=C2=A0
------=_Part_36933_740982792.1628332162750
Content-Type: application/octet-stream; name=t.c
Content-Transfer-Encoding: 7bit
X-ZM_AttachId: 138476249627520040
Content-Disposition: attachment; filename=t.c
#include <stdlib.h>
#include <argp.h>
const char *argp_program_version =
"argp-ex3 1.0";
const char *argp_program_bug_address =
"<[email protected]>";
/* Program documentation. */
static char doc[] =
"Argp example #3 -- a program with options and arguments using argp";
/* A description of the arguments we accept. */
static char args_doc[] = "ARG1 ARG2";
/* The options we understand. */
static struct argp_option options[] = {
{"verbose", 'v', 0, 0, "Produce verbose output" },
{"quiet", 'q', 0, 0, "Don't produce any output" },
{"silent", 's', 0, OPTION_ALIAS },
{"output", 'o', "FILE", 0,
"Output to FILE instead of standard output" },
{ 0 }
};
/* Used by main to communicate with parse_opt. */
struct arguments
{
char *args[2]; /* arg1 & arg2 */
int silent, verbose;
char *output_file;
};
/* Parse a single option. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
switch (key)
{
case 'q': case 's':
arguments->silent = 1;
break;
case 'v':
arguments->verbose = 1;
break;
case 'o':
arguments->output_file = arg;
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 2)
/* Too many arguments. */
argp_usage (state);
arguments->args[state->arg_num] = arg;
break;
case ARGP_KEY_NO_ARGS:
argp_help(state->root_argp,
stderr,
ARGP_HELP_BUG_ADDR | ARGP_HELP_DOC | ARGP_HELP_USAGE | ARGP_HELP_LONG,
state->name);
exit(1);
case ARGP_KEY_END:
if (state->arg_num < 2)
/* Not enough arguments. */
argp_usage (state);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = { options, parse_opt, args_doc, doc };
int
main (int argc, char **argv)
{
struct arguments arguments;
/* Default values. */
arguments.silent = 0;
arguments.verbose = 0;
arguments.output_file = "-";
/* Parse our arguments; every option seen by parse_opt will
be reflected in arguments. */
argp_parse (&argp, argc, argv, 0, 0, &arguments);
printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
"VERBOSE = %s\nSILENT = %s\n",
arguments.args[0], arguments.args[1],
arguments.output_file,
arguments.verbose ? "yes" : "no",
arguments.silent ? "yes" : "no");
exit (0);
}
------=_Part_36933_740982792.1628332162750--