isl_arg_parse: support phantom boolean options
authorSven Verdoolaege <skimo@kotnet.org>
Mon, 15 Nov 2010 22:06:53 +0000 (23:06 +0100)
committerSven Verdoolaege <skimo@kotnet.org>
Fri, 26 Nov 2010 14:54:26 +0000 (15:54 +0100)
Signed-off-by: Sven Verdoolaege <skimo@kotnet.org>
include/isl/arg.h
isl_arg.c

index 336a3c2..f8e49db 100644 (file)
@@ -49,6 +49,7 @@ struct isl_arg {
        const char              *argument_name;
        size_t                   offset;
        const char              *help_msg;
+       unsigned                 flags;
        union {
        struct {
                struct isl_arg_choice   *choice;
@@ -62,6 +63,7 @@ struct isl_arg {
        } flags;
        struct {
                unsigned                 default_value;
+               int (*set)(void *opt, unsigned val);
        } b;
        struct {
                long                    default_value;
@@ -121,14 +123,23 @@ struct isl_arg {
        .u = { .choice = { .choice = c, .default_value = d,             \
                            .default_selected = ds, .set = setter } }   \
 },
-#define ISL_ARG_BOOL(st,f,s,l,d,h)     {                               \
+#define _ISL_ARG_BOOL_F(o,s,l,setter,d,h,fl)   {                       \
        .type = isl_arg_bool,                                           \
        .short_name = s,                                                \
        .long_name = l,                                                 \
-       .offset = offsetof(st, f),                                      \
+       .offset = o,                                                    \
        .help_msg = h,                                                  \
-       .u = { .b = { .default_value = d } }                            \
+       .flags = fl,                                                    \
+       .u = { .b = { .default_value = d, .set = setter } }             \
 },
+#define ISL_ARG_BOOL_F(st,f,s,l,d,h,fl)                                        \
+       _ISL_ARG_BOOL_F(offsetof(st, f),s,l,NULL,d,h,fl)
+#define ISL_ARG_BOOL(st,f,s,l,d,h)                                     \
+       ISL_ARG_BOOL_F(st,f,s,l,d,h,0)
+#define ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,fl)                                \
+       _ISL_ARG_BOOL_F(-1,s,l,setter,0,h,fl)
+#define ISL_ARG_PHANTOM_BOOL(s,l,setter,h)                             \
+       ISL_ARG_PHANTOM_BOOL_F(s,l,setter,h,0)
 #define ISL_ARG_LONG(st,f,s,lo,d,h)    {                               \
        .type = isl_arg_long,                                           \
        .short_name = s,                                                \
index 5ce5e82..fa45358 100644 (file)
--- a/isl_arg.c
+++ b/isl_arg.c
@@ -26,6 +26,8 @@ static void set_default_flags(struct isl_arg *arg, void *opt)
 
 static void set_default_bool(struct isl_arg *arg, void *opt)
 {
+       if (arg->offset == (size_t) -1)
+               return;
        *(unsigned *)(((char *)opt) + arg->offset) = arg->u.b.default_value;
 }
 
@@ -346,7 +348,8 @@ static void print_bool_help(struct isl_arg *decl, const char *prefix)
        int no = decl->u.b.default_value == 1;
        pos = print_arg_help(decl, prefix, no);
        pos = print_help_msg(decl, pos);
-       print_default(decl, no ? "yes" : "no", pos);
+       if (decl->offset != (size_t) -1)
+               print_default(decl, no ? "yes" : "no", pos);
        printf("\n");
 }
 
@@ -633,8 +636,13 @@ static int parse_flags_option(struct isl_arg *decl, char **arg,
 static int parse_bool_option(struct isl_arg *decl, const char *arg,
        const char *prefix, void *opt)
 {
+       unsigned *p = (unsigned *)(((char *)opt) + decl->offset);
+
        if (skip_name(decl, arg, prefix, 0, NULL)) {
-               *(unsigned *)(((char *)opt) + decl->offset) = 1;
+               if (decl->u.b.set)
+                       decl->u.b.set(opt, 1);
+               else if (decl->offset != (size_t) -1)
+                       *p = 1;
 
                return 1;
        }
@@ -667,7 +675,10 @@ static int parse_bool_option(struct isl_arg *decl, const char *arg,
        }
 
        if (!strcmp(arg, decl->long_name)) {
-               *(unsigned *)(((char *)opt) + decl->offset) = 0;
+               if (decl->u.b.set)
+                       decl->u.b.set(opt, 0);
+               else if (decl->offset != (size_t) -1)
+                       *p = 0;
 
                return 1;
        }