1 /* Hierarchical argument parsing help output
2 Copyright (C) 1995-2024 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 file is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation, either version 3 of the
9 License, or (at your option) any later version.
11 This file 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 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
20 # define _GNU_SOURCE 1
38 # include <../libio/libioP.h>
45 # define dgettext(domain, msgid) \
46 __dcgettext (domain, msgid, LC_MESSAGES)
52 #include "argp-fmtstream.h"
53 #include "argp-namefrob.h"
56 # define SIZE_MAX ((size_t) -1)
59 /* ========================================================================== */
61 /* User-selectable (using an environment variable) formatting parameters.
63 These may be specified in an environment variable called 'ARGP_HELP_FMT',
64 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
65 Where VALn must be a positive integer. The list of variables is in the
66 UPARAM_NAMES vector, below. */
68 /* Default parameters. */
69 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
70 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
71 #define SHORT_OPT_COL 2 /* column in which short options start */
72 #define LONG_OPT_COL 6 /* column in which long options start */
73 #define DOC_OPT_COL 2 /* column in which doc options start */
74 #define OPT_DOC_COL 29 /* column in which option text starts */
75 #define HEADER_COL 1 /* column in which group headers are printed */
76 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
77 #define RMARGIN 79 /* right margin used for wrapping */
79 /* User-selectable (using an environment variable) formatting parameters.
80 They must all be of type 'int' for the parsing code to work. */
83 /* If true, arguments for an option are shown with both short and long
84 options, even when a given option has both, e.g. '-x ARG, --longx=ARG'.
85 If false, then if an option has both, the argument is only shown with
86 the long one, e.g., '-x, --longx=ARG', and a message indicating that
87 this really means both is printed below the options. */
90 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
91 been suppressed, an explanatory message should be printed. */
94 /* Various output columns. */
95 int short_opt_col
; /* column in which short options start */
96 int long_opt_col
; /* column in which long options start */
97 int doc_opt_col
; /* column in which doc options start */
98 int opt_doc_col
; /* column in which option text starts */
99 int header_col
; /* column in which group headers are printed */
100 int usage_indent
; /* indentation of wrapped usage lines */
101 int rmargin
; /* right margin used for wrapping */
103 int valid
; /* True when the values in here are valid. */
106 /* This is a global variable, as user options are only ever read once. */
107 static struct uparams uparams
= {
108 DUP_ARGS
, DUP_ARGS_NOTE
,
109 SHORT_OPT_COL
, LONG_OPT_COL
, DOC_OPT_COL
, OPT_DOC_COL
, HEADER_COL
,
110 USAGE_INDENT
, RMARGIN
113 /* A particular uparam, and what the user name is. */
116 const char name
[14]; /* User name. */
117 bool is_bool
; /* Whether it's 'boolean'. */
118 unsigned char uparams_offs
; /* Location of the (int) field in UPARAMS. */
121 /* The name-field mappings we know about. */
122 static const struct uparam_name uparam_names
[] =
124 { "dup-args", true, offsetof (struct uparams
, dup_args
) },
125 { "dup-args-note", true, offsetof (struct uparams
, dup_args_note
) },
126 { "short-opt-col", false, offsetof (struct uparams
, short_opt_col
) },
127 { "long-opt-col", false, offsetof (struct uparams
, long_opt_col
) },
128 { "doc-opt-col", false, offsetof (struct uparams
, doc_opt_col
) },
129 { "opt-doc-col", false, offsetof (struct uparams
, opt_doc_col
) },
130 { "header-col", false, offsetof (struct uparams
, header_col
) },
131 { "usage-indent", false, offsetof (struct uparams
, usage_indent
) },
132 { "rmargin", false, offsetof (struct uparams
, rmargin
) }
134 #define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
137 validate_uparams (const struct argp_state
*state
, struct uparams
*upptr
)
139 const struct uparam_name
*up
;
141 for (up
= uparam_names
; up
< uparam_names
+ nuparam_names
; up
++)
144 || up
->uparams_offs
== offsetof (struct uparams
, rmargin
))
146 if (*(int *)((char *)upptr
+ up
->uparams_offs
) >= upptr
->rmargin
)
148 __argp_failure (state
, 0, 0,
149 dgettext (state
== NULL
? NULL
150 : state
->root_argp
->argp_domain
,
152 ARGP_HELP_FMT: %s value is less than or equal to %s"),
153 "rmargin", up
->name
);
161 /* Read user options from the environment, and fill in UPARAMS appropriately. */
163 fill_in_uparams (const struct argp_state
*state
)
165 const char *var
= getenv ("ARGP_HELP_FMT");
166 struct uparams new_params
= uparams
;
168 #define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0)
177 if (isalpha ((unsigned char) *var
))
180 const struct uparam_name
*un
;
181 int unspec
= 0, val
= 0;
182 const char *arg
= var
;
184 while (isalnum ((unsigned char) *arg
) || *arg
== '-' || *arg
== '_')
190 if (*arg
== '\0' || *arg
== ',')
192 else if (*arg
== '=')
200 if (var
[0] == 'n' && var
[1] == 'o' && var
[2] == '-')
209 else if (isdigit ((unsigned char) *arg
))
212 while (isdigit ((unsigned char) *arg
))
217 for (un
= uparam_names
;
218 un
< uparam_names
+ nuparam_names
;
220 if (strlen (un
->name
) == var_len
221 && strncmp (var
, un
->name
, var_len
) == 0)
223 if (unspec
&& !un
->is_bool
)
224 __argp_failure (state
, 0, 0,
225 dgettext (state
== NULL
? NULL
226 : state
->root_argp
->argp_domain
,
228 %.*s: ARGP_HELP_FMT parameter requires a value"),
231 *(int *)((char *)&new_params
+ un
->uparams_offs
) = val
;
234 if (un
== uparam_names
+ nuparam_names
)
235 __argp_failure (state
, 0, 0,
236 dgettext (state
== NULL
? NULL
237 : state
->root_argp
->argp_domain
, "\
238 %.*s: Unknown ARGP_HELP_FMT parameter"),
247 __argp_failure (state
, 0, 0,
248 dgettext (state
== NULL
? NULL
249 : state
->root_argp
->argp_domain
,
250 "Garbage in ARGP_HELP_FMT: %s"), var
);
254 validate_uparams (state
, &new_params
);
258 /* ========================================================================== */
260 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
261 whether OPT is displayed or used in sorting, not option shadowing. */
262 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
264 /* Returns true if OPT is an alias for an earlier option. */
265 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
267 /* Returns true if OPT is a documentation-only entry. */
268 #define odoc(opt) ((opt)->flags & OPTION_DOC)
270 /* Returns true if OPT should not be translated */
271 #define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
273 /* Returns true if OPT is the end-of-list marker for a list of options. */
274 #define oend(opt) __option_is_end (opt)
276 /* Returns true if OPT has a short option. */
277 #define oshort(opt) __option_is_short (opt)
280 The help format for a particular option is like:
282 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
284 Where ARG will be omitted if there's no argument, for this option, or
285 will be surrounded by "[" and "]" appropriately if the argument is
286 optional. The documentation string is word-wrapped appropriately, and if
287 the list of options is long enough, it will be started on a separate line.
288 If there are no short options for a given option, the first long option is
289 indented slightly in a way that's supposed to make most long options appear
290 to be in a separate column.
292 For example, the following output (from ps):
294 -p PID, --pid=PID List the process PID
295 --pgrp=PGRP List processes in the process group PGRP
296 -P, -x, --no-parent Include processes without parents
297 -Q, --all-fields Don't elide unusable fields (normally if there's
298 some reason ps can't print a field for any
299 process, it's removed from the output entirely)
300 -r, --reverse, --gratuitously-long-reverse-option
301 Reverse the order of any sort
302 --session[=SID] Add the processes from the session SID (which
303 defaults to the sid of the current process)
305 Here are some more options:
306 -f ZOT, --foonly=ZOT Glork a foonly
307 -z, --zaza Snit a zar
309 -?, --help Give this help list
310 --usage Give a short usage message
311 -V, --version Print program version
313 The struct argp_option array for the above could look like:
316 {"pid", 'p', "PID", 0, "List the process PID"},
317 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
318 {"no-parent", 'P', 0, 0, "Include processes without parents"},
319 {0, 'x', 0, OPTION_ALIAS},
320 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
321 " if there's some reason ps can't"
322 " print a field for any process, it's"
323 " removed from the output entirely)" },
324 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
325 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
326 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
327 "Add the processes from the session"
328 " SID (which defaults to the sid of"
329 " the current process)" },
331 {0,0,0,0, "Here are some more options:"},
332 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
333 {"zaza", 'z', 0, 0, "Snit a zar"},
338 Note that the last three options are automatically supplied by argp_parse,
339 unless you tell it not to with ARGP_NO_HELP.
343 /* Returns true if CH occurs between BEG and END. */
345 find_char (char ch
, char *beg
, char *end
)
355 /* -------------------------------------------------------------------------- */
356 /* Data structure: HOL = Help Option List */
358 struct hol_cluster
; /* fwd decl */
363 const struct argp_option
*opt
;
364 /* Number of options (including aliases). */
367 /* A pointers into the HOL's short_options field, to the first short option
368 letter for this entry. The order of the characters following this point
369 corresponds to the order of options pointed to by OPT, and there are at
370 most NUM. A short option recorded in an option following OPT is only
371 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
372 probably been shadowed by some other entry). */
375 /* Entries are sorted by their group first, in the order:
376 0, 1, 2, ..., n, -m, ..., -2, -1
377 and then alphabetically within each group. The default is 0. */
380 /* The cluster of options this entry belongs to, or NULL if none. */
381 struct hol_cluster
*cluster
;
383 /* The argp from which this option came. */
384 const struct argp
*argp
;
386 /* Position in the array */
390 /* A cluster of entries to reflect the argp tree structure. */
393 /* A descriptive header printed before options in this cluster. */
396 /* Used to order clusters within the same group with the same parent,
397 according to the order in which they occurred in the parent argp's child
401 /* How to sort this cluster with respect to options and other clusters at the
402 same depth (clusters always follow options in the same group). */
405 /* The cluster to which this cluster belongs, or NULL if it's at the base
407 struct hol_cluster
*parent
;
409 /* The argp from which this cluster is (eventually) derived. */
410 const struct argp
*argp
;
412 /* The distance this cluster is from the root. */
415 /* Clusters in a given hol are kept in a linked list, to make freeing them
417 struct hol_cluster
*next
;
420 /* A list of options for help. */
423 /* An array of hol_entry's. */
424 struct hol_entry
*entries
;
425 /* The number of entries in this hol. If this field is zero, entries and
426 short_options are undefined. */
427 unsigned num_entries
;
429 /* A string containing all short options in this HOL. Each entry contains
430 pointers into this string, so the order can't be messed with blindly. */
433 /* Clusters of entries in this hol. */
434 struct hol_cluster
*clusters
;
437 /* Create a struct hol from the options in ARGP. CLUSTER is the
438 hol_cluster in which these entries occur, or NULL if at the root. */
440 make_hol (const struct argp
*argp
, struct hol_cluster
*cluster
)
443 const struct argp_option
*o
;
444 const struct argp_option
*opts
= argp
->options
;
445 struct hol_entry
*entry
;
446 unsigned num_short_options
= 0;
447 struct hol
*hol
= malloc (sizeof (struct hol
));
451 hol
->num_entries
= 0;
452 hol
->clusters
= NULL
;
458 /* The first option must not be an alias. */
459 assert (! oalias (opts
));
461 /* Calculate the space needed. */
462 for (o
= opts
; ! oend (o
); o
++)
467 num_short_options
++; /* This is an upper bound. */
470 hol
->entries
= malloc (sizeof (struct hol_entry
) * hol
->num_entries
);
471 hol
->short_options
= malloc (num_short_options
+ 1);
473 assert (hol
->entries
&& hol
->short_options
);
474 if (SIZE_MAX
<= UINT_MAX
)
475 assert (hol
->num_entries
<= SIZE_MAX
/ sizeof (struct hol_entry
));
477 /* Fill in the entries. */
478 so
= hol
->short_options
;
479 for (o
= opts
, entry
= hol
->entries
; ! oend (o
); entry
++)
483 entry
->short_options
= so
;
484 entry
->group
= cur_group
=
487 : ((!o
->name
&& !o
->key
)
490 entry
->cluster
= cluster
;
496 if (oshort (o
) && ! find_char (o
->key
, hol
->short_options
, so
))
497 /* O has a valid short option which hasn't already been used.*/
501 while (! oend (o
) && oalias (o
));
503 *so
= '\0'; /* null terminated so we can find the length */
509 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
510 associated argp child list entry), INDEX, and PARENT, and return a pointer
511 to it. ARGP is the argp that this cluster results from. */
512 static struct hol_cluster
*
513 hol_add_cluster (struct hol
*hol
, int group
, const char *header
, int index
,
514 struct hol_cluster
*parent
, const struct argp
*argp
)
516 struct hol_cluster
*cl
= malloc (sizeof (struct hol_cluster
));
525 cl
->depth
= parent
? parent
->depth
+ 1 : 0;
527 cl
->next
= hol
->clusters
;
533 /* Free HOL and any resources it uses. */
535 hol_free (struct hol
*hol
)
537 struct hol_cluster
*cl
= hol
->clusters
;
541 struct hol_cluster
*next
= cl
->next
;
546 if (hol
->num_entries
> 0)
549 free (hol
->short_options
);
555 /* Iterate across the short_options of the given ENTRY. Call FUNC for each.
556 Stop when such a call returns a non-zero value, and return this value.
557 If all FUNC invocations returned 0, return 0. */
559 hol_entry_short_iterate (const struct hol_entry
*entry
,
560 int (*func
)(const struct argp_option
*opt
,
561 const struct argp_option
*real
,
562 const char *domain
, void *cookie
),
563 const char *domain
, void *cookie
)
567 const struct argp_option
*opt
, *real
= entry
->opt
;
568 char *so
= entry
->short_options
;
570 for (opt
= real
, nopts
= entry
->num
; nopts
> 0 && !val
; opt
++, nopts
--)
571 if (oshort (opt
) && *so
== opt
->key
)
576 val
= (*func
)(opt
, real
, domain
, cookie
);
583 /* Iterate across the long options of the given ENTRY. Call FUNC for each.
584 Stop when such a call returns a non-zero value, and return this value.
585 If all FUNC invocations returned 0, return 0. */
587 #if (__GNUC__ >= 3) || (__clang_major__ >= 4)
588 __attribute__ ((always_inline
))
590 hol_entry_long_iterate (const struct hol_entry
*entry
,
591 int (*func
)(const struct argp_option
*opt
,
592 const struct argp_option
*real
,
593 const char *domain
, void *cookie
),
594 const char *domain
, void *cookie
)
598 const struct argp_option
*opt
, *real
= entry
->opt
;
600 for (opt
= real
, nopts
= entry
->num
; nopts
> 0 && !val
; opt
++, nopts
--)
606 val
= (*func
)(opt
, real
, domain
, cookie
);
612 /* A filter that returns true for the first short option of a given ENTRY. */
614 until_short (const struct argp_option
*opt
, const struct argp_option
*real
,
615 const char *domain
, void *cookie
)
617 return oshort (opt
) ? opt
->key
: 0;
620 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
622 hol_entry_first_short (const struct hol_entry
*entry
)
624 return hol_entry_short_iterate (entry
, until_short
,
625 entry
->argp
->argp_domain
, 0);
628 /* Returns the first valid long option in ENTRY, or NULL if there is none. */
630 hol_entry_first_long (const struct hol_entry
*entry
)
632 const struct argp_option
*opt
;
634 for (opt
= entry
->opt
, num
= entry
->num
; num
> 0; opt
++, num
--)
635 if (opt
->name
&& ovisible (opt
))
640 /* Returns the entry in HOL with the long option name NAME, or NULL if there is
642 static struct hol_entry
*
643 hol_find_entry (struct hol
*hol
, const char *name
)
645 unsigned num_entries
= hol
->num_entries
;
649 struct hol_entry
*entry
= hol
->entries
;
653 const struct argp_option
*opt
= entry
->opt
;
654 unsigned num_opts
= entry
->num
;
656 while (num_opts
-- > 0)
657 if (opt
->name
&& ovisible (opt
) && strcmp (opt
->name
, name
) == 0)
664 while (--num_entries
> 0);
670 /* If an entry with the long option NAME occurs in HOL, set its special
671 sort position to GROUP. */
673 hol_set_group (struct hol
*hol
, const char *name
, int group
)
675 struct hol_entry
*entry
= hol_find_entry (hol
, name
);
677 entry
->group
= group
;
680 /* -------------------------------------------------------------------------- */
681 /* Sorting the entries in a HOL. */
683 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. */
685 group_cmp (int group1
, int group2
)
687 if ((group1
< 0 && group2
< 0) || (group1
>= 0 && group2
>= 0))
688 return group1
- group2
;
690 /* Return > 0 if group1 < 0 <= group2.
691 Return < 0 if group2 < 0 <= group1. */
692 return group2
- group1
;
695 /* Compare clusters CL1 and CL2 by the order that they should appear in
696 output. Assume CL1 and CL2 have the same parent. */
698 hol_sibling_cluster_cmp (const struct hol_cluster
*cl1
,
699 const struct hol_cluster
*cl2
)
701 /* Compare by group first. */
702 int cmp
= group_cmp (cl1
->group
, cl2
->group
);
706 /* Within a group, compare by index within the group. */
707 return cl2
->index
- cl1
->index
;
710 /* Compare clusters CL1 and CL2 by the order that they should appear in
711 output. Assume CL1 and CL2 are at the same depth. */
713 hol_cousin_cluster_cmp (const struct hol_cluster
*cl1
,
714 const struct hol_cluster
*cl2
)
716 if (cl1
->parent
== cl2
->parent
)
717 return hol_sibling_cluster_cmp (cl1
, cl2
);
720 /* Compare the parent clusters first. */
721 int cmp
= hol_cousin_cluster_cmp (cl1
->parent
, cl2
->parent
);
725 /* Next, compare by group. */
726 cmp
= group_cmp (cl1
->group
, cl2
->group
);
730 /* Next, within a group, compare by index within the group. */
731 return cl2
->index
- cl1
->index
;
735 /* Compare clusters CL1 and CL2 by the order that they should appear in
738 hol_cluster_cmp (const struct hol_cluster
*cl1
, const struct hol_cluster
*cl2
)
740 /* If one cluster is deeper than the other, use its ancestor at the same
741 level. Then, go by the rule that entries that are not in a sub-cluster
742 come before entries in a sub-cluster. */
743 if (cl1
->depth
> cl2
->depth
)
747 while (cl1
->depth
> cl2
->depth
);
748 int cmp
= hol_cousin_cluster_cmp (cl1
, cl2
);
754 else if (cl1
->depth
< cl2
->depth
)
758 while (cl1
->depth
< cl2
->depth
);
759 int cmp
= hol_cousin_cluster_cmp (cl1
, cl2
);
766 return hol_cousin_cluster_cmp (cl1
, cl2
);
769 /* Return the ancestor of CL that's just below the root (i.e., has a parent
771 static struct hol_cluster
*
772 hol_cluster_base (struct hol_cluster
*cl
)
779 /* Given the name of an OPTION_DOC option, modifies *NAME to start at the tail
780 that should be used for comparisons, and returns true iff it should be
781 treated as a non-option. */
783 canon_doc_option (const char **name
)
786 /* Skip initial whitespace. */
787 while (isspace ((unsigned char) **name
))
789 /* Decide whether this looks like an option (leading '-') or not. */
790 non_opt
= (**name
!= '-');
791 /* Skip until part of name used for sorting. */
792 while (**name
&& !isalnum ((unsigned char) **name
))
797 /* Order ENTRY1 and ENTRY2 by the order which they should appear in a help
799 This function implements a total order, that is:
800 - if cmp (entry1, entry2) < 0 and cmp (entry2, entry3) < 0,
801 then cmp (entry1, entry3) < 0.
802 - if cmp (entry1, entry2) < 0 and cmp (entry2, entry3) == 0,
803 then cmp (entry1, entry3) < 0.
804 - if cmp (entry1, entry2) == 0 and cmp (entry2, entry3) < 0,
805 then cmp (entry1, entry3) < 0.
806 - if cmp (entry1, entry2) == 0 and cmp (entry2, entry3) == 0,
807 then cmp (entry1, entry3) == 0. */
809 hol_entry_cmp (const struct hol_entry
*entry1
,
810 const struct hol_entry
*entry2
)
812 /* First, compare the group numbers. For entries within a cluster, what
813 matters is the group number of the base cluster in which the entry
815 int group1
= (entry1
->cluster
816 ? hol_cluster_base (entry1
->cluster
)->group
818 int group2
= (entry2
->cluster
819 ? hol_cluster_base (entry2
->cluster
)->group
821 int cmp
= group_cmp (group1
, group2
);
825 /* The group numbers are the same. */
827 /* Entries that are not in a cluster come before entries in a cluster. */
828 cmp
= (entry1
->cluster
!= NULL
) - (entry2
->cluster
!= NULL
);
832 /* Compare the clusters. */
833 if (entry1
->cluster
!= NULL
)
835 cmp
= hol_cluster_cmp (entry1
->cluster
, entry2
->cluster
);
840 /* For entries in the same cluster, compare also the group numbers
841 within the cluster. */
842 cmp
= group_cmp (entry1
->group
, entry2
->group
);
846 /* The entries are both in the same group and the same cluster. */
848 /* 'documentation' options always follow normal options (or documentation
849 options that *look* like normal options). */
850 const char *long1
= hol_entry_first_long (entry1
);
851 const char *long2
= hol_entry_first_long (entry2
);
853 (odoc (entry1
->opt
) ? long1
!= NULL
&& canon_doc_option (&long1
) : 0);
855 (odoc (entry2
->opt
) ? long2
!= NULL
&& canon_doc_option (&long2
) : 0);
860 /* Compare the entries alphabetically. */
862 /* First, compare the first character of the options.
863 Put entries without *any* valid options (such as options with
864 OPTION_HIDDEN set) first. But as they're not displayed, it doesn't
865 matter where they are. */
866 int short1
= hol_entry_first_short (entry1
);
867 int short2
= hol_entry_first_short (entry2
);
868 unsigned char first1
= short1
? short1
: long1
!= NULL
? *long1
: 0;
869 unsigned char first2
= short2
? short2
: long2
!= NULL
? *long2
: 0;
870 /* Compare ignoring case. */
871 /* Use tolower, not _tolower, since the latter has undefined behaviour
872 for characters that are not uppercase letters. */
873 cmp
= tolower (first1
) - tolower (first2
);
876 /* When the options start with the same letter (ignoring case), lower-case
878 cmp
= first2
- first1
;
882 /* The first character of the options agree. */
884 /* Put entries with a short option before entries without a short option. */
885 cmp
= (short1
!= 0) - (short2
!= 0);
889 /* Compare entries without a short option by comparing the long option. */
892 cmp
= (long1
!= NULL
) - (long2
!= NULL
);
898 cmp
= __strcasecmp (long1
, long2
);
904 /* We're out of comparison criteria. At this point, if ENTRY1 != ENTRY2,
905 the order of these entries will be unpredictable. */
909 /* Variant of hol_entry_cmp with correct signature for qsort. */
911 hol_entry_qcmp (const void *entry1_v
, const void *entry2_v
)
913 return hol_entry_cmp (entry1_v
, entry2_v
);
916 /* Sort HOL by group and alphabetically by option name (with short options
917 taking precedence over long). Since the sorting is for display purposes
918 only, the shadowing of options isn't effected. */
920 hol_sort (struct hol
*hol
)
922 if (hol
->num_entries
> 0)
926 for (i
= 0, e
= hol
->entries
; i
< hol
->num_entries
; i
++, e
++)
929 qsort (hol
->entries
, hol
->num_entries
, sizeof (struct hol_entry
),
934 /* -------------------------------------------------------------------------- */
935 /* Constructing the HOL. */
937 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
938 any in MORE with the same name. */
940 hol_append (struct hol
*hol
, struct hol
*more
)
942 struct hol_cluster
**cl_end
= &hol
->clusters
;
944 /* Steal MORE's cluster list, and add it to the end of HOL's. */
946 cl_end
= &(*cl_end
)->next
;
947 *cl_end
= more
->clusters
;
948 more
->clusters
= NULL
;
951 if (more
->num_entries
> 0)
953 if (hol
->num_entries
== 0)
955 hol
->num_entries
= more
->num_entries
;
956 hol
->entries
= more
->entries
;
957 hol
->short_options
= more
->short_options
;
958 more
->num_entries
= 0; /* Mark MORE's fields as invalid. */
961 /* Append the entries in MORE to those in HOL, taking care to only add
962 non-shadowed SHORT_OPTIONS values. */
967 unsigned num_entries
= hol
->num_entries
+ more
->num_entries
;
968 struct hol_entry
*entries
=
969 malloc (num_entries
* sizeof (struct hol_entry
));
970 unsigned hol_so_len
= strlen (hol
->short_options
);
971 char *short_options
=
972 malloc (hol_so_len
+ strlen (more
->short_options
) + 1);
974 assert (entries
&& short_options
);
975 if (SIZE_MAX
<= UINT_MAX
)
976 assert (num_entries
<= SIZE_MAX
/ sizeof (struct hol_entry
));
978 __mempcpy (__mempcpy (entries
, hol
->entries
,
979 hol
->num_entries
* sizeof (struct hol_entry
)),
981 more
->num_entries
* sizeof (struct hol_entry
));
983 __mempcpy (short_options
, hol
->short_options
, hol_so_len
);
985 /* Fix up the short options pointers from HOL. */
986 for (e
= entries
, left
= hol
->num_entries
; left
> 0; e
++, left
--)
988 = short_options
+ (e
->short_options
- hol
->short_options
);
990 /* Now add the short options from MORE, fixing up its entries
992 so
= short_options
+ hol_so_len
;
993 more_so
= more
->short_options
;
994 for (left
= more
->num_entries
; left
> 0; e
++, left
--)
997 const struct argp_option
*opt
;
999 e
->short_options
= so
;
1001 for (opts_left
= e
->num
, opt
= e
->opt
; opts_left
; opt
++, opts_left
--)
1004 if (oshort (opt
) && ch
== opt
->key
)
1005 /* The next short option in MORE_SO, CH, is from OPT. */
1007 if (! find_char (ch
, short_options
,
1008 short_options
+ hol_so_len
))
1009 /* The short option CH isn't shadowed by HOL's options,
1010 so add it to the sum. */
1019 free (hol
->entries
);
1020 free (hol
->short_options
);
1022 hol
->entries
= entries
;
1023 hol
->num_entries
= num_entries
;
1024 hol
->short_options
= short_options
;
1031 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1032 cluster in which ARGP's entries should be clustered, or NULL. */
1034 argp_hol (const struct argp
*argp
, struct hol_cluster
*cluster
)
1036 const struct argp_child
*child
= argp
->children
;
1037 struct hol
*hol
= make_hol (argp
, cluster
);
1041 struct hol_cluster
*child_cluster
=
1042 ((child
->group
|| child
->header
)
1043 /* Put CHILD->argp within its own cluster. */
1044 ? hol_add_cluster (hol
, child
->group
, child
->header
,
1045 child
- argp
->children
, cluster
, argp
)
1046 /* Just merge it into the parent's cluster. */
1048 hol_append (hol
, argp_hol (child
->argp
, child_cluster
)) ;
1054 /* -------------------------------------------------------------------------- */
1055 /* Printing the HOL. */
1057 /* Inserts enough spaces to make sure STREAM is at column COL. */
1059 indent_to (argp_fmtstream_t stream
, unsigned col
)
1061 int needed
= col
- __argp_fmtstream_point (stream
);
1062 while (needed
-- > 0)
1063 __argp_fmtstream_putc (stream
, ' ');
1066 /* Output to STREAM either a space, or a newline if there isn't room for at
1067 least ENSURE characters before the right margin. */
1069 space (argp_fmtstream_t stream
, size_t ensure
)
1071 if (__argp_fmtstream_point (stream
) + ensure
1072 >= __argp_fmtstream_rmargin (stream
))
1073 __argp_fmtstream_putc (stream
, '\n');
1075 __argp_fmtstream_putc (stream
, ' ');
1078 /* If the option REAL has an argument, we print it in using the printf
1079 format REQ_FMT or OPT_FMT depending on whether it's a required or
1080 optional argument. */
1082 arg (const struct argp_option
*real
, const char *req_fmt
, const char *opt_fmt
,
1083 const char *domain
, argp_fmtstream_t stream
)
1087 if (real
->flags
& OPTION_ARG_OPTIONAL
)
1088 __argp_fmtstream_printf (stream
, opt_fmt
,
1089 dgettext (domain
, real
->arg
));
1091 __argp_fmtstream_printf (stream
, req_fmt
,
1092 dgettext (domain
, real
->arg
));
1096 /* Helper functions for hol_entry_help. */
1098 /* State used during the execution of hol_help. */
1099 struct hol_help_state
1101 /* PREV_ENTRY should contain the previous entry printed, or NULL. */
1102 struct hol_entry
*prev_entry
;
1104 /* If an entry is in a different group from the previous one, and SEP_GROUPS
1105 is true, then a blank line will be printed before any output. */
1108 /* True if a duplicate option argument was suppressed (only ever set if
1109 UPARAMS.dup_args is false). */
1110 int suppressed_dup_arg
;
1113 /* Some state used while printing a help entry (used to communicate with
1114 helper functions). See the doc for hol_entry_help for more info, as most
1115 of the fields are copied from its arguments. */
1118 const struct hol_entry
*entry
;
1119 argp_fmtstream_t stream
;
1120 struct hol_help_state
*hhstate
;
1122 /* True if nothing's been printed so far. */
1125 /* If non-zero, the state that was used to print this help. */
1126 const struct argp_state
*state
;
1129 /* If a user doc filter should be applied to DOC, do so. */
1131 filter_doc (const char *doc
, int key
, const struct argp
*argp
,
1132 const struct argp_state
*state
)
1134 if (argp
&& argp
->help_filter
)
1135 /* We must apply a user filter to this output. */
1137 void *input
= __argp_input (argp
, state
);
1138 return (*argp
->help_filter
) (key
, doc
, input
);
1145 /* Prints STR as a header line, with the margin lines set appropriately, and
1146 notes the fact that groups should be separated with a blank line. ARGP is
1147 the argp that should dictate any user doc filtering to take place. Note
1148 that the previous wrap margin isn't restored, but the left margin is reset
1151 print_header (const char *str
, const struct argp
*argp
,
1152 struct pentry_state
*pest
)
1154 const char *tstr
= str
? dgettext (argp
->argp_domain
, str
) : NULL
;
1155 const char *fstr
= filter_doc (tstr
, ARGP_KEY_HELP_HEADER
, argp
, pest
->state
);
1161 if (pest
->hhstate
->prev_entry
)
1162 /* Precede with a blank line. */
1163 __argp_fmtstream_putc (pest
->stream
, '\n');
1164 indent_to (pest
->stream
, uparams
.header_col
);
1165 __argp_fmtstream_set_lmargin (pest
->stream
, uparams
.header_col
);
1166 __argp_fmtstream_set_wmargin (pest
->stream
, uparams
.header_col
);
1167 __argp_fmtstream_puts (pest
->stream
, fstr
);
1168 __argp_fmtstream_set_lmargin (pest
->stream
, 0);
1169 __argp_fmtstream_putc (pest
->stream
, '\n');
1172 pest
->hhstate
->sep_groups
= 1; /* Separate subsequent groups. */
1176 free ((char *) fstr
);
1179 /* Return true if CL1 is a child of CL2. */
1181 hol_cluster_is_child (const struct hol_cluster
*cl1
,
1182 const struct hol_cluster
*cl2
)
1184 while (cl1
&& cl1
!= cl2
)
1189 /* Inserts a comma if this isn't the first item on the line, and then makes
1190 sure we're at least to column COL. If this *is* the first item on a line,
1191 prints any pending whitespace/headers that should precede this line. Also
1194 comma (unsigned col
, struct pentry_state
*pest
)
1198 const struct hol_entry
*pe
= pest
->hhstate
->prev_entry
;
1199 const struct hol_cluster
*cl
= pest
->entry
->cluster
;
1201 if (pest
->hhstate
->sep_groups
&& pe
&& pest
->entry
->group
!= pe
->group
)
1202 __argp_fmtstream_putc (pest
->stream
, '\n');
1204 if (cl
&& cl
->header
&& *cl
->header
1206 || (pe
->cluster
!= cl
1207 && !hol_cluster_is_child (pe
->cluster
, cl
))))
1208 /* If we're changing clusters, then this must be the start of the
1209 ENTRY's cluster unless that is an ancestor of the previous one
1210 (in which case we had just popped into a sub-cluster for a bit).
1211 If so, then print the cluster's header line. */
1213 int old_wm
= __argp_fmtstream_wmargin (pest
->stream
);
1214 print_header (cl
->header
, cl
->argp
, pest
);
1215 __argp_fmtstream_set_wmargin (pest
->stream
, old_wm
);
1221 __argp_fmtstream_puts (pest
->stream
, ", ");
1223 indent_to (pest
->stream
, col
);
1226 /* Print help for ENTRY to STREAM. */
1228 hol_entry_help (struct hol_entry
*entry
, const struct argp_state
*state
,
1229 argp_fmtstream_t stream
, struct hol_help_state
*hhstate
)
1232 const struct argp_option
*real
= entry
->opt
, *opt
;
1233 char *so
= entry
->short_options
;
1234 int have_long_opt
= 0; /* We have any long options. */
1235 /* Saved margins. */
1236 int old_lm
= __argp_fmtstream_set_lmargin (stream
, 0);
1237 int old_wm
= __argp_fmtstream_wmargin (stream
);
1238 /* PEST is a state block holding some of our variables that we'd like to
1239 share with helper functions. */
1240 struct pentry_state pest
= { entry
, stream
, hhstate
, 1, state
};
1243 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1244 if (opt
->name
&& ovisible (opt
))
1250 /* First emit short options. */
1251 __argp_fmtstream_set_wmargin (stream
, uparams
.short_opt_col
); /* For truly bizarre cases. */
1252 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1253 if (oshort (opt
) && opt
->key
== *so
)
1254 /* OPT has a valid (non shadowed) short option. */
1258 comma (uparams
.short_opt_col
, &pest
);
1259 __argp_fmtstream_putc (stream
, '-');
1260 __argp_fmtstream_putc (stream
, *so
);
1261 if (!have_long_opt
|| uparams
.dup_args
)
1262 arg (real
, " %s", "[%s]",
1263 state
== NULL
? NULL
: state
->root_argp
->argp_domain
,
1266 hhstate
->suppressed_dup_arg
= 1;
1271 /* Now, long options. */
1273 /* A "documentation" option. */
1275 __argp_fmtstream_set_wmargin (stream
, uparams
.doc_opt_col
);
1276 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1277 if (opt
->name
&& ovisible (opt
))
1279 comma (uparams
.doc_opt_col
, &pest
);
1280 /* Calling dgettext here isn't quite right, since sorting will
1281 have been done on the original; but documentation options
1282 should be pretty rare anyway... */
1283 __argp_fmtstream_puts (stream
,
1284 dgettext (state
== NULL
? NULL
1285 : state
->root_argp
->argp_domain
,
1290 /* A real long option. */
1292 __argp_fmtstream_set_wmargin (stream
, uparams
.long_opt_col
);
1293 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1294 if (opt
->name
&& ovisible (opt
))
1296 comma (uparams
.long_opt_col
, &pest
);
1297 __argp_fmtstream_printf (stream
, "--%s", opt
->name
);
1298 arg (real
, "=%s", "[=%s]",
1299 state
== NULL
? NULL
: state
->root_argp
->argp_domain
, stream
);
1303 /* Next, documentation strings. */
1304 __argp_fmtstream_set_lmargin (stream
, 0);
1308 /* Didn't print any switches, what's up? */
1309 if (!oshort (real
) && !real
->name
)
1310 /* This is a group header, print it nicely. */
1311 print_header (real
->doc
, entry
->argp
, &pest
);
1313 /* Just a totally shadowed option or null header; print nothing. */
1314 goto cleanup
; /* Just return, after cleaning up. */
1318 const char *tstr
= real
->doc
? dgettext (state
== NULL
? NULL
1319 : state
->root_argp
->argp_domain
,
1321 const char *fstr
= filter_doc (tstr
, real
->key
, entry
->argp
, state
);
1324 unsigned int col
= __argp_fmtstream_point (stream
);
1326 __argp_fmtstream_set_lmargin (stream
, uparams
.opt_doc_col
);
1327 __argp_fmtstream_set_wmargin (stream
, uparams
.opt_doc_col
);
1329 if (col
> (unsigned int) (uparams
.opt_doc_col
+ 3))
1330 __argp_fmtstream_putc (stream
, '\n');
1331 else if (col
>= (unsigned int) uparams
.opt_doc_col
)
1332 __argp_fmtstream_puts (stream
, " ");
1334 indent_to (stream
, uparams
.opt_doc_col
);
1336 __argp_fmtstream_puts (stream
, fstr
);
1338 if (fstr
&& fstr
!= tstr
)
1339 free ((char *) fstr
);
1341 /* Reset the left margin. */
1342 __argp_fmtstream_set_lmargin (stream
, 0);
1343 __argp_fmtstream_putc (stream
, '\n');
1346 hhstate
->prev_entry
= entry
;
1349 __argp_fmtstream_set_lmargin (stream
, old_lm
);
1350 __argp_fmtstream_set_wmargin (stream
, old_wm
);
1353 /* Output a long help message about the options in HOL to STREAM. */
1355 hol_help (struct hol
*hol
, const struct argp_state
*state
,
1356 argp_fmtstream_t stream
)
1359 struct hol_entry
*entry
;
1360 struct hol_help_state hhstate
= { 0, 0, 0 };
1362 for (entry
= hol
->entries
, num
= hol
->num_entries
; num
> 0; entry
++, num
--)
1363 hol_entry_help (entry
, state
, stream
, &hhstate
);
1365 if (hhstate
.suppressed_dup_arg
&& uparams
.dup_args_note
)
1367 const char *tstr
= dgettext (state
== NULL
? NULL
1368 : state
->root_argp
->argp_domain
, "\
1369 Mandatory or optional arguments to long options are also mandatory or \
1370 optional for any corresponding short options.");
1371 const char *fstr
= filter_doc (tstr
, ARGP_KEY_HELP_DUP_ARGS_NOTE
,
1372 state
? state
->root_argp
: 0, state
);
1375 __argp_fmtstream_putc (stream
, '\n');
1376 __argp_fmtstream_puts (stream
, fstr
);
1377 __argp_fmtstream_putc (stream
, '\n');
1379 if (fstr
&& fstr
!= tstr
)
1380 free ((char *) fstr
);
1384 /* Helper functions for hol_usage. */
1386 /* If OPT is a short option without an arg, append its key to the string
1387 pointer pointer to by COOKIE, and advance the pointer. */
1389 add_argless_short_opt (const struct argp_option
*opt
,
1390 const struct argp_option
*real
,
1391 const char *domain
, void *cookie
)
1393 char **snao_end
= cookie
;
1394 if (!(opt
->arg
|| real
->arg
)
1395 && !((opt
->flags
| real
->flags
) & OPTION_NO_USAGE
))
1396 *(*snao_end
)++ = opt
->key
;
1400 /* If OPT is a short option with an arg, output a usage entry for it to the
1401 stream pointed at by COOKIE. */
1403 usage_argful_short_opt (const struct argp_option
*opt
,
1404 const struct argp_option
*real
,
1405 const char *domain
, void *cookie
)
1407 argp_fmtstream_t stream
= cookie
;
1408 const char *arg
= opt
->arg
;
1409 int flags
= opt
->flags
| real
->flags
;
1414 if (arg
&& !(flags
& OPTION_NO_USAGE
))
1416 arg
= dgettext (domain
, arg
);
1418 if (flags
& OPTION_ARG_OPTIONAL
)
1419 __argp_fmtstream_printf (stream
, " [-%c[%s]]", opt
->key
, arg
);
1422 /* Manually do line wrapping so that it (probably) won't
1423 get wrapped at the embedded space. */
1424 space (stream
, 6 + strlen (arg
));
1425 __argp_fmtstream_printf (stream
, "[-%c %s]", opt
->key
, arg
);
1432 /* Output a usage entry for the long option opt to the stream pointed at by
1435 usage_long_opt (const struct argp_option
*opt
,
1436 const struct argp_option
*real
,
1437 const char *domain
, void *cookie
)
1439 argp_fmtstream_t stream
= cookie
;
1440 const char *arg
= opt
->arg
;
1441 int flags
= opt
->flags
| real
->flags
;
1446 if (! (flags
& OPTION_NO_USAGE
))
1450 arg
= dgettext (domain
, arg
);
1451 if (flags
& OPTION_ARG_OPTIONAL
)
1452 __argp_fmtstream_printf (stream
, " [--%s[=%s]]", opt
->name
, arg
);
1454 __argp_fmtstream_printf (stream
, " [--%s=%s]", opt
->name
, arg
);
1457 __argp_fmtstream_printf (stream
, " [--%s]", opt
->name
);
1463 /* Print a short usage description for the arguments in HOL to STREAM. */
1465 hol_usage (struct hol
*hol
, argp_fmtstream_t stream
)
1467 if (hol
->num_entries
> 0)
1470 struct hol_entry
*entry
;
1471 char *short_no_arg_opts
= alloca (strlen (hol
->short_options
) + 1);
1472 char *snao_end
= short_no_arg_opts
;
1474 /* First we put a list of short options without arguments. */
1475 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1477 ; entry
++, nentries
--)
1478 hol_entry_short_iterate (entry
, add_argless_short_opt
,
1479 entry
->argp
->argp_domain
, &snao_end
);
1480 if (snao_end
> short_no_arg_opts
)
1483 __argp_fmtstream_printf (stream
, " [-%s]", short_no_arg_opts
);
1486 /* Now a list of short options *with* arguments. */
1487 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1489 ; entry
++, nentries
--)
1490 hol_entry_short_iterate (entry
, usage_argful_short_opt
,
1491 entry
->argp
->argp_domain
, stream
);
1493 /* Finally, a list of long options (whew!). */
1494 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1496 ; entry
++, nentries
--)
1497 hol_entry_long_iterate (entry
, usage_long_opt
,
1498 entry
->argp
->argp_domain
, stream
);
1502 /* Calculate how many different levels with alternative args strings exist in
1505 argp_args_levels (const struct argp
*argp
)
1508 const struct argp_child
*child
= argp
->children
;
1510 if (argp
->args_doc
&& strchr (argp
->args_doc
, '\n'))
1515 levels
+= argp_args_levels ((child
++)->argp
);
1520 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1521 preceded by a space. LEVELS is a pointer to a byte vector the length
1522 returned by argp_args_levels; it should be initialized to zero, and
1523 updated by this routine for the next call if ADVANCE is true. True is
1524 returned as long as there are more patterns to output. */
1526 argp_args_usage (const struct argp
*argp
, const struct argp_state
*state
,
1527 char **levels
, int advance
, argp_fmtstream_t stream
)
1529 char *our_level
= *levels
;
1531 const struct argp_child
*child
= argp
->children
;
1533 argp
->args_doc
? dgettext (argp
->argp_domain
, argp
->args_doc
) : NULL
;
1534 const char *fdoc
= filter_doc (tdoc
, ARGP_KEY_HELP_ARGS_DOC
, argp
, state
);
1535 const char *nl
= NULL
;
1539 const char *cp
= fdoc
;
1540 nl
= __strchrnul (cp
, '\n');
1542 /* This is a 'multi-level' args doc; advance to the correct position
1543 as determined by our state in LEVELS, and update LEVELS. */
1547 for (i
= 0; i
< *our_level
; i
++)
1548 cp
= nl
+ 1, nl
= __strchrnul (cp
, '\n');
1552 /* Manually do line wrapping so that it (probably) won't get wrapped at
1553 any embedded spaces. */
1554 space (stream
, 1 + nl
- cp
);
1556 __argp_fmtstream_write (stream
, cp
, nl
- cp
);
1558 if (fdoc
&& fdoc
!= tdoc
)
1559 free ((char *)fdoc
); /* Free user's modified doc string. */
1563 advance
= !argp_args_usage ((child
++)->argp
, state
, levels
, advance
, stream
);
1565 if (advance
&& multiple
)
1567 /* Need to increment our level. */
1569 /* There's more we can do here. */
1572 advance
= 0; /* Our parent shouldn't advance also. */
1574 else if (*our_level
> 0)
1575 /* We had multiple levels, but used them up; reset to zero. */
1582 /* Print the documentation for ARGP to STREAM; if POST is false, then
1583 everything preceding a '\v' character in the documentation strings (or
1584 the whole string, for those with none) is printed, otherwise, everything
1585 following the '\v' character (nothing for strings without). Each separate
1586 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1587 then the first is as well. If FIRST_ONLY is true, only the first
1588 occurrence is output. Returns true if anything was output. */
1590 argp_doc (const struct argp
*argp
, const struct argp_state
*state
,
1591 int post
, int pre_blank
, int first_only
,
1592 argp_fmtstream_t stream
)
1595 const char *inp_text
;
1598 size_t inp_text_limit
= 0;
1599 const char *doc
= argp
->doc
? dgettext (argp
->argp_domain
, argp
->doc
) : NULL
;
1600 const struct argp_child
*child
= argp
->children
;
1604 char *vt
= strchr (doc
, '\v');
1605 inp_text
= post
? (vt
? vt
+ 1 : 0) : doc
;
1606 inp_text_limit
= (!post
&& vt
) ? (vt
- doc
) : 0;
1611 if (argp
->help_filter
)
1612 /* We have to filter the doc strings. */
1615 /* Copy INP_TEXT so that it's nul-terminated. */
1616 inp_text
= __strndup (inp_text
, inp_text_limit
);
1617 input
= __argp_input (argp
, state
);
1619 (*argp
->help_filter
) (post
1620 ? ARGP_KEY_HELP_POST_DOC
1621 : ARGP_KEY_HELP_PRE_DOC
,
1625 text
= (const char *) inp_text
;
1630 __argp_fmtstream_putc (stream
, '\n');
1632 if (text
== inp_text
&& inp_text_limit
)
1633 __argp_fmtstream_write (stream
, inp_text
, inp_text_limit
);
1635 __argp_fmtstream_puts (stream
, text
);
1637 if (__argp_fmtstream_point (stream
) > __argp_fmtstream_lmargin (stream
))
1638 __argp_fmtstream_putc (stream
, '\n');
1643 if (text
&& text
!= inp_text
)
1644 free ((char *) text
); /* Free TEXT returned from the help filter. */
1645 if (inp_text
&& inp_text_limit
&& argp
->help_filter
)
1646 free ((char *) inp_text
); /* We copied INP_TEXT, so free it now. */
1648 if (post
&& argp
->help_filter
)
1649 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1651 text
= (*argp
->help_filter
) (ARGP_KEY_HELP_EXTRA
, 0, input
);
1654 if (anything
|| pre_blank
)
1655 __argp_fmtstream_putc (stream
, '\n');
1656 __argp_fmtstream_puts (stream
, text
);
1657 free ((char *) text
);
1658 if (__argp_fmtstream_point (stream
)
1659 > __argp_fmtstream_lmargin (stream
))
1660 __argp_fmtstream_putc (stream
, '\n');
1666 while (child
->argp
&& !(first_only
&& anything
))
1668 argp_doc ((child
++)->argp
, state
,
1669 post
, anything
|| pre_blank
, first_only
,
1675 /* Output a usage message for ARGP to STREAM. If called from
1676 argp_state_help, STATE is the relevant parsing state. FLAGS are from the
1677 set ARGP_HELP_*. NAME is what to use wherever a 'program name' is
1680 _help (const struct argp
*argp
, const struct argp_state
*state
, FILE *stream
,
1681 unsigned flags
, char *name
)
1683 int anything
= 0; /* Whether we've output anything. */
1684 struct hol
*hol
= NULL
;
1685 argp_fmtstream_t fs
;
1690 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1691 __flockfile (stream
);
1694 if (! uparams
.valid
)
1695 fill_in_uparams (state
);
1697 fs
= __argp_make_fmtstream (stream
, 0, uparams
.rmargin
, 0);
1700 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1701 __funlockfile (stream
);
1706 if (flags
& (ARGP_HELP_USAGE
| ARGP_HELP_SHORT_USAGE
| ARGP_HELP_LONG
))
1708 hol
= argp_hol (argp
, 0);
1710 /* If present, these options always come last. */
1711 hol_set_group (hol
, "help", -1);
1712 hol_set_group (hol
, "version", -1);
1717 if (flags
& (ARGP_HELP_USAGE
| ARGP_HELP_SHORT_USAGE
))
1718 /* Print a short "Usage:" message. */
1720 int first_pattern
= 1, more_patterns
;
1721 size_t num_pattern_levels
= argp_args_levels (argp
);
1722 char *pattern_levels
= alloca (num_pattern_levels
);
1724 memset (pattern_levels
, 0, num_pattern_levels
);
1729 int old_wm
= __argp_fmtstream_set_wmargin (fs
, uparams
.usage_indent
);
1730 char *levels
= pattern_levels
;
1733 __argp_fmtstream_printf (fs
, "%s %s",
1734 dgettext (argp
->argp_domain
, "Usage:"),
1737 __argp_fmtstream_printf (fs
, "%s %s",
1738 dgettext (argp
->argp_domain
, " or: "),
1741 /* We set the lmargin as well as the wmargin, because hol_usage
1742 manually wraps options with newline to avoid annoying breaks. */
1743 old_lm
= __argp_fmtstream_set_lmargin (fs
, uparams
.usage_indent
);
1745 if (flags
& ARGP_HELP_SHORT_USAGE
)
1746 /* Just show where the options go. */
1748 if (hol
->num_entries
> 0)
1749 __argp_fmtstream_puts (fs
, dgettext (argp
->argp_domain
,
1753 /* Actually print the options. */
1755 hol_usage (hol
, fs
);
1756 flags
|= ARGP_HELP_SHORT_USAGE
; /* But only do so once. */
1759 more_patterns
= argp_args_usage (argp
, state
, &levels
, 1, fs
);
1761 __argp_fmtstream_set_wmargin (fs
, old_wm
);
1762 __argp_fmtstream_set_lmargin (fs
, old_lm
);
1764 __argp_fmtstream_putc (fs
, '\n');
1769 while (more_patterns
);
1772 if (flags
& ARGP_HELP_PRE_DOC
)
1773 anything
|= argp_doc (argp
, state
, 0, 0, 1, fs
);
1775 if (flags
& ARGP_HELP_SEE
)
1777 __argp_fmtstream_printf (fs
, dgettext (argp
->argp_domain
, "\
1778 Try '%s --help' or '%s --usage' for more information.\n"),
1783 if (flags
& ARGP_HELP_LONG
)
1784 /* Print a long, detailed help message. */
1786 /* Print info about all the options. */
1787 if (hol
->num_entries
> 0)
1790 __argp_fmtstream_putc (fs
, '\n');
1791 hol_help (hol
, state
, fs
);
1796 if (flags
& ARGP_HELP_POST_DOC
)
1797 /* Print any documentation strings at the end. */
1798 anything
|= argp_doc (argp
, state
, 1, anything
, 0, fs
);
1800 if ((flags
& ARGP_HELP_BUG_ADDR
) && argp_program_bug_address
)
1803 __argp_fmtstream_putc (fs
, '\n');
1804 __argp_fmtstream_printf (fs
, dgettext (argp
->argp_domain
,
1805 "Report bugs to %s.\n"),
1806 argp_program_bug_address
);
1810 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1811 __funlockfile (stream
);
1817 __argp_fmtstream_free (fs
);
1820 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1821 ARGP_HELP_*. NAME is what to use wherever a 'program name' is needed. */
1822 void __argp_help (const struct argp
*argp
, FILE *stream
,
1823 unsigned flags
, char *name
)
1825 _help (argp
, 0, stream
, flags
, name
);
1828 weak_alias (__argp_help
, argp_help
)
1831 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1833 __argp_short_program_name (void)
1835 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1836 char *name
= strrchr (program_invocation_name
, '/');
1837 return name
? name
+ 1 : program_invocation_name
;
1839 /* FIXME: What now? Miles suggests that it is better to use NULL,
1840 but currently the value is passed on directly to fputs_unlocked,
1841 so that requires more changes. */
1842 # if __GNUC__ || (__clang_major__ >= 4)
1843 # warning No reasonable value to return
1844 # endif /* __GNUC__ */
1850 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1851 from the set ARGP_HELP_*. */
1853 __argp_state_help (const struct argp_state
*state
, FILE *stream
, unsigned flags
)
1855 if ((!state
|| ! (state
->flags
& ARGP_NO_ERRS
)) && stream
)
1857 if (state
&& (state
->flags
& ARGP_LONG_ONLY
))
1858 flags
|= ARGP_HELP_LONG_ONLY
;
1860 _help (state
? state
->root_argp
: 0, state
, stream
, flags
,
1861 state
? state
->name
: __argp_short_program_name ());
1863 if (!state
|| ! (state
->flags
& ARGP_NO_EXIT
))
1865 if (flags
& ARGP_HELP_EXIT_ERR
)
1866 exit (argp_err_exit_status
);
1867 if (flags
& ARGP_HELP_EXIT_OK
)
1873 weak_alias (__argp_state_help
, argp_state_help
)
1876 /* If appropriate, print the printf string FMT and following args, preceded
1877 by the program name and ':', to stderr, and followed by a "Try ... --help"
1878 message, then exit (1). */
1880 __argp_error (const struct argp_state
*state
, const char *fmt
, ...)
1882 if (!state
|| !(state
->flags
& ARGP_NO_ERRS
))
1884 FILE *stream
= state
? state
->err_stream
: stderr
;
1890 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1891 __flockfile (stream
);
1899 if (_IO_vasprintf (&buf
, fmt
, ap
) < 0)
1902 __fxprintf (stream
, "%s: %s\n",
1903 state
? state
->name
: __argp_short_program_name (), buf
);
1907 fputs_unlocked (state
? state
->name
: __argp_short_program_name (),
1909 putc_unlocked (':', stream
);
1910 putc_unlocked (' ', stream
);
1912 vfprintf (stream
, fmt
, ap
);
1914 putc_unlocked ('\n', stream
);
1917 __argp_state_help (state
, stream
, ARGP_HELP_STD_ERR
);
1921 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1922 __funlockfile (stream
);
1928 weak_alias (__argp_error
, argp_error
)
1931 /* Similar to the standard gnu error-reporting function error(), but will
1932 respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1933 to STATE->err_stream. This is useful for argument parsing code that is
1934 shared between program startup (when exiting is desired) and runtime
1935 option parsing (when typically an error code is returned instead). The
1936 difference between this function and argp_error is that the latter is for
1937 *parsing errors*, and the former is for other problems that occur during
1938 parsing but don't reflect a (syntactic) problem with the input. */
1940 __argp_failure (const struct argp_state
*state
, int status
, int errnum
,
1941 const char *fmt
, ...)
1943 if (!state
|| !(state
->flags
& ARGP_NO_ERRS
))
1945 FILE *stream
= state
? state
->err_stream
: stderr
;
1949 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1950 __flockfile (stream
);
1954 __fxprintf (stream
, "%s",
1955 state
? state
->name
: __argp_short_program_name ());
1957 fputs_unlocked (state
? state
->name
: __argp_short_program_name (),
1969 if (_IO_vasprintf (&buf
, fmt
, ap
) < 0)
1972 __fxprintf (stream
, ": %s", buf
);
1976 putc_unlocked (':', stream
);
1977 putc_unlocked (' ', stream
);
1979 vfprintf (stream
, fmt
, ap
);
1990 __fxprintf (stream
, ": %s",
1991 __strerror_r (errnum
, buf
, sizeof (buf
)));
1993 char const *s
= NULL
;
1994 putc_unlocked (':', stream
);
1995 putc_unlocked (' ', stream
);
1996 # if GNULIB_STRERROR_R_POSIX || HAVE_DECL_STRERROR_R
1997 # if !GNULIB_STRERROR_R_POSIX && STRERROR_R_CHAR_P
1998 s
= __strerror_r (errnum
, buf
, sizeof buf
);
2000 if (__strerror_r (errnum
, buf
, sizeof buf
) == 0)
2004 if (! s
&& ! (s
= strerror (errnum
)))
2005 s
= dgettext (state
->root_argp
->argp_domain
,
2006 "Unknown system error");
2007 fputs_unlocked (s
, stream
);
2012 if (_IO_fwide (stream
, 0) > 0)
2013 putwc_unlocked (L
'\n', stream
);
2016 putc_unlocked ('\n', stream
);
2018 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
2019 __funlockfile (stream
);
2022 if (status
&& (!state
|| !(state
->flags
& ARGP_NO_EXIT
)))
2028 weak_alias (__argp_failure
, argp_failure
)