summaryrefslogtreecommitdiffstats
path: root/meta/recipes-core
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2016-01-12 01:24:37 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-01-24 09:40:31 +0000
commit5a8c935f2a63aec22e18bd18b05b7a9bf8b8187f (patch)
treeaeefce22bb5de051ef002855decc51f505e164ce /meta/recipes-core
parent1113d5830f81bc8d25b4abcf3cb1356eac0a0dbb (diff)
downloadpoky-5a8c935f2a63aec22e18bd18b05b7a9bf8b8187f.tar.gz
uclibc: Update to 1.0.11
changes are here http://mailman.uclibc-ng.org/pipermail/devel/2016-January/000665.html Drop upstreamed patch (From OE-Core rev: 1553adb92bfdcfda9c216a72658ccf327b6ab1aa) Signed-off-by: Khem Raj <raj.khem@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-core')
-rw-r--r--meta/recipes-core/uclibc/uclibc-git.inc5
-rw-r--r--meta/recipes-core/uclibc/uclibc-git/0003-Add-argp-implementation.patch5811
2 files changed, 2 insertions, 5814 deletions
diff --git a/meta/recipes-core/uclibc/uclibc-git.inc b/meta/recipes-core/uclibc/uclibc-git.inc
index a5c4b5e2ff..490dfcb96c 100644
--- a/meta/recipes-core/uclibc/uclibc-git.inc
+++ b/meta/recipes-core/uclibc/uclibc-git.inc
@@ -1,12 +1,11 @@
1SRCREV = "0ad73077c230093ae004829da44418597f330c6a" 1SRCREV = "94493929f674f4410c2743fa3dd82fd37b70c58f"
2 2
3PV = "1.0.10+git${SRCPV}" 3PV = "1.0.11+git${SRCPV}"
4 4
5FILESEXTRAPATHS =. "${FILE_DIRNAME}/uclibc-git:" 5FILESEXTRAPATHS =. "${FILE_DIRNAME}/uclibc-git:"
6 6
7SRC_URI = "git://uclibc-ng.org/git/uclibc-ng;branch=1.0 \ 7SRC_URI = "git://uclibc-ng.org/git/uclibc-ng;branch=1.0 \
8 file://0001-Disable-lrount_tes-function.patch \ 8 file://0001-Disable-lrount_tes-function.patch \
9 file://0003-Add-argp-implementation.patch \
10 file://uClibc.machine \ 9 file://uClibc.machine \
11 file://uClibc.distro \ 10 file://uClibc.distro \
12 file://obstack.cfg \ 11 file://obstack.cfg \
diff --git a/meta/recipes-core/uclibc/uclibc-git/0003-Add-argp-implementation.patch b/meta/recipes-core/uclibc/uclibc-git/0003-Add-argp-implementation.patch
deleted file mode 100644
index ee9448337c..0000000000
--- a/meta/recipes-core/uclibc/uclibc-git/0003-Add-argp-implementation.patch
+++ /dev/null
@@ -1,5811 +0,0 @@
1From eaae816fb22929469aa4cc3402b91b512fc69549 Mon Sep 17 00:00:00 2001
2From: Salvatore Cro <salvatore.cro@st.com>
3Date: Sun, 16 Aug 2015 20:53:37 -0700
4Subject: [PATCH 3/7] Add argp implementation
5
6Argp is an advanced support for parsing unix-style argument vectors.
7In addition to the common getopt interface, it provides automatic
8response
9to `--help' and `--version' options and use of custom parser in
10conjunction
11with argp native option parser, among others.
12Argp support is required by elfutils package and prelink.
13
14In uClibc argp functionalities has been moved from C library to
15libuargp.so
16Further the libc.so linker script contains an AS_NEEDED entry so that
17it doesn't need to link libuargp.so explicitely.
18
19Signed-off-by: Salvatore Cro <salvatore.cro@st.com>
20Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
21Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
22Signed-off-by: Khem Raj <raj.khem@gmail.com>
23---
24Upstream-Status: Pending
25
26 Makefile.in | 9 +
27 Makerules | 7 +-
28 Rules.mak | 13 +
29 extra/Configs/Config.in | 17 +
30 include/argp.h | 566 ++++++++
31 libc/sysdeps/linux/common/bits/getopt_int.h | 136 ++
32 libc/unistd/getopt.c | 19 +-
33 libuargp/Makefile | 14 +
34 libuargp/Makefile.in | 73 ++
35 libuargp/argp-ba.c | 26 +
36 libuargp/argp-eexst.c | 32 +
37 libuargp/argp-fmtstream.c | 439 +++++++
38 libuargp/argp-fmtstream.h | 314 +++++
39 libuargp/argp-fs-xinl.c | 44 +
40 libuargp/argp-help.c | 1882 +++++++++++++++++++++++++++
41 libuargp/argp-parse.c | 949 ++++++++++++++
42 libuargp/argp-pv.c | 25 +
43 libuargp/argp-pvh.c | 32 +
44 libuargp/argp-xinl.c | 35 +
45 test/argp/Makefile | 7 +
46 test/argp/Makefile.in | 12 +
47 test/argp/argp-ex1.c | 15 +
48 test/argp/argp-ex2.c | 45 +
49 test/argp/argp-ex3.c | 153 +++
50 test/argp/argp-ex4.c | 167 +++
51 test/argp/argp-test.c | 209 +++
52 test/argp/bug-argp1.c | 26 +
53 test/argp/tst-argp1.c | 118 ++
54 test/argp/tst-argp2.c | 101 ++
55 29 files changed, 5481 insertions(+), 4 deletions(-)
56 create mode 100644 include/argp.h
57 create mode 100644 libc/sysdeps/linux/common/bits/getopt_int.h
58 create mode 100644 libuargp/Makefile
59 create mode 100644 libuargp/Makefile.in
60 create mode 100644 libuargp/argp-ba.c
61 create mode 100644 libuargp/argp-eexst.c
62 create mode 100644 libuargp/argp-fmtstream.c
63 create mode 100644 libuargp/argp-fmtstream.h
64 create mode 100644 libuargp/argp-fs-xinl.c
65 create mode 100644 libuargp/argp-help.c
66 create mode 100644 libuargp/argp-parse.c
67 create mode 100644 libuargp/argp-pv.c
68 create mode 100644 libuargp/argp-pvh.c
69 create mode 100644 libuargp/argp-xinl.c
70 create mode 100644 test/argp/Makefile
71 create mode 100644 test/argp/Makefile.in
72 create mode 100644 test/argp/argp-ex1.c
73 create mode 100644 test/argp/argp-ex2.c
74 create mode 100644 test/argp/argp-ex3.c
75 create mode 100644 test/argp/argp-ex4.c
76 create mode 100644 test/argp/argp-test.c
77 create mode 100644 test/argp/bug-argp1.c
78 create mode 100644 test/argp/tst-argp1.c
79 create mode 100644 test/argp/tst-argp2.c
80
81diff --git a/Makefile.in b/Makefile.in
82index 04671a4..a450af9 100644
83--- a/Makefile.in
84+++ b/Makefile.in
85@@ -39,6 +39,7 @@ include $(top_srcdir)libresolv/Makefile.in
86 include $(top_srcdir)libutil/Makefile.in
87 include $(top_srcdir)libpthread/Makefile.in
88 include $(top_srcdir)librt/Makefile.in
89+include $(top_srcdir)libuargp/Makefile.in
90 include $(top_srcdir)libubacktrace/Makefile.in
91
92 # last included to catch all the objects added by others (locales/threads)
93@@ -262,6 +263,7 @@ HEADERS_RM- += sgtty.h
94 endif
95 HEADERS_RM-$(HAVE_SHARED) += dlfcn.h bits/dlfcn.h
96 HEADERS_RM-$(PTHREADS_DEBUG_SUPPORT) += thread_db.h
97+HEADERS_RM-$(UCLIBC_HAS_ARGP) += argp.h
98 HEADERS_RM-$(UCLIBC_HAS_BSD_ERR) += err.h
99 HEADERS_RM-$(UCLIBC_HAS_CRYPT) += crypt.h
100 HEADERS_RM-$(UCLIBC_HAS_EPOLL) += sys/epoll.h
101@@ -386,6 +388,13 @@ else
102 -$(INSTALL) -m 755 $(top_builddir)lib/libc.so $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/
103 endif
104 echo "$(UBACKTRACE_ASNEEDED)" >> $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so
105+ifeq ($(UCLIBC_HAS_ARGP),y)
106+# Add the AS_NEEDED entry for libuargp.so
107+ if [ -f $(top_builddir)lib/libc.so -a -f $(PREFIX)$(RUNTIME_PREFIX)$(MULTILIB_DIR)/$(SHARED_MAJORNAME) ] ; then \
108+ echo "GROUP ( $(UARGP_ASNEEDED) )" >> $(PREFIX)$(DEVEL_PREFIX)$(MULTILIB_DIR)/libc.so; \
109+ fi
110+endif
111+
112 ifeq ($(UCLIBC_HAS_THREADS),y)
113 ifneq ($(LINUXTHREADS_OLD),y)
114 ifeq ($(HARDWIRED_ABSPATH),y)
115diff --git a/Makerules b/Makerules
116index d6f7e24..e70050d 100644
117--- a/Makerules
118+++ b/Makerules
119@@ -48,6 +48,7 @@ $(eval $(call add_IS_IN_lib,libresolv,$(libresolv-a-y) $(libresolv-so-y)))
120 $(eval $(call add_IS_IN_lib,librt,$(librt-a-y) $(librt-so-y)))
121 $(eval $(call add_IS_IN_lib,libutil,$(libutil-a-y) $(libutil-so-y)))
122 $(eval $(call add_IS_IN_lib,libubacktrace,$(libubacktrace-a-y) $(libubacktrace-so-y)))
123+$(eval $(call add_IS_IN_lib,libuargp,$(libuargp-a-y) $(libuargp-so-y)))
124
125 shared_objs = $(libc-y:.o=.os) $(libc-shared-y) $(libc-nonshared-y) \
126 $(libcrypt-so-y) $(libdl-so-y) \
127@@ -55,12 +56,12 @@ shared_objs = $(libc-y:.o=.os) $(libc-shared-y) $(libc-nonshared-y) \
128 $(libpthread-so-y) $(libpthread-nonshared-y) $(libthread_db-so-y) \
129 $(libresolv-so-y) $(librt-so-y) \
130 $(ldso-y) \
131- $(libutil-so-y) $(libubacktrace-so-y)
132+ $(libutil-so-y) $(libubacktrace-so-y) $(libuargp-so-y)
133
134 ar_objs = $(libc-y) $(libc-static-y) $(libcrypt-a-y) \
135 $(libdl-a-y) $(libintl-a-y) $(libm-a-y) $(libnsl-a-y) \
136 $(libpthread-a-y) $(libthread_db-a-y) \
137- $(libresolv-a-y) $(librt-a-y) $(libutil-a-y) $(libubacktrace-a-y)
138+ $(libresolv-a-y) $(librt-a-y) $(libutil-a-y) $(libubacktrace-a-y) $(libuargp-a-y)
139 ifeq ($(DOPIC),y)
140 ar_objs := $(ar_objs:.o=.os)
141 endif
142@@ -498,7 +499,7 @@ files.dep := $(libc-a-y) $(libc-so-y) $(libc-nonshared-y) \
143 $(librt-a-y) $(librt-so-y) $(libresolv-a-y) $(libresolv-so-y) \
144 $(libcrypt-a-y) $(libcrypt-so-y) $(libutil-a-y) $(libutil-so-y) \
145 $(libnsl-a-y) $(libnsl-so-y) $(ldso-y) $(libdl-a-y) $(libdl-so-y) \
146- $(libubacktrace-a-y) $(libubacktrace-so-y)
147+ $(libubacktrace-a-y) $(libubacktrace-so-y) $(libuargp-so-y) $(libuargp-a-y)
148 .depends.dep := \
149 $(patsubst %.s,%.s.dep,$(filter %.s,$(files.dep))) \
150 $(patsubst %.o,%.o.dep,$(filter %.o,$(files.dep))) \
151diff --git a/Rules.mak b/Rules.mak
152index de9ffb3..a2baf58 100644
153--- a/Rules.mak
154+++ b/Rules.mak
155@@ -602,6 +602,19 @@ export UBACKTRACE_ASNEEDED:=$(shell $(CC) -Wl,--help 2>/dev/null | grep -q -- --
156 else
157 export UBACKTRACE_ASNEEDED:=""
158 endif
159+ifeq ($(UCLIBC_HAS_ARGP),y)
160+ifeq ($(HARDWIRED_ABSPATH),y)
161+# Only used in installed libc.so linker script
162+UARGP_FULL_NAME := $(subst //,/,$(RUNTIME_PREFIX)$(MULTILIB_DIR)/libuargp.so.$(MAJOR_VERSION))
163+else
164+UARGP_FULL_NAME := libuargp.so.$(MAJOR_VERSION)
165+endif
166+export UARGP_ASNEEDED:=$(shell $(CC) -Wl,--help 2>/dev/null | grep -q -- --as-needed && \
167+ echo "GROUP ( AS_NEEDED ( $(UARGP_FULL_NAME) ) )" || \
168+ echo "GROUP ( $(UARGP_FULL_NAME) )")
169+else
170+export UARGP_ASNEEDED:=""
171+endif
172 endif
173
174 # Add a bunch of extra pedantic annoyingly strict checks
175diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
176index 242e45a..b36d4c9 100644
177--- a/extra/Configs/Config.in
178+++ b/extra/Configs/Config.in
179@@ -1943,6 +1943,23 @@ config UCLIBC_HAS_GNU_GETSUBOPT
180 Answer Y if you want to include getsubopt().
181
182 Most people will answer Y.
183+
184+config UCLIBC_HAS_ARGP
185+ bool "Support argp (as standalone shared object)"
186+ default n
187+ help
188+ Argp is an interface for parsing unix-style argument vectors. Unlike
189+ the common getopt interface, it provides many advanced features in
190+ addition to parsing options, such as automatic output in response to
191+ `--help' and `--version' options.
192+ A library can export an argp option parser, which programs can easily
193+ use in conjunction with their own option parser.
194+ A new shared object "libuargp" is created. The "libc.so" linker script
195+ contains the AS_NEEDED entry for getting the libuargp linked automatically.
196+ Argp support is needed by elfutils libdw.
197+
198+ Most people can safely answer N.
199+
200 endmenu
201
202
203diff --git a/include/argp.h b/include/argp.h
204new file mode 100644
205index 0000000..9d53728
206--- /dev/null
207+++ b/include/argp.h
208@@ -0,0 +1,566 @@
209+/* Hierarchial argument parsing, layered over getopt.
210+ Copyright (C) 1995-1999, 2003, 2004, 2005, 2006, 2007, 2009
211+ Free Software Foundation, Inc.
212+ This file is part of the GNU C Library.
213+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
214+
215+ The GNU C Library is free software; you can redistribute it and/or
216+ modify it under the terms of the GNU Lesser General Public
217+ License as published by the Free Software Foundation; either
218+ version 2.1 of the License, or (at your option) any later version.
219+
220+ The GNU C Library is distributed in the hope that it will be useful,
221+ but WITHOUT ANY WARRANTY; without even the implied warranty of
222+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
223+ Lesser General Public License for more details.
224+
225+ You should have received a copy of the GNU Lesser General Public
226+ License along with the GNU C Library; if not, write to the Free
227+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
228+ 02111-1307 USA.
229+
230+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
231+*/
232+
233+#ifndef _ARGP_H
234+#define _ARGP_H
235+
236+#include <stdio.h>
237+#include <ctype.h>
238+#include <limits.h>
239+
240+#define __need_error_t
241+#include <errno.h>
242+
243+#ifndef __const
244+# define __const const
245+#endif
246+
247+#ifndef __THROW
248+# define __THROW
249+#endif
250+#ifndef __NTH
251+# define __NTH(fct) fct __THROW
252+#endif
253+
254+#ifndef __attribute__
255+/* This feature is available in gcc versions 2.5 and later. */
256+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(__STRICT_ANSI__)
257+# define __attribute__(Spec) /* empty */
258+# endif
259+/* The __-protected variants of `format' and `printf' attributes
260+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
261+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || defined(__STRICT_ANSI__)
262+# define __format__ format
263+# define __printf__ printf
264+# endif
265+#endif
266+
267+/* GCC 2.95 and later have "__restrict"; C99 compilers have
268+ "restrict", and "configure" may have defined "restrict". */
269+#ifndef __restrict
270+# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__))
271+# if defined restrict || 199901L <= __STDC_VERSION__
272+# define __restrict restrict
273+# else
274+# define __restrict
275+# endif
276+# endif
277+#endif
278+
279+#ifndef __error_t_defined
280+typedef int error_t;
281+# define __error_t_defined
282+#endif
283+
284+#ifdef __cplusplus
285+extern "C" {
286+#endif
287+
288+/* A description of a particular option. A pointer to an array of
289+ these is passed in the OPTIONS field of an argp structure. Each option
290+ entry can correspond to one long option and/or one short option; more
291+ names for the same option can be added by following an entry in an option
292+ array with options having the OPTION_ALIAS flag set. */
293+struct argp_option
294+{
295+ /* The long option name. For more than one name for the same option, you
296+ can use following options with the OPTION_ALIAS flag set. */
297+ __const char *name;
298+
299+ /* What key is returned for this option. If > 0 and printable, then it's
300+ also accepted as a short option. */
301+ int key;
302+
303+ /* If non-NULL, this is the name of the argument associated with this
304+ option, which is required unless the OPTION_ARG_OPTIONAL flag is set. */
305+ __const char *arg;
306+
307+ /* OPTION_ flags. */
308+ int flags;
309+
310+ /* The doc string for this option. If both NAME and KEY are 0, This string
311+ will be printed outdented from the normal option column, making it
312+ useful as a group header (it will be the first thing printed in its
313+ group); in this usage, it's conventional to end the string with a `:'. */
314+ __const char *doc;
315+
316+ /* The group this option is in. In a long help message, options are sorted
317+ alphabetically within each group, and the groups presented in the order
318+ 0, 1, 2, ..., n, -m, ..., -2, -1. Every entry in an options array with
319+ if this field 0 will inherit the group number of the previous entry, or
320+ zero if it's the first one, unless its a group header (NAME and KEY both
321+ 0), in which case, the previous entry + 1 is the default. Automagic
322+ options such as --help are put into group -1. */
323+ int group;
324+};
325+
326+/* The argument associated with this option is optional. */
327+#define OPTION_ARG_OPTIONAL 0x1
328+
329+/* This option isn't displayed in any help messages. */
330+#define OPTION_HIDDEN 0x2
331+
332+/* This option is an alias for the closest previous non-alias option. This
333+ means that it will be displayed in the same help entry, and will inherit
334+ fields other than NAME and KEY from the aliased option. */
335+#define OPTION_ALIAS 0x4
336+
337+/* This option isn't actually an option (and so should be ignored by the
338+ actual option parser), but rather an arbitrary piece of documentation that
339+ should be displayed in much the same manner as the options. If this flag
340+ is set, then the option NAME field is displayed unmodified (e.g., no `--'
341+ prefix is added) at the left-margin (where a *short* option would normally
342+ be displayed), and the documentation string in the normal place. For
343+ purposes of sorting, any leading whitespace and punctuation is ignored,
344+ except that if the first non-whitespace character is not `-', this entry
345+ is displayed after all options (and OPTION_DOC entries with a leading `-')
346+ in the same group. */
347+#define OPTION_DOC 0x8
348+
349+/* This option shouldn't be included in `long' usage messages (but is still
350+ included in help messages). This is mainly intended for options that are
351+ completely documented in an argp's ARGS_DOC field, in which case including
352+ the option in the generic usage list would be redundant. For instance,
353+ if ARGS_DOC is "FOO BAR\n-x BLAH", and the `-x' option's purpose is to
354+ distinguish these two cases, -x should probably be marked
355+ OPTION_NO_USAGE. */
356+#define OPTION_NO_USAGE 0x10
357+
358+struct argp; /* fwd declare this type */
359+struct argp_state; /* " */
360+struct argp_child; /* " */
361+
362+/* The type of a pointer to an argp parsing function. */
363+typedef error_t (*argp_parser_t) (int __key, char *__arg,
364+ struct argp_state *__state);
365+
366+/* What to return for unrecognized keys. For special ARGP_KEY_ keys, such
367+ returns will simply be ignored. For user keys, this error will be turned
368+ into EINVAL (if the call to argp_parse is such that errors are propagated
369+ back to the user instead of exiting); returning EINVAL itself would result
370+ in an immediate stop to parsing in *all* cases. */
371+#define ARGP_ERR_UNKNOWN E2BIG /* Hurd should never need E2BIG. XXX */
372+
373+/* Special values for the KEY argument to an argument parsing function.
374+ ARGP_ERR_UNKNOWN should be returned if they aren't understood.
375+
376+ The sequence of keys to a parsing function is either (where each
377+ uppercased word should be prefixed by `ARGP_KEY_' and opt is a user key):
378+
379+ INIT opt... NO_ARGS END SUCCESS -- No non-option arguments at all
380+ or INIT (opt | ARG)... END SUCCESS -- All non-option args parsed
381+ or INIT (opt | ARG)... SUCCESS -- Some non-option arg unrecognized
382+
383+ The third case is where every parser returned ARGP_KEY_UNKNOWN for an
384+ argument, in which case parsing stops at that argument (returning the
385+ unparsed arguments to the caller of argp_parse if requested, or stopping
386+ with an error message if not).
387+
388+ If an error occurs (either detected by argp, or because the parsing
389+ function returned an error value), then the parser is called with
390+ ARGP_KEY_ERROR, and no further calls are made. */
391+
392+/* This is not an option at all, but rather a command line argument. If a
393+ parser receiving this key returns success, the fact is recorded, and the
394+ ARGP_KEY_NO_ARGS case won't be used. HOWEVER, if while processing the
395+ argument, a parser function decrements the NEXT field of the state it's
396+ passed, the option won't be considered processed; this is to allow you to
397+ actually modify the argument (perhaps into an option), and have it
398+ processed again. */
399+#define ARGP_KEY_ARG 0
400+/* There are remaining arguments not parsed by any parser, which may be found
401+ starting at (STATE->argv + STATE->next). If success is returned, but
402+ STATE->next left untouched, it's assumed that all arguments were consume,
403+ otherwise, the parser should adjust STATE->next to reflect any arguments
404+ consumed. */
405+#define ARGP_KEY_ARGS 0x1000006
406+/* There are no more command line arguments at all. */
407+#define ARGP_KEY_END 0x1000001
408+/* Because it's common to want to do some special processing if there aren't
409+ any non-option args, user parsers are called with this key if they didn't
410+ successfully process any non-option arguments. Called just before
411+ ARGP_KEY_END (where more general validity checks on previously parsed
412+ arguments can take place). */
413+#define ARGP_KEY_NO_ARGS 0x1000002
414+/* Passed in before any parsing is done. Afterwards, the values of each
415+ element of the CHILD_INPUT field, if any, in the state structure is
416+ copied to each child's state to be the initial value of the INPUT field. */
417+#define ARGP_KEY_INIT 0x1000003
418+/* Use after all other keys, including SUCCESS & END. */
419+#define ARGP_KEY_FINI 0x1000007
420+/* Passed in when parsing has successfully been completed (even if there are
421+ still arguments remaining). */
422+#define ARGP_KEY_SUCCESS 0x1000004
423+/* Passed in if an error occurs. */
424+#define ARGP_KEY_ERROR 0x1000005
425+
426+/* An argp structure contains a set of options declarations, a function to
427+ deal with parsing one, documentation string, a possible vector of child
428+ argp's, and perhaps a function to filter help output. When actually
429+ parsing options, getopt is called with the union of all the argp
430+ structures chained together through their CHILD pointers, with conflicts
431+ being resolved in favor of the first occurrence in the chain. */
432+struct argp
433+{
434+ /* An array of argp_option structures, terminated by an entry with both
435+ NAME and KEY having a value of 0. */
436+ __const struct argp_option *options;
437+
438+ /* What to do with an option from this structure. KEY is the key
439+ associated with the option, and ARG is any associated argument (NULL if
440+ none was supplied). If KEY isn't understood, ARGP_ERR_UNKNOWN should be
441+ returned. If a non-zero, non-ARGP_ERR_UNKNOWN value is returned, then
442+ parsing is stopped immediately, and that value is returned from
443+ argp_parse(). For special (non-user-supplied) values of KEY, see the
444+ ARGP_KEY_ definitions below. */
445+ argp_parser_t parser;
446+
447+ /* A string describing what other arguments are wanted by this program. It
448+ is only used by argp_usage to print the `Usage:' message. If it
449+ contains newlines, the strings separated by them are considered
450+ alternative usage patterns, and printed on separate lines (lines after
451+ the first are prefix by ` or: ' instead of `Usage:'). */
452+ __const char *args_doc;
453+
454+ /* If non-NULL, a string containing extra text to be printed before and
455+ after the options in a long help message (separated by a vertical tab
456+ `\v' character). */
457+ __const char *doc;
458+
459+ /* A vector of argp_children structures, terminated by a member with a 0
460+ argp field, pointing to child argps should be parsed with this one. Any
461+ conflicts are resolved in favor of this argp, or early argps in the
462+ CHILDREN list. This field is useful if you use libraries that supply
463+ their own argp structure, which you want to use in conjunction with your
464+ own. */
465+ __const struct argp_child *children;
466+
467+ /* If non-zero, this should be a function to filter the output of help
468+ messages. KEY is either a key from an option, in which case TEXT is
469+ that option's help text, or a special key from the ARGP_KEY_HELP_
470+ defines, below, describing which other help text TEXT is. The function
471+ should return either TEXT, if it should be used as-is, a replacement
472+ string, which should be malloced, and will be freed by argp, or NULL,
473+ meaning `print nothing'. The value for TEXT is *after* any translation
474+ has been done, so if any of the replacement text also needs translation,
475+ that should be done by the filter function. INPUT is either the input
476+ supplied to argp_parse, or NULL, if argp_help was called directly. */
477+ char *(*help_filter) (int __key, __const char *__text, void *__input);
478+
479+ /* If non-zero the strings used in the argp library are translated using
480+ the domain described by this string. Otherwise the currently installed
481+ default domain is used. */
482+ const char *argp_domain;
483+};
484+
485+/* Possible KEY arguments to a help filter function. */
486+#define ARGP_KEY_HELP_PRE_DOC 0x2000001 /* Help text preceeding options. */
487+#define ARGP_KEY_HELP_POST_DOC 0x2000002 /* Help text following options. */
488+#define ARGP_KEY_HELP_HEADER 0x2000003 /* Option header string. */
489+#define ARGP_KEY_HELP_EXTRA 0x2000004 /* After all other documentation;
490+ TEXT is NULL for this key. */
491+/* Explanatory note emitted when duplicate option arguments have been
492+ suppressed. */
493+#define ARGP_KEY_HELP_DUP_ARGS_NOTE 0x2000005
494+#define ARGP_KEY_HELP_ARGS_DOC 0x2000006 /* Argument doc string. */
495+
496+/* When an argp has a non-zero CHILDREN field, it should point to a vector of
497+ argp_child structures, each of which describes a subsidiary argp. */
498+struct argp_child
499+{
500+ /* The child parser. */
501+ __const struct argp *argp;
502+
503+ /* Flags for this child. */
504+ int flags;
505+
506+ /* If non-zero, an optional header to be printed in help output before the
507+ child options. As a side-effect, a non-zero value forces the child
508+ options to be grouped together; to achieve this effect without actually
509+ printing a header string, use a value of "". */
510+ __const char *header;
511+
512+ /* Where to group the child options relative to the other (`consolidated')
513+ options in the parent argp; the values are the same as the GROUP field
514+ in argp_option structs, but all child-groupings follow parent options at
515+ a particular group level. If both this field and HEADER are zero, then
516+ they aren't grouped at all, but rather merged with the parent options
517+ (merging the child's grouping levels with the parents). */
518+ int group;
519+};
520+
521+/* Parsing state. This is provided to parsing functions called by argp,
522+ which may examine and, as noted, modify fields. */
523+struct argp_state
524+{
525+ /* The top level ARGP being parsed. */
526+ __const struct argp *root_argp;
527+
528+ /* The argument vector being parsed. May be modified. */
529+ int argc;
530+ char **argv;
531+
532+ /* The index in ARGV of the next arg that to be parsed. May be modified. */
533+ int next;
534+
535+ /* The flags supplied to argp_parse. May be modified. */
536+ unsigned flags;
537+
538+ /* While calling a parsing function with a key of ARGP_KEY_ARG, this is the
539+ number of the current arg, starting at zero, and incremented after each
540+ such call returns. At all other times, this is the number of such
541+ arguments that have been processed. */
542+ unsigned arg_num;
543+
544+ /* If non-zero, the index in ARGV of the first argument following a special
545+ `--' argument (which prevents anything following being interpreted as an
546+ option). Only set once argument parsing has proceeded past this point. */
547+ int quoted;
548+
549+ /* An arbitrary pointer passed in from the user. */
550+ void *input;
551+ /* Values to pass to child parsers. This vector will be the same length as
552+ the number of children for the current parser. */
553+ void **child_inputs;
554+
555+ /* For the parser's use. Initialized to 0. */
556+ void *hook;
557+
558+ /* The name used when printing messages. This is initialized to ARGV[0],
559+ or PROGRAM_INVOCATION_NAME if that is unavailable. */
560+ char *name;
561+
562+ /* Streams used when argp prints something. */
563+ FILE *err_stream; /* For errors; initialized to stderr. */
564+ FILE *out_stream; /* For information; initialized to stdout. */
565+
566+ void *pstate; /* Private, for use by argp. */
567+};
568+
569+/* Flags for argp_parse (note that the defaults are those that are
570+ convenient for program command line parsing): */
571+
572+/* Don't ignore the first element of ARGV. Normally (and always unless
573+ ARGP_NO_ERRS is set) the first element of the argument vector is
574+ skipped for option parsing purposes, as it corresponds to the program name
575+ in a command line. */
576+#define ARGP_PARSE_ARGV0 0x01
577+
578+/* Don't print error messages for unknown options to stderr; unless this flag
579+ is set, ARGP_PARSE_ARGV0 is ignored, as ARGV[0] is used as the program
580+ name in the error messages. This flag implies ARGP_NO_EXIT (on the
581+ assumption that silent exiting upon errors is bad behaviour). */
582+#define ARGP_NO_ERRS 0x02
583+
584+/* Don't parse any non-option args. Normally non-option args are parsed by
585+ calling the parse functions with a key of ARGP_KEY_ARG, and the actual arg
586+ as the value. Since it's impossible to know which parse function wants to
587+ handle it, each one is called in turn, until one returns 0 or an error
588+ other than ARGP_ERR_UNKNOWN; if an argument is handled by no one, the
589+ argp_parse returns prematurely (but with a return value of 0). If all
590+ args have been parsed without error, all parsing functions are called one
591+ last time with a key of ARGP_KEY_END. This flag needn't normally be set,
592+ as the normal behavior is to stop parsing as soon as some argument can't
593+ be handled. */
594+#define ARGP_NO_ARGS 0x04
595+
596+/* Parse options and arguments in the same order they occur on the command
597+ line -- normally they're rearranged so that all options come first. */
598+#define ARGP_IN_ORDER 0x08
599+
600+/* Don't provide the standard long option --help, which causes usage and
601+ option help information to be output to stdout, and exit (0) called. */
602+#define ARGP_NO_HELP 0x10
603+
604+/* Don't exit on errors (they may still result in error messages). */
605+#define ARGP_NO_EXIT 0x20
606+
607+/* Use the gnu getopt `long-only' rules for parsing arguments. */
608+#define ARGP_LONG_ONLY 0x40
609+
610+/* Turns off any message-printing/exiting options. */
611+#define ARGP_SILENT (ARGP_NO_EXIT | ARGP_NO_ERRS | ARGP_NO_HELP)
612+
613+/* Parse the options strings in ARGC & ARGV according to the options in ARGP.
614+ FLAGS is one of the ARGP_ flags above. If ARG_INDEX is non-NULL, the
615+ index in ARGV of the first unparsed option is returned in it. If an
616+ unknown option is present, ARGP_ERR_UNKNOWN is returned; if some parser
617+ routine returned a non-zero value, it is returned; otherwise 0 is
618+ returned. This function may also call exit unless the ARGP_NO_HELP flag
619+ is set. INPUT is a pointer to a value to be passed in to the parser. */
620+extern error_t argp_parse (__const struct argp *__restrict __argp,
621+ int __argc, char **__restrict __argv,
622+ unsigned __flags, int *__restrict __arg_index,
623+ void *__restrict __input);
624+
625+/* Global variables. */
626+
627+/* If defined or set by the user program to a non-zero value, then a default
628+ option --version is added (unless the ARGP_NO_HELP flag is used), which
629+ will print this string followed by a newline and exit (unless the
630+ ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
631+extern __const char *argp_program_version;
632+
633+/* If defined or set by the user program to a non-zero value, then a default
634+ option --version is added (unless the ARGP_NO_HELP flag is used), which
635+ calls this function with a stream to print the version to and a pointer to
636+ the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
637+ used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
638+extern void (*argp_program_version_hook) (FILE *__restrict __stream,
639+ struct argp_state *__restrict
640+ __state);
641+
642+/* If defined or set by the user program, it should point to string that is
643+ the bug-reporting address for the program. It will be printed by
644+ argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
645+ standard help messages), embedded in a sentence that says something like
646+ `Report bugs to ADDR.'. */
647+extern __const char *argp_program_bug_address;
648+
649+/* The exit status that argp will use when exiting due to a parsing error.
650+ If not defined or set by the user program, this defaults to EX_USAGE from
651+ <sysexits.h>. */
652+extern error_t argp_err_exit_status;
653+
654+/* Flags for argp_help. */
655+#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
656+#define ARGP_HELP_SHORT_USAGE 0x02 /* " but don't actually print options. */
657+#define ARGP_HELP_SEE 0x04 /* a `Try ... for more help' message. */
658+#define ARGP_HELP_LONG 0x08 /* a long help message. */
659+#define ARGP_HELP_PRE_DOC 0x10 /* doc string preceding long help. */
660+#define ARGP_HELP_POST_DOC 0x20 /* doc string following long help. */
661+#define ARGP_HELP_DOC (ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
662+#define ARGP_HELP_BUG_ADDR 0x40 /* bug report address */
663+#define ARGP_HELP_LONG_ONLY 0x80 /* modify output appropriately to
664+ reflect ARGP_LONG_ONLY mode. */
665+
666+/* These ARGP_HELP flags are only understood by argp_state_help. */
667+#define ARGP_HELP_EXIT_ERR 0x100 /* Call exit(1) instead of returning. */
668+#define ARGP_HELP_EXIT_OK 0x200 /* Call exit(0) instead of returning. */
669+
670+/* The standard thing to do after a program command line parsing error, if an
671+ error message has already been printed. */
672+#define ARGP_HELP_STD_ERR \
673+ (ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
674+/* The standard thing to do after a program command line parsing error, if no
675+ more specific error message has been printed. */
676+#define ARGP_HELP_STD_USAGE \
677+ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
678+/* The standard thing to do in response to a --help option. */
679+#define ARGP_HELP_STD_HELP \
680+ (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
681+ | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
682+
683+/* Output a usage message for ARGP to STREAM. FLAGS are from the set
684+ ARGP_HELP_*. */
685+extern void argp_help (__const struct argp *__restrict __argp,
686+ FILE *__restrict __stream,
687+ unsigned __flags, char *__restrict __name);
688+
689+/* The following routines are intended to be called from within an argp
690+ parsing routine (thus taking an argp_state structure as the first
691+ argument). They may or may not print an error message and exit, depending
692+ on the flags in STATE -- in any case, the caller should be prepared for
693+ them *not* to exit, and should return an appropiate error after calling
694+ them. [argp_usage & argp_error should probably be called argp_state_...,
695+ but they're used often enough that they should be short] */
696+
697+/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
698+ from the set ARGP_HELP_*. */
699+extern void argp_state_help (__const struct argp_state *__restrict __state,
700+ FILE *__restrict __stream,
701+ unsigned int __flags);
702+/* Possibly output the standard usage message for ARGP to stderr and exit. */
703+extern void argp_usage (__const struct argp_state *__state);
704+
705+/* If appropriate, print the printf string FMT and following args, preceded
706+ by the program name and `:', to stderr, and followed by a `Try ... --help'
707+ message, then exit (1). */
708+extern void argp_error (__const struct argp_state *__restrict __state,
709+ __const char *__restrict __fmt, ...)
710+ __attribute__ ((__format__ (__printf__, 2, 3)));
711+/* Similar to the standard gnu error-reporting function error(), but will
712+ respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
713+ to STATE->err_stream. This is useful for argument parsing code that is
714+ shared between program startup (when exiting is desired) and runtime
715+ option parsing (when typically an error code is returned instead). The
716+ difference between this function and argp_error is that the latter is for
717+ *parsing errors*, and the former is for other problems that occur during
718+ parsing but don't reflect a (syntactic) problem with the input. */
719+extern void argp_failure (__const struct argp_state *__restrict __state,
720+ int __status, int __errnum,
721+ __const char *__restrict __fmt, ...)
722+ __attribute__ ((__format__ (__printf__, 4, 5)));
723+/* Returns true if the option OPT is a valid short option. */
724+extern int _option_is_short (__const struct argp_option *__opt) __THROW;
725+extern int __option_is_short (__const struct argp_option *__opt) __THROW;
726+
727+/* Returns true if the option OPT is in fact the last (unused) entry in an
728+ options array. */
729+extern int _option_is_end (__const struct argp_option *__opt) __THROW;
730+extern int __option_is_end (__const struct argp_option *__opt) __THROW;
731+
732+/* Return the input field for ARGP in the parser corresponding to STATE; used
733+ by the help routines. */
734+/* We think this should not be exported */
735+extern void *__argp_input (__const struct argp *__restrict __argp,
736+ __const struct argp_state *__restrict __state)
737+ __THROW;
738+
739+#ifdef __USE_EXTERN_INLINES
740+
741+# ifndef ARGP_EI
742+# define ARGP_EI __extern_inline
743+# endif
744+
745+ARGP_EI void
746+argp_usage (__const struct argp_state *__state)
747+{
748+ argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
749+}
750+
751+ARGP_EI int
752+__NTH (__option_is_short (__const struct argp_option *__opt))
753+{
754+ if (__opt->flags & OPTION_DOC)
755+ return 0;
756+ else
757+ {
758+ int __key = __opt->key;
759+ return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
760+ }
761+}
762+
763+ARGP_EI int
764+__NTH (__option_is_end (__const struct argp_option *__opt))
765+{
766+ return !__opt->key && !__opt->name && !__opt->doc && !__opt->group;
767+}
768+#endif /* Use extern inlines. */
769+
770+#ifdef __cplusplus
771+}
772+#endif
773+
774+#endif /* argp.h */
775diff --git a/libc/sysdeps/linux/common/bits/getopt_int.h b/libc/sysdeps/linux/common/bits/getopt_int.h
776new file mode 100644
777index 0000000..291edfe
778--- /dev/null
779+++ b/libc/sysdeps/linux/common/bits/getopt_int.h
780@@ -0,0 +1,136 @@
781+/* Internal declarations for getopt.
782+ Copyright (C) 1989-1994,1996-1999,2001,2003,2004
783+ Free Software Foundation, Inc.
784+ This file is part of the GNU C Library.
785+
786+ The GNU C Library is free software; you can redistribute it and/or
787+ modify it under the terms of the GNU Lesser General Public
788+ License as published by the Free Software Foundation; either
789+ version 2.1 of the License, or (at your option) any later version.
790+
791+ The GNU C Library is distributed in the hope that it will be useful,
792+ but WITHOUT ANY WARRANTY; without even the implied warranty of
793+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
794+ Lesser General Public License for more details.
795+
796+ You should have received a copy of the GNU Lesser General Public
797+ License along with the GNU C Library; if not, write to the Free
798+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
799+ 02111-1307 USA. */
800+
801+#ifndef _GETOPT_INT_H
802+#define _GETOPT_INT_H 1
803+
804+extern int _getopt_internal (int ___argc, char *const *___argv,
805+ const char *__shortopts,
806+ const struct option *__longopts, int *__longind,
807+ int __long_only) attribute_hidden;
808+
809+
810+/* Reentrant versions which can handle parsing multiple argument
811+ vectors at the same time. */
812+
813+/* For __ordering member */
814+enum {
815+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
816+};
817+
818+/* Data type for reentrant functions. */
819+
820+struct _getopt_data
821+{
822+ /* These have exactly the same meaning as the corresponding global
823+ variables, except that they are used for the reentrant
824+ versions of getopt. */
825+ int optind;
826+ int opterr;
827+ char *optarg;
828+ smalluint optopt; /* we store characters here, a byte is enough */
829+
830+ /* Internal members. */
831+
832+ /* True if the internal members have been initialized. */
833+ smallint __initialized;
834+
835+ /* Describe how to deal with options that follow non-option ARGV-elements.
836+
837+ If the caller did not specify anything,
838+ the default is REQUIRE_ORDER if the environment variable
839+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
840+
841+ REQUIRE_ORDER means don't recognize them as options;
842+ stop option processing when the first non-option is seen.
843+ This is what Unix does.
844+ This mode of operation is selected by either setting the environment
845+ variable POSIXLY_CORRECT, or using `+' as the first character
846+ of the list of option characters.
847+
848+ PERMUTE is the default. We permute the contents of ARGV as we
849+ scan, so that eventually all the non-options are at the end.
850+ This allows options to be given in any order, even with programs
851+ that were not written to expect this.
852+
853+ RETURN_IN_ORDER is an option available to programs that were
854+ written to expect options and other ARGV-elements in any order
855+ and that care about the ordering of the two. We describe each
856+ non-option ARGV-element as if it were the argument of an option
857+ with character code 1. Using `-' as the first character of the
858+ list of option characters selects this mode of operation.
859+
860+ The special argument `--' forces an end of option-scanning regardless
861+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
862+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
863+ smallint __ordering;
864+
865+ /* If the POSIXLY_CORRECT environment variable is set. */
866+ smallint __posixly_correct;
867+
868+ /* The next char to be scanned in the option-element
869+ in which the last option character we returned was found.
870+ This allows us to pick up the scan where we left off.
871+
872+ If this is zero, or a null string, it means resume the scan
873+ by advancing to the next ARGV-element. */
874+ char *__nextchar;
875+
876+
877+ /* Handle permutation of arguments. */
878+
879+ /* Describe the part of ARGV that contains non-options that have
880+ been skipped. `first_nonopt' is the index in ARGV of the first
881+ of them; `last_nonopt' is the index after the last of them. */
882+
883+ int __first_nonopt;
884+ int __last_nonopt;
885+
886+#if defined _LIBC && defined USE_NONOPTION_FLAGS
887+ int __nonoption_flags_max_len;
888+ int __nonoption_flags_len;
889+# endif
890+};
891+
892+/* The initializer is necessary to set OPTIND and OPTERR to their
893+ default values and to clear the initialization flag. */
894+#define _GETOPT_DATA_INITIALIZER { 1, 1 }
895+
896+#if 0 /* first is static on uClibc, the others not used */
897+extern int _getopt_internal_r (int ___argc, char *const *___argv,
898+ const char *__shortopts,
899+ const struct option *__longopts, int *__longind,
900+ int __long_only, struct _getopt_data *__data);
901+#endif
902+#if defined __UCLIBC_HAS_GNU_GETOPT__ || defined __UCLIBC_HAS_GETOPT_LONG__
903+#ifndef __need_getopt
904+extern int _getopt_long_r (int ___argc, char *const *___argv,
905+ const char *__shortopts,
906+ const struct option *__longopts, int *__longind,
907+ struct _getopt_data *__data);
908+
909+extern int _getopt_long_only_r (int ___argc, char *const *___argv,
910+ const char *__shortopts,
911+ const struct option *__longopts,
912+ int *__longind,
913+ struct _getopt_data *__data);
914+#endif
915+#endif
916+#endif /* getopt_int.h */
917diff --git a/libc/unistd/getopt.c b/libc/unistd/getopt.c
918index f63482b..db5e12c 100644
919--- a/libc/unistd/getopt.c
920+++ b/libc/unistd/getopt.c
921@@ -105,7 +105,7 @@
922 they can distinguish the relative order of options and other arguments. */
923
924 #include <getopt.h>
925-#include "getopt_int.h"
926+#include <bits/getopt_int.h>
927
928
929 /* For communication from `getopt' to the caller.
930@@ -1170,6 +1170,15 @@ getopt_long (int argc, char *const *argv, const char *options,
931 return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
932 }
933
934+int
935+_getopt_long_r (int argc, char *const *argv, const char *options,
936+ const struct option *long_options, int *opt_index,
937+ struct _getopt_data *d)
938+{
939+ return _getopt_internal_r (argc, argv, options, long_options, opt_index,
940+ 0, d);
941+}
942+
943 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
944 If an option that starts with '-' (not '--') doesn't match a long option,
945 but does match a short option, it is parsed as a short option
946@@ -1183,4 +1192,12 @@ getopt_long_only (int argc, char *const *argv, const char *options,
947 }
948 #endif /* __UCLIBC_HAS_GETOPT_LONG__ */
949
950+int
951+_getopt_long_only_r (int argc, char *const *argv, const char *options,
952+ const struct option *long_options, int *opt_index,
953+ struct _getopt_data *d)
954+{
955+ return _getopt_internal_r (argc, argv, options, long_options, opt_index, 1, d);
956+}
957+
958 #endif /* Not ELIDE_CODE. */
959diff --git a/libuargp/Makefile b/libuargp/Makefile
960new file mode 100644
961index 0000000..45acdd9
962--- /dev/null
963+++ b/libuargp/Makefile
964@@ -0,0 +1,14 @@
965+# Makefile for uClibc (libuargp)
966+#
967+# Copyright (C) 2010 STMicroelectronics Ltd
968+# Author(s): Filippo Arcidiacono <filippo.arcidiacono at st.com>
969+#
970+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
971+#
972+
973+top_srcdir=../
974+top_builddir=../
975+include $(top_builddir)Rules.mak
976+all: libs
977+include Makefile.in
978+include $(top_srcdir)Makerules
979diff --git a/libuargp/Makefile.in b/libuargp/Makefile.in
980new file mode 100644
981index 0000000..1498abb
982--- /dev/null
983+++ b/libuargp/Makefile.in
984@@ -0,0 +1,73 @@
985+# Makefile for uClibc (libuargp)
986+#
987+# Copyright (C) 2009, 2010 STMicroelectronics Ltd.
988+# Author(s): Salvatore Cro <salvatore.cro at st.com>
989+# - First implementation, embedded into libc
990+# Filippo Arcidiacono <filippo.arcidiacono at st.com>
991+# - Reworked for stand-alone libuargp implementation
992+
993+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
994+#
995+
996+CFLAGS-libuargp := -DNOT_IN_libc -DIS_IN_libuargp $(SSP_ALL_CFLAGS)
997+
998+LDFLAGS-libuargp.so := $(LDFLAGS)
999+
1000+LIBS-libuargp.so := $(LIBS)
1001+
1002+libuargp_FULL_NAME := libuargp-$(VERSION).so
1003+
1004+libuargp_DIR := $(top_srcdir)libuargp
1005+libuargp_OUT := $(top_builddir)libuargp
1006+
1007+libuargp_SRC-y :=
1008+libuargp_SRC-$(UCLIBC_HAS_ARGP) := $(addsuffix .c,$(addprefix argp-, ba \
1009+ eexst fmtstream fs-xinl help parse pv pvh xinl))
1010+
1011+CFLAGS-argp-xinl.c = -fgnu89-inline
1012+
1013+libuargp_SRC := $(addprefix $(libuargp_DIR)/,$(libuargp_SRC-y))
1014+libuargp_OBJ := $(patsubst $(libuargp_DIR)/%.c,$(libuargp_OUT)/%.o,$(libuargp_SRC))
1015+
1016+libuargp_SRCS := $(libuargp_SRC)
1017+libuargp_OBJS := $(libuargp_OBJ)
1018+
1019+ifeq ($(DOPIC),y)
1020+libuargp-a-y := $(libuargp_OBJS:.o=.os)
1021+else
1022+libuargp-a-y := $(libuargp_OBJS)
1023+endif
1024+libuargp-so-y := $(libuargp_OBJS:.o=.os)
1025+
1026+lib-a-$(UCLIBC_HAS_ARGP) += $(top_builddir)lib/libuargp.a
1027+lib-so-$(UCLIBC_HAS_ARGP) += $(top_builddir)lib/libuargp.so
1028+
1029+objclean-y += CLEAN_libuargp
1030+
1031+ifeq ($(DOMULTI),n)
1032+ifeq ($(DOPIC),y)
1033+$(top_builddir)lib/libuargp.so: $(top_builddir)lib/libuargp.a $(libc.depend)
1034+else
1035+$(top_builddir)lib/libuargp.so: $(libuargp_OUT)/libuargp_so.a $(libc.depend)
1036+endif
1037+ $(call link.so,$(libuargp_FULL_NAME),$(MAJOR_VERSION))
1038+else
1039+$(top_builddir)lib/libuargp.so: $(libuargp_OUT)/libuargp.oS $(libc.depend)
1040+ $(call linkm.so,$(libuargp_FULL_NAME),$(MAJOR_VERSION))
1041+endif
1042+
1043+$(libuargp_OUT)/libuargp_so.a: $(libuargp-so-y)
1044+ $(Q)$(RM) $@
1045+ $(do_ar)
1046+
1047+$(libuargp_OUT)/libuargp.oS: $(libuargp_SRCS)
1048+ $(Q)$(RM) $@
1049+ $(compile-m)
1050+
1051+$(top_builddir)lib/libuargp.a: $(libuargp-a-y)
1052+ $(Q)$(INSTALL) -d $(dir $@)
1053+ $(Q)$(RM) $@
1054+ $(do_ar)
1055+
1056+CLEAN_libuargp:
1057+ $(do_rm) $(addprefix $(libuargp_OUT)/*., o os oS a)
1058diff --git a/libuargp/argp-ba.c b/libuargp/argp-ba.c
1059new file mode 100644
1060index 0000000..3522b02
1061--- /dev/null
1062+++ b/libuargp/argp-ba.c
1063@@ -0,0 +1,26 @@
1064+/* Default definition for ARGP_PROGRAM_BUG_ADDRESS.
1065+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
1066+ This file is part of the GNU C Library.
1067+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1068+
1069+ The GNU C Library is free software; you can redistribute it and/or
1070+ modify it under the terms of the GNU Lesser General Public
1071+ License as published by the Free Software Foundation; either
1072+ version 2.1 of the License, or (at your option) any later version.
1073+
1074+ The GNU C Library is distributed in the hope that it will be useful,
1075+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1076+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1077+ Lesser General Public License for more details.
1078+
1079+ You should have received a copy of the GNU Lesser General Public
1080+ License along with the GNU C Library; if not, write to the Free
1081+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1082+ 02111-1307 USA. */
1083+
1084+/* If set by the user program, it should point to string that is the
1085+ bug-reporting address for the program. It will be printed by argp_help if
1086+ the ARGP_HELP_BUG_ADDR flag is set (as it is by various standard help
1087+ messages), embedded in a sentence that says something like `Report bugs to
1088+ ADDR.'. */
1089+const char *argp_program_bug_address;
1090diff --git a/libuargp/argp-eexst.c b/libuargp/argp-eexst.c
1091new file mode 100644
1092index 0000000..445b68d
1093--- /dev/null
1094+++ b/libuargp/argp-eexst.c
1095@@ -0,0 +1,32 @@
1096+/* Default definition for ARGP_ERR_EXIT_STATUS
1097+ Copyright (C) 1997 Free Software Foundation, Inc.
1098+ This file is part of the GNU C Library.
1099+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1100+
1101+ The GNU C Library is free software; you can redistribute it and/or
1102+ modify it under the terms of the GNU Lesser General Public
1103+ License as published by the Free Software Foundation; either
1104+ version 2.1 of the License, or (at your option) any later version.
1105+
1106+ The GNU C Library is distributed in the hope that it will be useful,
1107+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1108+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1109+ Lesser General Public License for more details.
1110+
1111+ You should have received a copy of the GNU Lesser General Public
1112+ License along with the GNU C Library; if not, write to the Free
1113+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1114+ 02111-1307 USA. */
1115+
1116+#ifdef HAVE_CONFIG_H
1117+# include <config.h>
1118+#endif
1119+
1120+#include <sysexits.h>
1121+
1122+#include <argp.h>
1123+
1124+/* The exit status that argp will use when exiting due to a parsing error.
1125+ If not defined or set by the user program, this defaults to EX_USAGE from
1126+ <sysexits.h>. */
1127+error_t argp_err_exit_status = EX_USAGE;
1128diff --git a/libuargp/argp-fmtstream.c b/libuargp/argp-fmtstream.c
1129new file mode 100644
1130index 0000000..75227f9
1131--- /dev/null
1132+++ b/libuargp/argp-fmtstream.c
1133@@ -0,0 +1,439 @@
1134+/* Word-wrapping and line-truncating streams
1135+ Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
1136+ This file is part of the GNU C Library.
1137+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1138+
1139+ The GNU C Library is free software; you can redistribute it and/or
1140+ modify it under the terms of the GNU Lesser General Public
1141+ License as published by the Free Software Foundation; either
1142+ version 2.1 of the License, or (at your option) any later version.
1143+
1144+ The GNU C Library is distributed in the hope that it will be useful,
1145+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1146+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1147+ Lesser General Public License for more details.
1148+
1149+ You should have received a copy of the GNU Lesser General Public
1150+ License along with the GNU C Library; if not, write to the Free
1151+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1152+ 02111-1307 USA.
1153+
1154+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
1155+*/
1156+
1157+/* This package emulates glibc `line_wrap_stream' semantics for systems that
1158+ don't have that. */
1159+
1160+#ifdef HAVE_CONFIG_H
1161+# include <config.h>
1162+#endif
1163+
1164+#include <stdlib.h>
1165+#include <string.h>
1166+#include <errno.h>
1167+#include <stdarg.h>
1168+#include <ctype.h>
1169+
1170+#include "argp-fmtstream.h"
1171+
1172+#ifndef ARGP_FMTSTREAM_USE_LINEWRAP
1173+
1174+#ifndef isblank
1175+#define isblank(ch) ((ch)==' ' || (ch)=='\t')
1176+#endif
1177+
1178+#if defined _LIBC && defined USE_IN_LIBIO
1179+# include <wchar.h>
1180+# include <libio/libioP.h>
1181+# define __vsnprintf(s, l, f, a) _IO_vsnprintf (s, l, f, a)
1182+#else
1183+# define __vsnprintf(s, l, f, a) vsnprintf (s, l, f, a)
1184+#endif
1185+
1186+#define INIT_BUF_SIZE 200
1187+#define PRINTF_SIZE_GUESS 150
1188+
1189+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
1190+ written on it with LMARGIN spaces and limits them to RMARGIN columns
1191+ total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
1192+ replacing the whitespace before them with a newline and WMARGIN spaces.
1193+ Otherwise, chars beyond RMARGIN are simply dropped until a newline.
1194+ Returns NULL if there was an error. */
1195+argp_fmtstream_t
1196+__argp_make_fmtstream (FILE *stream,
1197+ size_t lmargin, size_t rmargin, ssize_t wmargin)
1198+{
1199+ argp_fmtstream_t fs;
1200+
1201+ fs = (struct argp_fmtstream *) malloc (sizeof (struct argp_fmtstream));
1202+ if (fs != NULL)
1203+ {
1204+ fs->stream = stream;
1205+
1206+ fs->lmargin = lmargin;
1207+ fs->rmargin = rmargin;
1208+ fs->wmargin = wmargin;
1209+ fs->point_col = 0;
1210+ fs->point_offs = 0;
1211+
1212+ fs->buf = (char *) malloc (INIT_BUF_SIZE);
1213+ if (! fs->buf)
1214+ {
1215+ free (fs);
1216+ fs = 0;
1217+ }
1218+ else
1219+ {
1220+ fs->p = fs->buf;
1221+ fs->end = fs->buf + INIT_BUF_SIZE;
1222+ }
1223+ }
1224+
1225+ return fs;
1226+}
1227+#if 0
1228+/* Not exported. */
1229+#ifdef weak_alias
1230+weak_alias (__argp_make_fmtstream, argp_make_fmtstream)
1231+#endif
1232+#endif
1233+
1234+/* Flush FS to its stream, and free it (but don't close the stream). */
1235+void
1236+__argp_fmtstream_free (argp_fmtstream_t fs)
1237+{
1238+ __argp_fmtstream_update (fs);
1239+ if (fs->p > fs->buf)
1240+ {
1241+#ifdef USE_IN_LIBIO
1242+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
1243+#else
1244+ fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
1245+#endif
1246+ }
1247+ free (fs->buf);
1248+ free (fs);
1249+}
1250+#if 0
1251+/* Not exported. */
1252+#ifdef weak_alias
1253+weak_alias (__argp_fmtstream_free, argp_fmtstream_free)
1254+#endif
1255+#endif
1256+
1257+/* Process FS's buffer so that line wrapping is done from POINT_OFFS to the
1258+ end of its buffer. This code is mostly from glibc stdio/linewrap.c. */
1259+void
1260+__argp_fmtstream_update (argp_fmtstream_t fs)
1261+{
1262+ char *buf, *nl;
1263+ size_t len;
1264+
1265+ /* Scan the buffer for newlines. */
1266+ buf = fs->buf + fs->point_offs;
1267+ while (buf < fs->p)
1268+ {
1269+ size_t r;
1270+
1271+ if (fs->point_col == 0 && fs->lmargin != 0)
1272+ {
1273+ /* We are starting a new line. Print spaces to the left margin. */
1274+ const size_t pad = fs->lmargin;
1275+ if (fs->p + pad < fs->end)
1276+ {
1277+ /* We can fit in them in the buffer by moving the
1278+ buffer text up and filling in the beginning. */
1279+ memmove (buf + pad, buf, fs->p - buf);
1280+ fs->p += pad; /* Compensate for bigger buffer. */
1281+ memset (buf, ' ', pad); /* Fill in the spaces. */
1282+ buf += pad; /* Don't bother searching them. */
1283+ }
1284+ else
1285+ {
1286+ /* No buffer space for spaces. Must flush. */
1287+ size_t i;
1288+ for (i = 0; i < pad; i++)
1289+ {
1290+#ifdef USE_IN_LIBIO
1291+ if (_IO_fwide (fs->stream, 0) > 0)
1292+ putwc_unlocked (L' ', fs->stream);
1293+ else
1294+#endif
1295+ putc_unlocked (' ', fs->stream);
1296+ }
1297+ }
1298+ fs->point_col = pad;
1299+ }
1300+
1301+ len = fs->p - buf;
1302+ nl = memchr (buf, '\n', len);
1303+
1304+ if (fs->point_col < 0)
1305+ fs->point_col = 0;
1306+
1307+ if (!nl)
1308+ {
1309+ /* The buffer ends in a partial line. */
1310+
1311+ if (fs->point_col + len < fs->rmargin)
1312+ {
1313+ /* The remaining buffer text is a partial line and fits
1314+ within the maximum line width. Advance point for the
1315+ characters to be written and stop scanning. */
1316+ fs->point_col += len;
1317+ break;
1318+ }
1319+ else
1320+ /* Set the end-of-line pointer for the code below to
1321+ the end of the buffer. */
1322+ nl = fs->p;
1323+ }
1324+ else if (fs->point_col + (nl - buf) < (ssize_t) fs->rmargin)
1325+ {
1326+ /* The buffer contains a full line that fits within the maximum
1327+ line width. Reset point and scan the next line. */
1328+ fs->point_col = 0;
1329+ buf = nl + 1;
1330+ continue;
1331+ }
1332+
1333+ /* This line is too long. */
1334+ r = fs->rmargin - 1;
1335+
1336+ if (fs->wmargin < 0)
1337+ {
1338+ /* Truncate the line by overwriting the excess with the
1339+ newline and anything after it in the buffer. */
1340+ if (nl < fs->p)
1341+ {
1342+ memmove (buf + (r - fs->point_col), nl, fs->p - nl);
1343+ fs->p -= buf + (r - fs->point_col) - nl;
1344+ /* Reset point for the next line and start scanning it. */
1345+ fs->point_col = 0;
1346+ buf += r + 1; /* Skip full line plus \n. */
1347+ }
1348+ else
1349+ {
1350+ /* The buffer ends with a partial line that is beyond the
1351+ maximum line width. Advance point for the characters
1352+ written, and discard those past the max from the buffer. */
1353+ fs->point_col += len;
1354+ fs->p -= fs->point_col - r;
1355+ break;
1356+ }
1357+ }
1358+ else
1359+ {
1360+ /* Do word wrap. Go to the column just past the maximum line
1361+ width and scan back for the beginning of the word there.
1362+ Then insert a line break. */
1363+
1364+ char *p, *nextline;
1365+ int i;
1366+
1367+ p = buf + (r + 1 - fs->point_col);
1368+ while (p >= buf && !isblank (*p))
1369+ --p;
1370+ nextline = p + 1; /* This will begin the next line. */
1371+
1372+ if (nextline > buf)
1373+ {
1374+ /* Swallow separating blanks. */
1375+ if (p >= buf)
1376+ do
1377+ --p;
1378+ while (p >= buf && isblank (*p));
1379+ nl = p + 1; /* The newline will replace the first blank. */
1380+ }
1381+ else
1382+ {
1383+ /* A single word that is greater than the maximum line width.
1384+ Oh well. Put it on an overlong line by itself. */
1385+ p = buf + (r + 1 - fs->point_col);
1386+ /* Find the end of the long word. */
1387+ do
1388+ ++p;
1389+ while (p < nl && !isblank (*p));
1390+ if (p == nl)
1391+ {
1392+ /* It already ends a line. No fussing required. */
1393+ fs->point_col = 0;
1394+ buf = nl + 1;
1395+ continue;
1396+ }
1397+ /* We will move the newline to replace the first blank. */
1398+ nl = p;
1399+ /* Swallow separating blanks. */
1400+ do
1401+ ++p;
1402+ while (isblank (*p));
1403+ /* The next line will start here. */
1404+ nextline = p;
1405+ }
1406+
1407+ /* Note: There are a bunch of tests below for
1408+ NEXTLINE == BUF + LEN + 1; this case is where NL happens to fall
1409+ at the end of the buffer, and NEXTLINE is in fact empty (and so
1410+ we need not be careful to maintain its contents). */
1411+
1412+ if ((nextline == buf + len + 1
1413+ ? fs->end - nl < fs->wmargin + 1
1414+ : nextline - (nl + 1) < fs->wmargin)
1415+ && fs->p > nextline)
1416+ {
1417+ /* The margin needs more blanks than we removed. */
1418+ if (fs->end - fs->p > fs->wmargin + 1)
1419+ /* Make some space for them. */
1420+ {
1421+ size_t mv = fs->p - nextline;
1422+ memmove (nl + 1 + fs->wmargin, nextline, mv);
1423+ nextline = nl + 1 + fs->wmargin;
1424+ len = nextline + mv - buf;
1425+ *nl++ = '\n';
1426+ }
1427+ else
1428+ /* Output the first line so we can use the space. */
1429+ {
1430+#if defined _LIBC && defined USE_IN_LIBIO
1431+ __fxprintf (fs->stream, "%.*s\n",
1432+ (int) (nl - fs->buf), fs->buf);
1433+#else
1434+ if (nl > fs->buf)
1435+ fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
1436+ putc_unlocked ('\n', fs->stream);
1437+#endif
1438+
1439+ len += buf - fs->buf;
1440+ nl = buf = fs->buf;
1441+ }
1442+ }
1443+ else
1444+ /* We can fit the newline and blanks in before
1445+ the next word. */
1446+ *nl++ = '\n';
1447+
1448+ if (nextline - nl >= fs->wmargin
1449+ || (nextline == buf + len + 1 && fs->end - nextline >= fs->wmargin))
1450+ /* Add blanks up to the wrap margin column. */
1451+ for (i = 0; i < fs->wmargin; ++i)
1452+ *nl++ = ' ';
1453+ else
1454+ for (i = 0; i < fs->wmargin; ++i)
1455+#ifdef USE_IN_LIBIO
1456+ if (_IO_fwide (fs->stream, 0) > 0)
1457+ putwc_unlocked (L' ', fs->stream);
1458+ else
1459+#endif
1460+ putc_unlocked (' ', fs->stream);
1461+
1462+ /* Copy the tail of the original buffer into the current buffer
1463+ position. */
1464+ if (nl < nextline)
1465+ memmove (nl, nextline, buf + len - nextline);
1466+ len -= nextline - buf;
1467+
1468+ /* Continue the scan on the remaining lines in the buffer. */
1469+ buf = nl;
1470+
1471+ /* Restore bufp to include all the remaining text. */
1472+ fs->p = nl + len;
1473+
1474+ /* Reset the counter of what has been output this line. If wmargin
1475+ is 0, we want to avoid the lmargin getting added, so we set
1476+ point_col to a magic value of -1 in that case. */
1477+ fs->point_col = fs->wmargin ? fs->wmargin : -1;
1478+ }
1479+ }
1480+
1481+ /* Remember that we've scanned as far as the end of the buffer. */
1482+ fs->point_offs = fs->p - fs->buf;
1483+}
1484+
1485+/* Ensure that FS has space for AMOUNT more bytes in its buffer, either by
1486+ growing the buffer, or by flushing it. True is returned iff we succeed. */
1487+int
1488+__argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
1489+{
1490+ if ((size_t) (fs->end - fs->p) < amount)
1491+ {
1492+ ssize_t wrote;
1493+
1494+ /* Flush FS's buffer. */
1495+ __argp_fmtstream_update (fs);
1496+
1497+#if defined _LIBC && defined USE_IN_LIBIO
1498+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
1499+ wrote = fs->p - fs->buf;
1500+#else
1501+ wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
1502+#endif
1503+ if (wrote == fs->p - fs->buf)
1504+ {
1505+ fs->p = fs->buf;
1506+ fs->point_offs = 0;
1507+ }
1508+ else
1509+ {
1510+ fs->p -= wrote;
1511+ fs->point_offs -= wrote;
1512+ memmove (fs->buf, fs->buf + wrote, fs->p - fs->buf);
1513+ return 0;
1514+ }
1515+
1516+ if ((size_t) (fs->end - fs->buf) < amount)
1517+ /* Gotta grow the buffer. */
1518+ {
1519+ size_t old_size = fs->end - fs->buf;
1520+ size_t new_size = old_size + amount;
1521+ char *new_buf;
1522+
1523+ if (new_size < old_size || ! (new_buf = realloc (fs->buf, new_size)))
1524+ {
1525+ __set_errno (ENOMEM);
1526+ return 0;
1527+ }
1528+
1529+ fs->buf = new_buf;
1530+ fs->end = new_buf + new_size;
1531+ fs->p = fs->buf;
1532+ }
1533+ }
1534+
1535+ return 1;
1536+}
1537+
1538+ssize_t
1539+__argp_fmtstream_printf (struct argp_fmtstream *fs, const char *fmt, ...)
1540+{
1541+ int out;
1542+ size_t avail;
1543+ size_t size_guess = PRINTF_SIZE_GUESS; /* How much space to reserve. */
1544+
1545+ do
1546+ {
1547+ va_list args;
1548+
1549+ if (! __argp_fmtstream_ensure (fs, size_guess))
1550+ return -1;
1551+
1552+ va_start (args, fmt);
1553+ avail = fs->end - fs->p;
1554+ out = __vsnprintf (fs->p, avail, fmt, args);
1555+ va_end (args);
1556+ if ((size_t) out >= avail)
1557+ size_guess = out + 1;
1558+ }
1559+ while ((size_t) out >= avail);
1560+
1561+ fs->p += out;
1562+
1563+ return out;
1564+}
1565+#if 0
1566+/* Not exported. */
1567+#ifdef weak_alias
1568+weak_alias (__argp_fmtstream_printf, argp_fmtstream_printf)
1569+#endif
1570+#endif
1571+
1572+#endif /* !ARGP_FMTSTREAM_USE_LINEWRAP */
1573diff --git a/libuargp/argp-fmtstream.h b/libuargp/argp-fmtstream.h
1574new file mode 100644
1575index 0000000..ca7c834
1576--- /dev/null
1577+++ b/libuargp/argp-fmtstream.h
1578@@ -0,0 +1,314 @@
1579+/* Word-wrapping and line-truncating streams.
1580+ Copyright (C) 1997 Free Software Foundation, Inc.
1581+ This file is part of the GNU C Library.
1582+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1583+
1584+ The GNU C Library is free software; you can redistribute it and/or
1585+ modify it under the terms of the GNU Lesser General Public
1586+ License as published by the Free Software Foundation; either
1587+ version 2.1 of the License, or (at your option) any later version.
1588+
1589+ The GNU C Library is distributed in the hope that it will be useful,
1590+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1591+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1592+ Lesser General Public License for more details.
1593+
1594+ You should have received a copy of the GNU Lesser General Public
1595+ License along with the GNU C Library; if not, write to the Free
1596+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1597+ 02111-1307 USA.
1598+
1599+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
1600+*/
1601+
1602+/* This package emulates glibc `line_wrap_stream' semantics for systems that
1603+ don't have that. If the system does have it, it is just a wrapper for
1604+ that. This header file is only used internally while compiling argp, and
1605+ shouldn't be installed. */
1606+
1607+#ifndef _ARGP_FMTSTREAM_H
1608+#define _ARGP_FMTSTREAM_H
1609+
1610+#include <stdio.h>
1611+#include <string.h>
1612+#include <unistd.h>
1613+
1614+#ifndef __attribute__
1615+/* This feature is available in gcc versions 2.5 and later. */
1616+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(__STRICT_ANSI__)
1617+# define __attribute__(Spec) /* empty */
1618+# endif
1619+/* The __-protected variants of `format' and `printf' attributes
1620+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
1621+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) || defined(__STRICT_ANSI__)
1622+# define __format__ format
1623+# define __printf__ printf
1624+# endif
1625+#endif
1626+
1627+#if 0 /* uClibc: disabled */
1628+#if (_LIBC - 0 && !defined (USE_IN_LIBIO)) \
1629+ || (defined (__GNU_LIBRARY__) && defined (HAVE_LINEWRAP_H))
1630+/* line_wrap_stream is available, so use that. */
1631+#define ARGP_FMTSTREAM_USE_LINEWRAP
1632+#endif
1633+#else
1634+/* line_wrap stream NOT available */
1635+# undef ARGP_FMTSTREAM_USE_LINEWRAP
1636+#endif
1637+
1638+#ifdef ARGP_FMTSTREAM_USE_LINEWRAP
1639+/* Just be a simple wrapper for line_wrap_stream; the semantics are
1640+ *slightly* different, as line_wrap_stream doesn't actually make a new
1641+ object, it just modifies the given stream (reversibly) to do
1642+ line-wrapping. Since we control who uses this code, it doesn't matter. */
1643+
1644+#include <linewrap.h>
1645+
1646+typedef FILE *argp_fmtstream_t;
1647+
1648+#define argp_make_fmtstream line_wrap_stream
1649+#define __argp_make_fmtstream line_wrap_stream
1650+#define argp_fmtstream_free line_unwrap_stream
1651+#define __argp_fmtstream_free line_unwrap_stream
1652+
1653+#define __argp_fmtstream_putc(fs,ch) putc(ch,fs)
1654+#define argp_fmtstream_putc(fs,ch) putc(ch,fs)
1655+#define __argp_fmtstream_puts(fs,str) fputs(str,fs)
1656+#define argp_fmtstream_puts(fs,str) fputs(str,fs)
1657+#define __argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
1658+#define argp_fmtstream_write(fs,str,len) fwrite(str,1,len,fs)
1659+#define __argp_fmtstream_printf fprintf
1660+#define argp_fmtstream_printf fprintf
1661+
1662+#define __argp_fmtstream_lmargin line_wrap_lmargin
1663+#define argp_fmtstream_lmargin line_wrap_lmargin
1664+#define __argp_fmtstream_set_lmargin line_wrap_set_lmargin
1665+#define argp_fmtstream_set_lmargin line_wrap_set_lmargin
1666+#define __argp_fmtstream_rmargin line_wrap_rmargin
1667+#define argp_fmtstream_rmargin line_wrap_rmargin
1668+#define __argp_fmtstream_set_rmargin line_wrap_set_rmargin
1669+#define argp_fmtstream_set_rmargin line_wrap_set_rmargin
1670+#define __argp_fmtstream_wmargin line_wrap_wmargin
1671+#define argp_fmtstream_wmargin line_wrap_wmargin
1672+#define __argp_fmtstream_set_wmargin line_wrap_set_wmargin
1673+#define argp_fmtstream_set_wmargin line_wrap_set_wmargin
1674+#define __argp_fmtstream_point line_wrap_point
1675+#define argp_fmtstream_point line_wrap_point
1676+
1677+#else /* !ARGP_FMTSTREAM_USE_LINEWRAP */
1678+/* Guess we have to define our own version. */
1679+
1680+#ifndef __const
1681+#define __const const
1682+#endif
1683+
1684+struct argp_fmtstream
1685+{
1686+ FILE *stream; /* The stream we're outputting to. */
1687+
1688+ size_t lmargin, rmargin; /* Left and right margins. */
1689+ ssize_t wmargin; /* Margin to wrap to, or -1 to truncate. */
1690+
1691+ /* Point in buffer to which we've processed for wrapping, but not output. */
1692+ size_t point_offs;
1693+ /* Output column at POINT_OFFS, or -1 meaning 0 but don't add lmargin. */
1694+ ssize_t point_col;
1695+
1696+ char *buf; /* Output buffer. */
1697+ char *p; /* Current end of text in BUF. */
1698+ char *end; /* Absolute end of BUF. */
1699+};
1700+
1701+typedef struct argp_fmtstream *argp_fmtstream_t;
1702+
1703+/* Return an argp_fmtstream that outputs to STREAM, and which prefixes lines
1704+ written on it with LMARGIN spaces and limits them to RMARGIN columns
1705+ total. If WMARGIN >= 0, words that extend past RMARGIN are wrapped by
1706+ replacing the whitespace before them with a newline and WMARGIN spaces.
1707+ Otherwise, chars beyond RMARGIN are simply dropped until a newline.
1708+ Returns NULL if there was an error. */
1709+extern argp_fmtstream_t __argp_make_fmtstream (FILE *__stream,
1710+ size_t __lmargin,
1711+ size_t __rmargin,
1712+ ssize_t __wmargin);
1713+extern argp_fmtstream_t argp_make_fmtstream (FILE *__stream,
1714+ size_t __lmargin,
1715+ size_t __rmargin,
1716+ ssize_t __wmargin);
1717+
1718+/* Flush __FS to its stream, and free it (but don't close the stream). */
1719+extern void __argp_fmtstream_free (argp_fmtstream_t __fs);
1720+extern void argp_fmtstream_free (argp_fmtstream_t __fs);
1721+
1722+extern ssize_t __argp_fmtstream_printf (argp_fmtstream_t __fs,
1723+ __const char *__fmt, ...)
1724+ __attribute__ ((__format__ (printf, 2, 3)));
1725+extern ssize_t argp_fmtstream_printf (argp_fmtstream_t __fs,
1726+ __const char *__fmt, ...)
1727+ __attribute__ ((__format__ (printf, 2, 3)));
1728+
1729+extern int __argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
1730+extern int argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch);
1731+
1732+extern int __argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
1733+extern int argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str);
1734+
1735+extern size_t __argp_fmtstream_write (argp_fmtstream_t __fs,
1736+ __const char *__str, size_t __len);
1737+extern size_t argp_fmtstream_write (argp_fmtstream_t __fs,
1738+ __const char *__str, size_t __len);
1739+
1740+/* Access macros for various bits of state. */
1741+#define argp_fmtstream_lmargin(__fs) ((__fs)->lmargin)
1742+#define argp_fmtstream_rmargin(__fs) ((__fs)->rmargin)
1743+#define argp_fmtstream_wmargin(__fs) ((__fs)->wmargin)
1744+#define __argp_fmtstream_lmargin argp_fmtstream_lmargin
1745+#define __argp_fmtstream_rmargin argp_fmtstream_rmargin
1746+#define __argp_fmtstream_wmargin argp_fmtstream_wmargin
1747+
1748+/* Set __FS's left margin to LMARGIN and return the old value. */
1749+extern size_t argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
1750+ size_t __lmargin);
1751+extern size_t __argp_fmtstream_set_lmargin (argp_fmtstream_t __fs,
1752+ size_t __lmargin);
1753+
1754+/* Set __FS's right margin to __RMARGIN and return the old value. */
1755+extern size_t argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
1756+ size_t __rmargin);
1757+extern size_t __argp_fmtstream_set_rmargin (argp_fmtstream_t __fs,
1758+ size_t __rmargin);
1759+
1760+/* Set __FS's wrap margin to __WMARGIN and return the old value. */
1761+extern size_t argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
1762+ size_t __wmargin);
1763+extern size_t __argp_fmtstream_set_wmargin (argp_fmtstream_t __fs,
1764+ size_t __wmargin);
1765+
1766+/* Return the column number of the current output point in __FS. */
1767+extern size_t argp_fmtstream_point (argp_fmtstream_t __fs);
1768+extern size_t __argp_fmtstream_point (argp_fmtstream_t __fs);
1769+
1770+/* Internal routines. */
1771+extern void _argp_fmtstream_update (argp_fmtstream_t __fs);
1772+extern void __argp_fmtstream_update (argp_fmtstream_t __fs);
1773+extern int _argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
1774+extern int __argp_fmtstream_ensure (argp_fmtstream_t __fs, size_t __amount);
1775+
1776+#ifdef __OPTIMIZE__
1777+/* Inline versions of above routines. */
1778+
1779+#if !_LIBC
1780+#define __argp_fmtstream_putc argp_fmtstream_putc
1781+#define __argp_fmtstream_puts argp_fmtstream_puts
1782+#define __argp_fmtstream_write argp_fmtstream_write
1783+#define __argp_fmtstream_set_lmargin argp_fmtstream_set_lmargin
1784+#define __argp_fmtstream_set_rmargin argp_fmtstream_set_rmargin
1785+#define __argp_fmtstream_set_wmargin argp_fmtstream_set_wmargin
1786+#define __argp_fmtstream_point argp_fmtstream_point
1787+#define __argp_fmtstream_update _argp_fmtstream_update
1788+#define __argp_fmtstream_ensure _argp_fmtstream_ensure
1789+#endif
1790+
1791+#ifndef ARGP_FS_EI
1792+#define ARGP_FS_EI __extern_inline
1793+#endif
1794+
1795+ARGP_FS_EI size_t
1796+__argp_fmtstream_write (argp_fmtstream_t __fs,
1797+ __const char *__str, size_t __len)
1798+{
1799+ if (__fs->p + __len <= __fs->end || __argp_fmtstream_ensure (__fs, __len))
1800+ {
1801+ memcpy (__fs->p, __str, __len);
1802+ __fs->p += __len;
1803+ return __len;
1804+ }
1805+ else
1806+ return 0;
1807+}
1808+
1809+ARGP_FS_EI int
1810+__argp_fmtstream_puts (argp_fmtstream_t __fs, __const char *__str)
1811+{
1812+ size_t __len = strlen (__str);
1813+ if (__len)
1814+ {
1815+ size_t __wrote = __argp_fmtstream_write (__fs, __str, __len);
1816+ return __wrote == __len ? 0 : -1;
1817+ }
1818+ else
1819+ return 0;
1820+}
1821+
1822+ARGP_FS_EI int
1823+__argp_fmtstream_putc (argp_fmtstream_t __fs, int __ch)
1824+{
1825+ if (__fs->p < __fs->end || __argp_fmtstream_ensure (__fs, 1))
1826+ return *__fs->p++ = __ch;
1827+ else
1828+ return EOF;
1829+}
1830+
1831+/* Set __FS's left margin to __LMARGIN and return the old value. */
1832+ARGP_FS_EI size_t
1833+__argp_fmtstream_set_lmargin (argp_fmtstream_t __fs, size_t __lmargin)
1834+{
1835+ size_t __old;
1836+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1837+ __argp_fmtstream_update (__fs);
1838+ __old = __fs->lmargin;
1839+ __fs->lmargin = __lmargin;
1840+ return __old;
1841+}
1842+
1843+/* Set __FS's right margin to __RMARGIN and return the old value. */
1844+ARGP_FS_EI size_t
1845+__argp_fmtstream_set_rmargin (argp_fmtstream_t __fs, size_t __rmargin)
1846+{
1847+ size_t __old;
1848+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1849+ __argp_fmtstream_update (__fs);
1850+ __old = __fs->rmargin;
1851+ __fs->rmargin = __rmargin;
1852+ return __old;
1853+}
1854+
1855+/* Set FS's wrap margin to __WMARGIN and return the old value. */
1856+ARGP_FS_EI size_t
1857+__argp_fmtstream_set_wmargin (argp_fmtstream_t __fs, size_t __wmargin)
1858+{
1859+ size_t __old;
1860+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1861+ __argp_fmtstream_update (__fs);
1862+ __old = __fs->wmargin;
1863+ __fs->wmargin = __wmargin;
1864+ return __old;
1865+}
1866+
1867+/* Return the column number of the current output point in __FS. */
1868+ARGP_FS_EI size_t
1869+__argp_fmtstream_point (argp_fmtstream_t __fs)
1870+{
1871+ if ((size_t) (__fs->p - __fs->buf) > __fs->point_offs)
1872+ __argp_fmtstream_update (__fs);
1873+ return __fs->point_col >= 0 ? __fs->point_col : 0;
1874+}
1875+
1876+#if !_LIBC
1877+#undef __argp_fmtstream_putc
1878+#undef __argp_fmtstream_puts
1879+#undef __argp_fmtstream_write
1880+#undef __argp_fmtstream_set_lmargin
1881+#undef __argp_fmtstream_set_rmargin
1882+#undef __argp_fmtstream_set_wmargin
1883+#undef __argp_fmtstream_point
1884+#undef __argp_fmtstream_update
1885+#undef __argp_fmtstream_ensure
1886+#endif
1887+
1888+#endif /* __OPTIMIZE__ */
1889+
1890+#endif /* ARGP_FMTSTREAM_USE_LINEWRAP */
1891+
1892+#endif /* argp-fmtstream.h */
1893diff --git a/libuargp/argp-fs-xinl.c b/libuargp/argp-fs-xinl.c
1894new file mode 100644
1895index 0000000..473cbbd
1896--- /dev/null
1897+++ b/libuargp/argp-fs-xinl.c
1898@@ -0,0 +1,44 @@
1899+/* Real definitions for extern inline functions in argp-fmtstream.h
1900+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
1901+ This file is part of the GNU C Library.
1902+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1903+
1904+ The GNU C Library is free software; you can redistribute it and/or
1905+ modify it under the terms of the GNU Lesser General Public
1906+ License as published by the Free Software Foundation; either
1907+ version 2.1 of the License, or (at your option) any later version.
1908+
1909+ The GNU C Library is distributed in the hope that it will be useful,
1910+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1911+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1912+ Lesser General Public License for more details.
1913+
1914+ You should have received a copy of the GNU Lesser General Public
1915+ License along with the GNU C Library; if not, write to the Free
1916+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1917+ 02111-1307 USA. */
1918+
1919+#ifdef HAVE_CONFIG_H
1920+# include <config.h>
1921+#endif
1922+
1923+#define ARGP_FS_EI
1924+#undef __OPTIMIZE__
1925+#define __OPTIMIZE__ 1
1926+#include "argp-fmtstream.h"
1927+
1928+#if 0
1929+/* Not exported. */
1930+/* Add weak aliases. */
1931+#if _LIBC - 0 && !defined (ARGP_FMTSTREAM_USE_LINEWRAP) && defined (weak_alias)
1932+
1933+weak_alias (__argp_fmtstream_putc, argp_fmtstream_putc)
1934+weak_alias (__argp_fmtstream_puts, argp_fmtstream_puts)
1935+weak_alias (__argp_fmtstream_write, argp_fmtstream_write)
1936+weak_alias (__argp_fmtstream_set_lmargin, argp_fmtstream_set_lmargin)
1937+weak_alias (__argp_fmtstream_set_rmargin, argp_fmtstream_set_rmargin)
1938+weak_alias (__argp_fmtstream_set_wmargin, argp_fmtstream_set_wmargin)
1939+weak_alias (__argp_fmtstream_point, argp_fmtstream_point)
1940+
1941+#endif
1942+#endif
1943diff --git a/libuargp/argp-help.c b/libuargp/argp-help.c
1944new file mode 100644
1945index 0000000..58a5e6e
1946--- /dev/null
1947+++ b/libuargp/argp-help.c
1948@@ -0,0 +1,1882 @@
1949+/* Hierarchial argument parsing help output
1950+ Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
1951+ Free Software Foundation, Inc.
1952+ This file is part of the GNU C Library.
1953+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
1954+
1955+ The GNU C Library is free software; you can redistribute it and/or
1956+ modify it under the terms of the GNU Lesser General Public
1957+ License as published by the Free Software Foundation; either
1958+ version 2.1 of the License, or (at your option) any later version.
1959+
1960+ The GNU C Library is distributed in the hope that it will be useful,
1961+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1962+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1963+ Lesser General Public License for more details.
1964+
1965+ You should have received a copy of the GNU Lesser General Public
1966+ License along with the GNU C Library; if not, write to the Free
1967+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1968+ 02111-1307 USA.
1969+
1970+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
1971+*/
1972+
1973+#ifndef _GNU_SOURCE
1974+# define _GNU_SOURCE 1
1975+#endif
1976+
1977+#ifdef HAVE_CONFIG_H
1978+#include <config.h>
1979+#endif
1980+
1981+/* AIX requires this to be the first thing in the file. */
1982+#ifndef __GNUC__
1983+# if HAVE_ALLOCA_H || defined _LIBC
1984+# include <alloca.h>
1985+# else
1986+# ifdef _AIX
1987+#pragma alloca
1988+# else
1989+# ifndef alloca /* predefined by HP cc +Olibcalls */
1990+char *alloca ();
1991+# endif
1992+# endif
1993+# endif
1994+#endif
1995+
1996+#include <stddef.h>
1997+#include <stdlib.h>
1998+#include <string.h>
1999+#include <assert.h>
2000+#include <stdarg.h>
2001+#include <ctype.h>
2002+#include <limits.h>
2003+#ifdef _LIBC
2004+# include <wchar.h>
2005+#endif
2006+
2007+#include <features.h>
2008+#ifndef _
2009+/* This is for other GNU distributions with internationalized messages. */
2010+# if (defined HAVE_LIBINTL_H || defined _LIBC) && defined __UCLIBC_HAS_GETTEXT_AWARENESS__
2011+# include <libintl.h>
2012+# ifdef _LIBC
2013+# undef dgettext
2014+# define dgettext(domain, msgid) \
2015+ INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
2016+# endif
2017+# else
2018+# define dgettext(domain, msgid) (msgid)
2019+# endif
2020+#endif
2021+
2022+#ifndef _LIBC
2023+# if HAVE_STRERROR_R
2024+# if !HAVE_DECL_STRERROR_R
2025+char *strerror_r (int errnum, char *buf, size_t buflen);
2026+# endif
2027+# else
2028+# if !HAVE_DECL_STRERROR
2029+char *strerror (int errnum);
2030+# endif
2031+# endif
2032+#endif
2033+
2034+#include <argp.h>
2035+#include "argp-fmtstream.h"
2036+#include <stdbool.h>
2037+#include <stdint.h>
2038+
2039+#ifndef SIZE_MAX
2040+# define SIZE_MAX ((size_t) -1)
2041+#endif
2042+
2043+/* User-selectable (using an environment variable) formatting parameters.
2044+
2045+ These may be specified in an environment variable called `ARGP_HELP_FMT',
2046+ with a contents like: VAR1=VAL1,VAR2=VAL2,BOOLVAR2,no-BOOLVAR2
2047+ Where VALn must be a positive integer. The list of variables is in the
2048+ UPARAM_NAMES vector, below. */
2049+
2050+/* Default parameters. */
2051+#define DUP_ARGS 0 /* True if option argument can be duplicated. */
2052+#define DUP_ARGS_NOTE 1 /* True to print a note about duplicate args. */
2053+#define SHORT_OPT_COL 2 /* column in which short options start */
2054+#define LONG_OPT_COL 6 /* column in which long options start */
2055+#define DOC_OPT_COL 2 /* column in which doc options start */
2056+#define OPT_DOC_COL 29 /* column in which option text starts */
2057+#define HEADER_COL 1 /* column in which group headers are printed */
2058+#define USAGE_INDENT 12 /* indentation of wrapped usage lines */
2059+#define RMARGIN 79 /* right margin used for wrapping */
2060+
2061+/* User-selectable (using an environment variable) formatting parameters.
2062+ They must all be of type `int' for the parsing code to work. */
2063+struct uparams
2064+{
2065+ /* If true, arguments for an option are shown with both short and long
2066+ options, even when a given option has both, e.g. `-x ARG, --longx=ARG'.
2067+ If false, then if an option has both, the argument is only shown with
2068+ the long one, e.g., `-x, --longx=ARG', and a message indicating that
2069+ this really means both is printed below the options. */
2070+ int dup_args;
2071+
2072+ /* This is true if when DUP_ARGS is false, and some duplicate arguments have
2073+ been suppressed, an explanatory message should be printed. */
2074+ int dup_args_note;
2075+
2076+ /* Various output columns. */
2077+ int short_opt_col;
2078+ int long_opt_col;
2079+ int doc_opt_col;
2080+ int opt_doc_col;
2081+ int header_col;
2082+ int usage_indent;
2083+ int rmargin;
2084+};
2085+
2086+/* This is a global variable, as user options are only ever read once. */
2087+static struct uparams uparams = {
2088+ DUP_ARGS, DUP_ARGS_NOTE,
2089+ SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
2090+ USAGE_INDENT, RMARGIN
2091+};
2092+
2093+/* A particular uparam, and what the user name is. */
2094+struct uparam_name
2095+{
2096+ const char name[14]; /* User name. */
2097+ bool is_bool; /* Whether it's `boolean'. */
2098+ uint8_t uparams_offs; /* Location of the (int) field in UPARAMS. */
2099+};
2100+
2101+/* The name-field mappings we know about. */
2102+static const struct uparam_name uparam_names[] =
2103+{
2104+ { "dup-args", true, offsetof (struct uparams, dup_args) },
2105+ { "dup-args-note", true, offsetof (struct uparams, dup_args_note) },
2106+ { "short-opt-col", false, offsetof (struct uparams, short_opt_col) },
2107+ { "long-opt-col", false, offsetof (struct uparams, long_opt_col) },
2108+ { "doc-opt-col", false, offsetof (struct uparams, doc_opt_col) },
2109+ { "opt-doc-col", false, offsetof (struct uparams, opt_doc_col) },
2110+ { "header-col", false, offsetof (struct uparams, header_col) },
2111+ { "usage-indent", false, offsetof (struct uparams, usage_indent) },
2112+ { "rmargin", false, offsetof (struct uparams, rmargin) }
2113+};
2114+#define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
2115+
2116+/* Read user options from the environment, and fill in UPARAMS appropiately. */
2117+static void
2118+fill_in_uparams (const struct argp_state *state)
2119+{
2120+ const char *var = getenv ("ARGP_HELP_FMT");
2121+
2122+#define SKIPWS(p) do { while (isspace (*p)) p++; } while (0);
2123+
2124+ if (var)
2125+ /* Parse var. */
2126+ while (*var)
2127+ {
2128+ SKIPWS (var);
2129+
2130+ if (isalpha (*var))
2131+ {
2132+ size_t var_len;
2133+ const struct uparam_name *un;
2134+ int unspec = 0, val = 0;
2135+ const char *arg = var;
2136+
2137+ while (isalnum (*arg) || *arg == '-' || *arg == '_')
2138+ arg++;
2139+ var_len = arg - var;
2140+
2141+ SKIPWS (arg);
2142+
2143+ if (*arg == '\0' || *arg == ',')
2144+ unspec = 1;
2145+ else if (*arg == '=')
2146+ {
2147+ arg++;
2148+ SKIPWS (arg);
2149+ }
2150+
2151+ if (unspec)
2152+ {
2153+ if (var[0] == 'n' && var[1] == 'o' && var[2] == '-')
2154+ {
2155+ val = 0;
2156+ var += 3;
2157+ var_len -= 3;
2158+ }
2159+ else
2160+ val = 1;
2161+ }
2162+ else if (isdigit (*arg))
2163+ {
2164+ val = atoi (arg);
2165+ while (isdigit (*arg))
2166+ arg++;
2167+ SKIPWS (arg);
2168+ }
2169+
2170+ un = uparam_names;
2171+ size_t u;
2172+ for (u = 0; u < nuparam_names; ++un, ++u)
2173+ if (strlen (un->name) == var_len
2174+ && strncmp (var, un->name, var_len) == 0)
2175+ {
2176+ if (unspec && !un->is_bool)
2177+ argp_failure (state, 0, 0,
2178+ dgettext (state == NULL ? NULL
2179+ : state->root_argp->argp_domain,
2180+ "\
2181+%.*s: ARGP_HELP_FMT parameter requires a value"),
2182+ (int) var_len, var);
2183+ else
2184+ *(int *)((char *)&uparams + un->uparams_offs) = val;
2185+ break;
2186+ }
2187+ if (u == nuparam_names)
2188+ argp_failure (state, 0, 0,
2189+ dgettext (state == NULL ? NULL
2190+ : state->root_argp->argp_domain, "\
2191+%.*s: Unknown ARGP_HELP_FMT parameter"),
2192+ (int) var_len, var);
2193+
2194+ var = arg;
2195+ if (*var == ',')
2196+ var++;
2197+ }
2198+ else if (*var)
2199+ {
2200+ argp_failure (state, 0, 0,
2201+ dgettext (state == NULL ? NULL
2202+ : state->root_argp->argp_domain,
2203+ "Garbage in ARGP_HELP_FMT: %s"), var);
2204+ break;
2205+ }
2206+ }
2207+}
2208+
2209+/* Returns true if OPT hasn't been marked invisible. Visibility only affects
2210+ whether OPT is displayed or used in sorting, not option shadowing. */
2211+#define ovisible(opt) (! ((opt)->flags & OPTION_HIDDEN))
2212+
2213+/* Returns true if OPT is an alias for an earlier option. */
2214+#define oalias(opt) ((opt)->flags & OPTION_ALIAS)
2215+
2216+/* Returns true if OPT is an documentation-only entry. */
2217+#define odoc(opt) ((opt)->flags & OPTION_DOC)
2218+
2219+/* Returns true if OPT is the end-of-list marker for a list of options. */
2220+#define oend(opt) __option_is_end (opt)
2221+
2222+/* Returns true if OPT has a short option. */
2223+#define oshort(opt) __option_is_short (opt)
2224+
2225+/*
2226+ The help format for a particular option is like:
2227+
2228+ -xARG, -yARG, --long1=ARG, --long2=ARG Documentation...
2229+
2230+ Where ARG will be omitted if there's no argument, for this option, or
2231+ will be surrounded by "[" and "]" appropiately if the argument is
2232+ optional. The documentation string is word-wrapped appropiately, and if
2233+ the list of options is long enough, it will be started on a separate line.
2234+ If there are no short options for a given option, the first long option is
2235+ indented slighly in a way that's supposed to make most long options appear
2236+ to be in a separate column.
2237+
2238+ For example, the following output (from ps):
2239+
2240+ -p PID, --pid=PID List the process PID
2241+ --pgrp=PGRP List processes in the process group PGRP
2242+ -P, -x, --no-parent Include processes without parents
2243+ -Q, --all-fields Don't elide unusable fields (normally if there's
2244+ some reason ps can't print a field for any
2245+ process, it's removed from the output entirely)
2246+ -r, --reverse, --gratuitously-long-reverse-option
2247+ Reverse the order of any sort
2248+ --session[=SID] Add the processes from the session SID (which
2249+ defaults to the sid of the current process)
2250+
2251+ Here are some more options:
2252+ -f ZOT, --foonly=ZOT Glork a foonly
2253+ -z, --zaza Snit a zar
2254+
2255+ -?, --help Give this help list
2256+ --usage Give a short usage message
2257+ -V, --version Print program version
2258+
2259+ The struct argp_option array for the above could look like:
2260+
2261+ {
2262+ {"pid", 'p', "PID", 0, "List the process PID"},
2263+ {"pgrp", OPT_PGRP, "PGRP", 0, "List processes in the process group PGRP"},
2264+ {"no-parent", 'P', 0, 0, "Include processes without parents"},
2265+ {0, 'x', 0, OPTION_ALIAS},
2266+ {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
2267+ " if there's some reason ps can't"
2268+ " print a field for any process, it's"
2269+ " removed from the output entirely)" },
2270+ {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
2271+ {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
2272+ {"session", OPT_SESS, "SID", OPTION_ARG_OPTIONAL,
2273+ "Add the processes from the session"
2274+ " SID (which defaults to the sid of"
2275+ " the current process)" },
2276+
2277+ {0,0,0,0, "Here are some more options:"},
2278+ {"foonly", 'f', "ZOT", 0, "Glork a foonly"},
2279+ {"zaza", 'z', 0, 0, "Snit a zar"},
2280+
2281+ {0}
2282+ }
2283+
2284+ Note that the last three options are automatically supplied by argp_parse,
2285+ unless you tell it not to with ARGP_NO_HELP.
2286+
2287+*/
2288+
2289+/* Returns true if CH occurs between BEG and END. */
2290+static int
2291+find_char (char ch, char *beg, char *end)
2292+{
2293+ while (beg < end)
2294+ if (*beg == ch)
2295+ return 1;
2296+ else
2297+ beg++;
2298+ return 0;
2299+}
2300+
2301+struct hol_cluster; /* fwd decl */
2302+
2303+struct hol_entry
2304+{
2305+ /* First option. */
2306+ const struct argp_option *opt;
2307+ /* Number of options (including aliases). */
2308+ unsigned num;
2309+
2310+ /* A pointers into the HOL's short_options field, to the first short option
2311+ letter for this entry. The order of the characters following this point
2312+ corresponds to the order of options pointed to by OPT, and there are at
2313+ most NUM. A short option recorded in a option following OPT is only
2314+ valid if it occurs in the right place in SHORT_OPTIONS (otherwise it's
2315+ probably been shadowed by some other entry). */
2316+ char *short_options;
2317+
2318+ /* Entries are sorted by their group first, in the order:
2319+ 1, 2, ..., n, 0, -m, ..., -2, -1
2320+ and then alphabetically within each group. The default is 0. */
2321+ int group;
2322+
2323+ /* The cluster of options this entry belongs to, or 0 if none. */
2324+ struct hol_cluster *cluster;
2325+
2326+ /* The argp from which this option came. */
2327+ const struct argp *argp;
2328+};
2329+
2330+/* A cluster of entries to reflect the argp tree structure. */
2331+struct hol_cluster
2332+{
2333+ /* A descriptive header printed before options in this cluster. */
2334+ const char *header;
2335+
2336+ /* Used to order clusters within the same group with the same parent,
2337+ according to the order in which they occurred in the parent argp's child
2338+ list. */
2339+ int index;
2340+
2341+ /* How to sort this cluster with respect to options and other clusters at the
2342+ same depth (clusters always follow options in the same group). */
2343+ int group;
2344+
2345+ /* The cluster to which this cluster belongs, or 0 if it's at the base
2346+ level. */
2347+ struct hol_cluster *parent;
2348+
2349+ /* The argp from which this cluster is (eventually) derived. */
2350+ const struct argp *argp;
2351+
2352+ /* The distance this cluster is from the root. */
2353+ int depth;
2354+
2355+ /* Clusters in a given hol are kept in a linked list, to make freeing them
2356+ possible. */
2357+ struct hol_cluster *next;
2358+};
2359+
2360+/* A list of options for help. */
2361+struct hol
2362+{
2363+ /* An array of hol_entry's. */
2364+ struct hol_entry *entries;
2365+ /* The number of entries in this hol. If this field is zero, the others
2366+ are undefined. */
2367+ unsigned num_entries;
2368+
2369+ /* A string containing all short options in this HOL. Each entry contains
2370+ pointers into this string, so the order can't be messed with blindly. */
2371+ char *short_options;
2372+
2373+ /* Clusters of entries in this hol. */
2374+ struct hol_cluster *clusters;
2375+};
2376+
2377+/* Create a struct hol from the options in ARGP. CLUSTER is the
2378+ hol_cluster in which these entries occur, or 0, if at the root. */
2379+static struct hol *
2380+make_hol (const struct argp *argp, struct hol_cluster *cluster)
2381+{
2382+ char *so;
2383+ const struct argp_option *o;
2384+ const struct argp_option *opts = argp->options;
2385+ struct hol_entry *entry;
2386+ unsigned num_short_options = 0;
2387+ struct hol *hol = malloc (sizeof (struct hol));
2388+
2389+ assert (hol);
2390+
2391+ hol->num_entries = 0;
2392+ hol->clusters = 0;
2393+
2394+ if (opts)
2395+ {
2396+ int cur_group = 0;
2397+
2398+ /* The first option must not be an alias. */
2399+ assert (! oalias (opts));
2400+
2401+ /* Calculate the space needed. */
2402+ for (o = opts; ! oend (o); o++)
2403+ {
2404+ if (! oalias (o))
2405+ hol->num_entries++;
2406+ if (oshort (o))
2407+ num_short_options++; /* This is an upper bound. */
2408+ }
2409+
2410+ hol->entries = malloc (sizeof (struct hol_entry) * hol->num_entries);
2411+ hol->short_options = malloc (num_short_options + 1);
2412+
2413+ assert (hol->entries && hol->short_options);
2414+#if SIZE_MAX <= UINT_MAX
2415+ assert (hol->num_entries <= SIZE_MAX / sizeof (struct hol_entry));
2416+#endif
2417+
2418+ /* Fill in the entries. */
2419+ so = hol->short_options;
2420+ for (o = opts, entry = hol->entries; ! oend (o); entry++)
2421+ {
2422+ entry->opt = o;
2423+ entry->num = 0;
2424+ entry->short_options = so;
2425+ entry->group = cur_group =
2426+ o->group
2427+ ? o->group
2428+ : ((!o->name && !o->key)
2429+ ? cur_group + 1
2430+ : cur_group);
2431+ entry->cluster = cluster;
2432+ entry->argp = argp;
2433+
2434+ do
2435+ {
2436+ entry->num++;
2437+ if (oshort (o) && ! find_char (o->key, hol->short_options, so))
2438+ /* O has a valid short option which hasn't already been used.*/
2439+ *so++ = o->key;
2440+ o++;
2441+ }
2442+ while (! oend (o) && oalias (o));
2443+ }
2444+ *so = '\0'; /* null terminated so we can find the length */
2445+ }
2446+
2447+ return hol;
2448+}
2449+
2450+/* Add a new cluster to HOL, with the given GROUP and HEADER (taken from the
2451+ associated argp child list entry), INDEX, and PARENT, and return a pointer
2452+ to it. ARGP is the argp that this cluster results from. */
2453+static struct hol_cluster *
2454+hol_add_cluster (struct hol *hol, int group, const char *header, int index,
2455+ struct hol_cluster *parent, const struct argp *argp)
2456+{
2457+ struct hol_cluster *cl = malloc (sizeof (struct hol_cluster));
2458+ if (cl)
2459+ {
2460+ cl->group = group;
2461+ cl->header = header;
2462+
2463+ cl->index = index;
2464+ cl->parent = parent;
2465+ cl->argp = argp;
2466+ cl->depth = parent ? parent->depth + 1 : 0;
2467+
2468+ cl->next = hol->clusters;
2469+ hol->clusters = cl;
2470+ }
2471+ return cl;
2472+}
2473+
2474+/* Free HOL and any resources it uses. */
2475+static void
2476+hol_free (struct hol *hol)
2477+{
2478+ struct hol_cluster *cl = hol->clusters;
2479+
2480+ while (cl)
2481+ {
2482+ struct hol_cluster *next = cl->next;
2483+ free (cl);
2484+ cl = next;
2485+ }
2486+
2487+ if (hol->num_entries > 0)
2488+ {
2489+ free (hol->entries);
2490+ free (hol->short_options);
2491+ }
2492+
2493+ free (hol);
2494+}
2495+
2496+static int
2497+hol_entry_short_iterate (const struct hol_entry *entry,
2498+ int (*func)(const struct argp_option *opt,
2499+ const struct argp_option *real,
2500+ const char *domain, void *cookie),
2501+ const char *domain, void *cookie)
2502+{
2503+ unsigned nopts;
2504+ int val = 0;
2505+ const struct argp_option *opt, *real = entry->opt;
2506+ char *so = entry->short_options;
2507+
2508+ for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
2509+ if (oshort (opt) && *so == opt->key)
2510+ {
2511+ if (!oalias (opt))
2512+ real = opt;
2513+ if (ovisible (opt))
2514+ val = (*func)(opt, real, domain, cookie);
2515+ so++;
2516+ }
2517+
2518+ return val;
2519+}
2520+
2521+static __inline__ int
2522+__attribute__ ((always_inline))
2523+hol_entry_long_iterate (const struct hol_entry *entry,
2524+ int (*func)(const struct argp_option *opt,
2525+ const struct argp_option *real,
2526+ const char *domain, void *cookie),
2527+ const char *domain, void *cookie)
2528+{
2529+ unsigned nopts;
2530+ int val = 0;
2531+ const struct argp_option *opt, *real = entry->opt;
2532+
2533+ for (opt = real, nopts = entry->num; nopts > 0 && !val; opt++, nopts--)
2534+ if (opt->name)
2535+ {
2536+ if (!oalias (opt))
2537+ real = opt;
2538+ if (ovisible (opt))
2539+ val = (*func)(opt, real, domain, cookie);
2540+ }
2541+
2542+ return val;
2543+}
2544+
2545+/* Iterator that returns true for the first short option. */
2546+static __inline__ int
2547+until_short (const struct argp_option *opt, const struct argp_option *real,
2548+ const char *domain, void *cookie)
2549+{
2550+ return oshort (opt) ? opt->key : 0;
2551+}
2552+
2553+/* Returns the first valid short option in ENTRY, or 0 if there is none. */
2554+static char
2555+hol_entry_first_short (const struct hol_entry *entry)
2556+{
2557+ return hol_entry_short_iterate (entry, until_short,
2558+ entry->argp->argp_domain, 0);
2559+}
2560+
2561+/* Returns the first valid long option in ENTRY, or 0 if there is none. */
2562+static const char *
2563+hol_entry_first_long (const struct hol_entry *entry)
2564+{
2565+ const struct argp_option *opt;
2566+ unsigned num;
2567+ for (opt = entry->opt, num = entry->num; num > 0; opt++, num--)
2568+ if (opt->name && ovisible (opt))
2569+ return opt->name;
2570+ return 0;
2571+}
2572+
2573+/* Returns the entry in HOL with the long option name NAME, or 0 if there is
2574+ none. */
2575+static struct hol_entry *
2576+hol_find_entry (struct hol *hol, const char *name)
2577+{
2578+ struct hol_entry *entry = hol->entries;
2579+ unsigned num_entries = hol->num_entries;
2580+
2581+ while (num_entries-- > 0)
2582+ {
2583+ const struct argp_option *opt = entry->opt;
2584+ unsigned num_opts = entry->num;
2585+
2586+ while (num_opts-- > 0)
2587+ if (opt->name && ovisible (opt) && strcmp (opt->name, name) == 0)
2588+ return entry;
2589+ else
2590+ opt++;
2591+
2592+ entry++;
2593+ }
2594+
2595+ return 0;
2596+}
2597+
2598+/* If an entry with the long option NAME occurs in HOL, set it's special
2599+ sort position to GROUP. */
2600+static void
2601+hol_set_group (struct hol *hol, const char *name, int group)
2602+{
2603+ struct hol_entry *entry = hol_find_entry (hol, name);
2604+ if (entry)
2605+ entry->group = group;
2606+}
2607+
2608+/* Order by group: 0, 1, 2, ..., n, -m, ..., -2, -1.
2609+ EQ is what to return if GROUP1 and GROUP2 are the same. */
2610+static int
2611+group_cmp (int group1, int group2, int eq)
2612+{
2613+ if (group1 == group2)
2614+ return eq;
2615+ else if ((group1 < 0 && group2 < 0) || (group1 >= 0 && group2 >= 0))
2616+ return group1 - group2;
2617+ else
2618+ return group2 - group1;
2619+}
2620+
2621+/* Compare clusters CL1 & CL2 by the order that they should appear in
2622+ output. */
2623+static int
2624+hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
2625+{
2626+ /* If one cluster is deeper than the other, use its ancestor at the same
2627+ level, so that finding the common ancestor is straightforward. */
2628+ while (cl1->depth > cl2->depth)
2629+ cl1 = cl1->parent;
2630+ while (cl2->depth > cl1->depth)
2631+ cl2 = cl2->parent;
2632+
2633+ /* Now reduce both clusters to their ancestors at the point where both have
2634+ a common parent; these can be directly compared. */
2635+ while (cl1->parent != cl2->parent)
2636+ cl1 = cl1->parent, cl2 = cl2->parent;
2637+
2638+ return group_cmp (cl1->group, cl2->group, cl2->index - cl1->index);
2639+}
2640+
2641+/* Return the ancestor of CL that's just below the root (i.e., has a parent
2642+ of 0). */
2643+static struct hol_cluster *
2644+hol_cluster_base (struct hol_cluster *cl)
2645+{
2646+ while (cl->parent)
2647+ cl = cl->parent;
2648+ return cl;
2649+}
2650+
2651+/* Return true if CL1 is a child of CL2. */
2652+static int
2653+hol_cluster_is_child (const struct hol_cluster *cl1,
2654+ const struct hol_cluster *cl2)
2655+{
2656+ while (cl1 && cl1 != cl2)
2657+ cl1 = cl1->parent;
2658+ return cl1 == cl2;
2659+}
2660+
2661+/* Given the name of a OPTION_DOC option, modifies NAME to start at the tail
2662+ that should be used for comparisons, and returns true iff it should be
2663+ treated as a non-option. */
2664+static int
2665+canon_doc_option (const char **name)
2666+{
2667+ int non_opt;
2668+ /* Skip initial whitespace. */
2669+ while (isspace (**name))
2670+ (*name)++;
2671+ /* Decide whether this looks like an option (leading `-') or not. */
2672+ non_opt = (**name != '-');
2673+ /* Skip until part of name used for sorting. */
2674+ while (**name && !isalnum (**name))
2675+ (*name)++;
2676+ return non_opt;
2677+}
2678+
2679+/* Order ENTRY1 & ENTRY2 by the order which they should appear in a help
2680+ listing. */
2681+static int
2682+hol_entry_cmp (const struct hol_entry *entry1,
2683+ const struct hol_entry *entry2)
2684+{
2685+ /* The group numbers by which the entries should be ordered; if either is
2686+ in a cluster, then this is just the group within the cluster. */
2687+ int group1 = entry1->group, group2 = entry2->group;
2688+
2689+ if (entry1->cluster != entry2->cluster)
2690+ {
2691+ /* The entries are not within the same cluster, so we can't compare them
2692+ directly, we have to use the appropiate clustering level too. */
2693+ if (! entry1->cluster)
2694+ /* ENTRY1 is at the `base level', not in a cluster, so we have to
2695+ compare it's group number with that of the base cluster in which
2696+ ENTRY2 resides. Note that if they're in the same group, the
2697+ clustered option always comes laster. */
2698+ return group_cmp (group1, hol_cluster_base (entry2->cluster)->group, -1);
2699+ else if (! entry2->cluster)
2700+ /* Likewise, but ENTRY2's not in a cluster. */
2701+ return group_cmp (hol_cluster_base (entry1->cluster)->group, group2, 1);
2702+ else
2703+ /* Both entries are in clusters, we can just compare the clusters. */
2704+ return hol_cluster_cmp (entry1->cluster, entry2->cluster);
2705+ }
2706+ else if (group1 == group2)
2707+ /* The entries are both in the same cluster and group, so compare them
2708+ alphabetically. */
2709+ {
2710+ int short1 = hol_entry_first_short (entry1);
2711+ int short2 = hol_entry_first_short (entry2);
2712+ int doc1 = odoc (entry1->opt);
2713+ int doc2 = odoc (entry2->opt);
2714+ const char *long1 = hol_entry_first_long (entry1);
2715+ const char *long2 = hol_entry_first_long (entry2);
2716+
2717+ if (doc1)
2718+ doc1 = long1 != NULL && canon_doc_option (&long1);
2719+ if (doc2)
2720+ doc2 = long2 != NULL && canon_doc_option (&long2);
2721+
2722+ if (doc1 != doc2)
2723+ /* `documentation' options always follow normal options (or
2724+ documentation options that *look* like normal options). */
2725+ return doc1 - doc2;
2726+ else if (!short1 && !short2 && long1 && long2)
2727+ /* Only long options. */
2728+ return strcasecmp (long1, long2);
2729+ else
2730+ /* Compare short/short, long/short, short/long, using the first
2731+ character of long options. Entries without *any* valid
2732+ options (such as options with OPTION_HIDDEN set) will be put
2733+ first, but as they're not displayed, it doesn't matter where
2734+ they are. */
2735+ {
2736+ char first1 = short1 ? short1 : long1 ? *long1 : 0;
2737+ char first2 = short2 ? short2 : long2 ? *long2 : 0;
2738+#ifdef _tolower
2739+ int lower_cmp = _tolower (first1) - _tolower (first2);
2740+#else
2741+ int lower_cmp = tolower (first1) - tolower (first2);
2742+#endif
2743+ /* Compare ignoring case, except when the options are both the
2744+ same letter, in which case lower-case always comes first. */
2745+ return lower_cmp ? lower_cmp : first2 - first1;
2746+ }
2747+ }
2748+ else
2749+ /* Within the same cluster, but not the same group, so just compare
2750+ groups. */
2751+ return group_cmp (group1, group2, 0);
2752+}
2753+
2754+/* Version of hol_entry_cmp with correct signature for qsort. */
2755+static int
2756+hol_entry_qcmp (const void *entry1_v, const void *entry2_v)
2757+{
2758+ return hol_entry_cmp (entry1_v, entry2_v);
2759+}
2760+
2761+/* Sort HOL by group and alphabetically by option name (with short options
2762+ taking precedence over long). Since the sorting is for display purposes
2763+ only, the shadowing of options isn't effected. */
2764+static void
2765+hol_sort (struct hol *hol)
2766+{
2767+ if (hol->num_entries > 0)
2768+ qsort (hol->entries, hol->num_entries, sizeof (struct hol_entry),
2769+ hol_entry_qcmp);
2770+}
2771+
2772+/* Append MORE to HOL, destroying MORE in the process. Options in HOL shadow
2773+ any in MORE with the same name. */
2774+static void
2775+hol_append (struct hol *hol, struct hol *more)
2776+{
2777+ struct hol_cluster **cl_end = &hol->clusters;
2778+
2779+ /* Steal MORE's cluster list, and add it to the end of HOL's. */
2780+ while (*cl_end)
2781+ cl_end = &(*cl_end)->next;
2782+ *cl_end = more->clusters;
2783+ more->clusters = 0;
2784+
2785+ /* Merge entries. */
2786+ if (more->num_entries > 0)
2787+ {
2788+ if (hol->num_entries == 0)
2789+ {
2790+ hol->num_entries = more->num_entries;
2791+ hol->entries = more->entries;
2792+ hol->short_options = more->short_options;
2793+ more->num_entries = 0; /* Mark MORE's fields as invalid. */
2794+ }
2795+ else
2796+ /* Append the entries in MORE to those in HOL, taking care to only add
2797+ non-shadowed SHORT_OPTIONS values. */
2798+ {
2799+ unsigned left;
2800+ char *so, *more_so;
2801+ struct hol_entry *e;
2802+ unsigned num_entries = hol->num_entries + more->num_entries;
2803+ struct hol_entry *entries =
2804+ malloc (num_entries * sizeof (struct hol_entry));
2805+ unsigned hol_so_len = strlen (hol->short_options);
2806+ char *short_options =
2807+ malloc (hol_so_len + strlen (more->short_options) + 1);
2808+
2809+ assert (entries && short_options);
2810+#if SIZE_MAX <= UINT_MAX
2811+ assert (num_entries <= SIZE_MAX / sizeof (struct hol_entry));
2812+#endif
2813+
2814+ mempcpy (mempcpy (entries, hol->entries,
2815+ hol->num_entries * sizeof (struct hol_entry)),
2816+ more->entries,
2817+ more->num_entries * sizeof (struct hol_entry));
2818+
2819+ mempcpy (short_options, hol->short_options, hol_so_len);
2820+
2821+ /* Fix up the short options pointers from HOL. */
2822+ for (e = entries, left = hol->num_entries; left > 0; e++, left--)
2823+ e->short_options += (short_options - hol->short_options);
2824+
2825+ /* Now add the short options from MORE, fixing up its entries
2826+ too. */
2827+ so = short_options + hol_so_len;
2828+ more_so = more->short_options;
2829+ for (left = more->num_entries; left > 0; e++, left--)
2830+ {
2831+ int opts_left;
2832+ const struct argp_option *opt;
2833+
2834+ e->short_options = so;
2835+
2836+ for (opts_left = e->num, opt = e->opt; opts_left; opt++, opts_left--)
2837+ {
2838+ int ch = *more_so;
2839+ if (oshort (opt) && ch == opt->key)
2840+ /* The next short option in MORE_SO, CH, is from OPT. */
2841+ {
2842+ if (! find_char (ch, short_options,
2843+ short_options + hol_so_len))
2844+ /* The short option CH isn't shadowed by HOL's options,
2845+ so add it to the sum. */
2846+ *so++ = ch;
2847+ more_so++;
2848+ }
2849+ }
2850+ }
2851+
2852+ *so = '\0';
2853+
2854+ free (hol->entries);
2855+ free (hol->short_options);
2856+
2857+ hol->entries = entries;
2858+ hol->num_entries = num_entries;
2859+ hol->short_options = short_options;
2860+ }
2861+ }
2862+
2863+ hol_free (more);
2864+}
2865+
2866+/* Inserts enough spaces to make sure STREAM is at column COL. */
2867+static void
2868+indent_to (argp_fmtstream_t stream, unsigned col)
2869+{
2870+ int needed = col - __argp_fmtstream_point (stream);
2871+ while (needed-- > 0)
2872+ __argp_fmtstream_putc (stream, ' ');
2873+}
2874+
2875+/* Output to STREAM either a space, or a newline if there isn't room for at
2876+ least ENSURE characters before the right margin. */
2877+static void
2878+space (argp_fmtstream_t stream, size_t ensure)
2879+{
2880+ if (__argp_fmtstream_point (stream) + ensure
2881+ >= __argp_fmtstream_rmargin (stream))
2882+ __argp_fmtstream_putc (stream, '\n');
2883+ else
2884+ __argp_fmtstream_putc (stream, ' ');
2885+}
2886+
2887+/* If the option REAL has an argument, we print it in using the printf
2888+ format REQ_FMT or OPT_FMT depending on whether it's a required or
2889+ optional argument. */
2890+static void
2891+arg (const struct argp_option *real, const char *req_fmt, const char *opt_fmt,
2892+ const char *domain, argp_fmtstream_t stream)
2893+{
2894+ if (real->arg)
2895+ {
2896+ if (real->flags & OPTION_ARG_OPTIONAL)
2897+ __argp_fmtstream_printf (stream, opt_fmt,
2898+ dgettext (domain, real->arg));
2899+ else
2900+ __argp_fmtstream_printf (stream, req_fmt,
2901+ dgettext (domain, real->arg));
2902+ }
2903+}
2904+
2905+/* Helper functions for hol_entry_help. */
2906+
2907+/* State used during the execution of hol_help. */
2908+struct hol_help_state
2909+{
2910+ /* PREV_ENTRY should contain the previous entry printed, or 0. */
2911+ struct hol_entry *prev_entry;
2912+
2913+ /* If an entry is in a different group from the previous one, and SEP_GROUPS
2914+ is true, then a blank line will be printed before any output. */
2915+ int sep_groups;
2916+
2917+ /* True if a duplicate option argument was suppressed (only ever set if
2918+ UPARAMS.dup_args is false). */
2919+ int suppressed_dup_arg;
2920+};
2921+
2922+/* Some state used while printing a help entry (used to communicate with
2923+ helper functions). See the doc for hol_entry_help for more info, as most
2924+ of the fields are copied from its arguments. */
2925+struct pentry_state
2926+{
2927+ const struct hol_entry *entry;
2928+ argp_fmtstream_t stream;
2929+ struct hol_help_state *hhstate;
2930+
2931+ /* True if nothing's been printed so far. */
2932+ int first;
2933+
2934+ /* If non-zero, the state that was used to print this help. */
2935+ const struct argp_state *state;
2936+};
2937+
2938+/* If a user doc filter should be applied to DOC, do so. */
2939+static const char *
2940+filter_doc (const char *doc, int key, const struct argp *argp,
2941+ const struct argp_state *state)
2942+{
2943+ if (argp && argp->help_filter)
2944+ /* We must apply a user filter to this output. */
2945+ {
2946+ void *input = __argp_input (argp, state);
2947+ return (*argp->help_filter) (key, doc, input);
2948+ }
2949+ else
2950+ /* No filter. */
2951+ return doc;
2952+}
2953+
2954+/* Prints STR as a header line, with the margin lines set appropiately, and
2955+ notes the fact that groups should be separated with a blank line. ARGP is
2956+ the argp that should dictate any user doc filtering to take place. Note
2957+ that the previous wrap margin isn't restored, but the left margin is reset
2958+ to 0. */
2959+static void
2960+print_header (const char *str, const struct argp *argp,
2961+ struct pentry_state *pest)
2962+{
2963+ const char *tstr = dgettext (argp->argp_domain, str);
2964+ const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_HEADER, argp, pest->state);
2965+
2966+ if (fstr)
2967+ {
2968+ if (*fstr)
2969+ {
2970+ if (pest->hhstate->prev_entry)
2971+ /* Precede with a blank line. */
2972+ __argp_fmtstream_putc (pest->stream, '\n');
2973+ indent_to (pest->stream, uparams.header_col);
2974+ __argp_fmtstream_set_lmargin (pest->stream, uparams.header_col);
2975+ __argp_fmtstream_set_wmargin (pest->stream, uparams.header_col);
2976+ __argp_fmtstream_puts (pest->stream, fstr);
2977+ __argp_fmtstream_set_lmargin (pest->stream, 0);
2978+ __argp_fmtstream_putc (pest->stream, '\n');
2979+ }
2980+
2981+ pest->hhstate->sep_groups = 1; /* Separate subsequent groups. */
2982+ }
2983+
2984+ if (fstr != tstr)
2985+ free ((char *) fstr);
2986+}
2987+
2988+/* Inserts a comma if this isn't the first item on the line, and then makes
2989+ sure we're at least to column COL. If this *is* the first item on a line,
2990+ prints any pending whitespace/headers that should precede this line. Also
2991+ clears FIRST. */
2992+static void
2993+comma (unsigned col, struct pentry_state *pest)
2994+{
2995+ if (pest->first)
2996+ {
2997+ const struct hol_entry *pe = pest->hhstate->prev_entry;
2998+ const struct hol_cluster *cl = pest->entry->cluster;
2999+
3000+ if (pest->hhstate->sep_groups && pe && pest->entry->group != pe->group)
3001+ __argp_fmtstream_putc (pest->stream, '\n');
3002+
3003+ if (cl && cl->header && *cl->header
3004+ && (!pe
3005+ || (pe->cluster != cl
3006+ && !hol_cluster_is_child (pe->cluster, cl))))
3007+ /* If we're changing clusters, then this must be the start of the
3008+ ENTRY's cluster unless that is an ancestor of the previous one
3009+ (in which case we had just popped into a sub-cluster for a bit).
3010+ If so, then print the cluster's header line. */
3011+ {
3012+ int old_wm = __argp_fmtstream_wmargin (pest->stream);
3013+ print_header (cl->header, cl->argp, pest);
3014+ __argp_fmtstream_set_wmargin (pest->stream, old_wm);
3015+ }
3016+
3017+ pest->first = 0;
3018+ }
3019+ else
3020+ __argp_fmtstream_puts (pest->stream, ", ");
3021+
3022+ indent_to (pest->stream, col);
3023+}
3024+
3025+/* Print help for ENTRY to STREAM. */
3026+static void
3027+hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
3028+ argp_fmtstream_t stream, struct hol_help_state *hhstate)
3029+{
3030+ unsigned num;
3031+ const struct argp_option *real = entry->opt, *opt;
3032+ char *so = entry->short_options;
3033+ int have_long_opt = 0; /* We have any long options. */
3034+ /* Saved margins. */
3035+ int old_lm = __argp_fmtstream_set_lmargin (stream, 0);
3036+ int old_wm = __argp_fmtstream_wmargin (stream);
3037+ /* PEST is a state block holding some of our variables that we'd like to
3038+ share with helper functions. */
3039+ struct pentry_state pest = { entry, stream, hhstate, 1, state };
3040+
3041+ if (! odoc (real))
3042+ for (opt = real, num = entry->num; num > 0; opt++, num--)
3043+ if (opt->name && ovisible (opt))
3044+ {
3045+ have_long_opt = 1;
3046+ break;
3047+ }
3048+
3049+ /* First emit short options. */
3050+ __argp_fmtstream_set_wmargin (stream, uparams.short_opt_col); /* For truly bizarre cases. */
3051+ for (opt = real, num = entry->num; num > 0; opt++, num--)
3052+ if (oshort (opt) && opt->key == *so)
3053+ /* OPT has a valid (non shadowed) short option. */
3054+ {
3055+ if (ovisible (opt))
3056+ {
3057+ comma (uparams.short_opt_col, &pest);
3058+ __argp_fmtstream_putc (stream, '-');
3059+ __argp_fmtstream_putc (stream, *so);
3060+ if (!have_long_opt || uparams.dup_args)
3061+ arg (real, " %s", "[%s]",
3062+ state == NULL ? NULL : state->root_argp->argp_domain,
3063+ stream);
3064+ else if (real->arg)
3065+ hhstate->suppressed_dup_arg = 1;
3066+ }
3067+ so++;
3068+ }
3069+
3070+ /* Now, long options. */
3071+ if (odoc (real))
3072+ /* A `documentation' option. */
3073+ {
3074+ __argp_fmtstream_set_wmargin (stream, uparams.doc_opt_col);
3075+ for (opt = real, num = entry->num; num > 0; opt++, num--)
3076+ if (opt->name && ovisible (opt))
3077+ {
3078+ comma (uparams.doc_opt_col, &pest);
3079+ /* Calling gettext here isn't quite right, since sorting will
3080+ have been done on the original; but documentation options
3081+ should be pretty rare anyway... */
3082+ __argp_fmtstream_puts (stream,
3083+ dgettext (state == NULL ? NULL
3084+ : state->root_argp->argp_domain,
3085+ opt->name));
3086+ }
3087+ }
3088+ else
3089+ /* A real long option. */
3090+ {
3091+ __argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
3092+ for (opt = real, num = entry->num; num > 0; opt++, num--)
3093+ if (opt->name && ovisible (opt))
3094+ {
3095+ comma (uparams.long_opt_col, &pest);
3096+ __argp_fmtstream_printf (stream, "--%s", opt->name);
3097+ arg (real, "=%s", "[=%s]",
3098+ state == NULL ? NULL : state->root_argp->argp_domain, stream);
3099+ }
3100+ }
3101+
3102+ /* Next, documentation strings. */
3103+ __argp_fmtstream_set_lmargin (stream, 0);
3104+
3105+ if (pest.first)
3106+ {
3107+ /* Didn't print any switches, what's up? */
3108+ if (!oshort (real) && !real->name)
3109+ /* This is a group header, print it nicely. */
3110+ print_header (real->doc, entry->argp, &pest);
3111+ else
3112+ /* Just a totally shadowed option or null header; print nothing. */
3113+ goto cleanup; /* Just return, after cleaning up. */
3114+ }
3115+ else
3116+ {
3117+ const char *tstr = real->doc ? dgettext (state == NULL ? NULL
3118+ : state->root_argp->argp_domain,
3119+ real->doc) : 0;
3120+ const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
3121+ if (fstr && *fstr)
3122+ {
3123+ unsigned int col = __argp_fmtstream_point (stream);
3124+
3125+ __argp_fmtstream_set_lmargin (stream, uparams.opt_doc_col);
3126+ __argp_fmtstream_set_wmargin (stream, uparams.opt_doc_col);
3127+
3128+ if (col > (unsigned int) (uparams.opt_doc_col + 3))
3129+ __argp_fmtstream_putc (stream, '\n');
3130+ else if (col >= (unsigned int) uparams.opt_doc_col)
3131+ __argp_fmtstream_puts (stream, " ");
3132+ else
3133+ indent_to (stream, uparams.opt_doc_col);
3134+
3135+ __argp_fmtstream_puts (stream, fstr);
3136+ }
3137+ if (fstr && fstr != tstr)
3138+ free ((char *) fstr);
3139+
3140+ /* Reset the left margin. */
3141+ __argp_fmtstream_set_lmargin (stream, 0);
3142+ __argp_fmtstream_putc (stream, '\n');
3143+ }
3144+
3145+ hhstate->prev_entry = entry;
3146+
3147+cleanup:
3148+ __argp_fmtstream_set_lmargin (stream, old_lm);
3149+ __argp_fmtstream_set_wmargin (stream, old_wm);
3150+}
3151+
3152+/* Output a long help message about the options in HOL to STREAM. */
3153+static void
3154+hol_help (struct hol *hol, const struct argp_state *state,
3155+ argp_fmtstream_t stream)
3156+{
3157+ unsigned num;
3158+ struct hol_entry *entry;
3159+ struct hol_help_state hhstate = { 0, 0, 0 };
3160+
3161+ for (entry = hol->entries, num = hol->num_entries; num > 0; entry++, num--)
3162+ hol_entry_help (entry, state, stream, &hhstate);
3163+
3164+ if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
3165+ {
3166+ const char *tstr = dgettext (state == NULL ? NULL
3167+ : state->root_argp->argp_domain, "\
3168+Mandatory or optional arguments to long options are also mandatory or \
3169+optional for any corresponding short options.");
3170+ const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
3171+ state ? state->root_argp : 0, state);
3172+ if (fstr && *fstr)
3173+ {
3174+ __argp_fmtstream_putc (stream, '\n');
3175+ __argp_fmtstream_puts (stream, fstr);
3176+ __argp_fmtstream_putc (stream, '\n');
3177+ }
3178+ if (fstr && fstr != tstr)
3179+ free ((char *) fstr);
3180+ }
3181+}
3182+
3183+/* Helper functions for hol_usage. */
3184+
3185+/* If OPT is a short option without an arg, append its key to the string
3186+ pointer pointer to by COOKIE, and advance the pointer. */
3187+static int
3188+add_argless_short_opt (const struct argp_option *opt,
3189+ const struct argp_option *real,
3190+ const char *domain, void *cookie)
3191+{
3192+ char **snao_end = cookie;
3193+ if (!(opt->arg || real->arg)
3194+ && !((opt->flags | real->flags) & OPTION_NO_USAGE))
3195+ *(*snao_end)++ = opt->key;
3196+ return 0;
3197+}
3198+
3199+/* If OPT is a short option with an arg, output a usage entry for it to the
3200+ stream pointed at by COOKIE. */
3201+static int
3202+usage_argful_short_opt (const struct argp_option *opt,
3203+ const struct argp_option *real,
3204+ const char *domain, void *cookie)
3205+{
3206+ argp_fmtstream_t stream = cookie;
3207+ const char *arg = opt->arg;
3208+ int flags = opt->flags | real->flags;
3209+
3210+ if (! arg)
3211+ arg = real->arg;
3212+
3213+ if (arg && !(flags & OPTION_NO_USAGE))
3214+ {
3215+ arg = dgettext (domain, arg);
3216+
3217+ if (flags & OPTION_ARG_OPTIONAL)
3218+ __argp_fmtstream_printf (stream, " [-%c[%s]]", opt->key, arg);
3219+ else
3220+ {
3221+ /* Manually do line wrapping so that it (probably) won't
3222+ get wrapped at the embedded space. */
3223+ space (stream, 6 + strlen (arg));
3224+ __argp_fmtstream_printf (stream, "[-%c %s]", opt->key, arg);
3225+ }
3226+ }
3227+
3228+ return 0;
3229+}
3230+
3231+/* Output a usage entry for the long option opt to the stream pointed at by
3232+ COOKIE. */
3233+static int
3234+usage_long_opt (const struct argp_option *opt,
3235+ const struct argp_option *real,
3236+ const char *domain, void *cookie)
3237+{
3238+ argp_fmtstream_t stream = cookie;
3239+ const char *arg = opt->arg;
3240+ int flags = opt->flags | real->flags;
3241+
3242+ if (! arg)
3243+ arg = real->arg;
3244+
3245+ if (! (flags & OPTION_NO_USAGE))
3246+ {
3247+ if (arg)
3248+ {
3249+ arg = dgettext (domain, arg);
3250+ if (flags & OPTION_ARG_OPTIONAL)
3251+ __argp_fmtstream_printf (stream, " [--%s[=%s]]", opt->name, arg);
3252+ else
3253+ __argp_fmtstream_printf (stream, " [--%s=%s]", opt->name, arg);
3254+ }
3255+ else
3256+ __argp_fmtstream_printf (stream, " [--%s]", opt->name);
3257+ }
3258+
3259+ return 0;
3260+}
3261+
3262+/* Print a short usage description for the arguments in HOL to STREAM. */
3263+static void
3264+hol_usage (struct hol *hol, argp_fmtstream_t stream)
3265+{
3266+ if (hol->num_entries > 0)
3267+ {
3268+ unsigned nentries;
3269+ struct hol_entry *entry;
3270+ char *short_no_arg_opts = alloca (strlen (hol->short_options) + 1);
3271+ char *snao_end = short_no_arg_opts;
3272+
3273+ /* First we put a list of short options without arguments. */
3274+ for (entry = hol->entries, nentries = hol->num_entries
3275+ ; nentries > 0
3276+ ; entry++, nentries--)
3277+ hol_entry_short_iterate (entry, add_argless_short_opt,
3278+ entry->argp->argp_domain, &snao_end);
3279+ if (snao_end > short_no_arg_opts)
3280+ {
3281+ *snao_end++ = 0;
3282+ __argp_fmtstream_printf (stream, " [-%s]", short_no_arg_opts);
3283+ }
3284+
3285+ /* Now a list of short options *with* arguments. */
3286+ for (entry = hol->entries, nentries = hol->num_entries
3287+ ; nentries > 0
3288+ ; entry++, nentries--)
3289+ hol_entry_short_iterate (entry, usage_argful_short_opt,
3290+ entry->argp->argp_domain, stream);
3291+
3292+ /* Finally, a list of long options (whew!). */
3293+ for (entry = hol->entries, nentries = hol->num_entries
3294+ ; nentries > 0
3295+ ; entry++, nentries--)
3296+ hol_entry_long_iterate (entry, usage_long_opt,
3297+ entry->argp->argp_domain, stream);
3298+ }
3299+}
3300+
3301+/* Make a HOL containing all levels of options in ARGP. CLUSTER is the
3302+ cluster in which ARGP's entries should be clustered, or 0. */
3303+static struct hol *
3304+argp_hol (const struct argp *argp, struct hol_cluster *cluster)
3305+{
3306+ const struct argp_child *child = argp->children;
3307+ struct hol *hol = make_hol (argp, cluster);
3308+ if (child)
3309+ while (child->argp)
3310+ {
3311+ struct hol_cluster *child_cluster =
3312+ ((child->group || child->header)
3313+ /* Put CHILD->argp within its own cluster. */
3314+ ? hol_add_cluster (hol, child->group, child->header,
3315+ child - argp->children, cluster, argp)
3316+ /* Just merge it into the parent's cluster. */
3317+ : cluster);
3318+ hol_append (hol, argp_hol (child->argp, child_cluster)) ;
3319+ child++;
3320+ }
3321+ return hol;
3322+}
3323+
3324+/* Calculate how many different levels with alternative args strings exist in
3325+ ARGP. */
3326+static size_t
3327+argp_args_levels (const struct argp *argp)
3328+{
3329+ size_t levels = 0;
3330+ const struct argp_child *child = argp->children;
3331+
3332+ if (argp->args_doc && strchr (argp->args_doc, '\n'))
3333+ levels++;
3334+
3335+ if (child)
3336+ while (child->argp)
3337+ levels += argp_args_levels ((child++)->argp);
3338+
3339+ return levels;
3340+}
3341+
3342+/* Print all the non-option args documented in ARGP to STREAM. Any output is
3343+ preceded by a space. LEVELS is a pointer to a byte vector the length
3344+ returned by argp_args_levels; it should be initialized to zero, and
3345+ updated by this routine for the next call if ADVANCE is true. True is
3346+ returned as long as there are more patterns to output. */
3347+static int
3348+argp_args_usage (const struct argp *argp, const struct argp_state *state,
3349+ char **levels, int advance, argp_fmtstream_t stream)
3350+{
3351+ char *our_level = *levels;
3352+ int multiple = 0;
3353+ const struct argp_child *child = argp->children;
3354+ const char *tdoc = dgettext (argp->argp_domain, argp->args_doc), *nl = 0;
3355+ const char *fdoc = filter_doc (tdoc, ARGP_KEY_HELP_ARGS_DOC, argp, state);
3356+
3357+ if (fdoc)
3358+ {
3359+ const char *cp = fdoc;
3360+ nl = strchrnul (cp, '\n');
3361+ if (*nl != '\0')
3362+ /* This is a `multi-level' args doc; advance to the correct position
3363+ as determined by our state in LEVELS, and update LEVELS. */
3364+ {
3365+ int i;
3366+ multiple = 1;
3367+ for (i = 0; i < *our_level; i++)
3368+ cp = nl + 1, nl = strchrnul (cp, '\n');
3369+ (*levels)++;
3370+ }
3371+
3372+ /* Manually do line wrapping so that it (probably) won't get wrapped at
3373+ any embedded spaces. */
3374+ space (stream, 1 + nl - cp);
3375+
3376+ __argp_fmtstream_write (stream, cp, nl - cp);
3377+ }
3378+ if (fdoc && fdoc != tdoc)
3379+ free ((char *)fdoc); /* Free user's modified doc string. */
3380+
3381+ if (child)
3382+ while (child->argp)
3383+ advance = !argp_args_usage ((child++)->argp, state, levels, advance, stream);
3384+
3385+ if (advance && multiple)
3386+ {
3387+ /* Need to increment our level. */
3388+ if (*nl)
3389+ /* There's more we can do here. */
3390+ {
3391+ (*our_level)++;
3392+ advance = 0; /* Our parent shouldn't advance also. */
3393+ }
3394+ else if (*our_level > 0)
3395+ /* We had multiple levels, but used them up; reset to zero. */
3396+ *our_level = 0;
3397+ }
3398+
3399+ return !advance;
3400+}
3401+
3402+/* Print the documentation for ARGP to STREAM; if POST is false, then
3403+ everything preceeding a `\v' character in the documentation strings (or
3404+ the whole string, for those with none) is printed, otherwise, everything
3405+ following the `\v' character (nothing for strings without). Each separate
3406+ bit of documentation is separated a blank line, and if PRE_BLANK is true,
3407+ then the first is as well. If FIRST_ONLY is true, only the first
3408+ occurrence is output. Returns true if anything was output. */
3409+static int
3410+argp_doc (const struct argp *argp, const struct argp_state *state,
3411+ int post, int pre_blank, int first_only,
3412+ argp_fmtstream_t stream)
3413+{
3414+ const char *text;
3415+ const char *inp_text;
3416+ void *input = 0;
3417+ int anything = 0;
3418+ size_t inp_text_limit = 0;
3419+ const char *doc = dgettext (argp->argp_domain, argp->doc);
3420+ const struct argp_child *child = argp->children;
3421+
3422+ if (doc)
3423+ {
3424+ char *vt = strchr (doc, '\v');
3425+ inp_text = post ? (vt ? vt + 1 : 0) : doc;
3426+ inp_text_limit = (!post && vt) ? (vt - doc) : 0;
3427+ }
3428+ else
3429+ inp_text = 0;
3430+
3431+ if (argp->help_filter)
3432+ /* We have to filter the doc strings. */
3433+ {
3434+ if (inp_text_limit)
3435+ /* Copy INP_TEXT so that it's nul-terminated. */
3436+ inp_text = strndup (inp_text, inp_text_limit);
3437+ input = __argp_input (argp, state);
3438+ text =
3439+ (*argp->help_filter) (post
3440+ ? ARGP_KEY_HELP_POST_DOC
3441+ : ARGP_KEY_HELP_PRE_DOC,
3442+ inp_text, input);
3443+ }
3444+ else
3445+ text = (const char *) inp_text;
3446+
3447+ if (text)
3448+ {
3449+ if (pre_blank)
3450+ __argp_fmtstream_putc (stream, '\n');
3451+
3452+ if (text == inp_text && inp_text_limit)
3453+ __argp_fmtstream_write (stream, inp_text, inp_text_limit);
3454+ else
3455+ __argp_fmtstream_puts (stream, text);
3456+
3457+ if (__argp_fmtstream_point (stream) > __argp_fmtstream_lmargin (stream))
3458+ __argp_fmtstream_putc (stream, '\n');
3459+
3460+ anything = 1;
3461+ }
3462+
3463+ if (text && text != inp_text)
3464+ free ((char *) text); /* Free TEXT returned from the help filter. */
3465+ if (inp_text && inp_text_limit && argp->help_filter)
3466+ free ((char *) inp_text); /* We copied INP_TEXT, so free it now. */
3467+
3468+ if (post && argp->help_filter)
3469+ /* Now see if we have to output a ARGP_KEY_HELP_EXTRA text. */
3470+ {
3471+ text = (*argp->help_filter) (ARGP_KEY_HELP_EXTRA, 0, input);
3472+ if (text)
3473+ {
3474+ if (anything || pre_blank)
3475+ __argp_fmtstream_putc (stream, '\n');
3476+ __argp_fmtstream_puts (stream, text);
3477+ free ((char *) text);
3478+ if (__argp_fmtstream_point (stream)
3479+ > __argp_fmtstream_lmargin (stream))
3480+ __argp_fmtstream_putc (stream, '\n');
3481+ anything = 1;
3482+ }
3483+ }
3484+
3485+ if (child)
3486+ while (child->argp && !(first_only && anything))
3487+ anything |=
3488+ argp_doc ((child++)->argp, state,
3489+ post, anything || pre_blank, first_only,
3490+ stream);
3491+
3492+ return anything;
3493+}
3494+
3495+/* Output a usage message for ARGP to STREAM. If called from
3496+ argp_state_help, STATE is the relevent parsing state. FLAGS are from the
3497+ set ARGP_HELP_*. NAME is what to use wherever a `program name' is
3498+ needed. */
3499+static void
3500+_help (const struct argp *argp, const struct argp_state *state, FILE *stream,
3501+ unsigned flags, char *name)
3502+{
3503+ int anything = 0; /* Whether we've output anything. */
3504+ struct hol *hol = 0;
3505+ argp_fmtstream_t fs;
3506+
3507+ if (! stream)
3508+ return;
3509+
3510+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3511+ flockfile (stream);
3512+#endif
3513+
3514+ fill_in_uparams (state);
3515+
3516+ fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
3517+ if (! fs)
3518+ {
3519+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3520+ funlockfile (stream);
3521+#endif
3522+ return;
3523+ }
3524+
3525+ if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG))
3526+ {
3527+ hol = argp_hol (argp, 0);
3528+
3529+ /* If present, these options always come last. */
3530+ hol_set_group (hol, "help", -1);
3531+ hol_set_group (hol, "version", -1);
3532+
3533+ hol_sort (hol);
3534+ }
3535+
3536+ if (flags & (ARGP_HELP_USAGE | ARGP_HELP_SHORT_USAGE))
3537+ /* Print a short `Usage:' message. */
3538+ {
3539+ int first_pattern = 1, more_patterns;
3540+ size_t num_pattern_levels = argp_args_levels (argp);
3541+ char *pattern_levels = alloca (num_pattern_levels);
3542+
3543+ memset (pattern_levels, 0, num_pattern_levels);
3544+
3545+ do
3546+ {
3547+ int old_lm;
3548+ int old_wm = __argp_fmtstream_set_wmargin (fs, uparams.usage_indent);
3549+ char *levels = pattern_levels;
3550+
3551+ if (first_pattern)
3552+ __argp_fmtstream_printf (fs, "%s %s",
3553+ dgettext (argp->argp_domain, "Usage:"),
3554+ name);
3555+ else
3556+ __argp_fmtstream_printf (fs, "%s %s",
3557+ dgettext (argp->argp_domain, " or: "),
3558+ name);
3559+
3560+ /* We set the lmargin as well as the wmargin, because hol_usage
3561+ manually wraps options with newline to avoid annoying breaks. */
3562+ old_lm = __argp_fmtstream_set_lmargin (fs, uparams.usage_indent);
3563+
3564+ if (flags & ARGP_HELP_SHORT_USAGE)
3565+ /* Just show where the options go. */
3566+ {
3567+ if (hol->num_entries > 0)
3568+ __argp_fmtstream_puts (fs, dgettext (argp->argp_domain,
3569+ " [OPTION...]"));
3570+ }
3571+ else
3572+ /* Actually print the options. */
3573+ {
3574+ hol_usage (hol, fs);
3575+ flags |= ARGP_HELP_SHORT_USAGE; /* But only do so once. */
3576+ }
3577+
3578+ more_patterns = argp_args_usage (argp, state, &levels, 1, fs);
3579+
3580+ __argp_fmtstream_set_wmargin (fs, old_wm);
3581+ __argp_fmtstream_set_lmargin (fs, old_lm);
3582+
3583+ __argp_fmtstream_putc (fs, '\n');
3584+ anything = 1;
3585+
3586+ first_pattern = 0;
3587+ }
3588+ while (more_patterns);
3589+ }
3590+
3591+ if (flags & ARGP_HELP_PRE_DOC)
3592+ anything |= argp_doc (argp, state, 0, 0, 1, fs);
3593+
3594+ if (flags & ARGP_HELP_SEE)
3595+ {
3596+ __argp_fmtstream_printf (fs, dgettext (argp->argp_domain, "\
3597+Try `%s --help' or `%s --usage' for more information.\n"),
3598+ name, name);
3599+ anything = 1;
3600+ }
3601+
3602+ if (flags & ARGP_HELP_LONG)
3603+ /* Print a long, detailed help message. */
3604+ {
3605+ /* Print info about all the options. */
3606+ if (hol->num_entries > 0)
3607+ {
3608+ if (anything)
3609+ __argp_fmtstream_putc (fs, '\n');
3610+ hol_help (hol, state, fs);
3611+ anything = 1;
3612+ }
3613+ }
3614+
3615+ if (flags & ARGP_HELP_POST_DOC)
3616+ /* Print any documentation strings at the end. */
3617+ anything |= argp_doc (argp, state, 1, anything, 0, fs);
3618+
3619+ if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
3620+ {
3621+ if (anything)
3622+ __argp_fmtstream_putc (fs, '\n');
3623+ __argp_fmtstream_printf (fs, dgettext (argp->argp_domain,
3624+ "Report bugs to %s.\n"),
3625+ argp_program_bug_address);
3626+ anything = 1;
3627+ }
3628+
3629+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3630+ funlockfile (stream);
3631+#endif
3632+
3633+ if (hol)
3634+ hol_free (hol);
3635+
3636+ __argp_fmtstream_free (fs);
3637+}
3638+
3639+/* Output a usage message for ARGP to STREAM. FLAGS are from the set
3640+ ARGP_HELP_*. NAME is what to use wherever a `program name' is needed. */
3641+void argp_help (const struct argp *argp, FILE *stream,
3642+ unsigned flags, char *name)
3643+{
3644+ _help (argp, 0, stream, flags, name);
3645+}
3646+
3647+char *
3648+__argp_short_program_name (void)
3649+{
3650+# ifdef __UCLIBC_HAS_PROGRAM_INVOCATION_NAME__
3651+/*
3652+ * uClibc provides both program_invocation_name and
3653+ * program_invocation_short_name
3654+ */
3655+ return (char *) program_invocation_short_name;
3656+# else
3657+ /* FIXME: What now? Miles suggests that it is better to use NULL,
3658+ but currently the value is passed on directly to fputs_unlocked,
3659+ so that requires more changes. */
3660+# if __GNUC__
3661+# warning No reasonable value to return
3662+# endif /* __GNUC__ */
3663+ return "";
3664+# endif
3665+}
3666+
3667+/* Output, if appropriate, a usage message for STATE to STREAM. FLAGS are
3668+ from the set ARGP_HELP_*. */
3669+void
3670+argp_state_help (const struct argp_state *state, FILE *stream, unsigned flags)
3671+{
3672+ if ((!state || ! (state->flags & ARGP_NO_ERRS)) && stream)
3673+ {
3674+ if (state && (state->flags & ARGP_LONG_ONLY))
3675+ flags |= ARGP_HELP_LONG_ONLY;
3676+
3677+ _help (state ? state->root_argp : 0, state, stream, flags,
3678+ state ? state->name : __argp_short_program_name ());
3679+
3680+ if (!state || ! (state->flags & ARGP_NO_EXIT))
3681+ {
3682+ if (flags & ARGP_HELP_EXIT_ERR)
3683+ exit (argp_err_exit_status);
3684+ if (flags & ARGP_HELP_EXIT_OK)
3685+ exit (0);
3686+ }
3687+ }
3688+}
3689+
3690+/* If appropriate, print the printf string FMT and following args, preceded
3691+ by the program name and `:', to stderr, and followed by a `Try ... --help'
3692+ message, then exit (1). */
3693+void
3694+argp_error (const struct argp_state *state, const char *fmt, ...)
3695+{
3696+ if (!state || !(state->flags & ARGP_NO_ERRS))
3697+ {
3698+ FILE *stream = state ? state->err_stream : stderr;
3699+
3700+ if (stream)
3701+ {
3702+ va_list ap;
3703+
3704+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3705+ flockfile (stream);
3706+#endif
3707+
3708+ va_start (ap, fmt);
3709+
3710+#if defined _LIBC && defined USE_IN_LIBIO
3711+ char *buf;
3712+
3713+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
3714+ buf = NULL;
3715+
3716+ __fxprintf (stream, "%s: %s\n",
3717+ state ? state->name : __argp_short_program_name (), buf);
3718+
3719+ free (buf);
3720+#else
3721+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
3722+ stream);
3723+ putc_unlocked (':', stream);
3724+ putc_unlocked (' ', stream);
3725+
3726+ vfprintf (stream, fmt, ap);
3727+
3728+ putc_unlocked ('\n', stream);
3729+#endif
3730+
3731+ argp_state_help (state, stream, ARGP_HELP_STD_ERR);
3732+
3733+ va_end (ap);
3734+
3735+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3736+ funlockfile (stream);
3737+#endif
3738+ }
3739+ }
3740+}
3741+
3742+/* Similar to the standard gnu error-reporting function error(), but will
3743+ respect the ARGP_NO_EXIT and ARGP_NO_ERRS flags in STATE, and will print
3744+ to STATE->err_stream. This is useful for argument parsing code that is
3745+ shared between program startup (when exiting is desired) and runtime
3746+ option parsing (when typically an error code is returned instead). The
3747+ difference between this function and argp_error is that the latter is for
3748+ *parsing errors*, and the former is for other problems that occur during
3749+ parsing but don't reflect a (syntactic) problem with the input. */
3750+void
3751+argp_failure (const struct argp_state *state, int status, int errnum,
3752+ const char *fmt, ...)
3753+{
3754+ if (!state || !(state->flags & ARGP_NO_ERRS))
3755+ {
3756+ FILE *stream = state ? state->err_stream : stderr;
3757+
3758+ if (stream)
3759+ {
3760+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3761+ flockfile (stream);
3762+#endif
3763+
3764+#if defined _LIBC && defined USE_IN_LIBIO
3765+ __fxprintf (stream, "%s",
3766+ state ? state->name : __argp_short_program_name ());
3767+#else
3768+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
3769+ stream);
3770+#endif
3771+
3772+ if (fmt)
3773+ {
3774+ va_list ap;
3775+
3776+ va_start (ap, fmt);
3777+#if defined _LIBC && defined USE_IN_LIBIO
3778+ char *buf;
3779+
3780+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
3781+ buf = NULL;
3782+
3783+ __fxprintf (stream, ": %s", buf);
3784+
3785+ free (buf);
3786+#else
3787+ putc_unlocked (':', stream);
3788+ putc_unlocked (' ', stream);
3789+
3790+ vfprintf (stream, fmt, ap);
3791+#endif
3792+
3793+ va_end (ap);
3794+ }
3795+
3796+ if (errnum)
3797+ {
3798+#if (defined _LIBC && defined USE_IN_LIBIO) || defined HAVE_STRERROR_R
3799+ char buf[200];
3800+#endif
3801+#if defined _LIBC && defined USE_IN_LIBIO
3802+ __fxprintf (stream, ": %s",
3803+ strerror_r (errnum, buf, sizeof (buf)));
3804+#else
3805+ putc_unlocked (':', stream);
3806+ putc_unlocked (' ', stream);
3807+# ifdef HAVE_STRERROR_R
3808+ fputs (strerror_r (errnum, buf, sizeof (buf)), stream);
3809+# else
3810+ fputs (strerror (errnum), stream);
3811+# endif
3812+#endif
3813+ }
3814+
3815+#ifdef USE_IN_LIBIO
3816+ if (_IO_fwide (stream, 0) > 0)
3817+ putwc_unlocked (L'\n', stream);
3818+ else
3819+#endif
3820+ putc_unlocked ('\n', stream);
3821+
3822+#if _LIBC || (HAVE_FLOCKFILE && HAVE_FUNLOCKFILE)
3823+ funlockfile (stream);
3824+#endif
3825+
3826+ if (status && (!state || !(state->flags & ARGP_NO_EXIT)))
3827+ exit (status);
3828+ }
3829+ }
3830+}
3831diff --git a/libuargp/argp-parse.c b/libuargp/argp-parse.c
3832new file mode 100644
3833index 0000000..86b2b24
3834--- /dev/null
3835+++ b/libuargp/argp-parse.c
3836@@ -0,0 +1,949 @@
3837+/* Hierarchial argument parsing, layered over getopt
3838+ Copyright (C) 1995-2000, 2002, 2003, 2004 Free Software Foundation, Inc.
3839+ This file is part of the GNU C Library.
3840+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
3841+
3842+ The GNU C Library is free software; you can redistribute it and/or
3843+ modify it under the terms of the GNU Lesser General Public
3844+ License as published by the Free Software Foundation; either
3845+ version 2.1 of the License, or (at your option) any later version.
3846+
3847+ The GNU C Library is distributed in the hope that it will be useful,
3848+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3849+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3850+ Lesser General Public License for more details.
3851+
3852+ You should have received a copy of the GNU Lesser General Public
3853+ License along with the GNU C Library; if not, write to the Free
3854+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3855+ 02111-1307 USA.
3856+
3857+ Modified for uClibc by: Salvatore Cro <salvatore.cro at st.com>
3858+*/
3859+
3860+#ifdef HAVE_CONFIG_H
3861+#include <config.h>
3862+#endif
3863+
3864+/* AIX requires this to be the first thing in the file. */
3865+#ifndef __GNUC__
3866+# if HAVE_ALLOCA_H || defined _LIBC
3867+# include <alloca.h>
3868+# else
3869+# ifdef _AIX
3870+#pragma alloca
3871+# else
3872+# ifndef alloca /* predefined by HP cc +Olibcalls */
3873+char *alloca ();
3874+# endif
3875+# endif
3876+# endif
3877+#endif
3878+
3879+#include <stdlib.h>
3880+#include <string.h>
3881+#include <unistd.h>
3882+#include <limits.h>
3883+#include <getopt.h>
3884+#include <bits/getopt_int.h>
3885+
3886+#include <features.h>
3887+#ifndef _
3888+/* This is for other GNU distributions with internationalized messages.
3889+ When compiling libc, the _ macro is predefined. */
3890+# if (defined HAVE_LIBINTL_H || defined _LIBC) && defined __UCLIBC_HAS_GETTEXT_AWARENESS__
3891+# include <libintl.h>
3892+# ifdef _LIBC
3893+# undef dgettext
3894+# define dgettext(domain, msgid) \
3895+ INTUSE(__dcgettext) (domain, msgid, LC_MESSAGES)
3896+# endif
3897+# else
3898+# define dgettext(domain, msgid) (msgid)
3899+# define gettext(msgid) (msgid)
3900+# endif
3901+#endif
3902+#ifndef N_
3903+# define N_(msgid) (msgid)
3904+#endif
3905+
3906+#include <argp.h>
3907+
3908+/* Getopt return values. */
3909+#define KEY_END (-1) /* The end of the options. */
3910+#define KEY_ARG 1 /* A non-option argument. */
3911+#define KEY_ERR '?' /* An error parsing the options. */
3912+
3913+/* The meta-argument used to prevent any further arguments being interpreted
3914+ as options. */
3915+#define QUOTE "--"
3916+
3917+/* The number of bits we steal in a long-option value for our own use. */
3918+#define GROUP_BITS CHAR_BIT
3919+
3920+/* The number of bits available for the user value. */
3921+#define USER_BITS ((sizeof ((struct option *)0)->val * CHAR_BIT) - GROUP_BITS)
3922+#define USER_MASK ((1 << USER_BITS) - 1)
3923+
3924+/* EZ alias for ARGP_ERR_UNKNOWN. */
3925+#define EBADKEY ARGP_ERR_UNKNOWN
3926+
3927+/* Default options. */
3928+
3929+/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep
3930+ for one second intervals, decrementing _ARGP_HANG until it's zero. Thus
3931+ you can force the program to continue by attaching a debugger and setting
3932+ it to 0 yourself. */
3933+static volatile int _argp_hang;
3934+
3935+#define OPT_PROGNAME -2
3936+#define OPT_USAGE -3
3937+#define OPT_HANG -4
3938+
3939+static const struct argp_option argp_default_options[] =
3940+{
3941+ {"help", '?', 0, 0, N_("Give this help list"), -1},
3942+ {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message")},
3943+ {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name")},
3944+ {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN,
3945+ N_("Hang for SECS seconds (default 3600)")},
3946+ {0, 0}
3947+};
3948+
3949+static error_t
3950+argp_default_parser (int key, char *arg, struct argp_state *state)
3951+{
3952+ switch (key)
3953+ {
3954+ case '?':
3955+ argp_state_help (state, state->out_stream, ARGP_HELP_STD_HELP);
3956+ break;
3957+ case OPT_USAGE:
3958+ argp_state_help (state, state->out_stream,
3959+ ARGP_HELP_USAGE | ARGP_HELP_EXIT_OK);
3960+ break;
3961+
3962+ case OPT_PROGNAME: /* Set the program name. */
3963+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_NAME
3964+ program_invocation_name = arg;
3965+#endif
3966+ /* [Note that some systems only have PROGRAM_INVOCATION_SHORT_NAME (aka
3967+ __PROGNAME), in which case, PROGRAM_INVOCATION_NAME is just defined
3968+ to be that, so we have to be a bit careful here.] */
3969+
3970+ /* Update what we use for messages. */
3971+ state->name = strrchr (arg, '/');
3972+ if (state->name)
3973+ state->name++;
3974+ else
3975+ state->name = arg;
3976+
3977+#if defined _LIBC || HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
3978+ program_invocation_short_name = state->name;
3979+#endif
3980+
3981+ if ((state->flags & (ARGP_PARSE_ARGV0 | ARGP_NO_ERRS))
3982+ == ARGP_PARSE_ARGV0)
3983+ /* Update what getopt uses too. */
3984+ state->argv[0] = arg;
3985+
3986+ break;
3987+
3988+ case OPT_HANG:
3989+ _argp_hang = atoi (arg ? arg : "3600");
3990+ while (_argp_hang-- > 0)
3991+ sleep (1);
3992+ break;
3993+
3994+ default:
3995+ return EBADKEY;
3996+ }
3997+ return 0;
3998+}
3999+
4000+static const struct argp argp_default_argp =
4001+ {argp_default_options, &argp_default_parser, NULL, NULL, NULL, NULL, "libc"};
4002+
4003+
4004+static const struct argp_option argp_version_options[] =
4005+{
4006+ {"version", 'V', 0, 0, N_("Print program version"), -1},
4007+ {0, 0}
4008+};
4009+
4010+static error_t
4011+argp_version_parser (int key, char *arg, struct argp_state *state)
4012+{
4013+ switch (key)
4014+ {
4015+ case 'V':
4016+ if (argp_program_version_hook)
4017+ (*argp_program_version_hook) (state->out_stream, state);
4018+ else if (argp_program_version)
4019+ fprintf (state->out_stream, "%s\n", argp_program_version);
4020+ else
4021+ argp_error (state, dgettext (state->root_argp->argp_domain,
4022+ "(PROGRAM ERROR) No version known!?"));
4023+ if (! (state->flags & ARGP_NO_EXIT))
4024+ exit (0);
4025+ break;
4026+ default:
4027+ return EBADKEY;
4028+ }
4029+ return 0;
4030+}
4031+
4032+static const struct argp argp_version_argp =
4033+ {argp_version_options, &argp_version_parser, NULL, NULL, NULL, NULL, "libc"};
4034+
4035+/* Returns the offset into the getopt long options array LONG_OPTIONS of a
4036+ long option with called NAME, or -1 if none is found. Passing NULL as
4037+ NAME will return the number of options. */
4038+static int
4039+find_long_option (struct option *long_options, const char *name)
4040+{
4041+ struct option *l = long_options;
4042+ while (l->name != NULL)
4043+ if (name != NULL && strcmp (l->name, name) == 0)
4044+ return l - long_options;
4045+ else
4046+ l++;
4047+ if (name == NULL)
4048+ return l - long_options;
4049+ else
4050+ return -1;
4051+}
4052+
4053+
4054+/* The state of a `group' during parsing. Each group corresponds to a
4055+ particular argp structure from the tree of such descending from the top
4056+ level argp passed to argp_parse. */
4057+struct group
4058+{
4059+ /* This group's parsing function. */
4060+ argp_parser_t parser;
4061+
4062+ /* Which argp this group is from. */
4063+ const struct argp *argp;
4064+
4065+ /* Points to the point in SHORT_OPTS corresponding to the end of the short
4066+ options for this group. We use it to determine from which group a
4067+ particular short options is from. */
4068+ char *short_end;
4069+
4070+ /* The number of non-option args sucessfully handled by this parser. */
4071+ unsigned args_processed;
4072+
4073+ /* This group's parser's parent's group. */
4074+ struct group *parent;
4075+ unsigned parent_index; /* And the our position in the parent. */
4076+
4077+ /* These fields are swapped into and out of the state structure when
4078+ calling this group's parser. */
4079+ void *input, **child_inputs;
4080+ void *hook;
4081+};
4082+
4083+/* Call GROUP's parser with KEY and ARG, swapping any group-specific info
4084+ from STATE before calling, and back into state afterwards. If GROUP has
4085+ no parser, EBADKEY is returned. */
4086+static error_t
4087+group_parse (struct group *group, struct argp_state *state, int key, char *arg)
4088+{
4089+ if (group->parser)
4090+ {
4091+ error_t err;
4092+ state->hook = group->hook;
4093+ state->input = group->input;
4094+ state->child_inputs = group->child_inputs;
4095+ state->arg_num = group->args_processed;
4096+ err = (*group->parser)(key, arg, state);
4097+ group->hook = state->hook;
4098+ return err;
4099+ }
4100+ else
4101+ return EBADKEY;
4102+}
4103+
4104+struct parser
4105+{
4106+ const struct argp *argp;
4107+
4108+ /* SHORT_OPTS is the getopt short options string for the union of all the
4109+ groups of options. */
4110+ char *short_opts;
4111+ /* LONG_OPTS is the array of getop long option structures for the union of
4112+ all the groups of options. */
4113+ struct option *long_opts;
4114+ /* OPT_DATA is the getopt data used for the re-entrant getopt. */
4115+ struct _getopt_data opt_data;
4116+
4117+ /* States of the various parsing groups. */
4118+ struct group *groups;
4119+ /* The end of the GROUPS array. */
4120+ struct group *egroup;
4121+ /* An vector containing storage for the CHILD_INPUTS field in all groups. */
4122+ void **child_inputs;
4123+
4124+ /* True if we think using getopt is still useful; if false, then
4125+ remaining arguments are just passed verbatim with ARGP_KEY_ARG. This is
4126+ cleared whenever getopt returns KEY_END, but may be set again if the user
4127+ moves the next argument pointer backwards. */
4128+ int try_getopt;
4129+
4130+ /* State block supplied to parsing routines. */
4131+ struct argp_state state;
4132+
4133+ /* Memory used by this parser. */
4134+ void *storage;
4135+};
4136+
4137+/* The next usable entries in the various parser tables being filled in by
4138+ convert_options. */
4139+struct parser_convert_state
4140+{
4141+ struct parser *parser;
4142+ char *short_end;
4143+ struct option *long_end;
4144+ void **child_inputs_end;
4145+};
4146+
4147+/* Converts all options in ARGP (which is put in GROUP) and ancestors
4148+ into getopt options stored in SHORT_OPTS and LONG_OPTS; SHORT_END and
4149+ CVT->LONG_END are the points at which new options are added. Returns the
4150+ next unused group entry. CVT holds state used during the conversion. */
4151+static struct group *
4152+convert_options (const struct argp *argp,
4153+ struct group *parent, unsigned parent_index,
4154+ struct group *group, struct parser_convert_state *cvt)
4155+{
4156+ /* REAL is the most recent non-alias value of OPT. */
4157+ const struct argp_option *real = argp->options;
4158+ const struct argp_child *children = argp->children;
4159+
4160+ if (real || argp->parser)
4161+ {
4162+ const struct argp_option *opt;
4163+
4164+ if (real)
4165+ for (opt = real; !__option_is_end (opt); opt++)
4166+ {
4167+ if (! (opt->flags & OPTION_ALIAS))
4168+ /* OPT isn't an alias, so we can use values from it. */
4169+ real = opt;
4170+
4171+ if (! (real->flags & OPTION_DOC))
4172+ /* A real option (not just documentation). */
4173+ {
4174+ if (__option_is_short (opt))
4175+ /* OPT can be used as a short option. */
4176+ {
4177+ *cvt->short_end++ = opt->key;
4178+ if (real->arg)
4179+ {
4180+ *cvt->short_end++ = ':';
4181+ if (real->flags & OPTION_ARG_OPTIONAL)
4182+ *cvt->short_end++ = ':';
4183+ }
4184+ *cvt->short_end = '\0'; /* keep 0 terminated */
4185+ }
4186+
4187+ if (opt->name
4188+ && find_long_option (cvt->parser->long_opts, opt->name) < 0)
4189+ /* OPT can be used as a long option. */
4190+ {
4191+ cvt->long_end->name = opt->name;
4192+ cvt->long_end->has_arg =
4193+ (real->arg
4194+ ? (real->flags & OPTION_ARG_OPTIONAL
4195+ ? optional_argument
4196+ : required_argument)
4197+ : no_argument);
4198+ cvt->long_end->flag = 0;
4199+ /* we add a disambiguating code to all the user's
4200+ values (which is removed before we actually call
4201+ the function to parse the value); this means that
4202+ the user loses use of the high 8 bits in all his
4203+ values (the sign of the lower bits is preserved
4204+ however)... */
4205+ cvt->long_end->val =
4206+ ((opt->key | real->key) & USER_MASK)
4207+ + (((group - cvt->parser->groups) + 1) << USER_BITS);
4208+
4209+ /* Keep the LONG_OPTS list terminated. */
4210+ (++cvt->long_end)->name = NULL;
4211+ }
4212+ }
4213+ }
4214+
4215+ group->parser = argp->parser;
4216+ group->argp = argp;
4217+ group->short_end = cvt->short_end;
4218+ group->args_processed = 0;
4219+ group->parent = parent;
4220+ group->parent_index = parent_index;
4221+ group->input = 0;
4222+ group->hook = 0;
4223+ group->child_inputs = 0;
4224+
4225+ if (children)
4226+ /* Assign GROUP's CHILD_INPUTS field some space from
4227+ CVT->child_inputs_end.*/
4228+ {
4229+ unsigned num_children = 0;
4230+ while (children[num_children].argp)
4231+ num_children++;
4232+ group->child_inputs = cvt->child_inputs_end;
4233+ cvt->child_inputs_end += num_children;
4234+ }
4235+
4236+ parent = group++;
4237+ }
4238+ else
4239+ parent = 0;
4240+
4241+ if (children)
4242+ {
4243+ unsigned index = 0;
4244+ while (children->argp)
4245+ group =
4246+ convert_options (children++->argp, parent, index++, group, cvt);
4247+ }
4248+
4249+ return group;
4250+}
4251+
4252+/* Find the merged set of getopt options, with keys appropiately prefixed. */
4253+static void
4254+parser_convert (struct parser *parser, const struct argp *argp, int flags)
4255+{
4256+ struct parser_convert_state cvt;
4257+
4258+ cvt.parser = parser;
4259+ cvt.short_end = parser->short_opts;
4260+ cvt.long_end = parser->long_opts;
4261+ cvt.child_inputs_end = parser->child_inputs;
4262+
4263+ if (flags & ARGP_IN_ORDER)
4264+ *cvt.short_end++ = '-';
4265+ else if (flags & ARGP_NO_ARGS)
4266+ *cvt.short_end++ = '+';
4267+ *cvt.short_end = '\0';
4268+
4269+ cvt.long_end->name = NULL;
4270+
4271+ parser->argp = argp;
4272+
4273+ if (argp)
4274+ parser->egroup = convert_options (argp, 0, 0, parser->groups, &cvt);
4275+ else
4276+ parser->egroup = parser->groups; /* No parsers at all! */
4277+}
4278+
4279+/* Lengths of various parser fields which we will allocated. */
4280+struct parser_sizes
4281+{
4282+ size_t short_len; /* Getopt short options string. */
4283+ size_t long_len; /* Getopt long options vector. */
4284+ size_t num_groups; /* Group structures we allocate. */
4285+ size_t num_child_inputs; /* Child input slots. */
4286+};
4287+
4288+/* For ARGP, increments the NUM_GROUPS field in SZS by the total number of
4289+ argp structures descended from it, and the SHORT_LEN & LONG_LEN fields by
4290+ the maximum lengths of the resulting merged getopt short options string and
4291+ long-options array, respectively. */
4292+static void
4293+calc_sizes (const struct argp *argp, struct parser_sizes *szs)
4294+{
4295+ const struct argp_child *child = argp->children;
4296+ const struct argp_option *opt = argp->options;
4297+
4298+ if (opt || argp->parser)
4299+ {
4300+ szs->num_groups++;
4301+ if (opt)
4302+ {
4303+ int num_opts = 0;
4304+ while (!__option_is_end (opt++))
4305+ num_opts++;
4306+ szs->short_len += num_opts * 3; /* opt + up to 2 `:'s */
4307+ szs->long_len += num_opts;
4308+ }
4309+ }
4310+
4311+ if (child)
4312+ while (child->argp)
4313+ {
4314+ calc_sizes ((child++)->argp, szs);
4315+ szs->num_child_inputs++;
4316+ }
4317+}
4318+
4319+
4320+extern char * __argp_short_program_name (void);
4321+/* Initializes PARSER to parse ARGP in a manner described by FLAGS. */
4322+static error_t
4323+parser_init (struct parser *parser, const struct argp *argp,
4324+ int argc, char **argv, int flags, void *input)
4325+{
4326+ error_t err = 0;
4327+ struct group *group;
4328+ struct parser_sizes szs;
4329+ struct _getopt_data opt_data = _GETOPT_DATA_INITIALIZER;
4330+
4331+ szs.short_len = (flags & ARGP_NO_ARGS) ? 0 : 1;
4332+ szs.long_len = 0;
4333+ szs.num_groups = 0;
4334+ szs.num_child_inputs = 0;
4335+
4336+ if (argp)
4337+ calc_sizes (argp, &szs);
4338+
4339+ /* Lengths of the various bits of storage used by PARSER. */
4340+#define GLEN (szs.num_groups + 1) * sizeof (struct group)
4341+#define CLEN (szs.num_child_inputs * sizeof (void *))
4342+#define LLEN ((szs.long_len + 1) * sizeof (struct option))
4343+#define SLEN (szs.short_len + 1)
4344+
4345+ parser->storage = malloc (GLEN + CLEN + LLEN + SLEN);
4346+ if (! parser->storage)
4347+ return ENOMEM;
4348+
4349+ parser->groups = parser->storage;
4350+ parser->child_inputs = parser->storage + GLEN;
4351+ parser->long_opts = parser->storage + GLEN + CLEN;
4352+ parser->short_opts = parser->storage + GLEN + CLEN + LLEN;
4353+ parser->opt_data = opt_data;
4354+
4355+ memset (parser->child_inputs, 0, szs.num_child_inputs * sizeof (void *));
4356+ parser_convert (parser, argp, flags);
4357+
4358+ memset (&parser->state, 0, sizeof (struct argp_state));
4359+ parser->state.root_argp = parser->argp;
4360+ parser->state.argc = argc;
4361+ parser->state.argv = argv;
4362+ parser->state.flags = flags;
4363+ parser->state.err_stream = stderr;
4364+ parser->state.out_stream = stdout;
4365+ parser->state.next = 0; /* Tell getopt to initialize. */
4366+ parser->state.pstate = parser;
4367+
4368+ parser->try_getopt = 1;
4369+
4370+ /* Call each parser for the first time, giving it a chance to propagate
4371+ values to child parsers. */
4372+ if (parser->groups < parser->egroup)
4373+ parser->groups->input = input;
4374+ for (group = parser->groups;
4375+ group < parser->egroup && (!err || err == EBADKEY);
4376+ group++)
4377+ {
4378+ if (group->parent)
4379+ /* If a child parser, get the initial input value from the parent. */
4380+ group->input = group->parent->child_inputs[group->parent_index];
4381+
4382+ if (!group->parser
4383+ && group->argp->children && group->argp->children->argp)
4384+ /* For the special case where no parsing function is supplied for an
4385+ argp, propagate its input to its first child, if any (this just
4386+ makes very simple wrapper argps more convenient). */
4387+ group->child_inputs[0] = group->input;
4388+
4389+ err = group_parse (group, &parser->state, ARGP_KEY_INIT, 0);
4390+ }
4391+ if (err == EBADKEY)
4392+ err = 0; /* Some parser didn't understand. */
4393+
4394+ if (err)
4395+ return err;
4396+
4397+ if (parser->state.flags & ARGP_NO_ERRS)
4398+ {
4399+ parser->opt_data.opterr = 0;
4400+ if (parser->state.flags & ARGP_PARSE_ARGV0)
4401+ /* getopt always skips ARGV[0], so we have to fake it out. As long
4402+ as OPTERR is 0, then it shouldn't actually try to access it. */
4403+ parser->state.argv--, parser->state.argc++;
4404+ }
4405+ else
4406+ parser->opt_data.opterr = 1; /* Print error messages. */
4407+
4408+ if (parser->state.argv == argv && argv[0])
4409+ /* There's an argv[0]; use it for messages. */
4410+ {
4411+ char *short_name = strrchr (argv[0], '/');
4412+ parser->state.name = short_name ? short_name + 1 : argv[0];
4413+ }
4414+ else
4415+ parser->state.name = __argp_short_program_name ();
4416+
4417+ return 0;
4418+}
4419+
4420+/* Free any storage consumed by PARSER (but not PARSER itself). */
4421+static error_t
4422+parser_finalize (struct parser *parser,
4423+ error_t err, int arg_ebadkey, int *end_index)
4424+{
4425+ struct group *group;
4426+
4427+ if (err == EBADKEY && arg_ebadkey)
4428+ /* Suppress errors generated by unparsed arguments. */
4429+ err = 0;
4430+
4431+ if (! err)
4432+ {
4433+ if (parser->state.next == parser->state.argc)
4434+ /* We successfully parsed all arguments! Call all the parsers again,
4435+ just a few more times... */
4436+ {
4437+ for (group = parser->groups;
4438+ group < parser->egroup && (!err || err==EBADKEY);
4439+ group++)
4440+ if (group->args_processed == 0)
4441+ err = group_parse (group, &parser->state, ARGP_KEY_NO_ARGS, 0);
4442+ for (group = parser->egroup - 1;
4443+ group >= parser->groups && (!err || err==EBADKEY);
4444+ group--)
4445+ err = group_parse (group, &parser->state, ARGP_KEY_END, 0);
4446+
4447+ if (err == EBADKEY)
4448+ err = 0; /* Some parser didn't understand. */
4449+
4450+ /* Tell the user that all arguments are parsed. */
4451+ if (end_index)
4452+ *end_index = parser->state.next;
4453+ }
4454+ else if (end_index)
4455+ /* Return any remaining arguments to the user. */
4456+ *end_index = parser->state.next;
4457+ else
4458+ /* No way to return the remaining arguments, they must be bogus. */
4459+ {
4460+ if (!(parser->state.flags & ARGP_NO_ERRS)
4461+ && parser->state.err_stream)
4462+ fprintf (parser->state.err_stream,
4463+ dgettext (parser->argp->argp_domain,
4464+ "%s: Too many arguments\n"),
4465+ parser->state.name);
4466+ err = EBADKEY;
4467+ }
4468+ }
4469+
4470+ /* Okay, we're all done, with either an error or success; call the parsers
4471+ to indicate which one. */
4472+
4473+ if (err)
4474+ {
4475+ /* Maybe print an error message. */
4476+ if (err == EBADKEY)
4477+ /* An appropriate message describing what the error was should have
4478+ been printed earlier. */
4479+ argp_state_help (&parser->state, parser->state.err_stream,
4480+ ARGP_HELP_STD_ERR);
4481+
4482+ /* Since we didn't exit, give each parser an error indication. */
4483+ for (group = parser->groups; group < parser->egroup; group++)
4484+ group_parse (group, &parser->state, ARGP_KEY_ERROR, 0);
4485+ }
4486+ else
4487+ /* Notify parsers of success, and propagate back values from parsers. */
4488+ {
4489+ /* We pass over the groups in reverse order so that child groups are
4490+ given a chance to do there processing before passing back a value to
4491+ the parent. */
4492+ for (group = parser->egroup - 1
4493+ ; group >= parser->groups && (!err || err == EBADKEY)
4494+ ; group--)
4495+ err = group_parse (group, &parser->state, ARGP_KEY_SUCCESS, 0);
4496+ if (err == EBADKEY)
4497+ err = 0; /* Some parser didn't understand. */
4498+ }
4499+
4500+ /* Call parsers once more, to do any final cleanup. Errors are ignored. */
4501+ for (group = parser->egroup - 1; group >= parser->groups; group--)
4502+ group_parse (group, &parser->state, ARGP_KEY_FINI, 0);
4503+
4504+ if (err == EBADKEY)
4505+ err = EINVAL;
4506+
4507+ free (parser->storage);
4508+
4509+ return err;
4510+}
4511+
4512+/* Call the user parsers to parse the non-option argument VAL, at the current
4513+ position, returning any error. The state NEXT pointer is assumed to have
4514+ been adjusted (by getopt) to point after this argument; this function will
4515+ adjust it correctly to reflect however many args actually end up being
4516+ consumed. */
4517+static error_t
4518+parser_parse_arg (struct parser *parser, char *val)
4519+{
4520+ /* Save the starting value of NEXT, first adjusting it so that the arg
4521+ we're parsing is again the front of the arg vector. */
4522+ int index = --parser->state.next;
4523+ error_t err = EBADKEY;
4524+ struct group *group;
4525+ int key = 0; /* Which of ARGP_KEY_ARG[S] we used. */
4526+
4527+ /* Try to parse the argument in each parser. */
4528+ for (group = parser->groups
4529+ ; group < parser->egroup && err == EBADKEY
4530+ ; group++)
4531+ {
4532+ parser->state.next++; /* For ARGP_KEY_ARG, consume the arg. */
4533+ key = ARGP_KEY_ARG;
4534+ err = group_parse (group, &parser->state, key, val);
4535+
4536+ if (err == EBADKEY)
4537+ /* This parser doesn't like ARGP_KEY_ARG; try ARGP_KEY_ARGS instead. */
4538+ {
4539+ parser->state.next--; /* For ARGP_KEY_ARGS, put back the arg. */
4540+ key = ARGP_KEY_ARGS;
4541+ err = group_parse (group, &parser->state, key, 0);
4542+ }
4543+ }
4544+
4545+ if (! err)
4546+ {
4547+ if (key == ARGP_KEY_ARGS)
4548+ /* The default for ARGP_KEY_ARGS is to assume that if NEXT isn't
4549+ changed by the user, *all* arguments should be considered
4550+ consumed. */
4551+ parser->state.next = parser->state.argc;
4552+
4553+ if (parser->state.next > index)
4554+ /* Remember that we successfully processed a non-option
4555+ argument -- but only if the user hasn't gotten tricky and set
4556+ the clock back. */
4557+ (--group)->args_processed += (parser->state.next - index);
4558+ else
4559+ /* The user wants to reparse some args, give getopt another try. */
4560+ parser->try_getopt = 1;
4561+ }
4562+
4563+ return err;
4564+}
4565+
4566+/* Call the user parsers to parse the option OPT, with argument VAL, at the
4567+ current position, returning any error. */
4568+static error_t
4569+parser_parse_opt (struct parser *parser, int opt, char *val)
4570+{
4571+ /* The group key encoded in the high bits; 0 for short opts or
4572+ group_number + 1 for long opts. */
4573+ int group_key = opt >> USER_BITS;
4574+ error_t err = EBADKEY;
4575+
4576+ if (group_key == 0)
4577+ /* A short option. By comparing OPT's position in SHORT_OPTS to the
4578+ various starting positions in each group's SHORT_END field, we can
4579+ determine which group OPT came from. */
4580+ {
4581+ struct group *group;
4582+ char *short_index = strchr (parser->short_opts, opt);
4583+
4584+ if (short_index)
4585+ for (group = parser->groups; group < parser->egroup; group++)
4586+ if (group->short_end > short_index)
4587+ {
4588+ err = group_parse (group, &parser->state, opt,
4589+ parser->opt_data.optarg);
4590+ break;
4591+ }
4592+ }
4593+ else
4594+ /* A long option. We use shifts instead of masking for extracting
4595+ the user value in order to preserve the sign. */
4596+ err =
4597+ group_parse (&parser->groups[group_key - 1], &parser->state,
4598+ (opt << GROUP_BITS) >> GROUP_BITS,
4599+ parser->opt_data.optarg);
4600+
4601+ if (err == EBADKEY)
4602+ /* At least currently, an option not recognized is an error in the
4603+ parser, because we pre-compute which parser is supposed to deal
4604+ with each option. */
4605+ {
4606+ static const char bad_key_err[] =
4607+ N_("(PROGRAM ERROR) Option should have been recognized!?");
4608+ if (group_key == 0)
4609+ argp_error (&parser->state, "-%c: %s", opt,
4610+ dgettext (parser->argp->argp_domain, bad_key_err));
4611+ else
4612+ {
4613+ struct option *long_opt = parser->long_opts;
4614+ while (long_opt->val != opt && long_opt->name)
4615+ long_opt++;
4616+ argp_error (&parser->state, "--%s: %s",
4617+ long_opt->name ? long_opt->name : "???",
4618+ dgettext (parser->argp->argp_domain, bad_key_err));
4619+ }
4620+ }
4621+
4622+ return err;
4623+}
4624+
4625+/* Parse the next argument in PARSER (as indicated by PARSER->state.next).
4626+ Any error from the parsers is returned, and *ARGP_EBADKEY indicates
4627+ whether a value of EBADKEY is due to an unrecognized argument (which is
4628+ generally not fatal). */
4629+static error_t
4630+parser_parse_next (struct parser *parser, int *arg_ebadkey)
4631+{
4632+ int opt;
4633+ error_t err = 0;
4634+
4635+ if (parser->state.quoted && parser->state.next < parser->state.quoted)
4636+ /* The next argument pointer has been moved to before the quoted
4637+ region, so pretend we never saw the quoting `--', and give getopt
4638+ another chance. If the user hasn't removed it, getopt will just
4639+ process it again. */
4640+ parser->state.quoted = 0;
4641+
4642+ if (parser->try_getopt && !parser->state.quoted)
4643+ /* Give getopt a chance to parse this. */
4644+ {
4645+ /* Put it back in OPTIND for getopt. */
4646+ parser->opt_data.optind = parser->state.next;
4647+ /* Distinguish KEY_ERR from a real option. */
4648+ parser->opt_data.optopt = KEY_END;
4649+ if (parser->state.flags & ARGP_LONG_ONLY)
4650+ opt = _getopt_long_only_r (parser->state.argc, parser->state.argv,
4651+ parser->short_opts, parser->long_opts, 0,
4652+ &parser->opt_data);
4653+ else
4654+ opt = _getopt_long_r (parser->state.argc, parser->state.argv,
4655+ parser->short_opts, parser->long_opts, 0,
4656+ &parser->opt_data);
4657+ /* And see what getopt did. */
4658+ parser->state.next = parser->opt_data.optind;
4659+
4660+ if (opt == KEY_END)
4661+ /* Getopt says there are no more options, so stop using
4662+ getopt; we'll continue if necessary on our own. */
4663+ {
4664+ parser->try_getopt = 0;
4665+ if (parser->state.next > 1
4666+ && strcmp (parser->state.argv[parser->state.next - 1], QUOTE)
4667+ == 0)
4668+ /* Not only is this the end of the options, but it's a
4669+ `quoted' region, which may have args that *look* like
4670+ options, so we definitely shouldn't try to use getopt past
4671+ here, whatever happens. */
4672+ parser->state.quoted = parser->state.next;
4673+ }
4674+ else if (opt == KEY_ERR && parser->opt_data.optopt != KEY_END)
4675+ /* KEY_ERR can have the same value as a valid user short
4676+ option, but in the case of a real error, getopt sets OPTOPT
4677+ to the offending character, which can never be KEY_END. */
4678+ {
4679+ *arg_ebadkey = 0;
4680+ return EBADKEY;
4681+ }
4682+ }
4683+ else
4684+ opt = KEY_END;
4685+
4686+ if (opt == KEY_END)
4687+ {
4688+ /* We're past what getopt considers the options. */
4689+ if (parser->state.next >= parser->state.argc
4690+ || (parser->state.flags & ARGP_NO_ARGS))
4691+ /* Indicate that we're done. */
4692+ {
4693+ *arg_ebadkey = 1;
4694+ return EBADKEY;
4695+ }
4696+ else
4697+ /* A non-option arg; simulate what getopt might have done. */
4698+ {
4699+ opt = KEY_ARG;
4700+ parser->opt_data.optarg = parser->state.argv[parser->state.next++];
4701+ }
4702+ }
4703+
4704+ if (opt == KEY_ARG)
4705+ /* A non-option argument; try each parser in turn. */
4706+ err = parser_parse_arg (parser, parser->opt_data.optarg);
4707+ else
4708+ err = parser_parse_opt (parser, opt, parser->opt_data.optarg);
4709+
4710+ if (err == EBADKEY)
4711+ *arg_ebadkey = (opt == KEY_END || opt == KEY_ARG);
4712+
4713+ return err;
4714+}
4715+
4716+/* Parse the options strings in ARGC & ARGV according to the argp in ARGP.
4717+ FLAGS is one of the ARGP_ flags above. If END_INDEX is non-NULL, the
4718+ index in ARGV of the first unparsed option is returned in it. If an
4719+ unknown option is present, EINVAL is returned; if some parser routine
4720+ returned a non-zero value, it is returned; otherwise 0 is returned. */
4721+error_t
4722+argp_parse (const struct argp *argp, int argc, char **argv, unsigned flags,
4723+ int *end_index, void *input)
4724+{
4725+ error_t err;
4726+ struct parser parser;
4727+
4728+ /* If true, then err == EBADKEY is a result of a non-option argument failing
4729+ to be parsed (which in some cases isn't actually an error). */
4730+ int arg_ebadkey = 0;
4731+
4732+ if (! (flags & ARGP_NO_HELP))
4733+ /* Add our own options. */
4734+ {
4735+ struct argp_child *child = alloca (4 * sizeof (struct argp_child));
4736+ struct argp *top_argp = alloca (sizeof (struct argp));
4737+
4738+ /* TOP_ARGP has no options, it just serves to group the user & default
4739+ argps. */
4740+ memset (top_argp, 0, sizeof (*top_argp));
4741+ top_argp->children = child;
4742+
4743+ memset (child, 0, 4 * sizeof (struct argp_child));
4744+
4745+ if (argp)
4746+ (child++)->argp = argp;
4747+ (child++)->argp = &argp_default_argp;
4748+ if (argp_program_version || argp_program_version_hook)
4749+ (child++)->argp = &argp_version_argp;
4750+ child->argp = 0;
4751+
4752+ argp = top_argp;
4753+ }
4754+
4755+ /* Construct a parser for these arguments. */
4756+ err = parser_init (&parser, argp, argc, argv, flags, input);
4757+
4758+ if (! err)
4759+ /* Parse! */
4760+ {
4761+ while (! err)
4762+ err = parser_parse_next (&parser, &arg_ebadkey);
4763+ err = parser_finalize (&parser, err, arg_ebadkey, end_index);
4764+ }
4765+
4766+ return err;
4767+}
4768+
4769+/* Return the input field for ARGP in the parser corresponding to STATE; used
4770+ by the help routines. */
4771+void *
4772+__argp_input (const struct argp *argp, const struct argp_state *state)
4773+{
4774+ if (state)
4775+ {
4776+ struct group *group;
4777+ struct parser *parser = state->pstate;
4778+
4779+ for (group = parser->groups; group < parser->egroup; group++)
4780+ if (group->argp == argp)
4781+ return group->input;
4782+ }
4783+
4784+ return 0;
4785+}
4786diff --git a/libuargp/argp-pv.c b/libuargp/argp-pv.c
4787new file mode 100644
4788index 0000000..f1227b5
4789--- /dev/null
4790+++ b/libuargp/argp-pv.c
4791@@ -0,0 +1,25 @@
4792+/* Default definition for ARGP_PROGRAM_VERSION.
4793+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
4794+ This file is part of the GNU C Library.
4795+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
4796+
4797+ The GNU C Library is free software; you can redistribute it and/or
4798+ modify it under the terms of the GNU Lesser General Public
4799+ License as published by the Free Software Foundation; either
4800+ version 2.1 of the License, or (at your option) any later version.
4801+
4802+ The GNU C Library is distributed in the hope that it will be useful,
4803+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4804+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4805+ Lesser General Public License for more details.
4806+
4807+ You should have received a copy of the GNU Lesser General Public
4808+ License along with the GNU C Library; if not, write to the Free
4809+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
4810+ 02111-1307 USA. */
4811+
4812+/* If set by the user program to a non-zero value, then a default option
4813+ --version is added (unless the ARGP_NO_HELP flag is used), which will
4814+ print this this string followed by a newline and exit (unless the
4815+ ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
4816+const char *argp_program_version;
4817diff --git a/libuargp/argp-pvh.c b/libuargp/argp-pvh.c
4818new file mode 100644
4819index 0000000..1f1d962
4820--- /dev/null
4821+++ b/libuargp/argp-pvh.c
4822@@ -0,0 +1,32 @@
4823+/* Default definition for ARGP_PROGRAM_VERSION_HOOK.
4824+ Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
4825+ This file is part of the GNU C Library.
4826+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
4827+
4828+ The GNU C Library is free software; you can redistribute it and/or
4829+ modify it under the terms of the GNU Lesser General Public
4830+ License as published by the Free Software Foundation; either
4831+ version 2.1 of the License, or (at your option) any later version.
4832+
4833+ The GNU C Library is distributed in the hope that it will be useful,
4834+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4835+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4836+ Lesser General Public License for more details.
4837+
4838+ You should have received a copy of the GNU Lesser General Public
4839+ License along with the GNU C Library; if not, write to the Free
4840+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
4841+ 02111-1307 USA. */
4842+
4843+#ifdef HAVE_CONFIG_H
4844+#include <config.h>
4845+#endif
4846+
4847+#include <argp.h>
4848+
4849+/* If set by the user program to a non-zero value, then a default option
4850+ --version is added (unless the ARGP_NO_HELP flag is used), which calls
4851+ this function with a stream to print the version to and a pointer to the
4852+ current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
4853+ used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
4854+void (*argp_program_version_hook) (FILE *stream, struct argp_state *state);
4855diff --git a/libuargp/argp-xinl.c b/libuargp/argp-xinl.c
4856new file mode 100644
4857index 0000000..f1d3000
4858--- /dev/null
4859+++ b/libuargp/argp-xinl.c
4860@@ -0,0 +1,35 @@
4861+/* Real definitions for extern inline functions in argp.h
4862+ Copyright (C) 1997, 1998, 2004 Free Software Foundation, Inc.
4863+ This file is part of the GNU C Library.
4864+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
4865+
4866+ The GNU C Library is free software; you can redistribute it and/or
4867+ modify it under the terms of the GNU Lesser General Public
4868+ License as published by the Free Software Foundation; either
4869+ version 2.1 of the License, or (at your option) any later version.
4870+
4871+ The GNU C Library is distributed in the hope that it will be useful,
4872+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4873+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4874+ Lesser General Public License for more details.
4875+
4876+ You should have received a copy of the GNU Lesser General Public
4877+ License along with the GNU C Library; if not, write to the Free
4878+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
4879+ 02111-1307 USA. */
4880+
4881+#ifdef HAVE_CONFIG_H
4882+# include <config.h>
4883+#endif
4884+
4885+#if defined _LIBC || defined HAVE_FEATURES_H
4886+# include <features.h>
4887+#endif
4888+
4889+#ifndef __USE_EXTERN_INLINES
4890+# define __USE_EXTERN_INLINES 1
4891+#endif
4892+#define ARGP_EI
4893+#undef __OPTIMIZE__
4894+#define __OPTIMIZE__ 1
4895+#include <argp.h>
4896diff --git a/test/argp/Makefile b/test/argp/Makefile
4897new file mode 100644
4898index 0000000..616fe71
4899--- /dev/null
4900+++ b/test/argp/Makefile
4901@@ -0,0 +1,7 @@
4902+# uClibc argp tests
4903+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4904+
4905+top_builddir=../../
4906+include ../Rules.mak
4907+-include Makefile.in
4908+include ../Test.mak
4909diff --git a/test/argp/Makefile.in b/test/argp/Makefile.in
4910new file mode 100644
4911index 0000000..d81b359
4912--- /dev/null
4913+++ b/test/argp/Makefile.in
4914@@ -0,0 +1,12 @@
4915+# uClibc argp tests
4916+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
4917+
4918+TESTS := $(addprefix argp-, ex1 ex2 ex3 ex4 test) \
4919+ bug-argp1 tst-argp1 tst-argp2
4920+
4921+EXTRA_LDFLAGS = -luargp
4922+
4923+OPTS_argp-ex3 = ARG1 ARG2
4924+OPTS_argp-ex4 = ARG1 string1 string2 string3
4925+OPTS_bug-argp1 = -- --help
4926+
4927diff --git a/test/argp/argp-ex1.c b/test/argp/argp-ex1.c
4928new file mode 100644
4929index 0000000..7bb5f22
4930--- /dev/null
4931+++ b/test/argp/argp-ex1.c
4932@@ -0,0 +1,15 @@
4933+/* Argp example #1 -- a minimal program using argp */
4934+
4935+/* This is (probably) the smallest possible program that
4936+ uses argp. It won't do much except give an error
4937+ messages and exit when there are any arguments, and print
4938+ a (rather pointless) messages for --help. */
4939+
4940+#include <stdlib.h>
4941+#include <argp.h>
4942+
4943+int main (int argc, char **argv)
4944+{
4945+ argp_parse (0, argc, argv, 0, 0, 0);
4946+ exit (0);
4947+}
4948diff --git a/test/argp/argp-ex2.c b/test/argp/argp-ex2.c
4949new file mode 100644
4950index 0000000..c49fbac
4951--- /dev/null
4952+++ b/test/argp/argp-ex2.c
4953@@ -0,0 +1,45 @@
4954+/* Argp example #2 -- a pretty minimal program using argp */
4955+
4956+/* This program doesn't use any options or arguments, but uses
4957+ argp to be compliant with the GNU standard command line
4958+ format.
4959+
4960+ In addition to making sure no arguments are given, and
4961+ implementing a --help option, this example will have a
4962+ --version option, and will put the given documentation string
4963+ and bug address in the --help output, as per GNU standards.
4964+
4965+ The variable ARGP contains the argument parser specification;
4966+ adding fields to this structure is the way most parameters are
4967+ passed to argp_parse (the first three fields are usually used,
4968+ but not in this small program). There are also two global
4969+ variables that argp knows about defined here,
4970+ ARGP_PROGRAM_VERSION and ARGP_PROGRAM_BUG_ADDRESS (they are
4971+ global variables because they will almost always be constant
4972+ for a given program, even if it uses different argument
4973+ parsers for various tasks). */
4974+
4975+#include <stdlib.h>
4976+#include <argp.h>
4977+
4978+const char *argp_program_version =
4979+ "argp-ex2 1.0";
4980+const char *argp_program_bug_address =
4981+ "<bug-gnu-utils@@gnu.org>";
4982+
4983+/* Program documentation. */
4984+static char doc[] =
4985+ "Argp example #2 -- a pretty minimal program using argp";
4986+
4987+/* Our argument parser. The @code{options}, @code{parser}, and
4988+ @code{args_doc} fields are zero because we have neither options or
4989+ arguments; @code{doc} and @code{argp_program_bug_address} will be
4990+ used in the output for @samp{--help}, and the @samp{--version}
4991+ option will print out @code{argp_program_version}. */
4992+static struct argp argp = { 0, 0, 0, doc };
4993+
4994+int main (int argc, char **argv)
4995+{
4996+ argp_parse (&argp, argc, argv, 0, 0, 0);
4997+ exit (0);
4998+}
4999diff --git a/test/argp/argp-ex3.c b/test/argp/argp-ex3.c
5000new file mode 100644
5001index 0000000..24d5c50
5002--- /dev/null
5003+++ b/test/argp/argp-ex3.c
5004@@ -0,0 +1,153 @@
5005+/* Argp example #3 -- a program with options and arguments using argp */
5006+
5007+/* This program uses the same features as example 2, and uses options and
5008+ arguments.
5009+
5010+ We now use the first four fields in ARGP, so here's a description of them:
5011+ OPTIONS -- A pointer to a vector of struct argp_option (see below)
5012+ PARSER -- A function to parse a single option, called by argp
5013+ ARGS_DOC -- A string describing how the non-option arguments should look
5014+ DOC -- A descriptive string about this program; if it contains a
5015+ vertical tab character (\v), the part after it will be
5016+ printed *following* the options
5017+
5018+ The function PARSER takes the following arguments:
5019+ KEY -- An integer specifying which option this is (taken
5020+ from the KEY field in each struct argp_option), or
5021+ a special key specifying something else; the only
5022+ special keys we use here are ARGP_KEY_ARG, meaning
5023+ a non-option argument, and ARGP_KEY_END, meaning
5024+ that all arguments have been parsed
5025+ ARG -- For an option KEY, the string value of its
5026+ argument, or NULL if it has none
5027+ STATE-- A pointer to a struct argp_state, containing
5028+ various useful information about the parsing state; used here
5029+ are the INPUT field, which reflects the INPUT argument to
5030+ argp_parse, and the ARG_NUM field, which is the number of the
5031+ current non-option argument being parsed
5032+ It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
5033+ given KEY wasn't recognized, or an errno value indicating some other
5034+ error.
5035+
5036+ Note that in this example, main uses a structure to communicate with the
5037+ parse_opt function, a pointer to which it passes in the INPUT argument to
5038+ argp_parse. Of course, it's also possible to use global variables
5039+ instead, but this is somewhat more flexible.
5040+
5041+ The OPTIONS field contains a pointer to a vector of struct argp_option's;
5042+ that structure has the following fields (if you assign your option
5043+ structures using array initialization like this example, unspecified
5044+ fields will be defaulted to 0, and need not be specified):
5045+ NAME -- The name of this option's long option (may be zero)
5046+ KEY -- The KEY to pass to the PARSER function when parsing this option,
5047+ *and* the name of this option's short option, if it is a
5048+ printable ascii character
5049+ ARG -- The name of this option's argument, if any
5050+ FLAGS -- Flags describing this option; some of them are:
5051+ OPTION_ARG_OPTIONAL -- The argument to this option is optional
5052+ OPTION_ALIAS -- This option is an alias for the
5053+ previous option
5054+ OPTION_HIDDEN -- Don't show this option in --help output
5055+ DOC -- A documentation string for this option, shown in --help output
5056+
5057+ An options vector should be terminated by an option with all fields zero. */
5058+
5059+#include <stdlib.h>
5060+#include <argp.h>
5061+
5062+const char *argp_program_version =
5063+ "argp-ex3 1.0";
5064+const char *argp_program_bug_address =
5065+ "<bug-gnu-utils@@gnu.org>";
5066+
5067+/* Program documentation. */
5068+static char doc[] =
5069+ "Argp example #3 -- a program with options and arguments using argp";
5070+
5071+/* A description of the arguments we accept. */
5072+static char args_doc[] = "ARG1 ARG2";
5073+
5074+/* The options we understand. */
5075+static struct argp_option options[] = {
5076+ {"verbose", 'v', 0, 0, "Produce verbose output" },
5077+ {"quiet", 'q', 0, 0, "Don't produce any output" },
5078+ {"silent", 's', 0, OPTION_ALIAS },
5079+ {"output", 'o', "FILE", 0,
5080+ "Output to FILE instead of standard output" },
5081+ { 0 }
5082+};
5083+
5084+/* Used by @code{main} to communicate with @code{parse_opt}. */
5085+struct arguments
5086+{
5087+ char *args[2]; /* @var{arg1} & @var{arg2} */
5088+ int silent, verbose;
5089+ char *output_file;
5090+};
5091+
5092+/* Parse a single option. */
5093+static error_t
5094+parse_opt (int key, char *arg, struct argp_state *state)
5095+{
5096+ /* Get the @var{input} argument from @code{argp_parse}, which we
5097+ know is a pointer to our arguments structure. */
5098+ struct arguments *arguments = state->input;
5099+
5100+ switch (key)
5101+ {
5102+ case 'q': case 's':
5103+ arguments->silent = 1;
5104+ break;
5105+ case 'v':
5106+ arguments->verbose = 1;
5107+ break;
5108+ case 'o':
5109+ arguments->output_file = arg;
5110+ break;
5111+
5112+ case ARGP_KEY_ARG:
5113+ if (state->arg_num >= 2)
5114+ /* Too many arguments. */
5115+ argp_usage (state);
5116+
5117+ arguments->args[state->arg_num] = arg;
5118+
5119+ break;
5120+
5121+ case ARGP_KEY_END:
5122+ if (state->arg_num < 2)
5123+ /* Not enough arguments. */
5124+ argp_usage (state);
5125+ break;
5126+
5127+ default:
5128+ return ARGP_ERR_UNKNOWN;
5129+ }
5130+ return 0;
5131+}
5132+
5133+/* Our argp parser. */
5134+static struct argp argp = { options, parse_opt, args_doc, doc };
5135+
5136+int main (int argc, char **argv)
5137+{
5138+ struct arguments arguments;
5139+
5140+ /* Default values. */
5141+ arguments.silent = 0;
5142+ arguments.verbose = 0;
5143+ arguments.output_file = "-";
5144+
5145+ /* Parse our arguments; every option seen by @code{parse_opt} will
5146+ be reflected in @code{arguments}. */
5147+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
5148+
5149+ printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
5150+ "VERBOSE = %s\nSILENT = %s\n",
5151+ arguments.args[0], arguments.args[1],
5152+ arguments.output_file,
5153+ arguments.verbose ? "yes" : "no",
5154+ arguments.silent ? "yes" : "no");
5155+
5156+ exit (0);
5157+}
5158diff --git a/test/argp/argp-ex4.c b/test/argp/argp-ex4.c
5159new file mode 100644
5160index 0000000..c77c7ef
5161--- /dev/null
5162+++ b/test/argp/argp-ex4.c
5163@@ -0,0 +1,167 @@
5164+/* Argp example #4 -- a program with somewhat more complicated options */
5165+
5166+/* This program uses the same features as example 3, but has more
5167+ options, and somewhat more structure in the -help output. It
5168+ also shows how you can `steal' the remainder of the input
5169+ arguments past a certain point, for programs that accept a
5170+ list of items. It also shows the special argp KEY value
5171+ ARGP_KEY_NO_ARGS, which is only given if no non-option
5172+ arguments were supplied to the program.
5173+
5174+ For structuring the help output, two features are used,
5175+ *headers* which are entries in the options vector with the
5176+ first four fields being zero, and a two part documentation
5177+ string (in the variable DOC), which allows documentation both
5178+ before and after the options; the two parts of DOC are
5179+ separated by a vertical-tab character ('\v', or '\013'). By
5180+ convention, the documentation before the options is just a
5181+ short string saying what the program does, and that afterwards
5182+ is longer, describing the behavior in more detail. All
5183+ documentation strings are automatically filled for output,
5184+ although newlines may be included to force a line break at a
5185+ particular point. All documentation strings are also passed to
5186+ the `gettext' function, for possible translation into the
5187+ current locale. */
5188+
5189+#include <stdlib.h>
5190+#include <error.h>
5191+#include <argp.h>
5192+
5193+const char *argp_program_version =
5194+ "argp-ex4 1.0";
5195+const char *argp_program_bug_address =
5196+ "<bug-gnu-utils@@prep.ai.mit.edu>";
5197+
5198+/* Program documentation. */
5199+static char doc[] =
5200+ "Argp example #4 -- a program with somewhat more complicated\
5201+options\
5202+\vThis part of the documentation comes *after* the options;\
5203+ note that the text is automatically filled, but it's possible\
5204+ to force a line-break, e.g.\n<-- here.";
5205+
5206+/* A description of the arguments we accept. */
5207+static char args_doc[] = "ARG1 [STRING...]";
5208+
5209+/* Keys for options without short-options. */
5210+#define OPT_ABORT 1 /* --abort */
5211+
5212+/* The options we understand. */
5213+static struct argp_option options[] = {
5214+ {"verbose", 'v', 0, 0, "Produce verbose output" },
5215+ {"quiet", 'q', 0, 0, "Don't produce any output" },
5216+ {"silent", 's', 0, OPTION_ALIAS },
5217+ {"output", 'o', "FILE", 0,
5218+ "Output to FILE instead of standard output" },
5219+
5220+ {0,0,0,0, "The following options should be grouped together:" },
5221+ {"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL,
5222+ "Repeat the output COUNT (default 10) times"},
5223+ {"abort", OPT_ABORT, 0, 0, "Abort before showing any output"},
5224+
5225+ { 0 }
5226+};
5227+
5228+/* Used by @code{main} to communicate with @code{parse_opt}. */
5229+struct arguments
5230+{
5231+ char *arg1; /* @var{arg1} */
5232+ char **strings; /* [@var{string}@dots{}] */
5233+ int silent, verbose, abort; /* @samp{-s}, @samp{-v}, @samp{--abort} */
5234+ char *output_file; /* @var{file} arg to @samp{--output} */
5235+ int repeat_count; /* @var{count} arg to @samp{--repeat} */
5236+};
5237+
5238+/* Parse a single option. */
5239+static error_t
5240+parse_opt (int key, char *arg, struct argp_state *state)
5241+{
5242+ /* Get the @code{input} argument from @code{argp_parse}, which we
5243+ know is a pointer to our arguments structure. */
5244+ struct arguments *arguments = state->input;
5245+
5246+ switch (key)
5247+ {
5248+ case 'q': case 's':
5249+ arguments->silent = 1;
5250+ break;
5251+ case 'v':
5252+ arguments->verbose = 1;
5253+ break;
5254+ case 'o':
5255+ arguments->output_file = arg;
5256+ break;
5257+ case 'r':
5258+ arguments->repeat_count = arg ? atoi (arg) : 10;
5259+ break;
5260+ case OPT_ABORT:
5261+ arguments->abort = 1;
5262+ break;
5263+
5264+ case ARGP_KEY_NO_ARGS:
5265+ argp_usage (state);
5266+
5267+ case ARGP_KEY_ARG:
5268+ /* Here we know that @code{state->arg_num == 0}, since we
5269+ force argument parsing to end before any more arguments can
5270+ get here. */
5271+ arguments->arg1 = arg;
5272+
5273+ /* Now we consume all the rest of the arguments.
5274+ @code{state->next} is the index in @code{state->argv} of the
5275+ next argument to be parsed, which is the first @var{string}
5276+ we're interested in, so we can just use
5277+ @code{&state->argv[state->next]} as the value for
5278+ arguments->strings.
5279+
5280+ @emph{In addition}, by setting @code{state->next} to the end
5281+ of the arguments, we can force argp to stop parsing here and
5282+ return. */
5283+ arguments->strings = &state->argv[state->next];
5284+ state->next = state->argc;
5285+
5286+ break;
5287+
5288+ default:
5289+ return ARGP_ERR_UNKNOWN;
5290+ }
5291+ return 0;
5292+}
5293+
5294+/* Our argp parser. */
5295+static struct argp argp = { options, parse_opt, args_doc, doc };
5296+
5297+int main (int argc, char **argv)
5298+{
5299+ int i, j;
5300+ struct arguments arguments;
5301+
5302+ /* Default values. */
5303+ arguments.silent = 0;
5304+ arguments.verbose = 0;
5305+ arguments.output_file = "-";
5306+ arguments.repeat_count = 1;
5307+ arguments.abort = 0;
5308+
5309+ /* Parse our arguments; every option seen by @code{parse_opt} will be
5310+ reflected in @code{arguments}. */
5311+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
5312+
5313+ if (arguments.abort)
5314+ error (10, 0, "ABORTED");
5315+
5316+ for (i = 0; i < arguments.repeat_count; i++)
5317+ {
5318+ printf ("ARG1 = %s\n", arguments.arg1);
5319+ printf ("STRINGS = ");
5320+ for (j = 0; arguments.strings[j]; j++)
5321+ printf (j == 0 ? "%s" : ", %s", arguments.strings[j]);
5322+ printf ("\n");
5323+ printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n",
5324+ arguments.output_file,
5325+ arguments.verbose ? "yes" : "no",
5326+ arguments.silent ? "yes" : "no");
5327+ }
5328+
5329+ exit (0);
5330+}
5331diff --git a/test/argp/argp-test.c b/test/argp/argp-test.c
5332new file mode 100644
5333index 0000000..b3d573b
5334--- /dev/null
5335+++ b/test/argp/argp-test.c
5336@@ -0,0 +1,209 @@
5337+/* Test program for argp argument parser
5338+ Copyright (C) 1997 Free Software Foundation, Inc.
5339+ This file is part of the GNU C Library.
5340+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
5341+
5342+ The GNU C Library is free software; you can redistribute it and/or
5343+ modify it under the terms of the GNU Lesser General Public
5344+ License as published by the Free Software Foundation; either
5345+ version 2.1 of the License, or (at your option) any later version.
5346+
5347+ The GNU C Library is distributed in the hope that it will be useful,
5348+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5349+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5350+ Lesser General Public License for more details.
5351+
5352+ You should have received a copy of the GNU Lesser General Public
5353+ License along with the GNU C Library; if not, write to the Free
5354+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
5355+ 02111-1307 USA. */
5356+
5357+#ifdef HAVE_CONFIG_H
5358+#include <config.h>
5359+#endif
5360+
5361+#include <stdlib.h>
5362+#include <time.h>
5363+#include <string.h>
5364+#include <argp.h>
5365+
5366+const char *argp_program_version = "argp-test 1.0";
5367+
5368+struct argp_option sub_options[] =
5369+{
5370+ {"subopt1", 's', 0, 0, "Nested option 1"},
5371+ {"subopt2", 'S', 0, 0, "Nested option 2"},
5372+
5373+ { 0, 0, 0, 0, "Some more nested options:", 10},
5374+ {"subopt3", 'p', 0, 0, "Nested option 3"},
5375+
5376+ {"subopt4", 'q', 0, 0, "Nested option 4", 1},
5377+
5378+ {0}
5379+};
5380+
5381+static const char sub_args_doc[] = "STRING...\n-";
5382+static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser.";
5383+
5384+static error_t
5385+sub_parse_opt (int key, char *arg, struct argp_state *state)
5386+{
5387+ switch (key)
5388+ {
5389+ case ARGP_KEY_NO_ARGS:
5390+ printf ("NO SUB ARGS\n");
5391+ break;
5392+ case ARGP_KEY_ARG:
5393+ printf ("SUB ARG: %s\n", arg);
5394+ break;
5395+
5396+ case 's' : case 'S': case 'p': case 'q':
5397+ printf ("SUB KEY %c\n", key);
5398+ break;
5399+
5400+ default:
5401+ return ARGP_ERR_UNKNOWN;
5402+ }
5403+ return 0;
5404+}
5405+
5406+static char *
5407+sub_help_filter (int key, const char *text, void *input)
5408+{
5409+ if (key == ARGP_KEY_HELP_EXTRA)
5410+ return strdup ("This is some extra text from the sub parser (note that it \
5411+is preceded by a blank line).");
5412+ else
5413+ return (char *)text;
5414+}
5415+
5416+static struct argp sub_argp = {
5417+ sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter
5418+};
5419+
5420+/* Structure used to communicate with the parsing functions. */
5421+struct params
5422+{
5423+ unsigned foonly; /* Value parsed for foonly. */
5424+ unsigned foonly_default; /* Default value for it. */
5425+};
5426+
5427+#define OPT_PGRP 1
5428+#define OPT_SESS 2
5429+
5430+struct argp_option options[] =
5431+{
5432+ {"pid", 'p', "PID", 0, "List the process PID"},
5433+ {"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"},
5434+ {"no-parent", 'P', 0, 0, "Include processes without parents"},
5435+ {0, 'x', 0, OPTION_ALIAS},
5436+ {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
5437+ " if there's some reason ps can't"
5438+ " print a field for any process, it's"
5439+ " removed from the output entirely)" },
5440+ {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
5441+ {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
5442+ {"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL,
5443+ "Add the processes from the session"
5444+ " SID (which defaults to the sid of"
5445+ " the current process)" },
5446+
5447+ {0,0,0,0, "Here are some more options:"},
5448+ {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"},
5449+ {"zaza", 'z', 0, 0, "Snit a zar"},
5450+
5451+ {0}
5452+};
5453+
5454+static const char args_doc[] = "STRING";
5455+static const char doc[] = "Test program for argp."
5456+ "\vThis doc string comes after the options."
5457+ "\nHey! Some manual formatting!"
5458+ "\nThe current time is: %s";
5459+
5460+static void
5461+popt (int key, char *arg)
5462+{
5463+ char buf[10];
5464+ if (isprint (key))
5465+ sprintf (buf, "%c", key);
5466+ else
5467+ sprintf (buf, "%d", key);
5468+ if (arg)
5469+ printf ("KEY %s: %s\n", buf, arg);
5470+ else
5471+ printf ("KEY %s\n", buf);
5472+}
5473+
5474+static error_t
5475+parse_opt (int key, char *arg, struct argp_state *state)
5476+{
5477+ struct params *params = state->input;
5478+
5479+ switch (key)
5480+ {
5481+ case ARGP_KEY_NO_ARGS:
5482+ printf ("NO ARGS\n");
5483+ break;
5484+
5485+ case ARGP_KEY_ARG:
5486+ if (state->arg_num > 0)
5487+ return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */
5488+ printf ("ARG: %s\n", arg);
5489+ break;
5490+
5491+ case 'f':
5492+ if (arg)
5493+ params->foonly = atoi (arg);
5494+ else
5495+ params->foonly = params->foonly_default;
5496+ popt (key, arg);
5497+ break;
5498+
5499+ case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q':
5500+ case 'r': case OPT_SESS: case 'z':
5501+ popt (key, arg);
5502+ break;
5503+
5504+ default:
5505+ return ARGP_ERR_UNKNOWN;
5506+ }
5507+ return 0;
5508+}
5509+
5510+static char *
5511+help_filter (int key, const char *text, void *input)
5512+{
5513+ char *new_text;
5514+ struct params *params = input;
5515+
5516+ if (key == ARGP_KEY_HELP_POST_DOC && text)
5517+ {
5518+ time_t now = time (0);
5519+ asprintf (&new_text, text, ctime (&now));
5520+ }
5521+ else if (key == 'f')
5522+ /* Show the default for the --foonly option. */
5523+ asprintf (&new_text, "%s (ZOT defaults to %x)",
5524+ text, params->foonly_default);
5525+ else
5526+ new_text = (char *)text;
5527+
5528+ return new_text;
5529+}
5530+
5531+static struct argp_child argp_children[] = { { &sub_argp }, { 0 } };
5532+static struct argp argp = {
5533+ options, parse_opt, args_doc, doc, argp_children, help_filter
5534+};
5535+
5536+int
5537+main (int argc, char **argv)
5538+{
5539+ struct params params;
5540+ params.foonly = 0;
5541+ params.foonly_default = random ();
5542+ argp_parse (&argp, argc, argv, 0, 0, &params);
5543+ printf ("After parsing: foonly = %x\n", params.foonly);
5544+ return 0;
5545+}
5546diff --git a/test/argp/bug-argp1.c b/test/argp/bug-argp1.c
5547new file mode 100644
5548index 0000000..a28cf4b
5549--- /dev/null
5550+++ b/test/argp/bug-argp1.c
5551@@ -0,0 +1,26 @@
5552+#include <argp.h>
5553+
5554+
5555+static const struct argp_option test_options[] =
5556+{
5557+ { NULL, 'a', NULL, OPTION_DOC, NULL },
5558+ { NULL, 'b', NULL, OPTION_DOC, NULL },
5559+ { NULL, 0, NULL, 0, NULL }
5560+};
5561+
5562+static struct argp test_argp =
5563+{
5564+ test_options
5565+};
5566+
5567+
5568+static int
5569+do_test (int argc, char *argv[])
5570+{
5571+ int i;
5572+ argp_parse (&test_argp, argc, argv, 0, &i, NULL);
5573+ return 0;
5574+}
5575+
5576+#define TEST_FUNCTION do_test (argc, argv)
5577+#include "../test-skeleton.c"
5578diff --git a/test/argp/tst-argp1.c b/test/argp/tst-argp1.c
5579new file mode 100644
5580index 0000000..827daca
5581--- /dev/null
5582+++ b/test/argp/tst-argp1.c
5583@@ -0,0 +1,118 @@
5584+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
5585+ This file is part of the GNU C Library.
5586+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
5587+
5588+ The GNU C Library is free software; you can redistribute it and/or
5589+ modify it under the terms of the GNU Lesser General Public
5590+ License as published by the Free Software Foundation; either
5591+ version 2.1 of the License, or (at your option) any later version.
5592+
5593+ The GNU C Library is distributed in the hope that it will be useful,
5594+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5595+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5596+ Lesser General Public License for more details.
5597+
5598+ You should have received a copy of the GNU Lesser General Public
5599+ License along with the GNU C Library; if not, write to the Free
5600+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
5601+ 02111-1307 USA. */
5602+
5603+#include <argp.h>
5604+
5605+
5606+
5607+
5608+#define OPT_TO_THREAD 300
5609+#define OPT_TO_PROCESS 301
5610+#define OPT_SYNC_SIGNAL 302
5611+#define OPT_SYNC_JOIN 303
5612+#define OPT_TOPLEVEL 304
5613+
5614+
5615+static const struct argp_option test_options[] =
5616+ {
5617+ { NULL, 0, NULL, 0, "\
5618+This is a test for threads so we allow ther user to selection the number of \
5619+threads which are used at any one time. Independently the total number of \
5620+rounds can be selected. This is the total number of threads which will have \
5621+run when the process terminates:" },
5622+ { "threads", 't', "NUMBER", 0, "Number of threads used at once" },
5623+ { "starts", 's', "NUMBER", 0, "Total number of working threads" },
5624+ { "toplevel", OPT_TOPLEVEL, "NUMBER", 0,
5625+ "Number of toplevel threads which start the other threads; this \
5626+implies --sync-join" },
5627+
5628+ { NULL, 0, NULL, 0, "\
5629+Each thread can do one of two things: sleep or do work. The latter is 100% \
5630+CPU bound. The work load is the probability a thread does work. All values \
5631+from zero to 100 (inclusive) are valid. How often each thread repeats this \
5632+can be determined by the number of rounds. The work cost determines how long \
5633+each work session (not sleeping) takes. If it is zero a thread would \
5634+effectively nothing. By setting the number of rounds to zero the thread \
5635+does no work at all and pure thread creation times can be measured." },
5636+ { "workload", 'w', "PERCENT", 0, "Percentage of time spent working" },
5637+ { "workcost", 'c', "NUMBER", 0,
5638+ "Factor in the cost of each round of working" },
5639+ { "rounds", 'r', "NUMBER", 0, "Number of rounds each thread runs" },
5640+
5641+ { NULL, 0, NULL, 0, "\
5642+There are a number of different methods how thread creation can be \
5643+synchronized. Synchronization is necessary since the number of concurrently \
5644+running threads is limited." },
5645+ { "sync-signal", OPT_SYNC_SIGNAL, NULL, 0,
5646+ "Synchronize using a signal (default)" },
5647+ { "sync-join", OPT_SYNC_JOIN, NULL, 0, "Synchronize using pthread_join" },
5648+
5649+ { NULL, 0, NULL, 0, "\
5650+One parameter for each threads execution is the size of the stack. If this \
5651+parameter is not used the system's default stack size is used. If many \
5652+threads are used the stack size should be chosen quite small." },
5653+ { "stacksize", 'S', "BYTES", 0, "Size of threads stack" },
5654+ { "guardsize", 'g', "BYTES", 0,
5655+ "Size of stack guard area; must fit into the stack" },
5656+
5657+ { NULL, 0, NULL, 0, "Signal options:" },
5658+ { "to-thread", OPT_TO_THREAD, NULL, 0, "Send signal to main thread" },
5659+ { "to-process", OPT_TO_PROCESS, NULL, 0,
5660+ "Send signal to process (default)" },
5661+
5662+ { NULL, 0, NULL, 0, "Administrative options:" },
5663+ { "progress", 'p', NULL, 0, "Show signs of progress" },
5664+ { "timing", 'T', NULL, 0,
5665+ "Measure time from startup to the last thread finishing" },
5666+ { NULL, 0, NULL, 0, NULL }
5667+ };
5668+
5669+/* Prototype for option handler. */
5670+static error_t parse_opt (int key, char *arg, struct argp_state *state);
5671+
5672+/* Data structure to communicate with argp functions. */
5673+static struct argp argp =
5674+{
5675+ test_options, parse_opt
5676+};
5677+
5678+
5679+static int
5680+do_test (void)
5681+{
5682+ int argc = 2;
5683+ char *argv[3] = { (char *) "tst-argp1", (char *) "--help", NULL };
5684+ int remaining;
5685+
5686+ /* Parse and process arguments. */
5687+ argp_parse (&argp, argc, argv, 0, &remaining, NULL);
5688+
5689+ return 0;
5690+}
5691+
5692+
5693+/* Handle program arguments. */
5694+static error_t
5695+parse_opt (int key, char *arg, struct argp_state *state)
5696+{
5697+ return ARGP_ERR_UNKNOWN;
5698+}
5699+
5700+#define TEST_FUNCTION do_test ()
5701+#include "../test-skeleton.c"
5702diff --git a/test/argp/tst-argp2.c b/test/argp/tst-argp2.c
5703new file mode 100644
5704index 0000000..705cdca
5705--- /dev/null
5706+++ b/test/argp/tst-argp2.c
5707@@ -0,0 +1,101 @@
5708+/* Copyright (C) 2007 Free Software Foundation, Inc.
5709+ This file is part of the GNU C Library.
5710+ Contributed by Jakub Jelinek <jakub at redhat.com>, 2007.
5711+
5712+ The GNU C Library is free software; you can redistribute it and/or
5713+ modify it under the terms of the GNU Lesser General Public
5714+ License as published by the Free Software Foundation; either
5715+ version 2.1 of the License, or (at your option) any later version.
5716+
5717+ The GNU C Library is distributed in the hope that it will be useful,
5718+ but WITHOUT ANY WARRANTY; without even the implied warranty of
5719+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5720+ Lesser General Public License for more details.
5721+
5722+ You should have received a copy of the GNU Lesser General Public
5723+ License along with the GNU C Library; if not, write to the Free
5724+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
5725+ 02111-1307 USA. */
5726+
5727+#include <argp.h>
5728+
5729+static const struct argp_option opt1[] =
5730+ {
5731+ { "opt1", '1', "NUMBER", 0, "Option 1" },
5732+ { NULL, 0, NULL, 0, NULL }
5733+ };
5734+
5735+static const struct argp_option opt2[] =
5736+ {
5737+ { "opt2", '2', "NUMBER", 0, "Option 2" },
5738+ { NULL, 0, NULL, 0, NULL }
5739+ };
5740+
5741+static const struct argp_option opt3[] =
5742+ {
5743+ { "opt3", '3', "NUMBER", 0, "Option 3" },
5744+ { NULL, 0, NULL, 0, NULL }
5745+ };
5746+
5747+static const struct argp_option opt4[] =
5748+ {
5749+ { "opt4", '4', "NUMBER", 0, "Option 4" },
5750+ { NULL, 0, NULL, 0, NULL }
5751+ };
5752+
5753+static const struct argp_option opt5[] =
5754+ {
5755+ { "opt5", '5', "NUMBER", 0, "Option 5" },
5756+ { NULL, 0, NULL, 0, NULL }
5757+ };
5758+
5759+static struct argp argp5 =
5760+ {
5761+ opt5, NULL, "args doc5", "doc5", NULL, NULL, NULL
5762+ };
5763+
5764+static struct argp argp4 =
5765+ {
5766+ opt4, NULL, "args doc4", "doc4", NULL, NULL, NULL
5767+ };
5768+
5769+static struct argp argp3 =
5770+ {
5771+ opt3, NULL, "args doc3", "doc3", NULL, NULL, NULL
5772+ };
5773+
5774+static struct argp_child children2[] =
5775+ {
5776+ { &argp4, 0, "child3", 3 },
5777+ { &argp5, 0, "child4", 4 },
5778+ { NULL, 0, NULL, 0 }
5779+ };
5780+
5781+static struct argp argp2 =
5782+ {
5783+ opt2, NULL, "args doc2", "doc2", children2, NULL, NULL
5784+ };
5785+
5786+static struct argp_child children1[] =
5787+ {
5788+ { &argp2, 0, "child1", 1 },
5789+ { &argp3, 0, "child2", 2 },
5790+ { NULL, 0, NULL, 0 }
5791+ };
5792+
5793+static struct argp argp1 =
5794+ {
5795+ opt1, NULL, "args doc1", "doc1", children1, NULL, NULL
5796+ };
5797+
5798+
5799+static int
5800+do_test (void)
5801+{
5802+ argp_help (&argp1, stdout, ARGP_HELP_LONG, (char *) "tst-argp2");
5803+ return 0;
5804+}
5805+
5806+
5807+#define TEST_FUNCTION do_test ()
5808+#include "../test-skeleton.c"
5809--
58102.1.4
5811