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