diff options
| author | Csaba Henk <csaba@gluster.com> | 2011-05-11 02:39:14 +0000 | 
|---|---|---|
| committer | Anand Avati <avati@gluster.com> | 2011-05-11 19:17:56 -0700 | 
| commit | 86c818a98a18a3b6c33a494202922f1cd275ac7b (patch) | |
| tree | 13dc415ce375aa480c7db81c6fd9e99c4e2296e9 /cli | |
| parent | 0652f9f92123e8bb3c0fee02c9fb3bbe23d9f7c6 (diff) | |
cli: taking my revenge for forcing "geo-replication" into commandline
Accept unambigous initial fragments of keywords, eg.
  gluster vol geo stat
is recognized. Compared to readline integration:
- no external dependency
- works in shell too
- works for inner keywords of operations
  (as in above example, or "vol crea <vol> repl 3 ...")
- you save pressing tabs :)
If not desired in customer builds, can be disabled by an #ifdef
(not integrated into build system as of now); however, I think
folks in house could like it.
Signed-off-by: Csaba Henk <csaba@gluster.com>
Signed-off-by: Anand Avati <avati@gluster.com>
BUG: 2757 (refactory gsync/gsyncd/syncdaemon/whatever to geo-replication)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2757
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/src/cli-cmd-parser.c | 189 | ||||
| -rw-r--r-- | cli/src/cli.h | 4 | ||||
| -rw-r--r-- | cli/src/registry.c | 52 | 
3 files changed, 137 insertions, 108 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c index 735dcb02bc4..1b3c5ca2d26 100644 --- a/cli/src/cli-cmd-parser.c +++ b/cli/src/cli-cmd-parser.c @@ -36,6 +36,20 @@  #include "protocol-common.h"  #include "cli1-xdr.h" + +static const char * +id_sel (void *wcon) +{ +        return (const char *)wcon; +} + +static char * +str_getunamb (const char *tok, char **opwords) +{ +        return (char *)cli_getunamb (tok, (void **)opwords, id_sel); +} + +  int32_t  cli_cmd_bricks_parse (const char **words, int wordcount, int brick_index,                        char **bricks, int *brick_count) @@ -150,13 +164,13 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options          int32_t index = 0;          char    *bricks = NULL;          int32_t brick_count = 0; +        char    *opwords_cl[] = { "replica", "stripe", NULL }; +        char    *opwords_tr[] = { "transport", NULL }; +        char    *w = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "create")) == 0); -          dict = dict_new ();          if (!dict) @@ -199,7 +213,11 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  ret = -1;                  goto out;          } -        if ((strcasecmp (words[3], "replica")) == 0) { +        w = str_getunamb (words[3], opwords_cl); +        if (!w) { +                type = GF_CLUSTER_TYPE_NONE; +                brick_index = 3; +        } else if ((strcmp (w, "replica")) == 0) {                  type = GF_CLUSTER_TYPE_REPLICATE;                  if (wordcount < 5) {                          ret = -1; @@ -215,7 +233,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  if (ret)                          goto out;                  brick_index = 5; -        } else if ((strcasecmp (words[3], "stripe")) == 0) { +        } else if ((strcmp (w, "stripe")) == 0) {                  type = GF_CLUSTER_TYPE_STRIPE;                  if (wordcount < 5) {                          ret = -1; @@ -231,10 +249,8 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  if (ret)                          goto out;                  brick_index = 5; -        } else { -                type = GF_CLUSTER_TYPE_NONE; -                brick_index = 3; -        } +        } else +                GF_ASSERT (!"opword mismatch");          ret = dict_set_int32 (dict, "type", type);          if (ret) @@ -250,7 +266,7 @@ cli_cmd_volume_create_parse (const char **words, int wordcount, dict_t **options                  goto out;          } -        if (strcasecmp(words[index], "transport") == 0) { +        if (str_getunamb (words[index], opwords_tr)) {                  brick_index = index+2;                  if (wordcount < (index + 2)) {                          ret = -1; @@ -331,9 +347,6 @@ cli_cmd_volume_reset_parse (const char **words, int wordcount, dict_t **options)          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "reset")) == 0); -          dict = dict_new ();          if (!dict) @@ -387,13 +400,13 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)          char             key[20] = {0, };          uint64_t         value   = 0;          gf_quota_type    type    = GF_QUOTA_OPTION_TYPE_NONE; +        char           *opwords[] = { "enable", "disable", "limit-usage", +                                      "remove", "list", "version", NULL }; +        char            *w       = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "quota")) == 0); -          dict = dict_new ();          if (!dict) @@ -434,18 +447,23 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)          if (ret)                  goto out; +        w = str_getunamb (words[3], opwords); +        if (!w) { +                ret = - 1; +                goto out; +        } -        if ((strcasecmp (words[3], "enable")) == 0 && wordcount == 4) { +        if ((strcmp (w, "enable")) == 0 && wordcount == 4) {                  type = GF_QUOTA_OPTION_TYPE_ENABLE;                  goto set_type;          } -        if (strcasecmp (words[3], "disable") == 0 && wordcount == 4) { +        if (strcmp (w, "disable") == 0 && wordcount == 4) {                  type = GF_QUOTA_OPTION_TYPE_DISABLE;                  goto set_type;          } -        if (strcasecmp (words[3], "limit-usage") == 0) { +        if (strcmp (w, "limit-usage") == 0) {                  if (wordcount != 6) {                          ret = -1;                          goto out; @@ -480,7 +498,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)                  goto set_type;          } -        if (strcasecmp (words[3], "remove") == 0) { +        if (strcmp (w, "remove") == 0) {                  if (wordcount != 5) {                          ret = -1;                          goto out; @@ -500,7 +518,7 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)                  goto set_type;          } -        if (strcasecmp (words[3], "list") == 0) { +        if (strcmp (w, "list") == 0) {                          if (wordcount < 4) {                                  ret = -1;                                  goto out; @@ -524,13 +542,11 @@ cli_cmd_quota_parse (const char **words, int wordcount, dict_t **options)                          goto set_type;          } -        if (strcasecmp (words[3], "version") == 0) { +        if (strcmp (w, "version") == 0) {                  type = GF_QUOTA_OPTION_TYPE_VERSION; -        } else { -                ret = -1; -                goto out; -        } +        } else +                GF_ASSERT (!"opword mismatch");  set_type:          ret = dict_set_int32 (dict, "type", type); @@ -562,9 +578,6 @@ cli_cmd_volume_set_parse (const char **words, int wordcount, dict_t **options)          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "set")) == 0); -          dict = dict_new ();          if (!dict) @@ -636,9 +649,6 @@ cli_cmd_volume_add_brick_parse (const char **words, int wordcount,          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "add-brick")) == 0); -          dict = dict_new ();          if (!dict) @@ -707,9 +717,6 @@ cli_cmd_volume_remove_brick_parse (const char **words, int wordcount,          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "remove-brick")) == 0); -          dict = dict_new ();          if (!dict) @@ -819,17 +826,16 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,          dict_t  *dict = NULL;          char    *volname = NULL;          int     ret = -1; -        char    *op = NULL;          int     op_index = 0;          char    *delimiter = NULL;          gf1_cli_replace_op replace_op = GF_REPLACE_OP_NONE; +        char    *opwords[] = { "start", "commit", "pause", "abort", "status", +                                NULL }; +        char    *w = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "replace-brick")) == 0); -          dict = dict_new ();          if (!dict) @@ -895,19 +901,21 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,                  goto out;          } -        op = (char *) words[op_index]; +        w = str_getunamb (words[op_index], opwords); -        if (!strcasecmp ("start", op)) { +        if (!w) { +        } else if (!strcmp ("start", w)) {                  replace_op = GF_REPLACE_OP_START; -        } else if (!strcasecmp ("commit", op)) { +        } else if (!strcmp ("commit", w)) {                  replace_op = GF_REPLACE_OP_COMMIT; -        } else if (!strcasecmp ("pause", op)) { +        } else if (!strcmp ("pause", w)) {                  replace_op = GF_REPLACE_OP_PAUSE; -        } else if (!strcasecmp ("abort", op)) { +        } else if (!strcmp ("abort", w)) {                  replace_op = GF_REPLACE_OP_ABORT; -        } else if (!strcasecmp ("status", op)) { +        } else if (!strcmp ("status", w)) {                  replace_op = GF_REPLACE_OP_STATUS; -        } +        } else +                GF_ASSERT (!"opword mismatch");          /* commit force option */          op_index = 6; @@ -918,8 +926,7 @@ cli_cmd_volume_replace_brick_parse (const char **words, int wordcount,          }          if (wordcount == (op_index + 1)) { -                op = (char *) words[op_index]; -                if (!strcasecmp ("force", op)) { +                if (!strcmp ("force", words[op_index])) {                          replace_op = GF_REPLACE_OP_COMMIT_FORCE;                  }          } @@ -961,10 +968,6 @@ cli_cmd_log_filename_parse (const char **words, int wordcount, dict_t **options)          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "log")) == 0); -        GF_ASSERT ((strcmp (words[2], "filename")) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1023,10 +1026,6 @@ cli_cmd_log_locate_parse (const char **words, int wordcount, dict_t **options)          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "log")) == 0); -        GF_ASSERT ((strcmp (words[2], "locate")) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1076,10 +1075,6 @@ cli_cmd_log_rotate_parse (const char **words, int wordcount, dict_t **options)          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "log")) == 0); -        GF_ASSERT ((strcmp (words[2], "rotate")) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1136,13 +1131,13 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)          unsigned           masteri = 0;          unsigned           slavei  = 0;          unsigned           cmdi    = 0; +        char               *opwords[] = { "status", "start", "stop", "config", +                                          NULL }; +        char               *w = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], GEOREP)) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1191,28 +1186,32 @@ cli_cmd_gsync_set_parse (const char **words, int wordcount, dict_t **options)          if (slavei && !gsyncd_url_check (words[slavei]))                  goto out; -        if (strcmp (words[cmdi], "status") == 0) { +        w = str_getunamb (words[cmdi], opwords); +        if (!w) +                goto out; + +        if (strcmp (w, "status") == 0) {                  type = GF_GSYNC_OPTION_TYPE_STATUS;                  if (slavei && !masteri)                          goto out; -        } else if (strcmp (words[cmdi], "config") == 0) { +        } else if (strcmp (w, "config") == 0) {                  type = GF_GSYNC_OPTION_TYPE_CONFIG;                  if (!slavei)                          goto out; -        } else if (strcmp (words[cmdi], "start") == 0) { +        } else if (strcmp (w, "start") == 0) {                  type = GF_GSYNC_OPTION_TYPE_START;                  if (!masteri || !slavei)                          goto out; -        } else if (strcmp (words[cmdi], "stop") == 0) { +        } else if (strcmp (w, "stop") == 0) {                  type = GF_GSYNC_OPTION_TYPE_STOP;                  if (!masteri || !slavei)                          goto out;          } else -                goto out; +                GF_ASSERT (!"opword mismatch");          if (type != GF_GSYNC_OPTION_TYPE_CONFIG && cmdi < wordcount - 1)                  goto out; @@ -1296,13 +1295,12 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,          char      *volname    = NULL;          int       ret         = -1;          gf1_cli_stats_op op = GF_CLI_STATS_NONE; +        char      *opwords[] = { "start", "stop", "info", NULL }; +        char      *w = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "profile")) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1316,16 +1314,19 @@ cli_cmd_volume_profile_parse (const char **words, int wordcount,          if (ret)                  goto out; -        if (strcmp (words[3], "start") == 0) { -                op = GF_CLI_STATS_START; -        } else if (strcmp (words[3], "stop") == 0) { -                op = GF_CLI_STATS_STOP; -        } else if (strcmp (words[3], "info") == 0) { -                op = GF_CLI_STATS_INFO; -        } else { +        w = str_getunamb (words[3], opwords); +        if (!w) {                  ret = -1;                  goto out;          } +        if (strcmp (w, "start") == 0) { +                op = GF_CLI_STATS_START; +        } else if (strcmp (w, "stop") == 0) { +                op = GF_CLI_STATS_STOP; +        } else if (strcmp (w, "info") == 0) { +                op = GF_CLI_STATS_INFO; +        } else +                GF_ASSERT (!"opword mismatch");          ret = dict_set_int32 (dict, "op", (int32_t)op);          *options = dict;  out: @@ -1351,13 +1352,14 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,          int32_t  blk_size       = 0;          int32_t  count          = 0;          char    *delimiter      = NULL; +        char    *opwords[]      = { "open", "read", "write", "opendir", +                                    "readdir", "read-perf", "write-perf", +                                    NULL }; +        char    *w = NULL;          GF_ASSERT (words);          GF_ASSERT (options); -        GF_ASSERT ((strcmp (words[0], "volume")) == 0); -        GF_ASSERT ((strcmp (words[1], "top")) == 0); -          dict = dict_new ();          if (!dict)                  goto out; @@ -1376,26 +1378,29 @@ cli_cmd_volume_top_parse (const char **words, int wordcount,          if (ret)                  goto out; -        if (strcmp (words[3], "open") == 0) { +        w = str_getunamb (words[3], opwords); +        if (!w) { +                ret = -1; +                goto out; +        } +        if (strcmp (w, "open") == 0) {                  top_op = GF_CLI_TOP_OPEN; -        } else if (strcmp (words[3], "read") == 0) { +        } else if (strcmp (w, "read") == 0) {                  top_op = GF_CLI_TOP_READ; -        } else if (strcmp (words[3], "write") == 0) { +        } else if (strcmp (w, "write") == 0) {                  top_op = GF_CLI_TOP_WRITE; -        } else if (strcmp (words[3], "opendir") == 0) { +        } else if (strcmp (w, "opendir") == 0) {                  top_op = GF_CLI_TOP_OPENDIR; -        } else if (strcmp (words[3], "readdir") == 0) { +        } else if (strcmp (w, "readdir") == 0) {                  top_op = GF_CLI_TOP_READDIR; -        } else if (strcmp (words[3], "read-perf") == 0) { +        } else if (strcmp (w, "read-perf") == 0) {                  top_op = GF_CLI_TOP_READ_PERF;                  perf = 1; -        } else if (strcmp (words[3], "write-perf") == 0) { +        } else if (strcmp (w, "write-perf") == 0) {                  top_op = GF_CLI_TOP_WRITE_PERF;                  perf = 1; -        } else { -                ret = -1; -                goto out; -        }  +        } else +                GF_ASSERT (!"opword mismatch");          ret = dict_set_int32 (dict, "top-op", (int32_t)top_op);          if (ret)                  goto out; diff --git a/cli/src/cli.h b/cli/src/cli.h index 70d6cfb271a..5d83f0fc1df 100644 --- a/cli/src/cli.h +++ b/cli/src/cli.h @@ -150,6 +150,10 @@ typedef ssize_t (*cli_serialize_t) (struct iovec outmsg, void *args);  extern struct cli_state *global_state; /* use only in readline callback */ +typedef const char *(*cli_selector_t) (void *wcon); + +void *cli_getunamb (const char *tok, void **choices, cli_selector_t sel); +  int cli_cmd_register (struct cli_cmd_tree *tree, struct cli_cmd *cmd);  int cli_cmds_register (struct cli_state *state); diff --git a/cli/src/registry.c b/cli/src/registry.c index 8fa116a48c7..bab44cd8996 100644 --- a/cli/src/registry.c +++ b/cli/src/registry.c @@ -260,29 +260,49 @@ err:          return NULL;  } - -struct cli_cmd_word * -cli_cmd_nextword (struct cli_cmd_word *word, const char *token) +void * +cli_getunamb (const char *tok, void **choices, cli_selector_t sel)  { -        struct cli_cmd_word    *next = NULL; -        struct cli_cmd_word   **trav = NULL; -        int                     ret = 0; +        void  **wcon = NULL; +        char      *w = NULL; +        unsigned  mn = 0; +        void    *ret = NULL; -        if (!word->nextwords) +        if (!choices || !*tok)                  return NULL; -        for (trav = word->nextwords; (next = *trav); trav++) { -                if (next->match) { -//                        ret = next->match (); -                } else { -                        ret = strcmp (next->word, token); -                } +        for (wcon = choices; *wcon; wcon++) { +                w = strtail ((char *)sel (*wcon), tok); +                if (!w) +                        /* no match */ +                        continue; +                if (!*w) +                        /* exact match */ +                        return *wcon; -                if (ret == 0) -                        break; +                ret = *wcon; +                mn++;          } -        return next; +#ifdef FORCE_MATCH_EXACT +        return NULL; +#else +        return (mn == 1) ? ret : NULL; +#endif +} + +static const char * +sel_cmd_word (void *wcon) +{ +        return ((struct cli_cmd_word *)wcon)->word; +} + +struct cli_cmd_word * +cli_cmd_nextword (struct cli_cmd_word *word, const char *token) +{ +        return (struct cli_cmd_word *)cli_getunamb (token, +                                                    (void **)word->nextwords, +                                                    sel_cmd_word);  }  | 
