s/putc_unlocked/putc/g for freebsd on alpha
[shishi.git] / argp / argp-help.c
blob7780c3e4d2841d1f7e82a7b29b5238b7158888b7
1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995,1996,1997,1998,1999,2000 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 Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 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 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 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 #ifndef alloca
30 # ifdef __GNUC__
31 # define alloca __builtin_alloca
32 # define HAVE_ALLOCA 1
33 # else
34 # if defined HAVE_ALLOCA_H || defined _LIBC
35 # include <alloca.h>
36 # else
37 # ifdef _AIX
38 #pragma alloca
39 # else
40 # ifndef alloca
41 char *alloca ();
42 # endif
43 # endif
44 # endif
45 # endif
46 #endif
48 #include <stddef.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <assert.h>
52 #include <stdarg.h>
53 #include <malloc.h>
54 #include <ctype.h>
57 #ifndef _
58 /* This is for other GNU distributions with internationalized messages. */
59 # if defined HAVE_LIBINTL_H || defined _LIBC
60 # include <libintl.h>
61 # ifdef _LIBC
62 # undef dgettext
63 # define dgettext(domain, msgid) __dcgettext (domain, msgid, LC_MESSAGES)
64 # endif
65 # else
66 # define dgettext(domain, msgid) (msgid)
67 # endif
68 #endif
70 #include "argp.h"
71 #include "argp-fmtstream.h"
72 #include "argp-namefrob.h"
75 /* FIXME: We could use a configure test to check for __attribute__,
76 * just like lsh does. */
77 #ifndef UNUSED
78 # if __GNUC__ >= 2
79 # define UNUSED __attribute__ ((__unused__))
80 # else
81 # define UNUSED
82 # endif
83 #endif
85 #ifndef _LIBC
86 # ifndef __strchrnul
87 # define __strchrnul strchrnul
88 # endif
89 # ifndef __mempcpy
90 # define __mempcpy mempcpy
91 # endif
92 /* We need to use a different name, as __strndup is likely a macro. */
93 # define STRNDUP strndup
94 # ifndef __flockfile
95 # define __flockfile flockfile
96 # endif
97 # ifndef __funlockfile
98 # define __funlockfile funlockfile
99 # endif
100 # if HAVE_STRERROR
101 # define STRERROR strerror
102 # else
103 # define STRERROR(x) (sys_errlist[x])
104 # endif
105 #else /* _LIBC */
106 # define STRNDUP __strndup
107 # define STRERROR strerror
108 #endif
110 #if !_LIBC
111 # if !HAVE_STRNDUP
112 char *strndup (const char *s, size_t size);
113 # endif /* !HAVE_STRNDUP */
115 # if !HAVE_MEMPCPY
116 void *mempcpy (void *to, const void *from, size_t size);
117 # endif /* !HAVE_MEMPCPY */
119 # if !HAVE_STRCHRNUL
120 char *strchrnul(const char *s, int c);
121 # endif /* !HAVE_STRCHRNUL */
123 #endif /* !_LIBC */
126 /* User-selectable (using an environment variable) formatting parameters.
128 These may be specified in an environment variable called `ARGP_HELP_FMT',
129 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
130 Where VALn must be a positive integer. The list of variables is in the
131 UPARAM_NAMES vector, below. */
133 /* Default parameters. */
134 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
135 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
136 #define SHORT_OPT_COL 2 /* column in which short options start */
137 #define LONG_OPT_COL 6 /* column in which long options start */
138 #define DOC_OPT_COL 2 /* column in which doc options start */
139 #define OPT_DOC_COL 29 /* column in which option text starts */
140 #define HEADER_COL 1 /* column in which group headers are printed */
141 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
142 #define RMARGIN 79 /* right margin used for wrapping */
144 /* User-selectable (using an environment variable) formatting parameters.
145 They must all be of type `int' for the parsing code to work. */
146 struct uparams
148 /* If true, arguments for an option are shown with both short and long
149 options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
150 If false, then if an option has both, the argument is only shown with
151 the long one, e.g., `-x, --longx=ARG', and a message indicating that
152 this really means both is printed below the options. */
153 int dup_args;
155 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
156 been suppressed, an explanatory message should be printed. */
157 int dup_args_note;
159 /* Various output columns. */
160 int short_opt_col;
161 int long_opt_col;
162 int doc_opt_col;
163 int opt_doc_col;
164 int header_col;
165 int usage_indent;
166 int rmargin;
168 int valid; /* True when the values in here are valid. */
171 /* This is a global variable, as user options are only ever read once. */
172 static struct uparams uparams = {
173 DUP_ARGS, DUP_ARGS_NOTE,
174 SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
175 USAGE_INDENT, RMARGIN,
179 /* A particular uparam, and what the user name is. */
180 struct uparam_name
182 const char *name; /* User name. */
183 int is_bool; /* Whether it's `boolean'. */
184 size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
187 /* The name-field mappings we know about. */
188 static const struct uparam_name uparam_names[] =
190 { "dup-args", 1, offsetof (struct uparams, dup_args) },
191 { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
192 { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
193 { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
194 { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
195 { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
196 { "header-col", 0, offsetof (struct uparams, header_col) },
197 { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
198 { "rmargin", 0, offsetof (struct uparams, rmargin) },
199 { 0 }
202 /* Read user options from the environment, and fill in UPARAMS appropiately. */
203 static void
204 fill_in_uparams (const struct argp_state *state)
206 /* FIXME: Can we get away without an explicit cast? */
207 const unsigned char *var = (unsigned char *) getenv ("ARGP_HELP_FMT");
209 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
211 if (var)
212 /* Parse var. */
213 while (*var)
215 SKIPWS (var);
217 if (isalpha (*var))
219 size_t var_len;
220 const struct uparam_name *un;
221 int unspec = 0, val = 0;
222 const unsigned char *arg = var;
224 while (isalnum (*arg) || *arg == '-' || *arg == '_')
225 arg++;
226 var_len = arg - var;
228 SKIPWS (arg);
230 if (*arg == '\0' || *arg == ',')
231 unspec = 1;
232 else if (*arg == '=')
234 arg++;
235 SKIPWS (arg);
238 if (unspec)
240 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
242 val = 0;
243 var += 3;
244 var_len -= 3;
246 else
247 val = 1;
249 else if (isdigit (*arg))
251 val = atoi (arg);
252 while (isdigit (*arg))
253 arg++;
254 SKIPWS (arg);
257 for (un = uparam_names; un->name; un++)
258 if (strlen (un->name) == var_len
259 && strncmp (var, un->name, var_len) == 0)
261 if (unspec && !un->is_bool)
262 __argp_failure (state, 0, 0,
263 dgettext (state->root_argp->argp_domain, "\
264 %.*s: ARGP_HELP_FMT parameter requires a value"),
265 (int) var_len, var);
266 else
267 *(int *)((char *)&uparams + un->uparams_offs) = val;
268 break;
270 if (! un->name)
271 __argp_failure (state, 0, 0,
272 dgettext (state->root_argp->argp_domain, "\
273 %.*s: Unknown ARGP_HELP_FMT parameter"),
274 (int) var_len, var);
276 var = arg;
277 if (*var == ',')
278 var++;
280 else if (*var)
282 __argp_failure (state, 0, 0,
283 dgettext (state->root_argp->argp_domain,
284 "Garbage in ARGP_HELP_FMT: %s"), var);
285 break;
290 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
291 whether OPT is displayed or used in sorting, not option shadowing. */
292 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
294 /* Returns true if OPT is an alias for an earlier option. */
295 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
297 /* Returns true if OPT is an documentation-only entry. */
298 #define odoc(opt) ((opt)->flags & OPTION_DOC)
300 /* Returns true if OPT is the end-of-list marker for a list of options. */
301 #define oend(opt) __option_is_end (opt)
303 /* Returns true if OPT has a short option. */
304 #define oshort(opt) __option_is_short (opt)
307 The help format for a particular option is like:
309 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
311 Where ARG will be omitted if there's no argument, for this option, or
312 will be surrounded by "[" and "]" appropiately if the argument is
313 optional. The documentation string is word-wrapped appropiately, and if
314 the list of options is long enough, it will be started on a separate line.
315 If there are no short options for a given option, the first long option is
316 indented slighly in a way that's supposed to make most long options appear
317 to be in a separate column.
319 For example, the following output (from ps):
321 -p PID, --pid=PID List the process PID
322 --pgrp=PGRP List processes in the process group PGRP
323 -P, -x, --no-parent Include processes without parents
324 -Q, --all-fields Don't elide unusable fields (normally if there's
325 some reason ps can't print a field for any
326 process, it's removed from the output entirely)
327 -r, --reverse, --gratuitously-long-reverse-option
328 Reverse the order of any sort
329 --session[=SID] Add the processes from the session SID (which
330 defaults to the sid of the current process)
332 Here are some more options:
333 -f ZOT, --foonly=ZOT Glork a foonly
334 -z, --zaza Snit a zar
336 -?, --help Give this help list
337 --usage Give a short usage message
338 -V, --version Print program version
340 The struct argp_option array for the above could look like:
343 {"pid", 'p', "PID", 0, "List the process PID"},
344 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
345 {"no-parent", 'P', 0, 0, "Include processes without parents"},
346 {0, 'x', 0, OPTION_ALIAS},
347 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
348 " if there's some reason ps can't"
349 " print a field for any process, it's"
350 " removed from the output entirely)" },
351 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
352 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
353 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
354 "Add the processes from the session"
355 " SID (which defaults to the sid of"
356 " the current process)" },
358 {0,0,0,0, "Here are some more options:"},
359 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
360 {"zaza", 'z', 0, 0, "Snit a zar"},
365 Note that the last three options are automatically supplied by argp_parse,
366 unless you tell it not to with ARGP_NO_HELP.
370 /* Returns true if CH occurs between BEG and END. */
371 static int
372 find_char (char ch, char *beg, char *end)
374 while (beg < end)
375 if (*beg == ch)
376 return 1;
377 else
378 beg++;
379 return 0;
382 struct hol_cluster; /* fwd decl */
384 struct hol_entry
386 /* First option. */
387 const struct argp_option *opt;
388 /* Number of options (including aliases). */
389 unsigned num;
391 /* A pointers into the HOL's short_options field, to the first short option
392 letter for this entry. The order of the characters following this point
393 corresponds to the order of options pointed to by OPT, and there are at
394 most NUM. A short option recorded in a option following OPT is only
395 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
396 probably been shadowed by some other entry). */
397 char *short_options;
399 /* Entries are sorted by their group first, in the order:
400 1, 2, ..., n, 0, -m, ..., -2, -1
401 and then alphabetically within each group. The default is 0. */
402 int group;
404 /* The cluster of options this entry belongs to, or 0 if none. */
405 struct hol_cluster *cluster;
407 /* The argp from which this option came. */
408 const struct argp *argp;
411 /* A cluster of entries to reflect the argp tree structure. */
412 struct hol_cluster
414 /* A descriptive header printed before options in this cluster. */
415 const char *header;
417 /* Used to order clusters within the same group with the same parent,
418 according to the order in which they occurred in the parent argp's child
419 list. */
420 int index;
422 /* How to sort this cluster with respect to options and other clusters at the
423 same depth (clusters always follow options in the same group). */
424 int group;
426 /* The cluster to which this cluster belongs, or 0 if it's at the base
427 level. */
428 struct hol_cluster *parent;
430 /* The argp from which this cluster is (eventually) derived. */
431 const struct argp *argp;
433 /* The distance this cluster is from the root. */
434 int depth;
436 /* Clusters in a given hol are kept in a linked list, to make freeing them
437 possible. */
438 struct hol_cluster *next;
441 /* A list of options for help. */
442 struct hol
444 /* An array of hol_entry's. */
445 struct hol_entry *entries;
446 /* The number of entries in this hol. If this field is zero, the others
447 are undefined. */
448 unsigned num_entries;
450 /* A string containing all short options in this HOL. Each entry contains
451 pointers into this string, so the order can't be messed with blindly. */
452 char *short_options;
454 /* Clusters of entries in this hol. */
455 struct hol_cluster *clusters;
458 /* Create a struct hol from the options in ARGP. CLUSTER is the
459 hol_cluster in which these entries occur, or 0, if at the root. */
460 static struct hol *
461 make_hol (const struct argp *argp, struct hol_cluster *cluster)
463 char *so;
464 const struct argp_option *o;
465 const struct argp_option *opts = argp->options;
466 struct hol_entry *entry;
467 unsigned num_short_options = 0;
468 struct hol *hol = malloc (sizeof (struct hol));
470 assert (hol);
472 hol->num_entries = 0;
473 hol->clusters = 0;
475 if (opts)
477 int cur_group = 0;
479 /* The first option must not be an alias. */
480 assert (! oalias (opts));
482 /* Calculate the space needed. */
483 for (o = opts; ! oend (o); o++)
485 if (! oalias (o))
486 hol->num_entries++;
487 if (oshort (o))
488 num_short_options++; /* This is an upper bound. */
491 hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
492 hol->short_options = malloc (num_short_options + 1);
494 assert (hol->entries && hol->short_options);
496 /* Fill in the entries. */
497 so = hol->short_options;
498 for (o = opts, entry = hol->entries; ! oend (o); entry++)
500 entry->opt = o;
501 entry->num = 0;
502 entry->short_options = so;
503 entry->group = cur_group =
504 o->group
505 ? o->group
506 : ((!o->name && !o->key)
507 ? cur_group + 1
508 : cur_group);
509 entry->cluster = cluster;
510 entry->argp = argp;
514 entry->num++;
515 if (oshort (o) && ! find_char (o->key, hol->short_options, so))
516 /* O has a valid short option which hasn't already been used.*/
517 *so++ = o->key;
518 o++;
520 while (! oend (o) && oalias (o));
522 *so = '\0'; /* null terminated so we can find the length */
525 return hol;
528 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
529 associated argp child list entry), INDEX, and PARENT, and return a pointer
530 to it. ARGP is the argp that this cluster results from. */
531 static struct hol_cluster *
532 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
533 struct hol_cluster *parent, const struct argp *argp)
535 struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
536 if (cl)
538 cl->group = group;
539 cl->header = header;
541 cl->index = index;
542 cl->parent = parent;
543 cl->argp = argp;
544 cl->depth = parent ? parent->depth + 1 : 0;
546 cl->next = hol->clusters;
547 hol->clusters = cl;
549 return cl;
552 /* Free HOL and any resources it uses. */
553 static void
554 hol_free (struct hol *hol)
556 struct hol_cluster *cl = hol->clusters;
558 while (cl)
560 struct hol_cluster *next = cl->next;
561 free (cl);
562 cl = next;
565 if (hol->num_entries > 0)
567 free (hol->entries);
568 free (hol->short_options);
571 free (hol);
574 static inline int
575 hol_entry_short_iterate (const struct hol_entry *entry,
576 int (*func)(const struct argp_option *opt,
577 const struct argp_option *real,
578 const char *domain, void *cookie),
579 const char *domain, void *cookie)
581 unsigned nopts;
582 int val = 0;
583 const struct argp_option *opt, *real = entry->opt;
584 char *so = entry->short_options;
586 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
587 if (oshort (opt) && *so == opt->key)
589 if (!oalias (opt))
590 real = opt;
591 if (ovisible (opt))
592 val = (*func)(opt, real, domain, cookie);
593 so++;
596 return val;
599 static inline int
600 hol_entry_long_iterate (const struct hol_entry *entry,
601 int (*func)(const struct argp_option *opt,
602 const struct argp_option *real,
603 const char *domain, void *cookie),
604 const char *domain, void *cookie)
606 unsigned nopts;
607 int val = 0;
608 const struct argp_option *opt, *real = entry->opt;
610 for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
611 if (opt->name)
613 if (!oalias (opt))
614 real = opt;
615 if (ovisible (opt))
616 val = (*func)(opt, real, domain, cookie);
619 return val;
622 /* Iterator that returns true for the first short option. */
623 static inline int
624 until_short (const struct argp_option *opt, const struct argp_option *real UNUSED,
625 const char *domain UNUSED, void *cookie UNUSED)
627 return oshort (opt) ? opt->key : 0;
630 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
631 static char
632 hol_entry_first_short (const struct hol_entry *entry)
634 return hol_entry_short_iterate (entry, until_short,
635 entry->argp->argp_domain, 0);
638 /* Returns the first valid long option in ENTRY, or 0 if there is none. */
639 static const char *
640 hol_entry_first_long (const struct hol_entry *entry)
642 const struct argp_option *opt;
643 unsigned num;
644 for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
645 if (opt->name && ovisible (opt))
646 return opt->name;
647 return 0;
650 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
651 none. */
652 static struct hol_entry *
653 hol_find_entry (struct hol *hol, const char *name)
655 struct hol_entry *entry = hol->entries;
656 unsigned num_entries = hol->num_entries;
658 while (num_entries-- > 0)
660 const struct argp_option *opt = entry->opt;
661 unsigned num_opts = entry->num;
663 while (num_opts-- > 0)
664 if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
665 return entry;
666 else
667 opt++;
669 entry++;
672 return 0;
675 /* If an entry with the long option NAME occurs in HOL, set it's special
676 sort position to GROUP. */
677 static void
678 hol_set_group (struct hol *hol, const char *name, int group)
680 struct hol_entry *entry = hol_find_entry (hol, name);
681 if (entry)
682 entry->group = group;
685 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
686 EQ is what to return if GROUP1 and GROUP2 are the same. */
687 static int
688 group_cmp (int group1, int group2, int eq)
690 if (group1 == group2)
691 return eq;
692 else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
693 return group1 - group2;
694 else
695 return group2 - group1;
698 /* Compare clusters CL1 & CL2 by the order that they should appear in
699 output. */
700 static int
701 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
703 /* If one cluster is deeper than the other, use its ancestor at the same
704 level, so that finding the common ancestor is straightforward. */
705 while (cl1->depth < cl2->depth)
706 cl1 = cl1->parent;
707 while (cl2->depth < cl1->depth)
708 cl2 = cl2->parent;
710 /* Now reduce both clusters to their ancestors at the point where both have
711 a common parent; these can be directly compared. */
712 while (cl1->parent != cl2->parent)
713 cl1 = cl1->parent, cl2 = cl2->parent;
715 return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
718 /* Return the ancestor of CL that's just below the root (i.e., has a parent
719 of 0). */
720 static struct hol_cluster *
721 hol_cluster_base (struct hol_cluster *cl)
723 while (cl->parent)
724 cl = cl->parent;
725 return cl;
728 /* Return true if CL1 is a child of CL2. */
729 static int
730 hol_cluster_is_child (const struct hol_cluster *cl1,
731 const struct hol_cluster *cl2)
733 while (cl1 && cl1 != cl2)
734 cl1 = cl1->parent;
735 return cl1 == cl2;
738 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
739 that should be used for comparisons, and returns true iff it should be
740 treated as a non-option. */
742 /* FIXME: Can we use unsigned char * for the argument? */
743 static int
744 canon_doc_option (const char **name)
746 int non_opt;
747 /* Skip initial whitespace. */
748 while (isspace ( (unsigned char) **name))
749 (*name)++;
750 /* Decide whether this looks like an option (leading `-') or not. */
751 non_opt = (**name != '-');
752 /* Skip until part of name used for sorting. */
753 while (**name && !isalnum ( (unsigned char) **name))
754 (*name)++;
755 return non_opt;
758 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
759 listing. */
760 static int
761 hol_entry_cmp (const struct hol_entry *entry1,
762 const struct hol_entry *entry2)
764 /* The group numbers by which the entries should be ordered; if either is
765 in a cluster, then this is just the group within the cluster. */
766 int group1 = entry1->group, group2 = entry2->group;
768 if (entry1->cluster != entry2->cluster)
770 /* The entries are not within the same cluster, so we can't compare them
771 directly, we have to use the appropiate clustering level too. */
772 if (! entry1->cluster)
773 /* ENTRY1 is at the `base level', not in a cluster, so we have to
774 compare it's group number with that of the base cluster in which
775 ENTRY2 resides. Note that if they're in the same group, the
776 clustered option always comes laster. */
777 return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
778 else if (! entry2->cluster)
779 /* Likewise, but ENTRY2's not in a cluster. */
780 return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
781 else
782 /* Both entries are in clusters, we can just compare the clusters. */
783 return hol_cluster_cmp (entry1->cluster, entry2->cluster);
785 else if (group1 == group2)
786 /* The entries are both in the same cluster and group, so compare them
787 alphabetically. */
789 int short1 = hol_entry_first_short (entry1);
790 int short2 = hol_entry_first_short (entry2);
791 int doc1 = odoc (entry1->opt);
792 int doc2 = odoc (entry2->opt);
793 /* FIXME: Can we use unsigned char * instead? */
794 const char *long1 = hol_entry_first_long (entry1);
795 const char *long2 = hol_entry_first_long (entry2);
797 if (doc1)
798 doc1 = canon_doc_option (&long1);
799 if (doc2)
800 doc2 = canon_doc_option (&long2);
802 if (doc1 != doc2)
803 /* `documentation' options always follow normal options (or
804 documentation options that *look* like normal options). */
805 return doc1 - doc2;
806 else if (!short1 && !short2 && long1 && long2)
807 /* Only long options. */
808 return __strcasecmp (long1, long2);
809 else
810 /* Compare short/short, long/short, short/long, using the first
811 character of long options. Entries without *any* valid
812 options (such as options with OPTION_HIDDEN set) will be put
813 first, but as they're not displayed, it doesn't matter where
814 they are. */
816 unsigned char first1 = short1 ? short1 : long1 ? *long1 : 0;
817 unsigned char first2 = short2 ? short2 : long2 ? *long2 : 0;
818 #ifdef _tolower
819 int lower_cmp = _tolower (first1) - _tolower (first2);
820 #else
821 int lower_cmp = tolower (first1) - tolower (first2);
822 #endif
823 /* Compare ignoring case, except when the options are both the
824 same letter, in which case lower-case always comes first. */
825 /* NOTE: The subtraction below does the right thing
826 even with eight-bit chars: first1 and first2 are
827 converted to int *before* the subtraction. */
828 return lower_cmp ? lower_cmp : first2 - first1;
831 else
832 /* Within the same cluster, but not the same group, so just compare
833 groups. */
834 return group_cmp (group1, group2, 0);
837 /* Version of hol_entry_cmp with correct signature for qsort. */
838 static int
839 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
841 return hol_entry_cmp (entry1_v, entry2_v);
844 /* Sort HOL by group and alphabetically by option name (with short options
845 taking precedence over long). Since the sorting is for display purposes
846 only, the shadowing of options isn't effected. */
847 static void
848 hol_sort (struct hol *hol)
850 if (hol->num_entries > 0)
851 qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
852 hol_entry_qcmp);
855 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
856 any in MORE with the same name. */
857 static void
858 hol_append (struct hol *hol, struct hol *more)
860 struct hol_cluster **cl_end = &hol->clusters;
862 /* Steal MORE's cluster list, and add it to the end of HOL's. */
863 while (*cl_end)
864 cl_end = &(*cl_end)->next;
865 *cl_end = more->clusters;
866 more->clusters = 0;
868 /* Merge entries. */
869 if (more->num_entries > 0)
871 if (hol->num_entries == 0)
873 hol->num_entries = more->num_entries;
874 hol->entries = more->entries;
875 hol->short_options = more->short_options;
876 more->num_entries = 0; /* Mark MORE's fields as invalid. */
878 else
879 /* Append the entries in MORE to those in HOL, taking care to only add
880 non-shadowed SHORT_OPTIONS values. */
882 unsigned left;
883 char *so, *more_so;
884 struct hol_entry *e;
885 unsigned num_entries = hol->num_entries + more->num_entries;
886 struct hol_entry *entries =
887 malloc (num_entries * sizeof (struct hol_entry));
888 unsigned hol_so_len = strlen (hol->short_options);
889 char *short_options =
890 malloc (hol_so_len + strlen (more->short_options) + 1);
892 __mempcpy (__mempcpy (entries, hol->entries,
893 hol->num_entries * sizeof (struct hol_entry)),
894 more->entries,
895 more->num_entries * sizeof (struct hol_entry));
897 __mempcpy (short_options, hol->short_options, hol_so_len);
899 /* Fix up the short options pointers from HOL. */
900 for (e = entries, left = hol->num_entries; left > 0; e++, left--)
901 e->short_options += (short_options - hol->short_options);
903 /* Now add the short options from MORE, fixing up its entries
904 too. */
905 so = short_options + hol_so_len;
906 more_so = more->short_options;
907 for (left = more->num_entries; left > 0; e++, left--)
909 int opts_left;
910 const struct argp_option *opt;
912 e->short_options = so;
914 for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
916 int ch = *more_so;
917 if (oshort (opt) && ch == opt->key)
918 /* The next short option in MORE_SO, CH, is from OPT. */
920 if (! find_char (ch, short_options,
921 short_options + hol_so_len))
922 /* The short option CH isn't shadowed by HOL's options,
923 so add it to the sum. */
924 *so++ = ch;
925 more_so++;
930 *so = '\0';
932 free (hol->entries);
933 free (hol->short_options);
935 hol->entries = entries;
936 hol->num_entries = num_entries;
937 hol->short_options = short_options;
941 hol_free (more);
944 /* Inserts enough spaces to make sure STREAM is at column COL. */
945 static void
946 indent_to (argp_fmtstream_t stream, unsigned col)
948 int needed = col - __argp_fmtstream_point (stream);
949 while (needed-- > 0)
950 __argp_fmtstream_putc (stream, ' ');
953 /* Output to STREAM either a space, or a newline if there isn't room for at
954 least ENSURE characters before the right margin. */
955 static void
956 space (argp_fmtstream_t stream, size_t ensure)
958 if (__argp_fmtstream_point (stream) + ensure
959 >= __argp_fmtstream_rmargin (stream))
960 __argp_fmtstream_putc (stream, '\n');
961 else
962 __argp_fmtstream_putc (stream, ' ');
965 /* If the option REAL has an argument, we print it in using the printf
966 format REQ_FMT or OPT_FMT depending on whether it's a required or
967 optional argument. */
968 static void
969 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
970 const char *domain UNUSED, argp_fmtstream_t stream)
972 if (real->arg)
974 if (real->flags & OPTION_ARG_OPTIONAL)
975 __argp_fmtstream_printf (stream, opt_fmt,
976 dgettext (domain, real->arg));
977 else
978 __argp_fmtstream_printf (stream, req_fmt,
979 dgettext (domain, real->arg));
983 /* Helper functions for hol_entry_help. */
985 /* State used during the execution of hol_help. */
986 struct hol_help_state
988 /* PREV_ENTRY should contain the previous entry printed, or 0. */
989 struct hol_entry *prev_entry;
991 /* If an entry is in a different group from the previous one, and SEP_GROUPS
992 is true, then a blank line will be printed before any output. */
993 int sep_groups;
995 /* True if a duplicate option argument was suppressed (only ever set if
996 UPARAMS.dup_args is false). */
997 int suppressed_dup_arg;
1000 /* Some state used while printing a help entry (used to communicate with
1001 helper functions). See the doc for hol_entry_help for more info, as most
1002 of the fields are copied from its arguments. */
1003 struct pentry_state
1005 const struct hol_entry *entry;
1006 argp_fmtstream_t stream;
1007 struct hol_help_state *hhstate;
1009 /* True if nothing's been printed so far. */
1010 int first;
1012 /* If non-zero, the state that was used to print this help. */
1013 const struct argp_state *state;
1016 /* If a user doc filter should be applied to DOC, do so. */
1017 static const char *
1018 filter_doc (const char *doc, int key, const struct argp *argp,
1019 const struct argp_state *state)
1021 if (argp->help_filter)
1022 /* We must apply a user filter to this output. */
1024 void *input = __argp_input (argp, state);
1025 return (*argp->help_filter) (key, doc, input);
1027 else
1028 /* No filter. */
1029 return doc;
1032 /* Prints STR as a header line, with the margin lines set appropiately, and
1033 notes the fact that groups should be separated with a blank line. ARGP is
1034 the argp that should dictate any user doc filtering to take place. Note
1035 that the previous wrap margin isn't restored, but the left margin is reset
1036 to 0. */
1037 static void
1038 print_header (const char *str, const struct argp *argp,
1039 struct pentry_state *pest)
1041 const char *tstr = dgettext (argp->argp_domain, str);
1042 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
1044 if (fstr)
1046 if (*fstr)
1048 if (pest->hhstate->prev_entry)
1049 /* Precede with a blank line. */
1050 __argp_fmtstream_putc (pest->stream, '\n');
1051 indent_to (pest->stream, uparams.header_col);
1052 __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
1053 __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
1054 __argp_fmtstream_puts (pest->stream, fstr);
1055 __argp_fmtstream_set_lmargin (pest->stream, 0);
1056 __argp_fmtstream_putc (pest->stream, '\n');
1059 pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
1062 if (fstr != tstr)
1063 free ((char *) fstr);
1066 /* Inserts a comma if this isn't the first item on the line, and then makes
1067 sure we're at least to column COL. If this *is* the first item on a line,
1068 prints any pending whitespace/headers that should precede this line. Also
1069 clears FIRST. */
1070 static void
1071 comma (unsigned col, struct pentry_state *pest)
1073 if (pest->first)
1075 const struct hol_entry *pe = pest->hhstate->prev_entry;
1076 const struct hol_cluster *cl = pest->entry->cluster;
1078 if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1079 __argp_fmtstream_putc (pest->stream, '\n');
1081 if (cl && cl->header && *cl->header
1082 && (!pe
1083 || (pe->cluster != cl
1084 && !hol_cluster_is_child (pe->cluster, cl))))
1085 /* If we're changing clusters, then this must be the start of the
1086 ENTRY's cluster unless that is an ancestor of the previous one
1087 (in which case we had just popped into a sub-cluster for a bit).
1088 If so, then print the cluster's header line. */
1090 int old_wm = __argp_fmtstream_wmargin (pest->stream);
1091 print_header (cl->header, cl->argp, pest);
1092 __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1095 pest->first = 0;
1097 else
1098 __argp_fmtstream_puts (pest->stream, ", ");
1100 indent_to (pest->stream, col);
1103 /* Print help for ENTRY to STREAM. */
1104 static void
1105 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1106 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1108 unsigned num;
1109 const struct argp_option *real = entry->opt, *opt;
1110 char *so = entry->short_options;
1111 int have_long_opt = 0; /* We have any long options. */
1112 /* Saved margins. */
1113 int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1114 int old_wm = __argp_fmtstream_wmargin (stream);
1115 /* PEST is a state block holding some of our variables that we'd like to
1116 share with helper functions. */
1117 #ifdef __GNUC__
1118 struct pentry_state pest = { entry, stream, hhstate, 1, state };
1119 #else /* !__GNUC__ */
1120 /* Decent initializers are a GNU extension */
1121 struct pentry_state pest;
1122 pest.entry = entry;
1123 pest.stream = stream;
1124 pest.hhstate = hhstate;
1125 pest.first = 1;
1126 pest.state = state;
1127 #endif /* !__GNUC__ */
1129 if (! odoc (real))
1130 for (opt = real, num = entry->num; num > 0; opt++, num--)
1131 if (opt->name && ovisible (opt))
1133 have_long_opt = 1;
1134 break;
1137 /* First emit short options. */
1138 __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1139 for (opt = real, num = entry->num; num > 0; opt++, num--)
1140 if (oshort (opt) && opt->key == *so)
1141 /* OPT has a valid (non shadowed) short option. */
1143 if (ovisible (opt))
1145 comma (uparams.short_opt_col, &pest);
1146 __argp_fmtstream_putc (stream, '-');
1147 __argp_fmtstream_putc (stream, *so);
1148 if (!have_long_opt || uparams.dup_args)
1149 arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
1150 else if (real->arg)
1151 hhstate->suppressed_dup_arg = 1;
1153 so++;
1156 /* Now, long options. */
1157 if (odoc (real))
1158 /* A `documentation' option. */
1160 __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1161 for (opt = real, num = entry->num; num > 0; opt++, num--)
1162 if (opt->name && ovisible (opt))
1164 comma (uparams.doc_opt_col, &pest);
1165 /* Calling gettext here isn't quite right, since sorting will
1166 have been done on the original; but documentation options
1167 should be pretty rare anyway... */
1168 __argp_fmtstream_puts (stream,
1169 dgettext (state->root_argp->argp_domain,
1170 opt->name));
1173 else
1174 /* A real long option. */
1176 int first_long_opt = 1;
1178 __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1179 for (opt = real, num = entry->num; num > 0; opt++, num--)
1180 if (opt->name && ovisible (opt))
1182 comma (uparams.long_opt_col, &pest);
1183 __argp_fmtstream_printf (stream, "--%s", opt->name);
1184 if (first_long_opt || uparams.dup_args)
1185 arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
1186 stream);
1187 else if (real->arg)
1188 hhstate->suppressed_dup_arg = 1;
1192 /* Next, documentation strings. */
1193 __argp_fmtstream_set_lmargin (stream, 0);
1195 if (pest.first)
1197 /* Didn't print any switches, what's up? */
1198 if (!oshort (real) && !real->name)
1199 /* This is a group header, print it nicely. */
1200 print_header (real->doc, entry->argp, &pest);
1201 else
1202 /* Just a totally shadowed option or null header; print nothing. */
1203 goto cleanup; /* Just return, after cleaning up. */
1205 else
1207 const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
1208 real->doc) : 0;
1209 const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1210 if (fstr && *fstr)
1212 unsigned int col = __argp_fmtstream_point (stream);
1214 __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1215 __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1217 if (col > (unsigned int) (uparams.opt_doc_col + 3))
1218 __argp_fmtstream_putc (stream, '\n');
1219 else if (col >= (unsigned int) uparams.opt_doc_col)
1220 __argp_fmtstream_puts (stream, " ");
1221 else
1222 indent_to (stream, uparams.opt_doc_col);
1224 __argp_fmtstream_puts (stream, fstr);
1226 if (fstr && fstr != tstr)
1227 free ((char *) fstr);
1229 /* Reset the left margin. */
1230 __argp_fmtstream_set_lmargin (stream, 0);
1231 __argp_fmtstream_putc (stream, '\n');
1234 hhstate->prev_entry = entry;
1236 cleanup:
1237 __argp_fmtstream_set_lmargin (stream, old_lm);
1238 __argp_fmtstream_set_wmargin (stream, old_wm);
1241 /* Output a long help message about the options in HOL to STREAM. */
1242 static void
1243 hol_help (struct hol *hol, const struct argp_state *state,
1244 argp_fmtstream_t stream)
1246 unsigned num;
1247 struct hol_entry *entry;
1248 struct hol_help_state hhstate = { 0, 0, 0 };
1250 for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1251 hol_entry_help (entry, state, stream, &hhstate);
1253 if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1255 const char *tstr = dgettext (state->root_argp->argp_domain, "\
1256 Mandatory or optional arguments to long options are also mandatory or \
1257 optional for any corresponding short options.");
1258 const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1259 state ? state->root_argp : 0, state);
1260 if (fstr && *fstr)
1262 __argp_fmtstream_putc (stream, '\n');
1263 __argp_fmtstream_puts (stream, fstr);
1264 __argp_fmtstream_putc (stream, '\n');
1266 if (fstr && fstr != tstr)
1267 free ((char *) fstr);
1271 /* Helper functions for hol_usage. */
1273 /* If OPT is a short option without an arg, append its key to the string
1274 pointer pointer to by COOKIE, and advance the pointer. */
1275 static int
1276 add_argless_short_opt (const struct argp_option *opt,
1277 const struct argp_option *real,
1278 const char *domain UNUSED, void *cookie)
1280 char **snao_end = cookie;
1281 if (!(opt->arg || real->arg)
1282 && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1283 *(*snao_end)++ = opt->key;
1284 return 0;
1287 /* If OPT is a short option with an arg, output a usage entry for it to the
1288 stream pointed at by COOKIE. */
1289 static int
1290 usage_argful_short_opt (const struct argp_option *opt,
1291 const struct argp_option *real,
1292 const char *domain UNUSED, void *cookie)
1294 argp_fmtstream_t stream = cookie;
1295 const char *arg = opt->arg;
1296 int flags = opt->flags | real->flags;
1298 if (! arg)
1299 arg = real->arg;
1301 if (arg && !(flags & OPTION_NO_USAGE))
1303 arg = dgettext (domain, arg);
1305 if (flags & OPTION_ARG_OPTIONAL)
1306 __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1307 else
1309 /* Manually do line wrapping so that it (probably) won't
1310 get wrapped at the embedded space. */
1311 space (stream, 6 + strlen (arg));
1312 __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1316 return 0;
1319 /* Output a usage entry for the long option opt to the stream pointed at by
1320 COOKIE. */
1321 static int
1322 usage_long_opt (const struct argp_option *opt,
1323 const struct argp_option *real,
1324 const char *domain UNUSED, void *cookie)
1326 argp_fmtstream_t stream = cookie;
1327 const char *arg = opt->arg;
1328 int flags = opt->flags | real->flags;
1330 if (! arg)
1331 arg = real->arg;
1333 if (! (flags & OPTION_NO_USAGE))
1335 if (arg)
1337 arg = dgettext (domain, arg);
1338 if (flags & OPTION_ARG_OPTIONAL)
1339 __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1340 else
1341 __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1343 else
1344 __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1347 return 0;
1350 /* Print a short usage description for the arguments in HOL to STREAM. */
1351 static void
1352 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1354 if (hol->num_entries > 0)
1356 unsigned nentries;
1357 struct hol_entry *entry;
1358 char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1359 char *snao_end = short_no_arg_opts;
1361 /* First we put a list of short options without arguments. */
1362 for (entry = hol->entries, nentries = hol->num_entries
1363 ; nentries > 0
1364 ; entry++, nentries--)
1365 hol_entry_short_iterate (entry, add_argless_short_opt,
1366 entry->argp->argp_domain, &snao_end);
1367 if (snao_end > short_no_arg_opts)
1369 *snao_end++ = 0;
1370 __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1373 /* Now a list of short options *with* arguments. */
1374 for (entry = hol->entries, nentries = hol->num_entries
1375 ; nentries > 0
1376 ; entry++, nentries--)
1377 hol_entry_short_iterate (entry, usage_argful_short_opt,
1378 entry->argp->argp_domain, stream);
1380 /* Finally, a list of long options (whew!). */
1381 for (entry = hol->entries, nentries = hol->num_entries
1382 ; nentries > 0
1383 ; entry++, nentries--)
1384 hol_entry_long_iterate (entry, usage_long_opt,
1385 entry->argp->argp_domain, stream);
1389 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1390 cluster in which ARGP's entries should be clustered, or 0. */
1391 static struct hol *
1392 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1394 const struct argp_child *child = argp->children;
1395 struct hol *hol = make_hol (argp, cluster);
1396 if (child)
1397 while (child->argp)
1399 struct hol_cluster *child_cluster =
1400 ((child->group || child->header)
1401 /* Put CHILD->argp within its own cluster. */
1402 ? hol_add_cluster (hol, child->group, child->header,
1403 child - argp->children, cluster, argp)
1404 /* Just merge it into the parent's cluster. */
1405 : cluster);
1406 hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1407 child++;
1409 return hol;
1412 /* Calculate how many different levels with alternative args strings exist in
1413 ARGP. */
1414 static size_t
1415 argp_args_levels (const struct argp *argp)
1417 size_t levels = 0;
1418 const struct argp_child *child = argp->children;
1420 if (argp->args_doc && strchr (argp->args_doc, '\n'))
1421 levels++;
1423 if (child)
1424 while (child->argp)
1425 levels += argp_args_levels ((child++)->argp);
1427 return levels;
1430 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1431 preceded by a space. LEVELS is a pointer to a byte vector the length
1432 returned by argp_args_levels; it should be initialized to zero, and
1433 updated by this routine for the next call if ADVANCE is true. True is
1434 returned as long as there are more patterns to output. */
1435 static int
1436 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1437 char **levels, int advance, argp_fmtstream_t stream)
1439 char *our_level = *levels;
1440 int multiple = 0;
1441 const struct argp_child *child = argp->children;
1442 const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1443 const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1445 if (fdoc)
1447 const char *cp = fdoc;
1448 nl = __strchrnul (cp, '\n');
1449 if (*nl != '\0')
1450 /* This is a `multi-level' args doc; advance to the correct position
1451 as determined by our state in LEVELS, and update LEVELS. */
1453 int i;
1454 multiple = 1;
1455 for (i = 0; i < *our_level; i++)
1456 cp = nl + 1, nl = __strchrnul (cp, '\n');
1457 (*levels)++;
1460 /* Manually do line wrapping so that it (probably) won't get wrapped at
1461 any embedded spaces. */
1462 space (stream, 1 + nl - cp);
1464 __argp_fmtstream_write (stream, cp, nl - cp);
1466 if (fdoc && fdoc != tdoc)
1467 free ((char *)fdoc); /* Free user's modified doc string. */
1469 if (child)
1470 while (child->argp)
1471 advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1473 if (advance && multiple)
1475 /* Need to increment our level. */
1476 if (*nl)
1477 /* There's more we can do here. */
1479 (*our_level)++;
1480 advance = 0; /* Our parent shouldn't advance also. */
1482 else if (*our_level > 0)
1483 /* We had multiple levels, but used them up; reset to zero. */
1484 *our_level = 0;
1487 return !advance;
1490 /* Print the documentation for ARGP to STREAM; if POST is false, then
1491 everything preceeding a `\v' character in the documentation strings (or
1492 the whole string, for those with none) is printed, otherwise, everything
1493 following the `\v' character (nothing for strings without). Each separate
1494 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1495 then the first is as well. If FIRST_ONLY is true, only the first
1496 occurrence is output. Returns true if anything was output. */
1497 static int
1498 argp_doc (const struct argp *argp, const struct argp_state *state,
1499 int post, int pre_blank, int first_only,
1500 argp_fmtstream_t stream)
1502 const char *text;
1503 const char *inp_text;
1504 void *input = 0;
1505 int anything = 0;
1506 size_t inp_text_limit = 0;
1507 const char *doc = dgettext (argp->argp_domain, argp->doc);
1508 const struct argp_child *child = argp->children;
1510 if (doc)
1512 char *vt = strchr (doc, '\v');
1513 inp_text = post ? (vt ? vt + 1 : 0) : doc;
1514 inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1516 else
1517 inp_text = 0;
1519 if (argp->help_filter)
1520 /* We have to filter the doc strings. */
1522 if (inp_text_limit)
1523 /* Copy INP_TEXT so that it's nul-terminated. */
1524 inp_text = STRNDUP (inp_text, inp_text_limit);
1525 input = __argp_input (argp, state);
1526 text =
1527 (*argp->help_filter) (post
1528 ? ARGP_KEY_HELP_POST_DOC
1529 : ARGP_KEY_HELP_PRE_DOC,
1530 inp_text, input);
1532 else
1533 text = (const char *) inp_text;
1535 if (text)
1537 if (pre_blank)
1538 __argp_fmtstream_putc (stream, '\n');
1540 if (text == inp_text && inp_text_limit)
1541 __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1542 else
1543 __argp_fmtstream_puts (stream, text);
1545 if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1546 __argp_fmtstream_putc (stream, '\n');
1548 anything = 1;
1551 if (text && text != inp_text)
1552 free ((char *) text); /* Free TEXT returned from the help filter. */
1553 if (inp_text && inp_text_limit && argp->help_filter)
1554 free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
1556 if (post && argp->help_filter)
1557 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1559 text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1560 if (text)
1562 if (anything || pre_blank)
1563 __argp_fmtstream_putc (stream, '\n');
1564 __argp_fmtstream_puts (stream, text);
1565 free ((char *) text);
1566 if (__argp_fmtstream_point (stream)
1567 > __argp_fmtstream_lmargin (stream))
1568 __argp_fmtstream_putc (stream, '\n');
1569 anything = 1;
1573 if (child)
1574 while (child->argp && !(first_only && anything))
1575 anything |=
1576 argp_doc ((child++)->argp, state,
1577 post, anything || pre_blank, first_only,
1578 stream);
1580 return anything;
1583 /* Output a usage message for ARGP to STREAM. If called from
1584 argp_state_help, STATE is the relevent parsing state. FLAGS are from the
1585 set ARGP_HELP_*. NAME is what to use wherever a `program name' is
1586 needed. */
1588 static void
1589 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1590 unsigned flags, const char *name)
1592 int anything = 0; /* Whether we've output anything. */
1593 struct hol *hol = 0;
1594 argp_fmtstream_t fs;
1596 if (! stream)
1597 return;
1599 __flockfile (stream);
1601 if (! uparams.valid)
1602 fill_in_uparams (state);
1604 fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1605 if (! fs)
1607 __funlockfile (stream);
1608 return;
1611 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1613 hol = argp_hol (argp, 0);
1615 /* If present, these options always come last. */
1616 hol_set_group (hol, "help", -1);
1617 hol_set_group (hol, "version", -1);
1619 hol_sort (hol);
1622 if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1623 /* Print a short `Usage:' message. */
1625 int first_pattern = 1, more_patterns;
1626 size_t num_pattern_levels = argp_args_levels (argp);
1627 char *pattern_levels = alloca (num_pattern_levels);
1629 memset (pattern_levels, 0, num_pattern_levels);
1633 int old_lm;
1634 int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1635 char *levels = pattern_levels;
1637 if (first_pattern)
1638 __argp_fmtstream_printf (fs, "%s %s",
1639 dgettext (argp->argp_domain, "Usage:"),
1640 name);
1641 else
1642 __argp_fmtstream_printf (fs, "%s %s",
1643 dgettext (argp->argp_domain, " or: "),
1644 name);
1646 /* We set the lmargin as well as the wmargin, because hol_usage
1647 manually wraps options with newline to avoid annoying breaks. */
1648 old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1650 if (flags & ARGP_HELP_SHORT_USAGE)
1651 /* Just show where the options go. */
1653 if (hol->num_entries > 0)
1654 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1655 " [OPTION...]"));
1657 else
1658 /* Actually print the options. */
1660 hol_usage (hol, fs);
1661 flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
1664 more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1666 __argp_fmtstream_set_wmargin (fs, old_wm);
1667 __argp_fmtstream_set_lmargin (fs, old_lm);
1669 __argp_fmtstream_putc (fs, '\n');
1670 anything = 1;
1672 first_pattern = 0;
1674 while (more_patterns);
1677 if (flags & ARGP_HELP_PRE_DOC)
1678 anything |= argp_doc (argp, state, 0, 0, 1, fs);
1680 if (flags & ARGP_HELP_SEE)
1682 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1683 Try `%s --help' or `%s --usage' for more information.\n"),
1684 name, name);
1685 anything = 1;
1688 if (flags & ARGP_HELP_LONG)
1689 /* Print a long, detailed help message. */
1691 /* Print info about all the options. */
1692 if (hol->num_entries > 0)
1694 if (anything)
1695 __argp_fmtstream_putc (fs, '\n');
1696 hol_help (hol, state, fs);
1697 anything = 1;
1701 if (flags & ARGP_HELP_POST_DOC)
1702 /* Print any documentation strings at the end. */
1703 anything |= argp_doc (argp, state, 1, anything, 0, fs);
1705 if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1707 if (anything)
1708 __argp_fmtstream_putc (fs, '\n');
1709 __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1710 "Report bugs to %s.\n"),
1711 argp_program_bug_address);
1712 anything = 1;
1715 __funlockfile (stream);
1717 if (hol)
1718 hol_free (hol);
1720 __argp_fmtstream_free (fs);
1723 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1724 ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
1725 void __argp_help (const struct argp *argp, FILE *stream,
1726 unsigned flags, char *name)
1728 _help (argp, 0, stream, flags, name);
1730 #ifdef weak_alias
1731 weak_alias (__argp_help, argp_help)
1732 #endif
1734 char *__argp_basename(char *name)
1736 char *short_name = strrchr(name, '/');
1737 return short_name ? short_name + 1 : name;
1740 char *
1741 __argp_short_program_name(const struct argp_state *state)
1743 if (state)
1744 return state->name;
1745 #if HAVE_PROGRAM_INVOCATION_SHORT_NAME
1746 return program_invocation_short_name;
1747 #elif HAVE_PROGRAM_INVOCATION_NAME
1748 return __argp_basename(program_invocation_name);
1749 #else /* !HAVE_PROGRAM_INVOCATION_NAME */
1750 /* FIXME: What now? Miles suggests that it is better to use NULL,
1751 but currently the value is passed on directly to fputs_unlocked,
1752 so that requires more changes. */
1753 # if __GNUC__
1754 # warning No reasonable value to return
1755 return "";
1756 # endif /* __GNUC__ */
1757 #endif /* !HAVE_PROGRAM_INVOCATION_NAME */
1760 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1761 from the set ARGP_HELP_*. */
1762 void
1763 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1765 if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1767 if (state && (state->flags & ARGP_LONG_ONLY))
1768 flags |= ARGP_HELP_LONG_ONLY;
1770 _help (state ? state->root_argp : 0, state, stream, flags,
1771 __argp_short_program_name(state));
1773 if (!state || ! (state->flags & ARGP_NO_EXIT))
1775 if (flags & ARGP_HELP_EXIT_ERR)
1776 exit (argp_err_exit_status);
1777 if (flags & ARGP_HELP_EXIT_OK)
1778 exit (0);
1782 #ifdef weak_alias
1783 weak_alias (__argp_state_help, argp_state_help)
1784 #endif
1786 /* If appropriate, print the printf string FMT and following args, preceded
1787 by the program name and `:', to stderr, and followed by a `Try ... --help'
1788 message, then exit (1). */
1789 void
1790 __argp_error (const struct argp_state *state, const char *fmt, ...)
1792 if (!state || !(state->flags & ARGP_NO_ERRS))
1794 FILE *stream = state ? state->err_stream : stderr;
1796 if (stream)
1798 va_list ap;
1800 __flockfile (stream);
1802 fputs_unlocked (__argp_short_program_name(state),
1803 stream);
1804 putc (':', stream);
1805 putc (' ', stream);
1807 va_start (ap, fmt);
1808 vfprintf (stream, fmt, ap);
1809 va_end (ap);
1811 putc ('\n', stream);
1813 __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1815 __funlockfile (stream);
1819 #ifdef weak_alias
1820 weak_alias (__argp_error, argp_error)
1821 #endif
1823 /* Similar to the standard gnu error-reporting function error(), but will
1824 respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1825 to STATE->err_stream. This is useful for argument parsing code that is
1826 shared between program startup (when exiting is desired) and runtime
1827 option parsing (when typically an error code is returned instead). The
1828 difference between this function and argp_error is that the latter is for
1829 *parsing errors*, and the former is for other problems that occur during
1830 parsing but don't reflect a (syntactic) problem with the input. */
1831 void
1832 __argp_failure (const struct argp_state *state, int status, int errnum,
1833 const char *fmt, ...)
1835 if (!state || !(state->flags & ARGP_NO_ERRS))
1837 FILE *stream = state ? state->err_stream : stderr;
1839 if (stream)
1841 __flockfile (stream);
1843 fputs_unlocked (__argp_short_program_name(state),
1844 stream);
1846 if (fmt)
1848 va_list ap;
1850 putc (':', stream);
1851 putc (' ', stream);
1853 va_start (ap, fmt);
1854 vfprintf (stream, fmt, ap);
1855 va_end (ap);
1858 if (errnum)
1860 putc (':', stream);
1861 putc (' ', stream);
1862 fputs (STRERROR (errnum), stream);
1865 putc ('\n', stream);
1867 __funlockfile (stream);
1869 if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1870 exit (status);
1874 #ifdef weak_alias
1875 weak_alias (__argp_failure, argp_failure)
1876 #endif