Esempio n. 1
0
static void
convert_options(const struct config_parser *parser,
		struct group *parent, unsigned parent_index,
		struct group **next_group,
		void ***next_input_slot)
{
  const struct config_parser **children = parser->children;
  struct group *group = (*next_group)++;

  group->parser = parser;
  group->parent = parent;
  group->parent_index = parent_index;

  if (!children)
    group->state.child_inputs = NULL;    
  else
    {
      size_t num_children;
      size_t i;
      for (num_children = 0; children[num_children]; num_children++)
	;
      group->state.child_inputs = *next_input_slot;
      *next_input_slot += num_children;

      for (i = 0; i < num_children; i++)
	convert_options(children[i], group, i, next_group, next_input_slot);
    }  
}
Esempio n. 2
0
/* Initialize GROUP from ARGP. If CVT->SHORT_END is non-NULL, short
 * options are recorded in the short options string. Returns the 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)
{
  const struct argp_option *opt = argp->options;
  const struct argp_child *children = argp->children;

  if (opt || argp->parser) {
      /* This parser needs a group. */
      if (cvt->short_end) {
		  /* Record any short options. */
		  for (; !__option_is_end(opt); opt++) {
			  if (opt && __option_is_short(opt)) {
				  *cvt->short_end++ = (char)opt->key;
			  }
		  }
	  }

      group->parser = argp->parser;
      group->argp = argp;
      group->args_processed = 0;
      group->parent = parent;
      group->parent_index = parent_index;
      group->input = 0;
      group->hook = 0;
      group->child_inputs = 0;

      if (children)
	/* 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;
	}
      parent = group++;
  } else {
	  parent = 0;
  }

  if (children) {
      unsigned local_index = 0;
      while (children->argp) {
		  group = convert_options(children++->argp, parent, local_index++,
								  group, cvt);
	  }
  }

  return group;
}
Esempio n. 3
0
/* Allocate and initialize the group structures, so that they are
   ordered as if by traversing the corresponding argp parser tree in
   pre-order. Also build the list of short options, if that is needed. */
static void
parser_convert (struct parser *parser, const struct argp *argp)
{
  struct parser_convert_state cvt;

  cvt.parser = parser;
  cvt.short_end = parser->short_opts;
  cvt.child_inputs_end = parser->child_inputs;

  parser->argp = argp;

  if (argp)
    parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
  else
    parser->egroup = parser->groups; /* No parsers at all! */

  if (parser->short_opts)
    *cvt.short_end ='\0';
}
Esempio n. 4
0
static int
parser_init(struct parser_state *state,
	    const struct config_parser *parser,
	    void *input)
{
  struct parser_sizes szs;
  size_t group_alloc;
  size_t input_alloc;
  void **next_input_slot;
  struct group *group;
  
  /* Allocate and initialize group structures */
  init_sizes(&szs);
  calc_sizes(parser, &szs);

  group_alloc = sizeof(*state->groups) * szs.num_groups;
  input_alloc = sizeof(*state->child_inputs) * szs.num_child_inputs;
  state->storage = malloc(group_alloc + input_alloc);

  if (!state->storage)
    return ENOMEM;

  state->groups = state->storage;
  state->egroup = state->groups + szs.num_groups;

  if (szs.num_child_inputs > 0)
    {
      state->child_inputs = (void *) ((char *) state->storage + group_alloc);
      memset(state->child_inputs, 0, input_alloc);
    }
  else
    state->child_inputs = NULL;

  group = state->groups;
  next_input_slot = state->child_inputs;

  convert_options(parser, NULL, 0, &group, &next_input_slot);

  assert(group == state->egroup);
  assert(next_input_slot == state->child_inputs + szs.num_child_inputs);

  /* Call with CONFIG_KEY_INIT, for propagation of child inputs */
  state->groups[0].state.input = input;

  for (group = state->groups; group < state->egroup; group++)
    {
      int err;
      
      if (group->parent)
	group->state.input = group->parent->state.child_inputs[group->parent_index];

      err = group->parser->handler(CONFIG_PARSE_KEY_INIT, 0, NULL, &group->state);
      if (err && err != EINVAL)
	{
	  /* Abort initialization */
	  free(state->storage);
	  state->storage = NULL;
	  return err;
	}
    }

  return 0;
}