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

📄 argp-help.c

📁 机器学习作者tom mitchell的书上代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	   /* Put CHILD->argp within its own cluster.  */	   ? hol_add_cluster (hol, child->group, child->header,			      child - argp->children, cluster, argp)	   /* Just merge it into the parent's cluster.  */	   : cluster);	hol_append (hol, argp_hol (child->argp, child_cluster)) ;	child++;      }  return hol;}/* Calculate how many different levels with alternative args strings exist in   ARGP.  */static size_targp_args_levels (const struct argp *argp){  size_t levels = 0;  const struct argp_child *child = argp->children;  if (argp->args_doc && strchr (argp->args_doc, '\n'))    levels++;  if (child)    while (child->argp)      levels += argp_args_levels ((child++)->argp);  return levels;}/* Print all the non-option args documented in ARGP to STREAM.  Any output is   preceded by a space.  LEVELS is a pointer to a byte vector the length   returned by argp_args_levels; it should be initialized to zero, and   updated by this routine for the next call if ADVANCE is true.  True is   returned as long as there are more patterns to output.  */static intargp_args_usage (const struct argp *argp, char **levels, int advance,		 argp_fmtstream_t stream){  char *our_level = *levels;  int multiple = 0;  const struct argp_child *child = argp->children;  const char *doc = gettext (argp->args_doc), *nl = 0;  if (doc)    {      nl = strchr (doc, '\n');      if (nl)	/* This is a `multi-level' args doc; advance to the correct position	   as determined by our state in LEVELS, and update LEVELS.  */	{	  int i;	  multiple = 1;	  for (i = 0; i < *our_level; i++)	    doc = nl + 1, nl = strchr (doc, '\n');	  (*levels)++;	}      if (! nl)	nl = doc + strlen (doc);      /* Manually do line wrapping so that it (probably) won't get wrapped at	 any embedded spaces.  */      space (stream, 1 + nl - doc);      __argp_fmtstream_write (stream, doc, nl - doc);    }  if (child)    while (child->argp)      advance = !argp_args_usage ((child++)->argp, levels, advance, stream);  if (advance && multiple)    /* Need to increment our level.  */    if (*nl)      /* There's more we can do here.  */      {	(*our_level)++;	advance = 0;		/* Our parent shouldn't advance also. */      }    else if (*our_level > 0)      /* We had multiple levels, but used them up; reset to zero.  */      *our_level = 0;  return !advance;}/* Print the documentation for ARGP to STREAM; if POST is false, then   everything preceeding a `\v' character in the documentation strings (or   the whole string, for those with none) is printed, otherwise, everything   following the `\v' character (nothing for strings without).  Each separate   bit of documentation is separated a blank line, and if PRE_BLANK is true,   then the first is as well.  If FIRST_ONLY is true, only the first   occurance is output.  Returns true if anything was output.  */static intargp_doc (const struct argp *argp, const struct argp_state *state,	  int post, int pre_blank, int first_only,	  argp_fmtstream_t stream){  const char *text;  const char *inp_text;  void *input = 0;  int anything = 0;  size_t inp_text_limit = 0;  const char *doc = gettext (argp->doc);  const struct argp_child *child = argp->children;  if (doc)    {      char *vt = strchr (doc, '\v');      inp_text = post ? (vt ? vt + 1 : 0) : doc;      inp_text_limit = (!post && vt) ? (vt - doc) : 0;    }  else    inp_text = 0;  if (argp->help_filter)    /* We have to filter the doc strings.  */    {      if (inp_text_limit)	/* Copy INP_TEXT so that it's nul-terminated.  */	inp_text = strndup (inp_text, inp_text_limit);      input = __argp_input (argp, state);      text =	(*argp->help_filter) (post			      ? ARGP_KEY_HELP_POST_DOC			      : ARGP_KEY_HELP_PRE_DOC,			      inp_text, input);    }  else    text = (const char *) inp_text;  if (text)    {      if (pre_blank)	__argp_fmtstream_putc (stream, '\n');      if (text == inp_text && inp_text_limit)	__argp_fmtstream_write (stream, inp_text, inp_text_limit);      else	__argp_fmtstream_puts (stream, text);      if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))	__argp_fmtstream_putc (stream, '\n');      anything = 1;    }  if (text && text != inp_text)    free ((char *) text);	/* Free TEXT returned from the help filter.  */  if (inp_text && inp_text_limit && argp->help_filter)    free ((char *) inp_text);	/* We copied INP_TEXT, so free it now.  */  if (post && argp->help_filter)    /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text.  */    {      text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);      if (text)	{	  if (anything || pre_blank)	    __argp_fmtstream_putc (stream, '\n');	  __argp_fmtstream_puts (stream, text);	  free ((char *) text);	  if (__argp_fmtstream_point (stream)	      > __argp_fmtstream_lmargin (stream))	    __argp_fmtstream_putc (stream, '\n');	  anything = 1;	}    }  if (child)    while (child->argp && !(first_only && anything))      anything |=	argp_doc ((child++)->argp, state,		  post, anything || pre_blank, first_only,		  stream);  return anything;}/* Output a usage message for ARGP to STREAM.  If called from   argp_state_help, STATE is the relevent parsing state.  FLAGS are from the   set ARGP_HELP_*.  NAME is what to use wherever a `program name' is   needed. */static void_help (const struct argp *argp, const struct argp_state *state, FILE *stream,       unsigned flags, char *name){  int anything = 0;		/* Whether we've output anything.  */  struct hol *hol = 0;  argp_fmtstream_t fs;  if (! stream)    return;  if (! uparams.valid)    fill_in_uparams (state);  fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);  if (! fs)    return;  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))    {      hol = argp_hol (argp, 0);      /* If present, these options always come last.  */      hol_set_group (hol, "help", -1);      hol_set_group (hol, "version", -1);      hol_sort (hol);    }  if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))    /* Print a short `Usage:' message.  */    {      int first_pattern = 1, more_patterns;      size_t num_pattern_levels = argp_args_levels (argp);      char *pattern_levels = alloca (num_pattern_levels);      memset (pattern_levels, 0, num_pattern_levels);      do	{	  int old_lm;	  int old_wm = __argp_fmtstream_set_wmargin (fs, USAGE_INDENT);	  char *levels = pattern_levels;	  __argp_fmtstream_printf (fs, "%s %s",				   _(first_pattern ? "Usage:" : "  or: "),				   name);	  /* We set the lmargin as well as the wmargin, because hol_usage	     manually wraps options with newline to avoid annoying breaks.  */	  old_lm = __argp_fmtstream_set_lmargin (fs, USAGE_INDENT);	  if (flags & ARGP_HELP_SHORT_USAGE)	    /* Just show where the options go.  */	    {	      if (hol->num_entries > 0)		__argp_fmtstream_puts (fs, _(" [OPTION...]"));	    }	  else	    /* Actually print the options.  */	    {	      hol_usage (hol, fs);	      flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */	    }	  more_patterns = argp_args_usage (argp, &levels, 1, fs);	  __argp_fmtstream_set_wmargin (fs, old_wm);	  __argp_fmtstream_set_lmargin (fs, old_lm);	  __argp_fmtstream_putc (fs, '\n');	  anything = 1;	  first_pattern = 0;	}      while (more_patterns);    }  if (flags & ARGP_HELP_PRE_DOC)    anything |= argp_doc (argp, state, 0, 0, 1, fs);  if (flags & ARGP_HELP_SEE)    {      __argp_fmtstream_printf (fs, _("\Try `%s --help' or `%s --usage' for more information.\n"),					    name, name);      anything = 1;    }  if (flags & ARGP_HELP_LONG)    /* Print a long, detailed help message.  */    {      /* Print info about all the options.  */      if (hol->num_entries > 0)	{	  if (anything)	    __argp_fmtstream_putc (fs, '\n');	  hol_help (hol, state, fs);	  anything = 1;	}    }  if (flags & ARGP_HELP_POST_DOC)    /* Print any documentation strings at the end.  */    anything |= argp_doc (argp, state, 1, anything, 0, fs);  if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)    {      if (anything)	__argp_fmtstream_putc (fs, '\n');      __argp_fmtstream_printf (fs, _("Report bugs to %s.\n"),			       argp_program_bug_address);      anything = 1;    }  if (hol)    hol_free (hol);  __argp_fmtstream_free (fs);}/* Output a usage message for ARGP to STREAM.  FLAGS are from the set   ARGP_HELP_*.  NAME is what to use wherever a `program name' is needed. */void __argp_help (const struct argp *argp, FILE *stream,		  unsigned flags, char *name){  _help (argp, 0, stream, flags, name);}#ifdef weak_aliasweak_alias (__argp_help, argp_help)#endif/* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are   from the set ARGP_HELP_*.  */void__argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags){  if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)    {      if (state && (state->flags & ARGP_LONG_ONLY))	flags |= ARGP_HELP_LONG_ONLY;      _help (state ? state->argp : 0, state, stream, flags,	     state ? state->name : program_invocation_short_name);      if (!state || ! (state->flags & ARGP_NO_EXIT))	{	  if (flags & ARGP_HELP_EXIT_ERR)	    exit (1);	  if (flags & ARGP_HELP_EXIT_OK)	    exit (0);	}  }}#ifdef weak_aliasweak_alias (__argp_state_help, argp_state_help)#endif/* If appropriate, print the printf string FMT and following args, preceded   by the program name and `:', to stderr, and followed by a `Try ... --help'   message, then exit (1).  */void__argp_error (const struct argp_state *state, const char *fmt, ...){  if (!state || !(state->flags & ARGP_NO_ERRS))    {      FILE *stream = state ? state->err_stream : stderr;      if (stream)	{	  va_list ap;	  fputs (state ? state->name : program_invocation_short_name, stream);	  putc (':', stream);	  putc (' ', stream);	  va_start (ap, fmt);	  vfprintf (stream, fmt, ap);	  va_end (ap);	  putc ('\n', stream);	  __argp_state_help (state, stream, ARGP_HELP_STD_ERR);	}    }}#ifdef weak_aliasweak_alias (__argp_error, argp_error)#endif/* Similar to the standard gnu error-reporting function error(), but will   respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print   to STATE->err_stream.  This is useful for argument parsing code that is   shared between program startup (when exiting is desired) and runtime   option parsing (when typically an error code is returned instead).  The   difference between this function and argp_error is that the latter is for   *parsing errors*, and the former is for other problems that occur during   parsing but don't reflect a (syntactic) problem with the input.  */void__argp_failure (const struct argp_state *state, int status, int errnum,		const char *fmt, ...){  if (!state || !(state->flags & ARGP_NO_ERRS))    {      FILE *stream = state ? state->err_stream : stderr;      if (stream)	{	  fputs (state ? state->name : program_invocation_short_name, stream);	  if (fmt)	    {	      va_list ap;	      putc (':', stream);	      putc (' ', stream);	      va_start (ap, fmt);	      vfprintf (stream, fmt, ap);	      va_end (ap);	    }	  if (errnum)	    {	      putc (':', stream);	      putc (' ', stream);#if HAVE_STRERROR	      fputs (strerror (errnum), stream);#else	      fprintf (stream, "error %d\n", errnum);#endif	    }	  putc ('\n', stream);	  if (status && (!state || !(state->flags & ARGP_NO_EXIT)))	    exit (status);	}    }}#ifdef weak_aliasweak_alias (__argp_failure, argp_failure)#endif

⌨️ 快捷键说明

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