X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fargp-parse.c;h=489d6de91c2a858b341136b60bc0dada82602e9f;hb=e7086a9a301ffcfef17edbcba9e7c0312c33f7a8;hp=509f6dea8522303f778f8f524a62dbe7bdad31cb;hpb=3d140c4471e983a16c5836de180ddf11a12eaa39;p=gnulib.git diff --git a/lib/argp-parse.c b/lib/argp-parse.c index 509f6dea8..489d6de91 100644 --- a/lib/argp-parse.c +++ b/lib/argp-parse.c @@ -1,27 +1,27 @@ -/* Hierarchial argument parsing, layered over getopt - Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc. +/* Hierarchical argument parsing, layered over getopt + Copyright (C) 1995-2000, 2002-2004, 2009-2013 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader . - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H -#include +# include #endif #include +#include #include #include #include @@ -38,18 +38,17 @@ #else # include "gettext.h" #endif -#define N_(msgid) (msgid) +#define N_(msgid) msgid #include "argp.h" #include "argp-namefrob.h" -#define alignof(type) offsetof (struct { char c; type x; }, x) #define alignto(n, d) ((((n) + (d) - 1) / (d)) * (d)) /* Getopt return values. */ -#define KEY_END (-1) /* The end of the options. */ -#define KEY_ARG 1 /* A non-option argument. */ -#define KEY_ERR '?' /* An error parsing the options. */ +#define KEY_END (-1) /* The end of the options. */ +#define KEY_ARG 1 /* A non-option argument. */ +#define KEY_ERR '?' /* An error parsing the options. */ /* The meta-argument used to prevent any further arguments being interpreted as options. */ @@ -73,17 +72,17 @@ it to 0 yourself. */ static volatile int _argp_hang; -#define OPT_PROGNAME -2 -#define OPT_USAGE -3 -#define OPT_HANG -4 +#define OPT_PROGNAME -2 +#define OPT_USAGE -3 +#define OPT_HANG -4 static const struct argp_option argp_default_options[] = { - {"help", '?', 0, 0, N_("Give this help list"), -1}, - {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0}, - {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0}, - {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, - N_("Hang for SECS seconds (default 3600)"), 0}, + {"help", '?', 0, 0, N_("give this help list"), -1}, + {"usage", OPT_USAGE, 0, 0, N_("give a short usage message"), 0}, + {"program-name",OPT_PROGNAME,N_("NAME"), OPTION_HIDDEN, N_("set the program name"), 0}, + {"HANG", OPT_HANG, N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN, + N_("hang for SECS seconds (default 3600)"), 0}, {NULL, 0, 0, 0, NULL, 0} }; @@ -97,39 +96,35 @@ argp_default_parser (int key, char *arg, struct argp_state *state) break; case OPT_USAGE: __argp_state_help (state, state->out_stream, - ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); + ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK); break; - case OPT_PROGNAME: /* Set the program name. */ + case OPT_PROGNAME: /* Set the program name. */ #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME program_invocation_name = arg; #endif /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka - __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined - to be that, so we have to be a bit careful here.] */ + __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined + to be that, so we have to be a bit careful here.] */ /* Update what we use for messages. */ - state->name = strrchr (arg, '/'); - if (state->name) - state->name++; - else - state->name = arg; + state->name = __argp_base_name (arg); #if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME program_invocation_short_name = state->name; #endif if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS)) - == ARGP_PARSE_ARGV0) - /* Update what getopt uses too. */ - state->argv[0] = arg; + == ARGP_PARSE_ARGV0) + /* Update what getopt uses too. */ + state->argv[0] = arg; break; case OPT_HANG: _argp_hang = atoi (arg ? arg : "3600"); while (_argp_hang-- > 0) - __sleep (1); + __sleep (1); break; default: @@ -144,7 +139,7 @@ static const struct argp argp_default_argp = static const struct argp_option argp_version_options[] = { - {"version", 'V', 0, 0, N_("Print program version"), -1}, + {"version", 'V', 0, 0, N_("print program version"), -1}, {NULL, 0, 0, 0, NULL, 0} }; @@ -155,14 +150,15 @@ argp_version_parser (int key, char *arg, struct argp_state *state) { case 'V': if (argp_program_version_hook) - (*argp_program_version_hook) (state->out_stream, state); + (*argp_program_version_hook) (state->out_stream, state); else if (argp_program_version) - fprintf (state->out_stream, "%s\n", argp_program_version); + fprintf (state->out_stream, "%s\n", argp_program_version); else - __argp_error (state, dgettext (state->root_argp->argp_domain, - "(PROGRAM ERROR) No version known!?")); + __argp_error (state, "%s", + dgettext (state->root_argp->argp_domain, + "(PROGRAM ERROR) No version known!?")); if (! (state->flags & ARGP_NO_EXIT)) - exit (0); + exit (0); break; default: return EBADKEY; @@ -192,7 +188,7 @@ find_long_option (struct option *long_options, const char *name) } -/* The state of a `group' during parsing. Each group corresponds to a +/* The state of a "group" during parsing. Each group corresponds to a particular argp structure from the tree of such descending from the top level argp passed to argp_parse. */ struct group @@ -208,12 +204,12 @@ struct group particular short options is from. */ char *short_end; - /* The number of non-option args sucessfully handled by this parser. */ + /* The number of non-option args successfully handled by this parser. */ unsigned args_processed; /* This group's parser's parent's group. */ struct group *parent; - unsigned parent_index; /* And the our position in the parent. */ + unsigned parent_index; /* And the our position in the parent. */ /* These fields are swapped into and out of the state structure when calling this group's parser. */ @@ -259,7 +255,7 @@ struct parser struct group *groups; /* The end of the GROUPS array. */ struct group *egroup; - /* An vector containing storage for the CHILD_INPUTS field in all groups. */ + /* A vector containing storage for the CHILD_INPUTS field in all groups. */ void **child_inputs; /* True if we think using getopt is still useful; if false, then @@ -291,8 +287,8 @@ struct parser_convert_state next unused group entry. CVT holds state used during the conversion. */ static struct group * convert_options (const struct argp *argp, - struct group *parent, unsigned parent_index, - struct group *group, struct parser_convert_state *cvt) + struct group *parent, unsigned parent_index, + struct group *group, struct parser_convert_state *cvt) { /* REAL is the most recent non-alias value of OPT. */ const struct argp_option *real = argp->options; @@ -303,55 +299,55 @@ convert_options (const struct argp *argp, const struct argp_option *opt; if (real) - for (opt = real; !__option_is_end (opt); opt++) - { - if (! (opt->flags & OPTION_ALIAS)) - /* OPT isn't an alias, so we can use values from it. */ - real = opt; - - if (! (real->flags & OPTION_DOC)) - /* A real option (not just documentation). */ - { - if (__option_is_short (opt)) - /* OPT can be used as a short option. */ - { - *cvt->short_end++ = opt->key; - if (real->arg) - { - *cvt->short_end++ = ':'; - if (real->flags & OPTION_ARG_OPTIONAL) - *cvt->short_end++ = ':'; - } - *cvt->short_end = '\0'; /* keep 0 terminated */ - } - - if (opt->name - && find_long_option (cvt->parser->long_opts, opt->name) < 0) - /* OPT can be used as a long option. */ - { - cvt->long_end->name = opt->name; - cvt->long_end->has_arg = - (real->arg - ? (real->flags & OPTION_ARG_OPTIONAL - ? optional_argument - : required_argument) - : no_argument); - cvt->long_end->flag = 0; - /* we add a disambiguating code to all the user's - values (which is removed before we actually call - the function to parse the value); this means that - the user loses use of the high 8 bits in all his - values (the sign of the lower bits is preserved - however)... */ - cvt->long_end->val = - ((opt->key | real->key) & USER_MASK) - + (((group - cvt->parser->groups) + 1) << USER_BITS); - - /* Keep the LONG_OPTS list terminated. */ - (++cvt->long_end)->name = NULL; - } - } - } + for (opt = real; !__option_is_end (opt); opt++) + { + if (! (opt->flags & OPTION_ALIAS)) + /* OPT isn't an alias, so we can use values from it. */ + real = opt; + + if (! (real->flags & OPTION_DOC)) + /* A real option (not just documentation). */ + { + if (__option_is_short (opt)) + /* OPT can be used as a short option. */ + { + *cvt->short_end++ = opt->key; + if (real->arg) + { + *cvt->short_end++ = ':'; + if (real->flags & OPTION_ARG_OPTIONAL) + *cvt->short_end++ = ':'; + } + *cvt->short_end = '\0'; /* keep 0 terminated */ + } + + if (opt->name + && find_long_option (cvt->parser->long_opts, opt->name) < 0) + /* OPT can be used as a long option. */ + { + cvt->long_end->name = opt->name; + cvt->long_end->has_arg = + (real->arg + ? (real->flags & OPTION_ARG_OPTIONAL + ? optional_argument + : required_argument) + : no_argument); + cvt->long_end->flag = 0; + /* we add a disambiguating code to all the user's + values (which is removed before we actually call + the function to parse the value); this means that + the user loses use of the high 8 bits in all his + values (the sign of the lower bits is preserved + however)... */ + cvt->long_end->val = + ((opt->key ? opt->key : real->key) & USER_MASK) + + (((group - cvt->parser->groups) + 1) << USER_BITS); + + /* Keep the LONG_OPTS list terminated. */ + (++cvt->long_end)->name = NULL; + } + } + } group->parser = argp->parser; group->argp = argp; @@ -364,15 +360,15 @@ convert_options (const struct argp *argp, group->child_inputs = 0; if (children) - /* Assign GROUP's CHILD_INPUTS field some space from + /* Assign GROUP's CHILD_INPUTS field some space from CVT->child_inputs_end.*/ - { - unsigned num_children = 0; - while (children[num_children].argp) - num_children++; - group->child_inputs = cvt->child_inputs_end; - cvt->child_inputs_end += num_children; - } + { + unsigned num_children = 0; + while (children[num_children].argp) + num_children++; + group->child_inputs = cvt->child_inputs_end; + cvt->child_inputs_end += num_children; + } parent = group++; } @@ -383,14 +379,14 @@ convert_options (const struct argp *argp, { unsigned index = 0; while (children->argp) - group = - convert_options (children++->argp, parent, index++, group, cvt); + group = + convert_options (children++->argp, parent, index++, group, cvt); } return group; } -/* Find the merged set of getopt options, with keys appropiately prefixed. */ +/* Find the merged set of getopt options, with keys appropriately prefixed. */ static void parser_convert (struct parser *parser, const struct argp *argp, int flags) { @@ -420,10 +416,10 @@ parser_convert (struct parser *parser, const struct argp *argp, int flags) /* Lengths of various parser fields which we will allocated. */ struct parser_sizes { - size_t short_len; /* Getopt short options string. */ - size_t long_len; /* Getopt long options vector. */ - size_t num_groups; /* Group structures we allocate. */ - size_t num_child_inputs; /* Child input slots. */ + size_t short_len; /* Getopt short options string. */ + size_t long_len; /* Getopt long options vector. */ + size_t num_groups; /* Group structures we allocate. */ + size_t num_child_inputs; /* Child input slots. */ }; /* For ARGP, increments the NUM_GROUPS field in SZS by the total number of @@ -440,27 +436,27 @@ calc_sizes (const struct argp *argp, struct parser_sizes *szs) { szs->num_groups++; if (opt) - { - int num_opts = 0; - while (!__option_is_end (opt++)) - num_opts++; - szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */ - szs->long_len += num_opts; - } + { + int num_opts = 0; + while (!__option_is_end (opt++)) + num_opts++; + szs->short_len += num_opts * 3; /* opt + up to 2 ':'s */ + szs->long_len += num_opts; + } } if (child) while (child->argp) { - calc_sizes ((child++)->argp, szs); - szs->num_child_inputs++; + calc_sizes ((child++)->argp, szs); + szs->num_child_inputs++; } } /* Initializes PARSER to parse ARGP in a manner described by FLAGS. */ static error_t parser_init (struct parser *parser, const struct argp *argp, - int argc, char **argv, int flags, void *input) + int argc, char **argv, int flags, void *input) { error_t err = 0; struct group *group; @@ -482,12 +478,18 @@ parser_init (struct parser *parser, const struct argp *argp, /* Lengths of the various bits of storage used by PARSER. */ glen = (szs.num_groups + 1) * sizeof (struct group); - gsum = alignto (glen, alignof (void *)); clen = szs.num_child_inputs * sizeof (void *); - csum = alignto (gsum + clen, alignof (struct option)); llen = (szs.long_len + 1) * sizeof (struct option); - lsum = alignto (csum + llen, alignof (char)); slen = szs.short_len + 1; + + /* Sums of previous lengths, properly aligned. There's no need to + align gsum, since struct group is aligned at least as strictly as + void * (since it contains a void * member). And there's no need + to align lsum, since struct option is aligned at least as + strictly as char. */ + gsum = glen; + csum = alignto (gsum + clen, alignof (struct option)); + lsum = csum + llen; ssum = lsum + slen; parser->storage = malloc (ssum); @@ -511,7 +513,7 @@ parser_init (struct parser *parser, const struct argp *argp, parser->state.flags = flags; parser->state.err_stream = stderr; parser->state.out_stream = stdout; - parser->state.next = 0; /* Tell getopt to initialize. */ + parser->state.next = 0; /* Tell getopt to initialize. */ parser->state.pstate = parser; parser->try_getopt = 1; @@ -525,20 +527,20 @@ parser_init (struct parser *parser, const struct argp *argp, group++) { if (group->parent) - /* If a child parser, get the initial input value from the parent. */ - group->input = group->parent->child_inputs[group->parent_index]; + /* If a child parser, get the initial input value from the parent. */ + group->input = group->parent->child_inputs[group->parent_index]; if (!group->parser - && group->argp->children && group->argp->children->argp) - /* For the special case where no parsing function is supplied for an - argp, propagate its input to its first child, if any (this just - makes very simple wrapper argps more convenient). */ - group->child_inputs[0] = group->input; + && group->argp->children && group->argp->children->argp) + /* For the special case where no parsing function is supplied for an + argp, propagate its input to its first child, if any (this just + makes very simple wrapper argps more convenient). */ + group->child_inputs[0] = group->input; err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0); } if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ + err = 0; /* Some parser didn't understand. */ if (err) return err; @@ -547,19 +549,16 @@ parser_init (struct parser *parser, const struct argp *argp, { parser->opt_data.opterr = 0; if (parser->state.flags & ARGP_PARSE_ARGV0) - /* getopt always skips ARGV[0], so we have to fake it out. As long - as OPTERR is 0, then it shouldn't actually try to access it. */ - parser->state.argv--, parser->state.argc++; + /* getopt always skips ARGV[0], so we have to fake it out. As long + as OPTERR is 0, then it shouldn't actually try to access it. */ + parser->state.argv--, parser->state.argc++; } else - parser->opt_data.opterr = 1; /* Print error messages. */ + parser->opt_data.opterr = 1; /* Print error messages. */ if (parser->state.argv == argv && argv[0]) /* There's an argv[0]; use it for messages. */ - { - char *short_name = strrchr (argv[0], '/'); - parser->state.name = short_name ? short_name + 1 : argv[0]; - } + parser->state.name = __argp_base_name (argv[0]); else parser->state.name = __argp_short_program_name (); @@ -569,7 +568,7 @@ parser_init (struct parser *parser, const struct argp *argp, /* Free any storage consumed by PARSER (but not PARSER itself). */ static error_t parser_finalize (struct parser *parser, - error_t err, int arg_ebadkey, int *end_index) + error_t err, int arg_ebadkey, int *end_index) { struct group *group; @@ -580,40 +579,40 @@ parser_finalize (struct parser *parser, if (! err) { if (parser->state.next == parser->state.argc) - /* We successfully parsed all arguments! Call all the parsers again, - just a few more times... */ - { - for (group = parser->groups; - group < parser->egroup && (!err || err==EBADKEY); - group++) - if (group->args_processed == 0) - err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); - for (group = parser->egroup - 1; - group >= parser->groups && (!err || err==EBADKEY); - group--) - err = group_parse (group, &parser->state, ARGP_KEY_END, 0); - - if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ - - /* Tell the user that all arguments are parsed. */ - if (end_index) - *end_index = parser->state.next; - } + /* We successfully parsed all arguments! Call all the parsers again, + just a few more times... */ + { + for (group = parser->groups; + group < parser->egroup && (!err || err==EBADKEY); + group++) + if (group->args_processed == 0) + err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0); + for (group = parser->egroup - 1; + group >= parser->groups && (!err || err==EBADKEY); + group--) + err = group_parse (group, &parser->state, ARGP_KEY_END, 0); + + if (err == EBADKEY) + err = 0; /* Some parser didn't understand. */ + + /* Tell the user that all arguments are parsed. */ + if (end_index) + *end_index = parser->state.next; + } else if (end_index) - /* Return any remaining arguments to the user. */ - *end_index = parser->state.next; + /* Return any remaining arguments to the user. */ + *end_index = parser->state.next; else - /* No way to return the remaining arguments, they must be bogus. */ - { - if (!(parser->state.flags & ARGP_NO_ERRS) - && parser->state.err_stream) - fprintf (parser->state.err_stream, - dgettext (parser->argp->argp_domain, - "%s: Too many arguments\n"), - parser->state.name); - err = EBADKEY; - } + /* No way to return the remaining arguments, they must be bogus. */ + { + if (!(parser->state.flags & ARGP_NO_ERRS) + && parser->state.err_stream) + fprintf (parser->state.err_stream, + dgettext (parser->argp->argp_domain, + "%s: Too many arguments\n"), + parser->state.name); + err = EBADKEY; + } } /* Okay, we're all done, with either an error or success; call the parsers @@ -623,27 +622,27 @@ parser_finalize (struct parser *parser, { /* Maybe print an error message. */ if (err == EBADKEY) - /* An appropriate message describing what the error was should have - been printed earlier. */ - __argp_state_help (&parser->state, parser->state.err_stream, - ARGP_HELP_STD_ERR); + /* An appropriate message describing what the error was should have + been printed earlier. */ + __argp_state_help (&parser->state, parser->state.err_stream, + ARGP_HELP_STD_ERR); /* Since we didn't exit, give each parser an error indication. */ for (group = parser->groups; group < parser->egroup; group++) - group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); + group_parse (group, &parser->state, ARGP_KEY_ERROR, 0); } else /* Notify parsers of success, and propagate back values from parsers. */ { /* We pass over the groups in reverse order so that child groups are - given a chance to do there processing before passing back a value to - the parent. */ + given a chance to do there processing before passing back a value to + the parent. */ for (group = parser->egroup - 1 - ; group >= parser->groups && (!err || err == EBADKEY) - ; group--) - err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); + ; group >= parser->groups && (!err || err == EBADKEY) + ; group--) + err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0); if (err == EBADKEY) - err = 0; /* Some parser didn't understand. */ + err = 0; /* Some parser didn't understand. */ } /* Call parsers once more, to do any final cleanup. Errors are ignored. */ @@ -671,42 +670,42 @@ parser_parse_arg (struct parser *parser, char *val) int index = --parser->state.next; error_t err = EBADKEY; struct group *group; - int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ + int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */ /* Try to parse the argument in each parser. */ for (group = parser->groups ; group < parser->egroup && err == EBADKEY ; group++) { - parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ + parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */ key = ARGP_KEY_ARG; err = group_parse (group, &parser->state, key, val); if (err == EBADKEY) - /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ - { - parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ - key = ARGP_KEY_ARGS; - err = group_parse (group, &parser->state, key, 0); - } + /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */ + { + parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */ + key = ARGP_KEY_ARGS; + err = group_parse (group, &parser->state, key, 0); + } } if (! err) { if (key == ARGP_KEY_ARGS) - /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't - changed by the user, *all* arguments should be considered - consumed. */ - parser->state.next = parser->state.argc; + /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't + changed by the user, *all* arguments should be considered + consumed. */ + parser->state.next = parser->state.argc; if (parser->state.next > index) - /* Remember that we successfully processed a non-option - argument -- but only if the user hasn't gotten tricky and set - the clock back. */ - (--group)->args_processed += (parser->state.next - index); + /* Remember that we successfully processed a non-option + argument -- but only if the user hasn't gotten tricky and set + the clock back. */ + (--group)->args_processed += (parser->state.next - index); else - /* The user wants to reparse some args, give getopt another try. */ - parser->try_getopt = 1; + /* The user wants to reparse some args, give getopt another try. */ + parser->try_getopt = 1; } return err; @@ -731,21 +730,21 @@ parser_parse_opt (struct parser *parser, int opt, char *val) char *short_index = strchr (parser->short_opts, opt); if (short_index) - for (group = parser->groups; group < parser->egroup; group++) - if (group->short_end > short_index) - { - err = group_parse (group, &parser->state, opt, - parser->opt_data.optarg); - break; - } + for (group = parser->groups; group < parser->egroup; group++) + if (group->short_end > short_index) + { + err = group_parse (group, &parser->state, opt, + parser->opt_data.optarg); + break; + } } else /* A long option. We use shifts instead of masking for extracting the user value in order to preserve the sign. */ err = group_parse (&parser->groups[group_key - 1], &parser->state, - (opt << GROUP_BITS) >> GROUP_BITS, - parser->opt_data.optarg); + (opt << GROUP_BITS) >> GROUP_BITS, + parser->opt_data.optarg); if (err == EBADKEY) /* At least currently, an option not recognized is an error in the @@ -753,19 +752,19 @@ parser_parse_opt (struct parser *parser, int opt, char *val) with each option. */ { static const char bad_key_err[] = - N_("(PROGRAM ERROR) Option should have been recognized!?"); + N_("(PROGRAM ERROR) Option should have been recognized!?"); if (group_key == 0) - __argp_error (&parser->state, "-%c: %s", opt, - dgettext (parser->argp->argp_domain, bad_key_err)); + __argp_error (&parser->state, "-%c: %s", opt, + dgettext (parser->argp->argp_domain, bad_key_err)); else - { - struct option *long_opt = parser->long_opts; - while (long_opt->val != opt && long_opt->name) - long_opt++; - __argp_error (&parser->state, "--%s: %s", - long_opt->name ? long_opt->name : "???", - dgettext (parser->argp->argp_domain, bad_key_err)); - } + { + struct option *long_opt = parser->long_opts; + while (long_opt->val != opt && long_opt->name) + long_opt++; + __argp_error (&parser->state, "--%s: %s", + long_opt->name ? long_opt->name : "???", + dgettext (parser->argp->argp_domain, bad_key_err)); + } } return err; @@ -783,7 +782,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) if (parser->state.quoted && parser->state.next < parser->state.quoted) /* The next argument pointer has been moved to before the quoted - region, so pretend we never saw the quoting `--', and give getopt + region, so pretend we never saw the quoting "--", and give getopt another chance. If the user hasn't removed it, getopt will just process it again. */ parser->state.quoted = 0; @@ -796,38 +795,38 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) /* Distinguish KEY_ERR from a real option. */ parser->opt_data.optopt = KEY_END; if (parser->state.flags & ARGP_LONG_ONLY) - opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); + opt = _getopt_long_only_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); else - opt = _getopt_long_r (parser->state.argc, parser->state.argv, - parser->short_opts, parser->long_opts, 0, - &parser->opt_data); + opt = _getopt_long_r (parser->state.argc, parser->state.argv, + parser->short_opts, parser->long_opts, 0, + &parser->opt_data); /* And see what getopt did. */ parser->state.next = parser->opt_data.optind; if (opt == KEY_END) - /* Getopt says there are no more options, so stop using - getopt; we'll continue if necessary on our own. */ - { - parser->try_getopt = 0; - if (parser->state.next > 1 - && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) - == 0) - /* Not only is this the end of the options, but it's a - `quoted' region, which may have args that *look* like - options, so we definitely shouldn't try to use getopt past - here, whatever happens. */ - parser->state.quoted = parser->state.next; - } + /* Getopt says there are no more options, so stop using + getopt; we'll continue if necessary on our own. */ + { + parser->try_getopt = 0; + if (parser->state.next > 1 + && strcmp (parser->state.argv[parser->state.next - 1], QUOTE) + == 0) + /* Not only is this the end of the options, but it's a + "quoted" region, which may have args that *look* like + options, so we definitely shouldn't try to use getopt past + here, whatever happens. */ + parser->state.quoted = parser->state.next; + } else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END) - /* KEY_ERR can have the same value as a valid user short - option, but in the case of a real error, getopt sets OPTOPT - to the offending character, which can never be KEY_END. */ - { - *arg_ebadkey = 0; - return EBADKEY; - } + /* KEY_ERR can have the same value as a valid user short + option, but in the case of a real error, getopt sets OPTOPT + to the offending character, which can never be KEY_END. */ + { + *arg_ebadkey = 0; + return EBADKEY; + } } else opt = KEY_END; @@ -836,18 +835,18 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) { /* We're past what getopt considers the options. */ if (parser->state.next >= parser->state.argc - || (parser->state.flags & ARGP_NO_ARGS)) - /* Indicate that we're done. */ - { - *arg_ebadkey = 1; - return EBADKEY; - } + || (parser->state.flags & ARGP_NO_ARGS)) + /* Indicate that we're done. */ + { + *arg_ebadkey = 1; + return EBADKEY; + } else - /* A non-option arg; simulate what getopt might have done. */ - { - opt = KEY_ARG; - parser->opt_data.optarg = parser->state.argv[parser->state.next++]; - } + /* A non-option arg; simulate what getopt might have done. */ + { + opt = KEY_ARG; + parser->opt_data.optarg = parser->state.argv[parser->state.next++]; + } } if (opt == KEY_ARG) @@ -869,7 +868,7 @@ parser_parse_next (struct parser *parser, int *arg_ebadkey) returned a non-zero value, it is returned; otherwise 0 is returned. */ error_t __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, - int *end_index, void *input) + int *end_index, void *input) { error_t err; struct parser parser; @@ -878,6 +877,20 @@ __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, to be parsed (which in some cases isn't actually an error). */ int arg_ebadkey = 0; +#ifndef _LIBC + if (!(flags & ARGP_PARSE_ARGV0)) + { +#if HAVE_DECL_PROGRAM_INVOCATION_NAME + if (!program_invocation_name) + program_invocation_name = argv[0]; +#endif +#if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME + if (!program_invocation_short_name) + program_invocation_short_name = __argp_base_name (argv[0]); +#endif + } +#endif + if (! (flags & ARGP_NO_HELP)) /* Add our own options. */ { @@ -885,17 +898,17 @@ __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, struct argp *top_argp = alloca (sizeof (struct argp)); /* TOP_ARGP has no options, it just serves to group the user & default - argps. */ + argps. */ memset (top_argp, 0, sizeof (*top_argp)); top_argp->children = child; memset (child, 0, 4 * sizeof (struct argp_child)); if (argp) - (child++)->argp = argp; + (child++)->argp = argp; (child++)->argp = &argp_default_argp; if (argp_program_version || argp_program_version_hook) - (child++)->argp = &argp_version_argp; + (child++)->argp = &argp_version_argp; child->argp = 0; argp = top_argp; @@ -908,7 +921,7 @@ __argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags, /* Parse! */ { while (! err) - err = parser_parse_next (&parser, &arg_ebadkey); + err = parser_parse_next (&parser, &arg_ebadkey); err = parser_finalize (&parser, err, arg_ebadkey, end_index); } @@ -929,8 +942,8 @@ __argp_input (const struct argp *argp, const struct argp_state *state) struct parser *parser = state->pstate; for (group = parser->groups; group < parser->egroup; group++) - if (group->argp == argp) - return group->input; + if (group->argp == argp) + return group->input; } return 0;