1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Written by Miles Bader <miles@gnu.ai.mit.edu>.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation,
18 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 # define _GNU_SOURCE 1
44 # define dgettext(domain, msgid) \
45 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
51 #include "argp-fmtstream.h"
52 #include "argp-namefrob.h"
55 # define SIZE_MAX ((size_t) -1)
58 /* User-selectable (using an environment variable) formatting parameters.
60 These may be specified in an environment variable called `ARGP_HELP_FMT',
61 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
62 Where VALn must be a positive integer. The list of variables is in the
63 UPARAM_NAMES vector, below. */
65 /* Default parameters. */
66 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
67 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
68 #define SHORT_OPT_COL 2 /* column in which short options start */
69 #define LONG_OPT_COL 6 /* column in which long options start */
70 #define DOC_OPT_COL 2 /* column in which doc options start */
71 #define OPT_DOC_COL 29 /* column in which option text starts */
72 #define HEADER_COL 1 /* column in which group headers are printed */
73 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
74 #define RMARGIN 79 /* right margin used for wrapping */
76 /* User-selectable (using an environment variable) formatting parameters.
77 They must all be of type `int' for the parsing code to work. */
80 /* If true, arguments for an option are shown with both short and long
81 options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
82 If false, then if an option has both, the argument is only shown with
83 the long one, e.g., `-x, --longx=ARG', and a message indicating that
84 this really means both is printed below the options. */
87 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
88 been suppressed, an explanatory message should be printed. */
91 /* Various output columns. */
100 int valid; /* True when the values in here are valid. */
103 /* This is a global variable, as user options are only ever read once. */
104 static struct uparams uparams = {
105 DUP_ARGS, DUP_ARGS_NOTE,
106 SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
107 USAGE_INDENT, RMARGIN,
111 /* A particular uparam, and what the user name is. */
114 const char *name; /* User name. */
115 int is_bool; /* Whether it's `boolean'. */
116 size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
119 /* The name-field mappings we know about. */
120 static const struct uparam_name uparam_names[] =
122 { "dup-args", 1, offsetof (struct uparams, dup_args) },
123 { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
124 { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
125 { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
126 { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
127 { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
128 { "header-col", 0, offsetof (struct uparams, header_col) },
129 { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
130 { "rmargin", 0, offsetof (struct uparams, rmargin) },
134 /* Read user options from the environment, and fill in UPARAMS appropiately. */
136 fill_in_uparams (const struct argp_state *state)
138 const char *var = getenv ("ARGP_HELP_FMT");
140 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
151 const struct uparam_name *un;
152 int unspec = 0, val = 0;
153 const char *arg = var;
155 while (isalnum (*arg) || *arg == '-' || *arg == '_')
161 if (*arg == '\0' || *arg == ',')
163 else if (*arg == '=')
171 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
180 else if (isdigit (*arg))
183 while (isdigit (*arg))
188 for (un = uparam_names; un->name; un++)
189 if (strlen (un->name) == var_len
190 && strncmp (var, un->name, var_len) == 0)
192 if (unspec && !un->is_bool)
193 __argp_failure (state, 0, 0,
194 dgettext (state->root_argp->argp_domain, "\
195 %.*s: ARGP_HELP_FMT parameter requires a value"),
198 *(int *)((char *)&uparams + un->uparams_offs) = val;
202 __argp_failure (state, 0, 0,
203 dgettext (state->root_argp->argp_domain, "\
204 %.*s: Unknown ARGP_HELP_FMT parameter"),
213 __argp_failure (state, 0, 0,
214 dgettext (state->root_argp->argp_domain,
215 "Garbage in ARGP_HELP_FMT: %s"), var);
221 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
222 whether OPT is displayed or used in sorting, not option shadowing. */
223 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
225 /* Returns true if OPT is an alias for an earlier option. */
226 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
228 /* Returns true if OPT is an documentation-only entry. */
229 #define odoc(opt) ((opt)->flags & OPTION_DOC)
231 /* Returns true if OPT is the end-of-list marker for a list of options. */
232 #define oend(opt) __option_is_end (opt)
234 /* Returns true if OPT has a short option. */
235 #define oshort(opt) __option_is_short (opt)
238 The help format for a particular option is like:
240 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
242 Where ARG will be omitted if there's no argument, for this option, or
243 will be surrounded by "[" and "]" appropiately if the argument is
244 optional. The documentation string is word-wrapped appropiately, and if
245 the list of options is long enough, it will be started on a separate line.
246 If there are no short options for a given option, the first long option is
247 indented slighly in a way that's supposed to make most long options appear
248 to be in a separate column.
250 For example, the following output (from ps):
252 -p PID, --pid=PID List the process PID
253 --pgrp=PGRP List processes in the process group PGRP
254 -P, -x, --no-parent Include processes without parents
255 -Q, --all-fields Don't elide unusable fields (normally if there's
256 some reason ps can't print a field for any
257 process, it's removed from the output entirely)
258 -r, --reverse, --gratuitously-long-reverse-option
259 Reverse the order of any sort
260 --session[=SID] Add the processes from the session SID (which
261 defaults to the sid of the current process)
263 Here are some more options:
264 -f ZOT, --foonly=ZOT Glork a foonly
265 -z, --zaza Snit a zar
267 -?, --help Give this help list
268 --usage Give a short usage message
269 -V, --version Print program version
271 The struct argp_option array for the above could look like:
274 {"pid", 'p', "PID", 0, "List the process PID"},
275 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
276 {"no-parent", 'P', 0, 0, "Include processes without parents"},
277 {0, 'x', 0, OPTION_ALIAS},
278 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
279 " if there's some reason ps can't"
280 " print a field for any process, it's"
281 " removed from the output entirely)" },
282 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
283 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
284 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
285 "Add the processes from the session"
286 " SID (which defaults to the sid of"
287 " the current process)" },
289 {0,0,0,0, "Here are some more options:"},
290 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
291 {"zaza", 'z', 0, 0, "Snit a zar"},
296 Note that the last three options are automatically supplied by argp_parse,
297 unless you tell it not to with ARGP_NO_HELP.
301 /* Returns true if CH occurs between BEG and END. */
303 find_char (char ch, char *beg, char *end)
313 struct hol_cluster; /* fwd decl */
318 const struct argp_option *opt;
319 /* Number of options (including aliases). */
322 /* A pointers into the HOL's short_options field, to the first short option
323 letter for this entry. The order of the characters following this point
324 corresponds to the order of options pointed to by OPT, and there are at
325 most NUM. A short option recorded in a option following OPT is only
326 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
327 probably been shadowed by some other entry). */
330 /* Entries are sorted by their group first, in the order:
331 1, 2, ..., n, 0, -m, ..., -2, -1
332 and then alphabetically within each group. The default is 0. */
335 /* The cluster of options this entry belongs to, or 0 if none. */
336 struct hol_cluster *cluster;
338 /* The argp from which this option came. */
339 const struct argp *argp;
342 /* A cluster of entries to reflect the argp tree structure. */
345 /* A descriptive header printed before options in this cluster. */
348 /* Used to order clusters within the same group with the same parent,
349 according to the order in which they occurred in the parent argp's child
353 /* How to sort this cluster with respect to options and other clusters at the
354 same depth (clusters always follow options in the same group). */
357 /* The cluster to which this cluster belongs, or 0 if it's at the base
359 struct hol_cluster *parent;
361 /* The argp from which this cluster is (eventually) derived. */
362 const struct argp *argp;
364 /* The distance this cluster is from the root. */
367 /* Clusters in a given hol are kept in a linked list, to make freeing them
369 struct hol_cluster *next;
372 /* A list of options for help. */
375 /* An array of hol_entry's. */
376 struct hol_entry *entries;
377 /* The number of entries in this hol. If this field is zero, the others
379 unsigned num_entries;
381 /* A string containing all short options in this HOL. Each entry contains
382 pointers into this string, so the order can't be messed with blindly. */
385 /* Clusters of entries in this hol. */
386 struct hol_cluster *clusters;
389 /* Create a struct hol from the options in ARGP. CLUSTER is the
390 hol_cluster in which these entries occur, or 0, if at the root. */
392 make_hol (const struct argp *argp, struct hol_cluster *cluster)
395 const struct argp_option *o;
396 const struct argp_option *opts = argp->options;
397 struct hol_entry *entry;
398 unsigned num_short_options = 0;
399 struct hol *hol = malloc (sizeof (struct hol));
403 hol->num_entries = 0;
410 /* The first option must not be an alias. */
411 assert (! oalias (opts));
413 /* Calculate the space needed. */
414 for (o = opts; ! oend (o); o++)
419 num_short_options++; /* This is an upper bound. */
422 hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
423 hol->short_options = malloc (num_short_options + 1);
425 assert (hol->entries && hol->short_options);
426 if (SIZE_MAX <= UINT_MAX)
427 assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
429 /* Fill in the entries. */
430 so = hol->short_options;
431 for (o = opts, entry = hol->entries; ! oend (o); entry++)
435 entry->short_options = so;
436 entry->group = cur_group =
439 : ((!o->name && !o->key)
442 entry->cluster = cluster;
448 if (oshort (o) && ! find_char (o->key, hol->short_options, so))
449 /* O has a valid short option which hasn't already been used.*/
453 while (! oend (o) && oalias (o));
455 *so = '\0'; /* null terminated so we can find the length */
461 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
462 associated argp child list entry), INDEX, and PARENT, and return a pointer
463 to it. ARGP is the argp that this cluster results from. */
464 static struct hol_cluster *
465 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
466 struct hol_cluster *parent, const struct argp *argp)
468 struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
477 cl->depth = parent ? parent->depth + 1 : 0;
479 cl->next = hol->clusters;
485 /* Free HOL and any resources it uses. */
487 hol_free (struct hol *hol)
489 struct hol_cluster *cl = hol->clusters;
493 struct hol_cluster *next = cl->next;
498 if (hol->num_entries > 0)
501 free (hol->short_options);
508 hol_entry_short_iterate (const struct hol_entry *entry,
509 int (*func)(const struct argp_option *opt,
510 const struct argp_option *real,
511 const char *domain, void *cookie),
512 const char *domain, void *cookie)
516 const struct argp_option *opt, *real = entry->opt;
517 char *so = entry->short_options;
519 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
520 if (oshort (opt) && *so == opt->key)
525 val = (*func)(opt, real, domain, cookie);
533 __attribute__ ((always_inline))
534 hol_entry_long_iterate (const struct hol_entry *entry,
535 int (*func)(const struct argp_option *opt,
536 const struct argp_option *real,
537 const char *domain, void *cookie),
538 const char *domain, void *cookie)
542 const struct argp_option *opt, *real = entry->opt;
544 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
550 val = (*func)(opt, real, domain, cookie);
556 /* Iterator that returns true for the first short option. */
558 until_short (const struct argp_option *opt, const struct argp_option *real,
559 const char *domain, void *cookie)
561 return oshort (opt) ? opt->key : 0;
564 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
566 hol_entry_first_short (const struct hol_entry *entry)
568 return hol_entry_short_iterate (entry, until_short,
569 entry->argp->argp_domain, 0);
572 /* Returns the first valid long option in ENTRY, or 0 if there is none. */
574 hol_entry_first_long (const struct hol_entry *entry)
576 const struct argp_option *opt;
578 for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
579 if (opt->name && ovisible (opt))
584 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
586 static struct hol_entry *
587 hol_find_entry (struct hol *hol, const char *name)
589 struct hol_entry *entry = hol->entries;
590 unsigned num_entries = hol->num_entries;
592 while (num_entries-- > 0)
594 const struct argp_option *opt = entry->opt;
595 unsigned num_opts = entry->num;
597 while (num_opts-- > 0)
598 if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
609 /* If an entry with the long option NAME occurs in HOL, set it's special
610 sort position to GROUP. */
612 hol_set_group (struct hol *hol, const char *name, int group)
614 struct hol_entry *entry = hol_find_entry (hol, name);
616 entry->group = group;
619 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
620 EQ is what to return if GROUP1 and GROUP2 are the same. */
622 group_cmp (int group1, int group2, int eq)
624 if (group1 == group2)
626 else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
627 return group1 - group2;
629 return group2 - group1;
632 /* Compare clusters CL1 & CL2 by the order that they should appear in
635 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
637 /* If one cluster is deeper than the other, use its ancestor at the same
638 level, so that finding the common ancestor is straightforward. */
639 while (cl1->depth < cl2->depth)
641 while (cl2->depth < cl1->depth)
644 /* Now reduce both clusters to their ancestors at the point where both have
645 a common parent; these can be directly compared. */
646 while (cl1->parent != cl2->parent)
647 cl1 = cl1->parent, cl2 = cl2->parent;
649 return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
652 /* Return the ancestor of CL that's just below the root (i.e., has a parent
654 static struct hol_cluster *
655 hol_cluster_base (struct hol_cluster *cl)
662 /* Return true if CL1 is a child of CL2. */
664 hol_cluster_is_child (const struct hol_cluster *cl1,
665 const struct hol_cluster *cl2)
667 while (cl1 && cl1 != cl2)
672 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
673 that should be used for comparisons, and returns true iff it should be
674 treated as a non-option. */
676 canon_doc_option (const char **name)
679 /* Skip initial whitespace. */
680 while (isspace (**name))
682 /* Decide whether this looks like an option (leading `-') or not. */
683 non_opt = (**name != '-');
684 /* Skip until part of name used for sorting. */
685 while (**name && !isalnum (**name))
690 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
693 hol_entry_cmp (const struct hol_entry *entry1,
694 const struct hol_entry *entry2)
696 /* The group numbers by which the entries should be ordered; if either is
697 in a cluster, then this is just the group within the cluster. */
698 int group1 = entry1->group, group2 = entry2->group;
700 if (entry1->cluster != entry2->cluster)
702 /* The entries are not within the same cluster, so we can't compare them
703 directly, we have to use the appropiate clustering level too. */
704 if (! entry1->cluster)
705 /* ENTRY1 is at the `base level', not in a cluster, so we have to
706 compare it's group number with that of the base cluster in which
707 ENTRY2 resides. Note that if they're in the same group, the
708 clustered option always comes laster. */
709 return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
710 else if (! entry2->cluster)
711 /* Likewise, but ENTRY2's not in a cluster. */
712 return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
714 /* Both entries are in clusters, we can just compare the clusters. */
715 return hol_cluster_cmp (entry1->cluster, entry2->cluster);
717 else if (group1 == group2)
718 /* The entries are both in the same cluster and group, so compare them
721 int short1 = hol_entry_first_short (entry1);
722 int short2 = hol_entry_first_short (entry2);
723 int doc1 = odoc (entry1->opt);
724 int doc2 = odoc (entry2->opt);
725 const char *long1 = hol_entry_first_long (entry1);
726 const char *long2 = hol_entry_first_long (entry2);
729 doc1 = canon_doc_option (&long1);
731 doc2 = canon_doc_option (&long2);
734 /* `documentation' options always follow normal options (or
735 documentation options that *look* like normal options). */
737 else if (!short1 && !short2 && long1 && long2)
738 /* Only long options. */
739 return __strcasecmp (long1, long2);
741 /* Compare short/short, long/short, short/long, using the first
742 character of long options. Entries without *any* valid
743 options (such as options with OPTION_HIDDEN set) will be put
744 first, but as they're not displayed, it doesn't matter where
747 char first1 = short1 ? short1 : long1 ? *long1 : 0;
748 char first2 = short2 ? short2 : long2 ? *long2 : 0;
750 int lower_cmp = _tolower (first1) - _tolower (first2);
752 int lower_cmp = tolower (first1) - tolower (first2);
754 /* Compare ignoring case, except when the options are both the
755 same letter, in which case lower-case always comes first. */
756 return lower_cmp ? lower_cmp : first2 - first1;
760 /* Within the same cluster, but not the same group, so just compare
762 return group_cmp (group1, group2, 0);
765 /* Version of hol_entry_cmp with correct signature for qsort. */
767 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
769 return hol_entry_cmp (entry1_v, entry2_v);
772 /* Sort HOL by group and alphabetically by option name (with short options
773 taking precedence over long). Since the sorting is for display purposes
774 only, the shadowing of options isn't effected. */
776 hol_sort (struct hol *hol)
778 if (hol->num_entries > 0)
779 qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
783 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
784 any in MORE with the same name. */
786 hol_append (struct hol *hol, struct hol *more)
788 struct hol_cluster **cl_end = &hol->clusters;
790 /* Steal MORE's cluster list, and add it to the end of HOL's. */
792 cl_end = &(*cl_end)->next;
793 *cl_end = more->clusters;
797 if (more->num_entries > 0)
799 if (hol->num_entries == 0)
801 hol->num_entries = more->num_entries;
802 hol->entries = more->entries;
803 hol->short_options = more->short_options;
804 more->num_entries = 0; /* Mark MORE's fields as invalid. */
807 /* Append the entries in MORE to those in HOL, taking care to only add
808 non-shadowed SHORT_OPTIONS values. */
813 unsigned num_entries = hol->num_entries + more->num_entries;
814 struct hol_entry *entries =
815 malloc (num_entries * sizeof (struct hol_entry));
816 unsigned hol_so_len = strlen (hol->short_options);
817 char *short_options =
818 malloc (hol_so_len + strlen (more->short_options) + 1);
820 assert (entries && short_options);
821 if (SIZE_MAX <= UINT_MAX)
822 assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
824 __mempcpy (__mempcpy (entries, hol->entries,
825 hol->num_entries * sizeof (struct hol_entry)),
827 more->num_entries * sizeof (struct hol_entry));
829 __mempcpy (short_options, hol->short_options, hol_so_len);
831 /* Fix up the short options pointers from HOL. */
832 for (e = entries, left = hol->num_entries; left > 0; e++, left--)
833 e->short_options += (short_options - hol->short_options);
835 /* Now add the short options from MORE, fixing up its entries
837 so = short_options + hol_so_len;
838 more_so = more->short_options;
839 for (left = more->num_entries; left > 0; e++, left--)
842 const struct argp_option *opt;
844 e->short_options = so;
846 for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
849 if (oshort (opt) && ch == opt->key)
850 /* The next short option in MORE_SO, CH, is from OPT. */
852 if (! find_char (ch, short_options,
853 short_options + hol_so_len))
854 /* The short option CH isn't shadowed by HOL's options,
855 so add it to the sum. */
865 free (hol->short_options);
867 hol->entries = entries;
868 hol->num_entries = num_entries;
869 hol->short_options = short_options;
876 /* Inserts enough spaces to make sure STREAM is at column COL. */
878 indent_to (argp_fmtstream_t stream, unsigned col)
880 int needed = col - __argp_fmtstream_point (stream);
882 __argp_fmtstream_putc (stream, ' ');
885 /* Output to STREAM either a space, or a newline if there isn't room for at
886 least ENSURE characters before the right margin. */
888 space (argp_fmtstream_t stream, size_t ensure)
890 if (__argp_fmtstream_point (stream) + ensure
891 >= __argp_fmtstream_rmargin (stream))
892 __argp_fmtstream_putc (stream, '\n');
894 __argp_fmtstream_putc (stream, ' ');
897 /* If the option REAL has an argument, we print it in using the printf
898 format REQ_FMT or OPT_FMT depending on whether it's a required or
899 optional argument. */
901 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
902 const char *domain, argp_fmtstream_t stream)
906 if (real->flags & OPTION_ARG_OPTIONAL)
907 __argp_fmtstream_printf (stream, opt_fmt,
908 dgettext (domain, real->arg));
910 __argp_fmtstream_printf (stream, req_fmt,
911 dgettext (domain, real->arg));
915 /* Helper functions for hol_entry_help. */
917 /* State used during the execution of hol_help. */
918 struct hol_help_state
920 /* PREV_ENTRY should contain the previous entry printed, or 0. */
921 struct hol_entry *prev_entry;
923 /* If an entry is in a different group from the previous one, and SEP_GROUPS
924 is true, then a blank line will be printed before any output. */
927 /* True if a duplicate option argument was suppressed (only ever set if
928 UPARAMS.dup_args is false). */
929 int suppressed_dup_arg;
932 /* Some state used while printing a help entry (used to communicate with
933 helper functions). See the doc for hol_entry_help for more info, as most
934 of the fields are copied from its arguments. */
937 const struct hol_entry *entry;
938 argp_fmtstream_t stream;
939 struct hol_help_state *hhstate;
941 /* True if nothing's been printed so far. */
944 /* If non-zero, the state that was used to print this help. */
945 const struct argp_state *state;
948 /* If a user doc filter should be applied to DOC, do so. */
950 filter_doc (const char *doc, int key, const struct argp *argp,
951 const struct argp_state *state)
953 if (argp->help_filter)
954 /* We must apply a user filter to this output. */
956 void *input = __argp_input (argp, state);
957 return (*argp->help_filter) (key, doc, input);
964 /* Prints STR as a header line, with the margin lines set appropiately, and
965 notes the fact that groups should be separated with a blank line. ARGP is
966 the argp that should dictate any user doc filtering to take place. Note
967 that the previous wrap margin isn't restored, but the left margin is reset
970 print_header (const char *str, const struct argp *argp,
971 struct pentry_state *pest)
973 const char *tstr = dgettext (argp->argp_domain, str);
974 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
980 if (pest->hhstate->prev_entry)
981 /* Precede with a blank line. */
982 __argp_fmtstream_putc (pest->stream, '\n');
983 indent_to (pest->stream, uparams.header_col);
984 __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
985 __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
986 __argp_fmtstream_puts (pest->stream, fstr);
987 __argp_fmtstream_set_lmargin (pest->stream, 0);
988 __argp_fmtstream_putc (pest->stream, '\n');
991 pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
995 free ((char *) fstr);
998 /* Inserts a comma if this isn't the first item on the line, and then makes
999 sure we're at least to column COL. If this *is* the first item on a line,
1000 prints any pending whitespace/headers that should precede this line. Also
1003 comma (unsigned col, struct pentry_state *pest)
1007 const struct hol_entry *pe = pest->hhstate->prev_entry;
1008 const struct hol_cluster *cl = pest->entry->cluster;
1010 if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1011 __argp_fmtstream_putc (pest->stream, '\n');
1013 if (cl && cl->header && *cl->header
1015 || (pe->cluster != cl
1016 && !hol_cluster_is_child (pe->cluster, cl))))
1017 /* If we're changing clusters, then this must be the start of the
1018 ENTRY's cluster unless that is an ancestor of the previous one
1019 (in which case we had just popped into a sub-cluster for a bit).
1020 If so, then print the cluster's header line. */
1022 int old_wm = __argp_fmtstream_wmargin (pest->stream);
1023 print_header (cl->header, cl->argp, pest);
1024 __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1030 __argp_fmtstream_puts (pest->stream, ", ");
1032 indent_to (pest->stream, col);
1035 /* Print help for ENTRY to STREAM. */
1037 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1038 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1041 const struct argp_option *real = entry->opt, *opt;
1042 char *so = entry->short_options;
1043 int have_long_opt = 0; /* We have any long options. */
1044 /* Saved margins. */
1045 int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1046 int old_wm = __argp_fmtstream_wmargin (stream);
1047 /* PEST is a state block holding some of our variables that we'd like to
1048 share with helper functions. */
1049 struct pentry_state pest = { entry, stream, hhstate, 1, state };
1052 for (opt = real, num = entry->num; num > 0; opt++, num--)
1053 if (opt->name && ovisible (opt))
1059 /* First emit short options. */
1060 __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1061 for (opt = real, num = entry->num; num > 0; opt++, num--)
1062 if (oshort (opt) && opt->key == *so)
1063 /* OPT has a valid (non shadowed) short option. */
1067 comma (uparams.short_opt_col, &pest);
1068 __argp_fmtstream_putc (stream, '-');
1069 __argp_fmtstream_putc (stream, *so);
1070 if (!have_long_opt || uparams.dup_args)
1071 arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
1073 hhstate->suppressed_dup_arg = 1;
1078 /* Now, long options. */
1080 /* A `documentation' option. */
1082 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1083 for (opt = real, num = entry->num; num > 0; opt++, num--)
1084 if (opt->name && ovisible (opt))
1086 comma (uparams.doc_opt_col, &pest);
1087 /* Calling gettext here isn't quite right, since sorting will
1088 have been done on the original; but documentation options
1089 should be pretty rare anyway... */
1090 __argp_fmtstream_puts (stream,
1091 dgettext (state->root_argp->argp_domain,
1096 /* A real long option. */
1098 int first_long_opt = 1;
1100 __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1101 for (opt = real, num = entry->num; num > 0; opt++, num--)
1102 if (opt->name && ovisible (opt))
1104 comma (uparams.long_opt_col, &pest);
1105 __argp_fmtstream_printf (stream, "--%s", opt->name);
1106 if (first_long_opt || uparams.dup_args)
1107 arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
1110 hhstate->suppressed_dup_arg = 1;
1114 /* Next, documentation strings. */
1115 __argp_fmtstream_set_lmargin (stream, 0);
1119 /* Didn't print any switches, what's up? */
1120 if (!oshort (real) && !real->name)
1121 /* This is a group header, print it nicely. */
1122 print_header (real->doc, entry->argp, &pest);
1124 /* Just a totally shadowed option or null header; print nothing. */
1125 goto cleanup; /* Just return, after cleaning up. */
1129 const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
1131 const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1134 unsigned int col = __argp_fmtstream_point (stream);
1136 __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1137 __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1139 if (col > (unsigned int) (uparams.opt_doc_col + 3))
1140 __argp_fmtstream_putc (stream, '\n');
1141 else if (col >= (unsigned int) uparams.opt_doc_col)
1142 __argp_fmtstream_puts (stream, " ");
1144 indent_to (stream, uparams.opt_doc_col);
1146 __argp_fmtstream_puts (stream, fstr);
1148 if (fstr && fstr != tstr)
1149 free ((char *) fstr);
1151 /* Reset the left margin. */
1152 __argp_fmtstream_set_lmargin (stream, 0);
1153 __argp_fmtstream_putc (stream, '\n');
1156 hhstate->prev_entry = entry;
1159 __argp_fmtstream_set_lmargin (stream, old_lm);
1160 __argp_fmtstream_set_wmargin (stream, old_wm);
1163 /* Output a long help message about the options in HOL to STREAM. */
1165 hol_help (struct hol *hol, const struct argp_state *state,
1166 argp_fmtstream_t stream)
1169 struct hol_entry *entry;
1170 struct hol_help_state hhstate = { 0, 0, 0 };
1172 for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1173 hol_entry_help (entry, state, stream, &hhstate);
1175 if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1177 const char *tstr = dgettext (state->root_argp->argp_domain, "\
1178 Mandatory or optional arguments to long options are also mandatory or \
1179 optional for any corresponding short options.");
1180 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1181 state ? state->root_argp : 0, state);
1184 __argp_fmtstream_putc (stream, '\n');
1185 __argp_fmtstream_puts (stream, fstr);
1186 __argp_fmtstream_putc (stream, '\n');
1188 if (fstr && fstr != tstr)
1189 free ((char *) fstr);
1193 /* Helper functions for hol_usage. */
1195 /* If OPT is a short option without an arg, append its key to the string
1196 pointer pointer to by COOKIE, and advance the pointer. */
1198 add_argless_short_opt (const struct argp_option *opt,
1199 const struct argp_option *real,
1200 const char *domain, void *cookie)
1202 char **snao_end = cookie;
1203 if (!(opt->arg || real->arg)
1204 && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1205 *(*snao_end)++ = opt->key;
1209 /* If OPT is a short option with an arg, output a usage entry for it to the
1210 stream pointed at by COOKIE. */
1212 usage_argful_short_opt (const struct argp_option *opt,
1213 const struct argp_option *real,
1214 const char *domain, void *cookie)
1216 argp_fmtstream_t stream = cookie;
1217 const char *arg = opt->arg;
1218 int flags = opt->flags | real->flags;
1223 if (arg && !(flags & OPTION_NO_USAGE))
1225 arg = dgettext (domain, arg);
1227 if (flags & OPTION_ARG_OPTIONAL)
1228 __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1231 /* Manually do line wrapping so that it (probably) won't
1232 get wrapped at the embedded space. */
1233 space (stream, 6 + strlen (arg));
1234 __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1241 /* Output a usage entry for the long option opt to the stream pointed at by
1244 usage_long_opt (const struct argp_option *opt,
1245 const struct argp_option *real,
1246 const char *domain, void *cookie)
1248 argp_fmtstream_t stream = cookie;
1249 const char *arg = opt->arg;
1250 int flags = opt->flags | real->flags;
1255 if (! (flags & OPTION_NO_USAGE))
1259 arg = dgettext (domain, arg);
1260 if (flags & OPTION_ARG_OPTIONAL)
1261 __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1263 __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1266 __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1272 /* Print a short usage description for the arguments in HOL to STREAM. */
1274 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1276 if (hol->num_entries > 0)
1279 struct hol_entry *entry;
1280 char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1281 char *snao_end = short_no_arg_opts;
1283 /* First we put a list of short options without arguments. */
1284 for (entry = hol->entries, nentries = hol->num_entries
1286 ; entry++, nentries--)
1287 hol_entry_short_iterate (entry, add_argless_short_opt,
1288 entry->argp->argp_domain, &snao_end);
1289 if (snao_end > short_no_arg_opts)
1292 __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1295 /* Now a list of short options *with* arguments. */
1296 for (entry = hol->entries, nentries = hol->num_entries
1298 ; entry++, nentries--)
1299 hol_entry_short_iterate (entry, usage_argful_short_opt,
1300 entry->argp->argp_domain, stream);
1302 /* Finally, a list of long options (whew!). */
1303 for (entry = hol->entries, nentries = hol->num_entries
1305 ; entry++, nentries--)
1306 hol_entry_long_iterate (entry, usage_long_opt,
1307 entry->argp->argp_domain, stream);
1311 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1312 cluster in which ARGP's entries should be clustered, or 0. */
1314 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1316 const struct argp_child *child = argp->children;
1317 struct hol *hol = make_hol (argp, cluster);
1321 struct hol_cluster *child_cluster =
1322 ((child->group || child->header)
1323 /* Put CHILD->argp within its own cluster. */
1324 ? hol_add_cluster (hol, child->group, child->header,
1325 child - argp->children, cluster, argp)
1326 /* Just merge it into the parent's cluster. */
1328 hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1334 /* Calculate how many different levels with alternative args strings exist in
1337 argp_args_levels (const struct argp *argp)
1340 const struct argp_child *child = argp->children;
1342 if (argp->args_doc && strchr (argp->args_doc, '\n'))
1347 levels += argp_args_levels ((child++)->argp);
1352 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1353 preceded by a space. LEVELS is a pointer to a byte vector the length
1354 returned by argp_args_levels; it should be initialized to zero, and
1355 updated by this routine for the next call if ADVANCE is true. True is
1356 returned as long as there are more patterns to output. */
1358 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1359 char **levels, int advance, argp_fmtstream_t stream)
1361 char *our_level = *levels;
1363 const struct argp_child *child = argp->children;
1364 const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1365 const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1369 const char *cp = fdoc;
1370 nl = __strchrnul (cp, '\n');
1372 /* This is a `multi-level' args doc; advance to the correct position
1373 as determined by our state in LEVELS, and update LEVELS. */
1377 for (i = 0; i < *our_level; i++)
1378 cp = nl + 1, nl = __strchrnul (cp, '\n');
1382 /* Manually do line wrapping so that it (probably) won't get wrapped at
1383 any embedded spaces. */
1384 space (stream, 1 + nl - cp);
1386 __argp_fmtstream_write (stream, cp, nl - cp);
1388 if (fdoc && fdoc != tdoc)
1389 free ((char *)fdoc); /* Free user's modified doc string. */
1393 advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1395 if (advance && multiple)
1397 /* Need to increment our level. */
1399 /* There's more we can do here. */
1402 advance = 0; /* Our parent shouldn't advance also. */
1404 else if (*our_level > 0)
1405 /* We had multiple levels, but used them up; reset to zero. */
1412 /* Print the documentation for ARGP to STREAM; if POST is false, then
1413 everything preceeding a `\v' character in the documentation strings (or
1414 the whole string, for those with none) is printed, otherwise, everything
1415 following the `\v' character (nothing for strings without). Each separate
1416 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1417 then the first is as well. If FIRST_ONLY is true, only the first
1418 occurrence is output. Returns true if anything was output. */
1420 argp_doc (const struct argp *argp, const struct argp_state *state,
1421 int post, int pre_blank, int first_only,
1422 argp_fmtstream_t stream)
1425 const char *inp_text;
1428 size_t inp_text_limit = 0;
1429 const char *doc = dgettext (argp->argp_domain, argp->doc);
1430 const struct argp_child *child = argp->children;
1434 char *vt = strchr (doc, '\v');
1435 inp_text = post ? (vt ? vt + 1 : 0) : doc;
1436 inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1441 if (argp->help_filter)
1442 /* We have to filter the doc strings. */
1445 /* Copy INP_TEXT so that it's nul-terminated. */
1446 inp_text = __strndup (inp_text, inp_text_limit);
1447 input = __argp_input (argp, state);
1449 (*argp->help_filter) (post
1450 ? ARGP_KEY_HELP_POST_DOC
1451 : ARGP_KEY_HELP_PRE_DOC,
1455 text = (const char *) inp_text;
1460 __argp_fmtstream_putc (stream, '\n');
1462 if (text == inp_text && inp_text_limit)
1463 __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1465 __argp_fmtstream_puts (stream, text);
1467 if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1468 __argp_fmtstream_putc (stream, '\n');
1473 if (text && text != inp_text)
1474 free ((char *) text); /* Free TEXT returned from the help filter. */
1475 if (inp_text && inp_text_limit && argp->help_filter)
1476 free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
1478 if (post && argp->help_filter)
1479 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1481 text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1484 if (anything || pre_blank)
1485 __argp_fmtstream_putc (stream, '\n');
1486 __argp_fmtstream_puts (stream, text);
1487 free ((char *) text);
1488 if (__argp_fmtstream_point (stream)
1489 > __argp_fmtstream_lmargin (stream))
1490 __argp_fmtstream_putc (stream, '\n');
1496 while (child->argp && !(first_only && anything))
1498 argp_doc ((child++)->argp, state,
1499 post, anything || pre_blank, first_only,
1505 /* Output a usage message for ARGP to STREAM. If called from
1506 argp_state_help, STATE is the relevent parsing state. FLAGS are from the
1507 set ARGP_HELP_*. NAME is what to use wherever a `program name' is
1510 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1511 unsigned flags, char *name)
1513 int anything = 0; /* Whether we've output anything. */
1514 struct hol *hol = 0;
1515 argp_fmtstream_t fs;
1520 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1521 __flockfile (stream);
1524 if (! uparams.valid)
1525 fill_in_uparams (state);
1527 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1530 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1531 __funlockfile (stream);
1536 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1538 hol = argp_hol (argp, 0);
1540 /* If present, these options always come last. */
1541 hol_set_group (hol, "help", -1);
1542 hol_set_group (hol, "version", -1);
1547 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1548 /* Print a short `Usage:' message. */
1550 int first_pattern = 1, more_patterns;
1551 size_t num_pattern_levels = argp_args_levels (argp);
1552 char *pattern_levels = alloca (num_pattern_levels);
1554 memset (pattern_levels, 0, num_pattern_levels);
1559 int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1560 char *levels = pattern_levels;
1563 __argp_fmtstream_printf (fs, "%s %s",
1564 dgettext (argp->argp_domain, "Usage:"),
1567 __argp_fmtstream_printf (fs, "%s %s",
1568 dgettext (argp->argp_domain, " or: "),
1571 /* We set the lmargin as well as the wmargin, because hol_usage
1572 manually wraps options with newline to avoid annoying breaks. */
1573 old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1575 if (flags & ARGP_HELP_SHORT_USAGE)
1576 /* Just show where the options go. */
1578 if (hol->num_entries > 0)
1579 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1583 /* Actually print the options. */
1585 hol_usage (hol, fs);
1586 flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
1589 more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1591 __argp_fmtstream_set_wmargin (fs, old_wm);
1592 __argp_fmtstream_set_lmargin (fs, old_lm);
1594 __argp_fmtstream_putc (fs, '\n');
1599 while (more_patterns);
1602 if (flags & ARGP_HELP_PRE_DOC)
1603 anything |= argp_doc (argp, state, 0, 0, 1, fs);
1605 if (flags & ARGP_HELP_SEE)
1607 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1608 Try `%s --help' or `%s --usage' for more information.\n"),
1613 if (flags & ARGP_HELP_LONG)
1614 /* Print a long, detailed help message. */
1616 /* Print info about all the options. */
1617 if (hol->num_entries > 0)
1620 __argp_fmtstream_putc (fs, '\n');
1621 hol_help (hol, state, fs);
1626 if (flags & ARGP_HELP_POST_DOC)
1627 /* Print any documentation strings at the end. */
1628 anything |= argp_doc (argp, state, 1, anything, 0, fs);
1630 if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1633 __argp_fmtstream_putc (fs, '\n');
1634 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1635 "Report bugs to %s.\n"),
1636 argp_program_bug_address);
1640 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1641 __funlockfile (stream);
1647 __argp_fmtstream_free (fs);
1650 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1651 ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
1652 void __argp_help (const struct argp *argp, FILE *stream,
1653 unsigned flags, char *name)
1655 _help (argp, 0, stream, flags, name);
1658 weak_alias (__argp_help, argp_help)
1661 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1663 __argp_short_program_name (void)
1665 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1666 char *name = strrchr (program_invocation_name, '/');
1667 return name ? name + 1 : program_invocation_name;
1669 /* FIXME: What now? Miles suggests that it is better to use NULL,
1670 but currently the value is passed on directly to fputs_unlocked,
1671 so that requires more changes. */
1673 # warning No reasonable value to return
1674 # endif /* __GNUC__ */
1680 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1681 from the set ARGP_HELP_*. */
1683 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1685 if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1687 if (state && (state->flags & ARGP_LONG_ONLY))
1688 flags |= ARGP_HELP_LONG_ONLY;
1690 _help (state ? state->root_argp : 0, state, stream, flags,
1691 state ? state->name : __argp_short_program_name ());
1693 if (!state || ! (state->flags & ARGP_NO_EXIT))
1695 if (flags & ARGP_HELP_EXIT_ERR)
1696 exit (argp_err_exit_status);
1697 if (flags & ARGP_HELP_EXIT_OK)
1703 weak_alias (__argp_state_help, argp_state_help)
1706 /* If appropriate, print the printf string FMT and following args, preceded
1707 by the program name and `:', to stderr, and followed by a `Try ... --help'
1708 message, then exit (1). */
1710 __argp_error (const struct argp_state *state, const char *fmt, ...)
1712 if (!state || !(state->flags & ARGP_NO_ERRS))
1714 FILE *stream = state ? state->err_stream : stderr;
1720 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1721 __flockfile (stream);
1727 if (_IO_fwide (stream, 0) > 0)
1731 __asprintf (&buf, fmt, ap);
1733 __fwprintf (stream, L"%s: %s\n",
1734 state ? state->name : __argp_short_program_name (),
1742 fputs_unlocked (state
1743 ? state->name : __argp_short_program_name (),
1745 putc_unlocked (':', stream);
1746 putc_unlocked (' ', stream);
1748 vfprintf (stream, fmt, ap);
1750 putc_unlocked ('\n', stream);
1753 __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1757 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1758 __funlockfile (stream);
1764 weak_alias (__argp_error, argp_error)
1767 /* Similar to the standard gnu error-reporting function error(), but will
1768 respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1769 to STATE->err_stream. This is useful for argument parsing code that is
1770 shared between program startup (when exiting is desired) and runtime
1771 option parsing (when typically an error code is returned instead). The
1772 difference between this function and argp_error is that the latter is for
1773 *parsing errors*, and the former is for other problems that occur during
1774 parsing but don't reflect a (syntactic) problem with the input. */
1776 __argp_failure (const struct argp_state *state, int status, int errnum,
1777 const char *fmt, ...)
1779 if (!state || !(state->flags & ARGP_NO_ERRS))
1781 FILE *stream = state ? state->err_stream : stderr;
1785 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1786 __flockfile (stream);
1790 if (_IO_fwide (stream, 0) > 0)
1791 __fwprintf (stream, L"%s",
1792 state ? state->name : __argp_short_program_name ());
1795 fputs_unlocked (state
1796 ? state->name : __argp_short_program_name (),
1805 if (_IO_fwide (stream, 0) > 0)
1809 __asprintf (&buf, fmt, ap);
1811 __fwprintf (stream, L": %s", buf);
1818 putc_unlocked (':', stream);
1819 putc_unlocked (' ', stream);
1821 vfprintf (stream, fmt, ap);
1832 if (_IO_fwide (stream, 0) > 0)
1833 __fwprintf (stream, L": %s",
1834 __strerror_r (errnum, buf, sizeof (buf)));
1838 char const *s = NULL;
1839 putc_unlocked (':', stream);
1840 putc_unlocked (' ', stream);
1841 #if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
1842 s = __strerror_r (errnum, buf, sizeof buf);
1843 #elif HAVE_DECL_STRERROR_R
1844 if (__strerror_r (errnum, buf, sizeof buf) == 0)
1848 if (! s && ! (s = strerror (errnum)))
1849 s = "Unknown system error"; /* FIXME: translate this */
1856 if (_IO_fwide (stream, 0) > 0)
1857 putwc_unlocked (L'\n', stream);
1860 putc_unlocked ('\n', stream);
1862 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1863 __funlockfile (stream);
1866 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1872 weak_alias (__argp_failure, argp_failure)