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