xref: /kvmtool/include/kvm/parse-options.h (revision 80ac1d059f2bdf60ea34c303bb918ce3e8dc877f)
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_INCR(s, l, v, h)                \
136 {                                           \
137 	.type = OPTION_INCR,	            \
138 	.short_name = (s),                  \
139 	.long_name = (l),                   \
140 	.value = check_vtype(v, int *),     \
141 	.help = (h)                         \
142 }
143 
144 #define OPT_GROUP(h)                        \
145 {                                           \
146 	.type = OPTION_GROUP,               \
147 	.help = (h)                         \
148 }
149 
150 #define OPT_CALLBACK(s, l, v, a, h, f)      \
151 {					    \
152 	.type = OPTION_CALLBACK,	    \
153 	.short_name = (s),		    \
154 	.long_name = (l),		    \
155 	.value = (v),			    \
156 	(a),				    \
157 	.help = (h),			    \
158 	.callback = (f)			    \
159 }
160 
161 #define OPT_CALLBACK_NOOPT(s, l, v, a, h, f) \
162 {					    \
163 	.type = OPTION_CALLBACK,	    \
164 	.short_name = (s),		    \
165 	.long_name = (l),		    \
166 	.value = (v),			    \
167 	(a),				    \
168 	.help = (h),			    \
169 	.callback = (f),		    \
170 	.flags = PARSE_OPT_NOARG	    \
171 }
172 
173 #define OPT_CALLBACK_DEFAULT(s, l, v, a, h, f, d) \
174 {					    \
175 	.type = OPTION_CALLBACK,	    \
176 	.short_name = (s),		    \
177 	.long_name = (l),		    \
178 	.value = (v), (a),		    \
179 	.help = (h),			    \
180 	.callback = (f),		    \
181 	.defval = (intptr_t)d,		    \
182 	.flags = PARSE_OPT_LASTARG_DEFAULT  \
183 }
184 
185 #define OPT_END() { .type = OPTION_END }
186 
187 enum {
188 	PARSE_OPT_HELP = -1,
189 	PARSE_OPT_DONE,
190 	PARSE_OPT_UNKNOWN,
191 };
192 
193 /*
194  * It's okay for the caller to consume argv/argc in the usual way.
195  * Other fields of that structure are private to parse-options and should not
196  * be modified in any way.
197  **/
198 struct parse_opt_ctx_t {
199 	const char **argv;
200 	const char **out;
201 	int argc, cpidx;
202 	const char *opt;
203 	int flags;
204 };
205 
206 /* global functions */
207 void usage_with_options(const char * const *usagestr,
208 		const struct option *opts);
209 int parse_options(int argc, const char **argv, const struct option *options,
210 		const char * const usagestr[], int flags);
211 #endif
212