Blame argp/argp-parse.c

Packit 6c4009
/* Hierarchial argument parsing, layered over getopt
Packit 6c4009
   Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
   Written by Miles Bader <miles@gnu.ai.mit.edu>.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#ifdef HAVE_CONFIG_H
Packit 6c4009
#include <config.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
/* AIX requires this to be the first thing in the file.  */
Packit 6c4009
#ifndef __GNUC__
Packit 6c4009
# if HAVE_ALLOCA_H || defined _LIBC
Packit 6c4009
#  include <alloca.h>
Packit 6c4009
# else
Packit 6c4009
#  ifdef _AIX
Packit 6c4009
#pragma alloca
Packit 6c4009
#  else
Packit 6c4009
#   ifndef alloca /* predefined by HP cc +Olibcalls */
Packit 6c4009
char *alloca ();
Packit 6c4009
#   endif
Packit 6c4009
#  endif
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <unistd.h>
Packit 6c4009
#include <limits.h>
Packit 6c4009
#include <getopt.h>
Packit 6c4009
#include <getopt_int.h>
Packit 6c4009
Packit 6c4009
#ifndef _
Packit 6c4009
/* This is for other GNU distributions with internationalized messages.
Packit 6c4009
   When compiling libc, the _ macro is predefined.  */
Packit 6c4009
# if defined HAVE_LIBINTL_H || defined _LIBC
Packit 6c4009
#  include <libintl.h>
Packit 6c4009
#  ifdef _LIBC
Packit 6c4009
#   undef dgettext
Packit 6c4009
#   define dgettext(domain, msgid) \
Packit 6c4009
  __dcgettext (domain, msgid, LC_MESSAGES)
Packit 6c4009
#  endif
Packit 6c4009
# else
Packit 6c4009
#  define dgettext(domain, msgid) (msgid)
Packit 6c4009
#  define gettext(msgid) (msgid)
Packit 6c4009
# endif
Packit 6c4009
#endif
Packit 6c4009
#ifndef N_
Packit 6c4009
# define N_(msgid) (msgid)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <argp.h>
Packit 6c4009
#include "argp-namefrob.h"
Packit 6c4009
Packit 6c4009
/* Getopt return values.  */
Packit 6c4009
#define KEY_END (-1)		/* The end of the options.  */
Packit 6c4009
#define KEY_ARG 1		/* A non-option argument.  */
Packit 6c4009
#define KEY_ERR '?'		/* An error parsing the options.  */
Packit 6c4009
Packit 6c4009
/* The meta-argument used to prevent any further arguments being interpreted
Packit 6c4009
   as options.  */
Packit 6c4009
#define QUOTE "--"
Packit 6c4009
Packit 6c4009
/* The number of bits we steal in a long-option value for our own use.  */
Packit 6c4009
#define GROUP_BITS CHAR_BIT
Packit 6c4009
Packit 6c4009
/* The number of bits available for the user value.  */
Packit 6c4009
#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
Packit 6c4009
#define USER_MASK ((1 << USER_BITS) - 1)
Packit 6c4009
Packit 6c4009
/* EZ alias for ARGP_ERR_UNKNOWN.  */
Packit 6c4009
#define EBADKEY ARGP_ERR_UNKNOWN
Packit 6c4009

Packit 6c4009
/* Default options.  */
Packit 6c4009
Packit 6c4009
/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
Packit 6c4009
   for one second intervals, decrementing _ARGP_HANG until it's zero.  Thus
Packit 6c4009
   you can force the program to continue by attaching a debugger and setting
Packit 6c4009
   it to 0 yourself.  */
Packit 6c4009
static volatile int _argp_hang;
Packit 6c4009
Packit 6c4009
#define OPT_PROGNAME	-2
Packit 6c4009
#define OPT_USAGE	-3
Packit 6c4009
#define OPT_HANG	-4
Packit 6c4009
Packit 6c4009
static const struct argp_option argp_default_options[] =
Packit 6c4009
{
Packit 6c4009
  {"help",	  '?',	  	0, 0,  N_("Give this help list"), -1},
Packit 6c4009
  {"usage",	  OPT_USAGE,	0, 0,  N_("Give a short usage message")},
Packit 6c4009
  {"program-name",OPT_PROGNAME, N_("NAME"), OPTION_HIDDEN,
Packit 6c4009
   N_("Set the program name")},
Packit 6c4009
  {"HANG",	  OPT_HANG,    N_("SECS"), OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
Packit 6c4009
   N_("Hang for SECS seconds (default 3600)")},
Packit 6c4009
  {0, 0}
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
static error_t
Packit 6c4009
argp_default_parser (int key, char *arg, struct argp_state *state)
Packit 6c4009
{
Packit 6c4009
  switch (key)
Packit 6c4009
    {
Packit 6c4009
    case '?':
Packit 6c4009
      __argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
Packit 6c4009
      break;
Packit 6c4009
    case OPT_USAGE:
Packit 6c4009
      __argp_state_help (state, state->out_stream,
Packit 6c4009
		       ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
Packit 6c4009
      break;
Packit 6c4009
Packit 6c4009
    case OPT_PROGNAME:		/* Set the program name.  */
Packit 6c4009
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
Packit 6c4009
      program_invocation_name = arg;
Packit 6c4009
#endif
Packit 6c4009
      /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
Packit 6c4009
	 __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
Packit 6c4009
	 to be that, so we have to be a bit careful here.]  */
Packit 6c4009
Packit 6c4009
      /* Update what we use for messages.  */
Packit 6c4009
      state->name = strrchr (arg, '/');
Packit 6c4009
      if (state->name)
Packit 6c4009
	state->name++;
Packit 6c4009
      else
Packit 6c4009
	state->name = arg;
Packit 6c4009
Packit 6c4009
#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
Packit 6c4009
      program_invocation_short_name = state->name;
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
      if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
Packit 6c4009
	  == ARGP_PARSE_ARGV0)
Packit 6c4009
	/* Update what getopt uses too.  */
Packit 6c4009
	state->argv[0] = arg;
Packit 6c4009
Packit 6c4009
      break;
Packit 6c4009
Packit 6c4009
    case OPT_HANG:
Packit 6c4009
      _argp_hang = atoi (arg ? arg : "3600");
Packit 6c4009
      while (_argp_hang-- > 0)
Packit 6c4009
	__sleep (1);
Packit 6c4009
      break;
Packit 6c4009
Packit 6c4009
    default:
Packit 6c4009
      return EBADKEY;
Packit 6c4009
    }
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static const struct argp argp_default_argp =
Packit 6c4009
  {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
Packit 6c4009
Packit 6c4009

Packit 6c4009
static const struct argp_option argp_version_options[] =
Packit 6c4009
{
Packit 6c4009
  {"version",	  'V',	  	0, 0,  N_("Print program version"), -1},
Packit 6c4009
  {0, 0}
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
static error_t
Packit 6c4009
argp_version_parser (int key, char *arg, struct argp_state *state)
Packit 6c4009
{
Packit 6c4009
  switch (key)
Packit 6c4009
    {
Packit 6c4009
    case 'V':
Packit 6c4009
      if (argp_program_version_hook)
Packit 6c4009
	(*argp_program_version_hook) (state->out_stream, state);
Packit 6c4009
      else if (argp_program_version)
Packit 6c4009
	fprintf (state->out_stream, "%s\n", argp_program_version);
Packit 6c4009
      else
Packit 6c4009
	__argp_error (state, dgettext (state->root_argp->argp_domain,
Packit 6c4009
				       "(PROGRAM ERROR) No version known!?"));
Packit 6c4009
      if (! (state->flags & ARGP_NO_EXIT))
Packit 6c4009
	exit (0);
Packit 6c4009
      break;
Packit 6c4009
    default:
Packit 6c4009
      return EBADKEY;
Packit 6c4009
    }
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static const struct argp argp_version_argp =
Packit 6c4009
  {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
Packit 6c4009

Packit 6c4009
/* Returns the offset into the getopt long options array LONG_OPTIONS of a
Packit 6c4009
   long option with called NAME, or -1 if none is found.  Passing NULL as
Packit 6c4009
   NAME will return the number of options.  */
Packit 6c4009
static int
Packit 6c4009
find_long_option (struct option *long_options, const char *name)
Packit 6c4009
{
Packit 6c4009
  struct option *l = long_options;
Packit 6c4009
  while (l->name != NULL)
Packit 6c4009
    if (name != NULL && strcmp (l->name, name) == 0)
Packit 6c4009
      return l - long_options;
Packit 6c4009
    else
Packit 6c4009
      l++;
Packit 6c4009
  if (name == NULL)
Packit 6c4009
    return l - long_options;
Packit 6c4009
  else
Packit 6c4009
    return -1;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009

Packit 6c4009
/* The state of a `group' during parsing.  Each group corresponds to a
Packit 6c4009
   particular argp structure from the tree of such descending from the top
Packit 6c4009
   level argp passed to argp_parse.  */
Packit 6c4009
struct group
Packit 6c4009
{
Packit 6c4009
  /* This group's parsing function.  */
Packit 6c4009
  argp_parser_t parser;
Packit 6c4009
Packit 6c4009
  /* Which argp this group is from.  */
Packit 6c4009
  const struct argp *argp;
Packit 6c4009
Packit 6c4009
  /* Points to the point in SHORT_OPTS corresponding to the end of the short
Packit 6c4009
     options for this group.  We use it to determine from which group a
Packit 6c4009
     particular short options is from.  */
Packit 6c4009
  char *short_end;
Packit 6c4009
Packit 6c4009
  /* The number of non-option args sucessfully handled by this parser.  */
Packit 6c4009
  unsigned args_processed;
Packit 6c4009
Packit 6c4009
  /* This group's parser's parent's group.  */
Packit 6c4009
  struct group *parent;
Packit 6c4009
  unsigned parent_index;	/* And the our position in the parent.   */
Packit 6c4009
Packit 6c4009
  /* These fields are swapped into and out of the state structure when
Packit 6c4009
     calling this group's parser.  */
Packit 6c4009
  void *input, **child_inputs;
Packit 6c4009
  void *hook;
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
Packit 6c4009
   from STATE before calling, and back into state afterwards.  If GROUP has
Packit 6c4009
   no parser, EBADKEY is returned.  */
Packit 6c4009
static error_t
Packit 6c4009
group_parse (struct group *group, struct argp_state *state, int key, char *arg)
Packit 6c4009
{
Packit 6c4009
  if (group->parser)
Packit 6c4009
    {
Packit 6c4009
      error_t err;
Packit 6c4009
      state->hook = group->hook;
Packit 6c4009
      state->input = group->input;
Packit 6c4009
      state->child_inputs = group->child_inputs;
Packit 6c4009
      state->arg_num = group->args_processed;
Packit 6c4009
      err = (*group->parser)(key, arg, state);
Packit 6c4009
      group->hook = state->hook;
Packit 6c4009
      return err;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    return EBADKEY;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
struct parser
Packit 6c4009
{
Packit 6c4009
  const struct argp *argp;
Packit 6c4009
Packit 6c4009
  /* SHORT_OPTS is the getopt short options string for the union of all the
Packit 6c4009
     groups of options.  */
Packit 6c4009
  char *short_opts;
Packit 6c4009
  /* LONG_OPTS is the array of getop long option structures for the union of
Packit 6c4009
     all the groups of options.  */
Packit 6c4009
  struct option *long_opts;
Packit 6c4009
  /* OPT_DATA is the getopt data used for the re-entrant getopt.  */
Packit 6c4009
  struct _getopt_data opt_data;
Packit 6c4009
Packit 6c4009
  /* States of the various parsing groups.  */
Packit 6c4009
  struct group *groups;
Packit 6c4009
  /* The end of the GROUPS array.  */
Packit 6c4009
  struct group *egroup;
Packit 6c4009
  /* An vector containing storage for the CHILD_INPUTS field in all groups.  */
Packit 6c4009
  void **child_inputs;
Packit 6c4009
Packit 6c4009
  /* True if we think using getopt is still useful; if false, then
Packit 6c4009
     remaining arguments are just passed verbatim with ARGP_KEY_ARG.  This is
Packit 6c4009
     cleared whenever getopt returns KEY_END, but may be set again if the user
Packit 6c4009
     moves the next argument pointer backwards.  */
Packit 6c4009
  int try_getopt;
Packit 6c4009
Packit 6c4009
  /* State block supplied to parsing routines.  */
Packit 6c4009
  struct argp_state state;
Packit 6c4009
Packit 6c4009
  /* Memory used by this parser.  */
Packit 6c4009
  void *storage;
Packit 6c4009
};
Packit 6c4009

Packit 6c4009
/* The next usable entries in the various parser tables being filled in by
Packit 6c4009
   convert_options.  */
Packit 6c4009
struct parser_convert_state
Packit 6c4009
{
Packit 6c4009
  struct parser *parser;
Packit 6c4009
  char *short_end;
Packit 6c4009
  struct option *long_end;
Packit 6c4009
  void **child_inputs_end;
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* Converts all options in ARGP (which is put in GROUP) and ancestors
Packit 6c4009
   into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
Packit 6c4009
   CVT->LONG_END are the points at which new options are added.  Returns the
Packit 6c4009
   next unused group entry.  CVT holds state used during the conversion.  */
Packit 6c4009
static struct group *
Packit 6c4009
convert_options (const struct argp *argp,
Packit 6c4009
		 struct group *parent, unsigned parent_index,
Packit 6c4009
		 struct group *group, struct parser_convert_state *cvt)
Packit 6c4009
{
Packit 6c4009
  /* REAL is the most recent non-alias value of OPT.  */
Packit 6c4009
  const struct argp_option *real = argp->options;
Packit 6c4009
  const struct argp_child *children = argp->children;
Packit 6c4009
Packit 6c4009
  if (real || argp->parser)
Packit 6c4009
    {
Packit 6c4009
      const struct argp_option *opt;
Packit 6c4009
Packit 6c4009
      if (real)
Packit 6c4009
	for (opt = real; !__option_is_end (opt); opt++)
Packit 6c4009
	  {
Packit 6c4009
	    if (! (opt->flags & OPTION_ALIAS))
Packit 6c4009
	      /* OPT isn't an alias, so we can use values from it.  */
Packit 6c4009
	      real = opt;
Packit 6c4009
Packit 6c4009
	    if (! (real->flags & OPTION_DOC))
Packit 6c4009
	      /* A real option (not just documentation).  */
Packit 6c4009
	      {
Packit 6c4009
		if (__option_is_short (opt))
Packit 6c4009
		  /* OPT can be used as a short option.  */
Packit 6c4009
		  {
Packit 6c4009
		    *cvt->short_end++ = opt->key;
Packit 6c4009
		    if (real->arg)
Packit 6c4009
		      {
Packit 6c4009
			*cvt->short_end++ = ':';
Packit 6c4009
			if (real->flags & OPTION_ARG_OPTIONAL)
Packit 6c4009
			  *cvt->short_end++ = ':';
Packit 6c4009
		      }
Packit 6c4009
		    *cvt->short_end = '\0'; /* keep 0 terminated */
Packit 6c4009
		  }
Packit 6c4009
Packit 6c4009
		if (opt->name
Packit 6c4009
		    && find_long_option (cvt->parser->long_opts, opt->name) < 0)
Packit 6c4009
		  /* OPT can be used as a long option.  */
Packit 6c4009
		  {
Packit 6c4009
		    cvt->long_end->name = opt->name;
Packit 6c4009
		    cvt->long_end->has_arg =
Packit 6c4009
		      (real->arg
Packit 6c4009
		       ? (real->flags & OPTION_ARG_OPTIONAL
Packit 6c4009
			  ? optional_argument
Packit 6c4009
			  : required_argument)
Packit 6c4009
		       : no_argument);
Packit 6c4009
		    cvt->long_end->flag = 0;
Packit 6c4009
		    /* we add a disambiguating code to all the user's
Packit 6c4009
		       values (which is removed before we actually call
Packit 6c4009
		       the function to parse the value); this means that
Packit 6c4009
		       the user loses use of the high 8 bits in all his
Packit 6c4009
		       values (the sign of the lower bits is preserved
Packit 6c4009
		       however)...  */
Packit 6c4009
		    cvt->long_end->val =
Packit 6c4009
		      ((opt->key ? opt->key : real->key) & USER_MASK)
Packit 6c4009
		      + (((group - cvt->parser->groups) + 1) << USER_BITS);
Packit 6c4009
Packit 6c4009
		    /* Keep the LONG_OPTS list terminated.  */
Packit 6c4009
		    (++cvt->long_end)->name = NULL;
Packit 6c4009
		  }
Packit 6c4009
	      }
Packit 6c4009
	    }
Packit 6c4009
Packit 6c4009
      group->parser = argp->parser;
Packit 6c4009
      group->argp = argp;
Packit 6c4009
      group->short_end = cvt->short_end;
Packit 6c4009
      group->args_processed = 0;
Packit 6c4009
      group->parent = parent;
Packit 6c4009
      group->parent_index = parent_index;
Packit 6c4009
      group->input = 0;
Packit 6c4009
      group->hook = 0;
Packit 6c4009
      group->child_inputs = 0;
Packit 6c4009
Packit 6c4009
      if (children)
Packit 6c4009
	/* Assign GROUP's CHILD_INPUTS field some space from
Packit 6c4009
	   CVT->child_inputs_end.*/
Packit 6c4009
	{
Packit 6c4009
	  unsigned num_children = 0;
Packit 6c4009
	  while (children[num_children].argp)
Packit 6c4009
	    num_children++;
Packit 6c4009
	  group->child_inputs = cvt->child_inputs_end;
Packit 6c4009
	  cvt->child_inputs_end += num_children;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      parent = group++;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    parent = 0;
Packit 6c4009
Packit 6c4009
  if (children)
Packit 6c4009
    {
Packit 6c4009
      unsigned index = 0;
Packit 6c4009
      while (children->argp)
Packit 6c4009
	group =
Packit 6c4009
	  convert_options (children++->argp, parent, index++, group, cvt);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return group;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Find the merged set of getopt options, with keys appropriately prefixed. */
Packit 6c4009
static void
Packit 6c4009
parser_convert (struct parser *parser, const struct argp *argp, int flags)
Packit 6c4009
{
Packit 6c4009
  struct parser_convert_state cvt;
Packit 6c4009
Packit 6c4009
  cvt.parser = parser;
Packit 6c4009
  cvt.short_end = parser->short_opts;
Packit 6c4009
  cvt.long_end = parser->long_opts;
Packit 6c4009
  cvt.child_inputs_end = parser->child_inputs;
Packit 6c4009
Packit 6c4009
  if (flags & ARGP_IN_ORDER)
Packit 6c4009
    *cvt.short_end++ = '-';
Packit 6c4009
  else if (flags & ARGP_NO_ARGS)
Packit 6c4009
    *cvt.short_end++ = '+';
Packit 6c4009
  *cvt.short_end = '\0';
Packit 6c4009
Packit 6c4009
  cvt.long_end->name = NULL;
Packit 6c4009
Packit 6c4009
  parser->argp = argp;
Packit 6c4009
Packit 6c4009
  if (argp)
Packit 6c4009
    parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
Packit 6c4009
  else
Packit 6c4009
    parser->egroup = parser->groups; /* No parsers at all! */
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Lengths of various parser fields which we will allocated.  */
Packit 6c4009
struct parser_sizes
Packit 6c4009
{
Packit 6c4009
  size_t short_len;		/* Getopt short options string.  */
Packit 6c4009
  size_t long_len;		/* Getopt long options vector.  */
Packit 6c4009
  size_t num_groups;		/* Group structures we allocate.  */
Packit 6c4009
  size_t num_child_inputs;	/* Child input slots.  */
Packit 6c4009
};
Packit 6c4009
Packit 6c4009
/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
Packit 6c4009
 argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
Packit 6c4009
 the maximum lengths of the resulting merged getopt short options string and
Packit 6c4009
 long-options array, respectively.  */
Packit 6c4009
static void
Packit 6c4009
calc_sizes (const struct argp *argp,  struct parser_sizes *szs)
Packit 6c4009
{
Packit 6c4009
  const struct argp_child *child = argp->children;
Packit 6c4009
  const struct argp_option *opt = argp->options;
Packit 6c4009
Packit 6c4009
  if (opt || argp->parser)
Packit 6c4009
    {
Packit 6c4009
      szs->num_groups++;
Packit 6c4009
      if (opt)
Packit 6c4009
	{
Packit 6c4009
	  int num_opts = 0;
Packit 6c4009
	  while (!__option_is_end (opt++))
Packit 6c4009
	    num_opts++;
Packit 6c4009
	  szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
Packit 6c4009
	  szs->long_len += num_opts;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (child)
Packit 6c4009
    while (child->argp)
Packit 6c4009
      {
Packit 6c4009
	calc_sizes ((child++)->argp, szs);
Packit 6c4009
	szs->num_child_inputs++;
Packit 6c4009
      }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
/* Initializes PARSER to parse ARGP in a manner described by FLAGS.  */
Packit 6c4009
static error_t
Packit 6c4009
parser_init (struct parser *parser, const struct argp *argp,
Packit 6c4009
	     int argc, char **argv, int flags, void *input)
Packit 6c4009
{
Packit 6c4009
  error_t err = 0;
Packit 6c4009
  struct group *group;
Packit 6c4009
  struct parser_sizes szs;
Packit 6c4009
  struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
Packit 6c4009
Packit 6c4009
  szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
Packit 6c4009
  szs.long_len = 0;
Packit 6c4009
  szs.num_groups = 0;
Packit 6c4009
  szs.num_child_inputs = 0;
Packit 6c4009
Packit 6c4009
  if (argp)
Packit 6c4009
    calc_sizes (argp, &szs;;
Packit 6c4009
Packit 6c4009
  /* Lengths of the various bits of storage used by PARSER.  */
Packit 6c4009
#define GLEN (szs.num_groups + 1) * sizeof (struct group)
Packit 6c4009
#define CLEN (szs.num_child_inputs * sizeof (void *))
Packit 6c4009
#define LLEN ((szs.long_len + 1) * sizeof (struct option))
Packit 6c4009
#define SLEN (szs.short_len + 1)
Packit 6c4009
Packit 6c4009
  parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
Packit 6c4009
  if (! parser->storage)
Packit 6c4009
    return ENOMEM;
Packit 6c4009
Packit 6c4009
  parser->groups = parser->storage;
Packit 6c4009
  parser->child_inputs = parser->storage + GLEN;
Packit 6c4009
  parser->long_opts = parser->storage + GLEN + CLEN;
Packit 6c4009
  parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
Packit 6c4009
  parser->opt_data = opt_data;
Packit 6c4009
Packit 6c4009
  memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
Packit 6c4009
  parser_convert (parser, argp, flags);
Packit 6c4009
Packit 6c4009
  memset (&parser->state, 0, sizeof (struct argp_state));
Packit 6c4009
  parser->state.root_argp = parser->argp;
Packit 6c4009
  parser->state.argc = argc;
Packit 6c4009
  parser->state.argv = argv;
Packit 6c4009
  parser->state.flags = flags;
Packit 6c4009
  parser->state.err_stream = stderr;
Packit 6c4009
  parser->state.out_stream = stdout;
Packit 6c4009
  parser->state.next = 0;	/* Tell getopt to initialize.  */
Packit 6c4009
  parser->state.pstate = parser;
Packit 6c4009
Packit 6c4009
  parser->try_getopt = 1;
Packit 6c4009
Packit 6c4009
  /* Call each parser for the first time, giving it a chance to propagate
Packit 6c4009
     values to child parsers.  */
Packit 6c4009
  if (parser->groups < parser->egroup)
Packit 6c4009
    parser->groups->input = input;
Packit 6c4009
  for (group = parser->groups;
Packit 6c4009
       group < parser->egroup && (!err || err == EBADKEY);
Packit 6c4009
       group++)
Packit 6c4009
    {
Packit 6c4009
      if (group->parent)
Packit 6c4009
	/* If a child parser, get the initial input value from the parent. */
Packit 6c4009
	group->input = group->parent->child_inputs[group->parent_index];
Packit 6c4009
Packit 6c4009
      if (!group->parser
Packit 6c4009
	  && group->argp->children && group->argp->children->argp)
Packit 6c4009
	/* For the special case where no parsing function is supplied for an
Packit 6c4009
	   argp, propagate its input to its first child, if any (this just
Packit 6c4009
	   makes very simple wrapper argps more convenient).  */
Packit 6c4009
	group->child_inputs[0] = group->input;
Packit 6c4009
Packit 6c4009
      err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
Packit 6c4009
    }
Packit 6c4009
  if (err == EBADKEY)
Packit 6c4009
    err = 0;			/* Some parser didn't understand.  */
Packit 6c4009
Packit 6c4009
  if (err)
Packit 6c4009
    return err;
Packit 6c4009
Packit 6c4009
  if (parser->state.flags & ARGP_NO_ERRS)
Packit 6c4009
    {
Packit 6c4009
      parser->opt_data.opterr = 0;
Packit 6c4009
      if (parser->state.flags & ARGP_PARSE_ARGV0)
Packit 6c4009
	/* getopt always skips ARGV[0], so we have to fake it out.  As long
Packit 6c4009
	   as OPTERR is 0, then it shouldn't actually try to access it.  */
Packit 6c4009
	parser->state.argv--, parser->state.argc++;
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    parser->opt_data.opterr = 1;	/* Print error messages.  */
Packit 6c4009
Packit 6c4009
  if (parser->state.argv == argv && argv[0])
Packit 6c4009
    /* There's an argv[0]; use it for messages.  */
Packit 6c4009
    {
Packit 6c4009
      char *short_name = strrchr (argv[0], '/');
Packit 6c4009
      parser->state.name = short_name ? short_name + 1 : argv[0];
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    parser->state.name = __argp_short_program_name ();
Packit 6c4009
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Free any storage consumed by PARSER (but not PARSER itself).  */
Packit 6c4009
static error_t
Packit 6c4009
parser_finalize (struct parser *parser,
Packit 6c4009
		 error_t err, int arg_ebadkey, int *end_index)
Packit 6c4009
{
Packit 6c4009
  struct group *group;
Packit 6c4009
Packit 6c4009
  if (err == EBADKEY && arg_ebadkey)
Packit 6c4009
    /* Suppress errors generated by unparsed arguments.  */
Packit 6c4009
    err = 0;
Packit 6c4009
Packit 6c4009
  if (! err)
Packit 6c4009
    {
Packit 6c4009
      if (parser->state.next == parser->state.argc)
Packit 6c4009
	/* We successfully parsed all arguments!  Call all the parsers again,
Packit 6c4009
	   just a few more times... */
Packit 6c4009
	{
Packit 6c4009
	  for (group = parser->groups;
Packit 6c4009
	       group < parser->egroup && (!err || err==EBADKEY);
Packit 6c4009
	       group++)
Packit 6c4009
	    if (group->args_processed == 0)
Packit 6c4009
	      err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
Packit 6c4009
	  for (group = parser->egroup - 1;
Packit 6c4009
	       group >= parser->groups && (!err || err==EBADKEY);
Packit 6c4009
	       group--)
Packit 6c4009
	    err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
Packit 6c4009
Packit 6c4009
	  if (err == EBADKEY)
Packit 6c4009
	    err = 0;		/* Some parser didn't understand.  */
Packit 6c4009
Packit 6c4009
	  /* Tell the user that all arguments are parsed.  */
Packit 6c4009
	  if (end_index)
Packit 6c4009
	    *end_index = parser->state.next;
Packit 6c4009
	}
Packit 6c4009
      else if (end_index)
Packit 6c4009
	/* Return any remaining arguments to the user.  */
Packit 6c4009
	*end_index = parser->state.next;
Packit 6c4009
      else
Packit 6c4009
	/* No way to return the remaining arguments, they must be bogus. */
Packit 6c4009
	{
Packit 6c4009
	  if (!(parser->state.flags & ARGP_NO_ERRS)
Packit 6c4009
	      && parser->state.err_stream)
Packit 6c4009
	    fprintf (parser->state.err_stream,
Packit 6c4009
		     dgettext (parser->argp->argp_domain,
Packit 6c4009
			       "%s: Too many arguments\n"),
Packit 6c4009
		     parser->state.name);
Packit 6c4009
	  err = EBADKEY;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Okay, we're all done, with either an error or success; call the parsers
Packit 6c4009
     to indicate which one.  */
Packit 6c4009
Packit 6c4009
  if (err)
Packit 6c4009
    {
Packit 6c4009
      /* Maybe print an error message.  */
Packit 6c4009
      if (err == EBADKEY)
Packit 6c4009
	/* An appropriate message describing what the error was should have
Packit 6c4009
	   been printed earlier.  */
Packit 6c4009
	__argp_state_help (&parser->state, parser->state.err_stream,
Packit 6c4009
			   ARGP_HELP_STD_ERR);
Packit 6c4009
Packit 6c4009
      /* Since we didn't exit, give each parser an error indication.  */
Packit 6c4009
      for (group = parser->groups; group < parser->egroup; group++)
Packit 6c4009
	group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    /* Notify parsers of success, and propagate back values from parsers.  */
Packit 6c4009
    {
Packit 6c4009
      /* We pass over the groups in reverse order so that child groups are
Packit 6c4009
	 given a chance to do there processing before passing back a value to
Packit 6c4009
	 the parent.  */
Packit 6c4009
      for (group = parser->egroup - 1
Packit 6c4009
	   ; group >= parser->groups && (!err || err == EBADKEY)
Packit 6c4009
	   ; group--)
Packit 6c4009
	err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
Packit 6c4009
      if (err == EBADKEY)
Packit 6c4009
	err = 0;		/* Some parser didn't understand.  */
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Call parsers once more, to do any final cleanup.  Errors are ignored.  */
Packit 6c4009
  for (group = parser->egroup - 1; group >= parser->groups; group--)
Packit 6c4009
    group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
Packit 6c4009
Packit 6c4009
  if (err == EBADKEY)
Packit 6c4009
    err = EINVAL;
Packit 6c4009
Packit 6c4009
  free (parser->storage);
Packit 6c4009
Packit 6c4009
  return err;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Call the user parsers to parse the non-option argument VAL, at the current
Packit 6c4009
   position, returning any error.  The state NEXT pointer is assumed to have
Packit 6c4009
   been adjusted (by getopt) to point after this argument; this function will
Packit 6c4009
   adjust it correctly to reflect however many args actually end up being
Packit 6c4009
   consumed.  */
Packit 6c4009
static error_t
Packit 6c4009
parser_parse_arg (struct parser *parser, char *val)
Packit 6c4009
{
Packit 6c4009
  /* Save the starting value of NEXT, first adjusting it so that the arg
Packit 6c4009
     we're parsing is again the front of the arg vector.  */
Packit 6c4009
  int index = --parser->state.next;
Packit 6c4009
  error_t err = EBADKEY;
Packit 6c4009
  struct group *group;
Packit 6c4009
  int key = 0;			/* Which of ARGP_KEY_ARG[S] we used.  */
Packit 6c4009
Packit 6c4009
  /* Try to parse the argument in each parser.  */
Packit 6c4009
  for (group = parser->groups
Packit 6c4009
       ; group < parser->egroup && err == EBADKEY
Packit 6c4009
       ; group++)
Packit 6c4009
    {
Packit 6c4009
      parser->state.next++;	/* For ARGP_KEY_ARG, consume the arg.  */
Packit 6c4009
      key = ARGP_KEY_ARG;
Packit 6c4009
      err = group_parse (group, &parser->state, key, val);
Packit 6c4009
Packit 6c4009
      if (err == EBADKEY)
Packit 6c4009
	/* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
Packit 6c4009
	{
Packit 6c4009
	  parser->state.next--;	/* For ARGP_KEY_ARGS, put back the arg.  */
Packit 6c4009
	  key = ARGP_KEY_ARGS;
Packit 6c4009
	  err = group_parse (group, &parser->state, key, 0);
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (! err)
Packit 6c4009
    {
Packit 6c4009
      if (key == ARGP_KEY_ARGS)
Packit 6c4009
	/* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
Packit 6c4009
	   changed by the user, *all* arguments should be considered
Packit 6c4009
	   consumed.  */
Packit 6c4009
	parser->state.next = parser->state.argc;
Packit 6c4009
Packit 6c4009
      if (parser->state.next > index)
Packit 6c4009
	/* Remember that we successfully processed a non-option
Packit 6c4009
	   argument -- but only if the user hasn't gotten tricky and set
Packit 6c4009
	   the clock back.  */
Packit 6c4009
	(--group)->args_processed += (parser->state.next - index);
Packit 6c4009
      else
Packit 6c4009
	/* The user wants to reparse some args, give getopt another try.  */
Packit 6c4009
	parser->try_getopt = 1;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return err;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Call the user parsers to parse the option OPT, with argument VAL, at the
Packit 6c4009
   current position, returning any error.  */
Packit 6c4009
static error_t
Packit 6c4009
parser_parse_opt (struct parser *parser, int opt, char *val)
Packit 6c4009
{
Packit 6c4009
  /* The group key encoded in the high bits; 0 for short opts or
Packit 6c4009
     group_number + 1 for long opts.  */
Packit 6c4009
  int group_key = opt >> USER_BITS;
Packit 6c4009
  error_t err = EBADKEY;
Packit 6c4009
Packit 6c4009
  if (group_key == 0)
Packit 6c4009
    /* A short option.  By comparing OPT's position in SHORT_OPTS to the
Packit 6c4009
       various starting positions in each group's SHORT_END field, we can
Packit 6c4009
       determine which group OPT came from.  */
Packit 6c4009
    {
Packit 6c4009
      struct group *group;
Packit 6c4009
      char *short_index = strchr (parser->short_opts, opt);
Packit 6c4009
Packit 6c4009
      if (short_index)
Packit 6c4009
	for (group = parser->groups; group < parser->egroup; group++)
Packit 6c4009
	  if (group->short_end > short_index)
Packit 6c4009
	    {
Packit 6c4009
	      err = group_parse (group, &parser->state, opt,
Packit 6c4009
				 parser->opt_data.optarg);
Packit 6c4009
	      break;
Packit 6c4009
	    }
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    /* A long option.  We use shifts instead of masking for extracting
Packit 6c4009
       the user value in order to preserve the sign.  */
Packit 6c4009
    err =
Packit 6c4009
      group_parse (&parser->groups[group_key - 1], &parser->state,
Packit 6c4009
		   (opt << GROUP_BITS) >> GROUP_BITS,
Packit 6c4009
		   parser->opt_data.optarg);
Packit 6c4009
Packit 6c4009
  if (err == EBADKEY)
Packit 6c4009
    /* At least currently, an option not recognized is an error in the
Packit 6c4009
       parser, because we pre-compute which parser is supposed to deal
Packit 6c4009
       with each option.  */
Packit 6c4009
    {
Packit 6c4009
      static const char bad_key_err[] =
Packit 6c4009
	N_("(PROGRAM ERROR) Option should have been recognized!?");
Packit 6c4009
      if (group_key == 0)
Packit 6c4009
	__argp_error (&parser->state, "-%c: %s", opt,
Packit 6c4009
		      dgettext (parser->argp->argp_domain, bad_key_err));
Packit 6c4009
      else
Packit 6c4009
	{
Packit 6c4009
	  struct option *long_opt = parser->long_opts;
Packit 6c4009
	  while (long_opt->val != opt && long_opt->name)
Packit 6c4009
	    long_opt++;
Packit 6c4009
	  __argp_error (&parser->state, "--%s: %s",
Packit 6c4009
			long_opt->name ? long_opt->name : "???",
Packit 6c4009
			dgettext (parser->argp->argp_domain, bad_key_err));
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return err;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
Packit 6c4009
   Any error from the parsers is returned, and *ARGP_EBADKEY indicates
Packit 6c4009
   whether a value of EBADKEY is due to an unrecognized argument (which is
Packit 6c4009
   generally not fatal).  */
Packit 6c4009
static error_t
Packit 6c4009
parser_parse_next (struct parser *parser, int *arg_ebadkey)
Packit 6c4009
{
Packit 6c4009
  int opt;
Packit 6c4009
  error_t err = 0;
Packit 6c4009
Packit 6c4009
  if (parser->state.quoted && parser->state.next < parser->state.quoted)
Packit 6c4009
    /* The next argument pointer has been moved to before the quoted
Packit 6c4009
       region, so pretend we never saw the quoting `--', and give getopt
Packit 6c4009
       another chance.  If the user hasn't removed it, getopt will just
Packit 6c4009
       process it again.  */
Packit 6c4009
    parser->state.quoted = 0;
Packit 6c4009
Packit 6c4009
  if (parser->try_getopt && !parser->state.quoted)
Packit 6c4009
    /* Give getopt a chance to parse this.  */
Packit 6c4009
    {
Packit 6c4009
      /* Put it back in OPTIND for getopt.  */
Packit 6c4009
      parser->opt_data.optind = parser->state.next;
Packit 6c4009
      /* Distinguish KEY_ERR from a real option.  */
Packit 6c4009
      parser->opt_data.optopt = KEY_END;
Packit 6c4009
      if (parser->state.flags & ARGP_LONG_ONLY)
Packit 6c4009
	opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
Packit 6c4009
				   parser->short_opts, parser->long_opts, 0,
Packit 6c4009
				   &parser->opt_data);
Packit 6c4009
      else
Packit 6c4009
	opt = _getopt_long_r (parser->state.argc, parser->state.argv,
Packit 6c4009
			      parser->short_opts, parser->long_opts, 0,
Packit 6c4009
			      &parser->opt_data);
Packit 6c4009
      /* And see what getopt did.  */
Packit 6c4009
      parser->state.next = parser->opt_data.optind;
Packit 6c4009
Packit 6c4009
      if (opt == KEY_END)
Packit 6c4009
	/* Getopt says there are no more options, so stop using
Packit 6c4009
	   getopt; we'll continue if necessary on our own.  */
Packit 6c4009
	{
Packit 6c4009
	  parser->try_getopt = 0;
Packit 6c4009
	  if (parser->state.next > 1
Packit 6c4009
	      && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
Packit 6c4009
		   == 0)
Packit 6c4009
	    /* Not only is this the end of the options, but it's a
Packit 6c4009
	       `quoted' region, which may have args that *look* like
Packit 6c4009
	       options, so we definitely shouldn't try to use getopt past
Packit 6c4009
	       here, whatever happens.  */
Packit 6c4009
	    parser->state.quoted = parser->state.next;
Packit 6c4009
	}
Packit 6c4009
      else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
Packit 6c4009
	/* KEY_ERR can have the same value as a valid user short
Packit 6c4009
	   option, but in the case of a real error, getopt sets OPTOPT
Packit 6c4009
	   to the offending character, which can never be KEY_END.  */
Packit 6c4009
	{
Packit 6c4009
	  *arg_ebadkey = 0;
Packit 6c4009
	  return EBADKEY;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    opt = KEY_END;
Packit 6c4009
Packit 6c4009
  if (opt == KEY_END)
Packit 6c4009
    {
Packit 6c4009
      /* We're past what getopt considers the options.  */
Packit 6c4009
      if (parser->state.next >= parser->state.argc
Packit 6c4009
	  || (parser->state.flags & ARGP_NO_ARGS))
Packit 6c4009
	/* Indicate that we're done.  */
Packit 6c4009
	{
Packit 6c4009
	  *arg_ebadkey = 1;
Packit 6c4009
	  return EBADKEY;
Packit 6c4009
	}
Packit 6c4009
      else
Packit 6c4009
	/* A non-option arg; simulate what getopt might have done.  */
Packit 6c4009
	{
Packit 6c4009
	  opt = KEY_ARG;
Packit 6c4009
	  parser->opt_data.optarg = parser->state.argv[parser->state.next++];
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (opt == KEY_ARG)
Packit 6c4009
    /* A non-option argument; try each parser in turn.  */
Packit 6c4009
    err = parser_parse_arg (parser, parser->opt_data.optarg);
Packit 6c4009
  else
Packit 6c4009
    err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
Packit 6c4009
Packit 6c4009
  if (err == EBADKEY)
Packit 6c4009
    *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
Packit 6c4009
Packit 6c4009
  return err;
Packit 6c4009
}
Packit 6c4009

Packit 6c4009
/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
Packit 6c4009
   FLAGS is one of the ARGP_ flags above.  If END_INDEX is non-NULL, the
Packit 6c4009
   index in ARGV of the first unparsed option is returned in it.  If an
Packit 6c4009
   unknown option is present, EINVAL is returned; if some parser routine
Packit 6c4009
   returned a non-zero value, it is returned; otherwise 0 is returned.  */
Packit 6c4009
error_t
Packit 6c4009
__argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
Packit 6c4009
	      int *end_index, void *input)
Packit 6c4009
{
Packit 6c4009
  error_t err;
Packit 6c4009
  struct parser parser;
Packit 6c4009
Packit 6c4009
  /* If true, then err == EBADKEY is a result of a non-option argument failing
Packit 6c4009
     to be parsed (which in some cases isn't actually an error).  */
Packit 6c4009
  int arg_ebadkey = 0;
Packit 6c4009
Packit 6c4009
  if (! (flags & ARGP_NO_HELP))
Packit 6c4009
    /* Add our own options.  */
Packit 6c4009
    {
Packit 6c4009
      struct argp_child *child = alloca (4 * sizeof (struct argp_child));
Packit 6c4009
      struct argp *top_argp = alloca (sizeof (struct argp));
Packit 6c4009
Packit 6c4009
      /* TOP_ARGP has no options, it just serves to group the user & default
Packit 6c4009
	 argps.  */
Packit 6c4009
      memset (top_argp, 0, sizeof (*top_argp));
Packit 6c4009
      top_argp->children = child;
Packit 6c4009
Packit 6c4009
      memset (child, 0, 4 * sizeof (struct argp_child));
Packit 6c4009
Packit 6c4009
      if (argp)
Packit 6c4009
	(child++)->argp = argp;
Packit 6c4009
      (child++)->argp = &argp_default_argp;
Packit 6c4009
      if (argp_program_version || argp_program_version_hook)
Packit 6c4009
	(child++)->argp = &argp_version_argp;
Packit 6c4009
      child->argp = 0;
Packit 6c4009
Packit 6c4009
      argp = top_argp;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Construct a parser for these arguments.  */
Packit 6c4009
  err = parser_init (&parser, argp, argc, argv, flags, input);
Packit 6c4009
Packit 6c4009
  if (! err)
Packit 6c4009
    /* Parse! */
Packit 6c4009
    {
Packit 6c4009
      while (! err)
Packit 6c4009
	err = parser_parse_next (&parser, &arg_ebadkey);
Packit 6c4009
      err = parser_finalize (&parser, err, arg_ebadkey, end_index);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return err;
Packit 6c4009
}
Packit 6c4009
#ifdef weak_alias
Packit 6c4009
weak_alias (__argp_parse, argp_parse)
Packit 6c4009
#endif
Packit 6c4009

Packit 6c4009
/* Return the input field for ARGP in the parser corresponding to STATE; used
Packit 6c4009
   by the help routines.  */
Packit 6c4009
void *
Packit 6c4009
__argp_input (const struct argp *argp, const struct argp_state *state)
Packit 6c4009
{
Packit 6c4009
  if (state)
Packit 6c4009
    {
Packit 6c4009
      struct group *group;
Packit 6c4009
      struct parser *parser = state->pstate;
Packit 6c4009
Packit 6c4009
      for (group = parser->groups; group < parser->egroup; group++)
Packit 6c4009
	if (group->argp == argp)
Packit 6c4009
	  return group->input;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  return 0;
Packit 6c4009
}
Packit 6c4009
#ifdef weak_alias
Packit 6c4009
weak_alias (__argp_input, _argp_input)
Packit 6c4009
#endif