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