static void set_default_child(struct isl_arg *arg, void *opt)
{
- void *child = calloc(1, arg->u.child.size);
+ void *child;
+
+ if (arg->offset == (size_t) -1)
+ child = opt;
+ else {
+ child = calloc(1, arg->u.child.size);
+ *(void **)(((char *)opt) + arg->offset) = child;
+ }
if (child)
isl_arg_set_defaults(arg->u.child.child, child);
-
- *(void **)(((char *)opt) + arg->offset) = child;
}
static void set_default_user(struct isl_arg *arg, void *opt)
arg->u.user.init(((char *)opt) + arg->offset);
}
+static void set_default_int(struct isl_arg *arg, void *opt)
+{
+ *(int *)(((char *)opt) + arg->offset) = arg->u.i.default_value;
+}
+
static void set_default_long(struct isl_arg *arg, void *opt)
{
*(long *)(((char *)opt) + arg->offset) = arg->u.l.default_value;
case isl_arg_user:
set_default_user(&arg[i], opt);
break;
+ case isl_arg_int:
+ set_default_int(&arg[i], opt);
+ break;
case isl_arg_long:
set_default_long(&arg[i], opt);
break;
set_default_str(&arg[i], opt);
break;
case isl_arg_alias:
+ case isl_arg_footer:
case isl_arg_version:
case isl_arg_end:
break;
}
}
-void isl_arg_free(struct isl_arg *arg, void *opt)
+static void free_args(struct isl_arg *arg, void *opt)
{
int i;
- if (!opt)
- return;
-
for (i = 0; arg[i].type != isl_arg_end; ++i) {
switch (arg[i].type) {
case isl_arg_child:
- isl_arg_free(arg[i].u.child.child,
- *(void **)(((char *)opt) + arg[i].offset));
+ if (arg[i].offset == (size_t) -1)
+ free_args(arg[i].u.child.child, opt);
+ else
+ isl_arg_free(arg[i].u.child.child,
+ *(void **)(((char *)opt) + arg[i].offset));
break;
case isl_arg_arg:
case isl_arg_str:
case isl_arg_bool:
case isl_arg_choice:
case isl_arg_flags:
+ case isl_arg_int:
case isl_arg_long:
case isl_arg_ulong:
case isl_arg_version:
+ case isl_arg_footer:
case isl_arg_end:
break;
}
}
+}
+
+void isl_arg_free(struct isl_arg *arg, void *opt)
+{
+ if (!opt)
+ return;
+
+ free_args(arg, opt);
free(opt);
}
return NULL;
}
-static int print_help_msg(struct isl_arg *decl, int pos)
+static int wrap_msg(const char *s, int indent, int pos)
{
int len;
- const char *s;
-
- if (!decl->help_msg)
- return pos;
+ int wrap_len = 75 - indent;
- if (pos >= 29)
- printf("\n%30s", "");
+ if (pos + 1 >= indent)
+ printf("\n%*s", indent, "");
else
- printf("%*s", 30 - pos, "");
+ printf("%*s", indent - pos, "");
- s = decl->help_msg;
len = strlen(s);
- while (len > 45) {
- const char *space = isl_memrchr(s, ' ', 45);
+ while (len > wrap_len) {
+ const char *space = isl_memrchr(s, ' ', wrap_len);
int l;
if (!space)
- space = strchr(s + 45, ' ');
+ space = strchr(s + wrap_len, ' ');
if (!space)
break;
l = space - s;
printf("%.*s", l, s);
s = space + 1;
len -= l + 1;
- printf("\n%30s", "");
+ printf("\n%*s", indent, "");
}
printf("%s", s);
return len;
}
+static int print_help_msg(struct isl_arg *decl, int pos)
+{
+ if (!decl->help_msg)
+ return pos;
+
+ return wrap_msg(decl->help_msg, 30, pos);
+}
+
static void print_default(struct isl_arg *decl, const char *def, int pos)
{
int i;
return pos + 3 + strlen(name);
}
+static void print_int_help(struct isl_arg *decl, const char *prefix)
+{
+ int pos;
+ char val[20];
+ pos = print_arg_help(decl, prefix, 0);
+ pos = print_argument_name(decl, decl->argument_name, pos);
+ pos = print_help_msg(decl, pos);
+ snprintf(val, sizeof(val), "%d", decl->u.i.default_value);
+ print_default(decl, val, pos);
+ printf("\n");
+}
+
static void print_long_help(struct isl_arg *decl, const char *prefix)
{
int pos;
static void print_help(struct isl_arg *arg, const char *prefix)
{
int i;
+ int any = 0;
for (i = 0; arg[i].type != isl_arg_end; ++i) {
+ if (arg[i].flags & ISL_ARG_HIDDEN)
+ continue;
switch (arg[i].type) {
case isl_arg_flags:
print_flags_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_choice:
print_choice_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_bool:
print_bool_help(&arg[i], prefix);
+ any = 1;
+ break;
+ case isl_arg_int:
+ print_int_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_long:
print_long_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_ulong:
print_ulong_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_str:
print_str_help(&arg[i], prefix);
+ any = 1;
break;
case isl_arg_alias:
case isl_arg_version:
case isl_arg_arg:
+ case isl_arg_footer:
case isl_arg_child:
case isl_arg_user:
case isl_arg_end:
for (i = 0; arg[i].type != isl_arg_end; ++i) {
if (arg[i].type != isl_arg_child)
continue;
+ if (arg[i].flags & ISL_ARG_HIDDEN)
+ continue;
- printf("\n");
+ if (any)
+ printf("\n");
if (arg[i].help_msg)
printf(" %s\n", arg[i].help_msg);
print_help(arg[i].u.child.child, arg[i].long_name);
+ any = 1;
}
}
printf(" -V, --version\n");
print_bool_help(help_arg, NULL);
+ for (i = 0; arg[i].type != isl_arg_end; ++i) {
+ if (arg[i].type != isl_arg_footer)
+ continue;
+ wrap_msg(arg[i].help_msg, 0, 0);
+ printf("\n");
+ }
+
exit(0);
}
return 0;
}
+static int parse_int_option(struct isl_arg *decl, char **arg,
+ const char *prefix, void *opt)
+{
+ int has_argument;
+ const char *val;
+ char *endptr;
+ int *p = (int *)(((char *)opt) + decl->offset);
+
+ val = skip_name(decl, arg[0], prefix, 0, &has_argument);
+ if (!val)
+ return 0;
+
+ if (has_argument) {
+ *p = atoi(val);
+ return 1;
+ }
+
+ if (arg[1]) {
+ int i = strtol(arg[1], &endptr, 0);
+ if (*endptr == '\0') {
+ *p = i;
+ return 2;
+ }
+ }
+
+ return 0;
+}
+
static int parse_long_option(struct isl_arg *decl, char **arg,
const char *prefix, void *opt)
{
static int parse_option(struct isl_arg *decl, char **arg,
const char *prefix, void *opt);
-static int parse_child_option(struct isl_arg *decl, char **arg, void *opt)
+static int parse_child_option(struct isl_arg *decl, char **arg,
+ const char *prefix, void *opt)
{
- return parse_option(decl->u.child.child, arg, decl->long_name,
- *(void **)(((char *)opt) + decl->offset));
+ void *child;
+
+ if (decl->offset == (size_t) -1)
+ child = opt;
+ else {
+ child = *(void **)(((char *)opt) + decl->offset);
+ prefix = decl->long_name;
+ }
+ return parse_option(decl->u.child.child, arg, prefix, child);
}
static int parse_option(struct isl_arg *decl, char **arg,
case isl_arg_flags:
parsed = parse_flags_option(&decl[i], arg, prefix, opt);
break;
+ case isl_arg_int:
+ parsed = parse_int_option(&decl[i], arg, prefix, opt);
+ break;
case isl_arg_long:
parsed = parse_long_option(&decl[i], arg, prefix, opt);
break;
parsed = parse_str_option(&decl[i], arg, prefix, opt);
break;
case isl_arg_child:
- parsed = parse_child_option(&decl[i], arg, opt);
+ parsed = parse_child_option(&decl[i], arg, prefix, opt);
break;
case isl_arg_alias:
case isl_arg_arg:
+ case isl_arg_footer:
case isl_arg_user:
case isl_arg_version:
case isl_arg_end: