1 | /* Argp example #3 -- a program with options and arguments using argp |
2 | Copyright (C) 1991-2022 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, see <https://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: 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: 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: &argp, argc: argc, argv: argv, flags: 0, arg_index: 0, input: &arguments); |
160 | |
161 | printf (format: "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 | } |
170 | |