.help_msg = h, \
.u = { .str = { .default_value = d } } \
},
-#define ISL_ARG_CHILD(st,f,l,c,h) { \
+#define _ISL_ARG_CHILD(o,sz,l,c,h,fl) { \
.type = isl_arg_child, \
.long_name = l, \
- .offset = offsetof(st, f), \
+ .offset = o, \
.help_msg = h, \
- .u = { .child = { .child = c, .size = sizeof(*((st *)NULL)->f) } }\
+ .flags = fl, \
+ .u = { .child = { .child = c, .size = sz } } \
},
+#define ISL_ARG_CHILD(st,f,l,c,h) \
+ _ISL_ARG_CHILD(offsetof(st, f),sizeof(*((st *)NULL)->f),l,c,h,0)
+#define ISL_ARG_GROUP_F(c,h,fl) \
+ _ISL_ARG_CHILD(-1,0,NULL,c,h,fl)
+#define ISL_ARG_GROUP(c,h) \
+ ISL_ARG_GROUP_F(c,h,0)
#define ISL_ARG_FLAGS(st,f,s,l,c,d,h) { \
.type = isl_arg_flags, \
.short_name = s, \
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)
}
}
-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:
break;
}
}
+}
+
+void isl_arg_free(struct isl_arg *arg, void *opt)
+{
+ if (!opt)
+ return;
+
+ free_args(arg, opt);
free(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,
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: