summaryrefslogtreecommitdiff
path: root/test/argp
diff options
context:
space:
mode:
Diffstat (limited to 'test/argp')
-rw-r--r--test/argp/Makefile8
-rw-r--r--test/argp/Makefile.in12
-rw-r--r--test/argp/argp-ex1.c15
-rw-r--r--test/argp/argp-ex2.c45
-rw-r--r--test/argp/argp-ex3.c153
-rw-r--r--test/argp/argp-ex4.c167
-rw-r--r--test/argp/argp-test.c209
-rw-r--r--test/argp/bug-argp1.c26
-rw-r--r--test/argp/tst-argp1.c118
-rw-r--r--test/argp/tst-argp2.c101
10 files changed, 854 insertions, 0 deletions
diff --git a/test/argp/Makefile b/test/argp/Makefile
new file mode 100644
index 000000000..fcb5a8328
--- /dev/null
+++ b/test/argp/Makefile
@@ -0,0 +1,8 @@
+# uClibc argp tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+top_builddir=../../
+top_srcdir=../../
+include ../Rules.mak
+-include Makefile.in
+include ../Test.mak
diff --git a/test/argp/Makefile.in b/test/argp/Makefile.in
new file mode 100644
index 000000000..d81b3595b
--- /dev/null
+++ b/test/argp/Makefile.in
@@ -0,0 +1,12 @@
+# uClibc argp tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+TESTS := $(addprefix argp-, ex1 ex2 ex3 ex4 test) \
+ bug-argp1 tst-argp1 tst-argp2
+
+EXTRA_LDFLAGS = -luargp
+
+OPTS_argp-ex3 = ARG1 ARG2
+OPTS_argp-ex4 = ARG1 string1 string2 string3
+OPTS_bug-argp1 = -- --help
+
diff --git a/test/argp/argp-ex1.c b/test/argp/argp-ex1.c
new file mode 100644
index 000000000..7bb5f2241
--- /dev/null
+++ b/test/argp/argp-ex1.c
@@ -0,0 +1,15 @@
+/* Argp example #1 -- a minimal program using argp */
+
+/* This is (probably) the smallest possible program that
+ uses argp. It won't do much except give an error
+ messages and exit when there are any arguments, and print
+ a (rather pointless) messages for --help. */
+
+#include <stdlib.h>
+#include <argp.h>
+
+int main (int argc, char **argv)
+{
+ argp_parse (0, argc, argv, 0, 0, 0);
+ exit (0);
+}
diff --git a/test/argp/argp-ex2.c b/test/argp/argp-ex2.c
new file mode 100644
index 000000000..c49fbaca9
--- /dev/null
+++ b/test/argp/argp-ex2.c
@@ -0,0 +1,45 @@
+/* Argp example #2 -- a pretty minimal program using argp */
+
+/* This program doesn't use any options or arguments, but uses
+ argp to be compliant with the GNU standard command line
+ format.
+
+ In addition to making sure no arguments are given, and
+ implementing a --help option, this example will have a
+ --version option, and will put the given documentation string
+ and bug address in the --help output, as per GNU standards.
+
+ The variable ARGP contains the argument parser specification;
+ adding fields to this structure is the way most parameters are
+ passed to argp_parse (the first three fields are usually used,
+ but not in this small program). There are also two global
+ variables that argp knows about defined here,
+ ARGP_PROGRAM_VERSION and ARGP_PROGRAM_BUG_ADDRESS (they are
+ global variables because they will almost always be constant
+ for a given program, even if it uses different argument
+ parsers for various tasks). */
+
+#include <stdlib.h>
+#include <argp.h>
+
+const char *argp_program_version =
+ "argp-ex2 1.0";
+const char *argp_program_bug_address =
+ "<bug-gnu-utils@@gnu.org>";
+
+/* Program documentation. */
+static char doc[] =
+ "Argp example #2 -- a pretty minimal program using argp";
+
+/* Our argument parser. The @code{options}, @code{parser}, and
+ @code{args_doc} fields are zero because we have neither options or
+ arguments; @code{doc} and @code{argp_program_bug_address} will be
+ used in the output for @samp{--help}, and the @samp{--version}
+ option will print out @code{argp_program_version}. */
+static struct argp argp = { 0, 0, 0, doc };
+
+int main (int argc, char **argv)
+{
+ argp_parse (&argp, argc, argv, 0, 0, 0);
+ exit (0);
+}
diff --git a/test/argp/argp-ex3.c b/test/argp/argp-ex3.c
new file mode 100644
index 000000000..24d5c501a
--- /dev/null
+++ b/test/argp/argp-ex3.c
@@ -0,0 +1,153 @@
+/* Argp example #3 -- a program with options and arguments using argp */
+
+/* This program uses the same features as example 2, and uses options and
+ arguments.
+
+ We now use the first four fields in ARGP, so here's a description of them:
+ OPTIONS -- A pointer to a vector of struct argp_option (see below)
+ PARSER -- A function to parse a single option, called by argp
+ ARGS_DOC -- A string describing how the non-option arguments should look
+ DOC -- A descriptive string about this program; if it contains a
+ vertical tab character (\v), the part after it will be
+ printed *following* the options
+
+ The function PARSER takes the following arguments:
+ KEY -- An integer specifying which option this is (taken
+ from the KEY field in each struct argp_option), or
+ a special key specifying something else; the only
+ special keys we use here are ARGP_KEY_ARG, meaning
+ a non-option argument, and ARGP_KEY_END, meaning
+ that all arguments have been parsed
+ ARG -- For an option KEY, the string value of its
+ argument, or NULL if it has none
+ STATE-- A pointer to a struct argp_state, containing
+ various useful information about the parsing state; used here
+ are the INPUT field, which reflects the INPUT argument to
+ argp_parse, and the ARG_NUM field, which is the number of the
+ current non-option argument being parsed
+ It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the
+ given KEY wasn't recognized, or an errno value indicating some other
+ error.
+
+ Note that in this example, main uses a structure to communicate with the
+ parse_opt function, a pointer to which it passes in the INPUT argument to
+ argp_parse. Of course, it's also possible to use global variables
+ instead, but this is somewhat more flexible.
+
+ The OPTIONS field contains a pointer to a vector of struct argp_option's;
+ that structure has the following fields (if you assign your option
+ structures using array initialization like this example, unspecified
+ fields will be defaulted to 0, and need not be specified):
+ NAME -- The name of this option's long option (may be zero)
+ KEY -- The KEY to pass to the PARSER function when parsing this option,
+ *and* the name of this option's short option, if it is a
+ printable ascii character
+ ARG -- The name of this option's argument, if any
+ FLAGS -- Flags describing this option; some of them are:
+ OPTION_ARG_OPTIONAL -- The argument to this option is optional
+ OPTION_ALIAS -- This option is an alias for the
+ previous option
+ OPTION_HIDDEN -- Don't show this option in --help output
+ DOC -- A documentation string for this option, shown in --help output
+
+ An options vector should be terminated by an option with all fields zero. */
+
+#include <stdlib.h>
+#include <argp.h>
+
+const char *argp_program_version =
+ "argp-ex3 1.0";
+const char *argp_program_bug_address =
+ "<bug-gnu-utils@@gnu.org>";
+
+/* Program documentation. */
+static char doc[] =
+ "Argp example #3 -- a program with options and arguments using argp";
+
+/* A description of the arguments we accept. */
+static char args_doc[] = "ARG1 ARG2";
+
+/* The options we understand. */
+static struct argp_option options[] = {
+ {"verbose", 'v', 0, 0, "Produce verbose output" },
+ {"quiet", 'q', 0, 0, "Don't produce any output" },
+ {"silent", 's', 0, OPTION_ALIAS },
+ {"output", 'o', "FILE", 0,
+ "Output to FILE instead of standard output" },
+ { 0 }
+};
+
+/* Used by @code{main} to communicate with @code{parse_opt}. */
+struct arguments
+{
+ char *args[2]; /* @var{arg1} & @var{arg2} */
+ int silent, verbose;
+ char *output_file;
+};
+
+/* Parse a single option. */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ /* Get the @var{input} argument from @code{argp_parse}, which we
+ know is a pointer to our arguments structure. */
+ struct arguments *arguments = state->input;
+
+ switch (key)
+ {
+ case 'q': case 's':
+ arguments->silent = 1;
+ break;
+ case 'v':
+ arguments->verbose = 1;
+ break;
+ case 'o':
+ arguments->output_file = arg;
+ break;
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num >= 2)
+ /* Too many arguments. */
+ argp_usage (state);
+
+ arguments->args[state->arg_num] = arg;
+
+ break;
+
+ case ARGP_KEY_END:
+ if (state->arg_num < 2)
+ /* Not enough arguments. */
+ argp_usage (state);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+/* Our argp parser. */
+static struct argp argp = { options, parse_opt, args_doc, doc };
+
+int main (int argc, char **argv)
+{
+ struct arguments arguments;
+
+ /* Default values. */
+ arguments.silent = 0;
+ arguments.verbose = 0;
+ arguments.output_file = "-";
+
+ /* Parse our arguments; every option seen by @code{parse_opt} will
+ be reflected in @code{arguments}. */
+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
+
+ printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n"
+ "VERBOSE = %s\nSILENT = %s\n",
+ arguments.args[0], arguments.args[1],
+ arguments.output_file,
+ arguments.verbose ? "yes" : "no",
+ arguments.silent ? "yes" : "no");
+
+ exit (0);
+}
diff --git a/test/argp/argp-ex4.c b/test/argp/argp-ex4.c
new file mode 100644
index 000000000..c77c7ef02
--- /dev/null
+++ b/test/argp/argp-ex4.c
@@ -0,0 +1,167 @@
+/* Argp example #4 -- a program with somewhat more complicated options */
+
+/* This program uses the same features as example 3, but has more
+ options, and somewhat more structure in the -help output. It
+ also shows how you can `steal' the remainder of the input
+ arguments past a certain point, for programs that accept a
+ list of items. It also shows the special argp KEY value
+ ARGP_KEY_NO_ARGS, which is only given if no non-option
+ arguments were supplied to the program.
+
+ For structuring the help output, two features are used,
+ *headers* which are entries in the options vector with the
+ first four fields being zero, and a two part documentation
+ string (in the variable DOC), which allows documentation both
+ before and after the options; the two parts of DOC are
+ separated by a vertical-tab character ('\v', or '\013'). By
+ convention, the documentation before the options is just a
+ short string saying what the program does, and that afterwards
+ is longer, describing the behavior in more detail. All
+ documentation strings are automatically filled for output,
+ although newlines may be included to force a line break at a
+ particular point. All documentation strings are also passed to
+ the `gettext' function, for possible translation into the
+ current locale. */
+
+#include <stdlib.h>
+#include <error.h>
+#include <argp.h>
+
+const char *argp_program_version =
+ "argp-ex4 1.0";
+const char *argp_program_bug_address =
+ "<bug-gnu-utils@@prep.ai.mit.edu>";
+
+/* Program documentation. */
+static char doc[] =
+ "Argp example #4 -- a program with somewhat more complicated\
+options\
+\vThis part of the documentation comes *after* the options;\
+ note that the text is automatically filled, but it's possible\
+ to force a line-break, e.g.\n<-- here.";
+
+/* A description of the arguments we accept. */
+static char args_doc[] = "ARG1 [STRING...]";
+
+/* Keys for options without short-options. */
+#define OPT_ABORT 1 /* --abort */
+
+/* The options we understand. */
+static struct argp_option options[] = {
+ {"verbose", 'v', 0, 0, "Produce verbose output" },
+ {"quiet", 'q', 0, 0, "Don't produce any output" },
+ {"silent", 's', 0, OPTION_ALIAS },
+ {"output", 'o', "FILE", 0,
+ "Output to FILE instead of standard output" },
+
+ {0,0,0,0, "The following options should be grouped together:" },
+ {"repeat", 'r', "COUNT", OPTION_ARG_OPTIONAL,
+ "Repeat the output COUNT (default 10) times"},
+ {"abort", OPT_ABORT, 0, 0, "Abort before showing any output"},
+
+ { 0 }
+};
+
+/* Used by @code{main} to communicate with @code{parse_opt}. */
+struct arguments
+{
+ char *arg1; /* @var{arg1} */
+ char **strings; /* [@var{string}@dots{}] */
+ int silent, verbose, abort; /* @samp{-s}, @samp{-v}, @samp{--abort} */
+ char *output_file; /* @var{file} arg to @samp{--output} */
+ int repeat_count; /* @var{count} arg to @samp{--repeat} */
+};
+
+/* Parse a single option. */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ /* Get the @code{input} argument from @code{argp_parse}, which we
+ know is a pointer to our arguments structure. */
+ struct arguments *arguments = state->input;
+
+ switch (key)
+ {
+ case 'q': case 's':
+ arguments->silent = 1;
+ break;
+ case 'v':
+ arguments->verbose = 1;
+ break;
+ case 'o':
+ arguments->output_file = arg;
+ break;
+ case 'r':
+ arguments->repeat_count = arg ? atoi (arg) : 10;
+ break;
+ case OPT_ABORT:
+ arguments->abort = 1;
+ break;
+
+ case ARGP_KEY_NO_ARGS:
+ argp_usage (state);
+
+ case ARGP_KEY_ARG:
+ /* Here we know that @code{state->arg_num == 0}, since we
+ force argument parsing to end before any more arguments can
+ get here. */
+ arguments->arg1 = arg;
+
+ /* Now we consume all the rest of the arguments.
+ @code{state->next} is the index in @code{state->argv} of the
+ next argument to be parsed, which is the first @var{string}
+ we're interested in, so we can just use
+ @code{&state->argv[state->next]} as the value for
+ arguments->strings.
+
+ @emph{In addition}, by setting @code{state->next} to the end
+ of the arguments, we can force argp to stop parsing here and
+ return. */
+ arguments->strings = &state->argv[state->next];
+ state->next = state->argc;
+
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+/* Our argp parser. */
+static struct argp argp = { options, parse_opt, args_doc, doc };
+
+int main (int argc, char **argv)
+{
+ int i, j;
+ struct arguments arguments;
+
+ /* Default values. */
+ arguments.silent = 0;
+ arguments.verbose = 0;
+ arguments.output_file = "-";
+ arguments.repeat_count = 1;
+ arguments.abort = 0;
+
+ /* Parse our arguments; every option seen by @code{parse_opt} will be
+ reflected in @code{arguments}. */
+ argp_parse (&argp, argc, argv, 0, 0, &arguments);
+
+ if (arguments.abort)
+ error (10, 0, "ABORTED");
+
+ for (i = 0; i < arguments.repeat_count; i++)
+ {
+ printf ("ARG1 = %s\n", arguments.arg1);
+ printf ("STRINGS = ");
+ for (j = 0; arguments.strings[j]; j++)
+ printf (j == 0 ? "%s" : ", %s", arguments.strings[j]);
+ printf ("\n");
+ printf ("OUTPUT_FILE = %s\nVERBOSE = %s\nSILENT = %s\n",
+ arguments.output_file,
+ arguments.verbose ? "yes" : "no",
+ arguments.silent ? "yes" : "no");
+ }
+
+ exit (0);
+}
diff --git a/test/argp/argp-test.c b/test/argp/argp-test.c
new file mode 100644
index 000000000..b3d573bae
--- /dev/null
+++ b/test/argp/argp-test.c
@@ -0,0 +1,209 @@
+/* Test program for argp argument parser
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Written by Miles Bader <miles at gnu.ai.mit.edu>.
+
+ 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. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <time.h>
+#include <string.h>
+#include <argp.h>
+
+const char *argp_program_version = "argp-test 1.0";
+
+struct argp_option sub_options[] =
+{
+ {"subopt1", 's', 0, 0, "Nested option 1"},
+ {"subopt2", 'S', 0, 0, "Nested option 2"},
+
+ { 0, 0, 0, 0, "Some more nested options:", 10},
+ {"subopt3", 'p', 0, 0, "Nested option 3"},
+
+ {"subopt4", 'q', 0, 0, "Nested option 4", 1},
+
+ {0}
+};
+
+static const char sub_args_doc[] = "STRING...\n-";
+static const char sub_doc[] = "\vThis is the doc string from the sub-arg-parser.";
+
+static error_t
+sub_parse_opt (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case ARGP_KEY_NO_ARGS:
+ printf ("NO SUB ARGS\n");
+ break;
+ case ARGP_KEY_ARG:
+ printf ("SUB ARG: %s\n", arg);
+ break;
+
+ case 's' : case 'S': case 'p': case 'q':
+ printf ("SUB KEY %c\n", key);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static char *
+sub_help_filter (int key, const char *text, void *input)
+{
+ if (key == ARGP_KEY_HELP_EXTRA)
+ return strdup ("This is some extra text from the sub parser (note that it \
+is preceded by a blank line).");
+ else
+ return (char *)text;
+}
+
+static struct argp sub_argp = {
+ sub_options, sub_parse_opt, sub_args_doc, sub_doc, 0, sub_help_filter
+};
+
+/* Structure used to communicate with the parsing functions. */
+struct params
+{
+ unsigned foonly; /* Value parsed for foonly. */
+ unsigned foonly_default; /* Default value for it. */
+};
+
+#define OPT_PGRP 1
+#define OPT_SESS 2
+
+struct argp_option options[] =
+{
+ {"pid", 'p', "PID", 0, "List the process PID"},
+ {"pgrp", OPT_PGRP,"PGRP",0, "List processes in the process group PGRP"},
+ {"no-parent", 'P', 0, 0, "Include processes without parents"},
+ {0, 'x', 0, OPTION_ALIAS},
+ {"all-fields",'Q', 0, 0, "Don't elide unusable fields (normally"
+ " if there's some reason ps can't"
+ " print a field for any process, it's"
+ " removed from the output entirely)" },
+ {"reverse", 'r', 0, 0, "Reverse the order of any sort"},
+ {"gratuitously-long-reverse-option", 0, 0, OPTION_ALIAS},
+ {"session", OPT_SESS,"SID", OPTION_ARG_OPTIONAL,
+ "Add the processes from the session"
+ " SID (which defaults to the sid of"
+ " the current process)" },
+
+ {0,0,0,0, "Here are some more options:"},
+ {"foonly", 'f', "ZOT", OPTION_ARG_OPTIONAL, "Glork a foonly"},
+ {"zaza", 'z', 0, 0, "Snit a zar"},
+
+ {0}
+};
+
+static const char args_doc[] = "STRING";
+static const char doc[] = "Test program for argp."
+ "\vThis doc string comes after the options."
+ "\nHey! Some manual formatting!"
+ "\nThe current time is: %s";
+
+static void
+popt (int key, char *arg)
+{
+ char buf[10];
+ if (isprint (key))
+ sprintf (buf, "%c", key);
+ else
+ sprintf (buf, "%d", key);
+ if (arg)
+ printf ("KEY %s: %s\n", buf, arg);
+ else
+ printf ("KEY %s\n", buf);
+}
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ struct params *params = state->input;
+
+ switch (key)
+ {
+ case ARGP_KEY_NO_ARGS:
+ printf ("NO ARGS\n");
+ break;
+
+ case ARGP_KEY_ARG:
+ if (state->arg_num > 0)
+ return ARGP_ERR_UNKNOWN; /* Leave it for the sub-arg parser. */
+ printf ("ARG: %s\n", arg);
+ break;
+
+ case 'f':
+ if (arg)
+ params->foonly = atoi (arg);
+ else
+ params->foonly = params->foonly_default;
+ popt (key, arg);
+ break;
+
+ case 'p': case 'P': case OPT_PGRP: case 'x': case 'Q':
+ case 'r': case OPT_SESS: case 'z':
+ popt (key, arg);
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
+static char *
+help_filter (int key, const char *text, void *input)
+{
+ char *new_text;
+ struct params *params = input;
+
+ if (key == ARGP_KEY_HELP_POST_DOC && text)
+ {
+ time_t now = time (0);
+ asprintf (&new_text, text, ctime (&now));
+ }
+ else if (key == 'f')
+ /* Show the default for the --foonly option. */
+ asprintf (&new_text, "%s (ZOT defaults to %x)",
+ text, params->foonly_default);
+ else
+ new_text = (char *)text;
+
+ return new_text;
+}
+
+static struct argp_child argp_children[] = { { &sub_argp }, { 0 } };
+static struct argp argp = {
+ options, parse_opt, args_doc, doc, argp_children, help_filter
+};
+
+int
+main (int argc, char **argv)
+{
+ struct params params;
+ params.foonly = 0;
+ params.foonly_default = random ();
+ argp_parse (&argp, argc, argv, 0, 0, &params);
+ printf ("After parsing: foonly = %x\n", params.foonly);
+ return 0;
+}
diff --git a/test/argp/bug-argp1.c b/test/argp/bug-argp1.c
new file mode 100644
index 000000000..a28cf4b9c
--- /dev/null
+++ b/test/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/test/argp/tst-argp1.c b/test/argp/tst-argp1.c
new file mode 100644
index 000000000..827daca6f
--- /dev/null
+++ b/test/argp/tst-argp1.c
@@ -0,0 +1,118 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper at redhat.com>, 2002.
+
+ 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>
+
+
+
+
+#define OPT_TO_THREAD 300
+#define OPT_TO_PROCESS 301
+#define OPT_SYNC_SIGNAL 302
+#define OPT_SYNC_JOIN 303
+#define OPT_TOPLEVEL 304
+
+
+static const struct argp_option test_options[] =
+ {
+ { NULL, 0, NULL, 0, "\
+This is a test for threads so we allow ther user to selection the number of \
+threads which are used at any one time. Independently the total number of \
+rounds can be selected. This is the total number of threads which will have \
+run when the process terminates:" },
+ { "threads", 't', "NUMBER", 0, "Number of threads used at once" },
+ { "starts", 's', "NUMBER", 0, "Total number of working threads" },
+ { "toplevel", OPT_TOPLEVEL, "NUMBER", 0,
+ "Number of toplevel threads which start the other threads; this \
+implies --sync-join" },
+
+ { NULL, 0, NULL, 0, "\
+Each thread can do one of two things: sleep or do work. The latter is 100% \
+CPU bound. The work load is the probability a thread does work. All values \
+from zero to 100 (inclusive) are valid. How often each thread repeats this \
+can be determined by the number of rounds. The work cost determines how long \
+each work session (not sleeping) takes. If it is zero a thread would \
+effectively nothing. By setting the number of rounds to zero the thread \
+does no work at all and pure thread creation times can be measured." },
+ { "workload", 'w', "PERCENT", 0, "Percentage of time spent working" },
+ { "workcost", 'c', "NUMBER", 0,
+ "Factor in the cost of each round of working" },
+ { "rounds", 'r', "NUMBER", 0, "Number of rounds each thread runs" },
+
+ { NULL, 0, NULL, 0, "\
+There are a number of different methods how thread creation can be \
+synchronized. Synchronization is necessary since the number of concurrently \
+running threads is limited." },
+ { "sync-signal", OPT_SYNC_SIGNAL, NULL, 0,
+ "Synchronize using a signal (default)" },
+ { "sync-join", OPT_SYNC_JOIN, NULL, 0, "Synchronize using pthread_join" },
+
+ { NULL, 0, NULL, 0, "\
+One parameter for each threads execution is the size of the stack. If this \
+parameter is not used the system's default stack size is used. If many \
+threads are used the stack size should be chosen quite small." },
+ { "stacksize", 'S', "BYTES", 0, "Size of threads stack" },
+ { "guardsize", 'g', "BYTES", 0,
+ "Size of stack guard area; must fit into the stack" },
+
+ { NULL, 0, NULL, 0, "Signal options:" },
+ { "to-thread", OPT_TO_THREAD, NULL, 0, "Send signal to main thread" },
+ { "to-process", OPT_TO_PROCESS, NULL, 0,
+ "Send signal to process (default)" },
+
+ { NULL, 0, NULL, 0, "Administrative options:" },
+ { "progress", 'p', NULL, 0, "Show signs of progress" },
+ { "timing", 'T', NULL, 0,
+ "Measure time from startup to the last thread finishing" },
+ { NULL, 0, NULL, 0, NULL }
+ };
+
+/* Prototype for option handler. */
+static error_t parse_opt (int key, char *arg, struct argp_state *state);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ test_options, parse_opt
+};
+
+
+static int
+do_test (void)
+{
+ int argc = 2;
+ char *argv[3] = { (char *) "tst-argp1", (char *) "--help", NULL };
+ int remaining;
+
+ /* Parse and process arguments. */
+ argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ return 0;
+}
+
+
+/* Handle program arguments. */
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ return ARGP_ERR_UNKNOWN;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/test/argp/tst-argp2.c b/test/argp/tst-argp2.c
new file mode 100644
index 000000000..705cdcaa9
--- /dev/null
+++ b/test/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 at 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"