add isl_printer
[isl.git] / isl_arg.c
blob3db185ea7371059679a867e213229600c301b77a
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"
16 static void set_default_choice(struct isl_arg *arg, void *opt)
18 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value;
21 static void set_default_bool(struct isl_arg *arg, void *opt)
23 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
26 static void set_default_child(struct isl_arg *arg, void *opt)
28 void *child = calloc(1, arg->u.child.size);
30 if (child)
31 isl_arg_set_defaults(arg->u.child.child, child);
33 *(void **)(((char *)opt) + arg->offset) = child;
36 void isl_arg_set_defaults(struct isl_arg *arg, void *opt)
38 int i;
40 for (i = 0; arg[i].type != isl_arg_end; ++i) {
41 switch (arg[i].type) {
42 case isl_arg_choice:
43 set_default_choice(&arg[i], opt);
44 break;
45 case isl_arg_bool:
46 set_default_bool(&arg[i], opt);
47 break;
48 case isl_arg_child:
49 set_default_child(&arg[i], opt);
50 break;
55 static void print_arg_help(struct isl_arg *decl, const char *prefix)
57 if (decl->short_name)
58 printf(" -%c, --", decl->short_name);
59 else
60 printf(" --");
61 if (prefix)
62 printf("%s-", prefix);
63 printf("%s", decl->long_name);
66 static void print_choice_help(struct isl_arg *decl, const char *prefix)
68 int i;
70 print_arg_help(decl, prefix);
71 printf("=");
73 for (i = 0; decl->u.choice.choice[i].name; ++i) {
74 if (i)
75 printf("|");
76 printf("%s", decl->u.choice.choice[i].name);
79 printf("\n");
82 static void print_bool_help(struct isl_arg *decl, const char *prefix)
84 print_arg_help(decl, prefix);
85 printf("\n");
88 static void print_help(struct isl_arg *arg, const char *prefix)
90 int i;
92 for (i = 0; arg[i].type != isl_arg_end; ++i) {
93 switch (arg[i].type) {
94 case isl_arg_choice:
95 print_choice_help(&arg[i], prefix);
96 break;
97 case isl_arg_bool:
98 print_bool_help(&arg[i], prefix);
99 break;
103 for (i = 0; arg[i].type != isl_arg_end; ++i) {
104 if (arg[i].type != isl_arg_child)
105 continue;
107 printf("\n");
108 print_help(arg[i].u.child.child, arg[i].long_name);
112 static void print_help_and_exit(struct isl_arg *arg, const char *prog)
114 const char *slash;
116 slash = strrchr(prog, '/');
117 if (slash)
118 printf("Usage: %s [OPTION...]\n\n", slash + 1);
120 print_help(arg, NULL);
122 exit(0);
125 static int parse_choice_option(struct isl_arg *decl, const char *arg,
126 const char *prefix, void *opt)
128 int i;
129 const char *equal;
130 const char *name;
132 if (strncmp(arg, "--", 2))
133 return 0;
135 name = arg + 2;
136 equal = strchr(name, '=');
137 if (!equal)
138 return 0;
140 if (prefix) {
141 size_t prefix_len = strlen(prefix);
142 if (strncmp(name, prefix, prefix_len) == 0 &&
143 name[prefix_len] == '-')
144 name += prefix_len + 1;
147 if (strncmp(name, decl->long_name, equal - name))
148 return 0;
150 for (i = 0; decl->u.choice.choice[i].name; ++i) {
151 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
152 continue;
154 *(unsigned *)(((char *)opt) + decl->offset) =
155 decl->u.choice.choice[i].value;
157 return 1;
160 return 0;
163 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
165 int i;
167 if ((arg[0] == '-' && arg[1] == decl->short_name && arg[2] == '\0') ||
168 (strncmp(arg, "--", 2) == 0 &&
169 strcmp(arg + 2, decl->long_name) == 0)) {
170 *(unsigned *)(((char *)opt) + decl->offset) = 1;
172 return 1;
175 return 0;
178 static int parse_option(struct isl_arg *decl, const char *arg,
179 const char *prefix, void *opt);
181 static int parse_child_option(struct isl_arg *decl, const char *arg, void *opt)
183 return parse_option(decl->u.child.child, arg, decl->long_name,
184 *(void **)(((char *)opt) + decl->offset));
187 static int parse_option(struct isl_arg *decl, const char *arg,
188 const char *prefix, void *opt)
190 int i;
192 for (i = 0; decl[i].type != isl_arg_end; ++i) {
193 switch (decl[i].type) {
194 case isl_arg_choice:
195 if (parse_choice_option(&decl[i], arg, prefix, opt))
196 return 1;
197 break;
198 case isl_arg_bool:
199 if (parse_bool_option(&decl[i], arg, opt))
200 return 1;
201 break;
202 case isl_arg_child:
203 if (parse_child_option(&decl[i], arg, opt))
204 return 1;
205 break;
209 return 0;
212 static int drop_argument(int argc, char **argv, int drop)
214 for (; drop < argc; ++drop)
215 argv[drop] = argv[drop + 1];
217 return argc - 1;
220 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt)
222 int skip = 0;
223 int i;
225 for (i = 1; i < argc; ++i) {
226 if (strcmp(argv[i], "--help") == 0)
227 print_help_and_exit(arg, argv[0]);
230 while (argc > 1 + skip) {
231 if (parse_option(arg, argv[1 + skip], NULL, opt))
232 argc = drop_argument(argc, argv, 1 + skip);
233 else {
234 fprintf(stderr, "unrecognized option: %s\n",
235 argv[1 + skip]);
236 exit(-1);
240 return argc;