isl_convex_hull.c: modulo_affine_hull: drop redundant argument
[platform/upstream/isl.git] / isl_arg.c
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 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "isl_arg.h"
15 #include <isl_ctx.h>
16
17 static void set_default_choice(struct isl_arg *arg, void *opt)
18 {
19         *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value;
20 }
21
22 static void set_default_bool(struct isl_arg *arg, void *opt)
23 {
24         *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
25 }
26
27 static void set_default_child(struct isl_arg *arg, void *opt)
28 {
29         void *child = calloc(1, arg->u.child.size);
30
31         if (child)
32                 isl_arg_set_defaults(arg->u.child.child, child);
33
34         *(void **)(((char *)opt) + arg->offset) = child;
35 }
36
37 void isl_arg_set_defaults(struct isl_arg *arg, void *opt)
38 {
39         int i;
40
41         for (i = 0; arg[i].type != isl_arg_end; ++i) {
42                 switch (arg[i].type) {
43                 case isl_arg_choice:
44                         set_default_choice(&arg[i], opt);
45                         break;
46                 case isl_arg_bool:
47                         set_default_bool(&arg[i], opt);
48                         break;
49                 case isl_arg_child:
50                         set_default_child(&arg[i], opt);
51                         break;
52                 }
53         }
54 }
55
56 static void print_arg_help(struct isl_arg *decl, const char *prefix)
57 {
58         if (decl->short_name)
59                 printf("  -%c, --", decl->short_name);
60         else
61                 printf("      --");
62         if (prefix)
63                 printf("%s-", prefix);
64         printf("%s", decl->long_name);
65 }
66
67 static void print_choice_help(struct isl_arg *decl, const char *prefix)
68 {
69         int i;
70
71         print_arg_help(decl, prefix);
72         printf("=");
73
74         for (i = 0; decl->u.choice.choice[i].name; ++i) {
75                 if (i)
76                         printf("|");
77                 printf("%s", decl->u.choice.choice[i].name);
78         }
79
80         printf("\n");
81 }
82
83 static void print_bool_help(struct isl_arg *decl, const char *prefix)
84 {
85         print_arg_help(decl, prefix);
86         printf("\n");
87 }
88
89 static void print_help(struct isl_arg *arg, const char *prefix)
90 {
91         int i;
92
93         for (i = 0; arg[i].type != isl_arg_end; ++i) {
94                 switch (arg[i].type) {
95                 case isl_arg_choice:
96                         print_choice_help(&arg[i], prefix);
97                         break;
98                 case isl_arg_bool:
99                         print_bool_help(&arg[i], prefix);
100                         break;
101                 }
102         }
103
104         for (i = 0; arg[i].type != isl_arg_end; ++i) {
105                 if (arg[i].type != isl_arg_child)
106                         continue;
107
108                 printf("\n");
109                 print_help(arg[i].u.child.child, arg[i].long_name);
110         }
111 }
112
113 static void print_help_and_exit(struct isl_arg *arg, const char *prog)
114 {
115         const char *slash;
116
117         slash = strrchr(prog, '/');
118         if (slash)
119                 printf("Usage: %s [OPTION...]\n\n", slash + 1);
120
121         print_help(arg, NULL);
122
123         exit(0);
124 }
125
126 static int parse_choice_option(struct isl_arg *decl, const char *arg,
127         const char *prefix, void *opt)
128 {
129         int i;
130         const char *equal;
131         const char *name;
132
133         if (strncmp(arg, "--", 2))
134                 return 0;
135
136         name = arg + 2;
137         equal = strchr(name, '=');
138         if (!equal)
139                 return 0;
140
141         if (prefix) {
142                 size_t prefix_len = strlen(prefix);
143                 if (strncmp(name, prefix, prefix_len) == 0 &&
144                     name[prefix_len] == '-')
145                         name += prefix_len + 1;
146         }
147
148         if (strncmp(name, decl->long_name, equal - name))
149                 return 0;
150
151         for (i = 0; decl->u.choice.choice[i].name; ++i) {
152                 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
153                         continue;
154
155                 *(unsigned *)(((char *)opt) + decl->offset) =
156                         decl->u.choice.choice[i].value;
157
158                 return 1;
159         }
160
161         return 0;
162 }
163
164 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
165 {
166         int i;
167
168         if ((arg[0] == '-' && arg[1] == decl->short_name && arg[2] == '\0') ||
169             (strncmp(arg, "--", 2) == 0 &&
170              strcmp(arg + 2, decl->long_name) == 0)) {
171                 *(unsigned *)(((char *)opt) + decl->offset) = 1;
172
173                 return 1;
174         }
175
176         return 0;
177 }
178
179 static int parse_option(struct isl_arg *decl, const char *arg,
180         const char *prefix, void *opt);
181
182 static int parse_child_option(struct isl_arg *decl, const char *arg, void *opt)
183 {
184         return parse_option(decl->u.child.child, arg, decl->long_name,
185                                 *(void **)(((char *)opt) + decl->offset));
186 }
187
188 static int parse_option(struct isl_arg *decl, const char *arg,
189         const char *prefix, void *opt)
190 {
191         int i;
192
193         for (i = 0; decl[i].type != isl_arg_end; ++i) {
194                 switch (decl[i].type) {
195                 case isl_arg_choice:
196                         if (parse_choice_option(&decl[i], arg, prefix, opt))
197                                 return 1;
198                         break;
199                 case isl_arg_bool:
200                         if (parse_bool_option(&decl[i], arg, opt))
201                                 return 1;
202                         break;
203                 case isl_arg_child:
204                         if (parse_child_option(&decl[i], arg, opt))
205                                 return 1;
206                         break;
207                 }
208         }
209
210         return 0;
211 }
212
213 static int drop_argument(int argc, char **argv, int drop)
214 {
215         for (; drop < argc; ++drop)
216                 argv[drop] = argv[drop + 1];
217
218         return argc - 1;
219 }
220
221 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt,
222         unsigned flags)
223 {
224         int skip = 0;
225         int i;
226
227         for (i = 1; i < argc; ++i) {
228                 if (strcmp(argv[i], "--help") == 0)
229                         print_help_and_exit(arg, argv[0]);
230         }
231
232         while (argc > 1 + skip) {
233                 if (parse_option(arg, argv[1 + skip], NULL, opt))
234                         argc = drop_argument(argc, argv, 1 + skip);
235                 else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) {
236                         fprintf(stderr, "unrecognized option: %s\n",
237                                         argv[1 + skip]);
238                         exit(-1);
239                 } else
240                         ++skip;
241         }
242
243         return argc;
244 }