From 86387d4eb3e8e6f97ab8b7f0e2d6988ed0e62e48 Mon Sep 17 00:00:00 2001 From: Salvatore Cro Date: Sun, 16 Aug 2015 20:53:37 -0700 Subject: Add argp implementation Argp is an advanced support for parsing unix-style argument vectors. In addition to the common getopt interface, it provides automatic response to `--help' and `--version' options and use of custom parser in conjunction with argp native option parser, among others. Argp support is required by elfutils package and prelink. In uClibc argp functionalities has been moved from C library to libuargp.so Further the libc.so linker script contains an AS_NEEDED entry so that it doesn't need to link libuargp.so explicitely. Disable argp test if feature disabled. Signed-off-by: Salvatore Cro Signed-off-by: Filippo Arcidiacono Signed-off-by: Carmelo Amoroso Signed-off-by: Khem Raj Signed-off-by: Waldemar Brodkorb --- test/Makefile | 3 + test/argp/Makefile | 8 ++ test/argp/Makefile.in | 12 +++ test/argp/argp-ex1.c | 15 ++++ test/argp/argp-ex2.c | 45 +++++++++++ test/argp/argp-ex3.c | 153 ++++++++++++++++++++++++++++++++++++ test/argp/argp-ex4.c | 167 ++++++++++++++++++++++++++++++++++++++++ test/argp/argp-test.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/argp/bug-argp1.c | 26 +++++++ test/argp/tst-argp1.c | 118 ++++++++++++++++++++++++++++ test/argp/tst-argp2.c | 101 ++++++++++++++++++++++++ 11 files changed, 857 insertions(+) create mode 100644 test/argp/Makefile create mode 100644 test/argp/Makefile.in create mode 100644 test/argp/argp-ex1.c create mode 100644 test/argp/argp-ex2.c create mode 100644 test/argp/argp-ex3.c create mode 100644 test/argp/argp-ex4.c create mode 100644 test/argp/argp-test.c create mode 100644 test/argp/bug-argp1.c create mode 100644 test/argp/tst-argp1.c create mode 100644 test/argp/tst-argp2.c (limited to 'test') diff --git a/test/Makefile b/test/Makefile index a1fa7280c..525a69c3c 100644 --- a/test/Makefile +++ b/test/Makefile @@ -42,6 +42,9 @@ endif ifeq ($(HAS_NO_THREADS),y) DIRS := $(filter-out pthread,$(DIRS)) endif +ifneq ($(UCLIBC_HAS_ARGP),y) + DIRS := $(filter-out argp,$(DIRS)) +endif test check all: run 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 +#include + +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 +#include + +const char *argp_program_version = + "argp-ex2 1.0"; +const char *argp_program_bug_address = + ""; + +/* 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 +#include + +const char *argp_program_version = + "argp-ex3 1.0"; +const char *argp_program_bug_address = + ""; + +/* 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 +#include +#include + +const char *argp_program_version = + "argp-ex4 1.0"; +const char *argp_program_bug_address = + ""; + +/* 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 . + + 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 +#endif + +#include +#include +#include +#include + +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, ¶ms); + 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 + + +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 , 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 + + + + +#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 , 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 + +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" -- cgit v1.2.3