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",