summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core/uclibc/uclibc-git/argp-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-core/uclibc/uclibc-git/argp-support.patch')
-rw-r--r--meta/recipes-core/uclibc/uclibc-git/argp-support.patch5192
1 files changed, 5192 insertions, 0 deletions
diff --git a/meta/recipes-core/uclibc/uclibc-git/argp-support.patch b/meta/recipes-core/uclibc/uclibc-git/argp-support.patch
new file mode 100644
index 0000000..bcec6a5
--- /dev/null
+++ b/meta/recipes-core/uclibc/uclibc-git/argp-support.patch
@@ -0,0 +1,5192 @@
1From: Salvatore Cro <salvatore.cro at st.com>
2
3Argp is an advanced support for parsing unix-style argument vectors.
4In addition to the common getopt interface, it provides automatic response
5to `--help' and `--version' options and use of custom parser in conjunction
6with argp native option parser, among others.
7Argp support is required by elfutils package and prelink.
8
9In uClibc argp functionalities has been moved from C library to libuargp.so
10Further the libc.so linker script contains an AS_NEEDED entry so that
11it doesn't need to link libuargp.so explicitely.
12
13Signed-off-by: Salvatore Cro <salvatore.cro at st.com>
14Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono at st.com>
15Signed-off-by: Carmelo Amoroso <carmelo.amoroso at st.com>
16
17Upstream-Status: Pending
18
19---
20 Makefile.in | 8 +
21 Makerules | 8 +-
22 Rules.mak | 7 +
23 extra/Configs/Config.in | 17 +
24 libc/sysdeps/linux/common/bits/getopt_int.h | 136 ++
25 libc/unistd/getopt.c | 18 +-
26 libc/unistd/getopt_int.h | 134 --
27 libuargp/Makefile | 14 +
28 libuargp/Makefile.in | 76 ++
29 libuargp/argp-ba.c | 26 +
30 libuargp/argp-eexst.c | 32 +
31 libuargp/argp-fmtstream.c | 439 +++++++
32 libuargp/argp-fmtstream.h | 314 +++++
33 libuargp/argp-fs-xinl.c | 44 +
34 libuargp/argp-help.c | 1882 +++++++++++++++++++++++++++
35 libuargp/argp-parse.c | 949 ++++++++++++++
36 libuargp/argp-pv.c | 25 +
37 libuargp/argp-pvh.c | 32 +
38 libuargp/argp-xinl.c | 35 +
39 test/argp/Makefile | 7 +
40 test/argp/Makefile.in | 12 +
41 test/argp/argp-ex1.c | 15 +
42 test/argp/argp-ex2.c | 45 +
43 test/argp/argp-ex3.c | 153 +++
44 test/argp/argp-ex4.c | 167 +++
45 test/argp/argp-test.c | 209 +++
46 test/argp/bug-argp1.c | 26 +
47 test/argp/tst-argp1.c | 118 ++
48 test/argp/tst-argp2.c | 101 ++
49 29 files changed, 4911 insertions(+), 138 deletions(-)
50 create mode 100644 libc/sysdeps/linux/common/bits/getopt_int.h
51 delete mode 100644 libc/unistd/getopt_int.h
52 create mode 100644 libuargp/Makefile
53 create mode 100644 libuargp/Makefile.in
54 create mode 100644 libuargp/argp-ba.c
55 create mode 100644 libuargp/argp-eexst.c
56 create mode 100644 libuargp/argp-fmtstream.c
57 create mode 100644 libuargp/argp-fmtstream.h
58 create mode 100644 libuargp/argp-fs-xinl.c
59 create mode 100644 libuargp/argp-help.c
60 create mode 100644 libuargp/argp-parse.c
61 create mode 100644 libuargp/argp-pv.c
62 create mode 100644 libuargp/argp-pvh.c
63 create mode 100644 libuargp/argp-xinl.c
64 create mode 100644 test/argp/Makefile
65 create mode 100644 test/argp/Makefile.in
66 create mode 100644 test/argp/argp-ex1.c
67 create mode 100644 test/argp/argp-ex2.c
68 create mode 100644 test/argp/argp-ex3.c
69 create mode 100644 test/argp/argp-ex4.c
70 create mode 100644 test/argp/argp-test.c
71 create mode 100644 test/argp/bug-argp1.c
72 create mode 100644 test/argp/tst-argp1.c
73 create mode 100644 test/argp/tst-argp2.c
74
75Index: git/Makefile.in
76===================================================================
77--- git.orig/Makefile.in 2012-06-18 13:10:12.000000000 -0700
78+++ git/Makefile.in 2012-06-18 13:12:06.448829343 -0700
79@@ -48,6 +48,7 @@
80 include $(top_srcdir)libutil/Makefile.in
81 include $(top_srcdir)libpthread/Makefile.in
82 include $(top_srcdir)librt/Makefile.in
83+include $(top_srcdir)libuargp/Makefile.in
84 include $(top_srcdir)libubacktrace/Makefile.in
85 include $(top_srcdir)extra/locale/Makefile.in
86
87@@ -250,6 +251,7 @@
88 endif
89 HEADERS_RM-$(HAVE_SHARED) += dlfcn.h bits/dlfcn.h
90 HEADERS_RM-$(PTHREADS_DEBUG_SUPPORT) += thread_db.h
91+HEADERS_RM-$(UCLIBC_HAS_ARGP) += argp.h
92 HEADERS_RM-$(UCLIBC_HAS_BSD_ERR) += err.h
93 HEADERS_RM-$(UCLIBC_HAS_CRYPT) += crypt.h
94 HEADERS_RM-$(UCLIBC_HAS_EPOLL) += sys/epoll.h
95@@ -368,6 +370,12 @@
96 -$(INSTALL) -m 755 $(top_builddir)lib/libc.so $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
97 endif
98 echo "$(UBACKTRACE_ASNEEDED)" >> $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so
99+ifeq ($(UCLIBC_HAS_ARGP),y)
100+# Add the AS_NEEDED entry for libuargp.so
101+ if [ -f $(top_builddir)lib/libc.so -a -f $(PREFIX)$(RUNTIME_PREFIX)lib/$(SHARED_MAJORNAME) ] ; then \
102+ echo "GROUP ( $(UARGP_ASNEEDED) )" >> $(PREFIX)$(DEVEL_PREFIX)lib/libc.so; \
103+ fi
104+endif
105 ifeq ($(UCLIBC_HAS_THREADS),y)
106 ifneq ($(LINUXTHREADS_OLD),y)
107 ifeq ($(HARDWIRED_ABSPATH),y)
108Index: git/Makerules
109===================================================================
110--- git.orig/Makerules 2012-06-18 13:10:12.000000000 -0700
111+++ git/Makerules 2012-06-18 13:10:44.052825547 -0700
112@@ -32,12 +32,12 @@
113 $(libpthread-so-y) $(libpthread-nonshared-y) $(libthread_db-so-y) \
114 $(libresolv-so-y) $(librt-so-y) \
115 $(ldso-y) \
116- $(libutil-so-y) $(libubacktrace-so-y)
117+ $(libutil-so-y) $(libubacktrace-so-y) $(libuargp-so-y)
118
119 ar_objs = $(libc-y) $(libc-static-y) $(libcrypt-a-y) \
120 $(libdl-a-y) $(libintl-a-y) $(libm-a-y) $(libnsl-a-y) \
121 $(libpthread-a-y) $(libthread_db-a-y) \
122- $(libresolv-a-y) $(librt-a-y) $(libutil-a-y) $(libubacktrace-a-y)
123+ $(libresolv-a-y) $(librt-a-y) $(libutil-a-y) $(libubacktrace-a-y) $(libuargp-a-y)
124 ifeq ($(DOPIC),y)
125 ar_objs := $(ar_objs:.o=.os)
126 endif
127@@ -472,7 +472,7 @@
128 $(librt-a-y) $(librt-so-y) $(libresolv-a-y) $(libresolv-so-y) \
129 $(libcrypt-a-y) $(libcrypt-so-y) $(libutil-a-y) $(libutil-so-y) \
130 $(libnsl-a-y) $(libnsl-so-y) $(ldso-y) $(libdl-a-y) $(libdl-so-y) \
131- $(libubacktrace-a-y) $(libubacktrace-so-y)
132+ $(libubacktrace-a-y) $(libubacktrace-so-y) $(libuargp-so-y) $(libuargp-a-y)
133 .depends.dep := \
134 $(patsubst %.s,%.s.dep,$(filter %.s,$(files.dep))) \
135 $(patsubst %.o,%.o.dep,$(filter %.o,$(files.dep))) \
136Index: git/Rules.mak
137===================================================================
138--- git.orig/Rules.mak 2012-06-18 13:10:12.000000000 -0700
139+++ git/Rules.mak 2012-06-18 13:10:44.056825544 -0700
140@@ -589,6 +589,13 @@
141 else
142 export UBACKTRACE_ASNEEDED:=""
143 endif
144+ifeq ($(UCLIBC_HAS_ARGP),y)
145+# Only used in installed libc.so linker script
146+UARGP_FULL_NAME := $(RUNTIME_PREFIX)lib/libuargp.so.$(MAJOR_VERSION)
147+export UARGP_ASNEEDED:=$(shell $(LD) --help 2>/dev/null | grep -q -- --as-needed && echo "AS_NEEDED ( $(UARGP_FULL_NAME) )" || echo "$(UARGP_FULL_NAME)")
148+else
149+export UARGP_ASNEEDED:=""
150+endif
151 endif
152
153 # Add a bunch of extra pedantic annoyingly strict checks
154Index: git/extra/Configs/Config.in
155===================================================================
156--- git.orig/extra/Configs/Config.in 2012-06-18 13:10:12.000000000 -0700
157+++ git/extra/Configs/Config.in 2012-06-18 13:10:44.056825544 -0700
158@@ -1853,6 +1853,23 @@
159 smaller SUSv3 compatible getsubopt().
160
161 Most people will answer Y.
162+
163+config UCLIBC_HAS_ARGP
164+ bool "Support argp (as standalone shared object)"
165+ default n
166+ help
167+ Argp is an interface for parsing unix-style argument vectors. Unlike
168+ the common getopt interface, it provides many advanced features in
169+ addition to parsing options, such as automatic output in response to
170+ `--help' and `--version' options.
171+ A library can export an argp option parser, which programs can easily
172+ use in conjunction with their own option parser.
173+ A new shared object "libuargp" is created. The "libc.so" linker script
174+ contains the AS_NEEDED entry for getting the libuargp linked automatically.
175+ Argp support is needed by elfutils libdw.
176+
177+ Most people can safely answer N.
178+
179 endmenu
180
181
182Index: git/libc/sysdeps/linux/common/bits/getopt_int.h
183===================================================================
184--- /dev/null 1970-01-01 00:00:00.000000000 +0000
185+++ git/libc/sysdeps/linux/common/bits/getopt_int.h 2012-06-18 13:10:44.056825544 -0700
186@@ -0,0 +1,136 @@
187+/* Internal declarations for getopt.
188+ Copyright (C) 1989-1994,1996-1999,2001,2003,2004
189+ Free Software Foundation, Inc.
190+ This file is part of the GNU C Library.
191+
192+ The GNU C Library is free software; you can redistribute it and/or
193+ modify it under the terms of the GNU Lesser General Public
194+ License as published by the Free Software Foundation; either
195+ version 2.1 of the License, or (at your option) any later version.
196+
197+ The GNU C Library is distributed in the hope that it will be useful,
198+ but WITHOUT ANY WARRANTY; without even the implied warranty of
199+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
200+ Lesser General Public License for more details.
201+
202+ You should have received a copy of the GNU Lesser General Public
203+ License along with the GNU C Library; if not, write to the Free
204+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
205+ 02111-1307 USA. */
206+
207+#ifndef _GETOPT_INT_H
208+#define _GETOPT_INT_H 1
209+
210+extern int _getopt_internal (int ___argc, char *const *___argv,
211+ const char *__shortopts,
212+ const struct option *__longopts, int *__longind,
213+ int __long_only) attribute_hidden;
214+
215+
216+/* Reentrant versions which can handle parsing multiple argument
217+ vectors at the same time. */
218+
219+/* For __ordering member */
220+enum {
221+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
222+};
223+
224+/* Data type for reentrant functions. */
225+
226+struct _getopt_data
227+{
228+ /* These have exactly the same meaning as the corresponding global
229+ variables, except that they are used for the reentrant
230+ versions of getopt. */
231+ int optind;
232+ int opterr;
233+ char *optarg;
234+ smalluint optopt; /* we store characters here, a byte is enough */
235+
236+ /* Internal members. */
237+
238+ /* True if the internal members have been initialized. */
239+ smallint __initialized;
240+
241+ /* Describe how to deal with options that follow non-option ARGV-elements.
242+
243+ If the caller did not specify anything,
244+ the default is REQUIRE_ORDER if the environment variable
245+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
246+
247+ REQUIRE_ORDER means don't recognize them as options;
248+ stop option processing when the first non-option is seen.
249+ This is what Unix does.
250+ This mode of operation is selected by either setting the environment
251+ variable POSIXLY_CORRECT, or using `+' as the first character
252+ of the list of option characters.
253+
254+ PERMUTE is the default. We permute the contents of ARGV as we
255+ scan, so that eventually all the non-options are at the end.
256+ This allows options to be given in any order, even with programs
257+ that were not written to expect this.
258+
259+ RETURN_IN_ORDER is an option available to programs that were
260+ written to expect options and other ARGV-elements in any order
261+ and that care about the ordering of the two. We describe each
262+ non-option ARGV-element as if it were the argument of an option
263+ with character code 1. Using `-' as the first character of the
264+ list of option characters selects this mode of operation.
265+
266+ The special argument `--' forces an end of option-scanning regardless
267+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
268+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
269+ smallint __ordering;
270+
271+ /* If the POSIXLY_CORRECT environment variable is set. */
272+ smallint __posixly_correct;
273+
274+ /* The next char to be scanned in the option-element
275+ in which the last option character we returned was found.
276+ This allows us to pick up the scan where we left off.
277+
278+ If this is zero, or a null string, it means resume the scan
279+ by advancing to the next ARGV-element. */
280+ char *__nextchar;
281+
282+
283+ /* Handle permutation of arguments. */
284+
285+ /* Describe the part of ARGV that contains non-options that have
286+ been skipped. `first_nonopt' is the index in ARGV of the first
287+ of them; `last_nonopt' is the index after the last of them. */
288+
289+ int __first_nonopt;
290+ int __last_nonopt;
291+
292+#if defined _LIBC && defined USE_NONOPTION_FLAGS
293+ int __nonoption_flags_max_len;
294+ int __nonoption_flags_len;
295+# endif
296+};
297+
298+/* The initializer is necessary to set OPTIND and OPTERR to their
299+ default values and to clear the initialization flag. */
300+#define _GETOPT_DATA_INITIALIZER { 1, 1 }
301+
302+#if 0 /* first is static on uClibc, the others not used */
303+extern int _getopt_internal_r (int ___argc, char *const *___argv,
304+ const char *__shortopts,
305+ const struct option *__longopts, int *__longind,
306+ int __long_only, struct _getopt_data *__data);
307+#endif
308+#if defined __UCLIBC_HAS_GNU_GETOPT__ || defined __UCLIBC_HAS_GETOPT_LONG__
309+#ifndef __need_getopt
310+extern int _getopt_long_r (int ___argc, char *const *___argv,
311+ const char *__shortopts,
312+ const struct option *__longopts, int *__longind,
313+ struct _getopt_data *__data);
314+
315+extern int _getopt_long_only_r (int ___argc, char *const *___argv,
316+ const char *__shortopts,
317+ const struct option *__longopts,
318+ int *__longind,
319+ struct _getopt_data *__data);
320+#endif
321+#endif
322+#endif /* getopt_int.h */
323Index: git/libc/unistd/getopt.c
324===================================================================
325--- git.orig/libc/unistd/getopt.c 2012-06-18 13:10:12.000000000 -0700
326+++ git/libc/unistd/getopt.c 2012-06-18 13:10:44.056825544 -0700
327@@ -106,7 +106,7 @@
328 they can distinguish the relative order of options and other arguments. */
329
330 #include <getopt.h>
331-#include "getopt_int.h"
332+#include <bits/getopt_int.h>
333
334
335 /* For communication from `getopt' to the caller.
336@@ -1170,6 +1170,15 @@
337 return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
338 }
339
340+int
341+_getopt_long_r (int argc, char *const *argv, const char *options,
342+ const struct option *long_options, int *opt_index,
343+ struct _getopt_data *d)
344+{
345+ return _getopt_internal_r (argc, argv, options, long_options, opt_index,
346+ 0, d);
347+}
348+
349 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
350 If an option that starts with '-' (not '--') doesn't match a long option,
351 but does match a short option, it is parsed as a short option
352@@ -1182,4 +1191,12 @@
353 return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
354 }
355
356+int
357+_getopt_long_only_r (int argc, char *const *argv, const char *options,
358+ const struct option *long_options, int *opt_index,
359+ struct _getopt_data *d)
360+{
361+ return _getopt_internal_r (argc, argv, options, long_options, opt_index, 1, d);
362+}
363+
364 #endif /* Not ELIDE_CODE. */
365Index: git/libuargp/Makefile
366===================================================================
367--- /dev/null 1970-01-01 00:00:00.000000000 +0000
368+++ git/libuargp/Makefile 2012-06-18 13:10:44.056825544 -0700
369@@ -0,0 +1,14 @@
370+# Makefile for uClibc (libuargp)
371+#
372+# Copyright (C) 2010 STMicroelectronics Ltd
373+# Author(s): Filippo Arcidiacono <filippo.arcidiacono at st.com>
374+#
375+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
376+#
377+
378+top_srcdir=../
379+top_builddir=../
380+include $(top_builddir)Rules.mak
381+all: libs
382+include Makefile.in
383+include $(top_srcdir)Makerules
384Index: git/libuargp/Makefile.in
385===================================================================
386--- /dev/null 1970-01-01 00:00:00.000000000 +0000
387+++ git/libuargp/Makefile.in 2012-06-18 13:10:44.056825544 -0700
388@@ -0,0 +1,73 @@
389+# Makefile for uClibc (libuargp)
390+#
391+# Copyright (C) 2009, 2010 STMicroelectronics Ltd.
392+# Author(s): Salvatore Cro <salvatore.cro at st.com>
393+# - First implementation, embedded into libc
394+# Filippo Arcidiacono <filippo.arcidiacono at st.com>
395+# - Reworked for stand-alone libuargp implementation
396+
397+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
398+#
399+
400+CFLAGS-libuargp := -DNOT_IN_libc -DIS_IN_libuargp $(SSP_ALL_CFLAGS)
401+
402+LDFLAGS-libuargp.so := $(LDFLAGS)
403+
404+LIBS-libuargp.so := $(LIBS)
405+
406+libuargp_FULL_NAME := libuargp-$(VERSION).so
407+
408+libuargp_DIR := $(top_srcdir)libuargp
409+libuargp_OUT := $(top_builddir)libuargp
410+
411+libuargp_SRC-y :=
412+libuargp_SRC-$(UCLIBC_HAS_ARGP) := $(addsuffix .c,$(addprefix argp-, ba \
413+ eexst fmtstream fs-xinl help parse pv pvh xinl))
414+
415+CFLAGS-argp-xinl.c = -fgnu89-inline
416+
417+libuargp_SRC := $(addprefix $(libuargp_DIR)/,$(libuargp_SRC-y))
418+libuargp_OBJ := $(patsubst $(libuargp_DIR)/%.c,$(libuargp_OUT)/%.o,$(libuargp_SRC))
419+
420+libuargp_SRCS := $(libuargp_SRC)
421+libuargp_OBJS := $(libuargp_OBJ)
422+
423+ifeq ($(DOPIC),y)
424+libuargp-a-y := $(libuargp_OBJS:.o=.os)
425+else
426+libuargp-a-y := $(libuargp_OBJS)
427+endif
428+libuargp-so-y := $(libuargp_OBJS:.o=.os)
429+
430+lib-a-$(UCLIBC_HAS_ARGP) += $(top_builddir)lib/libuargp.a
431+lib-so-$(UCLIBC_HAS_ARGP) += $(top_builddir)lib/libuargp.so
432+
433+objclean-y += CLEAN_libuargp
434+
435+ifeq ($(DOMULTI),n)
436+ifeq ($(DOPIC),y)
437+$(top_builddir)lib/libuargp.so: $(top_builddir)lib/libuargp.a $(libc.depend)
438+else
439+$(top_builddir)lib/libuargp.so: $(libuargp_OUT)/libuargp_so.a $(libc.depend)
440+endif
441+ $(call link.so,$(libuargp_FULL_NAME),$(MAJOR_VERSION))
442+else
443+$(top_builddir)lib/libuargp.so: $(libuargp_OUT)/libuargp.oS $(libc.depend)
444+ $(call linkm.so,$(libuargp_FULL_NAME),$(MAJOR_VERSION))
445+endif
446+
447+$(libuargp_OUT)/libuargp_so.a: $(libuargp-so-y)
448+ $(Q)$(RM) $@
449+ $(do_ar)
450+
451+$(libuargp_OUT)/libuargp.oS: $(libuargp_SRCS)
452+ $(Q)$(RM) $@
453+ $(compile-m)
454+
455+$(top_builddir)lib/libuargp.a: $(libuargp-a-y)
456+ $(Q)$(INSTALL) -d $(dir $@)
457+ $(Q)$(RM) $@
458+ $(do_ar)
459+
460+CLEAN_libuargp:
461+ $(do_rm) $(addprefix $(libuargp_OUT)/*., o os oS a)
462Index: git/libuargp/argp-ba.c
463===================================================================
464--- /dev/null 1970-01-01 00:00:00.000000000 +0000
465+++ git/libuargp/argp-ba.c 2012-06-18 13:10:44.056825544 -0700
466@@ -0,0 +1,26 @@
467+/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
468+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
469+ This file is part of the GNU C Library.
470+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
471+
472+ The GNU C Library is free software; you can redistribute it and/or
473+ modify it under the terms of the GNU Lesser General Public
474+ License as published by the Free Software Foundation; either
475+ version 2.1 of the License, or (at your option) any later version.
476+
477+ The GNU C Library is distributed in the hope that it will be useful,
478+ but WITHOUT ANY WARRANTY; without even the implied warranty of
479+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
480+ Lesser General Public License for more details.
481+
482+ You should have received a copy of the GNU Lesser General Public
483+ License along with the GNU C Library; if not, write to the Free
484+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
485+ 02111-1307 USA. */
486+
487+/* If set by the user program, it should point to string that is the
488+ bug-reporting address for the program. It will be printed by argp_help if
489+ the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
490+ messages), embedded in a sentence that says something like `Report bugs to
491+ ADDR.'. */
492+const char *argp_program_bug_address;
493Index: git/libuargp/argp-eexst.c
494===================================================================
495--- /dev/null 1970-01-01 00:00:00.000000000 +0000
496+++ git/libuargp/argp-eexst.c 2012-06-18 13:10:44.056825544 -0700
497@@ -0,0 +1,32 @@
498+/* Default definition for ARGP_ERR_EXIT_STATUS
499+ Copyright (C) 1997 Free Software Foundation, Inc.
500+ This file is part of the GNU C Library.
501+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
502+
503+ The GNU C Library is free software; you can redistribute it and/or
504+ modify it under the terms of the GNU Lesser General Public
505+ License as published by the Free Software Foundation; either
506+ version 2.1 of the License, or (at your option) any later version.
507+
508+ The GNU C Library is distributed in the hope that it will be useful,
509+ but WITHOUT ANY WARRANTY; without even the implied warranty of
510+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
511+ Lesser General Public License for more details.
512+
513+ You should have received a copy of the GNU Lesser General Public
514+ License along with the GNU C Library; if not, write to the Free
515+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
516+ 02111-1307 USA. */
517+
518+#ifdef HAVE_CONFIG_H
519+# include <config.h>
520+#endif
521+
522+#include <sysexits.h>
523+
524+#include <argp.h>
525+
526+/* The exit status that argp will use when exiting due to a parsing error.
527+ If not defined or set by the user program, this defaults to EX_USAGE from
528+ <sysexits.h>. */
529+error_t argp_err_exit_status = EX_USAGE;
530Index: git/libuargp/argp-fmtstream.c
531===================================================================
532--- /dev/null 1970-01-01 00:00:00.000000000 +0000
533+++ git/libuargp/argp-fmtstream.c 2012-06-18 13:10:44.056825544 -0700
534@@ -0,0 +1,439 @@
535+/* Word-wrapping and line-truncating streams
536+ Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
537+ This file is part of the GNU C Library.
538+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
539+
540+ The GNU C Library is free software; you can redistribute it and/or
541+ modify it under the terms of the GNU Lesser General Public
542+ License as published by the Free Software Foundation; either
543+ version 2.1 of the License, or (at your option) any later version.
544+
545+ The GNU C Library is distributed in the hope that it will be useful,
546+ but WITHOUT ANY WARRANTY; without even the implied warranty of
547+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
548+ Lesser General Public License for more details.
549+
550+ You should have received a copy of the GNU Lesser General Public
551+ License along with the GNU C Library; if not, write to the Free
552+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
553+ 02111-1307 USA.
554+
555+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
556+*/
557+
558+/* This package emulates glibc `line_wrap_stream' semantics for systems that
559+ don't have that. */
560+
561+#ifdef HAVE_CONFIG_H
562+# include <config.h>
563+#endif
564+
565+#include <stdlib.h>
566+#include <string.h>
567+#include <errno.h>
568+#include <stdarg.h>
569+#include <ctype.h>
570+
571+#include "argp-fmtstream.h"
572+
573+#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
574+
575+#ifndef isblank
576+#define isblank(ch) ((ch)==' ' || (ch)=='\t')
577+#endif
578+
579+#if defined _LIBC && defined USE_IN_LIBIO
580+# include <wchar.h>
581+# include <libio/libioP.h>
582+# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
583+#else
584+# define __vsnprintf(s, l, f, a) vsnprintf (s, l, f, a)
585+#endif
586+
587+#define INIT_BUF_SIZE 200
588+#define PRINTF_SIZE_GUESS 150
589+
590+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
591+ written on it with LMARGIN spaces and limits them to RMARGIN columns
592+ total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
593+ replacing the whitespace before them with a newline and WMARGIN spaces.
594+ Otherwise, chars beyond RMARGIN are simply dropped until a newline.
595+ Returns NULL if there was an error. */
596+argp_fmtstream_t
597+__argp_make_fmtstream (FILE *stream,
598+ size_t lmargin, size_t rmargin, ssize_t wmargin)
599+{
600+ argp_fmtstream_t fs;
601+
602+ fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
603+ if (fs != NULL)
604+ {
605+ fs->stream = stream;
606+
607+ fs->lmargin = lmargin;
608+ fs->rmargin = rmargin;
609+ fs->wmargin = wmargin;
610+ fs->point_col = 0;
611+ fs->point_offs = 0;
612+
613+ fs->buf = (char *) malloc (INIT_BUF_SIZE);
614+ if (! fs->buf)
615+ {
616+ free (fs);
617+ fs = 0;
618+ }
619+ else
620+ {
621+ fs->p = fs->buf;
622+ fs->end = fs->buf + INIT_BUF_SIZE;
623+ }
624+ }
625+
626+ return fs;
627+}
628+#if 0
629+/* Not exported. */
630+#ifdef weak_alias
631+weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
632+#endif
633+#endif
634+
635+/* Flush FS to its stream, and free it (but don't close the stream). */
636+void
637+__argp_fmtstream_free (argp_fmtstream_t fs)
638+{
639+ __argp_fmtstream_update (fs);
640+ if (fs->p > fs->buf)
641+ {
642+#ifdef USE_IN_LIBIO
643+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
644+#else
645+ fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
646+#endif
647+ }
648+ free (fs->buf);
649+ free (fs);
650+}
651+#if 0
652+/* Not exported. */
653+#ifdef weak_alias
654+weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
655+#endif
656+#endif
657+
658+/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
659+ end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
660+void
661+__argp_fmtstream_update (argp_fmtstream_t fs)
662+{
663+ char *buf, *nl;
664+ size_t len;
665+
666+ /* Scan the buffer for newlines. */
667+ buf = fs->buf + fs->point_offs;
668+ while (buf < fs->p)
669+ {
670+ size_t r;
671+
672+ if (fs->point_col == 0 && fs->lmargin != 0)
673+ {
674+ /* We are starting a new line. Print spaces to the left margin. */
675+ const size_t pad = fs->lmargin;
676+ if (fs->p + pad < fs->end)
677+ {
678+ /* We can fit in them in the buffer by moving the
679+ buffer text up and filling in the beginning. */
680+ memmove (buf + pad, buf, fs->p - buf);
681+ fs->p += pad; /* Compensate for bigger buffer. */
682+ memset (buf, ' ', pad); /* Fill in the spaces. */
683+ buf += pad; /* Don't bother searching them. */
684+ }
685+ else
686+ {
687+ /* No buffer space for spaces. Must flush. */
688+ size_t i;
689+ for (i = 0; i < pad; i++)
690+ {
691+#ifdef USE_IN_LIBIO
692+ if (_IO_fwide (fs->stream, 0) > 0)
693+ putwc_unlocked (L' ', fs->stream);
694+ else
695+#endif
696+ putc_unlocked (' ', fs->stream);
697+ }
698+ }
699+ fs->point_col = pad;
700+ }
701+
702+ len = fs->p - buf;
703+ nl = memchr (buf, '\n', len);
704+
705+ if (fs->point_col < 0)
706+ fs->point_col = 0;
707+
708+ if (!nl)
709+ {
710+ /* The buffer ends in a partial line. */
711+
712+ if (fs->point_col + len < fs->rmargin)
713+ {
714+ /* The remaining buffer text is a partial line and fits
715+ within the maximum line width. Advance point for the
716+ characters to be written and stop scanning. */
717+ fs->point_col += len;
718+ break;
719+ }
720+ else
721+ /* Set the end-of-line pointer for the code below to
722+ the end of the buffer. */
723+ nl = fs->p;
724+ }
725+ else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
726+ {
727+ /* The buffer contains a full line that fits within the maximum
728+ line width. Reset point and scan the next line. */
729+ fs->point_col = 0;
730+ buf = nl + 1;
731+ continue;
732+ }
733+
734+ /* This line is too long. */
735+ r = fs->rmargin - 1;
736+
737+ if (fs->wmargin < 0)
738+ {
739+ /* Truncate the line by overwriting the excess with the
740+ newline and anything after it in the buffer. */
741+ if (nl < fs->p)
742+ {
743+ memmove (buf + (r - fs->point_col), nl, fs->p - nl);
744+ fs->p -= buf + (r - fs->point_col) - nl;
745+ /* Reset point for the next line and start scanning it. */
746+ fs->point_col = 0;
747+ buf += r + 1; /* Skip full line plus \n. */
748+ }
749+ else
750+ {
751+ /* The buffer ends with a partial line that is beyond the
752+ maximum line width. Advance point for the characters
753+ written, and discard those past the max from the buffer. */
754+ fs->point_col += len;
755+ fs->p -= fs->point_col - r;
756+ break;
757+ }
758+ }
759+ else
760+ {
761+ /* Do word wrap. Go to the column just past the maximum line
762+ width and scan back for the beginning of the word there.
763+ Then insert a line break. */
764+
765+ char *p, *nextline;
766+ int i;
767+
768+ p = buf + (r + 1 - fs->point_col);
769+ while (p >= buf && !isblank (*p))
770+ --p;
771+ nextline = p + 1; /* This will begin the next line. */
772+
773+ if (nextline > buf)
774+ {
775+ /* Swallow separating blanks. */
776+ if (p >= buf)
777+ do
778+ --p;
779+ while (p >= buf && isblank (*p));
780+ nl = p + 1; /* The newline will replace the first blank. */
781+ }
782+ else
783+ {
784+ /* A single word that is greater than the maximum line width.
785+ Oh well. Put it on an overlong line by itself. */
786+ p = buf + (r + 1 - fs->point_col);
787+ /* Find the end of the long word. */
788+ do
789+ ++p;
790+ while (p < nl && !isblank (*p));
791+ if (p == nl)
792+ {
793+ /* It already ends a line. No fussing required. */
794+ fs->point_col = 0;
795+ buf = nl + 1;
796+ continue;
797+ }
798+ /* We will move the newline to replace the first blank. */
799+ nl = p;
800+ /* Swallow separating blanks. */
801+ do
802+ ++p;
803+ while (isblank (*p));
804+ /* The next line will start here. */
805+ nextline = p;
806+ }
807+
808+ /* Note: There are a bunch of tests below for
809+ NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
810+ at the end of the buffer, and NEXTLINE is in fact empty (and so
811+ we need not be careful to maintain its contents). */
812+
813+ if ((nextline == buf + len + 1
814+ ? fs->end - nl < fs->wmargin + 1
815+ : nextline - (nl + 1) < fs->wmargin)
816+ && fs->p > nextline)
817+ {
818+ /* The margin needs more blanks than we removed. */
819+ if (fs->end - fs->p > fs->wmargin + 1)
820+ /* Make some space for them. */
821+ {
822+ size_t mv = fs->p - nextline;
823+ memmove (nl + 1 + fs->wmargin, nextline, mv);
824+ nextline = nl + 1 + fs->wmargin;
825+ len = nextline + mv - buf;
826+ *nl++ = '\n';
827+ }
828+ else
829+ /* Output the first line so we can use the space. */
830+ {
831+#if defined _LIBC && defined USE_IN_LIBIO
832+ __fxprintf (fs->stream, "%.*s\n",
833+ (int) (nl - fs->buf), fs->buf);
834+#else
835+ if (nl > fs->buf)
836+ fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
837+ putc_unlocked ('\n', fs->stream);
838+#endif
839+
840+ len += buf - fs->buf;
841+ nl = buf = fs->buf;
842+ }
843+ }
844+ else
845+ /* We can fit the newline and blanks in before
846+ the next word. */
847+ *nl++ = '\n';
848+
849+ if (nextline - nl >= fs->wmargin
850+ || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
851+ /* Add blanks up to the wrap margin column. */
852+ for (i = 0; i < fs->wmargin; ++i)
853+ *nl++ = ' ';
854+ else
855+ for (i = 0; i < fs->wmargin; ++i)
856+#ifdef USE_IN_LIBIO
857+ if (_IO_fwide (fs->stream, 0) > 0)
858+ putwc_unlocked (L' ', fs->stream);
859+ else
860+#endif
861+ putc_unlocked (' ', fs->stream);
862+
863+ /* Copy the tail of the original buffer into the current buffer
864+ position. */
865+ if (nl < nextline)
866+ memmove (nl, nextline, buf + len - nextline);
867+ len -= nextline - buf;
868+
869+ /* Continue the scan on the remaining lines in the buffer. */
870+ buf = nl;
871+
872+ /* Restore bufp to include all the remaining text. */
873+ fs->p = nl + len;
874+
875+ /* Reset the counter of what has been output this line. If wmargin
876+ is 0, we want to avoid the lmargin getting added, so we set
877+ point_col to a magic value of -1 in that case. */
878+ fs->point_col = fs->wmargin ? fs->wmargin : -1;
879+ }
880+ }
881+
882+ /* Remember that we've scanned as far as the end of the buffer. */
883+ fs->point_offs = fs->p - fs->buf;
884+}
885+
886+/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
887+ growing the buffer, or by flushing it. True is returned iff we succeed. */
888+int
889+__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
890+{
891+ if ((size_t) (fs->end - fs->p) < amount)
892+ {
893+ ssize_t wrote;
894+
895+ /* Flush FS's buffer. */
896+ __argp_fmtstream_update (fs);
897+
898+#if defined _LIBC && defined USE_IN_LIBIO
899+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
900+ wrote = fs->p - fs->buf;
901+#else
902+ wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
903+#endif
904+ if (wrote == fs->p - fs->buf)
905+ {
906+ fs->p = fs->buf;
907+ fs->point_offs = 0;
908+ }
909+ else
910+ {
911+ fs->p -= wrote;
912+ fs->point_offs -= wrote;
913+ memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
914+ return 0;
915+ }
916+
917+ if ((size_t) (fs->end - fs->buf) < amount)
918+ /* Gotta grow the buffer. */
919+ {
920+ size_t old_size = fs->end - fs->buf;
921+ size_t new_size = old_size + amount;
922+ char *new_buf;
923+
924+ if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
925+ {
926+ __set_errno (ENOMEM);
927+ return 0;
928+ }
929+
930+ fs->buf = new_buf;
931+ fs->end = new_buf + new_size;
932+ fs->p = fs->buf;
933+ }
934+ }
935+
936+ return 1;
937+}
938+
939+ssize_t
940+__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
941+{
942+ int out;
943+ size_t avail;
944+ size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
945+
946+ do
947+ {
948+ va_list args;
949+
950+ if (! __argp_fmtstream_ensure (fs, size_guess))
951+ return -1;
952+
953+ va_start (args, fmt);
954+ avail = fs->end - fs->p;
955+ out = __vsnprintf (fs->p, avail, fmt, args);
956+ va_end (args);
957+ if ((size_t) out >= avail)
958+ size_guess = out + 1;
959+ }
960+ while ((size_t) out >= avail);
961+
962+ fs->p += out;
963+
964+ return out;
965+}
966+#if 0
967+/* Not exported. */
968+#ifdef weak_alias
969+weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
970+#endif
971+#endif
972+
973+#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
974Index: git/libuargp/argp-fmtstream.h
975===================================================================
976--- /dev/null 1970-01-01 00:00:00.000000000 +0000
977+++ git/libuargp/argp-fmtstream.h 2012-06-18 13:10:44.056825544 -0700
978@@ -0,0 +1,314 @@
979+/* Word-wrapping and line-truncating streams.
980+ Copyright (C) 1997 Free Software Foundation, Inc.
981+ This file is part of the GNU C Library.
982+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
983+
984+ The GNU C Library is free software; you can redistribute it and/or
985+ modify it under the terms of the GNU Lesser General Public
986+ License as published by the Free Software Foundation; either
987+ version 2.1 of the License, or (at your option) any later version.
988+
989+ The GNU C Library is distributed in the hope that it will be useful,
990+ but WITHOUT ANY WARRANTY; without even the implied warranty of
991+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
992+ Lesser General Public License for more details.
993+
994+ You should have received a copy of the GNU Lesser General Public
995+ License along with the GNU C Library; if not, write to the Free
996+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
997+ 02111-1307 USA.
998+
999+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
1000+*/
1001+
1002+/* This package emulates glibc `line_wrap_stream' semantics for systems that
1003+ don't have that. If the system does have it, it is just a wrapper for
1004+ that. This header file is only used internally while compiling argp, and
1005+ shouldn't be installed. */
1006+
1007+#ifndef _ARGP_FMTSTREAM_H
1008+#define _ARGP_FMTSTREAM_H
1009+
1010+#include <stdio.h>
1011+#include <string.h>
1012+#include <unistd.h>
1013+
1014+#ifndef __attribute__
1015+/* This feature is available in gcc versions 2.5 and later. */
1016+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(__STRICT_ANSI__)
1017+# define __attribute__(Spec) /* empty */
1018+# endif
1019+/* The __-protected variants of `format' and `printf' attributes
1020+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
1021+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || defined(__STRICT_ANSI__)
1022+# define __format__ format
1023+# define __printf__ printf
1024+# endif
1025+#endif
1026+
1027+#if 0 /* uClibc: disabled */
1028+#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
1029+ || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
1030+/* line_wrap_stream is available, so use that. */
1031+#define ARGP_FMTSTREAM_USE_LINEWRAP
1032+#endif
1033+#else
1034+/* line_wrap stream NOT available */
1035+# undef ARGP_FMTSTREAM_USE_LINEWRAP
1036+#endif
1037+
1038+#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
1039+/* Just be a simple wrapper for line_wrap_stream; the semantics are
1040+ *slightly* different, as line_wrap_stream doesn't actually make a new
1041+ object, it just modifies the given stream (reversibly) to do
1042+ line-wrapping. Since we control who uses this code, it doesn't matter. */
1043+
1044+#include <linewrap.h>
1045+
1046+typedef FILE *argp_fmtstream_t;
1047+
1048+#define argp_make_fmtstream line_wrap_stream
1049+#define __argp_make_fmtstream line_wrap_stream
1050+#define argp_fmtstream_free line_unwrap_stream
1051+#define __argp_fmtstream_free line_unwrap_stream
1052+
1053+#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
1054+#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
1055+#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
1056+#define argp_fmtstream_puts(fs,str) fputs(str,fs)
1057+#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
1058+#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
1059+#define __argp_fmtstream_printf fprintf
1060+#define argp_fmtstream_printf fprintf
1061+
1062+#define __argp_fmtstream_lmargin line_wrap_lmargin
1063+#define argp_fmtstream_lmargin line_wrap_lmargin
1064+#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
1065+#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
1066+#define __argp_fmtstream_rmargin line_wrap_rmargin
1067+#define argp_fmtstream_rmargin line_wrap_rmargin
1068+#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
1069+#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
1070+#define __argp_fmtstream_wmargin line_wrap_wmargin
1071+#define argp_fmtstream_wmargin line_wrap_wmargin
1072+#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
1073+#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
1074+#define __argp_fmtstream_point line_wrap_point
1075+#define argp_fmtstream_point line_wrap_point
1076+
1077+#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
1078+/* Guess we have to define our own version. */
1079+
1080+#ifndef __const
1081+#define __const const
1082+#endif
1083+
1084+struct argp_fmtstream
1085+{
1086+ FILE *stream; /* The stream we're outputting to. */
1087+
1088+ size_t lmargin, rmargin; /* Left and right margins. */
1089+ ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
1090+
1091+ /* Point in buffer to which we've processed for wrapping, but not output. */
1092+ size_t point_offs;
1093+ /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
1094+ ssize_t point_col;
1095+
1096+ char *buf; /* Output buffer. */
1097+ char *p; /* Current end of text in BUF. */
1098+ char *end; /* Absolute end of BUF. */
1099+};
1100+
1101+typedef struct argp_fmtstream *argp_fmtstream_t;
1102+
1103+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
1104+ written on it with LMARGIN spaces and limits them to RMARGIN columns
1105+ total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
1106+ replacing the whitespace before them with a newline and WMARGIN spaces.
1107+ Otherwise, chars beyond RMARGIN are simply dropped until a newline.
1108+ Returns NULL if there was an error. */
1109+extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
1110+ size_t __lmargin,
1111+ size_t __rmargin,
1112+ ssize_t __wmargin);
1113+extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
1114+ size_t __lmargin,
1115+ size_t __rmargin,
1116+ ssize_t __wmargin);
1117+
1118+/* Flush __FS to its stream, and free it (but don't close the stream). */
1119+extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
1120+extern void argp_fmtstream_free (argp_fmtstream_t __fs);
1121+
1122+extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
1123+ __const char *__fmt, ...)
1124+ __attribute__ ((__format__ (printf, 2, 3)));
1125+extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
1126+ __const char *__fmt, ...)
1127+ __attribute__ ((__format__ (printf, 2, 3)));
1128+
1129+extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
1130+extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
1131+
1132+extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
1133+extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
1134+
1135+extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
1136+ __const char *__str, size_t __len);
1137+extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
1138+ __const char *__str, size_t __len);
1139+
1140+/* Access macros for various bits of state. */
1141+#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
1142+#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
1143+#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
1144+#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
1145+#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
1146+#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
1147+
1148+/* Set __FS's left margin to LMARGIN and return the old value. */
1149+extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
1150+ size_t __lmargin);
1151+extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
1152+ size_t __lmargin);
1153+
1154+/* Set __FS's right margin to __RMARGIN and return the old value. */
1155+extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
1156+ size_t __rmargin);
1157+extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
1158+ size_t __rmargin);
1159+
1160+/* Set __FS's wrap margin to __WMARGIN and return the old value. */
1161+extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
1162+ size_t __wmargin);
1163+extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
1164+ size_t __wmargin);
1165+
1166+/* Return the column number of the current output point in __FS. */
1167+extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
1168+extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
1169+
1170+/* Internal routines. */
1171+extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
1172+extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
1173+extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
1174+extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
1175+
1176+#ifdef __OPTIMIZE__
1177+/* Inline versions of above routines. */
1178+
1179+#if !_LIBC
1180+#define __argp_fmtstream_putc argp_fmtstream_putc
1181+#define __argp_fmtstream_puts argp_fmtstream_puts
1182+#define __argp_fmtstream_write argp_fmtstream_write
1183+#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
1184+#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
1185+#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
1186+#define __argp_fmtstream_point argp_fmtstream_point
1187+#define __argp_fmtstream_update _argp_fmtstream_update
1188+#define __argp_fmtstream_ensure _argp_fmtstream_ensure
1189+#endif
1190+
1191+#ifndef ARGP_FS_EI
1192+#define ARGP_FS_EI __extern_inline
1193+#endif
1194+
1195+ARGP_FS_EI size_t
1196+__argp_fmtstream_write (argp_fmtstream_t __fs,
1197+ __const char *__str, size_t __len)
1198+{
1199+ if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
1200+ {
1201+ memcpy (__fs->p, __str, __len);
1202+ __fs->p += __len;
1203+ return __len;
1204+ }
1205+ else
1206+ return 0;
1207+}
1208+
1209+ARGP_FS_EI int
1210+__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
1211+{
1212+ size_t __len = strlen (__str);
1213+ if (__len)
1214+ {
1215+ size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
1216+ return __wrote == __len ? 0 : -1;
1217+ }
1218+ else
1219+ return 0;
1220+}
1221+
1222+ARGP_FS_EI int
1223+__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
1224+{
1225+ if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
1226+ return *__fs->p++ = __ch;
1227+ else
1228+ return EOF;
1229+}
1230+
1231+/* Set __FS's left margin to __LMARGIN and return the old value. */
1232+ARGP_FS_EI size_t
1233+__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
1234+{
1235+ size_t __old;
1236+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1237+ __argp_fmtstream_update (__fs);
1238+ __old = __fs->lmargin;
1239+ __fs->lmargin = __lmargin;
1240+ return __old;
1241+}
1242+
1243+/* Set __FS's right margin to __RMARGIN and return the old value. */
1244+ARGP_FS_EI size_t
1245+__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
1246+{
1247+ size_t __old;
1248+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1249+ __argp_fmtstream_update (__fs);
1250+ __old = __fs->rmargin;
1251+ __fs->rmargin = __rmargin;
1252+ return __old;
1253+}
1254+
1255+/* Set FS's wrap margin to __WMARGIN and return the old value. */
1256+ARGP_FS_EI size_t
1257+__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
1258+{
1259+ size_t __old;
1260+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1261+ __argp_fmtstream_update (__fs);
1262+ __old = __fs->wmargin;
1263+ __fs->wmargin = __wmargin;
1264+ return __old;
1265+}
1266+
1267+/* Return the column number of the current output point in __FS. */
1268+ARGP_FS_EI size_t
1269+__argp_fmtstream_point (argp_fmtstream_t __fs)
1270+{
1271+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1272+ __argp_fmtstream_update (__fs);
1273+ return __fs->point_col >= 0 ? __fs->point_col : 0;
1274+}
1275+
1276+#if !_LIBC
1277+#undef __argp_fmtstream_putc
1278+#undef __argp_fmtstream_puts
1279+#undef __argp_fmtstream_write
1280+#undef __argp_fmtstream_set_lmargin
1281+#undef __argp_fmtstream_set_rmargin
1282+#undef __argp_fmtstream_set_wmargin
1283+#undef __argp_fmtstream_point
1284+#undef __argp_fmtstream_update
1285+#undef __argp_fmtstream_ensure
1286+#endif
1287+
1288+#endif /* __OPTIMIZE__ */
1289+
1290+#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
1291+
1292+#endif /* argp-fmtstream.h */
1293Index: git/libuargp/argp-fs-xinl.c
1294===================================================================
1295--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1296+++ git/libuargp/argp-fs-xinl.c 2012-06-18 13:10:44.056825544 -0700
1297@@ -0,0 +1,44 @@
1298+/* Real definitions for extern inline functions in argp-fmtstream.h
1299+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
1300+ This file is part of the GNU C Library.
1301+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1302+
1303+ The GNU C Library is free software; you can redistribute it and/or
1304+ modify it under the terms of the GNU Lesser General Public
1305+ License as published by the Free Software Foundation; either
1306+ version 2.1 of the License, or (at your option) any later version.
1307+
1308+ The GNU C Library is distributed in the hope that it will be useful,
1309+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1310+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1311+ Lesser General Public License for more details.
1312+
1313+ You should have received a copy of the GNU Lesser General Public
1314+ License along with the GNU C Library; if not, write to the Free
1315+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1316+ 02111-1307 USA. */
1317+
1318+#ifdef HAVE_CONFIG_H
1319+# include <config.h>
1320+#endif
1321+
1322+#define ARGP_FS_EI
1323+#undef __OPTIMIZE__
1324+#define __OPTIMIZE__ 1
1325+#include "argp-fmtstream.h"
1326+
1327+#if 0
1328+/* Not exported. */
1329+/* Add weak aliases. */
1330+#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
1331+
1332+weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
1333+weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
1334+weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
1335+weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
1336+weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
1337+weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
1338+weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
1339+
1340+#endif
1341+#endif
1342Index: git/libuargp/argp-help.c
1343===================================================================
1344--- /dev/null 1970-01-01 00:00:00.000000000 +0000
1345+++ git/libuargp/argp-help.c 2012-06-18 13:10:44.060825542 -0700
1346@@ -0,0 +1,1882 @@
1347+/* Hierarchial argument parsing help output
1348+ Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
1349+ Free Software Foundation, Inc.
1350+ This file is part of the GNU C Library.
1351+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1352+
1353+ The GNU C Library is free software; you can redistribute it and/or
1354+ modify it under the terms of the GNU Lesser General Public
1355+ License as published by the Free Software Foundation; either
1356+ version 2.1 of the License, or (at your option) any later version.
1357+
1358+ The GNU C Library is distributed in the hope that it will be useful,
1359+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1360+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1361+ Lesser General Public License for more details.
1362+
1363+ You should have received a copy of the GNU Lesser General Public
1364+ License along with the GNU C Library; if not, write to the Free
1365+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1366+ 02111-1307 USA.
1367+
1368+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
1369+*/
1370+
1371+#ifndef _GNU_SOURCE
1372+# define _GNU_SOURCE 1
1373+#endif
1374+
1375+#ifdef HAVE_CONFIG_H
1376+#include <config.h>
1377+#endif
1378+
1379+/* AIX requires this to be the first thing in the file. */
1380+#ifndef __GNUC__
1381+# if HAVE_ALLOCA_H || defined _LIBC
1382+# include <alloca.h>
1383+# else
1384+# ifdef _AIX
1385+#pragma alloca
1386+# else
1387+# ifndef alloca /* predefined by HP cc +Olibcalls */
1388+char *alloca ();
1389+# endif
1390+# endif
1391+# endif
1392+#endif
1393+
1394+#include <stddef.h>
1395+#include <stdlib.h>
1396+#include <string.h>
1397+#include <assert.h>
1398+#include <stdarg.h>
1399+#include <ctype.h>
1400+#include <limits.h>
1401+#ifdef _LIBC
1402+# include <wchar.h>
1403+#endif
1404+
1405+#include <features.h>
1406+#ifndef _
1407+/* This is for other GNU distributions with internationalized messages. */
1408+# if (defined HAVE_LIBINTL_H || defined _LIBC) && defined __UCLIBC_HAS_GETTEXT_AWARENESS__
1409+# include <libintl.h>
1410+# ifdef _LIBC
1411+# undef dgettext
1412+# define dgettext(domain, msgid) \
1413+ INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
1414+# endif
1415+# else
1416+# define dgettext(domain, msgid) (msgid)
1417+# endif
1418+#endif
1419+
1420+#ifndef _LIBC
1421+# if HAVE_STRERROR_R
1422+# if !HAVE_DECL_STRERROR_R
1423+char *strerror_r (int errnum, char *buf, size_t buflen);
1424+# endif
1425+# else
1426+# if !HAVE_DECL_STRERROR
1427+char *strerror (int errnum);
1428+# endif
1429+# endif
1430+#endif
1431+
1432+#include <argp.h>
1433+#include "argp-fmtstream.h"
1434+#include <stdbool.h>
1435+#include <stdint.h>
1436+
1437+#ifndef SIZE_MAX
1438+# define SIZE_MAX ((size_t) -1)
1439+#endif
1440+
1441+/* User-selectable (using an environment variable) formatting parameters.
1442+
1443+ These may be specified in an environment variable called `ARGP_HELP_FMT',
1444+ with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
1445+ Where VALn must be a positive integer. The list of variables is in the
1446+ UPARAM_NAMES vector, below. */
1447+
1448+/* Default parameters. */
1449+#define DUP_ARGS 0 /* True if option argument can be duplicated. */
1450+#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
1451+#define SHORT_OPT_COL 2 /* column in which short options start */
1452+#define LONG_OPT_COL 6 /* column in which long options start */
1453+#define DOC_OPT_COL 2 /* column in which doc options start */
1454+#define OPT_DOC_COL 29 /* column in which option text starts */
1455+#define HEADER_COL 1 /* column in which group headers are printed */
1456+#define USAGE_INDENT 12 /* indentation of wrapped usage lines */
1457+#define RMARGIN 79 /* right margin used for wrapping */
1458+
1459+/* User-selectable (using an environment variable) formatting parameters.
1460+ They must all be of type `int' for the parsing code to work. */
1461+struct uparams
1462+{
1463+ /* If true, arguments for an option are shown with both short and long
1464+ options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
1465+ If false, then if an option has both, the argument is only shown with
1466+ the long one, e.g., `-x, --longx=ARG', and a message indicating that
1467+ this really means both is printed below the options. */
1468+ int dup_args;
1469+
1470+ /* This is true if when DUP_ARGS is false, and some duplicate arguments have
1471+ been suppressed, an explanatory message should be printed. */
1472+ int dup_args_note;
1473+
1474+ /* Various output columns. */
1475+ int short_opt_col;
1476+ int long_opt_col;
1477+ int doc_opt_col;
1478+ int opt_doc_col;
1479+ int header_col;
1480+ int usage_indent;
1481+ int rmargin;
1482+};
1483+
1484+/* This is a global variable, as user options are only ever read once. */
1485+static struct uparams uparams = {
1486+ DUP_ARGS, DUP_ARGS_NOTE,
1487+ SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
1488+ USAGE_INDENT, RMARGIN
1489+};
1490+
1491+/* A particular uparam, and what the user name is. */
1492+struct uparam_name
1493+{
1494+ const char name[14]; /* User name. */
1495+ bool is_bool; /* Whether it's `boolean'. */
1496+ uint8_t uparams_offs; /* Location of the (int) field in UPARAMS. */
1497+};
1498+
1499+/* The name-field mappings we know about. */
1500+static const struct uparam_name uparam_names[] =
1501+{
1502+ { "dup-args", true, offsetof (struct uparams, dup_args) },
1503+ { "dup-args-note", true, offsetof (struct uparams, dup_args_note) },
1504+ { "short-opt-col", false, offsetof (struct uparams, short_opt_col) },
1505+ { "long-opt-col", false, offsetof (struct uparams, long_opt_col) },
1506+ { "doc-opt-col", false, offsetof (struct uparams, doc_opt_col) },
1507+ { "opt-doc-col", false, offsetof (struct uparams, opt_doc_col) },
1508+ { "header-col", false, offsetof (struct uparams, header_col) },
1509+ { "usage-indent", false, offsetof (struct uparams, usage_indent) },
1510+ { "rmargin", false, offsetof (struct uparams, rmargin) }
1511+};
1512+#define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
1513+
1514+/* Read user options from the environment, and fill in UPARAMS appropiately. */
1515+static void
1516+fill_in_uparams (const struct argp_state *state)
1517+{
1518+ const char *var = getenv ("ARGP_HELP_FMT");
1519+
1520+#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
1521+
1522+ if (var)
1523+ /* Parse var. */
1524+ while (*var)
1525+ {
1526+ SKIPWS (var);
1527+
1528+ if (isalpha (*var))
1529+ {
1530+ size_t var_len;
1531+ const struct uparam_name *un;
1532+ int unspec = 0, val = 0;
1533+ const char *arg = var;
1534+
1535+ while (isalnum (*arg) || *arg == '-' || *arg == '_')
1536+ arg++;
1537+ var_len = arg - var;
1538+
1539+ SKIPWS (arg);
1540+
1541+ if (*arg == '\0' || *arg == ',')
1542+ unspec = 1;
1543+ else if (*arg == '=')
1544+ {
1545+ arg++;
1546+ SKIPWS (arg);
1547+ }
1548+
1549+ if (unspec)
1550+ {
1551+ if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
1552+ {
1553+ val = 0;
1554+ var += 3;
1555+ var_len -= 3;
1556+ }
1557+ else
1558+ val = 1;
1559+ }
1560+ else if (isdigit (*arg))
1561+ {
1562+ val = atoi (arg);
1563+ while (isdigit (*arg))
1564+ arg++;
1565+ SKIPWS (arg);
1566+ }
1567+
1568+ un = uparam_names;
1569+ size_t u;
1570+ for (u = 0; u < nuparam_names; ++un, ++u)
1571+ if (strlen (un->name) == var_len
1572+ && strncmp (var, un->name, var_len) == 0)
1573+ {
1574+ if (unspec && !un->is_bool)
1575+ argp_failure (state, 0, 0,
1576+ dgettext (state == NULL ? NULL
1577+ : state->root_argp->argp_domain,
1578+ "\
1579+%.*s: ARGP_HELP_FMT parameter requires a value"),
1580+ (int) var_len, var);
1581+ else
1582+ *(int *)((char *)&uparams + un->uparams_offs) = val;
1583+ break;
1584+ }
1585+ if (u == nuparam_names)
1586+ argp_failure (state, 0, 0,
1587+ dgettext (state == NULL ? NULL
1588+ : state->root_argp->argp_domain, "\
1589+%.*s: Unknown ARGP_HELP_FMT parameter"),
1590+ (int) var_len, var);
1591+
1592+ var = arg;
1593+ if (*var == ',')
1594+ var++;
1595+ }
1596+ else if (*var)
1597+ {
1598+ argp_failure (state, 0, 0,
1599+ dgettext (state == NULL ? NULL
1600+ : state->root_argp->argp_domain,
1601+ "Garbage in ARGP_HELP_FMT: %s"), var);
1602+ break;
1603+ }
1604+ }
1605+}
1606+
1607+/* Returns true if OPT hasn't been marked invisible. Visibility only affects
1608+ whether OPT is displayed or used in sorting, not option shadowing. */
1609+#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
1610+
1611+/* Returns true if OPT is an alias for an earlier option. */
1612+#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
1613+
1614+/* Returns true if OPT is an documentation-only entry. */
1615+#define odoc(opt) ((opt)->flags & OPTION_DOC)
1616+
1617+/* Returns true if OPT is the end-of-list marker for a list of options. */
1618+#define oend(opt) __option_is_end (opt)
1619+
1620+/* Returns true if OPT has a short option. */
1621+#define oshort(opt) __option_is_short (opt)
1622+
1623+/*
1624+ The help format for a particular option is like:
1625+
1626+ -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
1627+
1628+ Where ARG will be omitted if there's no argument, for this option, or
1629+ will be surrounded by "[" and "]" appropiately if the argument is
1630+ optional. The documentation string is word-wrapped appropiately, and if
1631+ the list of options is long enough, it will be started on a separate line.
1632+ If there are no short options for a given option, the first long option is
1633+ indented slighly in a way that's supposed to make most long options appear
1634+ to be in a separate column.
1635+
1636+ For example, the following output (from ps):
1637+
1638+ -p PID, --pid=PID List the process PID
1639+ --pgrp=PGRP List processes in the process group PGRP
1640+ -P, -x, --no-parent Include processes without parents
1641+ -Q, --all-fields Don't elide unusable fields (normally if there's
1642+ some reason ps can't print a field for any
1643+ process, it's removed from the output entirely)
1644+ -r, --reverse, --gratuitously-long-reverse-option
1645+ Reverse the order of any sort
1646+ --session[=SID] Add the processes from the session SID (which
1647+ defaults to the sid of the current process)
1648+
1649+ Here are some more options:
1650+ -f ZOT, --foonly=ZOT Glork a foonly
1651+ -z, --zaza Snit a zar
1652+
1653+ -?, --help Give this help list
1654+ --usage Give a short usage message
1655+ -V, --version Print program version
1656+
1657+ The struct argp_option array for the above could look like:
1658+
1659+ {
1660+ {"pid", 'p', "PID", 0, "List the process PID"},
1661+ {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
1662+ {"no-parent", 'P', 0, 0, "Include processes without parents"},
1663+ {0, 'x', 0, OPTION_ALIAS},
1664+ {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
1665+ " if there's some reason ps can't"
1666+ " print a field for any process, it's"
1667+ " removed from the output entirely)" },
1668+ {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
1669+ {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
1670+ {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
1671+ "Add the processes from the session"
1672+ " SID (which defaults to the sid of"
1673+ " the current process)" },
1674+
1675+ {0,0,0,0, "Here are some more options:"},
1676+ {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
1677+ {"zaza", 'z', 0, 0, "Snit a zar"},
1678+
1679+ {0}
1680+ }
1681+
1682+ Note that the last three options are automatically supplied by argp_parse,
1683+ unless you tell it not to with ARGP_NO_HELP.
1684+
1685+*/
1686+
1687+/* Returns true if CH occurs between BEG and END. */
1688+static int
1689+find_char (char ch, char *beg, char *end)
1690+{
1691+ while (beg < end)
1692+ if (*beg == ch)
1693+ return 1;
1694+ else
1695+ beg++;
1696+ return 0;
1697+}
1698+
1699+struct hol_cluster; /* fwd decl */
1700+
1701+struct hol_entry
1702+{
1703+ /* First option. */
1704+ const struct argp_option *opt;
1705+ /* Number of options (including aliases). */
1706+ unsigned num;
1707+
1708+ /* A pointers into the HOL's short_options field, to the first short option
1709+ letter for this entry. The order of the characters following this point
1710+ corresponds to the order of options pointed to by OPT, and there are at
1711+ most NUM. A short option recorded in a option following OPT is only
1712+ valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
1713+ probably been shadowed by some other entry). */
1714+ char *short_options;
1715+
1716+ /* Entries are sorted by their group first, in the order:
1717+ 1, 2, ..., n, 0, -m, ..., -2, -1
1718+ and then alphabetically within each group. The default is 0. */
1719+ int group;
1720+
1721+ /* The cluster of options this entry belongs to, or 0 if none. */
1722+ struct hol_cluster *cluster;
1723+
1724+ /* The argp from which this option came. */
1725+ const struct argp *argp;
1726+};
1727+
1728+/* A cluster of entries to reflect the argp tree structure. */
1729+struct hol_cluster
1730+{
1731+ /* A descriptive header printed before options in this cluster. */
1732+ const char *header;
1733+
1734+ /* Used to order clusters within the same group with the same parent,
1735+ according to the order in which they occurred in the parent argp's child
1736+ list. */
1737+ int index;
1738+
1739+ /* How to sort this cluster with respect to options and other clusters at the
1740+ same depth (clusters always follow options in the same group). */
1741+ int group;
1742+
1743+ /* The cluster to which this cluster belongs, or 0 if it's at the base
1744+ level. */
1745+ struct hol_cluster *parent;
1746+
1747+ /* The argp from which this cluster is (eventually) derived. */
1748+ const struct argp *argp;
1749+
1750+ /* The distance this cluster is from the root. */
1751+ int depth;
1752+
1753+ /* Clusters in a given hol are kept in a linked list, to make freeing them
1754+ possible. */
1755+ struct hol_cluster *next;
1756+};
1757+
1758+/* A list of options for help. */
1759+struct hol
1760+{
1761+ /* An array of hol_entry's. */
1762+ struct hol_entry *entries;
1763+ /* The number of entries in this hol. If this field is zero, the others
1764+ are undefined. */
1765+ unsigned num_entries;
1766+
1767+ /* A string containing all short options in this HOL. Each entry contains
1768+ pointers into this string, so the order can't be messed with blindly. */
1769+ char *short_options;
1770+
1771+ /* Clusters of entries in this hol. */
1772+ struct hol_cluster *clusters;
1773+};
1774+
1775+/* Create a struct hol from the options in ARGP. CLUSTER is the
1776+ hol_cluster in which these entries occur, or 0, if at the root. */
1777+static struct hol *
1778+make_hol (const struct argp *argp, struct hol_cluster *cluster)
1779+{
1780+ char *so;
1781+ const struct argp_option *o;
1782+ const struct argp_option *opts = argp->options;
1783+ struct hol_entry *entry;
1784+ unsigned num_short_options = 0;
1785+ struct hol *hol = malloc (sizeof (struct hol));
1786+
1787+ assert (hol);
1788+
1789+ hol->num_entries = 0;
1790+ hol->clusters = 0;
1791+
1792+ if (opts)
1793+ {
1794+ int cur_group = 0;
1795+
1796+ /* The first option must not be an alias. */
1797+ assert (! oalias (opts));
1798+
1799+ /* Calculate the space needed. */
1800+ for (o = opts; ! oend (o); o++)
1801+ {
1802+ if (! oalias (o))
1803+ hol->num_entries++;
1804+ if (oshort (o))
1805+ num_short_options++; /* This is an upper bound. */
1806+ }
1807+
1808+ hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
1809+ hol->short_options = malloc (num_short_options + 1);
1810+
1811+ assert (hol->entries && hol->short_options);
1812+#if SIZE_MAX <= UINT_MAX
1813+ assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
1814+#endif
1815+
1816+ /* Fill in the entries. */
1817+ so = hol->short_options;
1818+ for (o = opts, entry = hol->entries; ! oend (o); entry++)
1819+ {
1820+ entry->opt = o;
1821+ entry->num = 0;
1822+ entry->short_options = so;
1823+ entry->group = cur_group =
1824+ o->group
1825+ ? o->group
1826+ : ((!o->name && !o->key)
1827+ ? cur_group + 1
1828+ : cur_group);
1829+ entry->cluster = cluster;
1830+ entry->argp = argp;
1831+
1832+ do
1833+ {
1834+ entry->num++;
1835+ if (oshort (o) && ! find_char (o->key, hol->short_options, so))
1836+ /* O has a valid short option which hasn't already been used.*/
1837+ *so++ = o->key;
1838+ o++;
1839+ }
1840+ while (! oend (o) && oalias (o));
1841+ }
1842+ *so = '\0'; /* null terminated so we can find the length */
1843+ }
1844+
1845+ return hol;
1846+}
1847+
1848+/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
1849+ associated argp child list entry), INDEX, and PARENT, and return a pointer
1850+ to it. ARGP is the argp that this cluster results from. */
1851+static struct hol_cluster *
1852+hol_add_cluster (struct hol *hol, int group, const char *header, int index,
1853+ struct hol_cluster *parent, const struct argp *argp)
1854+{
1855+ struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
1856+ if (cl)
1857+ {
1858+ cl->group = group;
1859+ cl->header = header;
1860+
1861+ cl->index = index;
1862+ cl->parent = parent;
1863+ cl->argp = argp;
1864+ cl->depth = parent ? parent->depth + 1 : 0;
1865+
1866+ cl->next = hol->clusters;
1867+ hol->clusters = cl;
1868+ }
1869+ return cl;
1870+}
1871+
1872+/* Free HOL and any resources it uses. */
1873+static void
1874+hol_free (struct hol *hol)
1875+{
1876+ struct hol_cluster *cl = hol->clusters;
1877+
1878+ while (cl)
1879+ {
1880+ struct hol_cluster *next = cl->next;
1881+ free (cl);
1882+ cl = next;
1883+ }
1884+
1885+ if (hol->num_entries > 0)
1886+ {
1887+ free (hol->entries);
1888+ free (hol->short_options);
1889+ }
1890+
1891+ free (hol);
1892+}
1893+
1894+static int
1895+hol_entry_short_iterate (const struct hol_entry *entry,
1896+ int (*func)(const struct argp_option *opt,
1897+ const struct argp_option *real,
1898+ const char *domain, void *cookie),
1899+ const char *domain, void *cookie)
1900+{
1901+ unsigned nopts;
1902+ int val = 0;
1903+ const struct argp_option *opt, *real = entry->opt;
1904+ char *so = entry->short_options;
1905+
1906+ for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
1907+ if (oshort (opt) && *so == opt->key)
1908+ {
1909+ if (!oalias (opt))
1910+ real = opt;
1911+ if (ovisible (opt))
1912+ val = (*func)(opt, real, domain, cookie);
1913+ so++;
1914+ }
1915+
1916+ return val;
1917+}
1918+
1919+static __inline__ int
1920+__attribute__ ((always_inline))
1921+hol_entry_long_iterate (const struct hol_entry *entry,
1922+ int (*func)(const struct argp_option *opt,
1923+ const struct argp_option *real,
1924+ const char *domain, void *cookie),
1925+ const char *domain, void *cookie)
1926+{
1927+ unsigned nopts;
1928+ int val = 0;
1929+ const struct argp_option *opt, *real = entry->opt;
1930+
1931+ for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
1932+ if (opt->name)
1933+ {
1934+ if (!oalias (opt))
1935+ real = opt;
1936+ if (ovisible (opt))
1937+ val = (*func)(opt, real, domain, cookie);
1938+ }
1939+
1940+ return val;
1941+}
1942+
1943+/* Iterator that returns true for the first short option. */
1944+static __inline__ int
1945+until_short (const struct argp_option *opt, const struct argp_option *real,
1946+ const char *domain, void *cookie)
1947+{
1948+ return oshort (opt) ? opt->key : 0;
1949+}
1950+
1951+/* Returns the first valid short option in ENTRY, or 0 if there is none. */
1952+static char
1953+hol_entry_first_short (const struct hol_entry *entry)
1954+{
1955+ return hol_entry_short_iterate (entry, until_short,
1956+ entry->argp->argp_domain, 0);
1957+}
1958+
1959+/* Returns the first valid long option in ENTRY, or 0 if there is none. */
1960+static const char *
1961+hol_entry_first_long (const struct hol_entry *entry)
1962+{
1963+ const struct argp_option *opt;
1964+ unsigned num;
1965+ for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
1966+ if (opt->name && ovisible (opt))
1967+ return opt->name;
1968+ return 0;
1969+}
1970+
1971+/* Returns the entry in HOL with the long option name NAME, or 0 if there is
1972+ none. */
1973+static struct hol_entry *
1974+hol_find_entry (struct hol *hol, const char *name)
1975+{
1976+ struct hol_entry *entry = hol->entries;
1977+ unsigned num_entries = hol->num_entries;
1978+
1979+ while (num_entries-- > 0)
1980+ {
1981+ const struct argp_option *opt = entry->opt;
1982+ unsigned num_opts = entry->num;
1983+
1984+ while (num_opts-- > 0)
1985+ if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
1986+ return entry;
1987+ else
1988+ opt++;
1989+
1990+ entry++;
1991+ }
1992+
1993+ return 0;
1994+}
1995+
1996+/* If an entry with the long option NAME occurs in HOL, set it's special
1997+ sort position to GROUP. */
1998+static void
1999+hol_set_group (struct hol *hol, const char *name, int group)
2000+{
2001+ struct hol_entry *entry = hol_find_entry (hol, name);
2002+ if (entry)
2003+ entry->group = group;
2004+}
2005+
2006+/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
2007+ EQ is what to return if GROUP1 and GROUP2 are the same. */
2008+static int
2009+group_cmp (int group1, int group2, int eq)
2010+{
2011+ if (group1 == group2)
2012+ return eq;
2013+ else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
2014+ return group1 - group2;
2015+ else
2016+ return group2 - group1;
2017+}
2018+
2019+/* Compare clusters CL1 & CL2 by the order that they should appear in
2020+ output. */
2021+static int
2022+hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
2023+{
2024+ /* If one cluster is deeper than the other, use its ancestor at the same
2025+ level, so that finding the common ancestor is straightforward. */
2026+ while (cl1->depth > cl2->depth)
2027+ cl1 = cl1->parent;
2028+ while (cl2->depth > cl1->depth)
2029+ cl2 = cl2->parent;
2030+
2031+ /* Now reduce both clusters to their ancestors at the point where both have
2032+ a common parent; these can be directly compared. */
2033+ while (cl1->parent != cl2->parent)
2034+ cl1 = cl1->parent, cl2 = cl2->parent;
2035+
2036+ return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
2037+}
2038+
2039+/* Return the ancestor of CL that's just below the root (i.e., has a parent
2040+ of 0). */
2041+static struct hol_cluster *
2042+hol_cluster_base (struct hol_cluster *cl)
2043+{
2044+ while (cl->parent)
2045+ cl = cl->parent;
2046+ return cl;
2047+}
2048+
2049+/* Return true if CL1 is a child of CL2. */
2050+static int
2051+hol_cluster_is_child (const struct hol_cluster *cl1,
2052+ const struct hol_cluster *cl2)
2053+{
2054+ while (cl1 && cl1 != cl2)
2055+ cl1 = cl1->parent;
2056+ return cl1 == cl2;
2057+}
2058+
2059+/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
2060+ that should be used for comparisons, and returns true iff it should be
2061+ treated as a non-option. */
2062+static int
2063+canon_doc_option (const char **name)
2064+{
2065+ int non_opt;
2066+ /* Skip initial whitespace. */
2067+ while (isspace (**name))
2068+ (*name)++;
2069+ /* Decide whether this looks like an option (leading `-') or not. */
2070+ non_opt = (**name != '-');
2071+ /* Skip until part of name used for sorting. */
2072+ while (**name && !isalnum (**name))
2073+ (*name)++;
2074+ return non_opt;
2075+}
2076+
2077+/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
2078+ listing. */
2079+static int
2080+hol_entry_cmp (const struct hol_entry *entry1,
2081+ const struct hol_entry *entry2)
2082+{
2083+ /* The group numbers by which the entries should be ordered; if either is
2084+ in a cluster, then this is just the group within the cluster. */
2085+ int group1 = entry1->group, group2 = entry2->group;
2086+
2087+ if (entry1->cluster != entry2->cluster)
2088+ {
2089+ /* The entries are not within the same cluster, so we can't compare them
2090+ directly, we have to use the appropiate clustering level too. */
2091+ if (! entry1->cluster)
2092+ /* ENTRY1 is at the `base level', not in a cluster, so we have to
2093+ compare it's group number with that of the base cluster in which
2094+ ENTRY2 resides. Note that if they're in the same group, the
2095+ clustered option always comes laster. */
2096+ return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
2097+ else if (! entry2->cluster)
2098+ /* Likewise, but ENTRY2's not in a cluster. */
2099+ return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
2100+ else
2101+ /* Both entries are in clusters, we can just compare the clusters. */
2102+ return hol_cluster_cmp (entry1->cluster, entry2->cluster);
2103+ }
2104+ else if (group1 == group2)
2105+ /* The entries are both in the same cluster and group, so compare them
2106+ alphabetically. */
2107+ {
2108+ int short1 = hol_entry_first_short (entry1);
2109+ int short2 = hol_entry_first_short (entry2);
2110+ int doc1 = odoc (entry1->opt);
2111+ int doc2 = odoc (entry2->opt);
2112+ const char *long1 = hol_entry_first_long (entry1);
2113+ const char *long2 = hol_entry_first_long (entry2);
2114+
2115+ if (doc1)
2116+ doc1 = long1 != NULL && canon_doc_option (&long1);
2117+ if (doc2)
2118+ doc2 = long2 != NULL && canon_doc_option (&long2);
2119+
2120+ if (doc1 != doc2)
2121+ /* `documentation' options always follow normal options (or
2122+ documentation options that *look* like normal options). */
2123+ return doc1 - doc2;
2124+ else if (!short1 && !short2 && long1 && long2)
2125+ /* Only long options. */
2126+ return strcasecmp (long1, long2);
2127+ else
2128+ /* Compare short/short, long/short, short/long, using the first
2129+ character of long options. Entries without *any* valid
2130+ options (such as options with OPTION_HIDDEN set) will be put
2131+ first, but as they're not displayed, it doesn't matter where
2132+ they are. */
2133+ {
2134+ char first1 = short1 ? short1 : long1 ? *long1 : 0;
2135+ char first2 = short2 ? short2 : long2 ? *long2 : 0;
2136+#ifdef _tolower
2137+ int lower_cmp = _tolower (first1) - _tolower (first2);
2138+#else
2139+ int lower_cmp = tolower (first1) - tolower (first2);
2140+#endif
2141+ /* Compare ignoring case, except when the options are both the
2142+ same letter, in which case lower-case always comes first. */
2143+ return lower_cmp ? lower_cmp : first2 - first1;
2144+ }
2145+ }
2146+ else
2147+ /* Within the same cluster, but not the same group, so just compare
2148+ groups. */
2149+ return group_cmp (group1, group2, 0);
2150+}
2151+
2152+/* Version of hol_entry_cmp with correct signature for qsort. */
2153+static int
2154+hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
2155+{
2156+ return hol_entry_cmp (entry1_v, entry2_v);
2157+}
2158+
2159+/* Sort HOL by group and alphabetically by option name (with short options
2160+ taking precedence over long). Since the sorting is for display purposes
2161+ only, the shadowing of options isn't effected. */
2162+static void
2163+hol_sort (struct hol *hol)
2164+{
2165+ if (hol->num_entries > 0)
2166+ qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
2167+ hol_entry_qcmp);
2168+}
2169+
2170+/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
2171+ any in MORE with the same name. */
2172+static void
2173+hol_append (struct hol *hol, struct hol *more)
2174+{
2175+ struct hol_cluster **cl_end = &hol->clusters;
2176+
2177+ /* Steal MORE's cluster list, and add it to the end of HOL's. */
2178+ while (*cl_end)
2179+ cl_end = &(*cl_end)->next;
2180+ *cl_end = more->clusters;
2181+ more->clusters = 0;
2182+
2183+ /* Merge entries. */
2184+ if (more->num_entries > 0)
2185+ {
2186+ if (hol->num_entries == 0)
2187+ {
2188+ hol->num_entries = more->num_entries;
2189+ hol->entries = more->entries;
2190+ hol->short_options = more->short_options;
2191+ more->num_entries = 0; /* Mark MORE's fields as invalid. */
2192+ }
2193+ else
2194+ /* Append the entries in MORE to those in HOL, taking care to only add
2195+ non-shadowed SHORT_OPTIONS values. */
2196+ {
2197+ unsigned left;
2198+ char *so, *more_so;
2199+ struct hol_entry *e;
2200+ unsigned num_entries = hol->num_entries + more->num_entries;
2201+ struct hol_entry *entries =
2202+ malloc (num_entries * sizeof (struct hol_entry));
2203+ unsigned hol_so_len = strlen (hol->short_options);
2204+ char *short_options =
2205+ malloc (hol_so_len + strlen (more->short_options) + 1);
2206+
2207+ assert (entries && short_options);
2208+#if SIZE_MAX <= UINT_MAX
2209+ assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
2210+#endif
2211+
2212+ mempcpy (mempcpy (entries, hol->entries,
2213+ hol->num_entries * sizeof (struct hol_entry)),
2214+ more->entries,
2215+ more->num_entries * sizeof (struct hol_entry));
2216+
2217+ mempcpy (short_options, hol->short_options, hol_so_len);
2218+
2219+ /* Fix up the short options pointers from HOL. */
2220+ for (e = entries, left = hol->num_entries; left > 0; e++, left--)
2221+ e->short_options += (short_options - hol->short_options);
2222+
2223+ /* Now add the short options from MORE, fixing up its entries
2224+ too. */
2225+ so = short_options + hol_so_len;
2226+ more_so = more->short_options;
2227+ for (left = more->num_entries; left > 0; e++, left--)
2228+ {
2229+ int opts_left;
2230+ const struct argp_option *opt;
2231+
2232+ e->short_options = so;
2233+
2234+ for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
2235+ {
2236+ int ch = *more_so;
2237+ if (oshort (opt) && ch == opt->key)
2238+ /* The next short option in MORE_SO, CH, is from OPT. */
2239+ {
2240+ if (! find_char (ch, short_options,
2241+ short_options + hol_so_len))
2242+ /* The short option CH isn't shadowed by HOL's options,
2243+ so add it to the sum. */
2244+ *so++ = ch;
2245+ more_so++;
2246+ }
2247+ }
2248+ }
2249+
2250+ *so = '\0';
2251+
2252+ free (hol->entries);
2253+ free (hol->short_options);
2254+
2255+ hol->entries = entries;
2256+ hol->num_entries = num_entries;
2257+ hol->short_options = short_options;
2258+ }
2259+ }
2260+
2261+ hol_free (more);
2262+}
2263+
2264+/* Inserts enough spaces to make sure STREAM is at column COL. */
2265+static void
2266+indent_to (argp_fmtstream_t stream, unsigned col)
2267+{
2268+ int needed = col - __argp_fmtstream_point (stream);
2269+ while (needed-- > 0)
2270+ __argp_fmtstream_putc (stream, ' ');
2271+}
2272+
2273+/* Output to STREAM either a space, or a newline if there isn't room for at
2274+ least ENSURE characters before the right margin. */
2275+static void
2276+space (argp_fmtstream_t stream, size_t ensure)
2277+{
2278+ if (__argp_fmtstream_point (stream) + ensure
2279+ >= __argp_fmtstream_rmargin (stream))
2280+ __argp_fmtstream_putc (stream, '\n');
2281+ else
2282+ __argp_fmtstream_putc (stream, ' ');
2283+}
2284+
2285+/* If the option REAL has an argument, we print it in using the printf
2286+ format REQ_FMT or OPT_FMT depending on whether it's a required or
2287+ optional argument. */
2288+static void
2289+arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
2290+ const char *domain, argp_fmtstream_t stream)
2291+{
2292+ if (real->arg)
2293+ {
2294+ if (real->flags & OPTION_ARG_OPTIONAL)
2295+ __argp_fmtstream_printf (stream, opt_fmt,
2296+ dgettext (domain, real->arg));
2297+ else
2298+ __argp_fmtstream_printf (stream, req_fmt,
2299+ dgettext (domain, real->arg));
2300+ }
2301+}
2302+
2303+/* Helper functions for hol_entry_help. */
2304+
2305+/* State used during the execution of hol_help. */
2306+struct hol_help_state
2307+{
2308+ /* PREV_ENTRY should contain the previous entry printed, or 0. */
2309+ struct hol_entry *prev_entry;
2310+
2311+ /* If an entry is in a different group from the previous one, and SEP_GROUPS
2312+ is true, then a blank line will be printed before any output. */
2313+ int sep_groups;
2314+
2315+ /* True if a duplicate option argument was suppressed (only ever set if
2316+ UPARAMS.dup_args is false). */
2317+ int suppressed_dup_arg;
2318+};
2319+
2320+/* Some state used while printing a help entry (used to communicate with
2321+ helper functions). See the doc for hol_entry_help for more info, as most
2322+ of the fields are copied from its arguments. */
2323+struct pentry_state
2324+{
2325+ const struct hol_entry *entry;
2326+ argp_fmtstream_t stream;
2327+ struct hol_help_state *hhstate;
2328+
2329+ /* True if nothing's been printed so far. */
2330+ int first;
2331+
2332+ /* If non-zero, the state that was used to print this help. */
2333+ const struct argp_state *state;
2334+};
2335+
2336+/* If a user doc filter should be applied to DOC, do so. */
2337+static const char *
2338+filter_doc (const char *doc, int key, const struct argp *argp,
2339+ const struct argp_state *state)
2340+{
2341+ if (argp && argp->help_filter)
2342+ /* We must apply a user filter to this output. */
2343+ {
2344+ void *input = __argp_input (argp, state);
2345+ return (*argp->help_filter) (key, doc, input);
2346+ }
2347+ else
2348+ /* No filter. */
2349+ return doc;
2350+}
2351+
2352+/* Prints STR as a header line, with the margin lines set appropiately, and
2353+ notes the fact that groups should be separated with a blank line. ARGP is
2354+ the argp that should dictate any user doc filtering to take place. Note
2355+ that the previous wrap margin isn't restored, but the left margin is reset
2356+ to 0. */
2357+static void
2358+print_header (const char *str, const struct argp *argp,
2359+ struct pentry_state *pest)
2360+{
2361+ const char *tstr = dgettext (argp->argp_domain, str);
2362+ const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
2363+
2364+ if (fstr)
2365+ {
2366+ if (*fstr)
2367+ {
2368+ if (pest->hhstate->prev_entry)
2369+ /* Precede with a blank line. */
2370+ __argp_fmtstream_putc (pest->stream, '\n');
2371+ indent_to (pest->stream, uparams.header_col);
2372+ __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
2373+ __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
2374+ __argp_fmtstream_puts (pest->stream, fstr);
2375+ __argp_fmtstream_set_lmargin (pest->stream, 0);
2376+ __argp_fmtstream_putc (pest->stream, '\n');
2377+ }
2378+
2379+ pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
2380+ }
2381+
2382+ if (fstr != tstr)
2383+ free ((char *) fstr);
2384+}
2385+
2386+/* Inserts a comma if this isn't the first item on the line, and then makes
2387+ sure we're at least to column COL. If this *is* the first item on a line,
2388+ prints any pending whitespace/headers that should precede this line. Also
2389+ clears FIRST. */
2390+static void
2391+comma (unsigned col, struct pentry_state *pest)
2392+{
2393+ if (pest->first)
2394+ {
2395+ const struct hol_entry *pe = pest->hhstate->prev_entry;
2396+ const struct hol_cluster *cl = pest->entry->cluster;
2397+
2398+ if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
2399+ __argp_fmtstream_putc (pest->stream, '\n');
2400+
2401+ if (cl && cl->header && *cl->header
2402+ && (!pe
2403+ || (pe->cluster != cl
2404+ && !hol_cluster_is_child (pe->cluster, cl))))
2405+ /* If we're changing clusters, then this must be the start of the
2406+ ENTRY's cluster unless that is an ancestor of the previous one
2407+ (in which case we had just popped into a sub-cluster for a bit).
2408+ If so, then print the cluster's header line. */
2409+ {
2410+ int old_wm = __argp_fmtstream_wmargin (pest->stream);
2411+ print_header (cl->header, cl->argp, pest);
2412+ __argp_fmtstream_set_wmargin (pest->stream, old_wm);
2413+ }
2414+
2415+ pest->first = 0;
2416+ }
2417+ else
2418+ __argp_fmtstream_puts (pest->stream, ", ");
2419+
2420+ indent_to (pest->stream, col);
2421+}
2422+
2423+/* Print help for ENTRY to STREAM. */
2424+static void
2425+hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
2426+ argp_fmtstream_t stream, struct hol_help_state *hhstate)
2427+{
2428+ unsigned num;
2429+ const struct argp_option *real = entry->opt, *opt;
2430+ char *so = entry->short_options;
2431+ int have_long_opt = 0; /* We have any long options. */
2432+ /* Saved margins. */
2433+ int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
2434+ int old_wm = __argp_fmtstream_wmargin (stream);
2435+ /* PEST is a state block holding some of our variables that we'd like to
2436+ share with helper functions. */
2437+ struct pentry_state pest = { entry, stream, hhstate, 1, state };
2438+
2439+ if (! odoc (real))
2440+ for (opt = real, num = entry->num; num > 0; opt++, num--)
2441+ if (opt->name && ovisible (opt))
2442+ {
2443+ have_long_opt = 1;
2444+ break;
2445+ }
2446+
2447+ /* First emit short options. */
2448+ __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
2449+ for (opt = real, num = entry->num; num > 0; opt++, num--)
2450+ if (oshort (opt) && opt->key == *so)
2451+ /* OPT has a valid (non shadowed) short option. */
2452+ {
2453+ if (ovisible (opt))
2454+ {
2455+ comma (uparams.short_opt_col, &pest);
2456+ __argp_fmtstream_putc (stream, '-');
2457+ __argp_fmtstream_putc (stream, *so);
2458+ if (!have_long_opt || uparams.dup_args)
2459+ arg (real, " %s", "[%s]",
2460+ state == NULL ? NULL : state->root_argp->argp_domain,
2461+ stream);
2462+ else if (real->arg)
2463+ hhstate->suppressed_dup_arg = 1;
2464+ }
2465+ so++;
2466+ }
2467+
2468+ /* Now, long options. */
2469+ if (odoc (real))
2470+ /* A `documentation' option. */
2471+ {
2472+ __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
2473+ for (opt = real, num = entry->num; num > 0; opt++, num--)
2474+ if (opt->name && ovisible (opt))
2475+ {
2476+ comma (uparams.doc_opt_col, &pest);
2477+ /* Calling gettext here isn't quite right, since sorting will
2478+ have been done on the original; but documentation options
2479+ should be pretty rare anyway... */
2480+ __argp_fmtstream_puts (stream,
2481+ dgettext (state == NULL ? NULL
2482+ : state->root_argp->argp_domain,
2483+ opt->name));
2484+ }
2485+ }
2486+ else
2487+ /* A real long option. */
2488+ {
2489+ __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
2490+ for (opt = real, num = entry->num; num > 0; opt++, num--)
2491+ if (opt->name && ovisible (opt))
2492+ {
2493+ comma (uparams.long_opt_col, &pest);
2494+ __argp_fmtstream_printf (stream, "--%s", opt->name);
2495+ arg (real, "=%s", "[=%s]",
2496+ state == NULL ? NULL : state->root_argp->argp_domain, stream);
2497+ }
2498+ }
2499+
2500+ /* Next, documentation strings. */
2501+ __argp_fmtstream_set_lmargin (stream, 0);
2502+
2503+ if (pest.first)
2504+ {
2505+ /* Didn't print any switches, what's up? */
2506+ if (!oshort (real) && !real->name)
2507+ /* This is a group header, print it nicely. */
2508+ print_header (real->doc, entry->argp, &pest);
2509+ else
2510+ /* Just a totally shadowed option or null header; print nothing. */
2511+ goto cleanup; /* Just return, after cleaning up. */
2512+ }
2513+ else
2514+ {
2515+ const char *tstr = real->doc ? dgettext (state == NULL ? NULL
2516+ : state->root_argp->argp_domain,
2517+ real->doc) : 0;
2518+ const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
2519+ if (fstr && *fstr)
2520+ {
2521+ unsigned int col = __argp_fmtstream_point (stream);
2522+
2523+ __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
2524+ __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
2525+
2526+ if (col > (unsigned int) (uparams.opt_doc_col + 3))
2527+ __argp_fmtstream_putc (stream, '\n');
2528+ else if (col >= (unsigned int) uparams.opt_doc_col)
2529+ __argp_fmtstream_puts (stream, " ");
2530+ else
2531+ indent_to (stream, uparams.opt_doc_col);
2532+
2533+ __argp_fmtstream_puts (stream, fstr);
2534+ }
2535+ if (fstr && fstr != tstr)
2536+ free ((char *) fstr);
2537+
2538+ /* Reset the left margin. */
2539+ __argp_fmtstream_set_lmargin (stream, 0);
2540+ __argp_fmtstream_putc (stream, '\n');
2541+ }
2542+
2543+ hhstate->prev_entry = entry;
2544+
2545+cleanup:
2546+ __argp_fmtstream_set_lmargin (stream, old_lm);
2547+ __argp_fmtstream_set_wmargin (stream, old_wm);
2548+}
2549+
2550+/* Output a long help message about the options in HOL to STREAM. */
2551+static void
2552+hol_help (struct hol *hol, const struct argp_state *state,
2553+ argp_fmtstream_t stream)
2554+{
2555+ unsigned num;
2556+ struct hol_entry *entry;
2557+ struct hol_help_state hhstate = { 0, 0, 0 };
2558+
2559+ for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
2560+ hol_entry_help (entry, state, stream, &hhstate);
2561+
2562+ if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
2563+ {
2564+ const char *tstr = dgettext (state == NULL ? NULL
2565+ : state->root_argp->argp_domain, "\
2566+Mandatory or optional arguments to long options are also mandatory or \
2567+optional for any corresponding short options.");
2568+ const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
2569+ state ? state->root_argp : 0, state);
2570+ if (fstr && *fstr)
2571+ {
2572+ __argp_fmtstream_putc (stream, '\n');
2573+ __argp_fmtstream_puts (stream, fstr);
2574+ __argp_fmtstream_putc (stream, '\n');
2575+ }
2576+ if (fstr && fstr != tstr)
2577+ free ((char *) fstr);
2578+ }
2579+}
2580+
2581+/* Helper functions for hol_usage. */
2582+
2583+/* If OPT is a short option without an arg, append its key to the string
2584+ pointer pointer to by COOKIE, and advance the pointer. */
2585+static int
2586+add_argless_short_opt (const struct argp_option *opt,
2587+ const struct argp_option *real,
2588+ const char *domain, void *cookie)
2589+{
2590+ char **snao_end = cookie;
2591+ if (!(opt->arg || real->arg)
2592+ && !((opt->flags | real->flags) & OPTION_NO_USAGE))
2593+ *(*snao_end)++ = opt->key;
2594+ return 0;
2595+}
2596+
2597+/* If OPT is a short option with an arg, output a usage entry for it to the
2598+ stream pointed at by COOKIE. */
2599+static int
2600+usage_argful_short_opt (const struct argp_option *opt,
2601+ const struct argp_option *real,
2602+ const char *domain, void *cookie)
2603+{
2604+ argp_fmtstream_t stream = cookie;
2605+ const char *arg = opt->arg;
2606+ int flags = opt->flags | real->flags;
2607+
2608+ if (! arg)
2609+ arg = real->arg;
2610+
2611+ if (arg && !(flags & OPTION_NO_USAGE))
2612+ {
2613+ arg = dgettext (domain, arg);
2614+
2615+ if (flags & OPTION_ARG_OPTIONAL)
2616+ __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
2617+ else
2618+ {
2619+ /* Manually do line wrapping so that it (probably) won't
2620+ get wrapped at the embedded space. */
2621+ space (stream, 6 + strlen (arg));
2622+ __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
2623+ }
2624+ }
2625+
2626+ return 0;
2627+}
2628+
2629+/* Output a usage entry for the long option opt to the stream pointed at by
2630+ COOKIE. */
2631+static int
2632+usage_long_opt (const struct argp_option *opt,
2633+ const struct argp_option *real,
2634+ const char *domain, void *cookie)
2635+{
2636+ argp_fmtstream_t stream = cookie;
2637+ const char *arg = opt->arg;
2638+ int flags = opt->flags | real->flags;
2639+
2640+ if (! arg)
2641+ arg = real->arg;
2642+
2643+ if (! (flags & OPTION_NO_USAGE))
2644+ {
2645+ if (arg)
2646+ {
2647+ arg = dgettext (domain, arg);
2648+ if (flags & OPTION_ARG_OPTIONAL)
2649+ __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
2650+ else
2651+ __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
2652+ }
2653+ else
2654+ __argp_fmtstream_printf (stream, " [--%s]", opt->name);
2655+ }
2656+
2657+ return 0;
2658+}
2659+
2660+/* Print a short usage description for the arguments in HOL to STREAM. */
2661+static void
2662+hol_usage (struct hol *hol, argp_fmtstream_t stream)
2663+{
2664+ if (hol->num_entries > 0)
2665+ {
2666+ unsigned nentries;
2667+ struct hol_entry *entry;
2668+ char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
2669+ char *snao_end = short_no_arg_opts;
2670+
2671+ /* First we put a list of short options without arguments. */
2672+ for (entry = hol->entries, nentries = hol->num_entries
2673+ ; nentries > 0
2674+ ; entry++, nentries--)
2675+ hol_entry_short_iterate (entry, add_argless_short_opt,
2676+ entry->argp->argp_domain, &snao_end);
2677+ if (snao_end > short_no_arg_opts)
2678+ {
2679+ *snao_end++ = 0;
2680+ __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
2681+ }
2682+
2683+ /* Now a list of short options *with* arguments. */
2684+ for (entry = hol->entries, nentries = hol->num_entries
2685+ ; nentries > 0
2686+ ; entry++, nentries--)
2687+ hol_entry_short_iterate (entry, usage_argful_short_opt,
2688+ entry->argp->argp_domain, stream);
2689+
2690+ /* Finally, a list of long options (whew!). */
2691+ for (entry = hol->entries, nentries = hol->num_entries
2692+ ; nentries > 0
2693+ ; entry++, nentries--)
2694+ hol_entry_long_iterate (entry, usage_long_opt,
2695+ entry->argp->argp_domain, stream);
2696+ }
2697+}
2698+
2699+/* Make a HOL containing all levels of options in ARGP. CLUSTER is the
2700+ cluster in which ARGP's entries should be clustered, or 0. */
2701+static struct hol *
2702+argp_hol (const struct argp *argp, struct hol_cluster *cluster)
2703+{
2704+ const struct argp_child *child = argp->children;
2705+ struct hol *hol = make_hol (argp, cluster);
2706+ if (child)
2707+ while (child->argp)
2708+ {
2709+ struct hol_cluster *child_cluster =
2710+ ((child->group || child->header)
2711+ /* Put CHILD->argp within its own cluster. */
2712+ ? hol_add_cluster (hol, child->group, child->header,
2713+ child - argp->children, cluster, argp)
2714+ /* Just merge it into the parent's cluster. */
2715+ : cluster);
2716+ hol_append (hol, argp_hol (child->argp, child_cluster)) ;
2717+ child++;
2718+ }
2719+ return hol;
2720+}
2721+
2722+/* Calculate how many different levels with alternative args strings exist in
2723+ ARGP. */
2724+static size_t
2725+argp_args_levels (const struct argp *argp)
2726+{
2727+ size_t levels = 0;
2728+ const struct argp_child *child = argp->children;
2729+
2730+ if (argp->args_doc && strchr (argp->args_doc, '\n'))
2731+ levels++;
2732+
2733+ if (child)
2734+ while (child->argp)
2735+ levels += argp_args_levels ((child++)->argp);
2736+
2737+ return levels;
2738+}
2739+
2740+/* Print all the non-option args documented in ARGP to STREAM. Any output is
2741+ preceded by a space. LEVELS is a pointer to a byte vector the length
2742+ returned by argp_args_levels; it should be initialized to zero, and
2743+ updated by this routine for the next call if ADVANCE is true. True is
2744+ returned as long as there are more patterns to output. */
2745+static int
2746+argp_args_usage (const struct argp *argp, const struct argp_state *state,
2747+ char **levels, int advance, argp_fmtstream_t stream)
2748+{
2749+ char *our_level = *levels;
2750+ int multiple = 0;
2751+ const struct argp_child *child = argp->children;
2752+ const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
2753+ const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
2754+
2755+ if (fdoc)
2756+ {
2757+ const char *cp = fdoc;
2758+ nl = strchrnul (cp, '\n');
2759+ if (*nl != '\0')
2760+ /* This is a `multi-level' args doc; advance to the correct position
2761+ as determined by our state in LEVELS, and update LEVELS. */
2762+ {
2763+ int i;
2764+ multiple = 1;
2765+ for (i = 0; i < *our_level; i++)
2766+ cp = nl + 1, nl = strchrnul (cp, '\n');
2767+ (*levels)++;
2768+ }
2769+
2770+ /* Manually do line wrapping so that it (probably) won't get wrapped at
2771+ any embedded spaces. */
2772+ space (stream, 1 + nl - cp);
2773+
2774+ __argp_fmtstream_write (stream, cp, nl - cp);
2775+ }
2776+ if (fdoc && fdoc != tdoc)
2777+ free ((char *)fdoc); /* Free user's modified doc string. */
2778+
2779+ if (child)
2780+ while (child->argp)
2781+ advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
2782+
2783+ if (advance && multiple)
2784+ {
2785+ /* Need to increment our level. */
2786+ if (*nl)
2787+ /* There's more we can do here. */
2788+ {
2789+ (*our_level)++;
2790+ advance = 0; /* Our parent shouldn't advance also. */
2791+ }
2792+ else if (*our_level > 0)
2793+ /* We had multiple levels, but used them up; reset to zero. */
2794+ *our_level = 0;
2795+ }
2796+
2797+ return !advance;
2798+}
2799+
2800+/* Print the documentation for ARGP to STREAM; if POST is false, then
2801+ everything preceeding a `\v' character in the documentation strings (or
2802+ the whole string, for those with none) is printed, otherwise, everything
2803+ following the `\v' character (nothing for strings without). Each separate
2804+ bit of documentation is separated a blank line, and if PRE_BLANK is true,
2805+ then the first is as well. If FIRST_ONLY is true, only the first
2806+ occurrence is output. Returns true if anything was output. */
2807+static int
2808+argp_doc (const struct argp *argp, const struct argp_state *state,
2809+ int post, int pre_blank, int first_only,
2810+ argp_fmtstream_t stream)
2811+{
2812+ const char *text;
2813+ const char *inp_text;
2814+ void *input = 0;
2815+ int anything = 0;
2816+ size_t inp_text_limit = 0;
2817+ const char *doc = dgettext (argp->argp_domain, argp->doc);
2818+ const struct argp_child *child = argp->children;
2819+
2820+ if (doc)
2821+ {
2822+ char *vt = strchr (doc, '\v');
2823+ inp_text = post ? (vt ? vt + 1 : 0) : doc;
2824+ inp_text_limit = (!post && vt) ? (vt - doc) : 0;
2825+ }
2826+ else
2827+ inp_text = 0;
2828+
2829+ if (argp->help_filter)
2830+ /* We have to filter the doc strings. */
2831+ {
2832+ if (inp_text_limit)
2833+ /* Copy INP_TEXT so that it's nul-terminated. */
2834+ inp_text = strndup (inp_text, inp_text_limit);
2835+ input = __argp_input (argp, state);
2836+ text =
2837+ (*argp->help_filter) (post
2838+ ? ARGP_KEY_HELP_POST_DOC
2839+ : ARGP_KEY_HELP_PRE_DOC,
2840+ inp_text, input);
2841+ }
2842+ else
2843+ text = (const char *) inp_text;
2844+
2845+ if (text)
2846+ {
2847+ if (pre_blank)
2848+ __argp_fmtstream_putc (stream, '\n');
2849+
2850+ if (text == inp_text && inp_text_limit)
2851+ __argp_fmtstream_write (stream, inp_text, inp_text_limit);
2852+ else
2853+ __argp_fmtstream_puts (stream, text);
2854+
2855+ if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
2856+ __argp_fmtstream_putc (stream, '\n');
2857+
2858+ anything = 1;
2859+ }
2860+
2861+ if (text && text != inp_text)
2862+ free ((char *) text); /* Free TEXT returned from the help filter. */
2863+ if (inp_text && inp_text_limit && argp->help_filter)
2864+ free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
2865+
2866+ if (post && argp->help_filter)
2867+ /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
2868+ {
2869+ text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
2870+ if (text)
2871+ {
2872+ if (anything || pre_blank)
2873+ __argp_fmtstream_putc (stream, '\n');
2874+ __argp_fmtstream_puts (stream, text);
2875+ free ((char *) text);
2876+ if (__argp_fmtstream_point (stream)
2877+ > __argp_fmtstream_lmargin (stream))
2878+ __argp_fmtstream_putc (stream, '\n');
2879+ anything = 1;
2880+ }
2881+ }
2882+
2883+ if (child)
2884+ while (child->argp && !(first_only && anything))
2885+ anything |=
2886+ argp_doc ((child++)->argp, state,
2887+ post, anything || pre_blank, first_only,
2888+ stream);
2889+
2890+ return anything;
2891+}
2892+
2893+/* Output a usage message for ARGP to STREAM. If called from
2894+ argp_state_help, STATE is the relevent parsing state. FLAGS are from the
2895+ set ARGP_HELP_*. NAME is what to use wherever a `program name' is
2896+ needed. */
2897+static void
2898+_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
2899+ unsigned flags, char *name)
2900+{
2901+ int anything = 0; /* Whether we've output anything. */
2902+ struct hol *hol = 0;
2903+ argp_fmtstream_t fs;
2904+
2905+ if (! stream)
2906+ return;
2907+
2908+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
2909+ flockfile (stream);
2910+#endif
2911+
2912+ fill_in_uparams (state);
2913+
2914+ fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
2915+ if (! fs)
2916+ {
2917+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
2918+ funlockfile (stream);
2919+#endif
2920+ return;
2921+ }
2922+
2923+ if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
2924+ {
2925+ hol = argp_hol (argp, 0);
2926+
2927+ /* If present, these options always come last. */
2928+ hol_set_group (hol, "help", -1);
2929+ hol_set_group (hol, "version", -1);
2930+
2931+ hol_sort (hol);
2932+ }
2933+
2934+ if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
2935+ /* Print a short `Usage:' message. */
2936+ {
2937+ int first_pattern = 1, more_patterns;
2938+ size_t num_pattern_levels = argp_args_levels (argp);
2939+ char *pattern_levels = alloca (num_pattern_levels);
2940+
2941+ memset (pattern_levels, 0, num_pattern_levels);
2942+
2943+ do
2944+ {
2945+ int old_lm;
2946+ int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
2947+ char *levels = pattern_levels;
2948+
2949+ if (first_pattern)
2950+ __argp_fmtstream_printf (fs, "%s %s",
2951+ dgettext (argp->argp_domain, "Usage:"),
2952+ name);
2953+ else
2954+ __argp_fmtstream_printf (fs, "%s %s",
2955+ dgettext (argp->argp_domain, " or: "),
2956+ name);
2957+
2958+ /* We set the lmargin as well as the wmargin, because hol_usage
2959+ manually wraps options with newline to avoid annoying breaks. */
2960+ old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
2961+
2962+ if (flags & ARGP_HELP_SHORT_USAGE)
2963+ /* Just show where the options go. */
2964+ {
2965+ if (hol->num_entries > 0)
2966+ __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
2967+ " [OPTION...]"));
2968+ }
2969+ else
2970+ /* Actually print the options. */
2971+ {
2972+ hol_usage (hol, fs);
2973+ flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
2974+ }
2975+
2976+ more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
2977+
2978+ __argp_fmtstream_set_wmargin (fs, old_wm);
2979+ __argp_fmtstream_set_lmargin (fs, old_lm);
2980+
2981+ __argp_fmtstream_putc (fs, '\n');
2982+ anything = 1;
2983+
2984+ first_pattern = 0;
2985+ }
2986+ while (more_patterns);
2987+ }
2988+
2989+ if (flags & ARGP_HELP_PRE_DOC)
2990+ anything |= argp_doc (argp, state, 0, 0, 1, fs);
2991+
2992+ if (flags & ARGP_HELP_SEE)
2993+ {
2994+ __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
2995+Try `%s --help' or `%s --usage' for more information.\n"),
2996+ name, name);
2997+ anything = 1;
2998+ }
2999+
3000+ if (flags & ARGP_HELP_LONG)
3001+ /* Print a long, detailed help message. */
3002+ {
3003+ /* Print info about all the options. */
3004+ if (hol->num_entries > 0)
3005+ {
3006+ if (anything)
3007+ __argp_fmtstream_putc (fs, '\n');
3008+ hol_help (hol, state, fs);
3009+ anything = 1;
3010+ }
3011+ }
3012+
3013+ if (flags & ARGP_HELP_POST_DOC)
3014+ /* Print any documentation strings at the end. */
3015+ anything |= argp_doc (argp, state, 1, anything, 0, fs);
3016+
3017+ if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
3018+ {
3019+ if (anything)
3020+ __argp_fmtstream_putc (fs, '\n');
3021+ __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
3022+ "Report bugs to %s.\n"),
3023+ argp_program_bug_address);
3024+ anything = 1;
3025+ }
3026+
3027+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3028+ funlockfile (stream);
3029+#endif
3030+
3031+ if (hol)
3032+ hol_free (hol);
3033+
3034+ __argp_fmtstream_free (fs);
3035+}
3036+
3037+/* Output a usage message for ARGP to STREAM. FLAGS are from the set
3038+ ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
3039+void argp_help (const struct argp *argp, FILE *stream,
3040+ unsigned flags, char *name)
3041+{
3042+ _help (argp, 0, stream, flags, name);
3043+}
3044+
3045+char *
3046+__argp_short_program_name (void)
3047+{
3048+# ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
3049+/*
3050+ * uClibc provides both program_invocation_name and
3051+ * program_invocation_short_name
3052+ */
3053+ return (char *) program_invocation_short_name;
3054+# else
3055+ /* FIXME: What now? Miles suggests that it is better to use NULL,
3056+ but currently the value is passed on directly to fputs_unlocked,
3057+ so that requires more changes. */
3058+# if __GNUC__
3059+# warning No reasonable value to return
3060+# endif /* __GNUC__ */
3061+ return "";
3062+# endif
3063+}
3064+
3065+/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
3066+ from the set ARGP_HELP_*. */
3067+void
3068+argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
3069+{
3070+ if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
3071+ {
3072+ if (state && (state->flags & ARGP_LONG_ONLY))
3073+ flags |= ARGP_HELP_LONG_ONLY;
3074+
3075+ _help (state ? state->root_argp : 0, state, stream, flags,
3076+ state ? state->name : __argp_short_program_name ());
3077+
3078+ if (!state || ! (state->flags & ARGP_NO_EXIT))
3079+ {
3080+ if (flags & ARGP_HELP_EXIT_ERR)
3081+ exit (argp_err_exit_status);
3082+ if (flags & ARGP_HELP_EXIT_OK)
3083+ exit (0);
3084+ }
3085+ }
3086+}
3087+
3088+/* If appropriate, print the printf string FMT and following args, preceded
3089+ by the program name and `:', to stderr, and followed by a `Try ... --help'
3090+ message, then exit (1). */
3091+void
3092+argp_error (const struct argp_state *state, const char *fmt, ...)
3093+{
3094+ if (!state || !(state->flags & ARGP_NO_ERRS))
3095+ {
3096+ FILE *stream = state ? state->err_stream : stderr;
3097+
3098+ if (stream)
3099+ {
3100+ va_list ap;
3101+
3102+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3103+ flockfile (stream);
3104+#endif
3105+
3106+ va_start (ap, fmt);
3107+
3108+#if defined _LIBC && defined USE_IN_LIBIO
3109+ char *buf;
3110+
3111+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
3112+ buf = NULL;
3113+
3114+ __fxprintf (stream, "%s: %s\n",
3115+ state ? state->name : __argp_short_program_name (), buf);
3116+
3117+ free (buf);
3118+#else
3119+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
3120+ stream);
3121+ putc_unlocked (':', stream);
3122+ putc_unlocked (' ', stream);
3123+
3124+ vfprintf (stream, fmt, ap);
3125+
3126+ putc_unlocked ('\n', stream);
3127+#endif
3128+
3129+ argp_state_help (state, stream, ARGP_HELP_STD_ERR);
3130+
3131+ va_end (ap);
3132+
3133+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3134+ funlockfile (stream);
3135+#endif
3136+ }
3137+ }
3138+}
3139+
3140+/* Similar to the standard gnu error-reporting function error(), but will
3141+ respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
3142+ to STATE->err_stream. This is useful for argument parsing code that is
3143+ shared between program startup (when exiting is desired) and runtime
3144+ option parsing (when typically an error code is returned instead). The
3145+ difference between this function and argp_error is that the latter is for
3146+ *parsing errors*, and the former is for other problems that occur during
3147+ parsing but don't reflect a (syntactic) problem with the input. */
3148+void
3149+argp_failure (const struct argp_state *state, int status, int errnum,
3150+ const char *fmt, ...)
3151+{
3152+ if (!state || !(state->flags & ARGP_NO_ERRS))
3153+ {
3154+ FILE *stream = state ? state->err_stream : stderr;
3155+
3156+ if (stream)
3157+ {
3158+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3159+ flockfile (stream);
3160+#endif
3161+
3162+#if defined _LIBC && defined USE_IN_LIBIO
3163+ __fxprintf (stream, "%s",
3164+ state ? state->name : __argp_short_program_name ());
3165+#else
3166+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
3167+ stream);
3168+#endif
3169+
3170+ if (fmt)
3171+ {
3172+ va_list ap;
3173+
3174+ va_start (ap, fmt);
3175+#if defined _LIBC && defined USE_IN_LIBIO
3176+ char *buf;
3177+
3178+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
3179+ buf = NULL;
3180+
3181+ __fxprintf (stream, ": %s", buf);
3182+
3183+ free (buf);
3184+#else
3185+ putc_unlocked (':', stream);
3186+ putc_unlocked (' ', stream);
3187+
3188+ vfprintf (stream, fmt, ap);
3189+#endif
3190+
3191+ va_end (ap);
3192+ }
3193+
3194+ if (errnum)
3195+ {
3196+#if (defined _LIBC && defined USE_IN_LIBIO) || defined HAVE_STRERROR_R
3197+ char buf[200];
3198+#endif
3199+#if defined _LIBC && defined USE_IN_LIBIO
3200+ __fxprintf (stream, ": %s",
3201+ strerror_r (errnum, buf, sizeof (buf)));
3202+#else
3203+ putc_unlocked (':', stream);
3204+ putc_unlocked (' ', stream);
3205+# ifdef HAVE_STRERROR_R
3206+ fputs (strerror_r (errnum, buf, sizeof (buf)), stream);
3207+# else
3208+ fputs (strerror (errnum), stream);
3209+# endif
3210+#endif
3211+ }
3212+
3213+#ifdef USE_IN_LIBIO
3214+ if (_IO_fwide (stream, 0) > 0)
3215+ putwc_unlocked (L'\n', stream);
3216+ else
3217+#endif
3218+ putc_unlocked ('\n', stream);
3219+
3220+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3221+ funlockfile (stream);
3222+#endif
3223+
3224+ if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
3225+ exit (status);
3226+ }
3227+ }
3228+}
3229Index: git/libuargp/argp-parse.c
3230===================================================================
3231--- /dev/null 1970-01-01 00:00:00.000000000 +0000
3232+++ git/libuargp/argp-parse.c 2012-06-18 13:10:44.060825542 -0700
3233@@ -0,0 +1,949 @@
3234+/* Hierarchial argument parsing, layered over getopt
3235+ Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3236+ This file is part of the GNU C Library.
3237+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
3238+
3239+ The GNU C Library is free software; you can redistribute it and/or
3240+ modify it under the terms of the GNU Lesser General Public
3241+ License as published by the Free Software Foundation; either
3242+ version 2.1 of the License, or (at your option) any later version.
3243+
3244+ The GNU C Library is distributed in the hope that it will be useful,
3245+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3246+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3247+ Lesser General Public License for more details.
3248+
3249+ You should have received a copy of the GNU Lesser General Public
3250+ License along with the GNU C Library; if not, write to the Free
3251+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3252+ 02111-1307 USA.
3253+
3254+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
3255+*/
3256+
3257+#ifdef HAVE_CONFIG_H
3258+#include <config.h>
3259+#endif
3260+
3261+/* AIX requires this to be the first thing in the file. */
3262+#ifndef __GNUC__
3263+# if HAVE_ALLOCA_H || defined _LIBC
3264+# include <alloca.h>
3265+# else
3266+# ifdef _AIX
3267+#pragma alloca
3268+# else
3269+# ifndef alloca /* predefined by HP cc +Olibcalls */
3270+char *alloca ();
3271+# endif
3272+# endif
3273+# endif
3274+#endif
3275+
3276+#include <stdlib.h>
3277+#include <string.h>
3278+#include <unistd.h>
3279+#include <limits.h>
3280+#include <getopt.h>
3281+#include <bits/getopt_int.h>
3282+
3283+#include <features.h>
3284+#ifndef _
3285+/* This is for other GNU distributions with internationalized messages.
3286+ When compiling libc, the _ macro is predefined. */
3287+# if (defined HAVE_LIBINTL_H || defined _LIBC) && defined __UCLIBC_HAS_GETTEXT_AWARENESS__
3288+# include <libintl.h>
3289+# ifdef _LIBC
3290+# undef dgettext
3291+# define dgettext(domain, msgid) \
3292+ INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
3293+# endif
3294+# else
3295+# define dgettext(domain, msgid) (msgid)
3296+# define gettext(msgid) (msgid)
3297+# endif
3298+#endif
3299+#ifndef N_
3300+# define N_(msgid) (msgid)
3301+#endif
3302+
3303+#include <argp.h>
3304+
3305+/* Getopt return values. */
3306+#define KEY_END (-1) /* The end of the options. */
3307+#define KEY_ARG 1 /* A non-option argument. */
3308+#define KEY_ERR '?' /* An error parsing the options. */
3309+
3310+/* The meta-argument used to prevent any further arguments being interpreted
3311+ as options. */
3312+#define QUOTE "--"
3313+
3314+/* The number of bits we steal in a long-option value for our own use. */
3315+#define GROUP_BITS CHAR_BIT
3316+
3317+/* The number of bits available for the user value. */
3318+#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
3319+#define USER_MASK ((1 << USER_BITS) - 1)
3320+
3321+/* EZ alias for ARGP_ERR_UNKNOWN. */
3322+#define EBADKEY ARGP_ERR_UNKNOWN
3323+
3324+/* Default options. */
3325+
3326+/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
3327+ for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
3328+ you can force the program to continue by attaching a debugger and setting
3329+ it to 0 yourself. */
3330+static volatile int _argp_hang;
3331+
3332+#define OPT_PROGNAME -2
3333+#define OPT_USAGE -3
3334+#define OPT_HANG -4
3335+
3336+static const struct argp_option argp_default_options[] =
3337+{
3338+ {"help", '?', 0, 0, N_("Give this help list"), -1},
3339+ {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")},
3340+ {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name")},
3341+ {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
3342+ N_("Hang for SECS seconds (default 3600)")},
3343+ {0, 0}
3344+};
3345+
3346+static error_t
3347+argp_default_parser (int key, char *arg, struct argp_state *state)
3348+{
3349+ switch (key)
3350+ {
3351+ case '?':
3352+ argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
3353+ break;
3354+ case OPT_USAGE:
3355+ argp_state_help (state, state->out_stream,
3356+ ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
3357+ break;
3358+
3359+ case OPT_PROGNAME: /* Set the program name. */
3360+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
3361+ program_invocation_name = arg;
3362+#endif
3363+ /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
3364+ __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
3365+ to be that, so we have to be a bit careful here.] */
3366+
3367+ /* Update what we use for messages. */
3368+ state->name = strrchr (arg, '/');
3369+ if (state->name)
3370+ state->name++;
3371+ else
3372+ state->name = arg;
3373+
3374+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
3375+ program_invocation_short_name = state->name;
3376+#endif
3377+
3378+ if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
3379+ == ARGP_PARSE_ARGV0)
3380+ /* Update what getopt uses too. */
3381+ state->argv[0] = arg;
3382+
3383+ break;
3384+
3385+ case OPT_HANG:
3386+ _argp_hang = atoi (arg ? arg : "3600");
3387+ while (_argp_hang-- > 0)
3388+ sleep (1);
3389+ break;
3390+
3391+ default:
3392+ return EBADKEY;
3393+ }
3394+ return 0;
3395+}
3396+
3397+static const struct argp argp_default_argp =
3398+ {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
3399+
3400+
3401+static const struct argp_option argp_version_options[] =
3402+{
3403+ {"version", 'V', 0, 0, N_("Print program version"), -1},
3404+ {0, 0}
3405+};
3406+
3407+static error_t
3408+argp_version_parser (int key, char *arg, struct argp_state *state)
3409+{
3410+ switch (key)
3411+ {
3412+ case 'V':
3413+ if (argp_program_version_hook)
3414+ (*argp_program_version_hook) (state->out_stream, state);
3415+ else if (argp_program_version)
3416+ fprintf (state->out_stream, "%s\n", argp_program_version);
3417+ else
3418+ argp_error (state, dgettext (state->root_argp->argp_domain,
3419+ "(PROGRAM ERROR) No version known!?"));
3420+ if (! (state->flags & ARGP_NO_EXIT))
3421+ exit (0);
3422+ break;
3423+ default:
3424+ return EBADKEY;
3425+ }
3426+ return 0;
3427+}
3428+
3429+static const struct argp argp_version_argp =
3430+ {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
3431+
3432+/* Returns the offset into the getopt long options array LONG_OPTIONS of a
3433+ long option with called NAME, or -1 if none is found. Passing NULL as
3434+ NAME will return the number of options. */
3435+static int
3436+find_long_option (struct option *long_options, const char *name)
3437+{
3438+ struct option *l = long_options;
3439+ while (l->name != NULL)
3440+ if (name != NULL && strcmp (l->name, name) == 0)
3441+ return l - long_options;
3442+ else
3443+ l++;
3444+ if (name == NULL)
3445+ return l - long_options;
3446+ else
3447+ return -1;
3448+}
3449+
3450+
3451+/* The state of a `group' during parsing. Each group corresponds to a
3452+ particular argp structure from the tree of such descending from the top
3453+ level argp passed to argp_parse. */
3454+struct group
3455+{
3456+ /* This group's parsing function. */
3457+ argp_parser_t parser;
3458+
3459+ /* Which argp this group is from. */
3460+ const struct argp *argp;
3461+
3462+ /* Points to the point in SHORT_OPTS corresponding to the end of the short
3463+ options for this group. We use it to determine from which group a
3464+ particular short options is from. */
3465+ char *short_end;
3466+
3467+ /* The number of non-option args sucessfully handled by this parser. */
3468+ unsigned args_processed;
3469+
3470+ /* This group's parser's parent's group. */
3471<