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