2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the GNU LGPLv2.1 license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
17 static void set_default_choice(struct isl_arg *arg, void *opt)
19 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value;
22 static void set_default_bool(struct isl_arg *arg, void *opt)
24 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
27 static void set_default_child(struct isl_arg *arg, void *opt)
29 void *child = calloc(1, arg->u.child.size);
32 isl_arg_set_defaults(arg->u.child.child, child);
34 *(void **)(((char *)opt) + arg->offset) = child;
37 void isl_arg_set_defaults(struct isl_arg *arg, void *opt)
41 for (i = 0; arg[i].type != isl_arg_end; ++i) {
42 switch (arg[i].type) {
44 set_default_choice(&arg[i], opt);
47 set_default_bool(&arg[i], opt);
50 set_default_child(&arg[i], opt);
56 static int print_arg_help(struct isl_arg *decl, const char *prefix)
61 printf(" -%c, --", decl->short_name);
67 printf("%s-", prefix);
68 len += strlen(prefix) + 1;
70 printf("%s", decl->long_name);
71 len += strlen(decl->long_name);
76 const void *isl_memrchr(const void *s, int c, size_t n)
85 static int print_help_msg(struct isl_arg *decl, int pos)
96 printf("%*s", 30 - pos, "");
101 const char *space = isl_memrchr(s, ' ', 45);
105 space = strchr(s + 45, ' ');
109 printf("%.*s", l, s);
112 printf("\n%30s", "");
119 static void print_default_choice(struct isl_arg *decl, int pos)
122 const char *default_prefix = "[default: ";
123 const char *default_suffix = "]";
124 const char *s = "none";
125 int len = strlen(default_prefix) + strlen(s) + strlen(default_suffix);
127 for (i = 0; decl->u.choice.choice[i].name; ++i)
128 if (decl->u.choice.choice[i].value == decl->u.choice.default_value) {
129 s = decl->u.choice.choice[i].name;
133 if (!decl->help_msg) {
135 printf("\n%30s", "");
137 printf("%*s", 30 - pos, "");
141 if (pos && pos + len >= 48)
142 printf("\n%30s", "");
145 printf("%s%s%s", default_prefix, s, default_suffix);
148 static void print_choice_help(struct isl_arg *decl, const char *prefix)
153 pos = print_arg_help(decl, prefix);
157 for (i = 0; decl->u.choice.choice[i].name; ++i) {
162 printf("%s", decl->u.choice.choice[i].name);
163 pos += strlen(decl->u.choice.choice[i].name);
166 pos = print_help_msg(decl, pos);
167 print_default_choice(decl, pos);
172 static void print_bool_help(struct isl_arg *decl, const char *prefix)
175 pos = print_arg_help(decl, prefix);
176 print_help_msg(decl, pos);
180 static void print_help(struct isl_arg *arg, const char *prefix)
184 for (i = 0; arg[i].type != isl_arg_end; ++i) {
185 switch (arg[i].type) {
187 print_choice_help(&arg[i], prefix);
190 print_bool_help(&arg[i], prefix);
195 for (i = 0; arg[i].type != isl_arg_end; ++i) {
196 if (arg[i].type != isl_arg_child)
200 print_help(arg[i].u.child.child, arg[i].long_name);
204 static void print_help_and_exit(struct isl_arg *arg, const char *prog)
208 slash = strrchr(prog, '/');
210 printf("Usage: %s [OPTION...]\n\n", slash + 1);
212 print_help(arg, NULL);
217 static int parse_choice_option(struct isl_arg *decl, const char *arg,
218 const char *prefix, void *opt)
224 if (strncmp(arg, "--", 2))
228 equal = strchr(name, '=');
233 size_t prefix_len = strlen(prefix);
234 if (strncmp(name, prefix, prefix_len) == 0 &&
235 name[prefix_len] == '-')
236 name += prefix_len + 1;
239 if (strncmp(name, decl->long_name, equal - name))
242 for (i = 0; decl->u.choice.choice[i].name; ++i) {
243 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
246 *(unsigned *)(((char *)opt) + decl->offset) =
247 decl->u.choice.choice[i].value;
255 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
259 if ((arg[0] == '-' && arg[1] == decl->short_name && arg[2] == '\0') ||
260 (strncmp(arg, "--", 2) == 0 &&
261 strcmp(arg + 2, decl->long_name) == 0)) {
262 *(unsigned *)(((char *)opt) + decl->offset) = 1;
270 static int parse_option(struct isl_arg *decl, const char *arg,
271 const char *prefix, void *opt);
273 static int parse_child_option(struct isl_arg *decl, const char *arg, void *opt)
275 return parse_option(decl->u.child.child, arg, decl->long_name,
276 *(void **)(((char *)opt) + decl->offset));
279 static int parse_option(struct isl_arg *decl, const char *arg,
280 const char *prefix, void *opt)
284 for (i = 0; decl[i].type != isl_arg_end; ++i) {
285 switch (decl[i].type) {
287 if (parse_choice_option(&decl[i], arg, prefix, opt))
291 if (parse_bool_option(&decl[i], arg, opt))
295 if (parse_child_option(&decl[i], arg, opt))
304 static int drop_argument(int argc, char **argv, int drop)
306 for (; drop < argc; ++drop)
307 argv[drop] = argv[drop + 1];
312 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt,
318 for (i = 1; i < argc; ++i) {
319 if (strcmp(argv[i], "--help") == 0)
320 print_help_and_exit(arg, argv[0]);
323 while (argc > 1 + skip) {
324 if (parse_option(arg, argv[1 + skip], NULL, opt))
325 argc = drop_argument(argc, argv, 1 + skip);
326 else if (ISL_FL_ISSET(flags, ISL_ARG_ALL)) {
327 fprintf(stderr, "unrecognized option: %s\n",