Merge branch 'maint'
[isl.git] / include / isl / arg.h
blob0d37d1cab264bb9cb34ca30a82a683a8d3babc2a
1 /*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8 */
10 #ifndef ISL_ARG_H
11 #define ISL_ARG_H
13 #include <stddef.h>
14 #include <stdlib.h>
16 #if defined(__cplusplus)
17 extern "C" {
18 #endif
20 struct isl_arg_choice {
21 const char *name;
22 unsigned value;
25 struct isl_arg_flags {
26 const char *name;
27 unsigned mask;
28 unsigned value;
31 enum isl_arg_type {
32 isl_arg_end,
33 isl_arg_alias,
34 isl_arg_arg,
35 isl_arg_bool,
36 isl_arg_child,
37 isl_arg_choice,
38 isl_arg_flags,
39 isl_arg_footer,
40 isl_arg_int,
41 isl_arg_user,
42 isl_arg_long,
43 isl_arg_ulong,
44 isl_arg_str,
45 isl_arg_str_list,
46 isl_arg_version
49 struct isl_args;
51 struct isl_arg {
52 enum isl_arg_type type;
53 char short_name;
54 const char *long_name;
55 const char *argument_name;
56 size_t offset;
57 const char *help_msg;
58 #define ISL_ARG_SINGLE_DASH (1 << 0)
59 #define ISL_ARG_BOOL_ARG (1 << 1)
60 #define ISL_ARG_HIDDEN (1 << 2)
61 unsigned flags;
62 union {
63 struct {
64 struct isl_arg_choice *choice;
65 unsigned default_value;
66 unsigned default_selected;
67 int (*set)(void *opt, unsigned val);
68 } choice;
69 struct {
70 struct isl_arg_flags *flags;
71 unsigned default_value;
72 } flags;
73 struct {
74 unsigned default_value;
75 int (*set)(void *opt, unsigned val);
76 } b;
77 struct {
78 int default_value;
79 } i;
80 struct {
81 long default_value;
82 long default_selected;
83 int (*set)(void *opt, long val);
84 } l;
85 struct {
86 unsigned long default_value;
87 } ul;
88 struct {
89 const char *default_value;
90 } str;
91 struct {
92 size_t offset_n;
93 } str_list;
94 struct {
95 struct isl_args *child;
96 } child;
97 struct {
98 void (*print_version)(void);
99 } version;
100 struct {
101 int (*init)(void*);
102 void (*clear)(void*);
103 } user;
104 } u;
107 struct isl_args {
108 size_t options_size;
109 struct isl_arg *args;
112 #define ISL_ARGS_START(s,name) \
113 struct isl_arg name ## LIST[]; \
114 struct isl_args name = { sizeof(s), name ## LIST }; \
115 struct isl_arg name ## LIST[] = {
116 #define ISL_ARGS_END \
117 { isl_arg_end } };
119 #define ISL_ARG_ALIAS(l) { \
120 .type = isl_arg_alias, \
121 .long_name = l, \
123 #define ISL_ARG_ARG(st,f,a,d) { \
124 .type = isl_arg_arg, \
125 .argument_name = a, \
126 .offset = offsetof(st, f), \
127 .u = { .str = { .default_value = d } } \
129 #define ISL_ARG_FOOTER(h) { \
130 .type = isl_arg_footer, \
131 .help_msg = h, \
133 #define ISL_ARG_CHOICE(st,f,s,l,c,d,h) { \
134 .type = isl_arg_choice, \
135 .short_name = s, \
136 .long_name = l, \
137 .offset = offsetof(st, f), \
138 .help_msg = h, \
139 .u = { .choice = { .choice = c, .default_value = d, \
140 .default_selected = d, .set = NULL } } \
142 #define ISL_ARG_OPT_CHOICE(st,f,s,l,c,d,ds,h) { \
143 .type = isl_arg_choice, \
144 .short_name = s, \
145 .long_name = l, \
146 .offset = offsetof(st, f), \
147 .help_msg = h, \
148 .u = { .choice = { .choice = c, .default_value = d, \
149 .default_selected = ds, .set = NULL } } \
151 #define ISL_ARG_PHANTOM_USER_CHOICE_F(s,l,c,setter,d,h,fl) { \
152 .type = isl_arg_choice, \
153 .short_name = s, \
154 .long_name = l, \
155 .offset = -1, \
156 .help_msg = h, \
157 .flags = fl, \
158 .u = { .choice = { .choice = c, .default_value = d, \
159 .default_selected = d, .set = setter } } \
161 #define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h) { \
162 .type = isl_arg_choice, \
163 .short_name = s, \
164 .long_name = l, \
165 .offset = offsetof(st, f), \
166 .help_msg = h, \
167 .u = { .choice = { .choice = c, .default_value = d, \
168 .default_selected = ds, .set = setter } } \
170 #define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl) { \
171 .type = isl_arg_bool, \
172 .short_name = s, \
173 .long_name = l, \
174 .offset = o, \
175 .help_msg = h, \
176 .flags = fl, \
177 .u = { .b = { .default_value = d, .set = setter } } \
179 #define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl) \
180 _ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl)
181 #define ISL_ARG_BOOL(st,f,s,l,d,h) \
182 ISL_ARG_BOOL_F(st,f,s,l,d,h,0)
183 #define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl) \
184 _ISL_ARG_BOOL_F(-1,s,l,setter,0,h,fl)
185 #define ISL_ARG_PHANTOM_BOOL(s,l,setter,h) \
186 ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0)
187 #define ISL_ARG_INT_F(st,f,s,l,a,d,h,fl) { \
188 .type = isl_arg_int, \
189 .short_name = s, \
190 .long_name = l, \
191 .argument_name = a, \
192 .offset = offsetof(st, f), \
193 .help_msg = h, \
194 .flags = fl, \
195 .u = { .ul = { .default_value = d } } \
197 #define ISL_ARG_INT(st,f,s,l,a,d,h) \
198 ISL_ARG_INT_F(st,f,s,l,a,d,h,0)
199 #define ISL_ARG_LONG(st,f,s,lo,d,h) { \
200 .type = isl_arg_long, \
201 .short_name = s, \
202 .long_name = lo, \
203 .offset = offsetof(st, f), \
204 .help_msg = h, \
205 .u = { .l = { .default_value = d, .default_selected = d, \
206 .set = NULL } } \
208 #define ISL_ARG_USER_LONG(st,f,s,lo,setter,d,h) { \
209 .type = isl_arg_long, \
210 .short_name = s, \
211 .long_name = lo, \
212 .offset = offsetof(st, f), \
213 .help_msg = h, \
214 .u = { .l = { .default_value = d, .default_selected = d, \
215 .set = setter } } \
217 #define ISL_ARG_OPT_LONG(st,f,s,lo,d,ds,h) { \
218 .type = isl_arg_long, \
219 .short_name = s, \
220 .long_name = lo, \
221 .offset = offsetof(st, f), \
222 .help_msg = h, \
223 .u = { .l = { .default_value = d, .default_selected = ds, \
224 .set = NULL } } \
226 #define ISL_ARG_ULONG(st,f,s,l,d,h) { \
227 .type = isl_arg_ulong, \
228 .short_name = s, \
229 .long_name = l, \
230 .offset = offsetof(st, f), \
231 .help_msg = h, \
232 .u = { .ul = { .default_value = d } } \
234 #define ISL_ARG_STR_F(st,f,s,l,a,d,h,fl) { \
235 .type = isl_arg_str, \
236 .short_name = s, \
237 .long_name = l, \
238 .argument_name = a, \
239 .offset = offsetof(st, f), \
240 .help_msg = h, \
241 .flags = fl, \
242 .u = { .str = { .default_value = d } } \
244 #define ISL_ARG_STR(st,f,s,l,a,d,h) \
245 ISL_ARG_STR_F(st,f,s,l,a,d,h,0)
246 #define ISL_ARG_STR_LIST(st,f_n,f_l,s,l,a,h) { \
247 .type = isl_arg_str_list, \
248 .short_name = s, \
249 .long_name = l, \
250 .argument_name = a, \
251 .offset = offsetof(st, f_l), \
252 .help_msg = h, \
253 .u = { .str_list = { .offset_n = offsetof(st, f_n) } } \
255 #define _ISL_ARG_CHILD(o,l,c,h,fl) { \
256 .type = isl_arg_child, \
257 .long_name = l, \
258 .offset = o, \
259 .help_msg = h, \
260 .flags = fl, \
261 .u = { .child = { .child = c } } \
263 #define ISL_ARG_CHILD(st,f,l,c,h) \
264 _ISL_ARG_CHILD(offsetof(st, f),l,c,h,0)
265 #define ISL_ARG_GROUP_F(l,c,h,fl) \
266 _ISL_ARG_CHILD(-1,l,c,h,fl)
267 #define ISL_ARG_GROUP(l,c,h) \
268 ISL_ARG_GROUP_F(l,c,h,0)
269 #define ISL_ARG_FLAGS(st,f,s,l,c,d,h) { \
270 .type = isl_arg_flags, \
271 .short_name = s, \
272 .long_name = l, \
273 .offset = offsetof(st, f), \
274 .help_msg = h, \
275 .u = { .flags = { .flags = c, .default_value = d } } \
277 #define ISL_ARG_USER(st,f,i,c) { \
278 .type = isl_arg_user, \
279 .offset = offsetof(st, f), \
280 .u = { .user = { .init = i, .clear = c} } \
282 #define ISL_ARG_VERSION(print) { \
283 .type = isl_arg_version, \
284 .u = { .version = { .print_version = print } } \
287 #define ISL_ARG_ALL (1 << 0)
288 #define ISL_ARG_SKIP_HELP (1 << 1)
290 void isl_args_set_defaults(struct isl_args *args, void *opt);
291 void isl_args_free(struct isl_args *args, void *opt);
292 int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
293 unsigned flags);
295 #define ISL_ARG_DECL(prefix,st,args) \
296 extern struct isl_args args; \
297 st *prefix ## _new_with_defaults(void); \
298 void prefix ## _free(st *opt); \
299 int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags);
301 #define ISL_ARG_DEF(prefix,st,args) \
302 st *prefix ## _new_with_defaults() \
304 st *opt = (st *)calloc(1, sizeof(st)); \
305 if (opt) \
306 isl_args_set_defaults(&(args), opt); \
307 return opt; \
310 void prefix ## _free(st *opt) \
312 isl_args_free(&(args), opt); \
315 int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags) \
317 return isl_args_parse(&(args), argc, argv, opt, flags); \
320 #if defined(__cplusplus)
322 #endif
324 #endif