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