5d7df5454a733352c6f94de96a35e5a5d2d8f1a7
[kopensolaris-gnu/glibc.git] / argp / argp-help.c
1 /* Hierarchial argument parsing help output
2    Copyright (C) 1995, 1996, 1997 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    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    The GNU C Library 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 GNU
14    Library General Public License for more details.
15
16    You should have received a copy of the GNU Library General Public
17    License along with the GNU C Library; see the file COPYING.LIB.  If not,
18    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19    Boston, MA 02111-1307, USA.  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <assert.h>
28 #include <stdarg.h>
29 #include <malloc.h>
30 #include <ctype.h>
31
32 #ifndef _
33 /* This is for other GNU distributions with internationalized messages.
34    When compiling libc, the _ macro is predefined.  */
35 #ifdef HAVE_LIBINTL_H
36 # include <libintl.h>
37 # define _(msgid)       gettext (msgid)
38 #else
39 # define _(msgid)       (msgid)
40 # define gettext(msgid) (msgid)
41 #endif
42 #endif
43
44 #include "argp.h"
45 #include "argp-fmtstream.h"
46 #include "argp-namefrob.h"
47
48 #define SHORT_OPT_COL 2         /* column in which short options start */
49 #define LONG_OPT_COL  6         /* column in which long options start */
50 #define DOC_OPT_COL   2         /* column in which doc options start */
51 #define OPT_DOC_COL  29         /* column in which option text starts */
52 #define HEADER_COL    1         /* column in which group headers are printed */
53 #define USAGE_INDENT 12         /* indentation of wrapped usage lines */
54 #define RMARGIN      79         /* right margin used for wrapping */
55
56 /* Returns true if OPT hasn't been marked invisible.  Visibility only affects
57    whether OPT is displayed or used in sorting, not option shadowing.  */
58 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
59
60 /* Returns true if OPT is an alias for an earlier option.  */
61 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
62
63 /* Returns true if OPT is an documentation-only entry.  */
64 #define odoc(opt) ((opt)->flags & OPTION_DOC)
65
66 /* Returns true if OPT is the end-of-list marker for a list of options.  */
67 #define oend(opt) __option_is_end (opt)
68
69 /* Returns true if OPT has a short option.  */
70 #define oshort(opt) __option_is_short (opt)
71 \f
72 /*
73    The help format for a particular option is like:
74
75      -xARG, -yARG, --long1=ARG, --long2=ARG        Documentation...
76
77    Where ARG will be omitted if there's no argument, for this option, or
78    will be surrounded by "[" and "]" appropiately if the argument is
79    optional.  The documentation string is word-wrapped appropiately, and if
80    the list of options is long enough, it will be started on a separate line.
81    If there are no short options for a given option, the first long option is
82    indented slighly in a way that's supposed to make most long options appear
83    to be in a separate column.
84
85    For example, the following output (from ps):
86
87      -p PID, --pid=PID          List the process PID
88          --pgrp=PGRP            List processes in the process group PGRP
89      -P, -x, --no-parent        Include processes without parents
90      -Q, --all-fields           Don't elide unusable fields (normally if there's
91                                 some reason ps can't print a field for any
92                                 process, it's removed from the output entirely)
93      -r, --reverse, --gratuitously-long-reverse-option
94                                 Reverse the order of any sort
95          --session[=SID]        Add the processes from the session SID (which
96                                 defaults to the sid of the current process)
97
98     Here are some more options:
99      -f ZOT, --foonly=ZOT       Glork a foonly
100      -z, --zaza                 Snit a zar
101
102      -?, --help                 Give this help list
103          --usage                Give a short usage message
104      -V, --version              Print program version
105
106    The struct argp_option array for the above could look like:
107
108    {
109      {"pid",       'p',      "PID",  0, "List the process PID"},
110      {"pgrp",      OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
111      {"no-parent", 'P',       0,     0, "Include processes without parents"},
112      {0,           'x',       0,     OPTION_ALIAS},
113      {"all-fields",'Q',       0,     0, "Don't elide unusable fields (normally"
114                                         " if there's some reason ps can't"
115                                         " print a field for any process, it's"
116                                         " removed from the output entirely)" },
117      {"reverse",   'r',       0,     0, "Reverse the order of any sort"},
118      {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
119      {"session",   OPT_SESS,  "SID", OPTION_ARG_OPTIONAL,
120                                         "Add the processes from the session"
121                                         " SID (which defaults to the sid of"
122                                         " the current process)" },
123
124      {0,0,0,0, "Here are some more options:"},
125      {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
126      {"zaza", 'z', 0, 0, "Snit a zar"},
127
128      {0}
129    }
130
131    Note that the last three options are automatically supplied by argp_parse,
132    unless you tell it not to with ARGP_NO_HELP.
133
134 */
135 \f
136 /* Returns true if CH occurs between BEG and END.  */
137 static int
138 find_char (char ch, char *beg, char *end)
139 {
140   while (beg < end)
141     if (*beg == ch)
142       return 1;
143     else
144       beg++;
145   return 0;
146 }
147 \f
148 struct hol_cluster;             /* fwd decl */
149
150 struct hol_entry
151 {
152   /* First option.  */
153   const struct argp_option *opt;
154   /* Number of options (including aliases).  */
155   unsigned num;
156
157   /* A pointers into the HOL's short_options field, to the first short option
158      letter for this entry.  The order of the characters following this point
159      corresponds to the order of options pointed to by OPT, and there are at
160      most NUM.  A short option recorded in a option following OPT is only
161      valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
162      probably been shadowed by some other entry).  */
163   char *short_options;
164
165   /* Entries are sorted by their group first, in the order:
166        1, 2, ..., n, 0, -m, ..., -2, -1
167      and then alphabetically within each group.  The default is 0.  */
168   int group;
169
170   /* The cluster of options this entry belongs to, or 0 if none.  */
171   struct hol_cluster *cluster;
172 };
173
174 /* A cluster of entries to reflect the argp tree structure.  */
175 struct hol_cluster
176 {
177   /* A descriptive header printed before options in this cluster.  */
178   const char *header;
179
180   /* Used to order clusters within the same group with the same parent,
181      according to the order in which they occured in the parent argp's child
182      list.  */
183   int index;
184
185   /* How to sort this cluster with respect to options and other clusters at the
186      same depth (clusters always follow options in the same group).  */
187   int group;
188
189   /* The cluster to which this cluster belongs, or 0 if it's at the base
190      level.  */
191   struct hol_cluster *parent;
192
193   /* The distance this cluster is from the root.  */
194   int depth;
195
196   /* Clusters in a given hol are kept in a linked list, to make freeing them
197      possible.  */
198   struct hol_cluster *next;
199 };
200
201 /* A list of options for help.  */
202 struct hol
203 {
204   /* An array of hol_entry's.  */
205   struct hol_entry *entries;
206   /* The number of entries in this hol.  If this field is zero, the others
207      are undefined.  */
208   unsigned num_entries;
209
210   /* A string containing all short options in this HOL.  Each entry contains
211      pointers into this string, so the order can't be messed with blindly.  */
212   char *short_options;
213
214   /* Clusters of entries in this hol.  */
215   struct hol_cluster *clusters;
216 };
217 \f
218 /* Create a struct hol from an array of struct argp_option.  CLUSTER is the
219    hol_cluster in which these entries occur, or 0, if at the root.  */
220 static struct hol *
221 make_hol (const struct argp_option *opt, struct hol_cluster *cluster)
222 {
223   char *so;
224   const struct argp_option *o;
225   struct hol_entry *entry;
226   unsigned num_short_options = 0;
227   struct hol *hol = malloc (sizeof (struct hol));
228
229   assert (hol);
230
231   hol->num_entries = 0;
232   hol->clusters = 0;
233
234   if (opt)
235     {
236       int cur_group = 0;
237
238       /* The first option must not be an alias.  */
239       assert (! oalias (opt));
240
241       /* Calculate the space needed.  */
242       for (o = opt; ! oend (o); o++)
243         {
244           if (! oalias (o))
245             hol->num_entries++;
246           if (oshort (o))
247             num_short_options++;        /* This is an upper bound.  */
248         }
249
250       hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
251       hol->short_options = malloc (num_short_options + 1);
252
253       assert (hol->entries && hol->short_options);
254
255       /* Fill in the entries.  */
256       so = hol->short_options;
257       for (o = opt, entry = hol->entries; ! oend (o); entry++)
258         {
259           entry->opt = o;
260           entry->num = 0;
261           entry->short_options = so;
262           entry->group = cur_group =
263             o->group
264             ? o->group
265             : ((!o->name && !o->key)
266                ? cur_group + 1
267                : cur_group);
268           entry->cluster = cluster;
269
270           do
271             {
272               entry->num++;
273               if (oshort (o) && ! find_char (o->key, hol->short_options, so))
274                 /* O has a valid short option which hasn't already been used.*/
275                 *so++ = o->key;
276               o++;
277             }
278           while (! oend (o) && oalias (o));
279         }
280       *so = '\0';               /* null terminated so we can find the length */
281     }
282
283   return hol;
284 }
285 \f
286 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
287    associated argp child list entry), INDEX, and PARENT, and return a pointer
288    to it.  */
289 static struct hol_cluster *
290 hol_add_cluster (struct hol *hol, int group, const char *header, int index,
291                  struct hol_cluster *parent)
292 {
293   struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
294   if (cl)
295     {
296       cl->group = group;
297       cl->header = header;
298
299       cl->index = index;
300       cl->parent = parent;
301
302       cl->next = hol->clusters;
303       hol->clusters = cl;
304     }
305   return cl;
306 }
307 \f
308 /* Free HOL and any resources it uses.  */
309 static void
310 hol_free (struct hol *hol)
311 {
312   struct hol_cluster *cl = hol->clusters;
313
314   while (cl)
315     {
316       struct hol_cluster *next = cl->next;
317       free (cl);
318       cl = next;
319     }
320
321   if (hol->num_entries > 0)
322     {
323       free (hol->entries);
324       free (hol->short_options);
325     }
326
327   free (hol);
328 }
329 \f
330 static inline int
331 hol_entry_short_iterate (const struct hol_entry *entry,
332                          int (*func)(const struct argp_option *opt,
333                                      const struct argp_option *real,
334                                      void *cookie),
335                          void *cookie)
336 {
337   unsigned nopts;
338   int val = 0;
339   const struct argp_option *opt, *real = entry->opt;
340   char *so = entry->short_options;
341
342   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
343     if (oshort (opt) && *so == opt->key)
344       {
345         if (!oalias (opt))
346           real = opt;
347         if (ovisible (opt))
348           val = (*func)(opt, real, cookie);
349         so++;
350       }
351
352   return val;
353 }
354
355 static inline int
356 hol_entry_long_iterate (const struct hol_entry *entry,
357                         int (*func)(const struct argp_option *opt,
358                                     const struct argp_option *real,
359                                     void *cookie),
360                         void *cookie)
361 {
362   unsigned nopts;
363   int val = 0;
364   const struct argp_option *opt, *real = entry->opt;
365
366   for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
367     if (opt->name)
368       {
369         if (!oalias (opt))
370           real = opt;
371         if (ovisible (opt))
372           val = (*func)(opt, real, cookie);
373       }
374
375   return val;
376 }
377 \f
378 /* Iterator that returns true for the first short option.  */
379 static inline int
380 until_short (const struct argp_option *opt, const struct argp_option *real,
381              void *cookie)
382 {
383   return oshort (opt) ? opt->key : 0;
384 }
385
386 /* Returns the first valid short option in ENTRY, or 0 if there is none.  */
387 static char
388 hol_entry_first_short (const struct hol_entry *entry)
389 {
390   return hol_entry_short_iterate (entry, until_short, 0);
391 }
392
393 /* Returns the first valid long option in ENTRY, or 0 if there is none.  */
394 static const char *
395 hol_entry_first_long (const struct hol_entry *entry)
396 {
397   const struct argp_option *opt;
398   unsigned num;
399   for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
400     if (opt->name && ovisible (opt))
401       return opt->name;
402   return 0;
403 }
404
405 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
406    none.  */
407 static struct hol_entry *
408 hol_find_entry (struct hol *hol, const char *name)
409 {
410   struct hol_entry *entry = hol->entries;
411   unsigned num_entries = hol->num_entries;
412
413   while (num_entries-- > 0)
414     {
415       const struct argp_option *opt = entry->opt;
416       unsigned num_opts = entry->num;
417
418       while (num_opts-- > 0)
419         if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
420           return entry;
421         else
422           opt++;
423
424       entry++;
425     }
426
427   return 0;
428 }
429 \f
430 /* If an entry with the long option NAME occurs in HOL, set it's special
431    sort position to GROUP.  */
432 static void
433 hol_set_group (struct hol *hol, const char *name, int group)
434 {
435   struct hol_entry *entry = hol_find_entry (hol, name);
436   if (entry)
437     entry->group = group;
438 }
439 \f
440 /* Order by group:  0, 1, 2, ..., n, -m, ..., -2, -1.
441    EQ is what to return if GROUP1 and GROUP2 are the same.  */
442 static int
443 group_cmp (int group1, int group2, int eq)
444 {
445   if (group1 == group2)
446     return eq;
447   else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
448     return group1 - group2;
449   else
450     return group2 - group1;
451 }
452
453 /* Compare clusters CL1 & CL2 by the order that they should appear in
454    output.  */
455 static int
456 hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
457 {
458   /* If one cluster is deeper than the other, use its ancestor at the same
459      level, so that finding the common ancestor is straightforward.  */
460   while (cl1->depth < cl2->depth)
461     cl1 = cl1->parent;
462   while (cl2->depth < cl1->depth)
463     cl2 = cl2->parent;
464
465   /* Now reduce both clusters to their ancestors at the point where both have
466      a common parent; these can be directly compared.  */
467   while (cl1->parent != cl2->parent)
468     cl1 = cl1->parent, cl2 = cl2->parent;
469
470   return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
471 }
472
473 /* Return the ancestor of CL that's just below the root (i.e., has a parent
474    of 0).  */
475 static struct hol_cluster *
476 hol_cluster_base (struct hol_cluster *cl)
477 {
478   while (cl->parent)
479     cl = cl->parent;
480   return cl;
481 }
482
483 /* Return true if CL1 is a child of CL2.  */
484 static int
485 hol_cluster_is_child (const struct hol_cluster *cl1,
486                       const struct hol_cluster *cl2)
487 {
488   while (cl1 && cl1 != cl2)
489     cl1 = cl1->parent;
490   return cl1 == cl2;
491 }
492 \f
493 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
494    that should be used for comparisons, and returns true iff it should be
495    treated as a non-option.  */
496 static int
497 canon_doc_option (const char **name)
498 {
499   int non_opt;
500   /* Skip initial whitespace.  */
501   while (isspace (*name))
502     (*name)++;
503   /* Decide whether this looks like an option (leading `-') or not.  */
504   non_opt = (**name != '-');
505   /* Skip until part of name used for sorting.  */
506   while (**name && !isalnum (*name))
507     (*name)++;
508   return non_opt;
509 }
510
511 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
512    listing.  */
513 static int
514 hol_entry_cmp (const struct hol_entry *entry1, const struct hol_entry *entry2)
515 {
516   /* The group numbers by which the entries should be ordered; if either is
517      in a cluster, then this is just the group within the cluster.  */
518   int group1 = entry1->group, group2 = entry2->group;
519
520   if (entry1->cluster != entry2->cluster)
521     /* The entries are not within the same cluster, so we can't compare them
522        directly, we have to use the appropiate clustering level too.  */
523     if (! entry1->cluster)
524       /* ENTRY1 is at the `base level', not in a cluster, so we have to
525          compare it's group number with that of the base cluster in which
526          ENTRY2 resides.  Note that if they're in the same group, the
527          clustered option always comes laster.  */
528       return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
529     else if (! entry2->cluster)
530       /* Likewise, but ENTRY2's not in a cluster.  */
531       return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
532     else
533       /* Both entries are in clusters, we can just compare the clusters.  */
534       return hol_cluster_cmp (entry1->cluster, entry2->cluster);
535   else if (group1 == group2)
536     /* The entries are both in the same cluster and group, so compare them
537        alphabetically.  */
538     {
539       int short1 = hol_entry_first_short (entry1);
540       int short2 = hol_entry_first_short (entry2);
541       int doc1 = odoc (entry1->opt);
542       int doc2 = odoc (entry2->opt);
543       const char *long1 = hol_entry_first_long (entry1);
544       const char *long2 = hol_entry_first_long (entry2);
545
546       if (doc1)
547         doc1 = canon_doc_option (&long1);
548       if (doc2)
549         doc2 = canon_doc_option (&long2);
550
551       if (doc1 != doc2)
552         /* `documentation' options always follow normal options (or
553            documentation options that *look* like normal options).  */
554         return doc1 - doc2;
555       else if (!short1 && !short2 && long1 && long2)
556         /* Only long options.  */
557         return __strcasecmp (long1, long2);
558       else
559         /* Compare short/short, long/short, short/long, using the first
560            character of long options.  Entries without *any* valid
561            options (such as options with OPTION_HIDDEN set) will be put
562            first, but as they're not displayed, it doesn't matter where
563            they are.  */
564         {
565           char first1 = short1 ? short1 : long1 ? *long1 : 0;
566           char first2 = short2 ? short2 : long2 ? *long2 : 0;
567           int lower_cmp = tolower (first1) - tolower (first2);
568           /* Compare ignoring case, except when the options are both the
569              same letter, in which case lower-case always comes first.  */
570           return lower_cmp ? lower_cmp : first2 - first1;
571         }
572     }
573   else
574     /* Within the same cluster, but not the same group, so just compare
575        groups.  */
576     return group_cmp (group1, group2, 0);
577 }
578
579 /* Version of hol_entry_cmp with correct signature for qsort.  */
580 static int
581 hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
582 {
583   return hol_entry_cmp (entry1_v, entry2_v);
584 }
585
586 /* Sort HOL by group and alphabetically by option name (with short options
587    taking precedence over long).  Since the sorting is for display purposes
588    only, the shadowing of options isn't effected.  */
589 static void
590 hol_sort (struct hol *hol)
591 {
592   if (hol->num_entries > 0)
593     qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
594            hol_entry_qcmp);
595 }
596 \f
597 /* Append MORE to HOL, destroying MORE in the process.  Options in HOL shadow
598    any in MORE with the same name.  */
599 static void
600 hol_append (struct hol *hol, struct hol *more)
601 {
602   struct hol_cluster **cl_end = &hol->clusters;
603
604   /* Steal MORE's cluster list, and add it to the end of HOL's.  */
605   while (*cl_end)
606     cl_end = &(*cl_end)->next;
607   *cl_end = more->clusters;
608   more->clusters = 0;
609
610   /* Merge entries.  */
611   if (more->num_entries > 0)
612     if (hol->num_entries == 0)
613       {
614         hol->num_entries = more->num_entries;
615         hol->entries = more->entries;
616         hol->short_options = more->short_options;
617         more->num_entries = 0;  /* Mark MORE's fields as invalid.  */
618       }
619     else
620       /* append the entries in MORE to those in HOL, taking care to only add
621          non-shadowed SHORT_OPTIONS values.  */
622       {
623         unsigned left;
624         char *so, *more_so;
625         struct hol_entry *e;
626         unsigned num_entries = hol->num_entries + more->num_entries;
627         struct hol_entry *entries =
628           malloc (num_entries * sizeof (struct hol_entry));
629         unsigned hol_so_len = strlen (hol->short_options);
630         char *short_options =
631           malloc (hol_so_len + strlen (more->short_options) + 1);
632
633         memcpy (entries, hol->entries,
634                 hol->num_entries * sizeof (struct hol_entry));
635         memcpy (entries + hol->num_entries, more->entries,
636                 more->num_entries * sizeof (struct hol_entry));
637
638         memcpy (short_options, hol->short_options, hol_so_len);
639
640         /* Fix up the short options pointers from HOL.  */
641         for (e = entries, left = hol->num_entries; left > 0; e++, left--)
642           e->short_options += (short_options - hol->short_options);
643
644         /* Now add the short options from MORE, fixing up its entries too.  */
645         so = short_options + hol_so_len;
646         more_so = more->short_options;
647         for (left = more->num_entries; left > 0; e++, left--)
648           {
649             int opts_left;
650             const struct argp_option *opt;
651
652             e->short_options = so;
653
654             for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
655               {
656                 int ch = *more_so;
657                 if (oshort (opt) && ch == opt->key)
658                   /* The next short option in MORE_SO, CH, is from OPT.  */
659                   {
660                     if (! find_char (ch,
661                                      short_options, short_options + hol_so_len))
662                       /* The short option CH isn't shadowed by HOL's options,
663                          so add it to the sum.  */
664                       *so++ = ch;
665                     more_so++;
666                   }
667               }
668           }
669
670         *so = '\0';
671
672         free (hol->entries);
673         free (hol->short_options);
674
675         hol->entries = entries;
676         hol->num_entries = num_entries;
677         hol->short_options = short_options;
678       }
679
680   hol_free (more);
681 }
682 \f
683 /* Inserts enough spaces to make sure STREAM is at column COL.  */
684 static void
685 indent_to (argp_fmtstream_t stream, unsigned col)
686 {
687   int needed = col - __argp_fmtstream_point (stream);
688   while (needed-- > 0)
689     __argp_fmtstream_putc (stream, ' ');
690 }
691
692 /* If the option REAL has an argument, we print it in using the printf
693    format REQ_FMT or OPT_FMT depending on whether it's a required or
694    optional argument.  */
695 static void
696 arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
697      argp_fmtstream_t stream)
698 {
699   if (real->arg)
700     if (real->flags & OPTION_ARG_OPTIONAL)
701       __argp_fmtstream_printf (stream, opt_fmt, _(real->arg));
702     else
703       __argp_fmtstream_printf (stream, req_fmt, _(real->arg));
704 }
705 \f
706 /* Helper functions for hol_entry_help.  */
707
708 /* Some state used while printing a help entry (used to communicate with
709    helper functions).  See the doc for hol_entry_help for more info, as most
710    of the fields are copied from its arguments.  */
711 struct pentry_state
712 {
713   const struct hol_entry *entry;
714   argp_fmtstream_t stream;
715   struct hol_entry **prev_entry;
716   int *sep_groups;
717
718   int first;                    /* True if nothing's been printed so far.  */
719 };
720
721 /* Prints STR as a header line, with the margin lines set appropiately, and
722    notes the fact that groups should be separated with a blank line.  Note
723    that the previous wrap margin isn't restored, but the left margin is reset
724    to 0.  */
725 static void
726 print_header (const char *str, struct pentry_state *st)
727 {
728   if (*str)
729     {
730       if (st->prev_entry && *st->prev_entry)
731         __argp_fmtstream_putc (st->stream, '\n'); /* Precede with a blank line.  */
732       indent_to (st->stream, HEADER_COL);
733       __argp_fmtstream_set_lmargin (st->stream, HEADER_COL);
734       __argp_fmtstream_set_wmargin (st->stream, HEADER_COL);
735       __argp_fmtstream_puts (st->stream, str);
736       __argp_fmtstream_set_lmargin (st->stream, 0);
737     }
738
739   if (st->sep_groups)
740     *st->sep_groups = 1;        /* Separate subsequent groups. */
741 }
742
743 /* Inserts a comma if this isn't the first item on the line, and then makes
744    sure we're at least to column COL.  Also clears FIRST.  */
745 static void
746 comma (unsigned col, struct pentry_state *st)
747 {
748   if (st->first)
749     {
750       const struct hol_entry *pe = st->prev_entry ? *st->prev_entry : 0;
751       const struct hol_cluster *cl = st->entry->cluster;
752
753       if (st->sep_groups && *st->sep_groups
754           && pe && st->entry->group != pe->group)
755         __argp_fmtstream_putc (st->stream, '\n');
756
757       if (pe && cl && pe->cluster != cl && cl->header && *cl->header
758           && !hol_cluster_is_child (pe->cluster, cl))
759         /* If we're changing clusters, then this must be the start of the
760            ENTRY's cluster unless that is an ancestor of the previous one
761            (in which case we had just popped into a sub-cluster for a bit).
762            If so, then print the cluster's header line.  */
763         {
764           int old_wm = __argp_fmtstream_wmargin (st->stream);
765           print_header (cl->header, st);
766           __argp_fmtstream_putc (st->stream, '\n');
767           __argp_fmtstream_set_wmargin (st->stream, old_wm);
768         }
769
770       st->first = 0;
771     }
772   else
773     __argp_fmtstream_puts (st->stream, ", ");
774
775   indent_to (st->stream, col);
776 }
777 \f
778 /* Print help for ENTRY to STREAM.  *PREV_ENTRY should contain the last entry
779    printed before this, or null if it's the first, and if ENTRY is in a
780    different group, and *SEP_GROUPS is true, then a blank line will be
781    printed before any output.  *SEP_GROUPS is also set to true if a
782    user-specified group header is printed.  */
783 static void
784 hol_entry_help (struct hol_entry *entry, argp_fmtstream_t stream,
785                 struct hol_entry **prev_entry, int *sep_groups)
786 {
787   unsigned num;
788   const struct argp_option *real = entry->opt, *opt;
789   char *so = entry->short_options;
790   int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
791   int old_wm = __argp_fmtstream_wmargin (stream);
792   struct pentry_state pest = { entry, stream, prev_entry, sep_groups, 1 };
793
794   /* First emit short options.  */
795   __argp_fmtstream_set_wmargin (stream, SHORT_OPT_COL); /* For truly bizarre cases. */
796   for (opt = real, num = entry->num; num > 0; opt++, num--)
797     if (oshort (opt) && opt->key == *so)
798       /* OPT has a valid (non shadowed) short option.  */
799       {
800         if (ovisible (opt))
801           {
802             comma (SHORT_OPT_COL, &pest);
803             __argp_fmtstream_putc (stream, '-');
804             __argp_fmtstream_putc (stream, *so);
805             arg (real, " %s", "[%s]", stream);
806           }
807         so++;
808       }
809
810   /* Now, long options.  */
811   if (odoc (real))
812     /* Really a `documentation' option.  */
813     {
814       __argp_fmtstream_set_wmargin (stream, DOC_OPT_COL);
815       for (opt = real, num = entry->num; num > 0; opt++, num--)
816         if (opt->name && ovisible (opt))
817           {
818             comma (DOC_OPT_COL, &pest);
819             /* Calling gettext here isn't quite right, since sorting will
820                have been done on the original; but documentation options
821                should be pretty rare anyway...  */
822             __argp_fmtstream_puts (stream, _(opt->name));
823           }
824     }
825   else
826     /* A realy long option.  */
827     {
828       __argp_fmtstream_set_wmargin (stream, LONG_OPT_COL);
829       for (opt = real, num = entry->num; num > 0; opt++, num--)
830         if (opt->name && ovisible (opt))
831           {
832             comma (LONG_OPT_COL, &pest);
833             __argp_fmtstream_printf (stream, "--%s", opt->name);
834             arg (real, "=%s", "[=%s]", stream);
835           }
836     }
837
838   __argp_fmtstream_set_lmargin (stream, 0);
839   if (pest.first)
840     /* Didn't print any switches, what's up?  */
841     if (!oshort (real) && !real->name && real->doc)
842       /* This is a group header, print it nicely.  */
843       print_header (real->doc, &pest);
844     else
845       /* Just a totally shadowed option or null header; print nothing.  */
846       goto cleanup;             /* Just return, after cleaning up.  */
847   else if (real->doc)
848     /* Now the option documentation.  */
849     {
850       unsigned col = __argp_fmtstream_point (stream);
851       const char *doc = real->doc;
852
853       __argp_fmtstream_set_lmargin (stream, OPT_DOC_COL);
854       __argp_fmtstream_set_wmargin (stream, OPT_DOC_COL);
855
856       if (col > OPT_DOC_COL + 3)
857         __argp_fmtstream_putc (stream, '\n');
858       else if (col >= OPT_DOC_COL)
859         __argp_fmtstream_puts (stream, "   ");
860       else
861         indent_to (stream, OPT_DOC_COL);
862
863       __argp_fmtstream_puts (stream, doc);
864
865       /* Reset the left margin.  */
866       __argp_fmtstream_set_lmargin (stream, 0);
867     }
868
869   __argp_fmtstream_putc (stream, '\n');
870
871   if (prev_entry)
872     *prev_entry = entry;
873
874 cleanup:
875   __argp_fmtstream_set_lmargin (stream, old_lm);
876   __argp_fmtstream_set_wmargin (stream, old_wm);
877 }
878 \f
879 /* Output a long help message about the options in HOL to STREAM.  */
880 static void
881 hol_help (struct hol *hol, argp_fmtstream_t stream)
882 {
883   unsigned num;
884   struct hol_entry *entry;
885   struct hol_entry *last_entry = 0;
886   int sep_groups = 0;           /* True if we should separate different
887                                    sections with blank lines.   */
888   for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
889     hol_entry_help (entry, stream, &last_entry, &sep_groups);
890 }
891 \f
892 /* Helper functions for hol_usage.  */
893
894 /* If OPT is a short option without an arg, append its key to the string
895    pointer pointer to by COOKIE, and advance the pointer.  */
896 static int
897 add_argless_short_opt (const struct argp_option *opt,
898                        const struct argp_option *real,
899                        void *cookie)
900 {
901   char **snao_end = cookie;
902   if (! (opt->arg || real->arg))
903     *(*snao_end)++ = opt->key;
904   return 0;
905 }
906
907 /* If OPT is a short option with an arg, output a usage entry for it to the
908    stream pointed at by COOKIE.  */
909 static int
910 usage_argful_short_opt (const struct argp_option *opt,
911                         const struct argp_option *real,
912                         void *cookie)
913 {
914   argp_fmtstream_t stream = cookie;
915   const char *arg = opt->arg;
916
917   if (! arg)
918     arg = real->arg;
919
920   if (arg)
921     {
922       arg = _(arg);
923
924       if ((opt->flags | real->flags) & OPTION_ARG_OPTIONAL)
925         __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
926       else
927         {
928           /* Manually do line wrapping so that it (probably) won't
929              get wrapped at the embedded space.  */
930           if (__argp_fmtstream_point (stream) + 6 + strlen (arg)
931               >= __argp_fmtstream_rmargin (stream))
932             __argp_fmtstream_putc (stream, '\n');
933           else
934             __argp_fmtstream_putc (stream, ' ');
935           __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
936         }
937     }
938
939   return 0;
940 }
941
942 /* Output a usage entry for the long option opt to the stream pointed at by
943    COOKIE.  */
944 static int
945 usage_long_opt (const struct argp_option *opt,
946                 const struct argp_option *real,
947                 void *cookie)
948 {
949   argp_fmtstream_t stream = cookie;
950   const char *arg = opt->arg;
951
952   if (! arg)
953     arg = real->arg;
954
955   if (arg)
956     {
957       arg = gettext (arg);
958       if ((opt->flags | real->flags) & OPTION_ARG_OPTIONAL)
959         __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
960       else
961         __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
962     }
963   else
964     __argp_fmtstream_printf (stream, " [--%s]", opt->name);
965
966   return 0;
967 }
968 \f
969 /* Print a short usage description for the arguments in HOL to STREAM.  */
970 static void
971 hol_usage (struct hol *hol, argp_fmtstream_t stream)
972 {
973   if (hol->num_entries > 0)
974     {
975       unsigned nentries;
976       struct hol_entry *entry;
977       char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
978       char *snao_end = short_no_arg_opts;
979
980       /* First we put a list of short options without arguments.  */
981       for (entry = hol->entries, nentries = hol->num_entries
982            ; nentries > 0
983            ; entry++, nentries--)
984         hol_entry_short_iterate (entry, add_argless_short_opt, &snao_end);
985       if (snao_end > short_no_arg_opts)
986         {
987           *snao_end++ = 0;
988           __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
989         }
990
991       /* Now a list of short options *with* arguments.  */
992       for (entry = hol->entries, nentries = hol->num_entries
993            ; nentries > 0
994            ; entry++, nentries--)
995         hol_entry_short_iterate (entry, usage_argful_short_opt, stream);
996
997       /* Finally, a list of long options (whew!).  */
998       for (entry = hol->entries, nentries = hol->num_entries
999            ; nentries > 0
1000            ; entry++, nentries--)
1001         hol_entry_long_iterate (entry, usage_long_opt, stream);
1002     }
1003 }
1004 \f
1005 /* Make a HOL containing all levels of options in ARGP.  CLUSTER is the
1006    cluster in which ARGP's entries should be clustered, or 0.  */
1007 static struct hol *
1008 argp_hol (const struct argp *argp, struct hol_cluster *cluster)
1009 {
1010   const struct argp_child *child = argp->children;
1011   struct hol *hol = make_hol (argp->options, cluster);
1012   if (child)
1013     while (child->argp)
1014       {
1015         struct hol_cluster *child_cluster =
1016           ((child->group || child->header)
1017            /* Put CHILD->argp within its own cluster.  */
1018            ? hol_add_cluster (hol, child->group, child->header,
1019                               child - argp->children, cluster)
1020            /* Just merge it into the parent's cluster.  */
1021            : cluster);
1022         hol_append (hol, argp_hol (child->argp, child_cluster)) ;
1023         child++;
1024       }
1025   return hol;
1026 }
1027 \f
1028 /* Calculate how many different levels with alternative args strings exist in
1029    ARGP.  */
1030 static size_t
1031 argp_args_levels (const struct argp *argp)
1032 {
1033   size_t levels = 0;
1034   const struct argp_child *child = argp->children;
1035
1036   if (argp->args_doc && strchr (argp->args_doc, '\n'))
1037     levels++;
1038
1039   if (child)
1040     while (child->argp)
1041       levels += argp_args_levels ((child++)->argp);
1042
1043   return levels;
1044 }
1045
1046 /* Print all the non-option args documented in ARGP to STREAM.  Any output is
1047    preceded by a space.  LEVELS is a pointer to a byte vector the length
1048    returned by argp_args_levels; it should be initialized to zero, and
1049    updated by this routine for the next call if ADVANCE is true.  True is
1050    returned as long as there are more patterns to output.  */
1051 static int
1052 argp_args_usage (const struct argp *argp, char **levels, int advance,
1053                  argp_fmtstream_t stream)
1054 {
1055   char *our_level = *levels;
1056   int multiple = 0;
1057   const struct argp_child *child = argp->children;
1058   const char *doc = _(argp->args_doc), *nl = 0;
1059
1060   if (doc)
1061     {
1062       nl = strchr (doc, '\n');
1063       if (nl)
1064         /* This is a `multi-level' args doc; advance to the correct position
1065            as determined by our state in LEVELS, and update LEVELS.  */
1066         {
1067           int i;
1068           multiple = 1;
1069           for (i = 0; i < *our_level; i++)
1070             doc = nl + 1, nl = strchr (doc, '\n');
1071           (*levels)++;
1072         }
1073       if (! nl)
1074         nl = doc + strlen (doc);
1075
1076       /* Manually do line wrapping so that it (probably) won't get wrapped at
1077          any embedded spaces.  */
1078       if (__argp_fmtstream_point (stream) + 1 + nl - doc
1079           >= __argp_fmtstream_rmargin (stream))
1080         __argp_fmtstream_putc (stream, '\n');
1081       else
1082         __argp_fmtstream_putc (stream, ' ');
1083
1084       __argp_fmtstream_write (stream, doc, nl - doc);
1085     }
1086
1087   if (child)
1088     while (child->argp)
1089       advance = !argp_args_usage ((child++)->argp, levels, advance, stream);
1090
1091   if (advance && multiple)
1092     /* Need to increment our level.  */
1093     if (*nl)
1094       /* There's more we can do here.  */
1095       {
1096         (*our_level)++;
1097         advance = 0;            /* Our parent shouldn't advance also. */
1098       }
1099     else if (*our_level > 0)
1100       /* We had multiple levels, but used them up; reset to zero.  */
1101       *our_level = 0;
1102
1103   return !advance;
1104 }
1105 \f
1106 /* Print the documentation for ARGP to STREAM; if POST is false, then
1107    everything preceeding a `\v' character in the documentation strings (or
1108    the whole string, for those with none) is printed, otherwise, everything
1109    following the `\v' character (nothing for strings without).  Each separate
1110    bit of documentation is separated a blank line, and if PRE_BLANK is true,
1111    then the first is as well.  If FIRST_ONLY is true, only the first
1112    occurance is output.  Returns true if anything was output.  */
1113 static int
1114 argp_doc (const struct argp *argp, int post, int pre_blank, int first_only,
1115           argp_fmtstream_t stream)
1116 {
1117   const struct argp_child *child = argp->children;
1118   const char *doc = argp->doc;
1119   int anything = 0;
1120
1121   if (doc)
1122     {
1123       char *vt = strchr (doc, '\v');
1124
1125       if (pre_blank && (vt || !post))
1126         __argp_fmtstream_putc (stream, '\n');
1127
1128       if (vt)
1129         if (post)
1130           __argp_fmtstream_puts (stream, vt + 1);
1131         else
1132           __argp_fmtstream_write (stream, doc, vt - doc);
1133       else
1134         if (! post)
1135           __argp_fmtstream_puts (stream, doc);
1136       if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
1137         __argp_fmtstream_putc (stream, '\n');
1138
1139       anything = 1;
1140     }
1141   if (child)
1142     while (child->argp && !(first_only && anything))
1143       anything |=
1144         argp_doc ((child++)->argp, post, anything || pre_blank, first_only,
1145                   stream);
1146
1147   return anything;
1148 }
1149 \f
1150 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
1151    ARGP_HELP_*.  NAME is what to use wherever a `program name' is needed. */
1152 void __argp_help (const struct argp *argp, FILE *stream,
1153                   unsigned flags, char *name)
1154 {
1155   int anything = 0;             /* Whether we've output anything.  */
1156   struct hol *hol = 0;
1157   argp_fmtstream_t fs;
1158
1159   if (! stream)
1160     return;
1161
1162   fs = __argp_make_fmtstream (stream, 0, RMARGIN, 0);
1163   if (! fs)
1164     return;
1165
1166   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
1167     {
1168       hol = argp_hol (argp, 0);
1169
1170       /* If present, these options always come last.  */
1171       hol_set_group (hol, "help", -1);
1172       hol_set_group (hol, "version", -1);
1173
1174       hol_sort (hol);
1175     }
1176
1177   if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
1178     /* Print a short `Usage:' message.  */
1179     {
1180       int first_pattern = 1, more_patterns;
1181       size_t num_pattern_levels = argp_args_levels (argp);
1182       char *pattern_levels = alloca (num_pattern_levels);
1183
1184       memset (pattern_levels, 0, num_pattern_levels);
1185
1186       do
1187         {
1188           int old_lm;
1189           int old_wm = __argp_fmtstream_set_wmargin (fs, USAGE_INDENT);
1190           char *levels = pattern_levels;
1191
1192           __argp_fmtstream_printf (fs, "%s %s",
1193                                    first_pattern ? "Usage:" : "  or: ", name);
1194
1195           /* We set the lmargin as well as the wmargin, because hol_usage
1196              manually wraps options with newline to avoid annoying breaks.  */
1197           old_lm = __argp_fmtstream_set_lmargin (fs, USAGE_INDENT);
1198
1199           if (flags & ARGP_HELP_SHORT_USAGE)
1200             /* Just show where the options go.  */
1201             {
1202               if (hol->num_entries > 0)
1203                 __argp_fmtstream_puts (fs, " [OPTION...]");
1204             }
1205           else
1206             /* Actually print the options.  */
1207             {
1208               hol_usage (hol, fs);
1209               flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once.  */
1210             }
1211
1212           more_patterns = argp_args_usage (argp, &levels, 1, fs);
1213
1214           __argp_fmtstream_set_wmargin (fs, old_wm);
1215           __argp_fmtstream_set_lmargin (fs, old_lm);
1216
1217           __argp_fmtstream_putc (fs, '\n');
1218           anything = 1;
1219
1220           first_pattern = 0;
1221         }
1222       while (more_patterns);
1223     }
1224
1225   if (flags & ARGP_HELP_PRE_DOC)
1226     anything |= argp_doc (argp, 0, 0, 1, fs);
1227
1228   if (flags & ARGP_HELP_SEE)
1229     {
1230       __argp_fmtstream_printf (fs,
1231                "Try `%s --help' or `%s --usage' for more information.\n",
1232                name, name);
1233       anything = 1;
1234     }
1235
1236   if (flags & ARGP_HELP_LONG)
1237     /* Print a long, detailed help message.  */
1238     {
1239       /* Print info about all the options.  */
1240       if (hol->num_entries > 0)
1241         {
1242           if (anything)
1243             __argp_fmtstream_putc (fs, '\n');
1244           hol_help (hol, fs);
1245           anything = 1;
1246         }
1247     }
1248
1249   if (flags & ARGP_HELP_POST_DOC)
1250     /* Print any documentation strings at the end.  */
1251     anything |= argp_doc (argp, 1, anything, 0, fs);
1252
1253   if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
1254     {
1255       if (anything)
1256         __argp_fmtstream_putc (fs, '\n');
1257       __argp_fmtstream_printf (fs, "Report bugs to %s.\n", argp_program_bug_address);
1258       anything = 1;
1259     }
1260
1261   if (hol)
1262     hol_free (hol);
1263
1264   __argp_fmtstream_free (fs);
1265 }
1266 #ifdef weak_alias
1267 weak_alias (__argp_help, argp_help)
1268 #endif
1269
1270 /* Output, if appropriate, a usage message for STATE to STREAM.  FLAGS are
1271    from the set ARGP_HELP_*.  */
1272 void
1273 __argp_state_help (struct argp_state *state, FILE *stream, unsigned flags)
1274 {
1275   if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
1276     {
1277       if (state && (state->flags & ARGP_LONG_ONLY))
1278         flags |= ARGP_HELP_LONG_ONLY;
1279
1280       __argp_help (state ? state->argp : 0, stream, flags,
1281                    state ? state->name : program_invocation_name);
1282
1283       if (!state || ! (state->flags & ARGP_NO_EXIT))
1284         {
1285           if (flags & ARGP_HELP_EXIT_ERR)
1286             exit (1);
1287           if (flags & ARGP_HELP_EXIT_OK)
1288             exit (0);
1289         }
1290   }
1291 }
1292 #ifdef weak_alias
1293 weak_alias (__argp_state_help, argp_state_help)
1294 #endif
1295 \f
1296 /* If appropriate, print the printf string FMT and following args, preceded
1297    by the program name and `:', to stderr, and followed by a `Try ... --help'
1298    message, then exit (1).  */
1299 void
1300 __argp_error (struct argp_state *state, const char *fmt, ...)
1301 {
1302   if (!state || !(state->flags & ARGP_NO_ERRS))
1303     {
1304       FILE *stream = state ? state->err_stream : stderr;
1305
1306       if (stream)
1307         {
1308           va_list ap;
1309
1310           fputs (state ? state->name : program_invocation_name, stream);
1311           putc (':', stream);
1312           putc (' ', stream);
1313
1314           va_start (ap, fmt);
1315           vfprintf (stream, fmt, ap);
1316           va_end (ap);
1317
1318           putc ('\n', stream);
1319
1320           __argp_state_help (state, stream, ARGP_HELP_STD_ERR);
1321         }
1322     }
1323 }
1324 #ifdef weak_alias
1325 weak_alias (__argp_error, argp_error)
1326 #endif
1327 \f
1328 /* Similar to the standard gnu error-reporting function error(), but will
1329    respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1330    to STATE->err_stream.  This is useful for argument parsing code that is
1331    shared between program startup (when exiting is desired) and runtime
1332    option parsing (when typically an error code is returned instead).  The
1333    difference between this function and argp_error is that the latter is for
1334    *parsing errors*, and the former is for other problems that occur during
1335    parsing but don't reflect a (syntactic) problem with the input.  */
1336 void
1337 __argp_failure (struct argp_state *state, int status, int errnum,
1338               const char *fmt, ...)
1339 {
1340   if (!state || !(state->flags & ARGP_NO_ERRS))
1341     {
1342       FILE *stream = state ? state->err_stream : stderr;
1343
1344       if (stream)
1345         {
1346           fputs (state ? state->name : program_invocation_name, stream);
1347
1348           if (fmt)
1349             {
1350               va_list ap;
1351
1352               putc (':', stream);
1353               putc (' ', stream);
1354
1355               va_start (ap, fmt);
1356               vfprintf (stream, fmt, ap);
1357               va_end (ap);
1358             }
1359
1360           if (errnum)
1361             {
1362               putc (':', stream);
1363               putc (' ', stream);
1364               fputs (strerror (errnum), stream);
1365             }
1366
1367           putc ('\n', stream);
1368
1369           if (status)
1370             exit (status);
1371         }
1372     }
1373 }
1374 #ifdef weak_alias
1375 weak_alias (__argp_failure, argp_failure)
1376 #endif