summaryrefslogtreecommitdiff
path: root/argp
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /argp
parentTest for stack alignment. (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.bz2
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip
2.5-18.1
Diffstat (limited to 'argp')
-rw-r--r--argp/Makefile6
-rw-r--r--argp/argp-eexst.c2
-rw-r--r--argp/argp-fmtstream.c42
-rw-r--r--argp/argp-fmtstream.h4
-rw-r--r--argp/argp-fs-xinl.c2
-rw-r--r--argp/argp-help.c189
-rw-r--r--argp/argp-xinl.c2
-rw-r--r--argp/argp.h7
-rw-r--r--argp/bug-argp1.c26
-rw-r--r--argp/tst-argp2.c101
10 files changed, 244 insertions, 137 deletions
diff --git a/argp/Makefile b/argp/Makefile
index a68ca1bee3..b8c9fca0fb 100644
--- a/argp/Makefile
+++ b/argp/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1997, 2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1997, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
@@ -26,10 +26,12 @@ distribute = argp-fmtstream.h argp-namefrob.h
routines = $(addprefix argp-, ba fmtstream fs-xinl help parse pv \
pvh xinl eexst)
-tests = argp-test tst-argp1
+tests = argp-test tst-argp1 bug-argp1 tst-argp2
CFLAGS-argp-help.c = $(uses-callbacks) -fexceptions
CFLAGS-argp-parse.c = $(uses-callbacks)
CFLAGS-argp-fmtstream.c = -fexceptions
+bug-argp1-ARGS = -- --help
+
include ../Rules
diff --git a/argp/argp-eexst.c b/argp/argp-eexst.c
index 151f89a1c0..84df089e03 100644
--- a/argp/argp-eexst.c
+++ b/argp/argp-eexst.c
@@ -19,7 +19,7 @@
02111-1307 USA. */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#include <sysexits.h>
diff --git a/argp/argp-fmtstream.c b/argp/argp-fmtstream.c
index 215160bdcd..55ac7f9183 100644
--- a/argp/argp-fmtstream.c
+++ b/argp/argp-fmtstream.c
@@ -1,5 +1,5 @@
/* Word-wrapping and line-truncating streams
- Copyright (C) 1997,1998,1999,2001,2002,2003 Free Software Foundation, Inc.
+ Copyright (C) 1997-1999,2001,2002,2003,2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
@@ -22,7 +22,7 @@
don't have that. */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#include <stdlib.h>
@@ -102,11 +102,10 @@ __argp_fmtstream_free (argp_fmtstream_t fs)
if (fs->p > fs->buf)
{
#ifdef USE_IN_LIBIO
- if (_IO_fwide (fs->stream, 0) > 0)
- __fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
- else
+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
+#else
+ fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
#endif
- fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
}
free (fs->buf);
free (fs);
@@ -291,17 +290,15 @@ __argp_fmtstream_update (argp_fmtstream_t fs)
else
/* Output the first line so we can use the space. */
{
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (fs->stream, 0) > 0)
- __fwprintf (fs->stream, L"%.*s\n",
- (int) (nl - fs->buf), fs->buf);
- else
+#ifdef _LIBC
+ __fxprintf (fs->stream, "%.*s\n",
+ (int) (nl - fs->buf), fs->buf);
+#else
+ if (nl > fs->buf)
+ fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
+ putc_unlocked ('\n', fs->stream);
#endif
- {
- if (nl > fs->buf)
- fwrite_unlocked (fs->buf, 1, nl - fs->buf, fs->stream);
- putc_unlocked ('\n', fs->stream);
- }
+
len += buf - fs->buf;
nl = buf = fs->buf;
}
@@ -360,15 +357,12 @@ __argp_fmtstream_ensure (struct argp_fmtstream *fs, size_t amount)
/* Flush FS's buffer. */
__argp_fmtstream_update (fs);
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (fs->stream, 0) > 0)
- {
- __fwprintf (fs->stream, L"%.*s", (int) (fs->p - fs->buf), fs->buf);
- wrote = fs->p - fs->buf;
- }
- else
+#ifdef _LIBC
+ __fxprintf (fs->stream, "%.*s", (int) (fs->p - fs->buf), fs->buf);
+ wrote = fs->p - fs->buf;
+#else
+ wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
#endif
- wrote = fwrite_unlocked (fs->buf, 1, fs->p - fs->buf, fs->stream);
if (wrote == fs->p - fs->buf)
{
fs->p = fs->buf;
diff --git a/argp/argp-fmtstream.h b/argp/argp-fmtstream.h
index 5d0d5eac92..f94207a20b 100644
--- a/argp/argp-fmtstream.h
+++ b/argp/argp-fmtstream.h
@@ -26,10 +26,6 @@
#ifndef _ARGP_FMTSTREAM_H
#define _ARGP_FMTSTREAM_H
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include <stdio.h>
#include <string.h>
#include <unistd.h>
diff --git a/argp/argp-fs-xinl.c b/argp/argp-fs-xinl.c
index 3cf1f9827d..442ffa05d1 100644
--- a/argp/argp-fs-xinl.c
+++ b/argp/argp-fs-xinl.c
@@ -19,7 +19,7 @@
02111-1307 USA. */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#define ARGP_FS_EI
diff --git a/argp/argp-help.c b/argp/argp-help.c
index 67018709d3..c12b10e235 100644
--- a/argp/argp-help.c
+++ b/argp/argp-help.c
@@ -1,5 +1,6 @@
/* Hierarchial argument parsing help output
- Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-2003, 2004, 2005, 2006, 2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
@@ -48,7 +49,8 @@ char *alloca ();
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
-#ifdef USE_IN_LIBIO
+#ifdef _LIBC
+# include <../libio/libioP.h>
# include <wchar.h>
#endif
@@ -127,40 +129,37 @@ struct uparams
int header_col;
int usage_indent;
int rmargin;
-
- int valid; /* True when the values in here are valid. */
};
/* This is a global variable, as user options are only ever read once. */
static struct uparams uparams = {
DUP_ARGS, DUP_ARGS_NOTE,
SHORT_OPT_COL, LONG_OPT_COL, DOC_OPT_COL, OPT_DOC_COL, HEADER_COL,
- USAGE_INDENT, RMARGIN,
- 0
+ USAGE_INDENT, RMARGIN
};
/* A particular uparam, and what the user name is. */
struct uparam_name
{
- const char *name; /* User name. */
- int is_bool; /* Whether it's `boolean'. */
- size_t uparams_offs; /* Location of the (int) field in UPARAMS. */
+ const char name[14]; /* User name. */
+ bool is_bool; /* Whether it's `boolean'. */
+ uint8_t uparams_offs; /* Location of the (int) field in UPARAMS. */
};
/* The name-field mappings we know about. */
static const struct uparam_name uparam_names[] =
{
- { "dup-args", 1, offsetof (struct uparams, dup_args) },
- { "dup-args-note", 1, offsetof (struct uparams, dup_args_note) },
- { "short-opt-col", 0, offsetof (struct uparams, short_opt_col) },
- { "long-opt-col", 0, offsetof (struct uparams, long_opt_col) },
- { "doc-opt-col", 0, offsetof (struct uparams, doc_opt_col) },
- { "opt-doc-col", 0, offsetof (struct uparams, opt_doc_col) },
- { "header-col", 0, offsetof (struct uparams, header_col) },
- { "usage-indent", 0, offsetof (struct uparams, usage_indent) },
- { "rmargin", 0, offsetof (struct uparams, rmargin) },
- { 0 }
+ { "dup-args", true, offsetof (struct uparams, dup_args) },
+ { "dup-args-note", true, offsetof (struct uparams, dup_args_note) },
+ { "short-opt-col", false, offsetof (struct uparams, short_opt_col) },
+ { "long-opt-col", false, offsetof (struct uparams, long_opt_col) },
+ { "doc-opt-col", false, offsetof (struct uparams, doc_opt_col) },
+ { "opt-doc-col", false, offsetof (struct uparams, opt_doc_col) },
+ { "header-col", false, offsetof (struct uparams, header_col) },
+ { "usage-indent", false, offsetof (struct uparams, usage_indent) },
+ { "rmargin", false, offsetof (struct uparams, rmargin) }
};
+#define nuparam_names (sizeof (uparam_names) / sizeof (uparam_names[0]))
/* Read user options from the environment, and fill in UPARAMS appropiately. */
static void
@@ -216,22 +215,27 @@ fill_in_uparams (const struct argp_state *state)
SKIPWS (arg);
}
- for (un = uparam_names; un->name; un++)
+ un = uparam_names;
+ size_t u;
+ for (u = 0; u < nuparam_names; ++un, ++u)
if (strlen (un->name) == var_len
&& strncmp (var, un->name, var_len) == 0)
{
if (unspec && !un->is_bool)
__argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain, "\
+ dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain,
+ "\
%.*s: ARGP_HELP_FMT parameter requires a value"),
(int) var_len, var);
else
*(int *)((char *)&uparams + un->uparams_offs) = val;
break;
}
- if (! un->name)
+ if (u == nuparam_names)
__argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain, "\
+ dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain, "\
%.*s: Unknown ARGP_HELP_FMT parameter"),
(int) var_len, var);
@@ -242,7 +246,8 @@ fill_in_uparams (const struct argp_state *state)
else if (*var)
{
__argp_failure (state, 0, 0,
- dgettext (state->root_argp->argp_domain,
+ dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain,
"Garbage in ARGP_HELP_FMT: %s"), var);
break;
}
@@ -668,9 +673,9 @@ hol_cluster_cmp (const struct hol_cluster *cl1, const struct hol_cluster *cl2)
{
/* If one cluster is deeper than the other, use its ancestor at the same
level, so that finding the common ancestor is straightforward. */
- while (cl1->depth < cl2->depth)
+ while (cl1->depth > cl2->depth)
cl1 = cl1->parent;
- while (cl2->depth < cl1->depth)
+ while (cl2->depth > cl1->depth)
cl2 = cl2->parent;
/* Now reduce both clusters to their ancestors at the point where both have
@@ -758,9 +763,9 @@ hol_entry_cmp (const struct hol_entry *entry1,
const char *long2 = hol_entry_first_long (entry2);
if (doc1)
- doc1 = canon_doc_option (&long1);
+ doc1 = long1 != NULL && canon_doc_option (&long1);
if (doc2)
- doc2 = canon_doc_option (&long2);
+ doc2 = long2 != NULL && canon_doc_option (&long2);
if (doc1 != doc2)
/* `documentation' options always follow normal options (or
@@ -983,7 +988,7 @@ static const char *
filter_doc (const char *doc, int key, const struct argp *argp,
const struct argp_state *state)
{
- if (argp->help_filter)
+ if (argp && argp->help_filter)
/* We must apply a user filter to this output. */
{
void *input = __argp_input (argp, state);
@@ -1101,7 +1106,9 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
__argp_fmtstream_putc (stream, '-');
__argp_fmtstream_putc (stream, *so);
if (!have_long_opt || uparams.dup_args)
- arg (real, " %s", "[%s]", state->root_argp->argp_domain, stream);
+ arg (real, " %s", "[%s]",
+ state == NULL ? NULL : state->root_argp->argp_domain,
+ stream);
else if (real->arg)
hhstate->suppressed_dup_arg = 1;
}
@@ -1121,26 +1128,22 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
have been done on the original; but documentation options
should be pretty rare anyway... */
__argp_fmtstream_puts (stream,
- dgettext (state->root_argp->argp_domain,
+ dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain,
opt->name));
}
}
else
/* A real long option. */
{
- int first_long_opt = 1;
-
__argp_fmtstream_set_wmargin (stream, uparams.long_opt_col);
for (opt = real, num = entry->num; num > 0; opt++, num--)
if (opt->name && ovisible (opt))
{
comma (uparams.long_opt_col, &pest);
__argp_fmtstream_printf (stream, "--%s", opt->name);
- if (first_long_opt || uparams.dup_args)
- arg (real, "=%s", "[=%s]", state->root_argp->argp_domain,
- stream);
- else if (real->arg)
- hhstate->suppressed_dup_arg = 1;
+ arg (real, "=%s", "[=%s]",
+ state == NULL ? NULL : state->root_argp->argp_domain, stream);
}
}
@@ -1159,7 +1162,8 @@ hol_entry_help (struct hol_entry *entry, const struct argp_state *state,
}
else
{
- const char *tstr = real->doc ? dgettext (state->root_argp->argp_domain,
+ const char *tstr = real->doc ? dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain,
real->doc) : 0;
const char *fstr = filter_doc (tstr, real->key, entry->argp, state);
if (fstr && *fstr)
@@ -1207,7 +1211,8 @@ hol_help (struct hol *hol, const struct argp_state *state,
if (hhstate.suppressed_dup_arg && uparams.dup_args_note)
{
- const char *tstr = dgettext (state->root_argp->argp_domain, "\
+ const char *tstr = dgettext (state == NULL ? NULL
+ : state->root_argp->argp_domain, "\
Mandatory or optional arguments to long options are also mandatory or \
optional for any corresponding short options.");
const char *fstr = filter_doc (tstr, ARGP_KEY_HELP_DUP_ARGS_NOTE,
@@ -1554,8 +1559,7 @@ _help (const struct argp *argp, const struct argp_state *state, FILE *stream,
__flockfile (stream);
#endif
- if (! uparams.valid)
- fill_in_uparams (state);
+ fill_in_uparams (state);
fs = __argp_make_fmtstream (stream, 0, uparams.rmargin, 0);
if (! fs)
@@ -1763,33 +1767,26 @@ __argp_error (const struct argp_state *state, const char *fmt, ...)
va_start (ap, fmt);
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- {
- char *buf;
+#ifdef _LIBC
+ char *buf;
- if (__asprintf (&buf, fmt, ap) < 0)
- buf = NULL;
+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
+ buf = NULL;
- __fwprintf (stream, L"%s: %s\n",
- state ? state->name : __argp_short_program_name (),
- buf);
+ __fxprintf (stream, "%s: %s\n",
+ state ? state->name : __argp_short_program_name (), buf);
- free (buf);
- }
- else
-#endif
- {
- fputs_unlocked (state
- ? state->name : __argp_short_program_name (),
- stream);
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
+ free (buf);
+#else
+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
+ stream);
+ putc_unlocked (':', stream);
+ putc_unlocked (' ', stream);
- vfprintf (stream, fmt, ap);
+ vfprintf (stream, fmt, ap);
- putc_unlocked ('\n', stream);
- }
+ putc_unlocked ('\n', stream);
+#endif
__argp_state_help (state, stream, ARGP_HELP_STD_ERR);
@@ -1827,41 +1824,34 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
__flockfile (stream);
#endif
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- __fwprintf (stream, L"%s",
- state ? state->name : __argp_short_program_name ());
- else
+#ifdef _LIBC
+ __fxprintf (stream, "%s",
+ state ? state->name : __argp_short_program_name ());
+#else
+ fputs_unlocked (state ? state->name : __argp_short_program_name (),
+ stream);
#endif
- fputs_unlocked (state
- ? state->name : __argp_short_program_name (),
- stream);
if (fmt)
{
va_list ap;
va_start (ap, fmt);
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- {
- char *buf;
+#ifdef _LIBC
+ char *buf;
- if (__asprintf (&buf, fmt, ap) < 0)
- buf = NULL;
+ if (_IO_vasprintf (&buf, fmt, ap) < 0)
+ buf = NULL;
- __fwprintf (stream, L": %s", buf);
+ __fxprintf (stream, ": %s", buf);
- free (buf);
- }
- else
-#endif
- {
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
+ free (buf);
+#else
+ putc_unlocked (':', stream);
+ putc_unlocked (' ', stream);
- vfprintf (stream, fmt, ap);
- }
+ vfprintf (stream, fmt, ap);
+#endif
va_end (ap);
}
@@ -1870,21 +1860,18 @@ __argp_failure (const struct argp_state *state, int status, int errnum,
{
char buf[200];
-#ifdef USE_IN_LIBIO
- if (_IO_fwide (stream, 0) > 0)
- __fwprintf (stream, L": %s",
- __strerror_r (errnum, buf, sizeof (buf)));
- else
-#endif
- {
- putc_unlocked (':', stream);
- putc_unlocked (' ', stream);
-#if defined _LIBC || defined HAVE_STRERROR_R
- fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
+#ifdef _LIBC
+ __fxprintf (stream, ": %s",
+ __strerror_r (errnum, buf, sizeof (buf)));
#else
- fputs (strerror (errnum), stream);
+ putc_unlocked (':', stream);
+ putc_unlocked (' ', stream);
+# ifdef HAVE_STRERROR_R
+ fputs (__strerror_r (errnum, buf, sizeof (buf)), stream);
+# else
+ fputs (strerror (errnum), stream);
+# endif
#endif
- }
}
#ifdef USE_IN_LIBIO
diff --git a/argp/argp-xinl.c b/argp/argp-xinl.c
index 73177585e8..7913b061ac 100644
--- a/argp/argp-xinl.c
+++ b/argp/argp-xinl.c
@@ -19,7 +19,7 @@
02111-1307 USA. */
#ifdef HAVE_CONFIG_H
-#include <config.h>
+# include <config.h>
#endif
#if defined _LIBC || defined HAVE_FEATURES_H
diff --git a/argp/argp.h b/argp/argp.h
index 008e039f9e..3a5cb01fd8 100644
--- a/argp/argp.h
+++ b/argp/argp.h
@@ -1,5 +1,5 @@
/* Hierarchial argument parsing, layered over getopt.
- Copyright (C) 1995-1999,2003,2004 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999,2003,2004,2005,2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Written by Miles Bader <miles@gnu.ai.mit.edu>.
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <ctype.h>
#include <getopt.h>
+#include <limits.h>
#define __need_error_t
#include <errno.h>
@@ -561,7 +562,7 @@ extern void *__argp_input (__const struct argp *__restrict __argp,
# endif
ARGP_EI void
-__NTH (__argp_usage (__const struct argp_state *__state))
+__argp_usage (__const struct argp_state *__state)
{
__argp_state_help (__state, stderr, ARGP_HELP_STD_USAGE);
}
@@ -574,7 +575,7 @@ __NTH (__option_is_short (__const struct argp_option *__opt))
else
{
int __key = __opt->key;
- return __key > 0 && isprint (__key);
+ return __key > 0 && __key <= UCHAR_MAX && isprint (__key);
}
}
diff --git a/argp/bug-argp1.c b/argp/bug-argp1.c
new file mode 100644
index 0000000000..a28cf4b9c7
--- /dev/null
+++ b/argp/bug-argp1.c
@@ -0,0 +1,26 @@
+#include <argp.h>
+
+
+static const struct argp_option test_options[] =
+{
+ { NULL, 'a', NULL, OPTION_DOC, NULL },
+ { NULL, 'b', NULL, OPTION_DOC, NULL },
+ { NULL, 0, NULL, 0, NULL }
+};
+
+static struct argp test_argp =
+{
+ test_options
+};
+
+
+static int
+do_test (int argc, char *argv[])
+{
+ int i;
+ argp_parse (&test_argp, argc, argv, 0, &i, NULL);
+ return 0;
+}
+
+#define TEST_FUNCTION do_test (argc, argv)
+#include "../test-skeleton.c"
diff --git a/argp/tst-argp2.c b/argp/tst-argp2.c
new file mode 100644
index 0000000000..926614fbc8
--- /dev/null
+++ b/argp/tst-argp2.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2007.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <argp.h>
+
+static const struct argp_option opt1[] =
+ {
+ { "opt1", '1', "NUMBER", 0, "Option 1" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+static const struct argp_option opt2[] =
+ {
+ { "opt2", '2', "NUMBER", 0, "Option 2" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+static const struct argp_option opt3[] =
+ {
+ { "opt3", '3', "NUMBER", 0, "Option 3" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+static const struct argp_option opt4[] =
+ {
+ { "opt4", '4', "NUMBER", 0, "Option 4" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+static const struct argp_option opt5[] =
+ {
+ { "opt5", '5', "NUMBER", 0, "Option 5" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+static struct argp argp5 =
+ {
+ opt5, NULL, "args doc5", "doc5", NULL, NULL, NULL
+ };
+
+static struct argp argp4 =
+ {
+ opt4, NULL, "args doc4", "doc4", NULL, NULL, NULL
+ };
+
+static struct argp argp3 =
+ {
+ opt3, NULL, "args doc3", "doc3", NULL, NULL, NULL
+ };
+
+static struct argp_child children2[] =
+ {
+ { &argp4, 0, "child3", 3 },
+ { &argp5, 0, "child4", 4 },
+ { NULL, 0, NULL, 0 }
+ };
+
+static struct argp argp2 =
+ {
+ opt2, NULL, "args doc2", "doc2", children2, NULL, NULL
+ };
+
+static struct argp_child children1[] =
+ {
+ { &argp2, 0, "child1", 1 },
+ { &argp3, 0, "child2", 2 },
+ { NULL, 0, NULL, 0 }
+ };
+
+static struct argp argp1 =
+ {
+ opt1, NULL, "args doc1", "doc1", children1, NULL, NULL
+ };
+
+
+static int
+do_test (void)
+{
+ argp_help (&argp1, stdout, ARGP_HELP_LONG, (char *) "tst-argp2");
+ return 0;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"