add isl_dim_offset
[isl.git] / isl_arg.c
blobf7237e40d09454020b30714ecdbdaaf50ae2c03f
1 /*
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
8 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include "isl_arg.h"
15 #include <isl_ctx.h>
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);
31 if (child)
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)
39 int i;
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;
56 static void print_arg_help(struct isl_arg *decl, const char *prefix)
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);
67 static void print_choice_help(struct isl_arg *decl, const char *prefix)
69 int i;
71 print_arg_help(decl, prefix);
72 printf("=");
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);
80 printf("\n");
83 static void print_bool_help(struct isl_arg *decl, const char *prefix)
85 print_arg_help(decl, prefix);
86 printf("\n");
89 static void print_help(struct isl_arg *arg, const char *prefix)
91 int i;
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;
104 for (i = 0; arg[i].type != isl_arg_end; ++i) {
105 if (arg[i].type != isl_arg_child)
106 continue;
108 printf("\n");
109 print_help(arg[i].u.child.child, arg[i].long_name);
113 static void print_help_and_exit(struct isl_arg *arg, const char *prog)
115 const char *slash;
117 slash = strrchr(prog, '/');
118 if (slash)
119 printf("Usage: %s [OPTION...]\n\n", slash + 1);
121 print_help(arg, NULL);
123 exit(0);
126 static int parse_choice_option(struct isl_arg *decl, const char *arg,
127 const char *prefix, void *opt)
129 int i;
130 const char *equal;
131 const char *name;
133 if (strncmp(arg, "--", 2))
134 return 0;
136 name = arg + 2;
137 equal = strchr(name, '=');
138 if (!equal)
139 return 0;
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;
148 if (strncmp(name, decl->long_name, equal - name))
149 return 0;
151 for (i = 0; decl->u.choice.choice[i].name; ++i) {
152 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
153 continue;
155 *(unsigned *)(((char *)opt) + decl->offset) =
156 decl->u.choice.choice[i].value;
158 return 1;
161 return 0;
164 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
166 int i;
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;
173 return 1;
176 return 0;
179 static int parse_option(struct isl_arg *decl, const char *arg,
180 const char *prefix, void *opt);
182 static int parse_child_option(struct isl_arg *decl, const char *arg, void *opt)
184 return parse_option(decl->u.child.child, arg, decl->long_name,
185 *(void **)(((char *)opt) + decl->offset));
188 static int parse_option(struct isl_arg *decl, const char *arg,
189 const char *prefix, void *opt)
191 int i;
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;
210 return 0;
213 static int drop_argument(int argc, char **argv, int drop)
215 for (; drop < argc; ++drop)
216 argv[drop] = argv[drop + 1];
218 return argc - 1;
221 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt,
222 unsigned flags)
224 int skip = 0;
225 int i;
227 for (i = 1; i < argc; ++i) {
228 if (strcmp(argv[i], "--help") == 0)
229 print_help_and_exit(arg, argv[0]);
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;
243 return argc;