xf.li | bdd93d5 | 2023-05-12 07:10:14 -0700 | [diff] [blame^] | 1 | /* Argp example #3 -- a program with options and arguments using argp |
| 2 | Copyright (C) 1991-2016 Free Software Foundation, Inc. |
| 3 | |
| 4 | This program is free software; you can redistribute it and/or |
| 5 | modify it under the terms of the GNU General Public License |
| 6 | as published by the Free Software Foundation; either version 2 |
| 7 | of the License, or (at your option) any later version. |
| 8 | |
| 9 | This program is distributed in the hope that it will be useful, |
| 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 | GNU General Public License for more details. |
| 13 | |
| 14 | You should have received a copy of the GNU General Public License |
| 15 | along with this program; if not, if not, see <http://www.gnu.org/licenses/>. |
| 16 | */ |
| 17 | |
| 18 | /* This program uses the same features as example 2, and uses options and |
| 19 | arguments. |
| 20 | |
| 21 | We now use the first four fields in ARGP, so here's a description of them: |
| 22 | OPTIONS -- A pointer to a vector of struct argp_option (see below) |
| 23 | PARSER -- A function to parse a single option, called by argp |
| 24 | ARGS_DOC -- A string describing how the non-option arguments should look |
| 25 | DOC -- A descriptive string about this program; if it contains a |
| 26 | vertical tab character (\v), the part after it will be |
| 27 | printed *following* the options |
| 28 | |
| 29 | The function PARSER takes the following arguments: |
| 30 | KEY -- An integer specifying which option this is (taken |
| 31 | from the KEY field in each struct argp_option), or |
| 32 | a special key specifying something else; the only |
| 33 | special keys we use here are ARGP_KEY_ARG, meaning |
| 34 | a non-option argument, and ARGP_KEY_END, meaning |
| 35 | that all arguments have been parsed |
| 36 | ARG -- For an option KEY, the string value of its |
| 37 | argument, or NULL if it has none |
| 38 | STATE-- A pointer to a struct argp_state, containing |
| 39 | various useful information about the parsing state; used here |
| 40 | are the INPUT field, which reflects the INPUT argument to |
| 41 | argp_parse, and the ARG_NUM field, which is the number of the |
| 42 | current non-option argument being parsed |
| 43 | It should return either 0, meaning success, ARGP_ERR_UNKNOWN, meaning the |
| 44 | given KEY wasn't recognized, or an errno value indicating some other |
| 45 | error. |
| 46 | |
| 47 | Note that in this example, main uses a structure to communicate with the |
| 48 | parse_opt function, a pointer to which it passes in the INPUT argument to |
| 49 | argp_parse. Of course, it's also possible to use global variables |
| 50 | instead, but this is somewhat more flexible. |
| 51 | |
| 52 | The OPTIONS field contains a pointer to a vector of struct argp_option's; |
| 53 | that structure has the following fields (if you assign your option |
| 54 | structures using array initialization like this example, unspecified |
| 55 | fields will be defaulted to 0, and need not be specified): |
| 56 | NAME -- The name of this option's long option (may be zero) |
| 57 | KEY -- The KEY to pass to the PARSER function when parsing this option, |
| 58 | *and* the name of this option's short option, if it is a |
| 59 | printable ascii character |
| 60 | ARG -- The name of this option's argument, if any |
| 61 | FLAGS -- Flags describing this option; some of them are: |
| 62 | OPTION_ARG_OPTIONAL -- The argument to this option is optional |
| 63 | OPTION_ALIAS -- This option is an alias for the |
| 64 | previous option |
| 65 | OPTION_HIDDEN -- Don't show this option in --help output |
| 66 | DOC -- A documentation string for this option, shown in --help output |
| 67 | |
| 68 | An options vector should be terminated by an option with all fields zero. */ |
| 69 | |
| 70 | #include <stdlib.h> |
| 71 | #include <argp.h> |
| 72 | |
| 73 | const char *argp_program_version = |
| 74 | "argp-ex3 1.0"; |
| 75 | const char *argp_program_bug_address = |
| 76 | "<bug-gnu-utils@@gnu.org>"; |
| 77 | |
| 78 | /* Program documentation. */ |
| 79 | static char doc[] = |
| 80 | "Argp example #3 -- a program with options and arguments using argp"; |
| 81 | |
| 82 | /* A description of the arguments we accept. */ |
| 83 | static char args_doc[] = "ARG1 ARG2"; |
| 84 | |
| 85 | /* The options we understand. */ |
| 86 | static struct argp_option options[] = { |
| 87 | {"verbose", 'v', 0, 0, "Produce verbose output" }, |
| 88 | {"quiet", 'q', 0, 0, "Don't produce any output" }, |
| 89 | {"silent", 's', 0, OPTION_ALIAS }, |
| 90 | {"output", 'o', "FILE", 0, |
| 91 | "Output to FILE instead of standard output" }, |
| 92 | { 0 } |
| 93 | }; |
| 94 | |
| 95 | /* Used by @code{main} to communicate with @code{parse_opt}. */ |
| 96 | struct arguments |
| 97 | { |
| 98 | char *args[2]; /* @var{arg1} & @var{arg2} */ |
| 99 | int silent, verbose; |
| 100 | char *output_file; |
| 101 | }; |
| 102 | |
| 103 | /* Parse a single option. */ |
| 104 | static error_t |
| 105 | parse_opt (int key, char *arg, struct argp_state *state) |
| 106 | { |
| 107 | /* Get the @var{input} argument from @code{argp_parse}, which we |
| 108 | know is a pointer to our arguments structure. */ |
| 109 | struct arguments *arguments = state->input; |
| 110 | |
| 111 | switch (key) |
| 112 | { |
| 113 | case 'q': case 's': |
| 114 | arguments->silent = 1; |
| 115 | break; |
| 116 | case 'v': |
| 117 | arguments->verbose = 1; |
| 118 | break; |
| 119 | case 'o': |
| 120 | arguments->output_file = arg; |
| 121 | break; |
| 122 | |
| 123 | case ARGP_KEY_ARG: |
| 124 | if (state->arg_num >= 2) |
| 125 | /* Too many arguments. */ |
| 126 | argp_usage (state); |
| 127 | |
| 128 | arguments->args[state->arg_num] = arg; |
| 129 | |
| 130 | break; |
| 131 | |
| 132 | case ARGP_KEY_END: |
| 133 | if (state->arg_num < 2) |
| 134 | /* Not enough arguments. */ |
| 135 | argp_usage (state); |
| 136 | break; |
| 137 | |
| 138 | default: |
| 139 | return ARGP_ERR_UNKNOWN; |
| 140 | } |
| 141 | return 0; |
| 142 | } |
| 143 | |
| 144 | /* Our argp parser. */ |
| 145 | static struct argp argp = { options, parse_opt, args_doc, doc }; |
| 146 | |
| 147 | int |
| 148 | main (int argc, char **argv) |
| 149 | { |
| 150 | struct arguments arguments; |
| 151 | |
| 152 | /* Default values. */ |
| 153 | arguments.silent = 0; |
| 154 | arguments.verbose = 0; |
| 155 | arguments.output_file = "-"; |
| 156 | |
| 157 | /* Parse our arguments; every option seen by @code{parse_opt} will |
| 158 | be reflected in @code{arguments}. */ |
| 159 | argp_parse (&argp, argc, argv, 0, 0, &arguments); |
| 160 | |
| 161 | printf ("ARG1 = %s\nARG2 = %s\nOUTPUT_FILE = %s\n" |
| 162 | "VERBOSE = %s\nSILENT = %s\n", |
| 163 | arguments.args[0], arguments.args[1], |
| 164 | arguments.output_file, |
| 165 | arguments.verbose ? "yes" : "no", |
| 166 | arguments.silent ? "yes" : "no"); |
| 167 | |
| 168 | exit (0); |
| 169 | } |