xref: /kvmtool/include/kvm/parse-options.h (revision a33979d8e21fbd1cd920b16f5fc15ba377416881)
1 #ifndef __PARSE_OPTIONS_H__
2 #define __PARSE_OPTIONS_H__
3 
4 enum parse_opt_type {
5 	/* special types */
6 	OPTION_END,
7 	OPTION_ARGUMENT,
8 	OPTION_GROUP,
9 	/* options with no arguments */
10 	OPTION_BIT,
11 	OPTION_BOOLEAN,
12 	OPTION_INCR,
13 	OPTION_SET_UINT,
14 	OPTION_SET_PTR,
15 	/* options with arguments (usually) */
16 	OPTION_STRING,
17 	OPTION_INTEGER,
18 	OPTION_LONG,
19 	OPTION_CALLBACK,
20 	OPTION_U64,
21 	OPTION_UINTEGER,
22 };
23 
24 enum parse_opt_flags {
25 	PARSE_OPT_KEEP_DASHDASH = 1,
26 	PARSE_OPT_STOP_AT_NON_OPTION = 2,
27 	PARSE_OPT_KEEP_ARGV0 = 4,
28 	PARSE_OPT_KEEP_UNKNOWN = 8,
29 	PARSE_OPT_NO_INTERNAL_HELP = 16,
30 };
31 
32 enum parse_opt_option_flags {
33 	PARSE_OPT_OPTARG  = 1,
34 	PARSE_OPT_NOARG   = 2,
35 	PARSE_OPT_NONEG   = 4,
36 	PARSE_OPT_HIDDEN  = 8,
37 	PARSE_OPT_LASTARG_DEFAULT = 16,
38 };
39 
40 struct option;
41 typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
42 /*
43  * `type`::
44  *   holds the type of the option, you must have an OPTION_END last in your
45  *   array.
46  *
47  * `short_name`::
48  *   the character to use as a short option name, '\0' if none.
49  *
50  * `long_name`::
51  *   the long option name, without the leading dashes, NULL if none.
52  *
53  * `value`::
54  *   stores pointers to the values to be filled.
55  *
56  * `argh`::
57  *   token to explain the kind of argument this option wants. Keep it
58  *   homogenous across the repository.
59  *
60  * `help`::
61  *   the short help associated to what the option does.
62  *   Must never be NULL (except for OPTION_END).
63  *   OPTION_GROUP uses this pointer to store the group header.
64  *
65  * `flags`::
66  *   mask of parse_opt_option_flags.
67  *   PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
68  *   PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
69  *   PARSE_OPT_NONEG: says that this option cannot be negated
70  *   PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
71  *                    the long one.
72  *
73  * `callback`::
74  *   pointer to the callback to use for OPTION_CALLBACK.
75  *
76  * `defval`::
77  *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
78  *   OPTION_{BIT,SET_UINT,SET_PTR} store the {mask,integer,pointer} to put in
79  *   the value when met.
80  *   CALLBACKS can use it like they want.
81  */
82 struct option {
83 enum parse_opt_type type;
84 int short_name;
85 const char *long_name;
86 void *value;
87 const char *argh;
88 const char *help;
89 
90 int flags;
91 parse_opt_cb *callback;
92 intptr_t defval;
93 };
94 
95 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
96 #define check_vtype(v, type) \
97 	(BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v)
98 
99 #define OPT_INTEGER(s, l, v, h)             \
100 {                                           \
101 	.type = OPTION_INTEGER,             \
102 	.short_name = (s),                  \
103 	.long_name = (l),                   \
104 	.value = check_vtype(v, int *),     \
105 	.help = (h)                         \
106 }
107 
108 #define OPT_U64(s, l, v, h)                 \
109 {                                           \
110 	.type = OPTION_U64,                 \
111 	.short_name = (s),                  \
112 	.long_name = (l),                   \
113 	.value = check_vtype(v, u64 *),     \
114 	.help = (h)                         \
115 }
116 
117 #define OPT_STRING(s, l, v, a, h)           \
118 {                                           \
119 	.type = OPTION_STRING,              \
120 	.short_name = (s),                  \
121 	.long_name = (l),                   \
122 	.value = check_vtype(v, const char **), (a), \
123 	.help = (h)                         \
124 }
125 
126 #define OPT_BOOLEAN(s, l, v, h)             \
127 {                                           \
128 	.type = OPTION_BOOLEAN,             \
129 	.short_name = (s),                  \
130 	.long_name = (l),                   \
131 	.value = check_vtype(v, bool *),    \
132 	.help = (h)                         \
133 }
134 
135 #define OPT_GROUP(h)                        \
136 {                                           \
137 	.type = OPTION_GROUP,               \
138 	.help = (h)                         \
139 }
140 
141 #define OPT_CALLBACK(s, l, v, a, h, f)      \
142 {					    \
143 	.type = OPTION_CALLBACK,	    \
144 	.short_name = (s),		    \
145 	.long_name = (l),		    \
146 	.value = (v),			    \
147 	(a),				    \
148 	.help = (h),			    \
149 	.callback = (f)			    \
150 }
151 
152 #define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
153 {					    \
154 	.type = OPTION_CALLBACK,	    \
155 	.short_name = (s),		    \
156 	.long_name = (l),		    \
157 	.value = (v),			    \
158 	(a),				    \
159 	.help = (h),			    \
160 	.callback = (f),		    \
161 	.flags = PARSE_OPT_NOARG	    \
162 }
163 
164 #define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
165 {					    \
166 	.type = OPTION_CALLBACK,	    \
167 	.short_name = (s),		    \
168 	.long_name = (l),		    \
169 	.value = (v), (a),		    \
170 	.help = (h),			    \
171 	.callback = (f),		    \
172 	.defval = (intptr_t)d,		    \
173 	.flags = PARSE_OPT_LASTARG_DEFAULT  \
174 }
175 
176 #define OPT_END() { .type = OPTION_END }
177 
178 enum {
179 	PARSE_OPT_HELP = -1,
180 	PARSE_OPT_DONE,
181 	PARSE_OPT_UNKNOWN,
182 };
183 
184 /*
185  * It's okay for the caller to consume argv/argc in the usual way.
186  * Other fields of that structure are private to parse-options and should not
187  * be modified in any way.
188  **/
189 struct parse_opt_ctx_t {
190 	const char **argv;
191 	const char **out;
192 	int argc, cpidx;
193 	const char *opt;
194 	int flags;
195 };
196 
197 /* global functions */
198 void usage_with_options(const char * const *usagestr,
199 		const struct option *opts);
200 int parse_options(int argc, const char **argv, const struct option *options,
201 		const char * const usagestr[], int flags);
202 #endif
203