* nis/ypclnt.c (__xdr_ypresp_all): Minor optimization in string
[glibc.git] / argp / argp-help.c
blob4bc4d07b1568de9da4bbab7b56ac6ad1df53bbbf
1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995-2003, 2004, 2005 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 #include <limits.h>
51 #ifdef _LIBC
52 # include <../libio/libioP.h>
53 # include <wchar.h>
54 #endif
56 #ifndef _
57 /* This is for other GNU distributions with internationalized messages. */
58 # if defined HAVE_LIBINTL_H || defined _LIBC
59 # include <libintl.h>
60 # ifdef _LIBC
61 # undef dgettext
62 # define dgettext(domain, msgid) \
63 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
64 # endif
65 # else
66 # define dgettext(domain, msgid) (msgid)
67 # endif
68 #endif
70 #ifndef _LIBC
71 # if HAVE_STRERROR_R
72 # if !HAVE_DECL_STRERROR_R
73 char *strerror_r (int errnum, char *buf, size_t buflen);
74 # endif
75 # else
76 # if !HAVE_DECL_STRERROR
77 char *strerror (int errnum);
78 # endif
79 # endif
80 #endif
82 #include "argp.h"
83 #include "argp-fmtstream.h"
84 #include "argp-namefrob.h"
86 #ifndef SIZE_MAX
87 # define SIZE_MAX ((size_t) -1)
88 #endif
90 /* User-selectable (using an environment variable) formatting parameters.
92 These may be specified in an environment variable called `ARGP_HELP_FMT',
93 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
94 Where VALn must be a positive integer. The list of variables is in the
95 UPARAM_NAMES vector, below. */
97 /* Default parameters. */
98 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
99 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
100 #define SHORT_OPT_COL 2 /* column in which short options start */
101 #define LONG_OPT_COL 6 /* column in which long options start */
102 #define DOC_OPT_COL 2 /* column in which doc options start */
103 #define OPT_DOC_COL 29 /* column in which option text starts */
104 #define HEADER_COL 1 /* column in which group headers are printed */
105 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
106 #define RMARGIN 79 /* right margin used for wrapping */
108 /* User-selectable (using an environment variable) formatting parameters.
109 They must all be of type `int' for the parsing code to work. */
110 struct uparams
112 /* If true, arguments for an option are shown with both short and long
113 options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
114 If false, then if an option has both, the argument is only shown with
115 the long one, e.g., `-x, --longx=ARG', and a message indicating that
116 this really means both is printed below the options. */
117 int dup_args;
119 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
120 been suppressed, an explanatory message should be printed. */
121 int dup_args_note;
123 /* Various output columns. */
124 int short_opt_col;
125 int long_opt_col;
126 int doc_opt_col;
127 int opt_doc_col;
128 int header_col;
129 int usage_indent;
130 int rmargin;
132 int valid; /* True when the values in here are valid. */
135 /* This is a global variable, as user options are only ever read once. */
136 static struct uparams uparams = {
137 DUP_ARGS, DUP_ARGS_NOTE,
138 SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
139 USAGE_INDENT, RMARGIN,
143 /* A particular uparam, and what the user name is. */
144 struct uparam_name
146 const char *name; /* User name. */
147 int is_bool; /* Whether it's `boolean'. */
148 size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
151 /* The name-field mappings we know about. */
152 static const struct uparam_name uparam_names[] =
154 { "dup-args", 1, offsetof (struct uparams, dup_args) },
155 { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
156 { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
157 { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
158 { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
159 { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
160 { "header-col", 0, offsetof (struct uparams, header_col) },
161 { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
162 { "rmargin", 0, offsetof (struct uparams, rmargin) },
163 { 0 }
166 /* Read user options from the environment, and fill in UPARAMS appropiately. */
167 static void
168 fill_in_uparams (const struct argp_state *state)
170 const char *var = getenv ("ARGP_HELP_FMT");
172 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
174 if (var)
175 /* Parse var. */
176 while (*var)
178 SKIPWS (var);
180 if (isalpha (*var))
182 size_t var_len;
183 const struct uparam_name *un;
184 int unspec = 0, val = 0;
185 const char *arg = var;
187 while (isalnum (*arg) || *arg == '-' || *arg == '_')
188 arg++;
189 var_len = arg - var;
191 SKIPWS (arg);
193 if (*arg == '\0' || *arg == ',')
194 unspec = 1;
195 else if (*arg == '=')
197 arg++;
198 SKIPWS (arg);
201 if (unspec)
203 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
205 val = 0;
206 var += 3;
207 var_len -= 3;
209 else
210 val = 1;
212 else if (isdigit (*arg))
214 val = atoi (arg);
215 while (isdigit (*arg))
216 arg++;
217 SKIPWS (arg);
220 for (un = uparam_names; un->name; un++)
221 if (strlen (un->name) == var_len
222 && strncmp (var, un->name, var_len) == 0)
224 if (unspec && !un->is_bool)
225 __argp_failure (state, 0, 0,
226 dgettext (state->root_argp->argp_domain, "\
227 %.*s: ARGP_HELP_FMT parameter requires a value"),
228 (int) var_len, var);
229 else
230 *(int *)((char *)&uparams + un->uparams_offs) = val;
231 break;
233 if (! un->name)
234 __argp_failure (state, 0, 0,
235 dgettext (state->root_argp->argp_domain, "\
236 %.*s: Unknown ARGP_HELP_FMT parameter"),
237 (int) var_len, var);
239 var = arg;
240 if (*var == ',')
241 var++;
243 else if (*var)
245 __argp_failure (state, 0, 0,
246 dgettext (state->root_argp->argp_domain,
247 "Garbage in ARGP_HELP_FMT: %s"), var);
248 break;
253 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
254 whether OPT is displayed or used in sorting, not option shadowing. */
255 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
257 /* Returns true if OPT is an alias for an earlier option. */
258 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
260 /* Returns true if OPT is an documentation-only entry. */
261 #define odoc(opt) ((opt)->flags & OPTION_DOC)
263 /* Returns true if OPT is the end-of-list marker for a list of options. */
264 #define oend(opt) __option_is_end (opt)
266 /* Returns true if OPT has a short option. */
267 #define oshort(opt) __option_is_short (opt)
270 The help format for a particular option is like:
272 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
274 Where ARG will be omitted if there's no argument, for this option, or
275 will be surrounded by "[" and "]" appropiately if the argument is
276 optional. The documentation string is word-wrapped appropiately, and if
277 the list of options is long enough, it will be started on a separate line.
278 If there are no short options for a given option, the first long option is
279 indented slighly in a way that's supposed to make most long options appear
280 to be in a separate column.
282 For example, the following output (from ps):
284 -p PID, --pid=PID List the process PID
285 --pgrp=PGRP List processes in the process group PGRP
286 -P, -x, --no-parent Include processes without parents
287 -Q, --all-fields Don't elide unusable fields (normally if there's
288 some reason ps can't print a field for any
289 process, it's removed from the output entirely)
290 -r, --reverse, --gratuitously-long-reverse-option
291 Reverse the order of any sort
292 --session[=SID] Add the processes from the session SID (which
293 defaults to the sid of the current process)
295 Here are some more options:
296 -f ZOT, --foonly=ZOT Glork a foonly
297 -z, --zaza Snit a zar
299 -?, --help Give this help list
300 --usage Give a short usage message
301 -V, --version Print program version
303 The struct argp_option array for the above could look like:
306 {"pid", 'p', "PID", 0, "List the process PID"},
307 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
308 {"no-parent", 'P', 0, 0, "Include processes without parents"},
309 {0, 'x', 0, OPTION_ALIAS},
310 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
311 " if there's some reason ps can't"
312 " print a field for any process, it's"
313 " removed from the output entirely)" },
314 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
315 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
316 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
317 "Add the processes from the session"
318 " SID (which defaults to the sid of"
319 " the current process)" },
321 {0,0,0,0, "Here are some more options:"},
322 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
323 {"zaza", 'z', 0, 0, "Snit a zar"},
328 Note that the last three options are automatically supplied by argp_parse,
329 unless you tell it not to with ARGP_NO_HELP.
333 /* Returns true if CH occurs between BEG and END. */
334 static int
335 find_char (char ch, char *beg, char *end)
337 while (beg < end)
338 if (*beg == ch)
339 return 1;
340 else
341 beg++;
342 return 0;
345 struct hol_cluster; /* fwd decl */
347 struct hol_entry
349 /* First option. */
350 const struct argp_option *opt;
351 /* Number of options (including aliases). */
352 unsigned num;
354 /* A pointers into the HOL's short_options field, to the first short option
355 letter for this entry. The order of the characters following this point
356 corresponds to the order of options pointed to by OPT, and there are at
357 most NUM. A short option recorded in a option following OPT is only
358 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
359 probably been shadowed by some other entry). */
360 char *short_options;
362 /* Entries are sorted by their group first, in the order:
363 1, 2, ..., n, 0, -m, ..., -2, -1
364 and then alphabetically within each group. The default is 0. */
365 int group;
367 /* The cluster of options this entry belongs to, or 0 if none. */
368 struct hol_cluster *cluster;
370 /* The argp from which this option came. */
371 const struct argp *argp;
374 /* A cluster of entries to reflect the argp tree structure. */
375 struct hol_cluster
377 /* A descriptive header printed before options in this cluster. */
378 const char *header;
380 /* Used to order clusters within the same group with the same parent,
381 according to the order in which they occurred in the parent argp's child
382 list. */
383 int index;
385 /* How to sort this cluster with respect to options and other clusters at the
386 same depth (clusters always follow options in the same group). */
387 int group;
389 /* The cluster to which this cluster belongs, or 0 if it's at the base
390 level. */
391 struct hol_cluster *parent;
393 /* The argp from which this cluster is (eventually) derived. */
394 const struct argp *argp;
396 /* The distance this cluster is from the root. */
397 int depth;
399 /* Clusters in a given hol are kept in a linked list, to make freeing them
400 possible. */
401 struct hol_cluster *next;
404 /* A list of options for help. */
405 struct hol
407 /* An array of hol_entry's. */
408 struct hol_entry *entries;
409 /* The number of entries in this hol. If this field is zero, the others
410 are undefined. */
411 unsigned num_entries;
413 /* A string containing all short options in this HOL. Each entry contains
414 pointers into this string, so the order can't be messed with blindly. */
415 char *short_options;
417 /* Clusters of entries in this hol. */
418 struct hol_cluster *clusters;
421 /* Create a struct hol from the options in ARGP. CLUSTER is the
422 hol_cluster in which these entries occur, or 0, if at the root. */
423 static struct hol *
424 make_hol (const struct argp *argp, struct hol_cluster *cluster)
426 char *so;
427 const struct argp_option *o;
428 const struct argp_option *opts = argp->options;
429 struct hol_entry *entry;
430 unsigned num_short_options = 0;
431 struct hol *hol = malloc (sizeof (struct hol));
433 assert (hol);
435 hol->num_entries = 0;
436 hol->clusters = 0;
438 if (opts)
440 int cur_group = 0;
442 /* The first option must not be an alias. */
443 assert (! oalias (opts));
445 /* Calculate the space needed. */
446 for (o = opts; ! oend (o); o++)
448 if (! oalias (o))
449 hol->num_entries++;
450 if (oshort (o))
451 num_short_options++; /* This is an upper bound. */
454 hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
455 hol->short_options = malloc (num_short_options + 1);
457 assert (hol->entries && hol->short_options);
458 #if SIZE_MAX <= UINT_MAX
459 assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
460 #endif
462 /* Fill in the entries. */
463 so = hol->short_options;
464 for (o = opts, entry = hol->entries; ! oend (o); entry++)
466 entry->opt = o;
467 entry->num = 0;
468 entry->short_options = so;
469 entry->group = cur_group =
470 o->group
471 ? o->group
472 : ((!o->name && !o->key)
473 ? cur_group + 1
474 : cur_group);
475 entry->cluster = cluster;
476 entry->argp = argp;
480 entry->num++;
481 if (oshort (o) && ! find_char (o->key, hol->short_options, so))
482 /* O has a valid short option which hasn't already been used.*/
483 *so++ = o->key;
484 o++;
486 while (! oend (o) && oalias (o));
488 *so = '\0'; /* null terminated so we can find the length */
491 return hol;
494 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
495 associated argp child list entry), INDEX, and PARENT, and return a pointer
496 to it. ARGP is the argp that this cluster results from. */
497 static struct hol_cluster *
498 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
499 struct hol_cluster *parent, const struct argp *argp)
501 struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
502 if (cl)
504 cl->group = group;
505 cl->header = header;
507 cl->index = index;
508 cl->parent = parent;
509 cl->argp = argp;
510 cl->depth = parent ? parent->depth + 1 : 0;
512 cl->next = hol->clusters;
513 hol->clusters = cl;
515 return cl;
518 /* Free HOL and any resources it uses. */
519 static void
520 hol_free (struct hol *hol)
522 struct hol_cluster *cl = hol->clusters;
524 while (cl)
526 struct hol_cluster *next = cl->next;
527 free (cl);
528 cl = next;
531 if (hol->num_entries > 0)
533 free (hol->entries);
534 free (hol->short_options);
537 free (hol);
540 static int
541 hol_entry_short_iterate (const struct hol_entry *entry,
542 int (*func)(const struct argp_option *opt,
543 const struct argp_option *real,
544 const char *domain, void *cookie),
545 const char *domain, void *cookie)
547 unsigned nopts;
548 int val = 0;
549 const struct argp_option *opt, *real = entry->opt;
550 char *so = entry->short_options;
552 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
553 if (oshort (opt) && *so == opt->key)
555 if (!oalias (opt))
556 real = opt;
557 if (ovisible (opt))
558 val = (*func)(opt, real, domain, cookie);
559 so++;
562 return val;
565 static inline int
566 __attribute__ ((always_inline))
567 hol_entry_long_iterate (const struct hol_entry *entry,
568 int (*func)(const struct argp_option *opt,
569 const struct argp_option *real,
570 const char *domain, void *cookie),
571 const char *domain, void *cookie)
573 unsigned nopts;
574 int val = 0;
575 const struct argp_option *opt, *real = entry->opt;
577 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
578 if (opt->name)
580 if (!oalias (opt))
581 real = opt;
582 if (ovisible (opt))
583 val = (*func)(opt, real, domain, cookie);
586 return val;
589 /* Iterator that returns true for the first short option. */
590 static inline int
591 until_short (const struct argp_option *opt, const struct argp_option *real,
592 const char *domain, void *cookie)
594 return oshort (opt) ? opt->key : 0;
597 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
598 static char
599 hol_entry_first_short (const struct hol_entry *entry)
601 return hol_entry_short_iterate (entry, until_short,
602 entry->argp->argp_domain, 0);
605 /* Returns the first valid long option in ENTRY, or 0 if there is none. */
606 static const char *
607 hol_entry_first_long (const struct hol_entry *entry)
609 const struct argp_option *opt;
610 unsigned num;
611 for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
612 if (opt->name && ovisible (opt))
613 return opt->name;
614 return 0;
617 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
618 none. */
619 static struct hol_entry *
620 hol_find_entry (struct hol *hol, const char *name)
622 struct hol_entry *entry = hol->entries;
623 unsigned num_entries = hol->num_entries;
625 while (num_entries-- > 0)
627 const struct argp_option *opt = entry->opt;
628 unsigned num_opts = entry->num;
630 while (num_opts-- > 0)
631 if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
632 return entry;
633 else
634 opt++;
636 entry++;
639 return 0;
642 /* If an entry with the long option NAME occurs in HOL, set it's special
643 sort position to GROUP. */
644 static void
645 hol_set_group (struct hol *hol, const char *name, int group)
647 struct hol_entry *entry = hol_find_entry (hol, name);
648 if (entry)
649 entry->group = group;
652 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
653 EQ is what to return if GROUP1 and GROUP2 are the same. */
654 static int
655 group_cmp (int group1, int group2, int eq)
657 if (group1 == group2)
658 return eq;
659 else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
660 return group1 - group2;
661 else
662 return group2 - group1;
665 /* Compare clusters CL1 & CL2 by the order that they should appear in
666 output. */
667 static int
668 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
670 /* If one cluster is deeper than the other, use its ancestor at the same
671 level, so that finding the common ancestor is straightforward. */
672 while (cl1->depth < cl2->depth)
673 cl1 = cl1->parent;
674 while (cl2->depth < cl1->depth)
675 cl2 = cl2->parent;
677 /* Now reduce both clusters to their ancestors at the point where both have
678 a common parent; these can be directly compared. */
679 while (cl1->parent != cl2->parent)
680 cl1 = cl1->parent, cl2 = cl2->parent;
682 return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
685 /* Return the ancestor of CL that's just below the root (i.e., has a parent
686 of 0). */
687 static struct hol_cluster *
688 hol_cluster_base (struct hol_cluster *cl)
690 while (cl->parent)
691 cl = cl->parent;
692 return cl;
695 /* Return true if CL1 is a child of CL2. */
696 static int
697 hol_cluster_is_child (const struct hol_cluster *cl1,
698 const struct hol_cluster *cl2)
700 while (cl1 && cl1 != cl2)
701 cl1 = cl1->parent;
702 return cl1 == cl2;
705 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
706 that should be used for comparisons, and returns true iff it should be
707 treated as a non-option. */
708 static int
709 canon_doc_option (const char **name)
711 int non_opt;
712 /* Skip initial whitespace. */
713 while (isspace (**name))
714 (*name)++;
715 /* Decide whether this looks like an option (leading `-') or not. */
716 non_opt = (**name != '-');
717 /* Skip until part of name used for sorting. */
718 while (**name && !isalnum (**name))
719 (*name)++;
720 return non_opt;
723 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
724 listing. */
725 static int
726 hol_entry_cmp (const struct hol_entry *entry1,
727 const struct hol_entry *entry2)
729 /* The group numbers by which the entries should be ordered; if either is
730 in a cluster, then this is just the group within the cluster. */
731 int group1 = entry1->group, group2 = entry2->group;
733 if (entry1->cluster != entry2->cluster)
735 /* The entries are not within the same cluster, so we can't compare them
736 directly, we have to use the appropiate clustering level too. */
737 if (! entry1->cluster)
738 /* ENTRY1 is at the `base level', not in a cluster, so we have to
739 compare it's group number with that of the base cluster in which
740 ENTRY2 resides. Note that if they're in the same group, the
741 clustered option always comes laster. */
742 return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
743 else if (! entry2->cluster)
744 /* Likewise, but ENTRY2's not in a cluster. */
745 return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
746 else
747 /* Both entries are in clusters, we can just compare the clusters. */
748 return hol_cluster_cmp (entry1->cluster, entry2->cluster);
750 else if (group1 == group2)
751 /* The entries are both in the same cluster and group, so compare them
752 alphabetically. */
754 int short1 = hol_entry_first_short (entry1);
755 int short2 = hol_entry_first_short (entry2);
756 int doc1 = odoc (entry1->opt);
757 int doc2 = odoc (entry2->opt);
758 const char *long1 = hol_entry_first_long (entry1);
759 const char *long2 = hol_entry_first_long (entry2);
761 if (doc1)
762 doc1 = canon_doc_option (&long1);
763 if (doc2)
764 doc2 = canon_doc_option (&long2);
766 if (doc1 != doc2)
767 /* `documentation' options always follow normal options (or
768 documentation options that *look* like normal options). */
769 return doc1 - doc2;
770 else if (!short1 && !short2 && long1 && long2)
771 /* Only long options. */
772 return __strcasecmp (long1, long2);
773 else
774 /* Compare short/short, long/short, short/long, using the first
775 character of long options. Entries without *any* valid
776 options (such as options with OPTION_HIDDEN set) will be put
777 first, but as they're not displayed, it doesn't matter where
778 they are. */
780 char first1 = short1 ? short1 : long1 ? *long1 : 0;
781 char first2 = short2 ? short2 : long2 ? *long2 : 0;
782 #ifdef _tolower
783 int lower_cmp = _tolower (first1) - _tolower (first2);
784 #else
785 int lower_cmp = tolower (first1) - tolower (first2);
786 #endif
787 /* Compare ignoring case, except when the options are both the
788 same letter, in which case lower-case always comes first. */
789 return lower_cmp ? lower_cmp : first2 - first1;
792 else
793 /* Within the same cluster, but not the same group, so just compare
794 groups. */
795 return group_cmp (group1, group2, 0);
798 /* Version of hol_entry_cmp with correct signature for qsort. */
799 static int
800 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
802 return hol_entry_cmp (entry1_v, entry2_v);
805 /* Sort HOL by group and alphabetically by option name (with short options
806 taking precedence over long). Since the sorting is for display purposes
807 only, the shadowing of options isn't effected. */
808 static void
809 hol_sort (struct hol *hol)
811 if (hol->num_entries > 0)
812 qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
813 hol_entry_qcmp);
816 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
817 any in MORE with the same name. */
818 static void
819 hol_append (struct hol *hol, struct hol *more)
821 struct hol_cluster **cl_end = &hol->clusters;
823 /* Steal MORE's cluster list, and add it to the end of HOL's. */
824 while (*cl_end)
825 cl_end = &(*cl_end)->next;
826 *cl_end = more->clusters;
827 more->clusters = 0;
829 /* Merge entries. */
830 if (more->num_entries > 0)
832 if (hol->num_entries == 0)
834 hol->num_entries = more->num_entries;
835 hol->entries = more->entries;
836 hol->short_options = more->short_options;
837 more->num_entries = 0; /* Mark MORE's fields as invalid. */
839 else
840 /* Append the entries in MORE to those in HOL, taking care to only add
841 non-shadowed SHORT_OPTIONS values. */
843 unsigned left;
844 char *so, *more_so;
845 struct hol_entry *e;
846 unsigned num_entries = hol->num_entries + more->num_entries;
847 struct hol_entry *entries =
848 malloc (num_entries * sizeof (struct hol_entry));
849 unsigned hol_so_len = strlen (hol->short_options);
850 char *short_options =
851 malloc (hol_so_len + strlen (more->short_options) + 1);
853 assert (entries && short_options);
854 #if SIZE_MAX <= UINT_MAX
855 assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
856 #endif
858 __mempcpy (__mempcpy (entries, hol->entries,
859 hol->num_entries * sizeof (struct hol_entry)),
860 more->entries,
861 more->num_entries * sizeof (struct hol_entry));
863 __mempcpy (short_options, hol->short_options, hol_so_len);
865 /* Fix up the short options pointers from HOL. */
866 for (e = entries, left = hol->num_entries; left > 0; e++, left--)
867 e->short_options += (short_options - hol->short_options);
869 /* Now add the short options from MORE, fixing up its entries
870 too. */
871 so = short_options + hol_so_len;
872 more_so = more->short_options;
873 for (left = more->num_entries; left > 0; e++, left--)
875 int opts_left;
876 const struct argp_option *opt;
878 e->short_options = so;
880 for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
882 int ch = *more_so;
883 if (oshort (opt) && ch == opt->key)
884 /* The next short option in MORE_SO, CH, is from OPT. */
886 if (! find_char (ch, short_options,
887 short_options + hol_so_len))
888 /* The short option CH isn't shadowed by HOL's options,
889 so add it to the sum. */
890 *so++ = ch;
891 more_so++;
896 *so = '\0';
898 free (hol->entries);
899 free (hol->short_options);
901 hol->entries = entries;
902 hol->num_entries = num_entries;
903 hol->short_options = short_options;
907 hol_free (more);
910 /* Inserts enough spaces to make sure STREAM is at column COL. */
911 static void
912 indent_to (argp_fmtstream_t stream, unsigned col)
914 int needed = col - __argp_fmtstream_point (stream);
915 while (needed-- > 0)
916 __argp_fmtstream_putc (stream, ' ');
919 /* Output to STREAM either a space, or a newline if there isn't room for at
920 least ENSURE characters before the right margin. */
921 static void
922 space (argp_fmtstream_t stream, size_t ensure)
924 if (__argp_fmtstream_point (stream) + ensure
925 >= __argp_fmtstream_rmargin (stream))
926 __argp_fmtstream_putc (stream, '\n');
927 else
928 __argp_fmtstream_putc (stream, ' ');
931 /* If the option REAL has an argument, we print it in using the printf
932 format REQ_FMT or OPT_FMT depending on whether it's a required or
933 optional argument. */
934 static void
935 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
936 const char *domain, argp_fmtstream_t stream)
938 if (real->arg)
940 if (real->flags & OPTION_ARG_OPTIONAL)
941 __argp_fmtstream_printf (stream, opt_fmt,
942 dgettext (domain, real->arg));
943 else
944 __argp_fmtstream_printf (stream, req_fmt,
945 dgettext (domain, real->arg));
949 /* Helper functions for hol_entry_help. */
951 /* State used during the execution of hol_help. */
952 struct hol_help_state
954 /* PREV_ENTRY should contain the previous entry printed, or 0. */
955 struct hol_entry *prev_entry;
957 /* If an entry is in a different group from the previous one, and SEP_GROUPS
958 is true, then a blank line will be printed before any output. */
959 int sep_groups;
961 /* True if a duplicate option argument was suppressed (only ever set if
962 UPARAMS.dup_args is false). */
963 int suppressed_dup_arg;
966 /* Some state used while printing a help entry (used to communicate with
967 helper functions). See the doc for hol_entry_help for more info, as most
968 of the fields are copied from its arguments. */
969 struct pentry_state
971 const struct hol_entry *entry;
972 argp_fmtstream_t stream;
973 struct hol_help_state *hhstate;
975 /* True if nothing's been printed so far. */
976 int first;
978 /* If non-zero, the state that was used to print this help. */
979 const struct argp_state *state;
982 /* If a user doc filter should be applied to DOC, do so. */
983 static const char *
984 filter_doc (const char *doc, int key, const struct argp *argp,
985 const struct argp_state *state)
987 if (argp->help_filter)
988 /* We must apply a user filter to this output. */
990 void *input = __argp_input (argp, state);
991 return (*argp->help_filter) (key, doc, input);
993 else
994 /* No filter. */
995 return doc;
998 /* Prints STR as a header line, with the margin lines set appropiately, and
999 notes the fact that groups should be separated with a blank line. ARGP is
1000 the argp that should dictate any user doc filtering to take place. Note
1001 that the previous wrap margin isn't restored, but the left margin is reset
1002 to 0. */
1003 static void
1004 print_header (const char *str, const struct argp *argp,
1005 struct pentry_state *pest)
1007 const char *tstr = dgettext (argp->argp_domain, str);
1008 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
1010 if (fstr)
1012 if (*fstr)
1014 if (pest->hhstate->prev_entry)
1015 /* Precede with a blank line. */
1016 __argp_fmtstream_putc (pest->stream, '\n');
1017 indent_to (pest->stream, uparams.header_col);
1018 __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
1019 __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
1020 __argp_fmtstream_puts (pest->stream, fstr);
1021 __argp_fmtstream_set_lmargin (pest->stream, 0);
1022 __argp_fmtstream_putc (pest->stream, '\n');
1025 pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
1028 if (fstr != tstr)
1029 free ((char *) fstr);
1032 /* Inserts a comma if this isn't the first item on the line, and then makes
1033 sure we're at least to column COL. If this *is* the first item on a line,
1034 prints any pending whitespace/headers that should precede this line. Also
1035 clears FIRST. */
1036 static void
1037 comma (unsigned col, struct pentry_state *pest)
1039 if (pest->first)
1041 const struct hol_entry *pe = pest->hhstate->prev_entry;
1042 const struct hol_cluster *cl = pest->entry->cluster;
1044 if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1045 __argp_fmtstream_putc (pest->stream, '\n');
1047 if (cl && cl->header && *cl->header
1048 && (!pe
1049 || (pe->cluster != cl
1050 && !hol_cluster_is_child (pe->cluster, cl))))
1051 /* If we're changing clusters, then this must be the start of the
1052 ENTRY's cluster unless that is an ancestor of the previous one
1053 (in which case we had just popped into a sub-cluster for a bit).
1054 If so, then print the cluster's header line. */
1056 int old_wm = __argp_fmtstream_wmargin (pest->stream);
1057 print_header (cl->header, cl->argp, pest);
1058 __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1061 pest->first = 0;
1063 else
1064 __argp_fmtstream_puts (pest->stream, ", ");
1066 indent_to (pest->stream, col);
1069 /* Print help for ENTRY to STREAM. */
1070 static void
1071 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1072 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1074 unsigned num;
1075 const struct argp_option *real = entry->opt, *opt;
1076 char *so = entry->short_options;
1077 int have_long_opt = 0; /* We have any long options. */
1078 /* Saved margins. */
1079 int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1080 int old_wm = __argp_fmtstream_wmargin (stream);
1081 /* PEST is a state block holding some of our variables that we'd like to
1082 share with helper functions. */
1083 struct pentry_state pest = { entry, stream, hhstate, 1, state };
1085 if (! odoc (real))
1086 for (opt = real, num = entry->num; num > 0; opt++, num--)
1087 if (opt->name && ovisible (opt))
1089 have_long_opt = 1;
1090 break;
1093 /* First emit short options. */
1094 __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1095 for (opt = real, num = entry->num; num > 0; opt++, num--)
1096 if (oshort (opt) && opt->key == *so)
1097 /* OPT has a valid (non shadowed) short option. */
1099 if (ovisible (opt))
1101 comma (uparams.short_opt_col, &pest);
1102 __argp_fmtstream_putc (stream, '-');
1103 __argp_fmtstream_putc (stream, *so);
1104 if (!have_long_opt || uparams.dup_args)
1105 arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
1106 else if (real->arg)
1107 hhstate->suppressed_dup_arg = 1;
1109 so++;
1112 /* Now, long options. */
1113 if (odoc (real))
1114 /* A `documentation' option. */
1116 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1117 for (opt = real, num = entry->num; num > 0; opt++, num--)
1118 if (opt->name && ovisible (opt))
1120 comma (uparams.doc_opt_col, &pest);
1121 /* Calling gettext here isn't quite right, since sorting will
1122 have been done on the original; but documentation options
1123 should be pretty rare anyway... */
1124 __argp_fmtstream_puts (stream,
1125 dgettext (state->root_argp->argp_domain,
1126 opt->name));
1129 else
1130 /* A real long option. */
1132 int first_long_opt = 1;
1134 __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1135 for (opt = real, num = entry->num; num > 0; opt++, num--)
1136 if (opt->name && ovisible (opt))
1138 comma (uparams.long_opt_col, &pest);
1139 __argp_fmtstream_printf (stream, "--%s", opt->name);
1140 if (first_long_opt || uparams.dup_args)
1141 arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
1142 stream);
1143 else if (real->arg)
1144 hhstate->suppressed_dup_arg = 1;
1148 /* Next, documentation strings. */
1149 __argp_fmtstream_set_lmargin (stream, 0);
1151 if (pest.first)
1153 /* Didn't print any switches, what's up? */
1154 if (!oshort (real) && !real->name)
1155 /* This is a group header, print it nicely. */
1156 print_header (real->doc, entry->argp, &pest);
1157 else
1158 /* Just a totally shadowed option or null header; print nothing. */
1159 goto cleanup; /* Just return, after cleaning up. */
1161 else
1163 const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
1164 real->doc) : 0;
1165 const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1166 if (fstr && *fstr)
1168 unsigned int col = __argp_fmtstream_point (stream);
1170 __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1171 __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1173 if (col > (unsigned int) (uparams.opt_doc_col + 3))
1174 __argp_fmtstream_putc (stream, '\n');
1175 else if (col >= (unsigned int) uparams.opt_doc_col)
1176 __argp_fmtstream_puts (stream, " ");
1177 else
1178 indent_to (stream, uparams.opt_doc_col);
1180 __argp_fmtstream_puts (stream, fstr);
1182 if (fstr && fstr != tstr)
1183 free ((char *) fstr);
1185 /* Reset the left margin. */
1186 __argp_fmtstream_set_lmargin (stream, 0);
1187 __argp_fmtstream_putc (stream, '\n');
1190 hhstate->prev_entry = entry;
1192 cleanup:
1193 __argp_fmtstream_set_lmargin (stream, old_lm);
1194 __argp_fmtstream_set_wmargin (stream, old_wm);
1197 /* Output a long help message about the options in HOL to STREAM. */
1198 static void
1199 hol_help (struct hol *hol, const struct argp_state *state,
1200 argp_fmtstream_t stream)
1202 unsigned num;
1203 struct hol_entry *entry;
1204 struct hol_help_state hhstate = { 0, 0, 0 };
1206 for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1207 hol_entry_help (entry, state, stream, &hhstate);
1209 if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1211 const char *tstr = dgettext (state->root_argp->argp_domain, "\
1212 Mandatory or optional arguments to long options are also mandatory or \
1213 optional for any corresponding short options.");
1214 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1215 state ? state->root_argp : 0, state);
1216 if (fstr && *fstr)
1218 __argp_fmtstream_putc (stream, '\n');
1219 __argp_fmtstream_puts (stream, fstr);
1220 __argp_fmtstream_putc (stream, '\n');
1222 if (fstr && fstr != tstr)
1223 free ((char *) fstr);
1227 /* Helper functions for hol_usage. */
1229 /* If OPT is a short option without an arg, append its key to the string
1230 pointer pointer to by COOKIE, and advance the pointer. */
1231 static int
1232 add_argless_short_opt (const struct argp_option *opt,
1233 const struct argp_option *real,
1234 const char *domain, void *cookie)
1236 char **snao_end = cookie;
1237 if (!(opt->arg || real->arg)
1238 && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1239 *(*snao_end)++ = opt->key;
1240 return 0;
1243 /* If OPT is a short option with an arg, output a usage entry for it to the
1244 stream pointed at by COOKIE. */
1245 static int
1246 usage_argful_short_opt (const struct argp_option *opt,
1247 const struct argp_option *real,
1248 const char *domain, void *cookie)
1250 argp_fmtstream_t stream = cookie;
1251 const char *arg = opt->arg;
1252 int flags = opt->flags | real->flags;
1254 if (! arg)
1255 arg = real->arg;
1257 if (arg && !(flags & OPTION_NO_USAGE))
1259 arg = dgettext (domain, arg);
1261 if (flags & OPTION_ARG_OPTIONAL)
1262 __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1263 else
1265 /* Manually do line wrapping so that it (probably) won't
1266 get wrapped at the embedded space. */
1267 space (stream, 6 + strlen (arg));
1268 __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1272 return 0;
1275 /* Output a usage entry for the long option opt to the stream pointed at by
1276 COOKIE. */
1277 static int
1278 usage_long_opt (const struct argp_option *opt,
1279 const struct argp_option *real,
1280 const char *domain, void *cookie)
1282 argp_fmtstream_t stream = cookie;
1283 const char *arg = opt->arg;
1284 int flags = opt->flags | real->flags;
1286 if (! arg)
1287 arg = real->arg;
1289 if (! (flags & OPTION_NO_USAGE))
1291 if (arg)
1293 arg = dgettext (domain, arg);
1294 if (flags & OPTION_ARG_OPTIONAL)
1295 __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1296 else
1297 __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1299 else
1300 __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1303 return 0;
1306 /* Print a short usage description for the arguments in HOL to STREAM. */
1307 static void
1308 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1310 if (hol->num_entries > 0)
1312 unsigned nentries;
1313 struct hol_entry *entry;
1314 char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1315 char *snao_end = short_no_arg_opts;
1317 /* First we put a list of short options without arguments. */
1318 for (entry = hol->entries, nentries = hol->num_entries
1319 ; nentries > 0
1320 ; entry++, nentries--)
1321 hol_entry_short_iterate (entry, add_argless_short_opt,
1322 entry->argp->argp_domain, &snao_end);
1323 if (snao_end > short_no_arg_opts)
1325 *snao_end++ = 0;
1326 __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1329 /* Now a list of short options *with* arguments. */
1330 for (entry = hol->entries, nentries = hol->num_entries
1331 ; nentries > 0
1332 ; entry++, nentries--)
1333 hol_entry_short_iterate (entry, usage_argful_short_opt,
1334 entry->argp->argp_domain, stream);
1336 /* Finally, a list of long options (whew!). */
1337 for (entry = hol->entries, nentries = hol->num_entries
1338 ; nentries > 0
1339 ; entry++, nentries--)
1340 hol_entry_long_iterate (entry, usage_long_opt,
1341 entry->argp->argp_domain, stream);
1345 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1346 cluster in which ARGP's entries should be clustered, or 0. */
1347 static struct hol *
1348 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1350 const struct argp_child *child = argp->children;
1351 struct hol *hol = make_hol (argp, cluster);
1352 if (child)
1353 while (child->argp)
1355 struct hol_cluster *child_cluster =
1356 ((child->group || child->header)
1357 /* Put CHILD->argp within its own cluster. */
1358 ? hol_add_cluster (hol, child->group, child->header,
1359 child - argp->children, cluster, argp)
1360 /* Just merge it into the parent's cluster. */
1361 : cluster);
1362 hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1363 child++;
1365 return hol;
1368 /* Calculate how many different levels with alternative args strings exist in
1369 ARGP. */
1370 static size_t
1371 argp_args_levels (const struct argp *argp)
1373 size_t levels = 0;
1374 const struct argp_child *child = argp->children;
1376 if (argp->args_doc && strchr (argp->args_doc, '\n'))
1377 levels++;
1379 if (child)
1380 while (child->argp)
1381 levels += argp_args_levels ((child++)->argp);
1383 return levels;
1386 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1387 preceded by a space. LEVELS is a pointer to a byte vector the length
1388 returned by argp_args_levels; it should be initialized to zero, and
1389 updated by this routine for the next call if ADVANCE is true. True is
1390 returned as long as there are more patterns to output. */
1391 static int
1392 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1393 char **levels, int advance, argp_fmtstream_t stream)
1395 char *our_level = *levels;
1396 int multiple = 0;
1397 const struct argp_child *child = argp->children;
1398 const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1399 const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1401 if (fdoc)
1403 const char *cp = fdoc;
1404 nl = __strchrnul (cp, '\n');
1405 if (*nl != '\0')
1406 /* This is a `multi-level' args doc; advance to the correct position
1407 as determined by our state in LEVELS, and update LEVELS. */
1409 int i;
1410 multiple = 1;
1411 for (i = 0; i < *our_level; i++)
1412 cp = nl + 1, nl = __strchrnul (cp, '\n');
1413 (*levels)++;
1416 /* Manually do line wrapping so that it (probably) won't get wrapped at
1417 any embedded spaces. */
1418 space (stream, 1 + nl - cp);
1420 __argp_fmtstream_write (stream, cp, nl - cp);
1422 if (fdoc && fdoc != tdoc)
1423 free ((char *)fdoc); /* Free user's modified doc string. */
1425 if (child)
1426 while (child->argp)
1427 advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1429 if (advance && multiple)
1431 /* Need to increment our level. */
1432 if (*nl)
1433 /* There's more we can do here. */
1435 (*our_level)++;
1436 advance = 0; /* Our parent shouldn't advance also. */
1438 else if (*our_level > 0)
1439 /* We had multiple levels, but used them up; reset to zero. */
1440 *our_level = 0;
1443 return !advance;
1446 /* Print the documentation for ARGP to STREAM; if POST is false, then
1447 everything preceeding a `\v' character in the documentation strings (or
1448 the whole string, for those with none) is printed, otherwise, everything
1449 following the `\v' character (nothing for strings without). Each separate
1450 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1451 then the first is as well. If FIRST_ONLY is true, only the first
1452 occurrence is output. Returns true if anything was output. */
1453 static int
1454 argp_doc (const struct argp *argp, const struct argp_state *state,
1455 int post, int pre_blank, int first_only,
1456 argp_fmtstream_t stream)
1458 const char *text;
1459 const char *inp_text;
1460 void *input = 0;
1461 int anything = 0;
1462 size_t inp_text_limit = 0;
1463 const char *doc = dgettext (argp->argp_domain, argp->doc);
1464 const struct argp_child *child = argp->children;
1466 if (doc)
1468 char *vt = strchr (doc, '\v');
1469 inp_text = post ? (vt ? vt + 1 : 0) : doc;
1470 inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1472 else
1473 inp_text = 0;
1475 if (argp->help_filter)
1476 /* We have to filter the doc strings. */
1478 if (inp_text_limit)
1479 /* Copy INP_TEXT so that it's nul-terminated. */
1480 inp_text = __strndup (inp_text, inp_text_limit);
1481 input = __argp_input (argp, state);
1482 text =
1483 (*argp->help_filter) (post
1484 ? ARGP_KEY_HELP_POST_DOC
1485 : ARGP_KEY_HELP_PRE_DOC,
1486 inp_text, input);
1488 else
1489 text = (const char *) inp_text;
1491 if (text)
1493 if (pre_blank)
1494 __argp_fmtstream_putc (stream, '\n');
1496 if (text == inp_text && inp_text_limit)
1497 __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1498 else
1499 __argp_fmtstream_puts (stream, text);
1501 if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1502 __argp_fmtstream_putc (stream, '\n');
1504 anything = 1;
1507 if (text && text != inp_text)
1508 free ((char *) text); /* Free TEXT returned from the help filter. */
1509 if (inp_text && inp_text_limit && argp->help_filter)
1510 free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
1512 if (post && argp->help_filter)
1513 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1515 text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1516 if (text)
1518 if (anything || pre_blank)
1519 __argp_fmtstream_putc (stream, '\n');
1520 __argp_fmtstream_puts (stream, text);
1521 free ((char *) text);
1522 if (__argp_fmtstream_point (stream)
1523 > __argp_fmtstream_lmargin (stream))
1524 __argp_fmtstream_putc (stream, '\n');
1525 anything = 1;
1529 if (child)
1530 while (child->argp && !(first_only && anything))
1531 anything |=
1532 argp_doc ((child++)->argp, state,
1533 post, anything || pre_blank, first_only,
1534 stream);
1536 return anything;
1539 /* Output a usage message for ARGP to STREAM. If called from
1540 argp_state_help, STATE is the relevent parsing state. FLAGS are from the
1541 set ARGP_HELP_*. NAME is what to use wherever a `program name' is
1542 needed. */
1543 static void
1544 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1545 unsigned flags, char *name)
1547 int anything = 0; /* Whether we've output anything. */
1548 struct hol *hol = 0;
1549 argp_fmtstream_t fs;
1551 if (! stream)
1552 return;
1554 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1555 __flockfile (stream);
1556 #endif
1558 if (! uparams.valid)
1559 fill_in_uparams (state);
1561 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1562 if (! fs)
1564 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1565 __funlockfile (stream);
1566 #endif
1567 return;
1570 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1572 hol = argp_hol (argp, 0);
1574 /* If present, these options always come last. */
1575 hol_set_group (hol, "help", -1);
1576 hol_set_group (hol, "version", -1);
1578 hol_sort (hol);
1581 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1582 /* Print a short `Usage:' message. */
1584 int first_pattern = 1, more_patterns;
1585 size_t num_pattern_levels = argp_args_levels (argp);
1586 char *pattern_levels = alloca (num_pattern_levels);
1588 memset (pattern_levels, 0, num_pattern_levels);
1592 int old_lm;
1593 int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1594 char *levels = pattern_levels;
1596 if (first_pattern)
1597 __argp_fmtstream_printf (fs, "%s %s",
1598 dgettext (argp->argp_domain, "Usage:"),
1599 name);
1600 else
1601 __argp_fmtstream_printf (fs, "%s %s",
1602 dgettext (argp->argp_domain, " or: "),
1603 name);
1605 /* We set the lmargin as well as the wmargin, because hol_usage
1606 manually wraps options with newline to avoid annoying breaks. */
1607 old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1609 if (flags & ARGP_HELP_SHORT_USAGE)
1610 /* Just show where the options go. */
1612 if (hol->num_entries > 0)
1613 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1614 " [OPTION...]"));
1616 else
1617 /* Actually print the options. */
1619 hol_usage (hol, fs);
1620 flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
1623 more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1625 __argp_fmtstream_set_wmargin (fs, old_wm);
1626 __argp_fmtstream_set_lmargin (fs, old_lm);
1628 __argp_fmtstream_putc (fs, '\n');
1629 anything = 1;
1631 first_pattern = 0;
1633 while (more_patterns);
1636 if (flags & ARGP_HELP_PRE_DOC)
1637 anything |= argp_doc (argp, state, 0, 0, 1, fs);
1639 if (flags & ARGP_HELP_SEE)
1641 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1642 Try `%s --help' or `%s --usage' for more information.\n"),
1643 name, name);
1644 anything = 1;
1647 if (flags & ARGP_HELP_LONG)
1648 /* Print a long, detailed help message. */
1650 /* Print info about all the options. */
1651 if (hol->num_entries > 0)
1653 if (anything)
1654 __argp_fmtstream_putc (fs, '\n');
1655 hol_help (hol, state, fs);
1656 anything = 1;
1660 if (flags & ARGP_HELP_POST_DOC)
1661 /* Print any documentation strings at the end. */
1662 anything |= argp_doc (argp, state, 1, anything, 0, fs);
1664 if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1666 if (anything)
1667 __argp_fmtstream_putc (fs, '\n');
1668 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1669 "Report bugs to %s.\n"),
1670 argp_program_bug_address);
1671 anything = 1;
1674 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1675 __funlockfile (stream);
1676 #endif
1678 if (hol)
1679 hol_free (hol);
1681 __argp_fmtstream_free (fs);
1684 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1685 ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
1686 void __argp_help (const struct argp *argp, FILE *stream,
1687 unsigned flags, char *name)
1689 _help (argp, 0, stream, flags, name);
1691 #ifdef weak_alias
1692 weak_alias (__argp_help, argp_help)
1693 #endif
1695 #ifndef _LIBC
1696 char *__argp_basename (char *name)
1698 char *short_name = strrchr (name, '/');
1699 return short_name ? short_name + 1 : name;
1702 char *
1703 __argp_short_program_name (void)
1705 # if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
1706 return program_invocation_short_name;
1707 # elif HAVE_DECL_PROGRAM_INVOCATION_NAME
1708 return __argp_basename (program_invocation_name);
1709 # else
1710 /* FIXME: What now? Miles suggests that it is better to use NULL,
1711 but currently the value is passed on directly to fputs_unlocked,
1712 so that requires more changes. */
1713 # if __GNUC__
1714 # warning No reasonable value to return
1715 # endif /* __GNUC__ */
1716 return "";
1717 # endif
1719 #endif
1721 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1722 from the set ARGP_HELP_*. */
1723 void
1724 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1726 if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1728 if (state && (state->flags & ARGP_LONG_ONLY))
1729 flags |= ARGP_HELP_LONG_ONLY;
1731 _help (state ? state->root_argp : 0, state, stream, flags,
1732 state ? state->name : __argp_short_program_name ());
1734 if (!state || ! (state->flags & ARGP_NO_EXIT))
1736 if (flags & ARGP_HELP_EXIT_ERR)
1737 exit (argp_err_exit_status);
1738 if (flags & ARGP_HELP_EXIT_OK)
1739 exit (0);
1743 #ifdef weak_alias
1744 weak_alias (__argp_state_help, argp_state_help)
1745 #endif
1747 /* If appropriate, print the printf string FMT and following args, preceded
1748 by the program name and `:', to stderr, and followed by a `Try ... --help'
1749 message, then exit (1). */
1750 void
1751 __argp_error (const struct argp_state *state, const char *fmt, ...)
1753 if (!state || !(state->flags & ARGP_NO_ERRS))
1755 FILE *stream = state ? state->err_stream : stderr;
1757 if (stream)
1759 va_list ap;
1761 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1762 __flockfile (stream);
1763 #endif
1765 va_start (ap, fmt);
1767 #ifdef _LIBC
1768 char *buf;
1770 if (_IO_vasprintf (&buf, fmt, ap) < 0)
1771 buf = NULL;
1773 __fxprintf (stream, "%s: %s\n",
1774 state ? state->name : __argp_short_program_name (), buf);
1776 free (buf);
1777 #else
1778 fputs_unlocked (state ? 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);
1786 #endif
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 _LIBC
1825 __fxprintf (stream, "%s",
1826 state ? state->name : __argp_short_program_name ());
1827 #else
1828 fputs_unlocked (state ? state->name : __argp_short_program_name (),
1829 stream);
1830 #endif
1832 if (fmt)
1834 va_list ap;
1836 va_start (ap, fmt);
1837 #ifdef _LIBC
1838 char *buf;
1840 if (_IO_vasprintf (&buf, fmt, ap) < 0)
1841 buf = NULL;
1843 __fxprintf (stream, ": %s", buf);
1845 free (buf);
1846 #else
1847 putc_unlocked (':', stream);
1848 putc_unlocked (' ', stream);
1850 vfprintf (stream, fmt, ap);
1851 #endif
1853 va_end (ap);
1856 if (errnum)
1858 char buf[200];
1860 #ifdef _LIBC
1861 __fxprintf (stream, ": %s",
1862 __strerror_r (errnum, buf, sizeof (buf)));
1863 #else
1864 putc_unlocked (':', stream);
1865 putc_unlocked (' ', stream);
1866 # ifdef HAVE_STRERROR_R
1867 fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
1868 # else
1869 fputs (strerror (errnum), stream);
1870 # endif
1871 #endif
1874 #ifdef USE_IN_LIBIO
1875 if (_IO_fwide (stream, 0) > 0)
1876 putwc_unlocked (L'\n', stream);
1877 else
1878 #endif
1879 putc_unlocked ('\n', stream);
1881 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1882 __funlockfile (stream);
1883 #endif
1885 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1886 exit (status);
1890 #ifdef weak_alias
1891 weak_alias (__argp_failure, argp_failure)
1892 #endif