nexmon – Blame information for rev 1

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