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