cli: Add support for parsing keyword-flag arguments
authorJani Nikula <jani@nikula.org>
Fri, 31 Oct 2014 21:53:56 +0000 (22:53 +0100)
committerDavid Bremner <david@tethera.net>
Sat, 1 Nov 2014 07:02:21 +0000 (08:02 +0100)
This allows having multiple --foo=bar --foo=baz options on the command
line, with the corresponding values OR'd together.

[Test added by Michal Sojka]

command-line-arguments.c
command-line-arguments.h
test/T410-argument-parsing.sh
test/arg-test.c

index 844d6c3d18bf9db03be5368cbd20c66cc9e058b9..c6f7269603cbb3608186ee097a2ad993bbb5790e 100644 (file)
@@ -23,7 +23,10 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const char
     while (keywords->name) {
        if (strcmp (arg_str, keywords->name) == 0) {
            if (arg_desc->output_var) {
     while (keywords->name) {
        if (strcmp (arg_str, keywords->name) == 0) {
            if (arg_desc->output_var) {
-               *((int *)arg_desc->output_var) = keywords->value;
+               if (arg_desc->opt_type == NOTMUCH_OPT_KEYWORD_FLAGS)
+                   *((int *)arg_desc->output_var) |= keywords->value;
+               else
+                   *((int *)arg_desc->output_var) = keywords->value;
            }
            return TRUE;
        }
            }
            return TRUE;
        }
@@ -152,6 +155,7 @@ parse_option (const char *arg,
 
        switch (try->opt_type) {
        case NOTMUCH_OPT_KEYWORD:
 
        switch (try->opt_type) {
        case NOTMUCH_OPT_KEYWORD:
+       case NOTMUCH_OPT_KEYWORD_FLAGS:
            return _process_keyword_arg (try, next, value);
        case NOTMUCH_OPT_BOOLEAN:
            return _process_boolean_arg (try, next, value);
            return _process_keyword_arg (try, next, value);
        case NOTMUCH_OPT_BOOLEAN:
            return _process_boolean_arg (try, next, value);
index de1734ad2fdb3f0c5444c73abc5f74b7cbd99cf2..6444129ad2d095e811fcb0d17b93d8fc42aa7166 100644 (file)
@@ -8,6 +8,7 @@ enum notmuch_opt_type {
     NOTMUCH_OPT_BOOLEAN,       /* --verbose              */
     NOTMUCH_OPT_INT,           /* --frob=8               */
     NOTMUCH_OPT_KEYWORD,       /* --format=raw|json|text */
     NOTMUCH_OPT_BOOLEAN,       /* --verbose              */
     NOTMUCH_OPT_INT,           /* --frob=8               */
     NOTMUCH_OPT_KEYWORD,       /* --format=raw|json|text */
+    NOTMUCH_OPT_KEYWORD_FLAGS, /* the above with values OR'd together */
     NOTMUCH_OPT_STRING,                /* --file=/tmp/gnarf.txt  */
     NOTMUCH_OPT_POSITION       /* notmuch dump pos_arg   */
 };
     NOTMUCH_OPT_STRING,                /* --file=/tmp/gnarf.txt  */
     NOTMUCH_OPT_POSITION       /* notmuch dump pos_arg   */
 };
index 94e90874d2e0e422c433e0601b9e88f0342a618e..2e5d7ae3ab4da7f809d8ce4f6a7a1e7716515d66 100755 (executable)
@@ -3,9 +3,10 @@ test_description="argument parsing"
 . ./test-lib.sh
 
 test_begin_subtest "sanity check"
 . ./test-lib.sh
 
 test_begin_subtest "sanity check"
-$TEST_DIRECTORY/arg-test  pos1  --keyword=one --string=foo pos2 --int=7 > OUTPUT
+$TEST_DIRECTORY/arg-test  pos1  --keyword=one --string=foo pos2 --int=7 --flag=one --flag=three > OUTPUT
 cat <<EOF > EXPECTED
 keyword 1
 cat <<EOF > EXPECTED
 keyword 1
+flags 5
 int 7
 string foo
 positional arg 1 pos1
 int 7
 string foo
 positional arg 1 pos1
index 6c49eacd7f3a9bab7537ee82059b6c66a5a76d7a..736686ded2c07287f1daf237a5b6c22f71e5bb82 100644 (file)
@@ -7,6 +7,7 @@ int main(int argc, char **argv){
     int opt_index=1;
 
     int kw_val=0;
     int opt_index=1;
 
     int kw_val=0;
+    int fl_val=0;
     int int_val=0;
     char *pos_arg1=NULL;
     char *pos_arg2=NULL;
     int int_val=0;
     char *pos_arg1=NULL;
     char *pos_arg2=NULL;
@@ -17,6 +18,11 @@ int main(int argc, char **argv){
          (notmuch_keyword_t []){ { "one", 1 },
                                  { "two", 2 },
                                  { 0, 0 } } },
          (notmuch_keyword_t []){ { "one", 1 },
                                  { "two", 2 },
                                  { 0, 0 } } },
+       { NOTMUCH_OPT_KEYWORD_FLAGS, &fl_val, "flag", 'f',
+         (notmuch_keyword_t []){ { "one",   1 << 0},
+                                 { "two",   1 << 1 },
+                                 { "three", 1 << 2 },
+                                 { 0, 0 } } },
        { NOTMUCH_OPT_INT, &int_val, "int", 'i', 0},
        { NOTMUCH_OPT_STRING, &string_val, "string", 's', 0},
        { NOTMUCH_OPT_POSITION, &pos_arg1, 0,0, 0},
        { NOTMUCH_OPT_INT, &int_val, "int", 'i', 0},
        { NOTMUCH_OPT_STRING, &string_val, "string", 's', 0},
        { NOTMUCH_OPT_POSITION, &pos_arg1, 0,0, 0},
@@ -31,6 +37,9 @@ int main(int argc, char **argv){
     if (kw_val)
        printf("keyword %d\n", kw_val);
 
     if (kw_val)
        printf("keyword %d\n", kw_val);
 
+    if (fl_val)
+       printf("flags %d\n", fl_val);
+
     if (int_val)
        printf("int %d\n", int_val);
 
     if (int_val)
        printf("int %d\n", int_val);