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