exp2l: Work around a NetBSD 10.0/i386 bug.
[gnulib.git] / lib / argp-help.c
blob9c7456642c7512cfe07d94ecce442d7d79544844
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/>. */
19 #ifndef _GNU_SOURCE
20 # define _GNU_SOURCE 1
21 #endif
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
27 #include <alloca.h>
28 #include <errno.h>
29 #include <stddef.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <ctype.h>
36 #include <limits.h>
37 #ifdef _LIBC
38 # include <../libio/libioP.h>
39 # include <wchar.h>
40 #endif
42 #ifdef _LIBC
43 # include <libintl.h>
44 # undef dgettext
45 # define dgettext(domain, msgid) \
46 __dcgettext (domain, msgid, LC_MESSAGES)
47 #else
48 # include "gettext.h"
49 #endif
51 #include "argp.h"
52 #include "argp-fmtstream.h"
53 #include "argp-namefrob.h"
55 #ifndef SIZE_MAX
56 # define SIZE_MAX ((size_t) -1)
57 #endif
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. */
81 struct uparams
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. */
88 int dup_args;
90 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
91 been suppressed, an explanatory message should be printed. */
92 int dup_args_note;
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. */
114 struct uparam_name
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]))
136 static void
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++)
143 if (up->is_bool
144 || up->uparams_offs == offsetof (struct uparams, rmargin))
145 continue;
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);
154 return;
157 uparams = *upptr;
158 uparams.valid = 1;
161 /* Read user options from the environment, and fill in UPARAMS appropriately. */
162 static void
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)
170 if (var)
172 /* Parse var. */
173 while (*var)
175 SKIPWS (var);
177 if (isalpha ((unsigned char) *var))
179 size_t var_len;
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 == '_')
185 arg++;
186 var_len = arg - var;
188 SKIPWS (arg);
190 if (*arg == '\0' || *arg == ',')
191 unspec = 1;
192 else if (*arg == '=')
194 arg++;
195 SKIPWS (arg);
198 if (unspec)
200 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
202 val = 0;
203 var += 3;
204 var_len -= 3;
206 else
207 val = 1;
209 else if (isdigit ((unsigned char) *arg))
211 val = atoi (arg);
212 while (isdigit ((unsigned char) *arg))
213 arg++;
214 SKIPWS (arg);
217 for (un = uparam_names;
218 un < uparam_names + nuparam_names;
219 un++)
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"),
229 (int) var_len, var);
230 else
231 *(int *)((char *)&new_params + un->uparams_offs) = val;
232 break;
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"),
239 (int) var_len, var);
241 var = arg;
242 if (*var == ',')
243 var++;
245 else if (*var)
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);
251 break;
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. */
344 static int
345 find_char (char ch, char *beg, char *end)
347 while (beg < end)
348 if (*beg == ch)
349 return 1;
350 else
351 beg++;
352 return 0;
355 /* -------------------------------------------------------------------------- */
356 /* Data structure: HOL = Help Option List */
358 struct hol_cluster; /* fwd decl */
360 struct hol_entry
362 /* First option. */
363 const struct argp_option *opt;
364 /* Number of options (including aliases). */
365 unsigned num;
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). */
373 char *short_options;
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. */
378 int group;
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 */
387 unsigned ord;
390 /* A cluster of entries to reflect the argp tree structure. */
391 struct hol_cluster
393 /* A descriptive header printed before options in this cluster. */
394 const char *header;
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
398 list. */
399 int index;
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). */
403 int group;
405 /* The cluster to which this cluster belongs, or NULL if it's at the base
406 level. */
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. */
413 int depth;
415 /* Clusters in a given hol are kept in a linked list, to make freeing them
416 possible. */
417 struct hol_cluster *next;
420 /* A list of options for help. */
421 struct hol
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. */
431 char *short_options;
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. */
439 static struct hol *
440 make_hol (const struct argp *argp, struct hol_cluster *cluster)
442 char *so;
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));
449 assert (hol);
451 hol->num_entries = 0;
452 hol->clusters = NULL;
454 if (opts)
456 int cur_group = 0;
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++)
464 if (! oalias (o))
465 hol->num_entries++;
466 if (oshort (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++)
481 entry->opt = o;
482 entry->num = 0;
483 entry->short_options = so;
484 entry->group = cur_group =
485 o->group
486 ? o->group
487 : ((!o->name && !o->key)
488 ? cur_group + 1
489 : cur_group);
490 entry->cluster = cluster;
491 entry->argp = argp;
495 entry->num++;
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.*/
498 *so++ = o->key;
499 o++;
501 while (! oend (o) && oalias (o));
503 *so = '\0'; /* null terminated so we can find the length */
506 return hol;
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));
517 if (cl)
519 cl->group = group;
520 cl->header = header;
522 cl->index = index;
523 cl->parent = parent;
524 cl->argp = argp;
525 cl->depth = parent ? parent->depth + 1 : 0;
527 cl->next = hol->clusters;
528 hol->clusters = cl;
530 return cl;
533 /* Free HOL and any resources it uses. */
534 static void
535 hol_free (struct hol *hol)
537 struct hol_cluster *cl = hol->clusters;
539 while (cl)
541 struct hol_cluster *next = cl->next;
542 free (cl);
543 cl = next;
546 if (hol->num_entries > 0)
548 free (hol->entries);
549 free (hol->short_options);
552 free (hol);
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. */
558 static int
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)
565 unsigned nopts;
566 int val = 0;
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)
573 if (!oalias (opt))
574 real = opt;
575 if (ovisible (opt))
576 val = (*func)(opt, real, domain, cookie);
577 so++;
580 return val;
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. */
586 static inline int
587 #if (__GNUC__ >= 3) || (__clang_major__ >= 4)
588 __attribute__ ((always_inline))
589 #endif
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)
596 unsigned nopts;
597 int val = 0;
598 const struct argp_option *opt, *real = entry->opt;
600 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
601 if (opt->name)
603 if (!oalias (opt))
604 real = opt;
605 if (ovisible (opt))
606 val = (*func)(opt, real, domain, cookie);
609 return val;
612 /* A filter that returns true for the first short option of a given ENTRY. */
613 static int
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. */
621 static char
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. */
629 static const char *
630 hol_entry_first_long (const struct hol_entry *entry)
632 const struct argp_option *opt;
633 unsigned num;
634 for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
635 if (opt->name && ovisible (opt))
636 return opt->name;
637 return NULL;
640 /* Returns the entry in HOL with the long option name NAME, or NULL if there is
641 none. */
642 static struct hol_entry *
643 hol_find_entry (struct hol *hol, const char *name)
645 unsigned num_entries = hol->num_entries;
647 if (num_entries > 0)
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)
658 return entry;
659 else
660 opt++;
662 entry++;
664 while (--num_entries > 0);
667 return NULL;
670 /* If an entry with the long option NAME occurs in HOL, set its special
671 sort position to GROUP. */
672 static void
673 hol_set_group (struct hol *hol, const char *name, int group)
675 struct hol_entry *entry = hol_find_entry (hol, name);
676 if (entry)
677 entry->group = group;
680 /* -------------------------------------------------------------------------- */
681 /* Sorting the entries in a HOL. */
683 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1. */
684 static int
685 group_cmp (int group1, int group2)
687 if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
688 return group1 - group2;
689 else
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. */
697 static int
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);
703 if (cmp != 0)
704 return cmp;
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. */
712 static int
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);
718 else
720 /* Compare the parent clusters first. */
721 int cmp = hol_cousin_cluster_cmp (cl1->parent, cl2->parent);
722 if (cmp != 0)
723 return cmp;
725 /* Next, compare by group. */
726 cmp = group_cmp (cl1->group, cl2->group);
727 if (cmp != 0)
728 return cmp;
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
736 output. */
737 static int
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)
746 cl1 = cl1->parent;
747 while (cl1->depth > cl2->depth);
748 int cmp = hol_cousin_cluster_cmp (cl1, cl2);
749 if (cmp != 0)
750 return cmp;
752 return 1;
754 else if (cl1->depth < cl2->depth)
757 cl2 = cl2->parent;
758 while (cl1->depth < cl2->depth);
759 int cmp = hol_cousin_cluster_cmp (cl1, cl2);
760 if (cmp != 0)
761 return cmp;
763 return -1;
765 else
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
770 of 0). */
771 static struct hol_cluster *
772 hol_cluster_base (struct hol_cluster *cl)
774 while (cl->parent)
775 cl = cl->parent;
776 return 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. */
782 static int
783 canon_doc_option (const char **name)
785 int non_opt;
786 /* Skip initial whitespace. */
787 while (isspace ((unsigned char) **name))
788 (*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))
793 (*name)++;
794 return non_opt;
797 /* Order ENTRY1 and ENTRY2 by the order which they should appear in a help
798 listing.
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. */
808 static int
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
814 resides. */
815 int group1 = (entry1->cluster
816 ? hol_cluster_base (entry1->cluster)->group
817 : entry1->group);
818 int group2 = (entry2->cluster
819 ? hol_cluster_base (entry2->cluster)->group
820 : entry2->group);
821 int cmp = group_cmp (group1, group2);
822 if (cmp != 0)
823 return cmp;
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);
829 if (cmp != 0)
830 return cmp;
832 /* Compare the clusters. */
833 if (entry1->cluster != NULL)
835 cmp = hol_cluster_cmp (entry1->cluster, entry2->cluster);
836 if (cmp != 0)
837 return cmp;
840 /* For entries in the same cluster, compare also the group numbers
841 within the cluster. */
842 cmp = group_cmp (entry1->group, entry2->group);
843 if (cmp != 0)
844 return cmp;
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);
852 int doc1 =
853 (odoc (entry1->opt) ? long1 != NULL && canon_doc_option (&long1) : 0);
854 int doc2 =
855 (odoc (entry2->opt) ? long2 != NULL && canon_doc_option (&long2) : 0);
856 cmp = doc1 - doc2;
857 if (cmp != 0)
858 return cmp;
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);
874 if (cmp != 0)
875 return cmp;
876 /* When the options start with the same letter (ignoring case), lower-case
877 comes first. */
878 cmp = first2 - first1;
879 if (cmp != 0)
880 return cmp;
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);
886 if (cmp != 0)
887 return cmp;
889 /* Compare entries without a short option by comparing the long option. */
890 if (short1 == 0)
892 cmp = (long1 != NULL) - (long2 != NULL);
893 if (cmp != 0)
894 return cmp;
896 if (long1 != NULL)
898 cmp = __strcasecmp (long1, long2);
899 if (cmp != 0)
900 return cmp;
904 /* We're out of comparison criteria. At this point, if ENTRY1 != ENTRY2,
905 the order of these entries will be unpredictable. */
906 return 0;
909 /* Variant of hol_entry_cmp with correct signature for qsort. */
910 static int
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. */
919 static void
920 hol_sort (struct hol *hol)
922 if (hol->num_entries > 0)
924 unsigned i;
925 struct hol_entry *e;
926 for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
927 e->ord = i;
929 qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
930 hol_entry_qcmp);
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. */
939 static void
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. */
945 while (*cl_end)
946 cl_end = &(*cl_end)->next;
947 *cl_end = more->clusters;
948 more->clusters = NULL;
950 /* Merge entries. */
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. */
960 else
961 /* Append the entries in MORE to those in HOL, taking care to only add
962 non-shadowed SHORT_OPTIONS values. */
964 unsigned left;
965 char *so, *more_so;
966 struct hol_entry *e;
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)),
980 more->entries,
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--)
987 e->short_options
988 = short_options + (e->short_options - hol->short_options);
990 /* Now add the short options from MORE, fixing up its entries
991 too. */
992 so = short_options + hol_so_len;
993 more_so = more->short_options;
994 for (left = more->num_entries; left > 0; e++, left--)
996 int opts_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--)
1003 int ch = *more_so;
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. */
1011 *so++ = ch;
1012 more_so++;
1017 *so = '\0';
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;
1028 hol_free (more);
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. */
1033 static struct hol *
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);
1038 if (child)
1039 while (child->argp)
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. */
1047 : cluster);
1048 hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1049 child++;
1051 return hol;
1054 /* -------------------------------------------------------------------------- */
1055 /* Printing the HOL. */
1057 /* Inserts enough spaces to make sure STREAM is at column COL. */
1058 static void
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. */
1068 static void
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');
1074 else
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. */
1081 static void
1082 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
1083 const char *domain, argp_fmtstream_t stream)
1085 if (real->arg)
1087 if (real->flags & OPTION_ARG_OPTIONAL)
1088 __argp_fmtstream_printf (stream, opt_fmt,
1089 dgettext (domain, real->arg));
1090 else
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. */
1106 int sep_groups;
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. */
1116 struct pentry_state
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. */
1123 int first;
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. */
1130 static const char *
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);
1140 else
1141 /* No filter. */
1142 return doc;
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
1149 to 0. */
1150 static void
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);
1157 if (fstr)
1159 if (*fstr)
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. */
1175 if (fstr != tstr)
1176 free ((char *) fstr);
1179 /* Return true if CL1 is a child of CL2. */
1180 static int
1181 hol_cluster_is_child (const struct hol_cluster *cl1,
1182 const struct hol_cluster *cl2)
1184 while (cl1 && cl1 != cl2)
1185 cl1 = cl1->parent;
1186 return 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
1192 clears FIRST. */
1193 static void
1194 comma (unsigned col, struct pentry_state *pest)
1196 if (pest->first)
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
1205 && (!pe
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);
1218 pest->first = 0;
1220 else
1221 __argp_fmtstream_puts (pest->stream, ", ");
1223 indent_to (pest->stream, col);
1226 /* Print help for ENTRY to STREAM. */
1227 static void
1228 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1229 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1231 unsigned num;
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 };
1242 if (! odoc (real))
1243 for (opt = real, num = entry->num; num > 0; opt++, num--)
1244 if (opt->name && ovisible (opt))
1246 have_long_opt = 1;
1247 break;
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. */
1256 if (ovisible (opt))
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,
1264 stream);
1265 else if (real->arg)
1266 hhstate->suppressed_dup_arg = 1;
1268 so++;
1271 /* Now, long options. */
1272 if (odoc (real))
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,
1286 opt->name));
1289 else
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);
1306 if (pest.first)
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);
1312 else
1313 /* Just a totally shadowed option or null header; print nothing. */
1314 goto cleanup; /* Just return, after cleaning up. */
1316 else
1318 const char *tstr = real->doc ? dgettext (state == NULL ? NULL
1319 : state->root_argp->argp_domain,
1320 real->doc) : NULL;
1321 const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1322 if (fstr && *fstr)
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, " ");
1333 else
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;
1348 cleanup:
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. */
1354 static void
1355 hol_help (struct hol *hol, const struct argp_state *state,
1356 argp_fmtstream_t stream)
1358 unsigned num;
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);
1373 if (fstr && *fstr)
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. */
1388 static int
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;
1397 return 0;
1400 /* If OPT is a short option with an arg, output a usage entry for it to the
1401 stream pointed at by COOKIE. */
1402 static int
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;
1411 if (! arg)
1412 arg = real->arg;
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);
1420 else
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);
1429 return 0;
1432 /* Output a usage entry for the long option opt to the stream pointed at by
1433 COOKIE. */
1434 static int
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;
1443 if (! arg)
1444 arg = real->arg;
1446 if (! (flags & OPTION_NO_USAGE))
1448 if (arg)
1450 arg = dgettext (domain, arg);
1451 if (flags & OPTION_ARG_OPTIONAL)
1452 __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1453 else
1454 __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1456 else
1457 __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1460 return 0;
1463 /* Print a short usage description for the arguments in HOL to STREAM. */
1464 static void
1465 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1467 if (hol->num_entries > 0)
1469 unsigned nentries;
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
1476 ; nentries > 0
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)
1482 *snao_end++ = '\0';
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
1488 ; nentries > 0
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
1495 ; nentries > 0
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
1503 ARGP. */
1504 static size_t
1505 argp_args_levels (const struct argp *argp)
1507 size_t levels = 0;
1508 const struct argp_child *child = argp->children;
1510 if (argp->args_doc && strchr (argp->args_doc, '\n'))
1511 levels++;
1513 if (child)
1514 while (child->argp)
1515 levels += argp_args_levels ((child++)->argp);
1517 return levels;
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. */
1525 static int
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;
1530 int multiple = 0;
1531 const struct argp_child *child = argp->children;
1532 const char *tdoc =
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;
1537 if (fdoc)
1539 const char *cp = fdoc;
1540 nl = __strchrnul (cp, '\n');
1541 if (*nl != '\0')
1542 /* This is a 'multi-level' args doc; advance to the correct position
1543 as determined by our state in LEVELS, and update LEVELS. */
1545 int i;
1546 multiple = 1;
1547 for (i = 0; i < *our_level; i++)
1548 cp = nl + 1, nl = __strchrnul (cp, '\n');
1549 (*levels)++;
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. */
1561 if (child)
1562 while (child->argp)
1563 advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1565 if (advance && multiple)
1567 /* Need to increment our level. */
1568 if (*nl)
1569 /* There's more we can do here. */
1571 (*our_level)++;
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. */
1576 *our_level = 0;
1579 return !advance;
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. */
1589 static int
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)
1594 const char *text;
1595 const char *inp_text;
1596 void *input = NULL;
1597 int anything = 0;
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;
1602 if (doc)
1604 char *vt = strchr (doc, '\v');
1605 inp_text = post ? (vt ? vt + 1 : 0) : doc;
1606 inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1608 else
1609 inp_text = 0;
1611 if (argp->help_filter)
1612 /* We have to filter the doc strings. */
1614 if (inp_text_limit)
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);
1618 text =
1619 (*argp->help_filter) (post
1620 ? ARGP_KEY_HELP_POST_DOC
1621 : ARGP_KEY_HELP_PRE_DOC,
1622 inp_text, input);
1624 else
1625 text = (const char *) inp_text;
1627 if (text)
1629 if (pre_blank)
1630 __argp_fmtstream_putc (stream, '\n');
1632 if (text == inp_text && inp_text_limit)
1633 __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1634 else
1635 __argp_fmtstream_puts (stream, text);
1637 if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1638 __argp_fmtstream_putc (stream, '\n');
1640 anything = 1;
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);
1652 if (text)
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');
1661 anything = 1;
1665 if (child)
1666 while (child->argp && !(first_only && anything))
1667 anything |=
1668 argp_doc ((child++)->argp, state,
1669 post, anything || pre_blank, first_only,
1670 stream);
1672 return anything;
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
1678 needed. */
1679 static void
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;
1687 if (! stream)
1688 return;
1690 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1691 __flockfile (stream);
1692 #endif
1694 if (! uparams.valid)
1695 fill_in_uparams (state);
1697 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1698 if (! fs)
1700 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1701 __funlockfile (stream);
1702 #endif
1703 return;
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);
1714 hol_sort (hol);
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);
1728 int old_lm;
1729 int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1730 char *levels = pattern_levels;
1732 if (first_pattern)
1733 __argp_fmtstream_printf (fs, "%s %s",
1734 dgettext (argp->argp_domain, "Usage:"),
1735 name);
1736 else
1737 __argp_fmtstream_printf (fs, "%s %s",
1738 dgettext (argp->argp_domain, " or: "),
1739 name);
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,
1750 " [OPTION...]"));
1752 else
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');
1765 anything = 1;
1767 first_pattern = 0;
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"),
1779 name, name);
1780 anything = 1;
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)
1789 if (anything)
1790 __argp_fmtstream_putc (fs, '\n');
1791 hol_help (hol, state, fs);
1792 anything = 1;
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)
1802 if (anything)
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);
1807 anything = 1;
1810 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1811 __funlockfile (stream);
1812 #endif
1814 if (hol)
1815 hol_free (hol);
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);
1827 #ifdef weak_alias
1828 weak_alias (__argp_help, argp_help)
1829 #endif
1831 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1832 char *
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;
1838 # else
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__ */
1845 return "";
1846 # endif
1848 #endif
1850 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1851 from the set ARGP_HELP_*. */
1852 void
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)
1868 exit (0);
1872 #ifdef weak_alias
1873 weak_alias (__argp_state_help, argp_state_help)
1874 #endif
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). */
1879 void
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;
1886 if (stream)
1888 va_list ap;
1890 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1891 __flockfile (stream);
1892 #endif
1894 va_start (ap, fmt);
1896 #ifdef _LIBC
1897 char *buf;
1899 if (_IO_vasprintf (&buf, fmt, ap) < 0)
1900 buf = NULL;
1902 __fxprintf (stream, "%s: %s\n",
1903 state ? state->name : __argp_short_program_name (), buf);
1905 free (buf);
1906 #else
1907 fputs_unlocked (state ? state->name : __argp_short_program_name (),
1908 stream);
1909 putc_unlocked (':', stream);
1910 putc_unlocked (' ', stream);
1912 vfprintf (stream, fmt, ap);
1914 putc_unlocked ('\n', stream);
1915 #endif
1917 __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1919 va_end (ap);
1921 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1922 __funlockfile (stream);
1923 #endif
1927 #ifdef weak_alias
1928 weak_alias (__argp_error, argp_error)
1929 #endif
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. */
1939 void
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;
1947 if (stream)
1949 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1950 __flockfile (stream);
1951 #endif
1953 #ifdef _LIBC
1954 __fxprintf (stream, "%s",
1955 state ? state->name : __argp_short_program_name ());
1956 #else
1957 fputs_unlocked (state ? state->name : __argp_short_program_name (),
1958 stream);
1959 #endif
1961 if (fmt)
1963 va_list ap;
1965 va_start (ap, fmt);
1966 #ifdef _LIBC
1967 char *buf;
1969 if (_IO_vasprintf (&buf, fmt, ap) < 0)
1970 buf = NULL;
1972 __fxprintf (stream, ": %s", buf);
1974 free (buf);
1975 #else
1976 putc_unlocked (':', stream);
1977 putc_unlocked (' ', stream);
1979 vfprintf (stream, fmt, ap);
1980 #endif
1982 va_end (ap);
1985 if (errnum)
1987 char buf[200];
1989 #ifdef _LIBC
1990 __fxprintf (stream, ": %s",
1991 __strerror_r (errnum, buf, sizeof (buf)));
1992 #else
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);
1999 # else
2000 if (__strerror_r (errnum, buf, sizeof buf) == 0)
2001 s = buf;
2002 # endif
2003 # endif
2004 if (! s && ! (s = strerror (errnum)))
2005 s = dgettext (state->root_argp->argp_domain,
2006 "Unknown system error");
2007 fputs_unlocked (s, stream);
2008 #endif
2011 #if _LIBC
2012 if (_IO_fwide (stream, 0) > 0)
2013 putwc_unlocked (L'\n', stream);
2014 else
2015 #endif
2016 putc_unlocked ('\n', stream);
2018 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
2019 __funlockfile (stream);
2020 #endif
2022 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
2023 exit (status);
2027 #ifdef weak_alias
2028 weak_alias (__argp_failure, argp_failure)
2029 #endif