(BODY): Remove cast used as lvalue.
[glibc.git] / argp / argp-help.c
blobb7e088ef100bcae1913ee5328eb9492a8dc26e40
1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995-2000, 2001, 2002, 2003 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 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library 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 GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE 1
23 #endif
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
29 /* AIX requires this to be the first thing in the file. */
30 #ifndef __GNUC__
31 # if HAVE_ALLOCA_H || defined _LIBC
32 # include <alloca.h>
33 # else
34 # ifdef _AIX
35 #pragma alloca
36 # else
37 # ifndef alloca /* predefined by HP cc +Olibcalls */
38 char *alloca ();
39 # endif
40 # endif
41 # endif
42 #endif
44 #include <stddef.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <assert.h>
48 #include <stdarg.h>
49 #include <ctype.h>
50 #ifdef USE_IN_LIBIO
51 # include <wchar.h>
52 #endif
54 #ifndef _
55 /* This is for other GNU distributions with internationalized messages. */
56 # if defined HAVE_LIBINTL_H || defined _LIBC
57 # include <libintl.h>
58 # ifdef _LIBC
59 # undef dgettext
60 # define dgettext(domain, msgid) \
61 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
62 # endif
63 # else
64 # define dgettext(domain, msgid) (msgid)
65 # endif
66 #endif
68 #ifndef _LIBC
69 # if HAVE_STRERROR_R
70 # if !HAVE_DECL_STRERROR_R
71 char *strerror_r (int errnum, char *buf, size_t buflen);
72 # endif
73 # else
74 # if !HAVE_DECL_STRERROR
75 char *strerror (int errnum);
76 # endif
77 # endif
78 #endif
80 #include "argp.h"
81 #include "argp-fmtstream.h"
82 #include "argp-namefrob.h"
84 #ifndef SIZE_MAX
85 # define SIZE_MAX ((size_t) -1)
86 #endif
88 /* User-selectable (using an environment variable) formatting parameters.
90 These may be specified in an environment variable called `ARGP_HELP_FMT',
91 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
92 Where VALn must be a positive integer. The list of variables is in the
93 UPARAM_NAMES vector, below. */
95 /* Default parameters. */
96 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
97 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
98 #define SHORT_OPT_COL 2 /* column in which short options start */
99 #define LONG_OPT_COL 6 /* column in which long options start */
100 #define DOC_OPT_COL 2 /* column in which doc options start */
101 #define OPT_DOC_COL 29 /* column in which option text starts */
102 #define HEADER_COL 1 /* column in which group headers are printed */
103 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
104 #define RMARGIN 79 /* right margin used for wrapping */
106 /* User-selectable (using an environment variable) formatting parameters.
107 They must all be of type `int' for the parsing code to work. */
108 struct uparams
110 /* If true, arguments for an option are shown with both short and long
111 options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
112 If false, then if an option has both, the argument is only shown with
113 the long one, e.g., `-x, --longx=ARG', and a message indicating that
114 this really means both is printed below the options. */
115 int dup_args;
117 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
118 been suppressed, an explanatory message should be printed. */
119 int dup_args_note;
121 /* Various output columns. */
122 int short_opt_col;
123 int long_opt_col;
124 int doc_opt_col;
125 int opt_doc_col;
126 int header_col;
127 int usage_indent;
128 int rmargin;
130 int valid; /* True when the values in here are valid. */
133 /* This is a global variable, as user options are only ever read once. */
134 static struct uparams uparams = {
135 DUP_ARGS, DUP_ARGS_NOTE,
136 SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
137 USAGE_INDENT, RMARGIN,
141 /* A particular uparam, and what the user name is. */
142 struct uparam_name
144 const char *name; /* User name. */
145 int is_bool; /* Whether it's `boolean'. */
146 size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
149 /* The name-field mappings we know about. */
150 static const struct uparam_name uparam_names[] =
152 { "dup-args", 1, offsetof (struct uparams, dup_args) },
153 { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
154 { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
155 { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
156 { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
157 { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
158 { "header-col", 0, offsetof (struct uparams, header_col) },
159 { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
160 { "rmargin", 0, offsetof (struct uparams, rmargin) },
161 { 0 }
164 /* Read user options from the environment, and fill in UPARAMS appropiately. */
165 static void
166 fill_in_uparams (const struct argp_state *state)
168 const char *var = getenv ("ARGP_HELP_FMT");
170 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
172 if (var)
173 /* Parse var. */
174 while (*var)
176 SKIPWS (var);
178 if (isalpha (*var))
180 size_t var_len;
181 const struct uparam_name *un;
182 int unspec = 0, val = 0;
183 const char *arg = var;
185 while (isalnum (*arg) || *arg == '-' || *arg == '_')
186 arg++;
187 var_len = arg - var;
189 SKIPWS (arg);
191 if (*arg == '\0' || *arg == ',')
192 unspec = 1;
193 else if (*arg == '=')
195 arg++;
196 SKIPWS (arg);
199 if (unspec)
201 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
203 val = 0;
204 var += 3;
205 var_len -= 3;
207 else
208 val = 1;
210 else if (isdigit (*arg))
212 val = atoi (arg);
213 while (isdigit (*arg))
214 arg++;
215 SKIPWS (arg);
218 for (un = uparam_names; un->name; un++)
219 if (strlen (un->name) == var_len
220 && strncmp (var, un->name, var_len) == 0)
222 if (unspec && !un->is_bool)
223 __argp_failure (state, 0, 0,
224 dgettext (state->root_argp->argp_domain, "\
225 %.*s: ARGP_HELP_FMT parameter requires a value"),
226 (int) var_len, var);
227 else
228 *(int *)((char *)&uparams + un->uparams_offs) = val;
229 break;
231 if (! un->name)
232 __argp_failure (state, 0, 0,
233 dgettext (state->root_argp->argp_domain, "\
234 %.*s: Unknown ARGP_HELP_FMT parameter"),
235 (int) var_len, var);
237 var = arg;
238 if (*var == ',')
239 var++;
241 else if (*var)
243 __argp_failure (state, 0, 0,
244 dgettext (state->root_argp->argp_domain,
245 "Garbage in ARGP_HELP_FMT: %s"), var);
246 break;
251 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
252 whether OPT is displayed or used in sorting, not option shadowing. */
253 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
255 /* Returns true if OPT is an alias for an earlier option. */
256 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
258 /* Returns true if OPT is an documentation-only entry. */
259 #define odoc(opt) ((opt)->flags & OPTION_DOC)
261 /* Returns true if OPT is the end-of-list marker for a list of options. */
262 #define oend(opt) __option_is_end (opt)
264 /* Returns true if OPT has a short option. */
265 #define oshort(opt) __option_is_short (opt)
268 The help format for a particular option is like:
270 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
272 Where ARG will be omitted if there's no argument, for this option, or
273 will be surrounded by "[" and "]" appropiately if the argument is
274 optional. The documentation string is word-wrapped appropiately, and if
275 the list of options is long enough, it will be started on a separate line.
276 If there are no short options for a given option, the first long option is
277 indented slighly in a way that's supposed to make most long options appear
278 to be in a separate column.
280 For example, the following output (from ps):
282 -p PID, --pid=PID List the process PID
283 --pgrp=PGRP List processes in the process group PGRP
284 -P, -x, --no-parent Include processes without parents
285 -Q, --all-fields Don't elide unusable fields (normally if there's
286 some reason ps can't print a field for any
287 process, it's removed from the output entirely)
288 -r, --reverse, --gratuitously-long-reverse-option
289 Reverse the order of any sort
290 --session[=SID] Add the processes from the session SID (which
291 defaults to the sid of the current process)
293 Here are some more options:
294 -f ZOT, --foonly=ZOT Glork a foonly
295 -z, --zaza Snit a zar
297 -?, --help Give this help list
298 --usage Give a short usage message
299 -V, --version Print program version
301 The struct argp_option array for the above could look like:
304 {"pid", 'p', "PID", 0, "List the process PID"},
305 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
306 {"no-parent", 'P', 0, 0, "Include processes without parents"},
307 {0, 'x', 0, OPTION_ALIAS},
308 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
309 " if there's some reason ps can't"
310 " print a field for any process, it's"
311 " removed from the output entirely)" },
312 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
313 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
314 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
315 "Add the processes from the session"
316 " SID (which defaults to the sid of"
317 " the current process)" },
319 {0,0,0,0, "Here are some more options:"},
320 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
321 {"zaza", 'z', 0, 0, "Snit a zar"},
326 Note that the last three options are automatically supplied by argp_parse,
327 unless you tell it not to with ARGP_NO_HELP.
331 /* Returns true if CH occurs between BEG and END. */
332 static int
333 find_char (char ch, char *beg, char *end)
335 while (beg < end)
336 if (*beg == ch)
337 return 1;
338 else
339 beg++;
340 return 0;
343 struct hol_cluster; /* fwd decl */
345 struct hol_entry
347 /* First option. */
348 const struct argp_option *opt;
349 /* Number of options (including aliases). */
350 unsigned num;
352 /* A pointers into the HOL's short_options field, to the first short option
353 letter for this entry. The order of the characters following this point
354 corresponds to the order of options pointed to by OPT, and there are at
355 most NUM. A short option recorded in a option following OPT is only
356 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
357 probably been shadowed by some other entry). */
358 char *short_options;
360 /* Entries are sorted by their group first, in the order:
361 1, 2, ..., n, 0, -m, ..., -2, -1
362 and then alphabetically within each group. The default is 0. */
363 int group;
365 /* The cluster of options this entry belongs to, or 0 if none. */
366 struct hol_cluster *cluster;
368 /* The argp from which this option came. */
369 const struct argp *argp;
372 /* A cluster of entries to reflect the argp tree structure. */
373 struct hol_cluster
375 /* A descriptive header printed before options in this cluster. */
376 const char *header;
378 /* Used to order clusters within the same group with the same parent,
379 according to the order in which they occurred in the parent argp's child
380 list. */
381 int index;
383 /* How to sort this cluster with respect to options and other clusters at the
384 same depth (clusters always follow options in the same group). */
385 int group;
387 /* The cluster to which this cluster belongs, or 0 if it's at the base
388 level. */
389 struct hol_cluster *parent;
391 /* The argp from which this cluster is (eventually) derived. */
392 const struct argp *argp;
394 /* The distance this cluster is from the root. */
395 int depth;
397 /* Clusters in a given hol are kept in a linked list, to make freeing them
398 possible. */
399 struct hol_cluster *next;
402 /* A list of options for help. */
403 struct hol
405 /* An array of hol_entry's. */
406 struct hol_entry *entries;
407 /* The number of entries in this hol. If this field is zero, the others
408 are undefined. */
409 unsigned num_entries;
411 /* A string containing all short options in this HOL. Each entry contains
412 pointers into this string, so the order can't be messed with blindly. */
413 char *short_options;
415 /* Clusters of entries in this hol. */
416 struct hol_cluster *clusters;
419 /* Create a struct hol from the options in ARGP. CLUSTER is the
420 hol_cluster in which these entries occur, or 0, if at the root. */
421 static struct hol *
422 make_hol (const struct argp *argp, struct hol_cluster *cluster)
424 char *so;
425 const struct argp_option *o;
426 const struct argp_option *opts = argp->options;
427 struct hol_entry *entry;
428 unsigned num_short_options = 0;
429 struct hol *hol = malloc (sizeof (struct hol));
431 assert (hol);
433 hol->num_entries = 0;
434 hol->clusters = 0;
436 if (opts)
438 int cur_group = 0;
440 /* The first option must not be an alias. */
441 assert (! oalias (opts));
443 /* Calculate the space needed. */
444 for (o = opts; ! oend (o); o++)
446 if (! oalias (o))
447 hol->num_entries++;
448 if (oshort (o))
449 num_short_options++; /* This is an upper bound. */
452 hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
453 hol->short_options = malloc (num_short_options + 1);
455 assert (hol->entries && hol->short_options
456 && hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
458 /* Fill in the entries. */
459 so = hol->short_options;
460 for (o = opts, entry = hol->entries; ! oend (o); entry++)
462 entry->opt = o;
463 entry->num = 0;
464 entry->short_options = so;
465 entry->group = cur_group =
466 o->group
467 ? o->group
468 : ((!o->name && !o->key)
469 ? cur_group + 1
470 : cur_group);
471 entry->cluster = cluster;
472 entry->argp = argp;
476 entry->num++;
477 if (oshort (o) && ! find_char (o->key, hol->short_options, so))
478 /* O has a valid short option which hasn't already been used.*/
479 *so++ = o->key;
480 o++;
482 while (! oend (o) && oalias (o));
484 *so = '\0'; /* null terminated so we can find the length */
487 return hol;
490 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
491 associated argp child list entry), INDEX, and PARENT, and return a pointer
492 to it. ARGP is the argp that this cluster results from. */
493 static struct hol_cluster *
494 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
495 struct hol_cluster *parent, const struct argp *argp)
497 struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
498 if (cl)
500 cl->group = group;
501 cl->header = header;
503 cl->index = index;
504 cl->parent = parent;
505 cl->argp = argp;
506 cl->depth = parent ? parent->depth + 1 : 0;
508 cl->next = hol->clusters;
509 hol->clusters = cl;
511 return cl;
514 /* Free HOL and any resources it uses. */
515 static void
516 hol_free (struct hol *hol)
518 struct hol_cluster *cl = hol->clusters;
520 while (cl)
522 struct hol_cluster *next = cl->next;
523 free (cl);
524 cl = next;
527 if (hol->num_entries > 0)
529 free (hol->entries);
530 free (hol->short_options);
533 free (hol);
536 static int
537 hol_entry_short_iterate (const struct hol_entry *entry,
538 int (*func)(const struct argp_option *opt,
539 const struct argp_option *real,
540 const char *domain, void *cookie),
541 const char *domain, void *cookie)
543 unsigned nopts;
544 int val = 0;
545 const struct argp_option *opt, *real = entry->opt;
546 char *so = entry->short_options;
548 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
549 if (oshort (opt) && *so == opt->key)
551 if (!oalias (opt))
552 real = opt;
553 if (ovisible (opt))
554 val = (*func)(opt, real, domain, cookie);
555 so++;
558 return val;
561 static inline int
562 __attribute__ ((always_inline))
563 hol_entry_long_iterate (const struct hol_entry *entry,
564 int (*func)(const struct argp_option *opt,
565 const struct argp_option *real,
566 const char *domain, void *cookie),
567 const char *domain, void *cookie)
569 unsigned nopts;
570 int val = 0;
571 const struct argp_option *opt, *real = entry->opt;
573 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
574 if (opt->name)
576 if (!oalias (opt))
577 real = opt;
578 if (ovisible (opt))
579 val = (*func)(opt, real, domain, cookie);
582 return val;
585 /* Iterator that returns true for the first short option. */
586 static inline int
587 until_short (const struct argp_option *opt, const struct argp_option *real,
588 const char *domain, void *cookie)
590 return oshort (opt) ? opt->key : 0;
593 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
594 static char
595 hol_entry_first_short (const struct hol_entry *entry)
597 return hol_entry_short_iterate (entry, until_short,
598 entry->argp->argp_domain, 0);
601 /* Returns the first valid long option in ENTRY, or 0 if there is none. */
602 static const char *
603 hol_entry_first_long (const struct hol_entry *entry)
605 const struct argp_option *opt;
606 unsigned num;
607 for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
608 if (opt->name && ovisible (opt))
609 return opt->name;
610 return 0;
613 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
614 none. */
615 static struct hol_entry *
616 hol_find_entry (struct hol *hol, const char *name)
618 struct hol_entry *entry = hol->entries;
619 unsigned num_entries = hol->num_entries;
621 while (num_entries-- > 0)
623 const struct argp_option *opt = entry->opt;
624 unsigned num_opts = entry->num;
626 while (num_opts-- > 0)
627 if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
628 return entry;
629 else
630 opt++;
632 entry++;
635 return 0;
638 /* If an entry with the long option NAME occurs in HOL, set it's special
639 sort position to GROUP. */
640 static void
641 hol_set_group (struct hol *hol, const char *name, int group)
643 struct hol_entry *entry = hol_find_entry (hol, name);
644 if (entry)
645 entry->group = group;
648 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
649 EQ is what to return if GROUP1 and GROUP2 are the same. */
650 static int
651 group_cmp (int group1, int group2, int eq)
653 if (group1 == group2)
654 return eq;
655 else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
656 return group1 - group2;
657 else
658 return group2 - group1;
661 /* Compare clusters CL1 & CL2 by the order that they should appear in
662 output. */
663 static int
664 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
666 /* If one cluster is deeper than the other, use its ancestor at the same
667 level, so that finding the common ancestor is straightforward. */
668 while (cl1->depth < cl2->depth)
669 cl1 = cl1->parent;
670 while (cl2->depth < cl1->depth)
671 cl2 = cl2->parent;
673 /* Now reduce both clusters to their ancestors at the point where both have
674 a common parent; these can be directly compared. */
675 while (cl1->parent != cl2->parent)
676 cl1 = cl1->parent, cl2 = cl2->parent;
678 return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
681 /* Return the ancestor of CL that's just below the root (i.e., has a parent
682 of 0). */
683 static struct hol_cluster *
684 hol_cluster_base (struct hol_cluster *cl)
686 while (cl->parent)
687 cl = cl->parent;
688 return cl;
691 /* Return true if CL1 is a child of CL2. */
692 static int
693 hol_cluster_is_child (const struct hol_cluster *cl1,
694 const struct hol_cluster *cl2)
696 while (cl1 && cl1 != cl2)
697 cl1 = cl1->parent;
698 return cl1 == cl2;
701 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
702 that should be used for comparisons, and returns true iff it should be
703 treated as a non-option. */
704 static int
705 canon_doc_option (const char **name)
707 int non_opt;
708 /* Skip initial whitespace. */
709 while (isspace (**name))
710 (*name)++;
711 /* Decide whether this looks like an option (leading `-') or not. */
712 non_opt = (**name != '-');
713 /* Skip until part of name used for sorting. */
714 while (**name && !isalnum (**name))
715 (*name)++;
716 return non_opt;
719 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
720 listing. */
721 static int
722 hol_entry_cmp (const struct hol_entry *entry1,
723 const struct hol_entry *entry2)
725 /* The group numbers by which the entries should be ordered; if either is
726 in a cluster, then this is just the group within the cluster. */
727 int group1 = entry1->group, group2 = entry2->group;
729 if (entry1->cluster != entry2->cluster)
731 /* The entries are not within the same cluster, so we can't compare them
732 directly, we have to use the appropiate clustering level too. */
733 if (! entry1->cluster)
734 /* ENTRY1 is at the `base level', not in a cluster, so we have to
735 compare it's group number with that of the base cluster in which
736 ENTRY2 resides. Note that if they're in the same group, the
737 clustered option always comes laster. */
738 return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
739 else if (! entry2->cluster)
740 /* Likewise, but ENTRY2's not in a cluster. */
741 return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
742 else
743 /* Both entries are in clusters, we can just compare the clusters. */
744 return hol_cluster_cmp (entry1->cluster, entry2->cluster);
746 else if (group1 == group2)
747 /* The entries are both in the same cluster and group, so compare them
748 alphabetically. */
750 int short1 = hol_entry_first_short (entry1);
751 int short2 = hol_entry_first_short (entry2);
752 int doc1 = odoc (entry1->opt);
753 int doc2 = odoc (entry2->opt);
754 const char *long1 = hol_entry_first_long (entry1);
755 const char *long2 = hol_entry_first_long (entry2);
757 if (doc1)
758 doc1 = canon_doc_option (&long1);
759 if (doc2)
760 doc2 = canon_doc_option (&long2);
762 if (doc1 != doc2)
763 /* `documentation' options always follow normal options (or
764 documentation options that *look* like normal options). */
765 return doc1 - doc2;
766 else if (!short1 && !short2 && long1 && long2)
767 /* Only long options. */
768 return __strcasecmp (long1, long2);
769 else
770 /* Compare short/short, long/short, short/long, using the first
771 character of long options. Entries without *any* valid
772 options (such as options with OPTION_HIDDEN set) will be put
773 first, but as they're not displayed, it doesn't matter where
774 they are. */
776 char first1 = short1 ? short1 : long1 ? *long1 : 0;
777 char first2 = short2 ? short2 : long2 ? *long2 : 0;
778 #ifdef _tolower
779 int lower_cmp = _tolower (first1) - _tolower (first2);
780 #else
781 int lower_cmp = tolower (first1) - tolower (first2);
782 #endif
783 /* Compare ignoring case, except when the options are both the
784 same letter, in which case lower-case always comes first. */
785 return lower_cmp ? lower_cmp : first2 - first1;
788 else
789 /* Within the same cluster, but not the same group, so just compare
790 groups. */
791 return group_cmp (group1, group2, 0);
794 /* Version of hol_entry_cmp with correct signature for qsort. */
795 static int
796 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
798 return hol_entry_cmp (entry1_v, entry2_v);
801 /* Sort HOL by group and alphabetically by option name (with short options
802 taking precedence over long). Since the sorting is for display purposes
803 only, the shadowing of options isn't effected. */
804 static void
805 hol_sort (struct hol *hol)
807 if (hol->num_entries > 0)
808 qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
809 hol_entry_qcmp);
812 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
813 any in MORE with the same name. */
814 static void
815 hol_append (struct hol *hol, struct hol *more)
817 struct hol_cluster **cl_end = &hol->clusters;
819 /* Steal MORE's cluster list, and add it to the end of HOL's. */
820 while (*cl_end)
821 cl_end = &(*cl_end)->next;
822 *cl_end = more->clusters;
823 more->clusters = 0;
825 /* Merge entries. */
826 if (more->num_entries > 0)
828 if (hol->num_entries == 0)
830 hol->num_entries = more->num_entries;
831 hol->entries = more->entries;
832 hol->short_options = more->short_options;
833 more->num_entries = 0; /* Mark MORE's fields as invalid. */
835 else
836 /* Append the entries in MORE to those in HOL, taking care to only add
837 non-shadowed SHORT_OPTIONS values. */
839 unsigned left;
840 char *so, *more_so;
841 struct hol_entry *e;
842 unsigned num_entries = hol->num_entries + more->num_entries;
843 struct hol_entry *entries =
844 malloc (num_entries * sizeof (struct hol_entry));
845 unsigned hol_so_len = strlen (hol->short_options);
846 char *short_options =
847 malloc (hol_so_len + strlen (more->short_options) + 1);
849 assert (entries && short_options
850 && num_entries <= SIZE_MAX / sizeof (struct hol_entry));
852 __mempcpy (__mempcpy (entries, hol->entries,
853 hol->num_entries * sizeof (struct hol_entry)),
854 more->entries,
855 more->num_entries * sizeof (struct hol_entry));
857 __mempcpy (short_options, hol->short_options, hol_so_len);
859 /* Fix up the short options pointers from HOL. */
860 for (e = entries, left = hol->num_entries; left > 0; e++, left--)
861 e->short_options += (short_options - hol->short_options);
863 /* Now add the short options from MORE, fixing up its entries
864 too. */
865 so = short_options + hol_so_len;
866 more_so = more->short_options;
867 for (left = more->num_entries; left > 0; e++, left--)
869 int opts_left;
870 const struct argp_option *opt;
872 e->short_options = so;
874 for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
876 int ch = *more_so;
877 if (oshort (opt) && ch == opt->key)
878 /* The next short option in MORE_SO, CH, is from OPT. */
880 if (! find_char (ch, short_options,
881 short_options + hol_so_len))
882 /* The short option CH isn't shadowed by HOL's options,
883 so add it to the sum. */
884 *so++ = ch;
885 more_so++;
890 *so = '\0';
892 free (hol->entries);
893 free (hol->short_options);
895 hol->entries = entries;
896 hol->num_entries = num_entries;
897 hol->short_options = short_options;
901 hol_free (more);
904 /* Inserts enough spaces to make sure STREAM is at column COL. */
905 static void
906 indent_to (argp_fmtstream_t stream, unsigned col)
908 int needed = col - __argp_fmtstream_point (stream);
909 while (needed-- > 0)
910 __argp_fmtstream_putc (stream, ' ');
913 /* Output to STREAM either a space, or a newline if there isn't room for at
914 least ENSURE characters before the right margin. */
915 static void
916 space (argp_fmtstream_t stream, size_t ensure)
918 if (__argp_fmtstream_point (stream) + ensure
919 >= __argp_fmtstream_rmargin (stream))
920 __argp_fmtstream_putc (stream, '\n');
921 else
922 __argp_fmtstream_putc (stream, ' ');
925 /* If the option REAL has an argument, we print it in using the printf
926 format REQ_FMT or OPT_FMT depending on whether it's a required or
927 optional argument. */
928 static void
929 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
930 const char *domain, argp_fmtstream_t stream)
932 if (real->arg)
934 if (real->flags & OPTION_ARG_OPTIONAL)
935 __argp_fmtstream_printf (stream, opt_fmt,
936 dgettext (domain, real->arg));
937 else
938 __argp_fmtstream_printf (stream, req_fmt,
939 dgettext (domain, real->arg));
943 /* Helper functions for hol_entry_help. */
945 /* State used during the execution of hol_help. */
946 struct hol_help_state
948 /* PREV_ENTRY should contain the previous entry printed, or 0. */
949 struct hol_entry *prev_entry;
951 /* If an entry is in a different group from the previous one, and SEP_GROUPS
952 is true, then a blank line will be printed before any output. */
953 int sep_groups;
955 /* True if a duplicate option argument was suppressed (only ever set if
956 UPARAMS.dup_args is false). */
957 int suppressed_dup_arg;
960 /* Some state used while printing a help entry (used to communicate with
961 helper functions). See the doc for hol_entry_help for more info, as most
962 of the fields are copied from its arguments. */
963 struct pentry_state
965 const struct hol_entry *entry;
966 argp_fmtstream_t stream;
967 struct hol_help_state *hhstate;
969 /* True if nothing's been printed so far. */
970 int first;
972 /* If non-zero, the state that was used to print this help. */
973 const struct argp_state *state;
976 /* If a user doc filter should be applied to DOC, do so. */
977 static const char *
978 filter_doc (const char *doc, int key, const struct argp *argp,
979 const struct argp_state *state)
981 if (argp->help_filter)
982 /* We must apply a user filter to this output. */
984 void *input = __argp_input (argp, state);
985 return (*argp->help_filter) (key, doc, input);
987 else
988 /* No filter. */
989 return doc;
992 /* Prints STR as a header line, with the margin lines set appropiately, and
993 notes the fact that groups should be separated with a blank line. ARGP is
994 the argp that should dictate any user doc filtering to take place. Note
995 that the previous wrap margin isn't restored, but the left margin is reset
996 to 0. */
997 static void
998 print_header (const char *str, const struct argp *argp,
999 struct pentry_state *pest)
1001 const char *tstr = dgettext (argp->argp_domain, str);
1002 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
1004 if (fstr)
1006 if (*fstr)
1008 if (pest->hhstate->prev_entry)
1009 /* Precede with a blank line. */
1010 __argp_fmtstream_putc (pest->stream, '\n');
1011 indent_to (pest->stream, uparams.header_col);
1012 __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
1013 __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
1014 __argp_fmtstream_puts (pest->stream, fstr);
1015 __argp_fmtstream_set_lmargin (pest->stream, 0);
1016 __argp_fmtstream_putc (pest->stream, '\n');
1019 pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
1022 if (fstr != tstr)
1023 free ((char *) fstr);
1026 /* Inserts a comma if this isn't the first item on the line, and then makes
1027 sure we're at least to column COL. If this *is* the first item on a line,
1028 prints any pending whitespace/headers that should precede this line. Also
1029 clears FIRST. */
1030 static void
1031 comma (unsigned col, struct pentry_state *pest)
1033 if (pest->first)
1035 const struct hol_entry *pe = pest->hhstate->prev_entry;
1036 const struct hol_cluster *cl = pest->entry->cluster;
1038 if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1039 __argp_fmtstream_putc (pest->stream, '\n');
1041 if (cl && cl->header && *cl->header
1042 && (!pe
1043 || (pe->cluster != cl
1044 && !hol_cluster_is_child (pe->cluster, cl))))
1045 /* If we're changing clusters, then this must be the start of the
1046 ENTRY's cluster unless that is an ancestor of the previous one
1047 (in which case we had just popped into a sub-cluster for a bit).
1048 If so, then print the cluster's header line. */
1050 int old_wm = __argp_fmtstream_wmargin (pest->stream);
1051 print_header (cl->header, cl->argp, pest);
1052 __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1055 pest->first = 0;
1057 else
1058 __argp_fmtstream_puts (pest->stream, ", ");
1060 indent_to (pest->stream, col);
1063 /* Print help for ENTRY to STREAM. */
1064 static void
1065 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1066 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1068 unsigned num;
1069 const struct argp_option *real = entry->opt, *opt;
1070 char *so = entry->short_options;
1071 int have_long_opt = 0; /* We have any long options. */
1072 /* Saved margins. */
1073 int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1074 int old_wm = __argp_fmtstream_wmargin (stream);
1075 /* PEST is a state block holding some of our variables that we'd like to
1076 share with helper functions. */
1077 struct pentry_state pest = { entry, stream, hhstate, 1, state };
1079 if (! odoc (real))
1080 for (opt = real, num = entry->num; num > 0; opt++, num--)
1081 if (opt->name && ovisible (opt))
1083 have_long_opt = 1;
1084 break;
1087 /* First emit short options. */
1088 __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1089 for (opt = real, num = entry->num; num > 0; opt++, num--)
1090 if (oshort (opt) && opt->key == *so)
1091 /* OPT has a valid (non shadowed) short option. */
1093 if (ovisible (opt))
1095 comma (uparams.short_opt_col, &pest);
1096 __argp_fmtstream_putc (stream, '-');
1097 __argp_fmtstream_putc (stream, *so);
1098 if (!have_long_opt || uparams.dup_args)
1099 arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
1100 else if (real->arg)
1101 hhstate->suppressed_dup_arg = 1;
1103 so++;
1106 /* Now, long options. */
1107 if (odoc (real))
1108 /* A `documentation' option. */
1110 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1111 for (opt = real, num = entry->num; num > 0; opt++, num--)
1112 if (opt->name && ovisible (opt))
1114 comma (uparams.doc_opt_col, &pest);
1115 /* Calling gettext here isn't quite right, since sorting will
1116 have been done on the original; but documentation options
1117 should be pretty rare anyway... */
1118 __argp_fmtstream_puts (stream,
1119 dgettext (state->root_argp->argp_domain,
1120 opt->name));
1123 else
1124 /* A real long option. */
1126 int first_long_opt = 1;
1128 __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1129 for (opt = real, num = entry->num; num > 0; opt++, num--)
1130 if (opt->name && ovisible (opt))
1132 comma (uparams.long_opt_col, &pest);
1133 __argp_fmtstream_printf (stream, "--%s", opt->name);
1134 if (first_long_opt || uparams.dup_args)
1135 arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
1136 stream);
1137 else if (real->arg)
1138 hhstate->suppressed_dup_arg = 1;
1142 /* Next, documentation strings. */
1143 __argp_fmtstream_set_lmargin (stream, 0);
1145 if (pest.first)
1147 /* Didn't print any switches, what's up? */
1148 if (!oshort (real) && !real->name)
1149 /* This is a group header, print it nicely. */
1150 print_header (real->doc, entry->argp, &pest);
1151 else
1152 /* Just a totally shadowed option or null header; print nothing. */
1153 goto cleanup; /* Just return, after cleaning up. */
1155 else
1157 const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
1158 real->doc) : 0;
1159 const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1160 if (fstr && *fstr)
1162 unsigned int col = __argp_fmtstream_point (stream);
1164 __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1165 __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1167 if (col > (unsigned int) (uparams.opt_doc_col + 3))
1168 __argp_fmtstream_putc (stream, '\n');
1169 else if (col >= (unsigned int) uparams.opt_doc_col)
1170 __argp_fmtstream_puts (stream, " ");
1171 else
1172 indent_to (stream, uparams.opt_doc_col);
1174 __argp_fmtstream_puts (stream, fstr);
1176 if (fstr && fstr != tstr)
1177 free ((char *) fstr);
1179 /* Reset the left margin. */
1180 __argp_fmtstream_set_lmargin (stream, 0);
1181 __argp_fmtstream_putc (stream, '\n');
1184 hhstate->prev_entry = entry;
1186 cleanup:
1187 __argp_fmtstream_set_lmargin (stream, old_lm);
1188 __argp_fmtstream_set_wmargin (stream, old_wm);
1191 /* Output a long help message about the options in HOL to STREAM. */
1192 static void
1193 hol_help (struct hol *hol, const struct argp_state *state,
1194 argp_fmtstream_t stream)
1196 unsigned num;
1197 struct hol_entry *entry;
1198 struct hol_help_state hhstate = { 0, 0, 0 };
1200 for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1201 hol_entry_help (entry, state, stream, &hhstate);
1203 if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1205 const char *tstr = dgettext (state->root_argp->argp_domain, "\
1206 Mandatory or optional arguments to long options are also mandatory or \
1207 optional for any corresponding short options.");
1208 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1209 state ? state->root_argp : 0, state);
1210 if (fstr && *fstr)
1212 __argp_fmtstream_putc (stream, '\n');
1213 __argp_fmtstream_puts (stream, fstr);
1214 __argp_fmtstream_putc (stream, '\n');
1216 if (fstr && fstr != tstr)
1217 free ((char *) fstr);
1221 /* Helper functions for hol_usage. */
1223 /* If OPT is a short option without an arg, append its key to the string
1224 pointer pointer to by COOKIE, and advance the pointer. */
1225 static int
1226 add_argless_short_opt (const struct argp_option *opt,
1227 const struct argp_option *real,
1228 const char *domain, void *cookie)
1230 char **snao_end = cookie;
1231 if (!(opt->arg || real->arg)
1232 && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1233 *(*snao_end)++ = opt->key;
1234 return 0;
1237 /* If OPT is a short option with an arg, output a usage entry for it to the
1238 stream pointed at by COOKIE. */
1239 static int
1240 usage_argful_short_opt (const struct argp_option *opt,
1241 const struct argp_option *real,
1242 const char *domain, void *cookie)
1244 argp_fmtstream_t stream = cookie;
1245 const char *arg = opt->arg;
1246 int flags = opt->flags | real->flags;
1248 if (! arg)
1249 arg = real->arg;
1251 if (arg && !(flags & OPTION_NO_USAGE))
1253 arg = dgettext (domain, arg);
1255 if (flags & OPTION_ARG_OPTIONAL)
1256 __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1257 else
1259 /* Manually do line wrapping so that it (probably) won't
1260 get wrapped at the embedded space. */
1261 space (stream, 6 + strlen (arg));
1262 __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1266 return 0;
1269 /* Output a usage entry for the long option opt to the stream pointed at by
1270 COOKIE. */
1271 static int
1272 usage_long_opt (const struct argp_option *opt,
1273 const struct argp_option *real,
1274 const char *domain, void *cookie)
1276 argp_fmtstream_t stream = cookie;
1277 const char *arg = opt->arg;
1278 int flags = opt->flags | real->flags;
1280 if (! arg)
1281 arg = real->arg;
1283 if (! (flags & OPTION_NO_USAGE))
1285 if (arg)
1287 arg = dgettext (domain, arg);
1288 if (flags & OPTION_ARG_OPTIONAL)
1289 __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1290 else
1291 __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1293 else
1294 __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1297 return 0;
1300 /* Print a short usage description for the arguments in HOL to STREAM. */
1301 static void
1302 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1304 if (hol->num_entries > 0)
1306 unsigned nentries;
1307 struct hol_entry *entry;
1308 char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1309 char *snao_end = short_no_arg_opts;
1311 /* First we put a list of short options without arguments. */
1312 for (entry = hol->entries, nentries = hol->num_entries
1313 ; nentries > 0
1314 ; entry++, nentries--)
1315 hol_entry_short_iterate (entry, add_argless_short_opt,
1316 entry->argp->argp_domain, &snao_end);
1317 if (snao_end > short_no_arg_opts)
1319 *snao_end++ = 0;
1320 __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1323 /* Now a list of short options *with* arguments. */
1324 for (entry = hol->entries, nentries = hol->num_entries
1325 ; nentries > 0
1326 ; entry++, nentries--)
1327 hol_entry_short_iterate (entry, usage_argful_short_opt,
1328 entry->argp->argp_domain, stream);
1330 /* Finally, a list of long options (whew!). */
1331 for (entry = hol->entries, nentries = hol->num_entries
1332 ; nentries > 0
1333 ; entry++, nentries--)
1334 hol_entry_long_iterate (entry, usage_long_opt,
1335 entry->argp->argp_domain, stream);
1339 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1340 cluster in which ARGP's entries should be clustered, or 0. */
1341 static struct hol *
1342 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1344 const struct argp_child *child = argp->children;
1345 struct hol *hol = make_hol (argp, cluster);
1346 if (child)
1347 while (child->argp)
1349 struct hol_cluster *child_cluster =
1350 ((child->group || child->header)
1351 /* Put CHILD->argp within its own cluster. */
1352 ? hol_add_cluster (hol, child->group, child->header,
1353 child - argp->children, cluster, argp)
1354 /* Just merge it into the parent's cluster. */
1355 : cluster);
1356 hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1357 child++;
1359 return hol;
1362 /* Calculate how many different levels with alternative args strings exist in
1363 ARGP. */
1364 static size_t
1365 argp_args_levels (const struct argp *argp)
1367 size_t levels = 0;
1368 const struct argp_child *child = argp->children;
1370 if (argp->args_doc && strchr (argp->args_doc, '\n'))
1371 levels++;
1373 if (child)
1374 while (child->argp)
1375 levels += argp_args_levels ((child++)->argp);
1377 return levels;
1380 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1381 preceded by a space. LEVELS is a pointer to a byte vector the length
1382 returned by argp_args_levels; it should be initialized to zero, and
1383 updated by this routine for the next call if ADVANCE is true. True is
1384 returned as long as there are more patterns to output. */
1385 static int
1386 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1387 char **levels, int advance, argp_fmtstream_t stream)
1389 char *our_level = *levels;
1390 int multiple = 0;
1391 const struct argp_child *child = argp->children;
1392 const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1393 const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1395 if (fdoc)
1397 const char *cp = fdoc;
1398 nl = __strchrnul (cp, '\n');
1399 if (*nl != '\0')
1400 /* This is a `multi-level' args doc; advance to the correct position
1401 as determined by our state in LEVELS, and update LEVELS. */
1403 int i;
1404 multiple = 1;
1405 for (i = 0; i < *our_level; i++)
1406 cp = nl + 1, nl = __strchrnul (cp, '\n');
1407 (*levels)++;
1410 /* Manually do line wrapping so that it (probably) won't get wrapped at
1411 any embedded spaces. */
1412 space (stream, 1 + nl - cp);
1414 __argp_fmtstream_write (stream, cp, nl - cp);
1416 if (fdoc && fdoc != tdoc)
1417 free ((char *)fdoc); /* Free user's modified doc string. */
1419 if (child)
1420 while (child->argp)
1421 advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1423 if (advance && multiple)
1425 /* Need to increment our level. */
1426 if (*nl)
1427 /* There's more we can do here. */
1429 (*our_level)++;
1430 advance = 0; /* Our parent shouldn't advance also. */
1432 else if (*our_level > 0)
1433 /* We had multiple levels, but used them up; reset to zero. */
1434 *our_level = 0;
1437 return !advance;
1440 /* Print the documentation for ARGP to STREAM; if POST is false, then
1441 everything preceeding a `\v' character in the documentation strings (or
1442 the whole string, for those with none) is printed, otherwise, everything
1443 following the `\v' character (nothing for strings without). Each separate
1444 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1445 then the first is as well. If FIRST_ONLY is true, only the first
1446 occurrence is output. Returns true if anything was output. */
1447 static int
1448 argp_doc (const struct argp *argp, const struct argp_state *state,
1449 int post, int pre_blank, int first_only,
1450 argp_fmtstream_t stream)
1452 const char *text;
1453 const char *inp_text;
1454 void *input = 0;
1455 int anything = 0;
1456 size_t inp_text_limit = 0;
1457 const char *doc = dgettext (argp->argp_domain, argp->doc);
1458 const struct argp_child *child = argp->children;
1460 if (doc)
1462 char *vt = strchr (doc, '\v');
1463 inp_text = post ? (vt ? vt + 1 : 0) : doc;
1464 inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1466 else
1467 inp_text = 0;
1469 if (argp->help_filter)
1470 /* We have to filter the doc strings. */
1472 if (inp_text_limit)
1473 /* Copy INP_TEXT so that it's nul-terminated. */
1474 inp_text = __strndup (inp_text, inp_text_limit);
1475 input = __argp_input (argp, state);
1476 text =
1477 (*argp->help_filter) (post
1478 ? ARGP_KEY_HELP_POST_DOC
1479 : ARGP_KEY_HELP_PRE_DOC,
1480 inp_text, input);
1482 else
1483 text = (const char *) inp_text;
1485 if (text)
1487 if (pre_blank)
1488 __argp_fmtstream_putc (stream, '\n');
1490 if (text == inp_text && inp_text_limit)
1491 __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1492 else
1493 __argp_fmtstream_puts (stream, text);
1495 if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1496 __argp_fmtstream_putc (stream, '\n');
1498 anything = 1;
1501 if (text && text != inp_text)
1502 free ((char *) text); /* Free TEXT returned from the help filter. */
1503 if (inp_text && inp_text_limit && argp->help_filter)
1504 free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
1506 if (post && argp->help_filter)
1507 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1509 text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1510 if (text)
1512 if (anything || pre_blank)
1513 __argp_fmtstream_putc (stream, '\n');
1514 __argp_fmtstream_puts (stream, text);
1515 free ((char *) text);
1516 if (__argp_fmtstream_point (stream)
1517 > __argp_fmtstream_lmargin (stream))
1518 __argp_fmtstream_putc (stream, '\n');
1519 anything = 1;
1523 if (child)
1524 while (child->argp && !(first_only && anything))
1525 anything |=
1526 argp_doc ((child++)->argp, state,
1527 post, anything || pre_blank, first_only,
1528 stream);
1530 return anything;
1533 /* Output a usage message for ARGP to STREAM. If called from
1534 argp_state_help, STATE is the relevent parsing state. FLAGS are from the
1535 set ARGP_HELP_*. NAME is what to use wherever a `program name' is
1536 needed. */
1537 static void
1538 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1539 unsigned flags, char *name)
1541 int anything = 0; /* Whether we've output anything. */
1542 struct hol *hol = 0;
1543 argp_fmtstream_t fs;
1545 if (! stream)
1546 return;
1548 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1549 __flockfile (stream);
1550 #endif
1552 if (! uparams.valid)
1553 fill_in_uparams (state);
1555 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1556 if (! fs)
1558 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1559 __funlockfile (stream);
1560 #endif
1561 return;
1564 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1566 hol = argp_hol (argp, 0);
1568 /* If present, these options always come last. */
1569 hol_set_group (hol, "help", -1);
1570 hol_set_group (hol, "version", -1);
1572 hol_sort (hol);
1575 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1576 /* Print a short `Usage:' message. */
1578 int first_pattern = 1, more_patterns;
1579 size_t num_pattern_levels = argp_args_levels (argp);
1580 char *pattern_levels = alloca (num_pattern_levels);
1582 memset (pattern_levels, 0, num_pattern_levels);
1586 int old_lm;
1587 int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1588 char *levels = pattern_levels;
1590 if (first_pattern)
1591 __argp_fmtstream_printf (fs, "%s %s",
1592 dgettext (argp->argp_domain, "Usage:"),
1593 name);
1594 else
1595 __argp_fmtstream_printf (fs, "%s %s",
1596 dgettext (argp->argp_domain, " or: "),
1597 name);
1599 /* We set the lmargin as well as the wmargin, because hol_usage
1600 manually wraps options with newline to avoid annoying breaks. */
1601 old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1603 if (flags & ARGP_HELP_SHORT_USAGE)
1604 /* Just show where the options go. */
1606 if (hol->num_entries > 0)
1607 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1608 " [OPTION...]"));
1610 else
1611 /* Actually print the options. */
1613 hol_usage (hol, fs);
1614 flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
1617 more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1619 __argp_fmtstream_set_wmargin (fs, old_wm);
1620 __argp_fmtstream_set_lmargin (fs, old_lm);
1622 __argp_fmtstream_putc (fs, '\n');
1623 anything = 1;
1625 first_pattern = 0;
1627 while (more_patterns);
1630 if (flags & ARGP_HELP_PRE_DOC)
1631 anything |= argp_doc (argp, state, 0, 0, 1, fs);
1633 if (flags & ARGP_HELP_SEE)
1635 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1636 Try `%s --help' or `%s --usage' for more information.\n"),
1637 name, name);
1638 anything = 1;
1641 if (flags & ARGP_HELP_LONG)
1642 /* Print a long, detailed help message. */
1644 /* Print info about all the options. */
1645 if (hol->num_entries > 0)
1647 if (anything)
1648 __argp_fmtstream_putc (fs, '\n');
1649 hol_help (hol, state, fs);
1650 anything = 1;
1654 if (flags & ARGP_HELP_POST_DOC)
1655 /* Print any documentation strings at the end. */
1656 anything |= argp_doc (argp, state, 1, anything, 0, fs);
1658 if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1660 if (anything)
1661 __argp_fmtstream_putc (fs, '\n');
1662 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1663 "Report bugs to %s.\n"),
1664 argp_program_bug_address);
1665 anything = 1;
1668 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1669 __funlockfile (stream);
1670 #endif
1672 if (hol)
1673 hol_free (hol);
1675 __argp_fmtstream_free (fs);
1678 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1679 ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
1680 void __argp_help (const struct argp *argp, FILE *stream,
1681 unsigned flags, char *name)
1683 _help (argp, 0, stream, flags, name);
1685 #ifdef weak_alias
1686 weak_alias (__argp_help, argp_help)
1687 #endif
1689 #ifndef _LIBC
1690 char *__argp_basename (char *name)
1692 char *short_name = strrchr (name, '/');
1693 return short_name ? short_name + 1 : name;
1696 char *
1697 __argp_short_program_name (void)
1699 # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
1700 return program_invocation_short_name;
1701 # elif HAVE_DECL_PROGRAM_INVOCATION_NAME
1702 return __argp_basename (program_invocation_name);
1703 # else
1704 /* FIXME: What now? Miles suggests that it is better to use NULL,
1705 but currently the value is passed on directly to fputs_unlocked,
1706 so that requires more changes. */
1707 # if __GNUC__
1708 # warning No reasonable value to return
1709 # endif /* __GNUC__ */
1710 return "";
1711 # endif
1713 #endif
1715 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1716 from the set ARGP_HELP_*. */
1717 void
1718 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1720 if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1722 if (state && (state->flags & ARGP_LONG_ONLY))
1723 flags |= ARGP_HELP_LONG_ONLY;
1725 _help (state ? state->root_argp : 0, state, stream, flags,
1726 state ? state->name : __argp_short_program_name ());
1728 if (!state || ! (state->flags & ARGP_NO_EXIT))
1730 if (flags & ARGP_HELP_EXIT_ERR)
1731 exit (argp_err_exit_status);
1732 if (flags & ARGP_HELP_EXIT_OK)
1733 exit (0);
1737 #ifdef weak_alias
1738 weak_alias (__argp_state_help, argp_state_help)
1739 #endif
1741 /* If appropriate, print the printf string FMT and following args, preceded
1742 by the program name and `:', to stderr, and followed by a `Try ... --help'
1743 message, then exit (1). */
1744 void
1745 __argp_error (const struct argp_state *state, const char *fmt, ...)
1747 if (!state || !(state->flags & ARGP_NO_ERRS))
1749 FILE *stream = state ? state->err_stream : stderr;
1751 if (stream)
1753 va_list ap;
1755 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1756 __flockfile (stream);
1757 #endif
1759 va_start (ap, fmt);
1761 #ifdef USE_IN_LIBIO
1762 if (_IO_fwide (stream, 0) > 0)
1764 char *buf;
1766 __asprintf (&buf, fmt, ap);
1768 __fwprintf (stream, L"%s: %s\n",
1769 state ? state->name : __argp_short_program_name (),
1770 buf);
1772 free (buf);
1774 else
1775 #endif
1777 fputs_unlocked (state
1778 ? state->name : __argp_short_program_name (),
1779 stream);
1780 putc_unlocked (':', stream);
1781 putc_unlocked (' ', stream);
1783 vfprintf (stream, fmt, ap);
1785 putc_unlocked ('\n', stream);
1788 __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1790 va_end (ap);
1792 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1793 __funlockfile (stream);
1794 #endif
1798 #ifdef weak_alias
1799 weak_alias (__argp_error, argp_error)
1800 #endif
1802 /* Similar to the standard gnu error-reporting function error(), but will
1803 respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1804 to STATE->err_stream. This is useful for argument parsing code that is
1805 shared between program startup (when exiting is desired) and runtime
1806 option parsing (when typically an error code is returned instead). The
1807 difference between this function and argp_error is that the latter is for
1808 *parsing errors*, and the former is for other problems that occur during
1809 parsing but don't reflect a (syntactic) problem with the input. */
1810 void
1811 __argp_failure (const struct argp_state *state, int status, int errnum,
1812 const char *fmt, ...)
1814 if (!state || !(state->flags & ARGP_NO_ERRS))
1816 FILE *stream = state ? state->err_stream : stderr;
1818 if (stream)
1820 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1821 __flockfile (stream);
1822 #endif
1824 #ifdef USE_IN_LIBIO
1825 if (_IO_fwide (stream, 0) > 0)
1826 __fwprintf (stream, L"%s",
1827 state ? state->name : __argp_short_program_name ());
1828 else
1829 #endif
1830 fputs_unlocked (state
1831 ? state->name : __argp_short_program_name (),
1832 stream);
1834 if (fmt)
1836 va_list ap;
1838 va_start (ap, fmt);
1839 #ifdef USE_IN_LIBIO
1840 if (_IO_fwide (stream, 0) > 0)
1842 char *buf;
1844 __asprintf (&buf, fmt, ap);
1846 __fwprintf (stream, L": %s", buf);
1848 free (buf);
1850 else
1851 #endif
1853 putc_unlocked (':', stream);
1854 putc_unlocked (' ', stream);
1856 vfprintf (stream, fmt, ap);
1859 va_end (ap);
1862 if (errnum)
1864 char buf[200];
1866 #ifdef USE_IN_LIBIO
1867 if (_IO_fwide (stream, 0) > 0)
1868 __fwprintf (stream, L": %s",
1869 __strerror_r (errnum, buf, sizeof (buf)));
1870 else
1871 #endif
1873 putc_unlocked (':', stream);
1874 putc_unlocked (' ', stream);
1875 #if defined _LIBC || defined HAVE_STRERROR_R
1876 fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
1877 #else
1878 fputs (strerror (errnum), stream);
1879 #endif
1883 #ifdef USE_IN_LIBIO
1884 if (_IO_fwide (stream, 0) > 0)
1885 putwc_unlocked (L'\n', stream);
1886 else
1887 #endif
1888 putc_unlocked ('\n', stream);
1890 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1891 __funlockfile (stream);
1892 #endif
1894 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1895 exit (status);
1899 #ifdef weak_alias
1900 weak_alias (__argp_failure, argp_failure)
1901 #endif