This program uses the same features as example 2, adding user options and arguments.
We now use the first four fields in argp
(see Argp Parsers)
and specify parse_opt
as the parser function. See Argp Parser Functions.
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
. See Argp. It is retrieved
by parse_opt
through the input
field in its state
argument. See Argp Parsing State. Of course, it's also possible to
use global variables instead, but using a structure like this is
somewhat more flexible and clean.
/* 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 bymain
to communicate withparse_opt
. */ struct arguments { char *args[2]; /* arg1 & 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 input argument fromargp_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 byparse_opt
will be reflected inarguments
. */ 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); }