| /* 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 <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); |
| } |