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);
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)
31 for (i = 0; arg[i].type != isl_arg_end; ++i) {
32 switch (arg[i].type) {
34 set_default_choice(&arg[i], opt);
37 set_default_bool(&arg[i], opt);
40 set_default_child(&arg[i], opt);
46 static void print_arg_help(struct isl_arg *decl, const char *prefix)
49 printf(" -%c, --", decl->short_name);
53 printf("%s-", prefix);
54 printf("%s", decl->long_name);
57 static void print_choice_help(struct isl_arg *decl, const char *prefix)
61 print_arg_help(decl, prefix);
64 for (i = 0; decl->u.choice.choice[i].name; ++i) {
67 printf("%s", decl->u.choice.choice[i].name);
73 static void print_bool_help(struct isl_arg *decl, const char *prefix)
75 print_arg_help(decl, prefix);
79 static void print_help(struct isl_arg *arg, const char *prefix)
83 for (i = 0; arg[i].type != isl_arg_end; ++i) {
84 switch (arg[i].type) {
86 print_choice_help(&arg[i], prefix);
89 print_bool_help(&arg[i], prefix);
94 for (i = 0; arg[i].type != isl_arg_end; ++i) {
95 if (arg[i].type != isl_arg_child)
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)
107 slash = strrchr(prog, '/');
109 printf("Usage: %s [OPTION...]\n\n", slash + 1);
111 print_help(arg, NULL);
116 static int parse_choice_option(struct isl_arg *decl, const char *arg,
117 const char *prefix, void *opt)
123 if (strncmp(arg, "--", 2))
127 equal = strchr(name, '=');
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))
141 for (i = 0; decl->u.choice.choice[i].name; ++i) {
142 if (strcmp(equal + 1, decl->u.choice.choice[i].name))
145 *(unsigned *)(((char *)opt) + decl->offset) =
146 decl->u.choice.choice[i].value;
154 static int parse_bool_option(struct isl_arg *decl, const char *arg, void *opt)
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;
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)
183 for (i = 0; decl[i].type != isl_arg_end; ++i) {
184 switch (decl[i].type) {
186 if (parse_choice_option(&decl[i], arg, prefix, opt))
190 if (parse_bool_option(&decl[i], arg, opt))
194 if (parse_child_option(&decl[i], arg, opt))
203 static int drop_argument(int argc, char **argv, int drop)
205 for (; drop < argc; ++drop)
206 argv[drop] = argv[drop + 1];
211 int isl_arg_parse(struct isl_arg *arg, int argc, char **argv, void *opt)
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);
225 fprintf(stderr, "unrecognized option: %s\n",