isl_tab_detect_redundant: return status instead of isl_tab *
[isl.git] / isl_arg.c
blob7854204d4bf69548f45db584c345239ee547e5ee
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
5 #include "isl_arg.h"
7 static void set_default_choice(struct isl_arg *arg, void *opt)
9 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.choice.default_value;
12 static void set_default_bool(struct isl_arg *arg, void *opt)
14 *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
17 static void set_default_child(struct isl_arg *arg, void *opt)
19 void *child = calloc(1, arg->u.child.size);
21 if (child)
22 isl_arg_set_defaults(arg->u.child.child, child);
24 *(void **)(((char *)opt) + arg->offset) = child;
27 void isl_arg_set_defaults(struct isl_arg *arg, void *opt)
29 int i;
31 for (i = 0; arg[i].type != isl_arg_end; ++i) {
32 switch (arg[i].type) {
33 case isl_arg_choice:
34 set_default_choice(&arg[i], opt);
35 break;
36 case isl_arg_bool:
37 set_default_bool(&arg[i], opt);
38 break;
39 case isl_arg_child:
40 set_default_child(&arg[i], opt);
41 break;
46 static void print_arg_help(struct isl_arg *decl, const char *prefix)
48 if (decl->short_name)
49 printf(" -%c, --", decl->short_name);
50 else
51 printf(" --");
52 if (prefix)
53 printf("%s-", prefix);
54 printf("%s", decl->long_name);
57 static void print_choice_help(struct isl_arg *decl, const char *prefix)
59 int i;
61 print_arg_help(decl, prefix);
62 printf("=");
64 for (i = 0; decl->u.choice.choice[i].name; ++i) {
65 if (i)
66 printf("|");
67 printf("%s", decl->u.choice.choice[i].name);
70 printf("\n");
73 static void print_bool_help(struct isl_arg *decl, const char *prefix)
75 print_arg_help(decl, prefix);
76 printf("\n");
79 static void print_help(struct isl_arg *arg, const char *prefix)
81 int i;
83 for (i = 0; arg[i].type != isl_arg_end; ++i) {
84 switch (arg[i].type) {
85 case isl_arg_choice:
86 print_choice_help(&arg[i], prefix);
87 break;
88 case isl_arg_bool:
89 print_bool_help(&arg[i], prefix);
90 break;
94 for (i = 0; arg[i].type != isl_arg_end; ++i) {
95 if (arg[i].type != isl_arg_child)
96 continue;
98 printf("\n");
99 print_help(arg[i].u.child.child, arg[i].long_name);
103 static void print_help_and_exit(struct isl_arg *arg, const char *prog)
105 const char *slash;
107 slash = strrchr(prog, '/');
108 if (slash)
109 printf("Usage: %s [OPTION...]\n\n", slash + 1);
111 print_help(arg, NULL);
113 exit(0);
116 static int parse_choice_option(struct isl_arg *decl, const char *arg,
117 const char *prefix, void *opt)
119 int i;
120 const char *equal;
121 const char *name;
123 if (strncmp(arg, "--", 2))
124 return 0;
126 name = arg + 2;
127 equal = strchr(name, '=');
128 if (!equal)
129 return 0;
131 if (prefix) {
132 size_t prefix_len = strlen(prefix);
133 if (strncmp(name, prefix, prefix_len) == 0 &&
134 name[prefix_len] == '-')
135 name += prefix_len + 1;
138 if (strncmp(name, decl->long_name, equal - name))
139 return 0;
141 for (i = 0; decl->u.choice.choice[i].name; ++i) {
142 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
143 continue;
145 *(unsigned *)(((char *)opt) + decl->offset) =
146 decl->u.choice.choice[i].value;
148 return 1;
151 return 0;
154 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
156 int i;
158 if ((arg[0] == '-' && arg[1] == decl->short_name && arg[2] == '\0') ||
159 (strncmp(arg, "--", 2) == 0 &&
160 strcmp(arg + 2, decl->long_name) == 0)) {
161 *(unsigned *)(((char *)opt) + decl->offset) = 1;
163 return 1;
166 return 0;
169 static int parse_option(struct isl_arg *decl, const char *arg,
170 const char *prefix, void *opt);
172 static int parse_child_option(struct isl_arg *decl, const char *arg, void *opt)
174 return parse_option(decl->u.child.child, arg, decl->long_name,
175 *(void **)(((char *)opt) + decl->offset));
178 static int parse_option(struct isl_arg *decl, const char *arg,
179 const char *prefix, void *opt)
181 int i;
183 for (i = 0; decl[i].type != isl_arg_end; ++i) {
184 switch (decl[i].type) {
185 case isl_arg_choice:
186 if (parse_choice_option(&decl[i], arg, prefix, opt))
187 return 1;
188 break;
189 case isl_arg_bool:
190 if (parse_bool_option(&decl[i], arg, opt))
191 return 1;
192 break;
193 case isl_arg_child:
194 if (parse_child_option(&decl[i], arg, opt))
195 return 1;
196 break;
200 return 0;
203 static int drop_argument(int argc, char **argv, int drop)
205 for (; drop < argc; ++drop)
206 argv[drop] = argv[drop + 1];
208 return argc - 1;
211 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt)
213 int skip = 0;
214 int i;
216 for (i = 1; i < argc; ++i) {
217 if (strcmp(argv[i], "--help") == 0)
218 print_help_and_exit(arg, argv[0]);
221 while (argc > 1 + skip) {
222 if (parse_option(arg, argv[1 + skip], NULL, opt))
223 argc = drop_argument(argc, argv, 1 + skip);
224 else {
225 fprintf(stderr, "unrecognized option: %s\n",
226 argv[1 + skip]);
227 exit(-1);
231 return argc;