1 /* Hierarchial argument parsing help output
2 Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Written by Miles Bader <miles at gnu.ai.mit.edu>.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, write to the Free
19 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
26 # define _GNU_SOURCE 1
33 /* AIX requires this to be the first thing in the file. */
35 # if HAVE_ALLOCA_H || defined _LIBC
41 # ifndef alloca /* predefined by HP cc +Olibcalls */
61 /* This is for other GNU distributions with internationalized messages. */
62 # if (defined HAVE_LIBINTL_H || defined _LIBC) && defined __UCLIBC_HAS_GETTEXT_AWARENESS__
66 # define dgettext(domain, msgid) \
67 INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
70 # define dgettext(domain, msgid) (msgid)
76 # if !HAVE_DECL_STRERROR_R
77 char *strerror_r (int errnum
, char *buf
, size_t buflen
);
80 # if !HAVE_DECL_STRERROR
81 char *strerror (int errnum
);
87 #include "argp-fmtstream.h"
92 # define SIZE_MAX ((size_t) -1)
95 /* User-selectable (using an environment variable) formatting parameters.
97 These may be specified in an environment variable called `ARGP_HELP_FMT',
98 with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
99 Where VALn must be a positive integer. The list of variables is in the
100 UPARAM_NAMES vector, below. */
102 /* Default parameters. */
103 #define DUP_ARGS 0 /* True if option argument can be duplicated. */
104 #define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
105 #define SHORT_OPT_COL 2 /* column in which short options start */
106 #define LONG_OPT_COL 6 /* column in which long options start */
107 #define DOC_OPT_COL 2 /* column in which doc options start */
108 #define OPT_DOC_COL 29 /* column in which option text starts */
109 #define HEADER_COL 1 /* column in which group headers are printed */
110 #define USAGE_INDENT 12 /* indentation of wrapped usage lines */
111 #define RMARGIN 79 /* right margin used for wrapping */
113 /* User-selectable (using an environment variable) formatting parameters.
114 They must all be of type `int' for the parsing code to work. */
117 /* If true, arguments for an option are shown with both short and long
118 options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
119 If false, then if an option has both, the argument is only shown with
120 the long one, e.g., `-x, --longx=ARG', and a message indicating that
121 this really means both is printed below the options. */
124 /* This is true if when DUP_ARGS is false, and some duplicate arguments have
125 been suppressed, an explanatory message should be printed. */
128 /* Various output columns. */
138 /* This is a global variable, as user options are only ever read once. */
139 static struct uparams uparams
= {
140 DUP_ARGS
, DUP_ARGS_NOTE
,
141 SHORT_OPT_COL
, LONG_OPT_COL
, DOC_OPT_COL
, OPT_DOC_COL
, HEADER_COL
,
142 USAGE_INDENT
, RMARGIN
145 /* A particular uparam, and what the user name is. */
148 const char name
[14]; /* User name. */
149 bool is_bool
; /* Whether it's `boolean'. */
150 uint8_t uparams_offs
; /* Location of the (int) field in UPARAMS. */
153 /* The name-field mappings we know about. */
154 static const struct uparam_name uparam_names
[] =
156 { "dup-args", true, offsetof (struct uparams
, dup_args
) },
157 { "dup-args-note", true, offsetof (struct uparams
, dup_args_note
) },
158 { "short-opt-col", false, offsetof (struct uparams
, short_opt_col
) },
159 { "long-opt-col", false, offsetof (struct uparams
, long_opt_col
) },
160 { "doc-opt-col", false, offsetof (struct uparams
, doc_opt_col
) },
161 { "opt-doc-col", false, offsetof (struct uparams
, opt_doc_col
) },
162 { "header-col", false, offsetof (struct uparams
, header_col
) },
163 { "usage-indent", false, offsetof (struct uparams
, usage_indent
) },
164 { "rmargin", false, offsetof (struct uparams
, rmargin
) }
166 #define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
168 /* Read user options from the environment, and fill in UPARAMS appropiately. */
170 fill_in_uparams (const struct argp_state
*state
)
172 const char *var
= getenv ("ARGP_HELP_FMT");
174 #define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
185 const struct uparam_name
*un
;
186 int unspec
= 0, val
= 0;
187 const char *arg
= var
;
189 while (isalnum (*arg
) || *arg
== '-' || *arg
== '_')
195 if (*arg
== '\0' || *arg
== ',')
197 else if (*arg
== '=')
205 if (var
[0] == 'n' && var
[1] == 'o' && var
[2] == '-')
214 else if (isdigit (*arg
))
217 while (isdigit (*arg
))
224 for (u
= 0; u
< nuparam_names
; ++un
, ++u
)
225 if (strlen (un
->name
) == var_len
226 && strncmp (var
, un
->name
, var_len
) == 0)
228 if (unspec
&& !un
->is_bool
)
229 argp_failure (state
, 0, 0,
230 dgettext (state
== NULL
? NULL
231 : state
->root_argp
->argp_domain
,
233 %.*s: ARGP_HELP_FMT parameter requires a value"),
236 *(int *)((char *)&uparams
+ un
->uparams_offs
) = val
;
239 if (u
== nuparam_names
)
240 argp_failure (state
, 0, 0,
241 dgettext (state
== NULL
? NULL
242 : state
->root_argp
->argp_domain
, "\
243 %.*s: Unknown ARGP_HELP_FMT parameter"),
252 argp_failure (state
, 0, 0,
253 dgettext (state
== NULL
? NULL
254 : state
->root_argp
->argp_domain
,
255 "Garbage in ARGP_HELP_FMT: %s"), var
);
261 /* Returns true if OPT hasn't been marked invisible. Visibility only affects
262 whether OPT is displayed or used in sorting, not option shadowing. */
263 #define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
265 /* Returns true if OPT is an alias for an earlier option. */
266 #define oalias(opt) ((opt)->flags & OPTION_ALIAS)
268 /* Returns true if OPT is an documentation-only entry. */
269 #define odoc(opt) ((opt)->flags & OPTION_DOC)
271 /* Returns true if OPT is the end-of-list marker for a list of options. */
272 #define oend(opt) __option_is_end (opt)
274 /* Returns true if OPT has a short option. */
275 #define oshort(opt) __option_is_short (opt)
278 The help format for a particular option is like:
280 -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
282 Where ARG will be omitted if there's no argument, for this option, or
283 will be surrounded by "[" and "]" appropiately if the argument is
284 optional. The documentation string is word-wrapped appropiately, and if
285 the list of options is long enough, it will be started on a separate line.
286 If there are no short options for a given option, the first long option is
287 indented slighly in a way that's supposed to make most long options appear
288 to be in a separate column.
290 For example, the following output (from ps):
292 -p PID, --pid=PID List the process PID
293 --pgrp=PGRP List processes in the process group PGRP
294 -P, -x, --no-parent Include processes without parents
295 -Q, --all-fields Don't elide unusable fields (normally if there's
296 some reason ps can't print a field for any
297 process, it's removed from the output entirely)
298 -r, --reverse, --gratuitously-long-reverse-option
299 Reverse the order of any sort
300 --session[=SID] Add the processes from the session SID (which
301 defaults to the sid of the current process)
303 Here are some more options:
304 -f ZOT, --foonly=ZOT Glork a foonly
305 -z, --zaza Snit a zar
307 -?, --help Give this help list
308 --usage Give a short usage message
309 -V, --version Print program version
311 The struct argp_option array for the above could look like:
314 {"pid", 'p', "PID", 0, "List the process PID"},
315 {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
316 {"no-parent", 'P', 0, 0, "Include processes without parents"},
317 {0, 'x', 0, OPTION_ALIAS},
318 {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
319 " if there's some reason ps can't"
320 " print a field for any process, it's"
321 " removed from the output entirely)" },
322 {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
323 {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
324 {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
325 "Add the processes from the session"
326 " SID (which defaults to the sid of"
327 " the current process)" },
329 {0,0,0,0, "Here are some more options:"},
330 {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
331 {"zaza", 'z', 0, 0, "Snit a zar"},
336 Note that the last three options are automatically supplied by argp_parse,
337 unless you tell it not to with ARGP_NO_HELP.
341 /* Returns true if CH occurs between BEG and END. */
343 find_char (char ch
, char *beg
, char *end
)
353 struct hol_cluster
; /* fwd decl */
358 const struct argp_option
*opt
;
359 /* Number of options (including aliases). */
362 /* A pointers into the HOL's short_options field, to the first short option
363 letter for this entry. The order of the characters following this point
364 corresponds to the order of options pointed to by OPT, and there are at
365 most NUM. A short option recorded in a option following OPT is only
366 valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
367 probably been shadowed by some other entry). */
370 /* Entries are sorted by their group first, in the order:
371 1, 2, ..., n, 0, -m, ..., -2, -1
372 and then alphabetically within each group. The default is 0. */
375 /* The cluster of options this entry belongs to, or 0 if none. */
376 struct hol_cluster
*cluster
;
378 /* The argp from which this option came. */
379 const struct argp
*argp
;
382 /* A cluster of entries to reflect the argp tree structure. */
385 /* A descriptive header printed before options in this cluster. */
388 /* Used to order clusters within the same group with the same parent,
389 according to the order in which they occurred in the parent argp's child
393 /* How to sort this cluster with respect to options and other clusters at the
394 same depth (clusters always follow options in the same group). */
397 /* The cluster to which this cluster belongs, or 0 if it's at the base
399 struct hol_cluster
*parent
;
401 /* The argp from which this cluster is (eventually) derived. */
402 const struct argp
*argp
;
404 /* The distance this cluster is from the root. */
407 /* Clusters in a given hol are kept in a linked list, to make freeing them
409 struct hol_cluster
*next
;
412 /* A list of options for help. */
415 /* An array of hol_entry's. */
416 struct hol_entry
*entries
;
417 /* The number of entries in this hol. If this field is zero, the others
419 unsigned num_entries
;
421 /* A string containing all short options in this HOL. Each entry contains
422 pointers into this string, so the order can't be messed with blindly. */
425 /* Clusters of entries in this hol. */
426 struct hol_cluster
*clusters
;
429 /* Create a struct hol from the options in ARGP. CLUSTER is the
430 hol_cluster in which these entries occur, or 0, if at the root. */
432 make_hol (const struct argp
*argp
, struct hol_cluster
*cluster
)
435 const struct argp_option
*o
;
436 const struct argp_option
*opts
= argp
->options
;
437 struct hol_entry
*entry
;
438 unsigned num_short_options
= 0;
439 struct hol
*hol
= malloc (sizeof (struct hol
));
443 hol
->num_entries
= 0;
450 /* The first option must not be an alias. */
451 assert (! oalias (opts
));
453 /* Calculate the space needed. */
454 for (o
= opts
; ! oend (o
); o
++)
459 num_short_options
++; /* This is an upper bound. */
462 hol
->entries
= malloc (sizeof (struct hol_entry
) * hol
->num_entries
);
463 hol
->short_options
= malloc (num_short_options
+ 1);
465 assert (hol
->entries
&& hol
->short_options
);
466 #if SIZE_MAX <= UINT_MAX
467 assert (hol
->num_entries
<= SIZE_MAX
/ sizeof (struct hol_entry
));
470 /* Fill in the entries. */
471 so
= hol
->short_options
;
472 for (o
= opts
, entry
= hol
->entries
; ! oend (o
); entry
++)
476 entry
->short_options
= so
;
477 entry
->group
= cur_group
=
480 : ((!o
->name
&& !o
->key
)
483 entry
->cluster
= cluster
;
489 if (oshort (o
) && ! find_char (o
->key
, hol
->short_options
, so
))
490 /* O has a valid short option which hasn't already been used.*/
494 while (! oend (o
) && oalias (o
));
496 *so
= '\0'; /* null terminated so we can find the length */
502 /* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
503 associated argp child list entry), INDEX, and PARENT, and return a pointer
504 to it. ARGP is the argp that this cluster results from. */
505 static struct hol_cluster
*
506 hol_add_cluster (struct hol
*hol
, int group
, const char *header
, int index
,
507 struct hol_cluster
*parent
, const struct argp
*argp
)
509 struct hol_cluster
*cl
= malloc (sizeof (struct hol_cluster
));
518 cl
->depth
= parent
? parent
->depth
+ 1 : 0;
520 cl
->next
= hol
->clusters
;
526 /* Free HOL and any resources it uses. */
528 hol_free (struct hol
*hol
)
530 struct hol_cluster
*cl
= hol
->clusters
;
534 struct hol_cluster
*next
= cl
->next
;
539 if (hol
->num_entries
> 0)
542 free (hol
->short_options
);
549 hol_entry_short_iterate (const struct hol_entry
*entry
,
550 int (*func
)(const struct argp_option
*opt
,
551 const struct argp_option
*real
,
552 const char *domain
, void *cookie
),
553 const char *domain
, void *cookie
)
557 const struct argp_option
*opt
, *real
= entry
->opt
;
558 char *so
= entry
->short_options
;
560 for (opt
= real
, nopts
= entry
->num
; nopts
> 0 && !val
; opt
++, nopts
--)
561 if (oshort (opt
) && *so
== opt
->key
)
566 val
= (*func
)(opt
, real
, domain
, cookie
);
573 static __inline__
int
574 __attribute__ ((always_inline
))
575 hol_entry_long_iterate (const struct hol_entry
*entry
,
576 int (*func
)(const struct argp_option
*opt
,
577 const struct argp_option
*real
,
578 const char *domain
, void *cookie
),
579 const char *domain
, void *cookie
)
583 const struct argp_option
*opt
, *real
= entry
->opt
;
585 for (opt
= real
, nopts
= entry
->num
; nopts
> 0 && !val
; opt
++, nopts
--)
591 val
= (*func
)(opt
, real
, domain
, cookie
);
597 /* Iterator that returns true for the first short option. */
598 static __inline__
int
599 until_short (const struct argp_option
*opt
, const struct argp_option
*real
,
600 const char *domain
, void *cookie
)
602 return oshort (opt
) ? opt
->key
: 0;
605 /* Returns the first valid short option in ENTRY, or 0 if there is none. */
607 hol_entry_first_short (const struct hol_entry
*entry
)
609 return hol_entry_short_iterate (entry
, until_short
,
610 entry
->argp
->argp_domain
, 0);
613 /* Returns the first valid long option in ENTRY, or 0 if there is none. */
615 hol_entry_first_long (const struct hol_entry
*entry
)
617 const struct argp_option
*opt
;
619 for (opt
= entry
->opt
, num
= entry
->num
; num
> 0; opt
++, num
--)
620 if (opt
->name
&& ovisible (opt
))
625 /* Returns the entry in HOL with the long option name NAME, or 0 if there is
627 static struct hol_entry
*
628 hol_find_entry (struct hol
*hol
, const char *name
)
630 struct hol_entry
*entry
= hol
->entries
;
631 unsigned num_entries
= hol
->num_entries
;
633 while (num_entries
-- > 0)
635 const struct argp_option
*opt
= entry
->opt
;
636 unsigned num_opts
= entry
->num
;
638 while (num_opts
-- > 0)
639 if (opt
->name
&& ovisible (opt
) && strcmp (opt
->name
, name
) == 0)
650 /* If an entry with the long option NAME occurs in HOL, set it's special
651 sort position to GROUP. */
653 hol_set_group (struct hol
*hol
, const char *name
, int group
)
655 struct hol_entry
*entry
= hol_find_entry (hol
, name
);
657 entry
->group
= group
;
660 /* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
661 EQ is what to return if GROUP1 and GROUP2 are the same. */
663 group_cmp (int group1
, int group2
, int eq
)
665 if (group1
== group2
)
667 else if ((group1
< 0 && group2
< 0) || (group1
>= 0 && group2
>= 0))
668 return group1
- group2
;
670 return group2
- group1
;
673 /* Compare clusters CL1 & CL2 by the order that they should appear in
676 hol_cluster_cmp (const struct hol_cluster
*cl1
, const struct hol_cluster
*cl2
)
678 /* If one cluster is deeper than the other, use its ancestor at the same
679 level, so that finding the common ancestor is straightforward. */
680 while (cl1
->depth
> cl2
->depth
)
682 while (cl2
->depth
> cl1
->depth
)
685 /* Now reduce both clusters to their ancestors at the point where both have
686 a common parent; these can be directly compared. */
687 while (cl1
->parent
!= cl2
->parent
)
688 cl1
= cl1
->parent
, cl2
= cl2
->parent
;
690 return group_cmp (cl1
->group
, cl2
->group
, cl2
->index
- cl1
->index
);
693 /* Return the ancestor of CL that's just below the root (i.e., has a parent
695 static struct hol_cluster
*
696 hol_cluster_base (struct hol_cluster
*cl
)
703 /* Return true if CL1 is a child of CL2. */
705 hol_cluster_is_child (const struct hol_cluster
*cl1
,
706 const struct hol_cluster
*cl2
)
708 while (cl1
&& cl1
!= cl2
)
713 /* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
714 that should be used for comparisons, and returns true iff it should be
715 treated as a non-option. */
717 canon_doc_option (const char **name
)
720 /* Skip initial whitespace. */
721 while (isspace (**name
))
723 /* Decide whether this looks like an option (leading `-') or not. */
724 non_opt
= (**name
!= '-');
725 /* Skip until part of name used for sorting. */
726 while (**name
&& !isalnum (**name
))
731 /* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
734 hol_entry_cmp (const struct hol_entry
*entry1
,
735 const struct hol_entry
*entry2
)
737 /* The group numbers by which the entries should be ordered; if either is
738 in a cluster, then this is just the group within the cluster. */
739 int group1
= entry1
->group
, group2
= entry2
->group
;
741 if (entry1
->cluster
!= entry2
->cluster
)
743 /* The entries are not within the same cluster, so we can't compare them
744 directly, we have to use the appropiate clustering level too. */
745 if (! entry1
->cluster
)
746 /* ENTRY1 is at the `base level', not in a cluster, so we have to
747 compare it's group number with that of the base cluster in which
748 ENTRY2 resides. Note that if they're in the same group, the
749 clustered option always comes laster. */
750 return group_cmp (group1
, hol_cluster_base (entry2
->cluster
)->group
, -1);
751 else if (! entry2
->cluster
)
752 /* Likewise, but ENTRY2's not in a cluster. */
753 return group_cmp (hol_cluster_base (entry1
->cluster
)->group
, group2
, 1);
755 /* Both entries are in clusters, we can just compare the clusters. */
756 return hol_cluster_cmp (entry1
->cluster
, entry2
->cluster
);
758 else if (group1
== group2
)
759 /* The entries are both in the same cluster and group, so compare them
762 int short1
= hol_entry_first_short (entry1
);
763 int short2
= hol_entry_first_short (entry2
);
764 int doc1
= odoc (entry1
->opt
);
765 int doc2
= odoc (entry2
->opt
);
766 const char *long1
= hol_entry_first_long (entry1
);
767 const char *long2
= hol_entry_first_long (entry2
);
770 doc1
= long1
!= NULL
&& canon_doc_option (&long1
);
772 doc2
= long2
!= NULL
&& canon_doc_option (&long2
);
775 /* `documentation' options always follow normal options (or
776 documentation options that *look* like normal options). */
778 else if (!short1
&& !short2
&& long1
&& long2
)
779 /* Only long options. */
780 return strcasecmp (long1
, long2
);
782 /* Compare short/short, long/short, short/long, using the first
783 character of long options. Entries without *any* valid
784 options (such as options with OPTION_HIDDEN set) will be put
785 first, but as they're not displayed, it doesn't matter where
788 char first1
= short1
? short1
: long1
? *long1
: 0;
789 char first2
= short2
? short2
: long2
? *long2
: 0;
791 int lower_cmp
= _tolower (first1
) - _tolower (first2
);
793 int lower_cmp
= tolower (first1
) - tolower (first2
);
795 /* Compare ignoring case, except when the options are both the
796 same letter, in which case lower-case always comes first. */
797 return lower_cmp
? lower_cmp
: first2
- first1
;
801 /* Within the same cluster, but not the same group, so just compare
803 return group_cmp (group1
, group2
, 0);
806 /* Version of hol_entry_cmp with correct signature for qsort. */
808 hol_entry_qcmp (const void *entry1_v
, const void *entry2_v
)
810 return hol_entry_cmp (entry1_v
, entry2_v
);
813 /* Sort HOL by group and alphabetically by option name (with short options
814 taking precedence over long). Since the sorting is for display purposes
815 only, the shadowing of options isn't effected. */
817 hol_sort (struct hol
*hol
)
819 if (hol
->num_entries
> 0)
820 qsort (hol
->entries
, hol
->num_entries
, sizeof (struct hol_entry
),
824 /* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
825 any in MORE with the same name. */
827 hol_append (struct hol
*hol
, struct hol
*more
)
829 struct hol_cluster
**cl_end
= &hol
->clusters
;
831 /* Steal MORE's cluster list, and add it to the end of HOL's. */
833 cl_end
= &(*cl_end
)->next
;
834 *cl_end
= more
->clusters
;
838 if (more
->num_entries
> 0)
840 if (hol
->num_entries
== 0)
842 hol
->num_entries
= more
->num_entries
;
843 hol
->entries
= more
->entries
;
844 hol
->short_options
= more
->short_options
;
845 more
->num_entries
= 0; /* Mark MORE's fields as invalid. */
848 /* Append the entries in MORE to those in HOL, taking care to only add
849 non-shadowed SHORT_OPTIONS values. */
854 unsigned num_entries
= hol
->num_entries
+ more
->num_entries
;
855 struct hol_entry
*entries
=
856 malloc (num_entries
* sizeof (struct hol_entry
));
857 unsigned hol_so_len
= strlen (hol
->short_options
);
858 char *short_options
=
859 malloc (hol_so_len
+ strlen (more
->short_options
) + 1);
861 assert (entries
&& short_options
);
862 #if SIZE_MAX <= UINT_MAX
863 assert (num_entries
<= SIZE_MAX
/ sizeof (struct hol_entry
));
866 mempcpy (mempcpy (entries
, hol
->entries
,
867 hol
->num_entries
* sizeof (struct hol_entry
)),
869 more
->num_entries
* sizeof (struct hol_entry
));
871 mempcpy (short_options
, hol
->short_options
, hol_so_len
);
873 /* Fix up the short options pointers from HOL. */
874 for (e
= entries
, left
= hol
->num_entries
; left
> 0; e
++, left
--)
875 e
->short_options
+= (short_options
- hol
->short_options
);
877 /* Now add the short options from MORE, fixing up its entries
879 so
= short_options
+ hol_so_len
;
880 more_so
= more
->short_options
;
881 for (left
= more
->num_entries
; left
> 0; e
++, left
--)
884 const struct argp_option
*opt
;
886 e
->short_options
= so
;
888 for (opts_left
= e
->num
, opt
= e
->opt
; opts_left
; opt
++, opts_left
--)
891 if (oshort (opt
) && ch
== opt
->key
)
892 /* The next short option in MORE_SO, CH, is from OPT. */
894 if (! find_char (ch
, short_options
,
895 short_options
+ hol_so_len
))
896 /* The short option CH isn't shadowed by HOL's options,
897 so add it to the sum. */
907 free (hol
->short_options
);
909 hol
->entries
= entries
;
910 hol
->num_entries
= num_entries
;
911 hol
->short_options
= short_options
;
918 /* Inserts enough spaces to make sure STREAM is at column COL. */
920 indent_to (argp_fmtstream_t stream
, unsigned col
)
922 int needed
= col
- __argp_fmtstream_point (stream
);
924 __argp_fmtstream_putc (stream
, ' ');
927 /* Output to STREAM either a space, or a newline if there isn't room for at
928 least ENSURE characters before the right margin. */
930 space (argp_fmtstream_t stream
, size_t ensure
)
932 if (__argp_fmtstream_point (stream
) + ensure
933 >= __argp_fmtstream_rmargin (stream
))
934 __argp_fmtstream_putc (stream
, '\n');
936 __argp_fmtstream_putc (stream
, ' ');
939 /* If the option REAL has an argument, we print it in using the printf
940 format REQ_FMT or OPT_FMT depending on whether it's a required or
941 optional argument. */
943 arg (const struct argp_option
*real
, const char *req_fmt
, const char *opt_fmt
,
944 const char *domain
, argp_fmtstream_t stream
)
948 if (real
->flags
& OPTION_ARG_OPTIONAL
)
949 __argp_fmtstream_printf (stream
, opt_fmt
,
950 dgettext (domain
, real
->arg
));
952 __argp_fmtstream_printf (stream
, req_fmt
,
953 dgettext (domain
, real
->arg
));
957 /* Helper functions for hol_entry_help. */
959 /* State used during the execution of hol_help. */
960 struct hol_help_state
962 /* PREV_ENTRY should contain the previous entry printed, or 0. */
963 struct hol_entry
*prev_entry
;
965 /* If an entry is in a different group from the previous one, and SEP_GROUPS
966 is true, then a blank line will be printed before any output. */
969 /* True if a duplicate option argument was suppressed (only ever set if
970 UPARAMS.dup_args is false). */
971 int suppressed_dup_arg
;
974 /* Some state used while printing a help entry (used to communicate with
975 helper functions). See the doc for hol_entry_help for more info, as most
976 of the fields are copied from its arguments. */
979 const struct hol_entry
*entry
;
980 argp_fmtstream_t stream
;
981 struct hol_help_state
*hhstate
;
983 /* True if nothing's been printed so far. */
986 /* If non-zero, the state that was used to print this help. */
987 const struct argp_state
*state
;
990 /* If a user doc filter should be applied to DOC, do so. */
992 filter_doc (const char *doc
, int key
, const struct argp
*argp
,
993 const struct argp_state
*state
)
995 if (argp
&& argp
->help_filter
)
996 /* We must apply a user filter to this output. */
998 void *input
= __argp_input (argp
, state
);
999 return (*argp
->help_filter
) (key
, doc
, input
);
1006 /* Prints STR as a header line, with the margin lines set appropiately, and
1007 notes the fact that groups should be separated with a blank line. ARGP is
1008 the argp that should dictate any user doc filtering to take place. Note
1009 that the previous wrap margin isn't restored, but the left margin is reset
1012 print_header (const char *str
, const struct argp
*argp
,
1013 struct pentry_state
*pest
)
1015 const char *tstr
= dgettext (argp
->argp_domain
, str
);
1016 const char *fstr
= filter_doc (tstr
, ARGP_KEY_HELP_HEADER
, argp
, pest
->state
);
1022 if (pest
->hhstate
->prev_entry
)
1023 /* Precede with a blank line. */
1024 __argp_fmtstream_putc (pest
->stream
, '\n');
1025 indent_to (pest
->stream
, uparams
.header_col
);
1026 __argp_fmtstream_set_lmargin (pest
->stream
, uparams
.header_col
);
1027 __argp_fmtstream_set_wmargin (pest
->stream
, uparams
.header_col
);
1028 __argp_fmtstream_puts (pest
->stream
, fstr
);
1029 __argp_fmtstream_set_lmargin (pest
->stream
, 0);
1030 __argp_fmtstream_putc (pest
->stream
, '\n');
1033 pest
->hhstate
->sep_groups
= 1; /* Separate subsequent groups. */
1037 free ((char *) fstr
);
1040 /* Inserts a comma if this isn't the first item on the line, and then makes
1041 sure we're at least to column COL. If this *is* the first item on a line,
1042 prints any pending whitespace/headers that should precede this line. Also
1045 comma (unsigned col
, struct pentry_state
*pest
)
1049 const struct hol_entry
*pe
= pest
->hhstate
->prev_entry
;
1050 const struct hol_cluster
*cl
= pest
->entry
->cluster
;
1052 if (pest
->hhstate
->sep_groups
&& pe
&& pest
->entry
->group
!= pe
->group
)
1053 __argp_fmtstream_putc (pest
->stream
, '\n');
1055 if (cl
&& cl
->header
&& *cl
->header
1057 || (pe
->cluster
!= cl
1058 && !hol_cluster_is_child (pe
->cluster
, cl
))))
1059 /* If we're changing clusters, then this must be the start of the
1060 ENTRY's cluster unless that is an ancestor of the previous one
1061 (in which case we had just popped into a sub-cluster for a bit).
1062 If so, then print the cluster's header line. */
1064 int old_wm
= __argp_fmtstream_wmargin (pest
->stream
);
1065 print_header (cl
->header
, cl
->argp
, pest
);
1066 __argp_fmtstream_set_wmargin (pest
->stream
, old_wm
);
1072 __argp_fmtstream_puts (pest
->stream
, ", ");
1074 indent_to (pest
->stream
, col
);
1077 /* Print help for ENTRY to STREAM. */
1079 hol_entry_help (struct hol_entry
*entry
, const struct argp_state
*state
,
1080 argp_fmtstream_t stream
, struct hol_help_state
*hhstate
)
1083 const struct argp_option
*real
= entry
->opt
, *opt
;
1084 char *so
= entry
->short_options
;
1085 int have_long_opt
= 0; /* We have any long options. */
1086 /* Saved margins. */
1087 int old_lm
= __argp_fmtstream_set_lmargin (stream
, 0);
1088 int old_wm
= __argp_fmtstream_wmargin (stream
);
1089 /* PEST is a state block holding some of our variables that we'd like to
1090 share with helper functions. */
1091 struct pentry_state pest
= { entry
, stream
, hhstate
, 1, state
};
1094 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1095 if (opt
->name
&& ovisible (opt
))
1101 /* First emit short options. */
1102 __argp_fmtstream_set_wmargin (stream
, uparams
.short_opt_col
); /* For truly bizarre cases. */
1103 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1104 if (oshort (opt
) && opt
->key
== *so
)
1105 /* OPT has a valid (non shadowed) short option. */
1109 comma (uparams
.short_opt_col
, &pest
);
1110 __argp_fmtstream_putc (stream
, '-');
1111 __argp_fmtstream_putc (stream
, *so
);
1112 if (!have_long_opt
|| uparams
.dup_args
)
1113 arg (real
, " %s", "[%s]",
1114 state
== NULL
? NULL
: state
->root_argp
->argp_domain
,
1117 hhstate
->suppressed_dup_arg
= 1;
1122 /* Now, long options. */
1124 /* A `documentation' option. */
1126 __argp_fmtstream_set_wmargin (stream
, uparams
.doc_opt_col
);
1127 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1128 if (opt
->name
&& ovisible (opt
))
1130 comma (uparams
.doc_opt_col
, &pest
);
1131 /* Calling gettext here isn't quite right, since sorting will
1132 have been done on the original; but documentation options
1133 should be pretty rare anyway... */
1134 __argp_fmtstream_puts (stream
,
1135 dgettext (state
== NULL
? NULL
1136 : state
->root_argp
->argp_domain
,
1141 /* A real long option. */
1143 __argp_fmtstream_set_wmargin (stream
, uparams
.long_opt_col
);
1144 for (opt
= real
, num
= entry
->num
; num
> 0; opt
++, num
--)
1145 if (opt
->name
&& ovisible (opt
))
1147 comma (uparams
.long_opt_col
, &pest
);
1148 __argp_fmtstream_printf (stream
, "--%s", opt
->name
);
1149 arg (real
, "=%s", "[=%s]",
1150 state
== NULL
? NULL
: state
->root_argp
->argp_domain
, stream
);
1154 /* Next, documentation strings. */
1155 __argp_fmtstream_set_lmargin (stream
, 0);
1159 /* Didn't print any switches, what's up? */
1160 if (!oshort (real
) && !real
->name
)
1161 /* This is a group header, print it nicely. */
1162 print_header (real
->doc
, entry
->argp
, &pest
);
1164 /* Just a totally shadowed option or null header; print nothing. */
1165 goto cleanup
; /* Just return, after cleaning up. */
1169 const char *tstr
= real
->doc
? dgettext (state
== NULL
? NULL
1170 : state
->root_argp
->argp_domain
,
1172 const char *fstr
= filter_doc (tstr
, real
->key
, entry
->argp
, state
);
1175 unsigned int col
= __argp_fmtstream_point (stream
);
1177 __argp_fmtstream_set_lmargin (stream
, uparams
.opt_doc_col
);
1178 __argp_fmtstream_set_wmargin (stream
, uparams
.opt_doc_col
);
1180 if (col
> (unsigned int) (uparams
.opt_doc_col
+ 3))
1181 __argp_fmtstream_putc (stream
, '\n');
1182 else if (col
>= (unsigned int) uparams
.opt_doc_col
)
1183 __argp_fmtstream_puts (stream
, " ");
1185 indent_to (stream
, uparams
.opt_doc_col
);
1187 __argp_fmtstream_puts (stream
, fstr
);
1189 if (fstr
&& fstr
!= tstr
)
1190 free ((char *) fstr
);
1192 /* Reset the left margin. */
1193 __argp_fmtstream_set_lmargin (stream
, 0);
1194 __argp_fmtstream_putc (stream
, '\n');
1197 hhstate
->prev_entry
= entry
;
1200 __argp_fmtstream_set_lmargin (stream
, old_lm
);
1201 __argp_fmtstream_set_wmargin (stream
, old_wm
);
1204 /* Output a long help message about the options in HOL to STREAM. */
1206 hol_help (struct hol
*hol
, const struct argp_state
*state
,
1207 argp_fmtstream_t stream
)
1210 struct hol_entry
*entry
;
1211 struct hol_help_state hhstate
= { 0, 0, 0 };
1213 for (entry
= hol
->entries
, num
= hol
->num_entries
; num
> 0; entry
++, num
--)
1214 hol_entry_help (entry
, state
, stream
, &hhstate
);
1216 if (hhstate
.suppressed_dup_arg
&& uparams
.dup_args_note
)
1218 const char *tstr
= dgettext (state
== NULL
? NULL
1219 : state
->root_argp
->argp_domain
, "\
1220 Mandatory or optional arguments to long options are also mandatory or \
1221 optional for any corresponding short options.");
1222 const char *fstr
= filter_doc (tstr
, ARGP_KEY_HELP_DUP_ARGS_NOTE
,
1223 state
? state
->root_argp
: 0, state
);
1226 __argp_fmtstream_putc (stream
, '\n');
1227 __argp_fmtstream_puts (stream
, fstr
);
1228 __argp_fmtstream_putc (stream
, '\n');
1230 if (fstr
&& fstr
!= tstr
)
1231 free ((char *) fstr
);
1235 /* Helper functions for hol_usage. */
1237 /* If OPT is a short option without an arg, append its key to the string
1238 pointer pointer to by COOKIE, and advance the pointer. */
1240 add_argless_short_opt (const struct argp_option
*opt
,
1241 const struct argp_option
*real
,
1242 const char *domain
, void *cookie
)
1244 char **snao_end
= cookie
;
1245 if (!(opt
->arg
|| real
->arg
)
1246 && !((opt
->flags
| real
->flags
) & OPTION_NO_USAGE
))
1247 *(*snao_end
)++ = opt
->key
;
1251 /* If OPT is a short option with an arg, output a usage entry for it to the
1252 stream pointed at by COOKIE. */
1254 usage_argful_short_opt (const struct argp_option
*opt
,
1255 const struct argp_option
*real
,
1256 const char *domain
, void *cookie
)
1258 argp_fmtstream_t stream
= cookie
;
1259 const char *arg
= opt
->arg
;
1260 int flags
= opt
->flags
| real
->flags
;
1265 if (arg
&& !(flags
& OPTION_NO_USAGE
))
1267 arg
= dgettext (domain
, arg
);
1269 if (flags
& OPTION_ARG_OPTIONAL
)
1270 __argp_fmtstream_printf (stream
, " [-%c[%s]]", opt
->key
, arg
);
1273 /* Manually do line wrapping so that it (probably) won't
1274 get wrapped at the embedded space. */
1275 space (stream
, 6 + strlen (arg
));
1276 __argp_fmtstream_printf (stream
, "[-%c %s]", opt
->key
, arg
);
1283 /* Output a usage entry for the long option opt to the stream pointed at by
1286 usage_long_opt (const struct argp_option
*opt
,
1287 const struct argp_option
*real
,
1288 const char *domain
, void *cookie
)
1290 argp_fmtstream_t stream
= cookie
;
1291 const char *arg
= opt
->arg
;
1292 int flags
= opt
->flags
| real
->flags
;
1297 if (! (flags
& OPTION_NO_USAGE
))
1301 arg
= dgettext (domain
, arg
);
1302 if (flags
& OPTION_ARG_OPTIONAL
)
1303 __argp_fmtstream_printf (stream
, " [--%s[=%s]]", opt
->name
, arg
);
1305 __argp_fmtstream_printf (stream
, " [--%s=%s]", opt
->name
, arg
);
1308 __argp_fmtstream_printf (stream
, " [--%s]", opt
->name
);
1314 /* Print a short usage description for the arguments in HOL to STREAM. */
1316 hol_usage (struct hol
*hol
, argp_fmtstream_t stream
)
1318 if (hol
->num_entries
> 0)
1321 struct hol_entry
*entry
;
1322 char *short_no_arg_opts
= alloca (strlen (hol
->short_options
) + 1);
1323 char *snao_end
= short_no_arg_opts
;
1325 /* First we put a list of short options without arguments. */
1326 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1328 ; entry
++, nentries
--)
1329 hol_entry_short_iterate (entry
, add_argless_short_opt
,
1330 entry
->argp
->argp_domain
, &snao_end
);
1331 if (snao_end
> short_no_arg_opts
)
1334 __argp_fmtstream_printf (stream
, " [-%s]", short_no_arg_opts
);
1337 /* Now a list of short options *with* arguments. */
1338 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1340 ; entry
++, nentries
--)
1341 hol_entry_short_iterate (entry
, usage_argful_short_opt
,
1342 entry
->argp
->argp_domain
, stream
);
1344 /* Finally, a list of long options (whew!). */
1345 for (entry
= hol
->entries
, nentries
= hol
->num_entries
1347 ; entry
++, nentries
--)
1348 hol_entry_long_iterate (entry
, usage_long_opt
,
1349 entry
->argp
->argp_domain
, stream
);
1353 /* Make a HOL containing all levels of options in ARGP. CLUSTER is the
1354 cluster in which ARGP's entries should be clustered, or 0. */
1356 argp_hol (const struct argp
*argp
, struct hol_cluster
*cluster
)
1358 const struct argp_child
*child
= argp
->children
;
1359 struct hol
*hol
= make_hol (argp
, cluster
);
1363 struct hol_cluster
*child_cluster
=
1364 ((child
->group
|| child
->header
)
1365 /* Put CHILD->argp within its own cluster. */
1366 ? hol_add_cluster (hol
, child
->group
, child
->header
,
1367 child
- argp
->children
, cluster
, argp
)
1368 /* Just merge it into the parent's cluster. */
1370 hol_append (hol
, argp_hol (child
->argp
, child_cluster
)) ;
1376 /* Calculate how many different levels with alternative args strings exist in
1379 argp_args_levels (const struct argp
*argp
)
1382 const struct argp_child
*child
= argp
->children
;
1384 if (argp
->args_doc
&& strchr (argp
->args_doc
, '\n'))
1389 levels
+= argp_args_levels ((child
++)->argp
);
1394 /* Print all the non-option args documented in ARGP to STREAM. Any output is
1395 preceded by a space. LEVELS is a pointer to a byte vector the length
1396 returned by argp_args_levels; it should be initialized to zero, and
1397 updated by this routine for the next call if ADVANCE is true. True is
1398 returned as long as there are more patterns to output. */
1400 argp_args_usage (const struct argp
*argp
, const struct argp_state
*state
,
1401 char **levels
, int advance
, argp_fmtstream_t stream
)
1403 char *our_level
= *levels
;
1405 const struct argp_child
*child
= argp
->children
;
1406 const char *tdoc
= dgettext (argp
->argp_domain
, argp
->args_doc
), *nl
= 0;
1407 const char *fdoc
= filter_doc (tdoc
, ARGP_KEY_HELP_ARGS_DOC
, argp
, state
);
1411 const char *cp
= fdoc
;
1412 nl
= strchrnul (cp
, '\n');
1414 /* This is a `multi-level' args doc; advance to the correct position
1415 as determined by our state in LEVELS, and update LEVELS. */
1419 for (i
= 0; i
< *our_level
; i
++)
1420 cp
= nl
+ 1, nl
= strchrnul (cp
, '\n');
1424 /* Manually do line wrapping so that it (probably) won't get wrapped at
1425 any embedded spaces. */
1426 space (stream
, 1 + nl
- cp
);
1428 __argp_fmtstream_write (stream
, cp
, nl
- cp
);
1430 if (fdoc
&& fdoc
!= tdoc
)
1431 free ((char *)fdoc
); /* Free user's modified doc string. */
1435 advance
= !argp_args_usage ((child
++)->argp
, state
, levels
, advance
, stream
);
1437 if (advance
&& multiple
)
1439 /* Need to increment our level. */
1441 /* There's more we can do here. */
1444 advance
= 0; /* Our parent shouldn't advance also. */
1446 else if (*our_level
> 0)
1447 /* We had multiple levels, but used them up; reset to zero. */
1454 /* Print the documentation for ARGP to STREAM; if POST is false, then
1455 everything preceeding a `\v' character in the documentation strings (or
1456 the whole string, for those with none) is printed, otherwise, everything
1457 following the `\v' character (nothing for strings without). Each separate
1458 bit of documentation is separated a blank line, and if PRE_BLANK is true,
1459 then the first is as well. If FIRST_ONLY is true, only the first
1460 occurrence is output. Returns true if anything was output. */
1462 argp_doc (const struct argp
*argp
, const struct argp_state
*state
,
1463 int post
, int pre_blank
, int first_only
,
1464 argp_fmtstream_t stream
)
1467 const char *inp_text
;
1470 size_t inp_text_limit
= 0;
1471 const char *doc
= dgettext (argp
->argp_domain
, argp
->doc
);
1472 const struct argp_child
*child
= argp
->children
;
1476 char *vt
= strchr (doc
, '\v');
1477 inp_text
= post
? (vt
? vt
+ 1 : 0) : doc
;
1478 inp_text_limit
= (!post
&& vt
) ? (vt
- doc
) : 0;
1483 if (argp
->help_filter
)
1484 /* We have to filter the doc strings. */
1487 /* Copy INP_TEXT so that it's nul-terminated. */
1488 inp_text
= strndup (inp_text
, inp_text_limit
);
1489 input
= __argp_input (argp
, state
);
1491 (*argp
->help_filter
) (post
1492 ? ARGP_KEY_HELP_POST_DOC
1493 : ARGP_KEY_HELP_PRE_DOC
,
1497 text
= (const char *) inp_text
;
1502 __argp_fmtstream_putc (stream
, '\n');
1504 if (text
== inp_text
&& inp_text_limit
)
1505 __argp_fmtstream_write (stream
, inp_text
, inp_text_limit
);
1507 __argp_fmtstream_puts (stream
, text
);
1509 if (__argp_fmtstream_point (stream
) > __argp_fmtstream_lmargin (stream
))
1510 __argp_fmtstream_putc (stream
, '\n');
1515 if (text
&& text
!= inp_text
)
1516 free ((char *) text
); /* Free TEXT returned from the help filter. */
1517 if (inp_text
&& inp_text_limit
&& argp
->help_filter
)
1518 free ((char *) inp_text
); /* We copied INP_TEXT, so free it now. */
1520 if (post
&& argp
->help_filter
)
1521 /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
1523 text
= (*argp
->help_filter
) (ARGP_KEY_HELP_EXTRA
, 0, input
);
1526 if (anything
|| pre_blank
)
1527 __argp_fmtstream_putc (stream
, '\n');
1528 __argp_fmtstream_puts (stream
, text
);
1529 free ((char *) text
);
1530 if (__argp_fmtstream_point (stream
)
1531 > __argp_fmtstream_lmargin (stream
))
1532 __argp_fmtstream_putc (stream
, '\n');
1538 while (child
->argp
&& !(first_only
&& anything
))
1540 argp_doc ((child
++)->argp
, state
,
1541 post
, anything
|| pre_blank
, first_only
,
1547 /* Output a usage message for ARGP to STREAM. If called from
1548 argp_state_help, STATE is the relevent parsing state. FLAGS are from the
1549 set ARGP_HELP_*. NAME is what to use wherever a `program name' is
1552 _help (const struct argp
*argp
, const struct argp_state
*state
, FILE *stream
,
1553 unsigned flags
, char *name
)
1555 int anything
= 0; /* Whether we've output anything. */
1556 struct hol
*hol
= 0;
1557 argp_fmtstream_t fs
;
1562 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1566 fill_in_uparams (state
);
1568 fs
= __argp_make_fmtstream (stream
, 0, uparams
.rmargin
, 0);
1571 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1572 funlockfile (stream
);
1577 if (flags
& (ARGP_HELP_USAGE
| ARGP_HELP_SHORT_USAGE
| ARGP_HELP_LONG
))
1579 hol
= argp_hol (argp
, 0);
1581 /* If present, these options always come last. */
1582 hol_set_group (hol
, "help", -1);
1583 hol_set_group (hol
, "version", -1);
1588 if (flags
& (ARGP_HELP_USAGE
| ARGP_HELP_SHORT_USAGE
))
1589 /* Print a short `Usage:' message. */
1591 int first_pattern
= 1, more_patterns
;
1592 size_t num_pattern_levels
= argp_args_levels (argp
);
1593 char *pattern_levels
= alloca (num_pattern_levels
);
1595 memset (pattern_levels
, 0, num_pattern_levels
);
1600 int old_wm
= __argp_fmtstream_set_wmargin (fs
, uparams
.usage_indent
);
1601 char *levels
= pattern_levels
;
1604 __argp_fmtstream_printf (fs
, "%s %s",
1605 dgettext (argp
->argp_domain
, "Usage:"),
1608 __argp_fmtstream_printf (fs
, "%s %s",
1609 dgettext (argp
->argp_domain
, " or: "),
1612 /* We set the lmargin as well as the wmargin, because hol_usage
1613 manually wraps options with newline to avoid annoying breaks. */
1614 old_lm
= __argp_fmtstream_set_lmargin (fs
, uparams
.usage_indent
);
1616 if (flags
& ARGP_HELP_SHORT_USAGE
)
1617 /* Just show where the options go. */
1619 if (hol
->num_entries
> 0)
1620 __argp_fmtstream_puts (fs
, dgettext (argp
->argp_domain
,
1624 /* Actually print the options. */
1626 hol_usage (hol
, fs
);
1627 flags
|= ARGP_HELP_SHORT_USAGE
; /* But only do so once. */
1630 more_patterns
= argp_args_usage (argp
, state
, &levels
, 1, fs
);
1632 __argp_fmtstream_set_wmargin (fs
, old_wm
);
1633 __argp_fmtstream_set_lmargin (fs
, old_lm
);
1635 __argp_fmtstream_putc (fs
, '\n');
1640 while (more_patterns
);
1643 if (flags
& ARGP_HELP_PRE_DOC
)
1644 anything
|= argp_doc (argp
, state
, 0, 0, 1, fs
);
1646 if (flags
& ARGP_HELP_SEE
)
1648 __argp_fmtstream_printf (fs
, dgettext (argp
->argp_domain
, "\
1649 Try `%s --help' or `%s --usage' for more information.\n"),
1654 if (flags
& ARGP_HELP_LONG
)
1655 /* Print a long, detailed help message. */
1657 /* Print info about all the options. */
1658 if (hol
->num_entries
> 0)
1661 __argp_fmtstream_putc (fs
, '\n');
1662 hol_help (hol
, state
, fs
);
1667 if (flags
& ARGP_HELP_POST_DOC
)
1668 /* Print any documentation strings at the end. */
1669 anything
|= argp_doc (argp
, state
, 1, anything
, 0, fs
);
1671 if ((flags
& ARGP_HELP_BUG_ADDR
) && argp_program_bug_address
)
1674 __argp_fmtstream_putc (fs
, '\n');
1675 __argp_fmtstream_printf (fs
, dgettext (argp
->argp_domain
,
1676 "Report bugs to %s.\n"),
1677 argp_program_bug_address
);
1681 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1682 funlockfile (stream
);
1688 __argp_fmtstream_free (fs
);
1691 /* Output a usage message for ARGP to STREAM. FLAGS are from the set
1692 ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
1693 void argp_help (const struct argp
*argp
, FILE *stream
,
1694 unsigned flags
, char *name
)
1696 _help (argp
, 0, stream
, flags
, name
);
1700 __argp_short_program_name (void)
1702 # ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
1704 * uClibc provides both program_invocation_name and
1705 * program_invocation_short_name
1707 return (char *) program_invocation_short_name
;
1709 /* FIXME: What now? Miles suggests that it is better to use NULL,
1710 but currently the value is passed on directly to fputs_unlocked,
1711 so that requires more changes. */
1713 # warning No reasonable value to return
1714 # endif /* __GNUC__ */
1719 /* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
1720 from the set ARGP_HELP_*. */
1722 argp_state_help (const struct argp_state
*state
, FILE *stream
, unsigned flags
)
1724 if ((!state
|| ! (state
->flags
& ARGP_NO_ERRS
)) && stream
)
1726 if (state
&& (state
->flags
& ARGP_LONG_ONLY
))
1727 flags
|= ARGP_HELP_LONG_ONLY
;
1729 _help (state
? state
->root_argp
: 0, state
, stream
, flags
,
1730 state
? state
->name
: __argp_short_program_name ());
1732 if (!state
|| ! (state
->flags
& ARGP_NO_EXIT
))
1734 if (flags
& ARGP_HELP_EXIT_ERR
)
1735 exit (argp_err_exit_status
);
1736 if (flags
& ARGP_HELP_EXIT_OK
)
1742 /* If appropriate, print the printf string FMT and following args, preceded
1743 by the program name and `:', to stderr, and followed by a `Try ... --help'
1744 message, then exit (1). */
1746 argp_error (const struct argp_state
*state
, const char *fmt
, ...)
1748 if (!state
|| !(state
->flags
& ARGP_NO_ERRS
))
1750 FILE *stream
= state
? state
->err_stream
: stderr
;
1756 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1762 #if defined _LIBC && defined USE_IN_LIBIO
1765 if (_IO_vasprintf (&buf
, fmt
, ap
) < 0)
1768 __fxprintf (stream
, "%s: %s\n",
1769 state
? state
->name
: __argp_short_program_name (), buf
);
1773 fputs_unlocked (state
? state
->name
: __argp_short_program_name (),
1775 putc_unlocked (':', stream
);
1776 putc_unlocked (' ', stream
);
1778 vfprintf (stream
, fmt
, ap
);
1780 putc_unlocked ('\n', stream
);
1783 argp_state_help (state
, stream
, ARGP_HELP_STD_ERR
);
1787 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1788 funlockfile (stream
);
1794 /* Similar to the standard gnu error-reporting function error(), but will
1795 respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
1796 to STATE->err_stream. This is useful for argument parsing code that is
1797 shared between program startup (when exiting is desired) and runtime
1798 option parsing (when typically an error code is returned instead). The
1799 difference between this function and argp_error is that the latter is for
1800 *parsing errors*, and the former is for other problems that occur during
1801 parsing but don't reflect a (syntactic) problem with the input. */
1803 argp_failure (const struct argp_state
*state
, int status
, int errnum
,
1804 const char *fmt
, ...)
1806 if (!state
|| !(state
->flags
& ARGP_NO_ERRS
))
1808 FILE *stream
= state
? state
->err_stream
: stderr
;
1812 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1816 #if defined _LIBC && defined USE_IN_LIBIO
1817 __fxprintf (stream
, "%s",
1818 state
? state
->name
: __argp_short_program_name ());
1820 fputs_unlocked (state
? state
->name
: __argp_short_program_name (),
1829 #if defined _LIBC && defined USE_IN_LIBIO
1832 if (_IO_vasprintf (&buf
, fmt
, ap
) < 0)
1835 __fxprintf (stream
, ": %s", buf
);
1839 putc_unlocked (':', stream
);
1840 putc_unlocked (' ', stream
);
1842 vfprintf (stream
, fmt
, ap
);
1850 #if (defined _LIBC && defined USE_IN_LIBIO) || defined HAVE_STRERROR_R
1853 #if defined _LIBC && defined USE_IN_LIBIO
1854 __fxprintf (stream
, ": %s",
1855 strerror_r (errnum
, buf
, sizeof (buf
)));
1857 putc_unlocked (':', stream
);
1858 putc_unlocked (' ', stream
);
1859 # ifdef HAVE_STRERROR_R
1860 fputs (strerror_r (errnum
, buf
, sizeof (buf
)), stream
);
1862 fputs (strerror (errnum
), stream
);
1868 if (_IO_fwide (stream
, 0) > 0)
1869 putwc_unlocked (L
'\n', stream
);
1872 putc_unlocked ('\n', stream
);
1874 #if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
1875 funlockfile (stream
);
1878 if (status
&& (!state
|| !(state
->flags
& ARGP_NO_EXIT
)))