Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/lib/subcmd/parse-options.h
26285 views
1
/* SPDX-License-Identifier: GPL-2.0 */
2
#ifndef __SUBCMD_PARSE_OPTIONS_H
3
#define __SUBCMD_PARSE_OPTIONS_H
4
5
#include <linux/kernel.h>
6
#include <stdbool.h>
7
#include <stdint.h>
8
9
enum parse_opt_type {
10
/* special types */
11
OPTION_END,
12
OPTION_ARGUMENT,
13
OPTION_GROUP,
14
/* options with no arguments */
15
OPTION_BIT,
16
OPTION_BOOLEAN,
17
OPTION_INCR,
18
OPTION_SET_UINT,
19
OPTION_SET_PTR,
20
/* options with arguments (usually) */
21
OPTION_STRING,
22
OPTION_INTEGER,
23
OPTION_LONG,
24
OPTION_ULONG,
25
OPTION_CALLBACK,
26
OPTION_U64,
27
OPTION_UINTEGER,
28
};
29
30
enum parse_opt_flags {
31
PARSE_OPT_KEEP_DASHDASH = 1,
32
PARSE_OPT_STOP_AT_NON_OPTION = 2,
33
PARSE_OPT_KEEP_ARGV0 = 4,
34
PARSE_OPT_KEEP_UNKNOWN = 8,
35
PARSE_OPT_NO_INTERNAL_HELP = 16,
36
};
37
38
enum parse_opt_option_flags {
39
PARSE_OPT_OPTARG = 1,
40
PARSE_OPT_NOARG = 2,
41
PARSE_OPT_NONEG = 4,
42
PARSE_OPT_HIDDEN = 8,
43
PARSE_OPT_LASTARG_DEFAULT = 16,
44
PARSE_OPT_DISABLED = 32,
45
PARSE_OPT_EXCLUSIVE = 64,
46
PARSE_OPT_NOEMPTY = 128,
47
PARSE_OPT_NOBUILD = 256,
48
PARSE_OPT_CANSKIP = 512,
49
};
50
51
struct option;
52
typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
53
54
/*
55
* `type`::
56
* holds the type of the option, you must have an OPTION_END last in your
57
* array.
58
*
59
* `short_name`::
60
* the character to use as a short option name, '\0' if none.
61
*
62
* `long_name`::
63
* the long option name, without the leading dashes, NULL if none.
64
*
65
* `value`::
66
* stores pointers to the values to be filled.
67
*
68
* `argh`::
69
* token to explain the kind of argument this option wants. Keep it
70
* homogeneous across the repository.
71
*
72
* `help`::
73
* the short help associated to what the option does.
74
* Must never be NULL (except for OPTION_END).
75
* OPTION_GROUP uses this pointer to store the group header.
76
*
77
* `flags`::
78
* mask of parse_opt_option_flags.
79
* PARSE_OPT_OPTARG: says that the argument is optional (not for BOOLEANs)
80
* PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
81
* PARSE_OPT_NONEG: says that this option cannot be negated
82
* PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
83
* the long one.
84
*
85
* `callback`::
86
* pointer to the callback to use for OPTION_CALLBACK.
87
*
88
* `defval`::
89
* default value to fill (*->value) with for PARSE_OPT_OPTARG.
90
* OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
91
* the value when met.
92
* CALLBACKS can use it like they want.
93
*
94
* `set`::
95
* whether an option was set by the user
96
*/
97
struct option {
98
enum parse_opt_type type;
99
int short_name;
100
const char *long_name;
101
void *value;
102
const char *argh;
103
const char *help;
104
const char *build_opt;
105
106
int flags;
107
parse_opt_cb *callback;
108
intptr_t defval;
109
bool *set;
110
void *data;
111
const struct option *parent;
112
};
113
114
#define check_vtype(v, type) ( BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v )
115
116
#define OPT_END() { .type = OPTION_END }
117
#define OPT_PARENT(p) { .type = OPTION_END, .parent = (p) }
118
#define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) }
119
#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) }
120
#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h), .defval = (b) }
121
#define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h) }
122
#define OPT_BOOLEAN_FLAG(s, l, v, h, f) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = check_vtype(v, bool *), .help = (h), .flags = (f) }
123
#define OPT_BOOLEAN_SET(s, l, v, os, h) \
124
{ .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), \
125
.value = check_vtype(v, bool *), .help = (h), \
126
.set = check_vtype(os, bool *)}
127
#define OPT_INCR(s, l, v, h) { .type = OPTION_INCR, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
128
#define OPT_SET_UINT(s, l, v, h, i) { .type = OPTION_SET_UINT, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .defval = (i) }
129
#define OPT_SET_PTR(s, l, v, h, p) { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) }
130
#define OPT_INTEGER(s, l, v, h) { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, int *), .help = (h) }
131
#define OPT_UINTEGER(s, l, v, h) { .type = OPTION_UINTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h) }
132
#define OPT_UINTEGER_OPTARG(s, l, v, d, h) { .type = OPTION_UINTEGER, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned int *), .help = (h), .flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d) }
133
#define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
134
#define OPT_ULONG(s, l, v, h) { .type = OPTION_ULONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, unsigned long *), .help = (h) }
135
#define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
136
#define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), .argh = (a), .help = (h) }
137
#define OPT_STRING_OPTARG(s, l, v, a, h, d) \
138
{ .type = OPTION_STRING, .short_name = (s), .long_name = (l), \
139
.value = check_vtype(v, const char **), .argh =(a), .help = (h), \
140
.flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d) }
141
#define OPT_STRING_OPTARG_SET(s, l, v, os, a, h, d) \
142
{ .type = OPTION_STRING, .short_name = (s), .long_name = (l), \
143
.value = check_vtype(v, const char **), .argh = (a), .help = (h), \
144
.flags = PARSE_OPT_OPTARG, .defval = (intptr_t)(d), \
145
.set = check_vtype(os, bool *)}
146
#define OPT_STRING_NOEMPTY(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), .argh = (a), .help = (h), .flags = PARSE_OPT_NOEMPTY}
147
#define OPT_DATE(s, l, v, h) \
148
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb }
149
#define OPT_CALLBACK(s, l, v, a, h, f) \
150
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f) }
151
#define OPT_CALLBACK_SET(s, l, v, os, a, h, f) \
152
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .set = check_vtype(os, bool *)}
153
#define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
154
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .flags = PARSE_OPT_NOARG }
155
#define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
156
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = (a), .help = (h), .callback = (f), .defval = (intptr_t)d, .flags = PARSE_OPT_LASTARG_DEFAULT }
157
#define OPT_CALLBACK_DEFAULT_NOOPT(s, l, v, a, h, f, d) \
158
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l),\
159
.value = (v), .arg = (a), .help = (h), .callback = (f), .defval = (intptr_t)d,\
160
.flags = PARSE_OPT_LASTARG_DEFAULT | PARSE_OPT_NOARG}
161
#define OPT_CALLBACK_OPTARG(s, l, v, d, a, h, f) \
162
{ .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), \
163
.value = (v), .argh = (a), .help = (h), .callback = (f), \
164
.flags = PARSE_OPT_OPTARG, .data = (d) }
165
166
/* parse_options() will filter out the processed options and leave the
167
* non-option argments in argv[].
168
* Returns the number of arguments left in argv[].
169
*
170
* NOTE: parse_options() and parse_options_subcommand() may call exit() in the
171
* case of an error (or for 'special' options like --list-cmds or --list-opts).
172
*/
173
extern int parse_options(int argc, const char **argv,
174
const struct option *options,
175
const char * const usagestr[], int flags);
176
177
extern int parse_options_subcommand(int argc, const char **argv,
178
const struct option *options,
179
const char *const subcommands[],
180
const char *usagestr[], int flags);
181
182
extern __noreturn void usage_with_options(const char * const *usagestr,
183
const struct option *options);
184
extern __noreturn __attribute__((format(printf,3,4)))
185
void usage_with_options_msg(const char * const *usagestr,
186
const struct option *options,
187
const char *fmt, ...);
188
189
/*----- incremantal advanced APIs -----*/
190
191
enum {
192
PARSE_OPT_HELP = -1,
193
PARSE_OPT_DONE,
194
PARSE_OPT_LIST_OPTS,
195
PARSE_OPT_LIST_SUBCMDS,
196
PARSE_OPT_UNKNOWN,
197
};
198
199
/*
200
* It's okay for the caller to consume argv/argc in the usual way.
201
* Other fields of that structure are private to parse-options and should not
202
* be modified in any way.
203
*/
204
struct parse_opt_ctx_t {
205
const char **argv;
206
const char **out;
207
int argc, cpidx;
208
const char *opt;
209
const struct option *excl_opt;
210
int flags;
211
};
212
213
extern int parse_options_usage(const char * const *usagestr,
214
const struct option *opts,
215
const char *optstr,
216
bool short_opt);
217
218
219
/*----- some often used options -----*/
220
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
221
extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
222
extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
223
224
#define OPT__VERBOSE(var) OPT_BOOLEAN('v', "verbose", (var), "be verbose")
225
#define OPT__QUIET(var) OPT_BOOLEAN('q', "quiet", (var), "be quiet")
226
#define OPT__VERBOSITY(var) \
227
{ OPTION_CALLBACK, 'v', "verbose", (var), NULL, "be more verbose", \
228
PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }, \
229
{ OPTION_CALLBACK, 'q', "quiet", (var), NULL, "be more quiet", \
230
PARSE_OPT_NOARG, &parse_opt_verbosity_cb, 0 }
231
#define OPT__DRY_RUN(var) OPT_BOOLEAN('n', "dry-run", (var), "dry run")
232
#define OPT__ABBREV(var) \
233
{ OPTION_CALLBACK, 0, "abbrev", (var), "n", \
234
"use <n> digits to display SHA-1s", \
235
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
236
237
extern const char *parse_options_fix_filename(const char *prefix, const char *file);
238
239
void set_option_flag(struct option *opts, int sopt, const char *lopt, int flag);
240
void set_option_nobuild(struct option *opts, int shortopt, const char *longopt,
241
const char *build_opt, bool can_skip);
242
243
#endif /* __SUBCMD_PARSE_OPTIONS_H */
244
245