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