introduce isl_args structure that constains isl_arg list and size of options
[platform/upstream/isl.git] / include / isl / arg.h
1 /*
2  * Copyright 2008-2009 Katholieke Universiteit Leuven
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 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_version
46 };
47
48 struct isl_args;
49
50 struct isl_arg {
51         enum isl_arg_type        type;
52         char                     short_name;
53         const char              *long_name;
54         const char              *argument_name;
55         size_t                   offset;
56         const char              *help_msg;
57 #define ISL_ARG_SINGLE_DASH     (1 << 0)
58 #define ISL_ARG_BOOL_ARG        (1 << 1)
59 #define ISL_ARG_HIDDEN          (1 << 2)
60         unsigned                 flags;
61         union {
62         struct {
63                 struct isl_arg_choice   *choice;
64                 unsigned                 default_value;
65                 unsigned                 default_selected;
66                 int (*set)(void *opt, unsigned val);
67         } choice;
68         struct {
69                 struct isl_arg_flags    *flags;
70                 unsigned                 default_value;
71         } flags;
72         struct {
73                 unsigned                 default_value;
74                 int (*set)(void *opt, unsigned val);
75         } b;
76         struct {
77                 int                     default_value;
78         } i;
79         struct {
80                 long                    default_value;
81                 long                    default_selected;
82                 int (*set)(void *opt, long val);
83         } l;
84         struct {
85                 unsigned long           default_value;
86         } ul;
87         struct {
88                 const char              *default_value;
89         } str;
90         struct {
91                 struct isl_args         *child;
92         } child;
93         struct {
94                 void (*print_version)(void);
95         } version;
96         struct {
97                 int (*init)(void*);
98                 void (*clear)(void*);
99         } user;
100         } u;
101 };
102
103 struct isl_args {
104         size_t                   options_size;
105         struct isl_arg          *args;
106 };
107
108 #define ISL_ARGS_START(s,name)                                          \
109         struct isl_arg name ## LIST[];                                  \
110         struct isl_args name = { sizeof(s), name ## LIST };             \
111         struct isl_arg name ## LIST[] = {
112 #define ISL_ARGS_END                                                    \
113         { isl_arg_end } };
114
115 #define ISL_ARG_ALIAS(l)        {                                       \
116         .type = isl_arg_alias,                                          \
117         .long_name = l,                                                 \
118 },
119 #define ISL_ARG_ARG(st,f,a,d)   {                                       \
120         .type = isl_arg_arg,                                            \
121         .argument_name = a,                                             \
122         .offset = offsetof(st, f),                                      \
123         .u = { .str = { .default_value = d } }                          \
124 },
125 #define ISL_ARG_FOOTER(h)       {                                       \
126         .type = isl_arg_footer,                                         \
127         .help_msg = h,                                                  \
128 },
129 #define ISL_ARG_CHOICE(st,f,s,l,c,d,h)  {                               \
130         .type = isl_arg_choice,                                         \
131         .short_name = s,                                                \
132         .long_name = l,                                                 \
133         .offset = offsetof(st, f),                                      \
134         .help_msg = h,                                                  \
135         .u = { .choice = { .choice = c, .default_value = d,             \
136                             .default_selected = d, .set = NULL } }      \
137 },
138 #define ISL_ARG_OPT_CHOICE(st,f,s,l,c,d,ds,h)   {                       \
139         .type = isl_arg_choice,                                         \
140         .short_name = s,                                                \
141         .long_name = l,                                                 \
142         .offset = offsetof(st, f),                                      \
143         .help_msg = h,                                                  \
144         .u = { .choice = { .choice = c, .default_value = d,             \
145                             .default_selected = ds, .set = NULL } }     \
146 },
147 #define ISL_ARG_USER_OPT_CHOICE(st,f,s,l,c,setter,d,ds,h)       {       \
148         .type = isl_arg_choice,                                         \
149         .short_name = s,                                                \
150         .long_name = l,                                                 \
151         .offset = offsetof(st, f),                                      \
152         .help_msg = h,                                                  \
153         .u = { .choice = { .choice = c, .default_value = d,             \
154                             .default_selected = ds, .set = setter } }   \
155 },
156 #define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl)    {                       \
157         .type = isl_arg_bool,                                           \
158         .short_name = s,                                                \
159         .long_name = l,                                                 \
160         .offset = o,                                                    \
161         .help_msg = h,                                                  \
162         .flags = fl,                                                    \
163         .u = { .b = { .default_value = d, .set = setter } }             \
164 },
165 #define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl)                                 \
166         _ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl)
167 #define ISL_ARG_BOOL(st,f,s,l,d,h)                                      \
168         ISL_ARG_BOOL_F(st,f,s,l,d,h,0)
169 #define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl)                         \
170         _ISL_ARG_BOOL_F(-1,s,l,setter,0,h,fl)
171 #define ISL_ARG_PHANTOM_BOOL(s,l,setter,h)                              \
172         ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0)
173 #define ISL_ARG_INT_F(st,f,s,l,a,d,h,fl)        {                       \
174         .type = isl_arg_int,                                            \
175         .short_name = s,                                                \
176         .long_name = l,                                                 \
177         .argument_name = a,                                             \
178         .offset = offsetof(st, f),                                      \
179         .help_msg = h,                                                  \
180         .flags = fl,                                                    \
181         .u = { .ul = { .default_value = d } }                           \
182 },
183 #define ISL_ARG_INT(st,f,s,l,a,d,h)                                     \
184         ISL_ARG_INT_F(st,f,s,l,a,d,h,0)
185 #define ISL_ARG_LONG(st,f,s,lo,d,h)     {                               \
186         .type = isl_arg_long,                                           \
187         .short_name = s,                                                \
188         .long_name = lo,                                                \
189         .offset = offsetof(st, f),                                      \
190         .help_msg = h,                                                  \
191         .u = { .l = { .default_value = d, .default_selected = d,        \
192                       .set = NULL } }                                   \
193 },
194 #define ISL_ARG_USER_LONG(st,f,s,lo,setter,d,h) {                       \
195         .type = isl_arg_long,                                           \
196         .short_name = s,                                                \
197         .long_name = lo,                                                \
198         .offset = offsetof(st, f),                                      \
199         .help_msg = h,                                                  \
200         .u = { .l = { .default_value = d, .default_selected = d,        \
201                       .set = setter } }                                 \
202 },
203 #define ISL_ARG_OPT_LONG(st,f,s,lo,d,ds,h)      {                       \
204         .type = isl_arg_long,                                           \
205         .short_name = s,                                                \
206         .long_name = lo,                                                \
207         .offset = offsetof(st, f),                                      \
208         .help_msg = h,                                                  \
209         .u = { .l = { .default_value = d, .default_selected = ds,       \
210                       .set = NULL } }                                   \
211 },
212 #define ISL_ARG_ULONG(st,f,s,l,d,h)     {                               \
213         .type = isl_arg_ulong,                                          \
214         .short_name = s,                                                \
215         .long_name = l,                                                 \
216         .offset = offsetof(st, f),                                      \
217         .help_msg = h,                                                  \
218         .u = { .ul = { .default_value = d } }                           \
219 },
220 #define ISL_ARG_STR_F(st,f,s,l,a,d,h,fl)        {                       \
221         .type = isl_arg_str,                                            \
222         .short_name = s,                                                \
223         .long_name = l,                                                 \
224         .argument_name = a,                                             \
225         .offset = offsetof(st, f),                                      \
226         .help_msg = h,                                                  \
227         .flags = fl,                                                    \
228         .u = { .str = { .default_value = d } }                          \
229 },
230 #define ISL_ARG_STR(st,f,s,l,a,d,h)                                     \
231         ISL_ARG_STR_F(st,f,s,l,a,d,h,0)
232 #define _ISL_ARG_CHILD(o,l,c,h,fl)      {                               \
233         .type = isl_arg_child,                                          \
234         .long_name = l,                                                 \
235         .offset = o,                                                    \
236         .help_msg = h,                                                  \
237         .flags = fl,                                                    \
238         .u = { .child = { .child = c } }                                \
239 },
240 #define ISL_ARG_CHILD(st,f,l,c,h)                                       \
241         _ISL_ARG_CHILD(offsetof(st, f),l,c,h,0)
242 #define ISL_ARG_GROUP_F(c,h,fl)                                         \
243         _ISL_ARG_CHILD(-1,NULL,c,h,fl)
244 #define ISL_ARG_GROUP(c,h)                                              \
245         ISL_ARG_GROUP_F(c,h,0)
246 #define ISL_ARG_FLAGS(st,f,s,l,c,d,h)   {                               \
247         .type = isl_arg_flags,                                          \
248         .short_name = s,                                                \
249         .long_name = l,                                                 \
250         .offset = offsetof(st, f),                                      \
251         .help_msg = h,                                                  \
252         .u = { .flags = { .flags = c, .default_value = d } }            \
253 },
254 #define ISL_ARG_USER(st,f,i,c) {                                        \
255         .type = isl_arg_user,                                           \
256         .offset = offsetof(st, f),                                      \
257         .u = { .user = { .init = i, .clear = c} }                       \
258 },
259 #define ISL_ARG_VERSION(print) {                                        \
260         .type = isl_arg_version,                                        \
261         .u = { .version = { .print_version = print } }                  \
262 },
263
264 #define ISL_ARG_ALL     (1 << 0)
265
266 void isl_args_set_defaults(struct isl_args *args, void *opt);
267 void isl_args_free(struct isl_args *args, void *opt);
268 int isl_args_parse(struct isl_args *args, int argc, char **argv, void *opt,
269         unsigned flags);
270
271 #define ISL_ARG_DECL(prefix,st,args)                                    \
272 extern struct isl_args args;                                            \
273 st *prefix ## _new_with_defaults(void);                                 \
274 void prefix ## _free(st *opt);                                          \
275 int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags);
276
277 #define ISL_ARG_DEF(prefix,st,args)                                     \
278 st *prefix ## _new_with_defaults()                                      \
279 {                                                                       \
280         st *opt = (st *)calloc(1, sizeof(st));                          \
281         if (opt)                                                        \
282                 isl_args_set_defaults(&(args), opt);                    \
283         return opt;                                                     \
284 }                                                                       \
285                                                                         \
286 void prefix ## _free(st *opt)                                           \
287 {                                                                       \
288         isl_args_free(&(args), opt);                                    \
289 }                                                                       \
290                                                                         \
291 int prefix ## _parse(st *opt, int argc, char **argv, unsigned flags)    \
292 {                                                                       \
293         return isl_args_parse(&(args), argc, argv, opt, flags);         \
294 }
295
296 #if defined(__cplusplus)
297 }
298 #endif
299
300 #endif