⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 argp-parse.c

📁 贝叶斯学习算法分类文本。基于朴素贝叶斯分类器的文本分类的通用算法
💻 C
📖 第 1 页 / 共 2 页
字号:
}/* 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.  */};/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by the maximum lengths of the resulting merged getopt short options string and long-options array, respectively.  */static voidcalc_sizes (const struct argp *argp,  struct parser_sizes *szs){  const struct argp_child *child = argp->children;  const struct argp_option *opt = argp->options;  if (opt || argp->parser)    {      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;	}    }  if (child)    while (child->argp)      {	calc_sizes ((child++)->argp, szs);	szs->num_child_inputs++;      }}/* Initializes PARSER to parse ARGP in a manner described by FLAGS.  */static error_tparser_init (struct parser *parser, const struct argp *argp,	     int argc, char **argv, int flags, void *input){  error_t err = 0;  struct group *group;  struct parser_sizes szs;  szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;  szs.long_len = 0;  szs.num_groups = 0;  szs.num_child_inputs = 0;  if (argp)    calc_sizes (argp, &szs);  /* Lengths of the various bits of storage used by PARSER.  */#define GLEN (szs.num_groups + 1) * sizeof (struct group)#define CLEN (szs.num_child_inputs * sizeof (void *))#define LLEN ((szs.long_len + 1) * sizeof (struct option))#define SLEN (szs.short_len + 1)  parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);  if (! parser->storage)    return ENOMEM;  parser->groups = parser->storage;  parser->child_inputs = parser->storage + GLEN;  parser->long_opts = parser->storage + GLEN + CLEN;  parser->short_opts = parser->storage + GLEN + CLEN + LLEN;  memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));  parser_convert (parser, argp, flags);  memset (&parser->state, 0, sizeof (struct argp_state));  parser->state.argp = parser->argp;  parser->state.argc = argc;  parser->state.argv = argv;  parser->state.flags = flags;  parser->state.err_stream = stderr;  parser->state.out_stream = stdout;  parser->state.next = 0;	/* Tell getopt to initialize.  */  parser->state.pstate = parser;  parser->try_getopt = 1;  /* Call each parser for the first time, giving it a chance to propagate     values to child parsers.  */  if (parser->groups < parser->egroup)    parser->groups->input = input;  for (group = parser->groups;       group < parser->egroup && (!err || err == EBADKEY);       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];      err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);    }  if (err == EBADKEY)    err = 0;			/* Some parser didn't understand.  */  if (err)    return err;  /* Getopt is (currently) non-reentrant.  */  LOCK_GETOPT;  if (parser->state.flags & ARGP_NO_ERRS)    {      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++;    }  else    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];    }  else    parser->state.name = program_invocation_short_name;  return 0;}/* Free any storage consumed by PARSER (but not PARSER itself).  */static error_tparser_finalize (struct parser *parser,		 error_t err, int arg_ebadkey, int *end_index){  struct group *group;  UNLOCK_GETOPT;  if (err == EBADKEY && arg_ebadkey)    /* Suppress errors generated by unparsed arguments.  */    err = 0;  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->groups;	     group < parser->egroup && (!err || err==EBADKEY);	     group++)	  err = group_parse (group, &parser->state, ARGP_KEY_END, 0);	if (err == EBADKEY)	  err = 0;		/* Some parser didn't understand.  */      }    else if (end_index)      /* 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,		   _("%s: Too many arguments\n"), parser->state.name);	err = EBADKEY;      }  /* Okay, we're all done, with either an error or success.  We only call the     parsers once more, to indicate which one.  */  if (err)    {      /* 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);      /* 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);    }  else    /* Do final cleanup, including propagating 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.  */      for (group = parser->egroup - 1	   ; 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.  */    }  if (err == EBADKEY)    err = EINVAL;  free (parser->storage);  return err;}/* Call the user parsers to parse the non-option argument VAL, at the current   position, returning any error.  */static error_tparser_parse_arg (struct parser *parser, char *val){  int index = parser->state.next;  error_t err = EBADKEY;  struct group *group;  for (group = parser->groups       ; group < parser->egroup && err == EBADKEY       ; group++)    err = group_parse (group, &parser->state, ARGP_KEY_ARG, val);  if (!err)    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++;    else      /* The user wants to reparse some args, give getopt another try.  */      parser->try_getopt = 1;  return err;}/* Call the user parsers to parse the option OPT, with argument VAL, at the   current position, returning any error.  */static error_tparser_parse_opt (struct parser *parser, int opt, char *val){  /* The group key encoded in the high bits; 0 for short opts or     group_number + 1 for long opts.  */  int group_key = opt >> USER_BITS;  if (group_key == 0)    /* A short option.  By comparing OPT's position in SHORT_OPTS to the       various starting positions in each group's SHORT_END field, we can       determine which group OPT came from.  */    {      struct group *group;      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)	    return group_parse (group, &parser->state, opt, optarg);      return EBADKEY;		/* until otherwise asserted */    }  else    /* A long option.  We use shifts instead of masking for extracting       the user value in order to preserve the sign.  */    return      group_parse (&parser->groups[group_key - 1], &parser->state,		   (opt << GROUP_BITS) >> GROUP_BITS, optarg);}/* Parse the next argument in PARSER (as indicated by PARSER->state.next).   Any error from the parsers is returned, and *ARGP_EBADKEY indicates   whether a value of EBADKEY is due to an unrecognized argument (which is   generally not fatal).  */static error_tparser_parse_next (struct parser *parser, int *arg_ebadkey){  int opt;  error_t err = 0;  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       another chance.  If the user hasn't removed it, getopt will just       process it again.  */    parser->state.quoted = 0;  if (parser->try_getopt && !parser->state.quoted)    /* Give getopt a chance to parse this.  */    {      optind = parser->state.next; /* Put it back in OPTIND for getopt.  */      optopt = KEY_END;		/* Distinguish KEY_ERR from a real option.  */      if (parser->state.flags & ARGP_LONG_ONLY)	opt = getopt_long_only (parser->state.argc, parser->state.argv,				parser->short_opts, parser->long_opts, 0);      else	opt = getopt_long (parser->state.argc, parser->state.argv,			   parser->short_opts, parser->long_opts, 0);      parser->state.next = optind; /* And see what getopt did.  */      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;	}      else if (opt == KEY_ERR && 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;	}    }  else    opt = KEY_END;  if (opt == KEY_END)    /* 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;      }    else      /* A non-option arg.  */      err =	parser_parse_arg (parser, parser->state.argv[parser->state.next++]);  else if (opt == KEY_ARG)    /* A non-option argument; try each parser in turn.  */    err = parser_parse_arg (parser, optarg);  else    err = parser_parse_opt (parser, opt, optarg);  if (err == EBADKEY)    {      *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);      parser->state.next--;	/* Put back the unused argument.  */    }  return err;}/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.   FLAGS is one of the ARGP_ flags above.  If END_INDEX is non-NULL, the   index in ARGV of the first unparsed option is returned in it.  If an   unknown option is present, EINVAL is returned; if some parser routine   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){  error_t err;  struct parser parser;  /* If true, then err == EBADKEY is a result of a non-option argument failing     to be parsed (which in some cases isn't actually an error).  */  int arg_ebadkey = 0;#if !HAVE_PROGRAM_INVOCATION_NAME  /* Set the PROGRAM_INVOCATION_NAME and PROGRAM_INVOCATION_SHORT_NAME      if this system doesn't automatically do that. */  {    char *s;    program_invocation_name = argv[0];    s = strrchr (program_invocation_name, '/');    if (s)      program_invocation_short_name = s + 1;    else      program_invocation_short_name = program_invocation_name;  }#endif  if (! (flags & ARGP_NO_HELP))    /* Add our own options.  */    {      struct argp_child *child = alloca (4 * sizeof (struct argp_child));      struct argp *top_argp = alloca (sizeof (struct argp));      /* TOP_ARGP has no options, it just serves to group the user & default	 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_default_argp;      if (argp_program_version || argp_program_version_hook)	(child++)->argp = &argp_version_argp;      child->argp = 0;      argp = top_argp;    }  /* Construct a parser for these arguments.  */  err = parser_init (&parser, argp, argc, argv, flags, input);  if (! err)    /* Parse! */    {      while (! err)	err = parser_parse_next (&parser, &arg_ebadkey);      err = parser_finalize (&parser, err, arg_ebadkey, end_index);    }  return err;}#ifdef weak_aliasweak_alias (__argp_parse, argp_parse)#endif/* Return the input field for ARGP in the parser corresponding to STATE; used   by the help routines.  */void *__argp_input (const struct argp *argp, const struct argp_state *state){  if (state)    {      struct group *group;      struct parser *parser = state->pstate;      for (group = parser->groups; group < parser->egroup; group++)	if (group->argp == argp)	  return group->input;    }  return 0;}#ifdef weak_aliasweak_alias (__argp_input, _argp_input)#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -