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