Bump to 1.14.1
[platform/upstream/augeas.git] / lib / argp-help.c
1 /* Hierarchical argument parsing help output
2    Copyright (C) 1995-2016 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 <stdbool.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 _LIBC
38 # include <../libio/libioP.h>
39 # include <wchar.h>
40 #endif
41
42 #ifdef _LIBC
43 # include <libintl.h>
44 # undef dgettext
45 # define dgettext(domain, msgid) \
46    __dcgettext (domain, msgid, LC_MESSAGES)
47 #else
48 # include "gettext.h"
49 #endif
50
51 #include "argp.h"
52 #include "argp-fmtstream.h"
53 #include "argp-namefrob.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 };
110
111 /* A particular uparam, and what the user name is.  */
112 struct uparam_name
113 {
114   const char name[14];          /* User name.  */
115   bool is_bool;                 /* Whether it's 'boolean'.  */
116   unsigned char uparams_offs;   /* Location of the (int) field in UPARAMS.  */
117 };
118
119 /* The name-field mappings we know about.  */
120 static const struct uparam_name uparam_names[] =
121 {
122   { "dup-args",       true, offsetof (struct uparams, dup_args) },
123   { "dup-args-note",  true, offsetof (struct uparams, dup_args_note) },
124   { "short-opt-col",  false, offsetof (struct uparams, short_opt_col) },
125   { "long-opt-col",   false, offsetof (struct uparams, long_opt_col) },
126   { "doc-opt-col",    false, offsetof (struct uparams, doc_opt_col) },
127   { "opt-doc-col",    false, offsetof (struct uparams, opt_doc_col) },
128   { "header-col",     false, offsetof (struct uparams, header_col) },
129   { "usage-indent",   false, offsetof (struct uparams, usage_indent) },
130   { "rmargin",        false, offsetof (struct uparams, rmargin) }
131 };
132 #define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
133
134 static void
135 validate_uparams (const struct argp_state *state, struct uparams *upptr)
136 {
137   const struct uparam_name *up;
138
139   for (up = uparam_names; up < uparam_names + nuparam_names; up++)
140     {
141       if (up->is_bool
142           || up->uparams_offs == offsetof (struct uparams, rmargin))
143         continue;
144       if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin)
145         {
146           __argp_failure (state, 0, 0,
147                           dgettext (state->root_argp->argp_domain,
148                                     "\
149 ARGP_HELP_FMT: %s value is less than or equal to %s"),
150                           "rmargin", up->name);
151           return;
152         }
153     }
154   uparams = *upptr;
155   uparams.valid = 1;
156 }
157
158 /* Read user options from the environment, and fill in UPARAMS appropriately.  */
159 static void
160 fill_in_uparams (const struct argp_state *state)
161 {
162   const char *var = getenv ("ARGP_HELP_FMT");
163   struct uparams new_params = uparams;
164
165 #define SKIPWS(p) do { while (isspace ((unsigned char) *p)) p++; } while (0);
166
167   if (var)
168     {
169       /* Parse var. */
170       while (*var)
171         {
172           SKIPWS (var);
173
174           if (isalpha ((unsigned char) *var))
175             {
176               size_t var_len;
177               const struct uparam_name *un;
178               int unspec = 0, val = 0;
179               const char *arg = var;
180
181               while (isalnum ((unsigned char) *arg) || *arg == '-' || *arg == '_')
182                 arg++;
183               var_len = arg - var;
184
185               SKIPWS (arg);
186
187               if (*arg == '\0' || *arg == ',')
188                 unspec = 1;
189               else if (*arg == '=')
190                 {
191                   arg++;
192                   SKIPWS (arg);
193                 }
194
195               if (unspec)
196                 {
197                   if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
198                     {
199                       val = 0;
200                       var += 3;
201                       var_len -= 3;
202                     }
203                   else
204                     val = 1;
205                 }
206               else if (isdigit ((unsigned char) *arg))
207                 {
208                   val = atoi (arg);
209                   while (isdigit ((unsigned char) *arg))
210                     arg++;
211                   SKIPWS (arg);
212                 }
213
214               for (un = uparam_names;
215                    un < uparam_names + nuparam_names;
216                    un++)
217                 if (strlen (un->name) == var_len
218                     && strncmp (var, un->name, var_len) == 0)
219                   {
220                     if (unspec && !un->is_bool)
221                       __argp_failure (state, 0, 0,
222                                       dgettext (state == NULL ? NULL
223                                                 : state->root_argp->argp_domain,
224                                                 "\
225 %.*s: ARGP_HELP_FMT parameter requires a value"),
226                                       (int) var_len, var);
227                     else
228                       *(int *)((char *)&new_params + un->uparams_offs) = val;
229                     break;
230                   }
231               if (un == uparam_names + nuparam_names)
232                 __argp_failure (state, 0, 0,
233                                 dgettext (state == NULL ? NULL
234                                           : state->root_argp->argp_domain, "\
235 %.*s: Unknown ARGP_HELP_FMT parameter"),
236                                 (int) var_len, var);
237
238               var = arg;
239               if (*var == ',')
240                 var++;
241             }
242           else if (*var)
243             {
244               __argp_failure (state, 0, 0,
245                               dgettext (state == NULL ? NULL
246                                         : 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 a 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 "]" appropriately if the argument is
281    optional.  The documentation string is word-wrapped appropriately, 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 slightly 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 an 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 #if __GNUC__ >= 3
574 __attribute__ ((always_inline))
575 #endif
576 hol_entry_long_iterate (const struct hol_entry *entry,
577                         int (*func)(const struct argp_option *opt,
578                                     const struct argp_option *real,
579                                     const char *domain, void *cookie),
580                         const char *domain, void *cookie)
581 {
582   unsigned nopts;
583   int val = 0;
584   const struct argp_option *opt, *real = entry->opt;
585
586   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
587     if (opt->name)
588       {
589         if (!oalias (opt))
590           real = opt;
591         if (ovisible (opt))
592           val = (*func)(opt, real, domain, cookie);
593       }
594
595   return val;
596 }
597 \f
598 /* Iterator that returns true for the first short option.  */
599 static int
600 until_short (const struct argp_option *opt, const struct argp_option *real,
601              const char *domain, void *cookie)
602 {
603   return oshort (opt) ? opt->key : 0;
604 }
605
606 /* Returns the first valid short option in ENTRY, or 0 if there is none.  */
607 static char
608 hol_entry_first_short (const struct hol_entry *entry)
609 {
610   return hol_entry_short_iterate (entry, until_short,
611                                   entry->argp->argp_domain, 0);
612 }
613
614 /* Returns the first valid long option in ENTRY, or 0 if there is none.  */
615 static const char *
616 hol_entry_first_long (const struct hol_entry *entry)
617 {
618   const struct argp_option *opt;
619   unsigned num;
620   for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
621     if (opt->name && ovisible (opt))
622       return opt->name;
623   return 0;
624 }
625
626 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
627    none.  */
628 static struct hol_entry *
629 hol_find_entry (struct hol *hol, const char *name)
630 {
631   struct hol_entry *entry = hol->entries;
632   unsigned num_entries = hol->num_entries;
633
634   while (num_entries-- > 0)
635     {
636       const struct argp_option *opt = entry->opt;
637       unsigned num_opts = entry->num;
638
639       while (num_opts-- > 0)
640         if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
641           return entry;
642         else
643           opt++;
644
645       entry++;
646     }
647
648   return 0;
649 }
650 \f
651 /* If an entry with the long option NAME occurs in HOL, set its special
652    sort position to GROUP.  */
653 static void
654 hol_set_group (struct hol *hol, const char *name, int group)
655 {
656   struct hol_entry *entry = hol_find_entry (hol, name);
657   if (entry)
658     entry->group = group;
659 }
660 \f
661 /* Order by group:  0, 1, 2, ..., n, -m, ..., -2, -1.
662    EQ is what to return if GROUP1 and GROUP2 are the same.  */
663 static int
664 group_cmp (int group1, int group2, int eq)
665 {
666   if (group1 == group2)
667     return eq;
668   else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
669     return group1 - group2;
670   else
671     return group2 - group1;
672 }
673
674 /* Compare clusters CL1 & CL2 by the order that they should appear in
675    output.  */
676 static int
677 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
678 {
679   /* If one cluster is deeper than the other, use its ancestor at the same
680      level, so that finding the common ancestor is straightforward.  */
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 an 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   /* Skip initial whitespace.  */
722   while (isspace (**name))
723     (*name)++;
724   /* Decide whether this looks like an option (leading '-') or not.  */
725   non_opt = (**name != '-');
726   /* Skip until part of name used for sorting.  */
727   while (**name && !isalnum (**name))
728     (*name)++;
729   return non_opt;
730 }
731
732 #define HOL_ENTRY_PTRCMP(a,b) ((a)->ord < (b)->ord ? -1 : 1)
733
734 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
735    listing.  */
736 static int
737 hol_entry_cmp (const struct hol_entry *entry1,
738                const struct hol_entry *entry2)
739 {
740   /* The group numbers by which the entries should be ordered; if either is
741      in a cluster, then this is just the group within the cluster.  */
742   int group1 = entry1->group, group2 = entry2->group;
743
744   if (entry1->cluster != entry2->cluster)
745     {
746       /* The entries are not within the same cluster, so we can't compare them
747          directly, we have to use the appropriate clustering level too.  */
748       if (! entry1->cluster)
749         /* ENTRY1 is at the 'base level', not in a cluster, so we have to
750            compare it's group number with that of the base cluster in which
751            ENTRY2 resides.  Note that if they're in the same group, the
752            clustered option always comes last.  */
753         return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
754       else if (! entry2->cluster)
755         /* Likewise, but ENTRY2's not in a cluster.  */
756         return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
757       else
758         /* Both entries are in clusters, we can just compare the clusters.  */
759         return hol_cluster_cmp (entry1->cluster, entry2->cluster);
760     }
761   else if (group1 == group2)
762     /* The entries are both in the same cluster and group, so compare them
763        alphabetically.  */
764     {
765       int short1 = hol_entry_first_short (entry1);
766       int short2 = hol_entry_first_short (entry2);
767       int doc1 = odoc (entry1->opt);
768       int doc2 = odoc (entry2->opt);
769       const char *long1 = hol_entry_first_long (entry1);
770       const char *long2 = hol_entry_first_long (entry2);
771
772       if (doc1)
773         doc1 = long1 != NULL && canon_doc_option (&long1);
774       if (doc2)
775         doc2 = long2 != NULL && canon_doc_option (&long2);
776
777       if (doc1 != doc2)
778         /* 'documentation' options always follow normal options (or
779            documentation options that *look* like normal options).  */
780         return doc1 - doc2;
781       else if (!short1 && !short2 && long1 && long2)
782         /* Only long options.  */
783         return __strcasecmp (long1, long2);
784       else
785         /* Compare short/short, long/short, short/long, using the first
786            character of long options.  Entries without *any* valid
787            options (such as options with OPTION_HIDDEN set) will be put
788            first, but as they're not displayed, it doesn't matter where
789            they are.  */
790         {
791           char first1 = short1 ? short1 : long1 ? *long1 : 0;
792           char first2 = short2 ? short2 : long2 ? *long2 : 0;
793 #ifdef _tolower
794           int lower_cmp = _tolower (first1) - _tolower (first2);
795 #else
796           int lower_cmp = tolower (first1) - tolower (first2);
797 #endif
798           /* Compare ignoring case, except when the options are both the
799              same letter, in which case lower-case always comes first.  */
800           return lower_cmp ? lower_cmp : first2 - first1;
801         }
802     }
803   else
804     /* Within the same cluster, but not the same group, so just compare
805        groups.  */
806     return group_cmp (group1, group2, 0);
807 }
808
809 /* Version of hol_entry_cmp with correct signature for qsort.  */
810 static int
811 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
812 {
813   return hol_entry_cmp (entry1_v, entry2_v);
814 }
815
816 /* Sort HOL by group and alphabetically by option name (with short options
817    taking precedence over long).  Since the sorting is for display purposes
818    only, the shadowing of options isn't effected.  */
819 static void
820 hol_sort (struct hol *hol)
821 {
822   if (hol->num_entries > 0)
823     {
824       unsigned i;
825       struct hol_entry *e;
826       for (i = 0, e = hol->entries; i < hol->num_entries; i++, e++)
827         e->ord = i;
828       qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
829              hol_entry_qcmp);
830     }
831 }
832 \f
833 /* Append MORE to HOL, destroying MORE in the process.  Options in HOL shadow
834    any in MORE with the same name.  */
835 static void
836 hol_append (struct hol *hol, struct hol *more)
837 {
838   struct hol_cluster **cl_end = &hol->clusters;
839
840   /* Steal MORE's cluster list, and add it to the end of HOL's.  */
841   while (*cl_end)
842     cl_end = &(*cl_end)->next;
843   *cl_end = more->clusters;
844   more->clusters = 0;
845
846   /* Merge entries.  */
847   if (more->num_entries > 0)
848     {
849       if (hol->num_entries == 0)
850         {
851           hol->num_entries = more->num_entries;
852           hol->entries = more->entries;
853           hol->short_options = more->short_options;
854           more->num_entries = 0;        /* Mark MORE's fields as invalid.  */
855         }
856       else
857         /* Append the entries in MORE to those in HOL, taking care to only add
858            non-shadowed SHORT_OPTIONS values.  */
859         {
860           unsigned left;
861           char *so, *more_so;
862           struct hol_entry *e;
863           unsigned num_entries = hol->num_entries + more->num_entries;
864           struct hol_entry *entries =
865             malloc (num_entries * sizeof (struct hol_entry));
866           unsigned hol_so_len = strlen (hol->short_options);
867           char *short_options =
868             malloc (hol_so_len + strlen (more->short_options) + 1);
869
870           assert (entries && short_options);
871           if (SIZE_MAX <= UINT_MAX)
872             assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
873
874           __mempcpy (__mempcpy (entries, hol->entries,
875                                 hol->num_entries * sizeof (struct hol_entry)),
876                      more->entries,
877                      more->num_entries * sizeof (struct hol_entry));
878
879           __mempcpy (short_options, hol->short_options, hol_so_len);
880
881           /* Fix up the short options pointers from HOL.  */
882           for (e = entries, left = hol->num_entries; left > 0; e++, left--)
883             e->short_options += (short_options - hol->short_options);
884
885           /* Now add the short options from MORE, fixing up its entries
886              too.  */
887           so = short_options + hol_so_len;
888           more_so = more->short_options;
889           for (left = more->num_entries; left > 0; e++, left--)
890             {
891               int opts_left;
892               const struct argp_option *opt;
893
894               e->short_options = so;
895
896               for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
897                 {
898                   int ch = *more_so;
899                   if (oshort (opt) && ch == opt->key)
900                     /* The next short option in MORE_SO, CH, is from OPT.  */
901                     {
902                       if (! find_char (ch, short_options,
903                                        short_options + hol_so_len))
904                         /* The short option CH isn't shadowed by HOL's options,
905                            so add it to the sum.  */
906                         *so++ = ch;
907                       more_so++;
908                     }
909                 }
910             }
911
912           *so = '\0';
913
914           free (hol->entries);
915           free (hol->short_options);
916
917           hol->entries = entries;
918           hol->num_entries = num_entries;
919           hol->short_options = short_options;
920         }
921     }
922
923   hol_free (more);
924 }
925 \f
926 /* Inserts enough spaces to make sure STREAM is at column COL.  */
927 static void
928 indent_to (argp_fmtstream_t stream, unsigned col)
929 {
930   int needed = col - __argp_fmtstream_point (stream);
931   while (needed-- > 0)
932     __argp_fmtstream_putc (stream, ' ');
933 }
934
935 /* Output to STREAM either a space, or a newline if there isn't room for at
936    least ENSURE characters before the right margin.  */
937 static void
938 space (argp_fmtstream_t stream, size_t ensure)
939 {
940   if (__argp_fmtstream_point (stream) + ensure
941       >= __argp_fmtstream_rmargin (stream))
942     __argp_fmtstream_putc (stream, '\n');
943   else
944     __argp_fmtstream_putc (stream, ' ');
945 }
946
947 /* If the option REAL has an argument, we print it in using the printf
948    format REQ_FMT or OPT_FMT depending on whether it's a required or
949    optional argument.  */
950 static void
951 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
952      const char *domain, argp_fmtstream_t stream)
953 {
954   if (real->arg)
955     {
956       if (real->flags & OPTION_ARG_OPTIONAL)
957         __argp_fmtstream_printf (stream, opt_fmt,
958                                  dgettext (domain, real->arg));
959       else
960         __argp_fmtstream_printf (stream, req_fmt,
961                                  dgettext (domain, real->arg));
962     }
963 }
964 \f
965 /* Helper functions for hol_entry_help.  */
966
967 /* State used during the execution of hol_help.  */
968 struct hol_help_state
969 {
970   /* PREV_ENTRY should contain the previous entry printed, or 0.  */
971   struct hol_entry *prev_entry;
972
973   /* If an entry is in a different group from the previous one, and SEP_GROUPS
974      is true, then a blank line will be printed before any output. */
975   int sep_groups;
976
977   /* True if a duplicate option argument was suppressed (only ever set if
978      UPARAMS.dup_args is false).  */
979   int suppressed_dup_arg;
980 };
981
982 /* Some state used while printing a help entry (used to communicate with
983    helper functions).  See the doc for hol_entry_help for more info, as most
984    of the fields are copied from its arguments.  */
985 struct pentry_state
986 {
987   const struct hol_entry *entry;
988   argp_fmtstream_t stream;
989   struct hol_help_state *hhstate;
990
991   /* True if nothing's been printed so far.  */
992   int first;
993
994   /* If non-zero, the state that was used to print this help.  */
995   const struct argp_state *state;
996 };
997
998 /* If a user doc filter should be applied to DOC, do so.  */
999 static const char *
1000 filter_doc (const char *doc, int key, const struct argp *argp,
1001             const struct argp_state *state)
1002 {
1003   if (argp && argp->help_filter)
1004     /* We must apply a user filter to this output.  */
1005     {
1006       void *input = __argp_input (argp, state);
1007       return (*argp->help_filter) (key, doc, input);
1008     }
1009   else
1010     /* No filter.  */
1011     return doc;
1012 }
1013
1014 /* Prints STR as a header line, with the margin lines set appropriately, and
1015    notes the fact that groups should be separated with a blank line.  ARGP is
1016    the argp that should dictate any user doc filtering to take place.  Note
1017    that the previous wrap margin isn't restored, but the left margin is reset
1018    to 0.  */
1019 static void
1020 print_header (const char *str, const struct argp *argp,
1021               struct pentry_state *pest)
1022 {
1023   const char *tstr = dgettext (argp->argp_domain, str);
1024   const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
1025
1026   if (fstr)
1027     {
1028       if (*fstr)
1029         {
1030           if (pest->hhstate->prev_entry)
1031             /* Precede with a blank line.  */
1032             __argp_fmtstream_putc (pest->stream, '\n');
1033           indent_to (pest->stream, uparams.header_col);
1034           __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
1035           __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
1036           __argp_fmtstream_puts (pest->stream, fstr);
1037           __argp_fmtstream_set_lmargin (pest->stream, 0);
1038           __argp_fmtstream_putc (pest->stream, '\n');
1039         }
1040
1041       pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
1042     }
1043
1044   if (fstr != tstr)
1045     free ((char *) fstr);
1046 }
1047
1048 /* Inserts a comma if this isn't the first item on the line, and then makes
1049    sure we're at least to column COL.  If this *is* the first item on a line,
1050    prints any pending whitespace/headers that should precede this line. Also
1051    clears FIRST.  */
1052 static void
1053 comma (unsigned col, struct pentry_state *pest)
1054 {
1055   if (pest->first)
1056     {
1057       const struct hol_entry *pe = pest->hhstate->prev_entry;
1058       const struct hol_cluster *cl = pest->entry->cluster;
1059
1060       if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
1061         __argp_fmtstream_putc (pest->stream, '\n');
1062
1063       if (cl && cl->header && *cl->header
1064           && (!pe
1065               || (pe->cluster != cl
1066                   && !hol_cluster_is_child (pe->cluster, cl))))
1067         /* If we're changing clusters, then this must be the start of the
1068            ENTRY's cluster unless that is an ancestor of the previous one
1069            (in which case we had just popped into a sub-cluster for a bit).
1070            If so, then print the cluster's header line.  */
1071         {
1072           int old_wm = __argp_fmtstream_wmargin (pest->stream);
1073           print_header (cl->header, cl->argp, pest);
1074           __argp_fmtstream_set_wmargin (pest->stream, old_wm);
1075         }
1076
1077       pest->first = 0;
1078     }
1079   else
1080     __argp_fmtstream_puts (pest->stream, ", ");
1081
1082   indent_to (pest->stream, col);
1083 }
1084 \f
1085 /* Print help for ENTRY to STREAM.  */
1086 static void
1087 hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
1088                 argp_fmtstream_t stream, struct hol_help_state *hhstate)
1089 {
1090   unsigned num;
1091   const struct argp_option *real = entry->opt, *opt;
1092   char *so = entry->short_options;
1093   int have_long_opt = 0;        /* We have any long options.  */
1094   /* Saved margins.  */
1095   int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
1096   int old_wm = __argp_fmtstream_wmargin (stream);
1097   /* PEST is a state block holding some of our variables that we'd like to
1098      share with helper functions.  */
1099   struct pentry_state pest = { entry, stream, hhstate, 1, state };
1100
1101   if (! odoc (real))
1102     for (opt = real, num = entry->num; num > 0; opt++, num--)
1103       if (opt->name && ovisible (opt))
1104         {
1105           have_long_opt = 1;
1106           break;
1107         }
1108
1109   /* First emit short options.  */
1110   __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
1111   for (opt = real, num = entry->num; num > 0; opt++, num--)
1112     if (oshort (opt) && opt->key == *so)
1113       /* OPT has a valid (non shadowed) short option.  */
1114       {
1115         if (ovisible (opt))
1116           {
1117             comma (uparams.short_opt_col, &pest);
1118             __argp_fmtstream_putc (stream, '-');
1119             __argp_fmtstream_putc (stream, *so);
1120             if (!have_long_opt || uparams.dup_args)
1121               arg (real, " %s", "[%s]",
1122                    state == NULL ? NULL : state->root_argp->argp_domain,
1123                    stream);
1124             else if (real->arg)
1125               hhstate->suppressed_dup_arg = 1;
1126           }
1127         so++;
1128       }
1129
1130   /* Now, long options.  */
1131   if (odoc (real))
1132     /* A "documentation" option.  */
1133     {
1134       __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
1135       for (opt = real, num = entry->num; num > 0; opt++, num--)
1136         if (opt->name && ovisible (opt))
1137           {
1138             comma (uparams.doc_opt_col, &pest);
1139             /* Calling dgettext here isn't quite right, since sorting will
1140                have been done on the original; but documentation options
1141                should be pretty rare anyway...  */
1142             __argp_fmtstream_puts (stream,
1143                                    dgettext (state == NULL ? NULL
1144                                              : state->root_argp->argp_domain,
1145                                              opt->name));
1146           }
1147     }
1148   else
1149     /* A real long option.  */
1150     {
1151       __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
1152       for (opt = real, num = entry->num; num > 0; opt++, num--)
1153         if (opt->name && ovisible (opt))
1154           {
1155             comma (uparams.long_opt_col, &pest);
1156             __argp_fmtstream_printf (stream, "--%s", opt->name);
1157             arg (real, "=%s", "[=%s]",
1158                  state == NULL ? NULL : state->root_argp->argp_domain, stream);
1159           }
1160     }
1161
1162   /* Next, documentation strings.  */
1163   __argp_fmtstream_set_lmargin (stream, 0);
1164
1165   if (pest.first)
1166     {
1167       /* Didn't print any switches, what's up?  */
1168       if (!oshort (real) && !real->name)
1169         /* This is a group header, print it nicely.  */
1170         print_header (real->doc, entry->argp, &pest);
1171       else
1172         /* Just a totally shadowed option or null header; print nothing.  */
1173         goto cleanup;           /* Just return, after cleaning up.  */
1174     }
1175   else
1176     {
1177       const char *tstr = real->doc ? dgettext (state == NULL ? NULL
1178                                                : state->root_argp->argp_domain,
1179                                                real->doc) : 0;
1180       const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
1181       if (fstr && *fstr)
1182         {
1183           unsigned int col = __argp_fmtstream_point (stream);
1184
1185           __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
1186           __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
1187
1188           if (col > (unsigned int) (uparams.opt_doc_col + 3))
1189             __argp_fmtstream_putc (stream, '\n');
1190           else if (col >= (unsigned int) uparams.opt_doc_col)
1191             __argp_fmtstream_puts (stream, "   ");
1192           else
1193             indent_to (stream, uparams.opt_doc_col);
1194
1195           __argp_fmtstream_puts (stream, fstr);
1196         }
1197       if (fstr && fstr != tstr)
1198         free ((char *) fstr);
1199
1200       /* Reset the left margin.  */
1201       __argp_fmtstream_set_lmargin (stream, 0);
1202       __argp_fmtstream_putc (stream, '\n');
1203     }
1204
1205   hhstate->prev_entry = entry;
1206
1207 cleanup:
1208   __argp_fmtstream_set_lmargin (stream, old_lm);
1209   __argp_fmtstream_set_wmargin (stream, old_wm);
1210 }
1211 \f
1212 /* Output a long help message about the options in HOL to STREAM.  */
1213 static void
1214 hol_help (struct hol *hol, const struct argp_state *state,
1215           argp_fmtstream_t stream)
1216 {
1217   unsigned num;
1218   struct hol_entry *entry;
1219   struct hol_help_state hhstate = { 0, 0, 0 };
1220
1221   for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
1222     hol_entry_help (entry, state, stream, &hhstate);
1223
1224   if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
1225     {
1226       const char *tstr = dgettext (state == NULL ? NULL
1227                                    : state->root_argp->argp_domain, "\
1228 Mandatory or optional arguments to long options are also mandatory or \
1229 optional for any corresponding short options.");
1230       const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
1231                                      state ? state->root_argp : 0, state);
1232       if (fstr && *fstr)
1233         {
1234           __argp_fmtstream_putc (stream, '\n');
1235           __argp_fmtstream_puts (stream, fstr);
1236           __argp_fmtstream_putc (stream, '\n');
1237         }
1238       if (fstr && fstr != tstr)
1239         free ((char *) fstr);
1240     }
1241 }
1242 \f
1243 /* Helper functions for hol_usage.  */
1244
1245 /* If OPT is a short option without an arg, append its key to the string
1246    pointer pointer to by COOKIE, and advance the pointer.  */
1247 static int
1248 add_argless_short_opt (const struct argp_option *opt,
1249                        const struct argp_option *real,
1250                        const char *domain, void *cookie)
1251 {
1252   char **snao_end = cookie;
1253   if (!(opt->arg || real->arg)
1254       && !((opt->flags | real->flags) & OPTION_NO_USAGE))
1255     *(*snao_end)++ = opt->key;
1256   return 0;
1257 }
1258
1259 /* If OPT is a short option with an arg, output a usage entry for it to the
1260    stream pointed at by COOKIE.  */
1261 static int
1262 usage_argful_short_opt (const struct argp_option *opt,
1263                         const struct argp_option *real,
1264                         const char *domain, void *cookie)
1265 {
1266   argp_fmtstream_t stream = cookie;
1267   const char *arg = opt->arg;
1268   int flags = opt->flags | real->flags;
1269
1270   if (! arg)
1271     arg = real->arg;
1272
1273   if (arg && !(flags & OPTION_NO_USAGE))
1274     {
1275       arg = dgettext (domain, arg);
1276
1277       if (flags & OPTION_ARG_OPTIONAL)
1278         __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
1279       else
1280         {
1281           /* Manually do line wrapping so that it (probably) won't
1282              get wrapped at the embedded space.  */
1283           space (stream, 6 + strlen (arg));
1284           __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
1285         }
1286     }
1287
1288   return 0;
1289 }
1290
1291 /* Output a usage entry for the long option opt to the stream pointed at by
1292    COOKIE.  */
1293 static int
1294 usage_long_opt (const struct argp_option *opt,
1295                 const struct argp_option *real,
1296                 const char *domain, void *cookie)
1297 {
1298   argp_fmtstream_t stream = cookie;
1299   const char *arg = opt->arg;
1300   int flags = opt->flags | real->flags;
1301
1302   if (! arg)
1303     arg = real->arg;
1304
1305   if (! (flags & OPTION_NO_USAGE))
1306     {
1307       if (arg)
1308         {
1309           arg = dgettext (domain, arg);
1310           if (flags & OPTION_ARG_OPTIONAL)
1311             __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
1312           else
1313             __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
1314         }
1315       else
1316         __argp_fmtstream_printf (stream, " [--%s]", opt->name);
1317     }
1318
1319   return 0;
1320 }
1321 \f
1322 /* Print a short usage description for the arguments in HOL to STREAM.  */
1323 static void
1324 hol_usage (struct hol *hol, argp_fmtstream_t stream)
1325 {
1326   if (hol->num_entries > 0)
1327     {
1328       unsigned nentries;
1329       struct hol_entry *entry;
1330       char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
1331       char *snao_end = short_no_arg_opts;
1332
1333       /* First we put a list of short options without arguments.  */
1334       for (entry = hol->entries, nentries = hol->num_entries
1335            ; nentries > 0
1336            ; entry++, nentries--)
1337         hol_entry_short_iterate (entry, add_argless_short_opt,
1338                                  entry->argp->argp_domain, &snao_end);
1339       if (snao_end > short_no_arg_opts)
1340         {
1341           *snao_end++ = 0;
1342           __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
1343         }
1344
1345       /* Now a list of short options *with* arguments.  */
1346       for (entry = hol->entries, nentries = hol->num_entries
1347            ; nentries > 0
1348            ; entry++, nentries--)
1349         hol_entry_short_iterate (entry, usage_argful_short_opt,
1350                                  entry->argp->argp_domain, stream);
1351
1352       /* Finally, a list of long options (whew!).  */
1353       for (entry = hol->entries, nentries = hol->num_entries
1354            ; nentries > 0
1355            ; entry++, nentries--)
1356         hol_entry_long_iterate (entry, usage_long_opt,
1357                                 entry->argp->argp_domain, stream);
1358     }
1359 }
1360 \f
1361 /* Make a HOL containing all levels of options in ARGP.  CLUSTER is the
1362    cluster in which ARGP's entries should be clustered, or 0.  */
1363 static struct hol *
1364 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1365 {
1366   const struct argp_child *child = argp->children;
1367   struct hol *hol = make_hol (argp, cluster);
1368   if (child)
1369     while (child->argp)
1370       {
1371         struct hol_cluster *child_cluster =
1372           ((child->group || child->header)
1373            /* Put CHILD->argp within its own cluster.  */
1374            ? hol_add_cluster (hol, child->group, child->header,
1375                               child - argp->children, cluster, argp)
1376            /* Just merge it into the parent's cluster.  */
1377            : cluster);
1378         hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1379         child++;
1380       }
1381   return hol;
1382 }
1383 \f
1384 /* Calculate how many different levels with alternative args strings exist in
1385    ARGP.  */
1386 static size_t
1387 argp_args_levels (const struct argp *argp)
1388 {
1389   size_t levels = 0;
1390   const struct argp_child *child = argp->children;
1391
1392   if (argp->args_doc && strchr (argp->args_doc, '\n'))
1393     levels++;
1394
1395   if (child)
1396     while (child->argp)
1397       levels += argp_args_levels ((child++)->argp);
1398
1399   return levels;
1400 }
1401
1402 /* Print all the non-option args documented in ARGP to STREAM.  Any output is
1403    preceded by a space.  LEVELS is a pointer to a byte vector the length
1404    returned by argp_args_levels; it should be initialized to zero, and
1405    updated by this routine for the next call if ADVANCE is true.  True is
1406    returned as long as there are more patterns to output.  */
1407 static int
1408 argp_args_usage (const struct argp *argp, const struct argp_state *state,
1409                  char **levels, int advance, argp_fmtstream_t stream)
1410 {
1411   char *our_level = *levels;
1412   int multiple = 0;
1413   const struct argp_child *child = argp->children;
1414   const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
1415   const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
1416
1417   if (fdoc)
1418     {
1419       const char *cp = fdoc;
1420       nl = __strchrnul (cp, '\n');
1421       if (*nl != '\0')
1422         /* This is a 'multi-level' args doc; advance to the correct position
1423            as determined by our state in LEVELS, and update LEVELS.  */
1424         {
1425           int i;
1426           multiple = 1;
1427           for (i = 0; i < *our_level; i++)
1428             cp = nl + 1, nl = __strchrnul (cp, '\n');
1429           (*levels)++;
1430         }
1431
1432       /* Manually do line wrapping so that it (probably) won't get wrapped at
1433          any embedded spaces.  */
1434       space (stream, 1 + nl - cp);
1435
1436       __argp_fmtstream_write (stream, cp, nl - cp);
1437     }
1438   if (fdoc && fdoc != tdoc)
1439     free ((char *)fdoc);        /* Free user's modified doc string.  */
1440
1441   if (child)
1442     while (child->argp)
1443       advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
1444
1445   if (advance && multiple)
1446     {
1447       /* Need to increment our level.  */
1448       if (*nl)
1449         /* There's more we can do here.  */
1450         {
1451           (*our_level)++;
1452           advance = 0;          /* Our parent shouldn't advance also. */
1453         }
1454       else if (*our_level > 0)
1455         /* We had multiple levels, but used them up; reset to zero.  */
1456         *our_level = 0;
1457     }
1458
1459   return !advance;
1460 }
1461 \f
1462 /* Print the documentation for ARGP to STREAM; if POST is false, then
1463    everything preceeding a '\v' character in the documentation strings (or
1464    the whole string, for those with none) is printed, otherwise, everything
1465    following the '\v' character (nothing for strings without).  Each separate
1466    bit of documentation is separated a blank line, and if PRE_BLANK is true,
1467    then the first is as well.  If FIRST_ONLY is true, only the first
1468    occurrence is output.  Returns true if anything was output.  */
1469 static int
1470 argp_doc (const struct argp *argp, const struct argp_state *state,
1471           int post, int pre_blank, int first_only,
1472           argp_fmtstream_t stream)
1473 {
1474   const char *text;
1475   const char *inp_text;
1476   void *input = 0;
1477   int anything = 0;
1478   size_t inp_text_limit = 0;
1479   const char *doc = dgettext (argp->argp_domain, argp->doc);
1480   const struct argp_child *child = argp->children;
1481
1482   if (doc)
1483     {
1484       char *vt = strchr (doc, '\v');
1485       inp_text = post ? (vt ? vt + 1 : 0) : doc;
1486       inp_text_limit = (!post && vt) ? (vt - doc) : 0;
1487     }
1488   else
1489     inp_text = 0;
1490
1491   if (argp->help_filter)
1492     /* We have to filter the doc strings.  */
1493     {
1494       if (inp_text_limit)
1495         /* Copy INP_TEXT so that it's nul-terminated.  */
1496         inp_text = __strndup (inp_text, inp_text_limit);
1497       input = __argp_input (argp, state);
1498       text =
1499         (*argp->help_filter) (post
1500                               ? ARGP_KEY_HELP_POST_DOC
1501                               : ARGP_KEY_HELP_PRE_DOC,
1502                               inp_text, input);
1503     }
1504   else
1505     text = (const char *) inp_text;
1506
1507   if (text)
1508     {
1509       if (pre_blank)
1510         __argp_fmtstream_putc (stream, '\n');
1511
1512       if (text == inp_text && inp_text_limit)
1513         __argp_fmtstream_write (stream, inp_text, inp_text_limit);
1514       else
1515         __argp_fmtstream_puts (stream, text);
1516
1517       if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1518         __argp_fmtstream_putc (stream, '\n');
1519
1520       anything = 1;
1521     }
1522
1523   if (text && text != inp_text)
1524     free ((char *) text);       /* Free TEXT returned from the help filter.  */
1525   if (inp_text && inp_text_limit && argp->help_filter)
1526     free ((char *) inp_text);   /* We copied INP_TEXT, so free it now.  */
1527
1528   if (post && argp->help_filter)
1529     /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text.  */
1530     {
1531       text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
1532       if (text)
1533         {
1534           if (anything || pre_blank)
1535             __argp_fmtstream_putc (stream, '\n');
1536           __argp_fmtstream_puts (stream, text);
1537           free ((char *) text);
1538           if (__argp_fmtstream_point (stream)
1539               > __argp_fmtstream_lmargin (stream))
1540             __argp_fmtstream_putc (stream, '\n');
1541           anything = 1;
1542         }
1543     }
1544
1545   if (child)
1546     while (child->argp && !(first_only && anything))
1547       anything |=
1548         argp_doc ((child++)->argp, state,
1549                   post, anything || pre_blank, first_only,
1550                   stream);
1551
1552   return anything;
1553 }
1554 \f
1555 /* Output a usage message for ARGP to STREAM.  If called from
1556    argp_state_help, STATE is the relevent parsing state.  FLAGS are from the
1557    set ARGP_HELP_*.  NAME is what to use wherever a 'program name' is
1558    needed. */
1559 static void
1560 _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
1561        unsigned flags, char *name)
1562 {
1563   int anything = 0;             /* Whether we've output anything.  */
1564   struct hol *hol = 0;
1565   argp_fmtstream_t fs;
1566
1567   if (! stream)
1568     return;
1569
1570 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1571   __flockfile (stream);
1572 #endif
1573
1574   if (! uparams.valid)
1575     fill_in_uparams (state);
1576
1577   fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
1578   if (! fs)
1579     {
1580 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1581       __funlockfile (stream);
1582 #endif
1583       return;
1584     }
1585
1586   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1587     {
1588       hol = argp_hol (argp, 0);
1589
1590       /* If present, these options always come last.  */
1591       hol_set_group (hol, "help", -1);
1592       hol_set_group (hol, "version", -1);
1593
1594       hol_sort (hol);
1595     }
1596
1597   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1598     /* Print a short "Usage:" message.  */
1599     {
1600       int first_pattern = 1, more_patterns;
1601       size_t num_pattern_levels = argp_args_levels (argp);
1602       char *pattern_levels = alloca (num_pattern_levels);
1603
1604       memset (pattern_levels, 0, num_pattern_levels);
1605
1606       do
1607         {
1608           int old_lm;
1609           int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
1610           char *levels = pattern_levels;
1611
1612           if (first_pattern)
1613             __argp_fmtstream_printf (fs, "%s %s",
1614                                      dgettext (argp->argp_domain, "Usage:"),
1615                                      name);
1616           else
1617             __argp_fmtstream_printf (fs, "%s %s",
1618                                      dgettext (argp->argp_domain, "  or: "),
1619                                      name);
1620
1621           /* We set the lmargin as well as the wmargin, because hol_usage
1622              manually wraps options with newline to avoid annoying breaks.  */
1623           old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
1624
1625           if (flags & ARGP_HELP_SHORT_USAGE)
1626             /* Just show where the options go.  */
1627             {
1628               if (hol->num_entries > 0)
1629                 __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
1630                                                      " [OPTION...]"));
1631             }
1632           else
1633             /* Actually print the options.  */
1634             {
1635               hol_usage (hol, fs);
1636               flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */
1637             }
1638
1639           more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
1640
1641           __argp_fmtstream_set_wmargin (fs, old_wm);
1642           __argp_fmtstream_set_lmargin (fs, old_lm);
1643
1644           __argp_fmtstream_putc (fs, '\n');
1645           anything = 1;
1646
1647           first_pattern = 0;
1648         }
1649       while (more_patterns);
1650     }
1651
1652   if (flags & ARGP_HELP_PRE_DOC)
1653     anything |= argp_doc (argp, state, 0, 0, 1, fs);
1654
1655   if (flags & ARGP_HELP_SEE)
1656     {
1657       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
1658 Try '%s --help' or '%s --usage' for more information.\n"),
1659                                name, name);
1660       anything = 1;
1661     }
1662
1663   if (flags & ARGP_HELP_LONG)
1664     /* Print a long, detailed help message.  */
1665     {
1666       /* Print info about all the options.  */
1667       if (hol->num_entries > 0)
1668         {
1669           if (anything)
1670             __argp_fmtstream_putc (fs, '\n');
1671           hol_help (hol, state, fs);
1672           anything = 1;
1673         }
1674     }
1675
1676   if (flags & ARGP_HELP_POST_DOC)
1677     /* Print any documentation strings at the end.  */
1678     anything |= argp_doc (argp, state, 1, anything, 0, fs);
1679
1680   if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1681     {
1682       if (anything)
1683         __argp_fmtstream_putc (fs, '\n');
1684       __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
1685                                              "Report bugs to %s.\n"),
1686                                argp_program_bug_address);
1687       anything = 1;
1688     }
1689
1690 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1691   __funlockfile (stream);
1692 #endif
1693
1694   if (hol)
1695     hol_free (hol);
1696
1697   __argp_fmtstream_free (fs);
1698 }
1699 \f
1700 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
1701    ARGP_HELP_*.  NAME is what to use wherever a 'program name' is needed. */
1702 void __argp_help (const struct argp *argp, FILE *stream,
1703                   unsigned flags, char *name)
1704 {
1705   _help (argp, 0, stream, flags, name);
1706 }
1707 #ifdef weak_alias
1708 weak_alias (__argp_help, argp_help)
1709 #endif
1710
1711 #if ! (defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
1712 char *
1713 __argp_short_program_name (void)
1714 {
1715 # if HAVE_DECL_PROGRAM_INVOCATION_NAME
1716   char *name = strrchr (program_invocation_name, '/');
1717   return name ? name + 1 : program_invocation_name;
1718 # else
1719   /* FIXME: What now? Miles suggests that it is better to use NULL,
1720      but currently the value is passed on directly to fputs_unlocked,
1721      so that requires more changes. */
1722 # if __GNUC__
1723 #  warning No reasonable value to return
1724 # endif /* __GNUC__ */
1725   return "";
1726 # endif
1727 }
1728 #endif
1729
1730 /* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
1731    from the set ARGP_HELP_*.  */
1732 void
1733 __argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
1734 {
1735   if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1736     {
1737       if (state && (state->flags & ARGP_LONG_ONLY))
1738         flags |= ARGP_HELP_LONG_ONLY;
1739
1740       _help (state ? state->root_argp : 0, state, stream, flags,
1741              state ? state->name : __argp_short_program_name ());
1742
1743       if (!state || ! (state->flags & ARGP_NO_EXIT))
1744         {
1745           if (flags & ARGP_HELP_EXIT_ERR)
1746             exit (argp_err_exit_status);
1747           if (flags & ARGP_HELP_EXIT_OK)
1748             exit (0);
1749         }
1750   }
1751 }
1752 #ifdef weak_alias
1753 weak_alias (__argp_state_help, argp_state_help)
1754 #endif
1755 \f
1756 /* If appropriate, print the printf string FMT and following args, preceded
1757    by the program name and ':', to stderr, and followed by a "Try ... --help"
1758    message, then exit (1).  */
1759 void
1760 __argp_error (const struct argp_state *state, const char *fmt, ...)
1761 {
1762   if (!state || !(state->flags & ARGP_NO_ERRS))
1763     {
1764       FILE *stream = state ? state->err_stream : stderr;
1765
1766       if (stream)
1767         {
1768           va_list ap;
1769
1770 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1771           __flockfile (stream);
1772 #endif
1773
1774           va_start (ap, fmt);
1775
1776 #ifdef _LIBC
1777           char *buf;
1778
1779           if (_IO_vasprintf (&buf, fmt, ap) < 0)
1780             buf = NULL;
1781
1782           __fxprintf (stream, "%s: %s\n",
1783                       state ? state->name : __argp_short_program_name (), buf);
1784
1785           free (buf);
1786 #else
1787           fputs_unlocked (state ? state->name : __argp_short_program_name (),
1788                           stream);
1789           putc_unlocked (':', stream);
1790           putc_unlocked (' ', stream);
1791
1792           vfprintf (stream, fmt, ap);
1793
1794           putc_unlocked ('\n', stream);
1795 #endif
1796
1797           __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1798
1799           va_end (ap);
1800
1801 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1802           __funlockfile (stream);
1803 #endif
1804         }
1805     }
1806 }
1807 #ifdef weak_alias
1808 weak_alias (__argp_error, argp_error)
1809 #endif
1810 \f
1811 /* Similar to the standard gnu error-reporting function error(), but will
1812    respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1813    to STATE->err_stream.  This is useful for argument parsing code that is
1814    shared between program startup (when exiting is desired) and runtime
1815    option parsing (when typically an error code is returned instead).  The
1816    difference between this function and argp_error is that the latter is for
1817    *parsing errors*, and the former is for other problems that occur during
1818    parsing but don't reflect a (syntactic) problem with the input.  */
1819 void
1820 __argp_failure (const struct argp_state *state, int status, int errnum,
1821                 const char *fmt, ...)
1822 {
1823   if (!state || !(state->flags & ARGP_NO_ERRS))
1824     {
1825       FILE *stream = state ? state->err_stream : stderr;
1826
1827       if (stream)
1828         {
1829 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1830           __flockfile (stream);
1831 #endif
1832
1833 #ifdef _LIBC
1834           __fxprintf (stream, "%s",
1835                       state ? state->name : __argp_short_program_name ());
1836 #else
1837           fputs_unlocked (state ? state->name : __argp_short_program_name (),
1838                           stream);
1839 #endif
1840
1841           if (fmt)
1842             {
1843               va_list ap;
1844
1845               va_start (ap, fmt);
1846 #ifdef _LIBC
1847               char *buf;
1848
1849               if (_IO_vasprintf (&buf, fmt, ap) < 0)
1850                 buf = NULL;
1851
1852               __fxprintf (stream, ": %s", buf);
1853
1854               free (buf);
1855 #else
1856               putc_unlocked (':', stream);
1857               putc_unlocked (' ', stream);
1858
1859               vfprintf (stream, fmt, ap);
1860 #endif
1861
1862               va_end (ap);
1863             }
1864
1865           if (errnum)
1866             {
1867               char buf[200];
1868
1869 #ifdef _LIBC
1870               __fxprintf (stream, ": %s",
1871                           __strerror_r (errnum, buf, sizeof (buf)));
1872 #else
1873               char const *s = NULL;
1874               putc_unlocked (':', stream);
1875               putc_unlocked (' ', stream);
1876 # if HAVE_DECL_STRERROR_R
1877 #  if STRERROR_R_CHAR_P
1878               s = __strerror_r (errnum, buf, sizeof buf);
1879 #  else
1880               if (__strerror_r (errnum, buf, sizeof buf) == 0)
1881                 s = buf;
1882 #  endif
1883 # endif
1884               if (! s && ! (s = strerror (errnum)))
1885                 s = dgettext (state->root_argp->argp_domain,
1886                               "Unknown system error");
1887               fputs_unlocked (s, stream);
1888 #endif
1889             }
1890
1891 #if _LIBC
1892           if (_IO_fwide (stream, 0) > 0)
1893             putwc_unlocked (L'\n', stream);
1894           else
1895 #endif
1896             putc_unlocked ('\n', stream);
1897
1898 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1899           __funlockfile (stream);
1900 #endif
1901
1902           if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
1903             exit (status);
1904         }
1905     }
1906 }
1907 #ifdef weak_alias
1908 weak_alias (__argp_failure, argp_failure)
1909 #endif