]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/cpio/lib/argp-help.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / contrib / cpio / lib / argp-help.c
1 /* Hierarchial argument parsing help output
2    Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Written by Miles Bader <miles@gnu.ai.mit.edu>.
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2, or (at your option)
9    any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation,
18    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
19
20 #ifndef _GNU_SOURCE
21 # define _GNU_SOURCE    1
22 #endif
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <alloca.h>
29 #include <errno.h>
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <assert.h>
34 #include <stdarg.h>
35 #include <ctype.h>
36 #include <limits.h>
37 #ifdef USE_IN_LIBIO
38 # include <wchar.h>
39 #endif
40
41 #ifdef _LIBC
42 # include <libintl.h>
43 # undef dgettext
44 # define dgettext(domain, msgid) \
45    INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
46 #else
47 # include "gettext.h"
48 #endif
49
50 #include "argp.h"
51 #include "argp-fmtstream.h"
52 #include "argp-namefrob.h"
53
54 #ifndef SIZE_MAX
55 # define SIZE_MAX ((size_t) -1)
56 #endif
57 \f
58 /* User-selectable (using an environment variable) formatting parameters.
59
60    These may be specified in an environment variable called `ARGP_HELP_FMT',
61    with a contents like:  VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
62    Where VALn must be a positive integer.  The list of variables is in the
63    UPARAM_NAMES vector, below.  */
64
65 /* Default parameters.  */
66 #define DUP_ARGS      0         /* True if option argument can be duplicated. */
67 #define DUP_ARGS_NOTE 1         /* True to print a note about duplicate args. */
68 #define SHORT_OPT_COL 2         /* column in which short options start */
69 #define LONG_OPT_COL  6         /* column in which long options start */
70 #define DOC_OPT_COL   2         /* column in which doc options start */
71 #define OPT_DOC_COL  29         /* column in which option text starts */
72 #define HEADER_COL    1         /* column in which group headers are printed */
73 #define USAGE_INDENT 12         /* indentation of wrapped usage lines */
74 #define RMARGIN      79         /* right margin used for wrapping */
75
76 /* User-selectable (using an environment variable) formatting parameters.
77    They must all be of type `int' for the parsing code to work.  */
78 struct uparams
79 {
80   /* If true, arguments for an option are shown with both short and long
81      options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
82      If false, then if an option has both, the argument is only shown with
83      the long one, e.g., `-x, --longx=ARG', and a message indicating that
84      this really means both is printed below the options.  */
85   int dup_args;
86
87   /* This is true if when DUP_ARGS is false, and some duplicate arguments have
88      been suppressed, an explanatory message should be printed.  */
89   int dup_args_note;
90
91   /* Various output columns.  */
92   int short_opt_col;
93   int long_opt_col;
94   int doc_opt_col;
95   int opt_doc_col;
96   int header_col;
97   int usage_indent;
98   int rmargin;
99
100   int valid;                    /* True when the values in here are valid.  */
101 };
102
103 /* This is a global variable, as user options are only ever read once.  */
104 static struct uparams uparams = {
105   DUP_ARGS, DUP_ARGS_NOTE,
106   SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
107   USAGE_INDENT, RMARGIN,
108   0
109 };
110
111 /* A particular uparam, and what the user name is.  */
112 struct uparam_name
113 {
114   const char *name;             /* User name.  */
115   int is_bool;                  /* Whether it's `boolean'.  */
116   size_t uparams_offs;          /* Location of the (int) field in UPARAMS.  */
117 };
118
119 /* The name-field mappings we know about.  */
120 static const struct uparam_name uparam_names[] =
121 {
122   { "dup-args",       1, offsetof (struct uparams, dup_args) },
123   { "dup-args-note",  1, offsetof (struct uparams, dup_args_note) },
124   { "short-opt-col",  0, offsetof (struct uparams, short_opt_col) },
125   { "long-opt-col",   0, offsetof (struct uparams, long_opt_col) },
126   { "doc-opt-col",    0, offsetof (struct uparams, doc_opt_col) },
127   { "opt-doc-col",    0, offsetof (struct uparams, opt_doc_col) },
128   { "header-col",     0, offsetof (struct uparams, header_col) },
129   { "usage-indent",   0, offsetof (struct uparams, usage_indent) },
130   { "rmargin",        0, offsetof (struct uparams, rmargin) },
131   { 0 }
132 };
133
134 /* Read user options from the environment, and fill in UPARAMS appropiately.  */
135 static void
136 fill_in_uparams (const struct argp_state *state)
137 {
138   const char *var = getenv ("ARGP_HELP_FMT");
139
140 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
141
142   if (var)
143     /* Parse var. */
144     while (*var)
145       {
146         SKIPWS (var);
147
148         if (isalpha (*var))
149           {
150             size_t var_len;
151             const struct uparam_name *un;
152             int unspec = 0, val = 0;
153             const char *arg = var;
154
155             while (isalnum (*arg) || *arg == '-' || *arg == '_')
156               arg++;
157             var_len = arg - var;
158
159             SKIPWS (arg);
160
161             if (*arg == '\0' || *arg == ',')
162               unspec = 1;
163             else if (*arg == '=')
164               {
165                 arg++;
166                 SKIPWS (arg);
167               }
168
169             if (unspec)
170               {
171                 if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
172                   {
173                     val = 0;
174                     var += 3;
175                     var_len -= 3;
176                   }
177                 else
178                   val = 1;
179               }
180             else if (isdigit (*arg))
181               {
182                 val = atoi (arg);
183                 while (isdigit (*arg))
184                   arg++;
185                 SKIPWS (arg);
186               }
187
188             for (un = uparam_names; un->name; un++)
189               if (strlen (un->name) == var_len
190                   && strncmp (var, un->name, var_len) == 0)
191                 {
192                   if (unspec && !un->is_bool)
193                     __argp_failure (state, 0, 0,
194                                     dgettext (state->root_argp->argp_domain, "\
195 %.*s: ARGP_HELP_FMT parameter requires a value"),
196                                     (int) var_len, var);
197                   else
198                     *(int *)((char *)&uparams + un->uparams_offs) = val;
199                   break;
200                 }
201             if (! un->name)
202               __argp_failure (state, 0, 0,
203                               dgettext (state->root_argp->argp_domain, "\
204 %.*s: Unknown ARGP_HELP_FMT parameter"),
205                               (int) var_len, var);
206
207             var = arg;
208             if (*var == ',')
209               var++;
210           }
211         else if (*var)
212           {
213             __argp_failure (state, 0, 0,
214                             dgettext (state->root_argp->argp_domain,
215                                       "Garbage in ARGP_HELP_FMT: %s"), var);
216             break;
217           }
218       }
219 }
220 \f
221 /* Returns true if OPT hasn't been marked invisible.  Visibility only affects
222    whether OPT is displayed or used in sorting, not option shadowing.  */
223 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
224
225 /* Returns true if OPT is an alias for an earlier option.  */
226 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
227
228 /* Returns true if OPT is an documentation-only entry.  */
229 #define odoc(opt) ((opt)->flags & OPTION_DOC)
230
231 /* Returns true if OPT should not be translated */
232 #define onotrans(opt) ((opt)->flags & OPTION_NO_TRANS)
233
234 /* Returns true if OPT is the end-of-list marker for a list of options.  */
235 #define oend(opt) __option_is_end (opt)
236
237 /* Returns true if OPT has a short option.  */
238 #define oshort(opt) __option_is_short (opt)
239 \f
240 /*
241    The help format for a particular option is like:
242
243      -xARG, -yARG, --long1=ARG, --long2=ARG        Documentation...
244
245    Where ARG will be omitted if there's no argument, for this option, or
246    will be surrounded by "[" and "]" appropiately if the argument is
247    optional.  The documentation string is word-wrapped appropiately, and if
248    the list of options is long enough, it will be started on a separate line.
249    If there are no short options for a given option, the first long option is
250    indented slighly in a way that's supposed to make most long options appear
251    to be in a separate column.
252
253    For example, the following output (from ps):
254
255      -p PID, --pid=PID          List the process PID
256          --pgrp=PGRP            List processes in the process group PGRP
257      -P, -x, --no-parent        Include processes without parents
258      -Q, --all-fields           Don't elide unusable fields (normally if there's
259                                 some reason ps can't print a field for any
260                                 process, it's removed from the output entirely)
261      -r, --reverse, --gratuitously-long-reverse-option
262                                 Reverse the order of any sort
263          --session[=SID]        Add the processes from the session SID (which
264                                 defaults to the sid of the current process)
265
266     Here are some more options:
267      -f ZOT, --foonly=ZOT       Glork a foonly
268      -z, --zaza                 Snit a zar
269
270      -?, --help                 Give this help list
271          --usage                Give a short usage message
272      -V, --version              Print program version
273
274    The struct argp_option array for the above could look like:
275
276    {
277      {"pid",       'p',      "PID",  0, "List the process PID"},
278      {"pgrp",      OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
279      {"no-parent", 'P',       0,     0, "Include processes without parents"},
280      {0,           'x',       0,     OPTION_ALIAS},
281      {"all-fields",'Q',       0,     0, "Don't elide unusable fields (normally"
282                                         " if there's some reason ps can't"
283                                         " print a field for any process, it's"
284                                         " removed from the output entirely)" },
285      {"reverse",   'r',       0,     0, "Reverse the order of any sort"},
286      {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
287      {"session",   OPT_SESS,  "SID", OPTION_ARG_OPTIONAL,
288                                         "Add the processes from the session"
289                                         " SID (which defaults to the sid of"
290                                         " the current process)" },
291
292      {0,0,0,0, "Here are some more options:"},
293      {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
294      {"zaza", 'z', 0, 0, "Snit a zar"},
295
296      {0}
297    }
298
299    Note that the last three options are automatically supplied by argp_parse,
300    unless you tell it not to with ARGP_NO_HELP.
301
302 */
303 \f
304 /* Returns true if CH occurs between BEG and END.  */
305 static int
306 find_char (char ch, char *beg, char *end)
307 {
308   while (beg < end)
309     if (*beg == ch)
310       return 1;
311     else
312       beg++;
313   return 0;
314 }
315 \f
316 struct hol_cluster;             /* fwd decl */
317
318 struct hol_entry
319 {
320   /* First option.  */
321   const struct argp_option *opt;
322   /* Number of options (including aliases).  */
323   unsigned num;
324
325   /* A pointers into the HOL's short_options field, to the first short option
326      letter for this entry.  The order of the characters following this point
327      corresponds to the order of options pointed to by OPT, and there are at
328      most NUM.  A short option recorded in a option following OPT is only
329      valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
330      probably been shadowed by some other entry).  */
331   char *short_options;
332
333   /* Entries are sorted by their group first, in the order:
334        1, 2, ..., n, 0, -m, ..., -2, -1
335      and then alphabetically within each group.  The default is 0.  */
336   int group;
337
338   /* The cluster of options this entry belongs to, or 0 if none.  */
339   struct hol_cluster *cluster;
340
341   /* The argp from which this option came.  */
342   const struct argp *argp;
343 };
344
345 /* A cluster of entries to reflect the argp tree structure.  */
346 struct hol_cluster
347 {
348   /* A descriptive header printed before options in this cluster.  */
349   const char *header;
350
351   /* Used to order clusters within the same group with the same parent,
352      according to the order in which they occurred in the parent argp's child
353      list.  */
354   int index;
355
356   /* How to sort this cluster with respect to options and other clusters at the
357      same depth (clusters always follow options in the same group).  */
358   int group;
359
360   /* The cluster to which this cluster belongs, or 0 if it's at the base
361      level.  */
362   struct hol_cluster *parent;
363
364   /* The argp from which this cluster is (eventually) derived.  */
365   const struct argp *argp;
366
367   /* The distance this cluster is from the root.  */
368   int depth;
369
370   /* Clusters in a given hol are kept in a linked list, to make freeing them
371      possible.  */
372   struct hol_cluster *next;
373 };
374
375 /* A list of options for help.  */
376 struct hol
377 {
378   /* An array of hol_entry's.  */
379   struct hol_entry *entries;
380   /* The number of entries in this hol.  If this field is zero, the others
381      are undefined.  */
382   unsigned num_entries;
383
384   /* A string containing all short options in this HOL.  Each entry contains
385      pointers into this string, so the order can't be messed with blindly.  */
386   char *short_options;
387
388   /* Clusters of entries in this hol.  */
389   struct hol_cluster *clusters;
390 };
391 \f
392 /* Create a struct hol from the options in ARGP.  CLUSTER is the
393    hol_cluster in which these entries occur, or 0, if at the root.  */
394 static struct hol *
395 make_hol (const struct argp *argp, struct hol_cluster *cluster)
396 {
397   char *so;
398   const struct argp_option *o;
399   const struct argp_option *opts = argp->options;
400   struct hol_entry *entry;
401   unsigned num_short_options = 0;
402   struct hol *hol = malloc (sizeof (struct hol));
403
404   assert (hol);
405
406   hol->num_entries = 0;
407   hol->clusters = 0;
408
409   if (opts)
410     {
411       int cur_group = 0;
412
413       /* The first option must not be an alias.  */
414       assert (! oalias (opts));
415
416       /* Calculate the space needed.  */
417       for (o = opts; ! oend (o); o++)
418         {
419           if (! oalias (o))
420             hol->num_entries++;
421           if (oshort (o))
422             num_short_options++;        /* This is an upper bound.  */
423         }
424
425       hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
426       hol->short_options = malloc (num_short_options + 1);
427
428       assert (hol->entries && hol->short_options);
429       if (SIZE_MAX <= UINT_MAX)
430         assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
431
432       /* Fill in the entries.  */
433       so = hol->short_options;
434       for (o = opts, entry = hol->entries; ! oend (o); entry++)
435         {
436           entry->opt = o;
437           entry->num = 0;
438           entry->short_options = so;
439           entry->group = cur_group =
440             o->group
441             ? o->group
442             : ((!o->name && !o->key)
443                ? cur_group + 1
444                : cur_group);
445           entry->cluster = cluster;
446           entry->argp = argp;
447
448           do
449             {
450               entry->num++;
451               if (oshort (o) && ! find_char (o->key, hol->short_options, so))
452                 /* O has a valid short option which hasn't already been used.*/
453                 *so++ = o->key;
454               o++;
455             }
456           while (! oend (o) && oalias (o));
457         }
458       *so = '\0';               /* null terminated so we can find the length */
459     }
460
461   return hol;
462 }
463 \f
464 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
465    associated argp child list entry), INDEX, and PARENT, and return a pointer
466    to it.  ARGP is the argp that this cluster results from.  */
467 static struct hol_cluster *
468 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
469                  struct hol_cluster *parent, const struct argp *argp)
470 {
471   struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
472   if (cl)
473     {
474       cl->group = group;
475       cl->header = header;
476
477       cl->index = index;
478       cl->parent = parent;
479       cl->argp = argp;
480       cl->depth = parent ? parent->depth + 1 : 0;
481
482       cl->next = hol->clusters;
483       hol->clusters = cl;
484     }
485   return cl;
486 }
487 \f
488 /* Free HOL and any resources it uses.  */
489 static void
490 hol_free (struct hol *hol)
491 {
492   struct hol_cluster *cl = hol->clusters;
493
494   while (cl)
495     {
496       struct hol_cluster *next = cl->next;
497       free (cl);
498       cl = next;
499     }
500
501   if (hol->num_entries > 0)
502     {
503       free (hol->entries);
504       free (hol->short_options);
505     }
506
507   free (hol);
508 }
509 \f
510 static int
511 hol_entry_short_iterate (const struct hol_entry *entry,
512                          int (*func)(const struct argp_option *opt,
513                                      const struct argp_option *real,
514                                      const char *domain, void *cookie),
515                          const char *domain, void *cookie)
516 {
517   unsigned nopts;
518   int val = 0;
519   const struct argp_option *opt, *real = entry->opt;
520   char *so = entry->short_options;
521
522   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
523     if (oshort (opt) && *so == opt->key)
524       {
525         if (!oalias (opt))
526           real = opt;
527         if (ovisible (opt))
528           val = (*func)(opt, real, domain, cookie);
529         so++;
530       }
531
532   return val;
533 }
534
535 static inline int
536 __attribute__ ((always_inline))
537 hol_entry_long_iterate (const struct hol_entry *entry,
538                         int (*func)(const struct argp_option *opt,
539                                     const struct argp_option *real,
540                                     const char *domain, void *cookie),
541                         const char *domain, void *cookie)
542 {
543   unsigned nopts;
544   int val = 0;
545   const struct argp_option *opt, *real = entry->opt;
546
547   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
548     if (opt->name)
549       {
550         if (!oalias (opt))
551           real = opt;
552         if (ovisible (opt))
553           val = (*func)(opt, real, domain, cookie);
554       }
555
556   return val;
557 }
558 \f
559 /* Iterator that returns true for the first short option.  */
560 static inline int
561 until_short (const struct argp_option *opt, const struct argp_option *real,
562              const char *domain, void *cookie)
563 {
564   return oshort (opt) ? opt->key : 0;
565 }
566
567 /* Returns the first valid short option in ENTRY, or 0 if there is none.  */
568 static char
569 hol_entry_first_short (const struct hol_entry *entry)
570 {
571   return hol_entry_short_iterate (entry, until_short,
572                                   entry->argp->argp_domain, 0);
573 }
574
575 /* Returns the first valid long option in ENTRY, or 0 if there is none.  */
576 static const char *
577 hol_entry_first_long (const struct hol_entry *entry)
578 {
579   const struct argp_option *opt;
580   unsigned num;
581   for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
582     if (opt->name && ovisible (opt))
583       return opt->name;
584   return 0;
585 }
586
587 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
588    none.  */
589 static struct hol_entry *
590 hol_find_entry (struct hol *hol, const char *name)
591 {
592   struct hol_entry *entry = hol->entries;
593   unsigned num_entries = hol->num_entries;
594
595   while (num_entries-- > 0)
596     {
597       const struct argp_option *opt = entry->opt;
598       unsigned num_opts = entry->num;
599
600       while (num_opts-- > 0)
601         if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
602           return entry;
603         else
604           opt++;
605
606       entry++;
607     }
608
609   return 0;
610 }
611 \f
612 /* If an entry with the long option NAME occurs in HOL, set it's special
613    sort position to GROUP.  */
614 static void
615 hol_set_group (struct hol *hol, const char *name, int group)
616 {
617   struct hol_entry *entry = hol_find_entry (hol, name);
618   if (entry)
619     entry->group = group;
620 }
621 \f
622 /* Order by group:  0, 1, 2, ..., n, -m, ..., -2, -1.
623    EQ is what to return if GROUP1 and GROUP2 are the same.  */
624 static int
625 group_cmp (int group1, int group2, int eq)
626 {
627   if (group1 == group2)
628     return eq;
629   else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
630     return group1 - group2;
631   else
632     return group2 - group1;
633 }
634
635 /* Compare clusters CL1 & CL2 by the order that they should appear in
636    output.  */
637 static int
638 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
639 {
640   /* If one cluster is deeper than the other, use its ancestor at the same
641      level, so that finding the common ancestor is straightforward.  */
642   while (cl1->depth < cl2->depth)
643     cl1 = cl1->parent;
644   while (cl2->depth < cl1->depth)
645     cl2 = cl2->parent;
646
647   /* Now reduce both clusters to their ancestors at the point where both have
648      a common parent; these can be directly compared.  */
649   while (cl1->parent != cl2->parent)
650     cl1 = cl1->parent, cl2 = cl2->parent;
651
652   return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
653 }
654
655 /* Return the ancestor of CL that's just below the root (i.e., has a parent
656    of 0).  */
657 static struct hol_cluster *
658 hol_cluster_base (struct hol_cluster *cl)
659 {
660   while (cl->parent)
661     cl = cl->parent;
662   return cl;
663 }
664
665 /* Return true if CL1 is a child of CL2.  */
666 static int
667 hol_cluster_is_child (const struct hol_cluster *cl1,
668                       const struct hol_cluster *cl2)
669 {
670   while (cl1 && cl1 != cl2)
671     cl1 = cl1->parent;
672   return cl1 == cl2;
673 }
674 \f
675 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
676    that should be used for comparisons, and returns true iff it should be
677    treated as a non-option.  */
678 static int
679 canon_doc_option (const char **name)
680 {
681   int non_opt;
682
683   if (!*name)
684     non_opt = 1;
685   else
686     {
687       /* Skip initial whitespace.  */
688       while (isspace (**name))
689         (*name)++;
690       /* Decide whether this looks like an option (leading `-') or not.  */
691       non_opt = (**name != '-');
692       /* Skip until part of name used for sorting.  */
693       while (**name && !isalnum (**name))
694         (*name)++;
695     }
696   return non_opt;
697 }
698
699 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
700    listing.  */
701 static int
702 hol_entry_cmp (const struct hol_entry *entry1,
703                const struct hol_entry *entry2)
704 {
705   /* The group numbers by which the entries should be ordered; if either is
706      in a cluster, then this is just the group within the cluster.  */
707   int group1 = entry1->group, group2 = entry2->group;
708
709   if (entry1->cluster != entry2->cluster)
710     {
711       /* The entries are not within the same cluster, so we can't compare them
712          directly, we have to use the appropiate clustering level too.  */
713       if (! entry1->cluster)
714         /* ENTRY1 is at the `base level', not in a cluster, so we have to
715            compare it's group number with that of the base cluster in which
716            ENTRY2 resides.  Note that if they're in the same group, the
717            clustered option always comes laster.  */
718         return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
719       else if (! entry2->cluster)
720         /* Likewise, but ENTRY2's not in a cluster.  */
721         return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
722       else
723         /* Both entries are in clusters, we can just compare the clusters.  */
724         return hol_cluster_cmp (entry1->cluster, entry2->cluster);
725     }
726   else if (group1 == group2)
727     /* The entries are both in the same cluster and group, so compare them
728        alphabetically.  */
729     {
730       int short1 = hol_entry_first_short (entry1);
731       int short2 = hol_entry_first_short (entry2);
732       int doc1 = odoc (entry1->opt);
733       int doc2 = odoc (entry2->opt);
734       const char *long1 = hol_entry_first_long (entry1);
735       const char *long2 = hol_entry_first_long (entry2);
736
737       if (doc1)
738         doc1 = canon_doc_option (&long1);
739       if (doc2)
740         doc2 = canon_doc_option (&long2);
741
742       if (doc1 != doc2)
743         /* `documentation' options always follow normal options (or
744            documentation options that *look* like normal options).  */
745         return doc1 - doc2;
746       else if (!short1 && !short2 && long1 && long2)
747         /* Only long options.  */
748         return __strcasecmp (long1, long2);
749       else
750         /* Compare short/short, long/short, short/long, using the first
751            character of long options.  Entries without *any* valid
752            options (such as options with OPTION_HIDDEN set) will be put
753            first, but as they're not displayed, it doesn't matter where
754            they are.  */
755         {
756           char first1 = short1 ? short1 : long1 ? *long1 : 0;
757           char first2 = short2 ? short2 : long2 ? *long2 : 0;
758 #ifdef _tolower
759           int lower_cmp = _tolower (first1) - _tolower (first2);
760 #else
761           int lower_cmp = tolower (first1) - tolower (first2);
762 #endif
763           /* Compare ignoring case, except when the options are both the
764              same letter, in which case lower-case always comes first.  */
765           return lower_cmp ? lower_cmp : first2 - first1;
766         }
767     }
768   else
769     /* Within the same cluster, but not the same group, so just compare
770        groups.  */
771     return group_cmp (group1, group2, 0);
772 }
773
774 /* Version of hol_entry_cmp with correct signature for qsort.  */
775 static int
776 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
777 {
778   return hol_entry_cmp (entry1_v, entry2_v);
779 }
780
781 /* Sort HOL by group and alphabetically by option name (with short options
782    taking precedence over long).  Since the sorting is for display purposes
783    only, the shadowing of options isn't effected.  */
784 static void
785 hol_sort (struct hol *hol)
786 {
787   if (hol->num_entries > 0)
788     qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
789            hol_entry_qcmp);
790 }
791 \f
792 /* Append MORE to HOL, destroying MORE in the process.  Options in HOL shadow
793    any in MORE with the same name.  */
794 static void
795 hol_append (struct hol *hol, struct hol *more)
796 {
797   struct hol_cluster **cl_end = &hol->clusters;
798
799   /* Steal MORE's cluster list, and add it to the end of HOL's.  */
800   while (*cl_end)
801     cl_end = &(*cl_end)->next;
802   *cl_end = more->clusters;
803   more->clusters = 0;
804
805   /* Merge entries.  */
806   if (more->num_entries > 0)
807     {
808       if (hol->num_entries == 0)
809         {
810           hol->num_entries = more->num_entries;
811           hol->entries = more->entries;
812           hol->short_options = more->short_options;
813           more->num_entries = 0;        /* Mark MORE's fields as invalid.  */
814         }
815       else
816         /* Append the entries in MORE to those in HOL, taking care to only add
817            non-shadowed SHORT_OPTIONS values.  */
818         {
819           unsigned left;
820           char *so, *more_so;
821           struct hol_entry *e;
822           unsigned num_entries = hol->num_entries + more->num_entries;
823           struct hol_entry *entries =
824             malloc (num_entries * sizeof (struct hol_entry));
825           unsigned hol_so_len = strlen (hol->short_options);
826           char *short_options =
827             malloc (hol_so_len + strlen (more->short_options) + 1);
828
829           assert (entries && short_options);
830           if (SIZE_MAX <= UINT_MAX)
831             assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
832
833           __mempcpy (__mempcpy (entries, hol->entries,
834                                 hol->num_entries * sizeof (struct hol_entry)),
835                      more->entries,
836                      more->num_entries * sizeof (struct hol_entry));
837
838           __mempcpy (short_options, hol->short_options, hol_so_len);
839
840           /* Fix up the short options pointers from HOL.  */
841           for (e = entries, left = hol->num_entries; left > 0; e++, left--)
842             e->short_options += (short_options - hol->short_options);
843
844           /* Now add the short options from MORE, fixing up its entries
845              too.  */
846           so = short_options + hol_so_len;
847           more_so = more->short_options;
848           for (left = more->num_entries; left > 0; e++, left--)
849             {
850               int opts_left;
851               const struct argp_option *opt;
852
853               e->short_options = so;
854
855               for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
856                 {
857                   int ch = *more_so;
858                   if (oshort (opt) && ch == opt->key)
859                     /* The next short option in MORE_SO, CH, is from OPT.  */
860                     {
861                       if (! find_char (ch, short_options,
862                                        short_options + hol_so_len))
863                         /* The short option CH isn't shadowed by HOL's options,
864                            so add it to the sum.  */
865                         *so++ = ch;
866                       more_so++;
867                     }
868                 }
869             }
870
871           *so = '\0';
872
873           free (hol->entries);
874           free (hol->short_options);
875
876           hol->entries = entries;
877           hol->num_entries = num_entries;
878           hol->short_options = short_options;
879         }
880     }
881
882   hol_free (more);
883 }
884 \f
885 /* Inserts enough spaces to make sure STREAM is at column COL.  */
886 static void
887 indent_to (argp_fmtstream_t stream, unsigned col)
888 {
889   int needed = col - __argp_fmtstream_point (stream);
890   while (needed-- > 0)
891     __argp_fmtstream_putc (stream, ' ');
892 }
893
894 /* Output to STREAM either a space, or a newline if there isn't room for at
895    least ENSURE characters before the right margin.  */
896 static void
897 space (argp_fmtstream_t stream, size_t ensure)
898 {
899   if (__argp_fmtstream_point (stream) + ensure
900       >= __argp_fmtstream_rmargin (stream))
901     __argp_fmtstream_putc (stream, '\n');
902   else
903     __argp_fmtstream_putc (stream, ' ');
904 }
905
906 /* If the option REAL has an argument, we print it in using the printf
907    format REQ_FMT or OPT_FMT depending on whether it's a required or
908    optional argument.  */
909 static void
910 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
911      const char *domain, argp_fmtstream_t stream)
912 {
913   if (real->arg)
914     {
915       if (real->flags & OPTION_ARG_OPTIONAL)
916         __argp_fmtstream_printf (stream, opt_fmt,
917                                  dgettext (domain, real->arg));
918       else
919         __argp_fmtstream_printf (stream, req_fmt,
920                                  dgettext (domain, real->arg));
921     }
922 }
923 \f
924 /* Helper functions for hol_entry_help.  */
925
926 /* State used during the execution of hol_help.  */
927 struct hol_help_state
928 {
929   /* PREV_ENTRY should contain the previous entry printed, or 0.  */
930   struct hol_entry *prev_entry;
931
932   /* If an entry is in a different group from the previous one, and SEP_GROUPS
933      is true, then a blank line will be printed before any output. */
934   int sep_groups;
935
936   /* True if a duplicate option argument was suppressed (only ever set if
937      UPARAMS.dup_args is false).  */
938   int suppressed_dup_arg;
939 };
940
941 /* Some state used while printing a help entry (used to communicate with
942    helper functions).  See the doc for hol_entry_help for more info, as most
943    of the fields are copied from its arguments.  */
944 struct pentry_state
945 {
946   const struct hol_entry *entry;
947   argp_fmtstream_t stream;
948   struct hol_help_state *hhstate;
949
950   /* True if nothing's been printed so far.  */
951   int first;
952
953   /* If non-zero, the state that was used to print this help.  */
954   const struct argp_state *state;
955 };
956
957 /* If a user doc filter should be applied to DOC, do so.  */
958 static const char *
959 filter_doc (const char *doc, int key, const struct argp *argp,
960             const struct argp_state *state)
961 {
962   if (argp->help_filter)
963     /* We must apply a user filter to this output.  */
964     {
965       void *input = __argp_input (argp, state);
966       return (*argp->help_filter) (key, doc, input);
967     }
968   else
969     /* No filter.  */
970     return doc;
971 }
972
973 /* Prints STR as a header line, with the margin lines set appropiately, and
974    notes the fact that groups should be separated with a blank line.  ARGP is
975    the argp that should dictate any user doc filtering to take place.  Note
976    that the previous wrap margin isn't restored, but the left margin is reset
977    to 0.  */
978 static void
979 print_header (const char *str, const struct argp *argp,
980               struct pentry_state *pest)
981 {
982   const char *tstr = dgettext (argp->argp_domain, str);
983   const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
984
985   if (fstr)
986     {
987       if (*fstr)
988         {
989           if (pest->hhstate->prev_entry)
990             /* Precede with a blank line.  */
991             __argp_fmtstream_putc (pest->stream, '\n');
992           indent_to (pest->stream, uparams.header_col);
993           __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
994           __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
995           __argp_fmtstream_puts (pest->stream, fstr);
996           __argp_fmtstream_set_lmargin (pest->stream, 0);
997           __argp_fmtstream_putc (pest->stream, '\n');
998         }
999
1000       pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
1001     }
1002
1003   if (fstr != tstr)
1004     free ((char *) fstr);
1005 }
1006
1007 /* Inserts a comma if this isn't the first item on the line, and then makes
1008    sure we're at least to column COL.  If this *is* the first item on a line,
1009    prints any pending whitespace/headers that should precede this line. Also
1010    clears FIRST.  */
1011 static void
1012 comma (unsigned col, struct pentry_state *pest)
1013 {
1014   if (pest->first)
1015     {
1016       const struct hol_entry *pe = pest->hhstate->prev_entry;
1017       const struct hol_cluster *cl = pest->entry->cluster;
1018
1019       if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1020         __argp_fmtstream_putc (pest->stream, '\n');
1021
1022       if (cl && cl->header && *cl->header
1023           && (!pe
1024               || (pe->cluster != cl
1025                   && !hol_cluster_is_child (pe->cluster, cl))))
1026         /* If we're changing clusters, then this must be the start of the
1027            ENTRY's cluster unless that is an ancestor of the previous one
1028            (in which case we had just popped into a sub-cluster for a bit).
1029            If so, then print the cluster's header line.  */
1030         {
1031           int old_wm = __argp_fmtstream_wmargin (pest->stream);
1032           print_header (cl->header, cl->argp, pest);
1033           __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1034         }
1035
1036       pest->first = 0;
1037     }
1038   else
1039     __argp_fmtstream_puts (pest->stream, ", ");
1040
1041   indent_to (pest->stream, col);
1042 }
1043 \f
1044 /* Print help for ENTRY to STREAM.  */
1045 static void
1046 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1047                 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1048 {
1049   unsigned num;
1050   const struct argp_option *real = entry->opt, *opt;
1051   char *so = entry->short_options;
1052   int have_long_opt = 0;        /* We have any long options.  */
1053   /* Saved margins.  */
1054   int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1055   int old_wm = __argp_fmtstream_wmargin (stream);
1056   /* PEST is a state block holding some of our variables that we'd like to
1057      share with helper functions.  */
1058   struct pentry_state pest = { entry, stream, hhstate, 1, state };
1059
1060   if (! odoc (real))
1061     for (opt = real, num = entry->num; num > 0; opt++, num--)
1062       if (opt->name && ovisible (opt))
1063         {
1064           have_long_opt = 1;
1065           break;
1066         }
1067
1068   /* First emit short options.  */
1069   __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1070   for (opt = real, num = entry->num; num > 0; opt++, num--)
1071     if (oshort (opt) && opt->key == *so)
1072       /* OPT has a valid (non shadowed) short option.  */
1073       {
1074         if (ovisible (opt))
1075           {
1076             comma (uparams.short_opt_col, &pest);
1077             __argp_fmtstream_putc (stream, '-');
1078             __argp_fmtstream_putc (stream, *so);
1079             if (!have_long_opt || uparams.dup_args)
1080               arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
1081             else if (real->arg)
1082               hhstate->suppressed_dup_arg = 1;
1083           }
1084         so++;
1085       }
1086
1087   /* Now, long options.  */
1088   if (odoc (real))
1089     /* A `documentation' option.  */
1090     {
1091       __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1092       for (opt = real, num = entry->num; num > 0; opt++, num--)
1093         if (opt->name && *opt->name && ovisible (opt))
1094           {
1095             comma (uparams.doc_opt_col, &pest);
1096             /* Calling dgettext here isn't quite right, since sorting will
1097                have been done on the original; but documentation options
1098                should be pretty rare anyway...  */
1099             __argp_fmtstream_puts (stream,
1100                                    onotrans (opt) ?
1101                                              opt->name :
1102                                    dgettext (state->root_argp->argp_domain,
1103                                              opt->name));
1104           }
1105     }
1106   else
1107     /* A real long option.  */
1108     {
1109       int first_long_opt = 1;
1110
1111       __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1112       for (opt = real, num = entry->num; num > 0; opt++, num--)
1113         if (opt->name && ovisible (opt))
1114           {
1115             comma (uparams.long_opt_col, &pest);
1116             __argp_fmtstream_printf (stream, "--%s", opt->name);
1117             if (first_long_opt || uparams.dup_args)
1118               arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
1119                    stream);
1120             else if (real->arg)
1121               hhstate->suppressed_dup_arg = 1;
1122           }
1123     }
1124
1125   /* Next, documentation strings.  */
1126   __argp_fmtstream_set_lmargin (stream, 0);
1127
1128   if (pest.first)
1129     {
1130       /* Didn't print any switches, what's up?  */
1131       if (!oshort (real) && !real->name)
1132         /* This is a group header, print it nicely.  */
1133         print_header (real->doc, entry->argp, &pest);
1134       else
1135         /* Just a totally shadowed option or null header; print nothing.  */
1136         goto cleanup;           /* Just return, after cleaning up.  */
1137     }
1138   else
1139     {
1140       const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
1141                                                real->doc) : 0;
1142       const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1143       if (fstr && *fstr)
1144         {
1145           unsigned int col = __argp_fmtstream_point (stream);
1146
1147           __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1148           __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1149
1150           if (col > (unsigned int) (uparams.opt_doc_col + 3))
1151             __argp_fmtstream_putc (stream, '\n');
1152           else if (col >= (unsigned int) uparams.opt_doc_col)
1153             __argp_fmtstream_puts (stream, "   ");
1154           else
1155             indent_to (stream, uparams.opt_doc_col);
1156
1157           __argp_fmtstream_puts (stream, fstr);
1158         }
1159       if (fstr && fstr != tstr)
1160         free ((char *) fstr);
1161
1162       /* Reset the left margin.  */
1163       __argp_fmtstream_set_lmargin (stream, 0);
1164       __argp_fmtstream_putc (stream, '\n');
1165     }
1166
1167   hhstate->prev_entry = entry;
1168
1169 cleanup:
1170   __argp_fmtstream_set_lmargin (stream, old_lm);
1171   __argp_fmtstream_set_wmargin (stream, old_wm);
1172 }
1173 \f
1174 /* Output a long help message about the options in HOL to STREAM.  */
1175 static void
1176 hol_help (struct hol *hol, const struct argp_state *state,
1177           argp_fmtstream_t stream)
1178 {
1179   unsigned num;
1180   struct hol_entry *entry;
1181   struct hol_help_state hhstate = { 0, 0, 0 };
1182
1183   for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1184     hol_entry_help (entry, state, stream, &hhstate);
1185
1186   if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1187     {
1188       const char *tstr = dgettext (state->root_argp->argp_domain, "\
1189 Mandatory or optional arguments to long options are also mandatory or \
1190 optional for any corresponding short options.");
1191       const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1192                                      state ? state->root_argp : 0, state);
1193       if (fstr && *fstr)
1194         {
1195           __argp_fmtstream_putc (stream, '\n');
1196           __argp_fmtstream_puts (stream, fstr);
1197           __argp_fmtstream_putc (stream, '\n');
1198         }
1199       if (fstr && fstr != tstr)
1200         free ((char *) fstr);
1201     }
1202 }
1203 \f
1204 /* Helper functions for hol_usage.  */
1205
1206 /* If OPT is a short option without an arg, append its key to the string
1207    pointer pointer to by COOKIE, and advance the pointer.  */
1208 static int
1209 add_argless_short_opt (const struct argp_option *opt,
1210                        const struct argp_option *real,
1211                        const char *domain, void *cookie)
1212 {
1213   char **snao_end = cookie;
1214   if (!(opt->arg || real->arg)
1215       && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1216     *(*snao_end)++ = opt->key;
1217   return 0;
1218 }
1219
1220 /* If OPT is a short option with an arg, output a usage entry for it to the
1221    stream pointed at by COOKIE.  */
1222 static int
1223 usage_argful_short_opt (const struct argp_option *opt,
1224                         const struct argp_option *real,
1225                         const char *domain, void *cookie)
1226 {
1227   argp_fmtstream_t stream = cookie;
1228   const char *arg = opt->arg;
1229   int flags = opt->flags | real->flags;
1230
1231   if (! arg)
1232     arg = real->arg;
1233
1234   if (arg && !(flags & OPTION_NO_USAGE))
1235     {
1236       arg = dgettext (domain, arg);
1237
1238       if (flags & OPTION_ARG_OPTIONAL)
1239         __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1240       else
1241         {
1242           /* Manually do line wrapping so that it (probably) won't
1243              get wrapped at the embedded space.  */
1244           space (stream, 6 + strlen (arg));
1245           __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1246         }
1247     }
1248
1249   return 0;
1250 }
1251
1252 /* Output a usage entry for the long option opt to the stream pointed at by
1253    COOKIE.  */
1254 static int
1255 usage_long_opt (const struct argp_option *opt,
1256                 const struct argp_option *real,
1257                 const char *domain, void *cookie)
1258 {
1259   argp_fmtstream_t stream = cookie;
1260   const char *arg = opt->arg;
1261   int flags = opt->flags | real->flags;
1262
1263   if (! arg)
1264     arg = real->arg;
1265
1266   if (! (flags & OPTION_NO_USAGE))
1267     {
1268       if (arg)
1269         {
1270           arg = dgettext (domain, arg);
1271           if (flags & OPTION_ARG_OPTIONAL)
1272             __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1273           else
1274             __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1275         }
1276       else
1277         __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1278     }
1279
1280   return 0;
1281 }
1282 \f
1283 /* Print a short usage description for the arguments in HOL to STREAM.  */
1284 static void
1285 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1286 {
1287   if (hol->num_entries > 0)
1288     {
1289       unsigned nentries;
1290       struct hol_entry *entry;
1291       char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1292       char *snao_end = short_no_arg_opts;
1293
1294       /* First we put a list of short options without arguments.  */
1295       for (entry = hol->entries, nentries = hol->num_entries
1296            ; nentries > 0
1297            ; entry++, nentries--)
1298         hol_entry_short_iterate (entry, add_argless_short_opt,
1299                                  entry->argp->argp_domain, &snao_end);
1300       if (snao_end > short_no_arg_opts)
1301         {
1302           *snao_end++ = 0;
1303           __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1304         }
1305
1306       /* Now a list of short options *with* arguments.  */
1307       for (entry = hol->entries, nentries = hol->num_entries
1308            ; nentries > 0
1309            ; entry++, nentries--)
1310         hol_entry_short_iterate (entry, usage_argful_short_opt,
1311                                  entry->argp->argp_domain, stream);
1312
1313       /* Finally, a list of long options (whew!).  */
1314       for (entry = hol->entries, nentries = hol->num_entries
1315            ; nentries > 0
1316            ; entry++, nentries--)
1317         hol_entry_long_iterate (entry, usage_long_opt,
1318                                 entry->argp->argp_domain, stream);
1319     }
1320 }
1321 \f
1322 /* Make a HOL containing all levels of options in ARGP.  CLUSTER is the
1323    cluster in which ARGP's entries should be clustered, or 0.  */
1324 static struct hol *
1325 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1326 {
1327   const struct argp_child *child = argp->children;
1328   struct hol *hol = make_hol (argp, cluster);
1329   if (child)
1330     while (child->argp)
1331       {
1332         struct hol_cluster *child_cluster =
1333           ((child->group || child->header)
1334            /* Put CHILD->argp within its own cluster.  */
1335            ? hol_add_cluster (hol, child->group, child->header,
1336                               child - argp->children, cluster, argp)
1337            /* Just merge it into the parent's cluster.  */
1338            : cluster);
1339         hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1340         child++;
1341       }
1342   return hol;
1343 }
1344 \f
1345 /* Calculate how many different levels with alternative args strings exist in
1346    ARGP.  */
1347 static size_t
1348 argp_args_levels (const struct argp *argp)
1349 {
1350   size_t levels = 0;
1351   const struct argp_child *child = argp->children;
1352
1353   if (argp->args_doc && strchr (argp->args_doc, '\n'))
1354     levels++;
1355
1356   if (child)
1357     while (child->argp)
1358       levels += argp_args_levels ((child++)->argp);
1359
1360   return levels;
1361 }
1362
1363 /* Print all the non-option args documented in ARGP to STREAM.  Any output is
1364    preceded by a space.  LEVELS is a pointer to a byte vector the length
1365    returned by argp_args_levels; it should be initialized to zero, and
1366    updated by this routine for the next call if ADVANCE is true.  True is
1367    returned as long as there are more patterns to output.  */
1368 static int
1369 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1370                  char **levels, int advance, argp_fmtstream_t stream)
1371 {
1372   char *our_level = *levels;
1373   int multiple = 0;
1374   const struct argp_child *child = argp->children;
1375   const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1376   const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1377
1378   if (fdoc)
1379     {
1380       const char *cp = fdoc;
1381       nl = __strchrnul (cp, '\n');
1382       if (*nl != '\0')
1383         /* This is a `multi-level' args doc; advance to the correct position
1384            as determined by our state in LEVELS, and update LEVELS.  */
1385         {
1386           int i;
1387           multiple = 1;
1388           for (i = 0; i < *our_level; i++)
1389             cp = nl + 1, nl = __strchrnul (cp, '\n');
1390           (*levels)++;
1391         }
1392
1393       /* Manually do line wrapping so that it (probably) won't get wrapped at
1394          any embedded spaces.  */
1395       space (stream, 1 + nl - cp);
1396
1397       __argp_fmtstream_write (stream, cp, nl - cp);
1398     }
1399   if (fdoc && fdoc != tdoc)
1400     free ((char *)fdoc);        /* Free user's modified doc string.  */
1401
1402   if (child)
1403     while (child->argp)
1404       advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1405
1406   if (advance && multiple)
1407     {
1408       /* Need to increment our level.  */
1409       if (*nl)
1410         /* There's more we can do here.  */
1411         {
1412           (*our_level)++;
1413           advance = 0;          /* Our parent shouldn't advance also. */
1414         }
1415       else if (*our_level > 0)
1416         /* We had multiple levels, but used them up; reset to zero.  */
1417         *our_level = 0;
1418     }
1419
1420   return !advance;
1421 }
1422 \f
1423 /* Print the documentation for ARGP to STREAM; if POST is false, then
1424    everything preceeding a `\v' character in the documentation strings (or
1425    the whole string, for those with none) is printed, otherwise, everything
1426    following the `\v' character (nothing for strings without).  Each separate
1427    bit of documentation is separated a blank line, and if PRE_BLANK is true,
1428    then the first is as well.  If FIRST_ONLY is true, only the first
1429    occurrence is output.  Returns true if anything was output.  */
1430 static int
1431 argp_doc (const struct argp *argp, const struct argp_state *state,
1432           int post, int pre_blank, int first_only,
1433           argp_fmtstream_t stream)
1434 {
1435   const char *text;
1436   const char *inp_text;
1437   void *input = 0;
1438   int anything = 0;
1439   size_t inp_text_limit = 0;
1440   const char *doc = dgettext (argp->argp_domain, argp->doc);
1441   const struct argp_child *child = argp->children;
1442
1443   if (doc)
1444     {
1445       char *vt = strchr (doc, '\v');
1446       inp_text = post ? (vt ? vt + 1 : 0) : doc;
1447       inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1448     }
1449   else
1450     inp_text = 0;
1451
1452   if (argp->help_filter)
1453     /* We have to filter the doc strings.  */
1454     {
1455       if (inp_text_limit)
1456         /* Copy INP_TEXT so that it's nul-terminated.  */
1457         inp_text = __strndup (inp_text, inp_text_limit);
1458       input = __argp_input (argp, state);
1459       text =
1460         (*argp->help_filter) (post
1461                               ? ARGP_KEY_HELP_POST_DOC
1462                               : ARGP_KEY_HELP_PRE_DOC,
1463                               inp_text, input);
1464     }
1465   else
1466     text = (const char *) inp_text;
1467
1468   if (text)
1469     {
1470       if (pre_blank)
1471         __argp_fmtstream_putc (stream, '\n');
1472
1473       if (text == inp_text && inp_text_limit)
1474         __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1475       else
1476         __argp_fmtstream_puts (stream, text);
1477
1478       if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1479         __argp_fmtstream_putc (stream, '\n');
1480
1481       anything = 1;
1482     }
1483
1484   if (text && text != inp_text)
1485     free ((char *) text);       /* Free TEXT returned from the help filter.  */
1486   if (inp_text && inp_text_limit && argp->help_filter)
1487     free ((char *) inp_text);   /* We copied INP_TEXT, so free it now.  */
1488
1489   if (post && argp->help_filter)
1490     /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text.  */
1491     {
1492       text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1493       if (text)
1494         {
1495           if (anything || pre_blank)
1496             __argp_fmtstream_putc (stream, '\n');
1497           __argp_fmtstream_puts (stream, text);
1498           free ((char *) text);
1499           if (__argp_fmtstream_point (stream)
1500               > __argp_fmtstream_lmargin (stream))
1501             __argp_fmtstream_putc (stream, '\n');
1502           anything = 1;
1503         }
1504     }
1505
1506   if (child)
1507     while (child->argp && !(first_only && anything))
1508       anything |=
1509         argp_doc ((child++)->argp, state,
1510                   post, anything || pre_blank, first_only,
1511                   stream);
1512
1513   return anything;
1514 }
1515 \f
1516 /* Output a usage message for ARGP to STREAM.  If called from
1517    argp_state_help, STATE is the relevent parsing state.  FLAGS are from the
1518    set ARGP_HELP_*.  NAME is what to use wherever a `program name' is
1519    needed. */
1520 static void
1521 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1522        unsigned flags, char *name)
1523 {
1524   int anything = 0;             /* Whether we've output anything.  */
1525   struct hol *hol = 0;
1526   argp_fmtstream_t fs;
1527
1528   if (! stream)
1529     return;
1530
1531 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1532   __flockfile (stream);
1533 #endif
1534
1535   if (! uparams.valid)
1536     fill_in_uparams (state);
1537
1538   fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1539   if (! fs)
1540     {
1541 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1542       __funlockfile (stream);
1543 #endif
1544       return;
1545     }
1546
1547   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1548     {
1549       hol = argp_hol (argp, 0);
1550
1551       /* If present, these options always come last.  */
1552       hol_set_group (hol, "help", -1);
1553       hol_set_group (hol, "version", -1);
1554
1555       hol_sort (hol);
1556     }
1557
1558   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1559     /* Print a short `Usage:' message.  */
1560     {
1561       int first_pattern = 1, more_patterns;
1562       size_t num_pattern_levels = argp_args_levels (argp);
1563       char *pattern_levels = alloca (num_pattern_levels);
1564
1565       memset (pattern_levels, 0, num_pattern_levels);
1566
1567       do
1568         {
1569           int old_lm;
1570           int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1571           char *levels = pattern_levels;
1572
1573           if (first_pattern)
1574             __argp_fmtstream_printf (fs, "%s %s",
1575                                      dgettext (argp->argp_domain, "Usage:"),
1576                                      name);
1577           else
1578             __argp_fmtstream_printf (fs, "%s %s",
1579                                      dgettext (argp->argp_domain, "  or: "),
1580                                      name);
1581
1582           /* We set the lmargin as well as the wmargin, because hol_usage
1583              manually wraps options with newline to avoid annoying breaks.  */
1584           old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1585
1586           if (flags & ARGP_HELP_SHORT_USAGE)
1587             /* Just show where the options go.  */
1588             {
1589               if (hol->num_entries > 0)
1590                 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1591                                                      " [OPTION...]"));
1592             }
1593           else
1594             /* Actually print the options.  */
1595             {
1596               hol_usage (hol, fs);
1597               flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */
1598             }
1599
1600           more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1601
1602           __argp_fmtstream_set_wmargin (fs, old_wm);
1603           __argp_fmtstream_set_lmargin (fs, old_lm);
1604
1605           __argp_fmtstream_putc (fs, '\n');
1606           anything = 1;
1607
1608           first_pattern = 0;
1609         }
1610       while (more_patterns);
1611     }
1612
1613   if (flags & ARGP_HELP_PRE_DOC)
1614     anything |= argp_doc (argp, state, 0, 0, 1, fs);
1615
1616   if (flags & ARGP_HELP_SEE)
1617     {
1618       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1619 Try `%s --help' or `%s --usage' for more information.\n"),
1620                                name, name);
1621       anything = 1;
1622     }
1623
1624   if (flags & ARGP_HELP_LONG)
1625     /* Print a long, detailed help message.  */
1626     {
1627       /* Print info about all the options.  */
1628       if (hol->num_entries > 0)
1629         {
1630           if (anything)
1631             __argp_fmtstream_putc (fs, '\n');
1632           hol_help (hol, state, fs);
1633           anything = 1;
1634         }
1635     }
1636
1637   if (flags & ARGP_HELP_POST_DOC)
1638     /* Print any documentation strings at the end.  */
1639     anything |= argp_doc (argp, state, 1, anything, 0, fs);
1640
1641   if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1642     {
1643       if (anything)
1644         __argp_fmtstream_putc (fs, '\n');
1645       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1646                                              "Report bugs to %s.\n"),
1647                                argp_program_bug_address);
1648       anything = 1;
1649     }
1650
1651 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1652   __funlockfile (stream);
1653 #endif
1654
1655   if (hol)
1656     hol_free (hol);
1657
1658   __argp_fmtstream_free (fs);
1659 }
1660 \f
1661 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
1662    ARGP_HELP_*.  NAME is what to use wherever a `program name' is needed. */
1663 void __argp_help (const struct argp *argp, FILE *stream,
1664                   unsigned flags, char *name)
1665 {
1666   _help (argp, 0, stream, flags, name);
1667 }
1668 #ifdef weak_alias
1669 weak_alias (__argp_help, argp_help)
1670 #endif
1671
1672 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1673 char *
1674 __argp_short_program_name (void)
1675 {
1676 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1677   char *name = strrchr (program_invocation_name, '/');
1678   return name ? name + 1 : program_invocation_name;
1679 # else
1680   /* FIXME: What now? Miles suggests that it is better to use NULL,
1681      but currently the value is passed on directly to fputs_unlocked,
1682      so that requires more changes. */
1683 # if __GNUC__
1684 #  warning No reasonable value to return
1685 # endif /* __GNUC__ */
1686   return "";
1687 # endif
1688 }
1689 #endif
1690
1691 /* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
1692    from the set ARGP_HELP_*.  */
1693 void
1694 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1695 {
1696   if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1697     {
1698       if (state && (state->flags & ARGP_LONG_ONLY))
1699         flags |= ARGP_HELP_LONG_ONLY;
1700
1701       _help (state ? state->root_argp : 0, state, stream, flags,
1702              state ? state->name : __argp_short_program_name ());
1703
1704       if (!state || ! (state->flags & ARGP_NO_EXIT))
1705         {
1706           if (flags & ARGP_HELP_EXIT_ERR)
1707             exit (argp_err_exit_status);
1708           if (flags & ARGP_HELP_EXIT_OK)
1709             exit (0);
1710         }
1711   }
1712 }
1713 #ifdef weak_alias
1714 weak_alias (__argp_state_help, argp_state_help)
1715 #endif
1716 \f
1717 /* If appropriate, print the printf string FMT and following args, preceded
1718    by the program name and `:', to stderr, and followed by a `Try ... --help'
1719    message, then exit (1).  */
1720 void
1721 __argp_error (const struct argp_state *state, const char *fmt, ...)
1722 {
1723   if (!state || !(state->flags & ARGP_NO_ERRS))
1724     {
1725       FILE *stream = state ? state->err_stream : stderr;
1726
1727       if (stream)
1728         {
1729           va_list ap;
1730
1731 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1732           __flockfile (stream);
1733 #endif
1734
1735           va_start (ap, fmt);
1736
1737 #ifdef USE_IN_LIBIO
1738           if (_IO_fwide (stream, 0) > 0)
1739             {
1740               char *buf;
1741
1742               __asprintf (&buf, fmt, ap);
1743
1744               __fwprintf (stream, L"%s: %s\n",
1745                           state ? state->name : __argp_short_program_name (),
1746                           buf);
1747
1748               free (buf);
1749             }
1750           else
1751 #endif
1752             {
1753               fputs_unlocked (state
1754                               ? state->name : __argp_short_program_name (),
1755                               stream);
1756               putc_unlocked (':', stream);
1757               putc_unlocked (' ', stream);
1758
1759               vfprintf (stream, fmt, ap);
1760
1761               putc_unlocked ('\n', stream);
1762             }
1763
1764           __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1765
1766           va_end (ap);
1767
1768 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1769           __funlockfile (stream);
1770 #endif
1771         }
1772     }
1773 }
1774 #ifdef weak_alias
1775 weak_alias (__argp_error, argp_error)
1776 #endif
1777 \f
1778 /* Similar to the standard gnu error-reporting function error(), but will
1779    respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1780    to STATE->err_stream.  This is useful for argument parsing code that is
1781    shared between program startup (when exiting is desired) and runtime
1782    option parsing (when typically an error code is returned instead).  The
1783    difference between this function and argp_error is that the latter is for
1784    *parsing errors*, and the former is for other problems that occur during
1785    parsing but don't reflect a (syntactic) problem with the input.  */
1786 void
1787 __argp_failure (const struct argp_state *state, int status, int errnum,
1788                 const char *fmt, ...)
1789 {
1790   if (!state || !(state->flags & ARGP_NO_ERRS))
1791     {
1792       FILE *stream = state ? state->err_stream : stderr;
1793
1794       if (stream)
1795         {
1796 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1797           __flockfile (stream);
1798 #endif
1799
1800 #ifdef USE_IN_LIBIO
1801           if (_IO_fwide (stream, 0) > 0)
1802             __fwprintf (stream, L"%s",
1803                         state ? state->name : __argp_short_program_name ());
1804           else
1805 #endif
1806             fputs_unlocked (state
1807                             ? state->name : __argp_short_program_name (),
1808                             stream);
1809
1810           if (fmt)
1811             {
1812               va_list ap;
1813
1814               va_start (ap, fmt);
1815 #ifdef USE_IN_LIBIO
1816               if (_IO_fwide (stream, 0) > 0)
1817                 {
1818                   char *buf;
1819
1820                   __asprintf (&buf, fmt, ap);
1821
1822                   __fwprintf (stream, L": %s", buf);
1823
1824                   free (buf);
1825                 }
1826               else
1827 #endif
1828                 {
1829                   putc_unlocked (':', stream);
1830                   putc_unlocked (' ', stream);
1831
1832                   vfprintf (stream, fmt, ap);
1833                 }
1834
1835               va_end (ap);
1836             }
1837
1838           if (errnum)
1839             {
1840               char buf[200];
1841
1842 #ifdef USE_IN_LIBIO
1843               if (_IO_fwide (stream, 0) > 0)
1844                 __fwprintf (stream, L": %s",
1845                             __strerror_r (errnum, buf, sizeof (buf)));
1846               else
1847 #endif
1848                 {
1849                   char const *s = NULL;
1850                   putc_unlocked (':', stream);
1851                   putc_unlocked (' ', stream);
1852 #if _LIBC || (HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P)
1853                   s = __strerror_r (errnum, buf, sizeof buf);
1854 #elif HAVE_DECL_STRERROR_R
1855                   if (__strerror_r (errnum, buf, sizeof buf) == 0)
1856                     s = buf;
1857 #endif
1858 #if !_LIBC
1859                   if (! s && ! (s = strerror (errnum)))
1860                     s = "Unknown system error"; /* FIXME: translate this */
1861 #endif
1862                   fputs (s, stream);
1863                 }
1864             }
1865
1866 #ifdef USE_IN_LIBIO
1867           if (_IO_fwide (stream, 0) > 0)
1868             putwc_unlocked (L'\n', stream);
1869           else
1870 #endif
1871             putc_unlocked ('\n', stream);
1872
1873 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1874           __funlockfile (stream);
1875 #endif
1876
1877           if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1878             exit (status);
1879         }
1880     }
1881 }
1882 #ifdef weak_alias
1883 weak_alias (__argp_failure, argp_failure)
1884 #endif