22 # define _GNU_SOURCE 1
56 # if defined HAVE_LIBINTL_H || defined _LIBC
60 # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES)
63 # define dgettext(domain, msgid) (msgid)
64 # define gettext(msgid) (msgid)
68 # define N_(msgid) (msgid)
72 #include <bits/libc-lock.h>
74 #ifdef HAVE_CTHREADS_H
80 #include "argp-namefrob.h"
88 #define EBADKEY ARGP_ERR_UNKNOWN
97 volatile int _argp_hang;
99 #define OPT_PROGNAME -2
103 static const struct argp_option argp_default_options[] =
105 {
"help",
'?', 0, 0, N_(
"Give this help list"), -1},
106 {
"usage", OPT_USAGE, 0, 0, N_(
"Give a short usage message"), 0 },
107 {
"program-name",OPT_PROGNAME,
"NAME", OPTION_HIDDEN,
108 N_(
"Set the program name"), 0},
109 {
"HANG", OPT_HANG,
"SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
110 N_(
"Hang for SECS seconds (default 3600)"), 0 },
115 argp_default_parser (
int key,
char *arg,
struct argp_state *state)
120 __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
123 __argp_state_help (state, state->out_stream,
124 ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
128 #if HAVE_DECL_PROGRAM_INVOCATION_NAME
129 program_invocation_name = arg;
137 state->name = __argp_basename(arg);
139 #if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
140 program_invocation_short_name = state->name;
143 if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
146 state->argv[0] = arg;
151 _argp_hang = atoi (arg ? arg :
"3600");
152 fprintf(state->err_stream,
"%s: pid = %ld\n",
153 state->name, (
long) getpid());
154 while (_argp_hang-- > 0)
164 static const struct argp argp_default_argp =
165 {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL,
"libc"};
168 static const struct argp_option argp_version_options[] =
170 {
"version",
'V', 0, 0, N_(
"Print program version"), -1},
175 argp_version_parser (
int key,
char *arg UNUSED,
struct argp_state *state)
180 if (argp_program_version_hook)
181 (*argp_program_version_hook) (state->out_stream, state);
182 else if (argp_program_version)
183 fprintf (state->out_stream,
"%s\n", argp_program_version);
185 __argp_error (state, dgettext (state->root_argp->argp_domain,
186 "(PROGRAM ERROR) No version known!?"));
187 if (! (state->flags & ARGP_NO_EXIT))
196 static const struct argp argp_version_argp =
197 {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL,
"libc"};
213 unsigned args_processed;
216 struct group *parent;
217 unsigned parent_index;
221 void *input, **child_inputs;
234 state->hook =
group->hook;
235 state->input =
group->input;
236 state->child_inputs =
group->child_inputs;
237 state->arg_num =
group->args_processed;
238 err = (*
group->parser)(key, arg, state);
239 group->hook = state->hook;
250 const char *posixly_correct;
283 enum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER } ordering;
305 struct group *groups;
307 struct group *egroup;
325 assert(isascii(key));
331 for (opts =
group->argp->options; !__option_is_end(opts); opts++)
332 if (opts->key == key)
341 enum match_result { MATCH_EXACT, MATCH_PARTIAL, MATCH_NO };
344 #ifndef ARGP_COMPLETE
345 #define ARGP_COMPLETE 0
350 static enum match_result
351 match_option(
const char *arg,
const char *name)
354 for (i = j = 0;; i++, j++)
360 return name[j] ? MATCH_PARTIAL : MATCH_EXACT;
363 while (name[j] !=
'-')
369 if (arg[i] != name[j])
383 struct group *matched_group = NULL;
393 for (opts =
group->argp->options; !__option_is_end(opts); opts++)
397 switch (match_option(arg, opts->name))
404 matched_group =
group;
405 matched_option = opts;
415 if (num_partial == 1)
418 return matched_option;
431 void **child_inputs_end;
437 static struct group *
438 convert_options (
const struct argp *
argp,
439 struct group *parent,
unsigned parent_index,
445 if (opt ||
argp->parser)
451 for ( ; !__option_is_end (opt); opt++)
452 if (__option_is_short(opt))
453 *cvt->short_end++ = opt->key;
458 group->args_processed = 0;
459 group->parent = parent;
460 group->parent_index = parent_index;
463 group->child_inputs = 0;
469 unsigned num_children = 0;
470 while (children[num_children].
argp)
472 group->child_inputs = cvt->child_inputs_end;
473 cvt->child_inputs_end += num_children;
483 while (children->argp)
485 convert_options (children++->
argp, parent, index++,
group, cvt);
499 cvt.short_end =
parser->short_opts;
500 cvt.child_inputs_end =
parser->child_inputs;
510 *cvt.short_end =
'\0';
520 size_t num_child_inputs;
532 if (opt ||
argp->parser)
538 while (__option_is_short (opt++))
546 calc_sizes ((child++)->
argp, szs);
547 szs->num_child_inputs++;
554 int argc,
char **argv,
int flags,
void *input)
560 parser->posixly_correct = getenv (
"POSIXLY_CORRECT");
562 if (flags & ARGP_IN_ORDER)
563 parser->ordering = RETURN_IN_ORDER;
564 else if (flags & ARGP_NO_ARGS)
565 parser->ordering = REQUIRE_ORDER;
566 else if (
parser->posixly_correct)
567 parser->ordering = REQUIRE_ORDER;
569 parser->ordering = PERMUTE;
573 szs.num_child_inputs = 0;
576 calc_sizes (
argp, &szs);
578 if (!(flags & ARGP_LONG_ONLY))
583 #define GLEN (szs.num_groups + 1) * sizeof (struct group)
584 #define CLEN (szs.num_child_inputs * sizeof (void *))
585 #define SLEN (szs.short_len + 1)
586 #define STORAGE(offset) ((void *) (((char *) parser->storage) + (offset)))
588 parser->storage = malloc (GLEN + CLEN + SLEN);
594 parser->child_inputs = STORAGE(GLEN);
595 memset (
parser->child_inputs, 0, szs.num_child_inputs * sizeof (
void *));
597 if (flags & ARGP_LONG_ONLY)
598 parser->short_opts = STORAGE(GLEN + CLEN);
600 parser->short_opts = NULL;
607 parser->state.argc = argc;
608 parser->state.argv = argv;
609 parser->state.flags = flags;
610 parser->state.err_stream = stderr;
611 parser->state.out_stream = stdout;
621 parser->groups->input = input;
631 &&
group->argp->children &&
group->argp->children->argp)
637 err = group_parse (
group, &
parser->state, ARGP_KEY_INIT, 0);
645 if (argv[0] && !(
parser->state.flags & ARGP_PARSE_ARGV0))
648 parser->state.name = __argp_basename(argv[0]);
654 parser->state.name = __argp_short_program_name(NULL);
662 error_t err,
int arg_ebadkey,
int *end_index)
666 if (err == EBADKEY && arg_ebadkey)
679 if (
group->args_processed == 0)
680 err = group_parse (
group, &
parser->state, ARGP_KEY_NO_ARGS, 0);
684 err = group_parse (
group, &
parser->state, ARGP_KEY_END, 0);
691 *end_index =
parser->state.next;
695 *end_index =
parser->state.next;
699 if (!(
parser->state.flags & ARGP_NO_ERRS)
700 &&
parser->state.err_stream)
701 fprintf (
parser->state.err_stream,
702 dgettext (
parser->argp->argp_domain,
703 "%s: Too many arguments\n"),
718 __argp_state_help (&
parser->state,
parser->state.err_stream,
723 group_parse (
group, &
parser->state, ARGP_KEY_ERROR, 0);
732 ;
group >=
parser->groups && (!err || err == EBADKEY)
734 err = group_parse (
group, &
parser->state, ARGP_KEY_SUCCESS, 0);
741 group_parse (
group, &
parser->state, ARGP_KEY_FINI, 0);
760 int index =
parser->state.next;
761 error_t err = EBADKEY;
772 err = group_parse (
group, &
parser->state, key, val);
785 if (key == ARGP_KEY_ARGS)
791 if (
parser->state.next > index)
795 (--
group)->args_processed += (
parser->state.next - index);
816 int bottom =
parser->first_nonopt;
817 int middle =
parser->last_nonopt;
818 int top =
parser->state.next;
819 char **argv =
parser->state.argv;
828 while (top > middle && middle > bottom)
830 if (top - middle > middle - bottom)
833 int len = middle - bottom;
837 for (i = 0; i < len; i++)
839 tem = argv[bottom + i];
840 argv[bottom + i] = argv[top - (middle - bottom) + i];
841 argv[top - (middle - bottom) + i] = tem;
849 int len = top - middle;
853 for (i = 0; i < len; i++)
855 tem = argv[bottom + i];
856 argv[bottom + i] = argv[middle + i];
857 argv[middle + i] = tem;
872 enum arg_type { ARG_ARG, ARG_SHORT_OPTION,
873 ARG_LONG_OPTION, ARG_LONG_ONLY_OPTION,
877 classify_arg(
struct parser *
parser,
char *arg,
char **opt)
894 return ARG_LONG_OPTION;
902 if (
parser->state.flags & ARGP_LONG_ONLY)
919 assert(
parser->short_opts);
921 if (arg[2] || !strchr(
parser->short_opts, arg[1]))
922 return ARG_LONG_ONLY_OPTION;
925 return ARG_SHORT_OPTION;
937 parser_parse_next (
struct parser *
parser,
int *arg_ebadkey)
961 assert(!
parser->args_only);
968 if (
parser->posixly_correct)
970 fprintf (
parser->state.err_stream,
971 dgettext(
parser->state.root_argp->argp_domain,
972 "%s: illegal option -- %c\n"),
975 fprintf (
parser->state.err_stream,
976 dgettext(
parser->state.root_argp->argp_domain,
977 "%s: invalid option -- %c\n"),
993 && !(option->flags & OPTION_ARG_OPTIONAL))
1000 fprintf (
parser->state.err_stream,
1001 dgettext(
parser->state.root_argp->argp_domain,
1002 "%s: option requires an argument -- %c\n"),
1012 option->key, value);
1024 return parser_parse_arg(
parser,
1055 enum arg_type token = classify_arg(
parser, arg, &optstart);
1060 switch (
parser->ordering)
1085 case RETURN_IN_ORDER:
1087 return parser_parse_arg(
parser, arg);
1116 case ARG_LONG_ONLY_OPTION:
1117 case ARG_LONG_OPTION:
1124 option = find_long_option(
parser, optstart, &
group);
1129 fprintf (
parser->state.err_stream,
1130 dgettext(
parser->state.root_argp->argp_domain,
1131 "%s: unrecognized option `%s'\n"),
1132 parser->state.name, arg);
1137 value = strchr(optstart,
'=');
1141 if (value && !option->arg)
1144 if (token == ARG_LONG_OPTION)
1146 fprintf (
parser->state.err_stream,
1147 dgettext(
parser->state.root_argp->argp_domain,
1148 "%s: option `--%s' doesn't allow an argument\n"),
1149 parser->state.name, option->name);
1152 fprintf (
parser->state.err_stream,
1153 dgettext(
parser->state.root_argp->argp_domain,
1154 "%s: option `%c%s' doesn't allow an argument\n"),
1155 parser->state.name, arg[0], option->name);
1161 if (option->arg && !value
1162 && !(option->flags & OPTION_ARG_OPTIONAL))
1168 if (token == ARG_LONG_OPTION)
1170 fprintf (
parser->state.err_stream,
1171 dgettext(
parser->state.root_argp->argp_domain,
1172 "%s: option `--%s' requires an argument\n"),
1173 parser->state.name, option->name);
1176 fprintf (
parser->state.err_stream,
1177 dgettext(
parser->state.root_argp->argp_domain,
1178 "%s: option `%c%s' requires an argument\n"),
1179 parser->state.name, arg[0], option->name);
1189 option->key, value);
1191 case ARG_SHORT_OPTION:
1193 parser->nextchar = optstart;
1209 __argp_parse (
const struct argp *
argp,
int argc,
char **argv,
unsigned flags,
1210 int *end_index,
void *input)
1217 int arg_ebadkey = 0;
1219 if (! (flags & ARGP_NO_HELP))
1223 struct argp *top_argp = alloca (
sizeof (
struct argp));
1227 memset (top_argp, 0,
sizeof (*top_argp));
1228 top_argp->children = child;
1230 memset (child, 0, 4 *
sizeof (
struct argp_child));
1234 (child++)->
argp = &argp_default_argp;
1235 if (argp_program_version || argp_program_version_hook)
1236 (child++)->
argp = &argp_version_argp;
1243 err = parser_init (&
parser,
argp, argc, argv, flags, input);
1249 err = parser_parse_next (&
parser, &arg_ebadkey);
1250 err = parser_finalize (&
parser, err, arg_ebadkey, end_index);
1256 weak_alias (__argp_parse, argp_parse)
1271 return group->input;
1277 weak_alias (__argp_input, _argp_input)
1283 __argp_usage (__const
struct argp_state *__state)
1285 __argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
1289 __option_is_short (__const
struct argp_option *__opt)
1291 if (__opt->flags & OPTION_DOC)
1295 int __key = __opt->key;
1298 return __key > 0 && isprint (__key);
1303 __option_is_end (__const
struct argp_option *__opt)
1305 return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;