diff options
Diffstat (limited to 'cli/src/registry.c')
| -rw-r--r-- | cli/src/registry.c | 519 |
1 files changed, 261 insertions, 258 deletions
diff --git a/cli/src/registry.c b/cli/src/registry.c index c3634d974de..85f7686ade1 100644 --- a/cli/src/registry.c +++ b/cli/src/registry.c @@ -1,27 +1,12 @@ /* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ - + Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ #include <stdio.h> #include <string.h> @@ -30,20 +15,18 @@ #include "cli.h" #include "cli-cmd.h" - static int -__is_spc (int ch) +__is_spc(int ch) { - if (ch == ' ') - return 1; - return 0; + if (ch == ' ') + return 1; + return 0; } - static int -__is_div (int ch) +__is_div(int ch) { - switch (ch) { + switch (ch) { case '(': case ')': case '<': @@ -53,336 +36,356 @@ __is_div (int ch) case '{': case '}': case '|': - return 1; - } + return 1; + } - return 0; + return 0; } - static int -__is_word (const char *word) +__is_word(const char *word) { - return (!__is_div (*word) && !__is_spc (*word)); + return (!__is_div(*word) && !__is_spc(*word)); } - int -counter_char (int ch) +counter_char(int ch) { - switch (ch) { + switch (ch) { case '(': - return ')'; + return ')'; case '<': - return '>'; + return '>'; case '[': - return ']'; + return ']'; case '{': - return '}'; - } + return '}'; + } - return -1; + return -1; } - const char * -__is_template_balanced (const char *template) +__is_template_balanced(const char *template) { - const char *trav = NULL; - int ch = 0; - - trav = template; - - while (*trav) { - ch = *trav; - - switch (ch) { - case '<': - case '(': - case '[': - trav = __is_template_balanced (trav+1); - if (!trav) - return NULL; - if (*trav != counter_char (ch)) - return NULL; - break; - case '>': - case ')': - case ']': - return trav; - } + const char *trav = NULL; + int ch = 0; + + trav = template; + + while (*trav) { + ch = *trav; - trav++; + switch (ch) { + case '<': + case '(': + case '[': + trav = __is_template_balanced(trav + 1); + if (!trav) + return NULL; + if (*trav != counter_char(ch)) + return NULL; + break; + case '>': + case ')': + case ']': + return trav; } - return trav; -} + trav++; + } + return trav; +} int -is_template_balanced (const char *template) +is_template_balanced(const char *template) { - const char *trav = NULL; + const char *trav = NULL; - trav = __is_template_balanced (template); - if (!trav || *trav) - return -1; + trav = __is_template_balanced(template); + if (!trav || *trav) + return -1; - return 0; + return 0; } - int -cli_cmd_token_count (const char *template) +cli_cmd_token_count(const char *template) { - int count = 0; - const char *trav = NULL; - int is_alnum = 0; - - for (trav = template; *trav; trav++) { - switch (*trav) { - case '<': - case '>': - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case '|': - count++; - /* fall through */ - case ' ': - is_alnum = 0; - break; - default: - if (!is_alnum) { - is_alnum = 1; - count++; - } + int count = 0; + const char *trav = NULL; + int is_alnum = 0; + + for (trav = template; *trav; trav++) { + switch (*trav) { + case '<': + case '>': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '|': + count++; + /* fall through */ + case ' ': + is_alnum = 0; + break; + default: + if (!is_alnum) { + is_alnum = 1; + count++; } } + } - return count + 1; + return count + 1; } - void -cli_cmd_tokens_destroy (char **tokens) +cli_cmd_tokens_destroy(char **tokens) { - char **tokenp = NULL; + char **tokenp = NULL; - if (!tokens) - return; + if (!tokens) + return; - tokenp = tokens; - while (*tokenp) { - free (*tokenp); - tokenp++; - } + tokenp = tokens; + while (*tokenp) { + free(*tokenp); + tokenp++; + } - free (tokens); + free(tokens); } - int -cli_cmd_tokens_fill (char **tokens, const char *template) +cli_cmd_tokens_fill(char **tokens, const char *template) { - const char *trav = NULL; - char **tokenp = NULL; - char *token = NULL; - int ret = 0; - int ch = 0; + const char *trav = NULL; + char **tokenp = NULL; + char *token = NULL; + int ret = 0; + int ch = 0; - tokenp = tokens; + tokenp = tokens; - for (trav = template; *trav; trav++) { - ch = *trav; + for (trav = template; *trav; trav++) { + ch = *trav; - if (__is_spc (ch)) - continue; + if (__is_spc(ch)) + continue; - if (__is_div (ch)) { - token = calloc (2, 1); - if (!token) - return -1; - token[0] = ch; + if (__is_div(ch)) { + token = calloc(2, 1); + if (!token) + return -1; + token[0] = ch; - *tokenp = token; - tokenp++; + *tokenp = token; + tokenp++; - continue; - } + continue; + } - token = strdup (trav); - *tokenp = token; - tokenp++; + token = strdup(trav); + *tokenp = token; + tokenp++; - for (token++; *token; token++) { - if (__is_spc (*token) || __is_div (*token)) { - *token = 0; - break; - } - trav++; - } + for (token++; *token; token++) { + if (__is_spc(*token) || __is_div(*token)) { + *token = 0; + break; + } + trav++; } + } - return ret; + return ret; } - char ** -cli_cmd_tokenize (const char *template) +cli_cmd_tokenize(const char *template) { - char **tokens = NULL; - int ret = 0; - int count = 0; + char **tokens = NULL; + int ret = 0; + int count = 0; - ret = is_template_balanced (template); - if (ret) - return NULL; + ret = is_template_balanced(template); + if (ret) + return NULL; - count = cli_cmd_token_count (template); - if (count <= 0) - return NULL; + count = cli_cmd_token_count(template); + if (count <= 0) + return NULL; - tokens = calloc (count + 1, sizeof (char *)); - if (!tokens) - return NULL; + tokens = calloc(count + 1, sizeof(char *)); + if (!tokens) + return NULL; - ret = cli_cmd_tokens_fill (tokens, template); - if (ret) - goto err; + ret = cli_cmd_tokens_fill(tokens, template); + if (ret) + goto err; - return tokens; + return tokens; err: - cli_cmd_tokens_destroy (tokens); - return NULL; + cli_cmd_tokens_destroy(tokens); + 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; - - if (!word->nextwords) - return NULL; - - for (trav = word->nextwords; (next = *trav); trav++) { - if (next->match) { -// ret = next->match (); - } else { - ret = strcmp (next->word, token); - } + void **wcon = NULL; + char *w = NULL; + unsigned mn = 0; + void *ret = NULL; - if (ret == 0) - break; - } + if (!choices || !tok || !*tok) + return NULL; - return next; + for (wcon = choices; *wcon; wcon++) { + w = strtail((char *)sel(*wcon), tok); + if (!w) + /* no match */ + continue; + if (!*w) + /* exact match */ + return *wcon; + + ret = *wcon; + mn++; + } + +#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_newword (struct cli_cmd_word *word, const char *token) +cli_cmd_nextword(struct cli_cmd_word *word, const char *token) { - struct cli_cmd_word **nextwords = NULL; - struct cli_cmd_word *nextword = NULL; + return (struct cli_cmd_word *)cli_getunamb(token, (void **)word->nextwords, + sel_cmd_word); +} - nextwords = realloc (word->nextwords, - (word->nextwords_cnt + 2) * sizeof (*nextwords)); - if (!nextwords) - return NULL; +struct cli_cmd_word * +cli_cmd_newword(struct cli_cmd_word *word, const char *token) +{ + struct cli_cmd_word **nextwords = NULL; + struct cli_cmd_word *nextword = NULL; - word->nextwords = nextwords; + nextwords = realloc(word->nextwords, + (word->nextwords_cnt + 2) * sizeof(*nextwords)); + if (!nextwords) + return NULL; - nextword = calloc (1, sizeof (*nextword)); - if (!nextword) - return NULL; + word->nextwords = nextwords; - nextword->word = strdup (token); - if (!nextword->word) { - free (nextword); - return NULL; - } + nextword = calloc(1, sizeof(*nextword)); + if (!nextword) + return NULL; - nextword->tree = word->tree; - nextwords[word->nextwords_cnt++] = nextword; - nextwords[word->nextwords_cnt] = NULL; + nextword->word = strdup(token); + if (!nextword->word) { + free(nextword); + return NULL; + } - return nextword; -} + nextword->tree = word->tree; + nextwords[word->nextwords_cnt++] = nextword; + nextwords[word->nextwords_cnt] = NULL; + return nextword; +} int -cli_cmd_ingest (struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn, - const char *desc) +cli_cmd_ingest(struct cli_cmd_tree *tree, char **tokens, cli_cmd_cbk_t *cbkfn, + const char *desc, const char *pattern) { - int ret = 0; - char **tokenp = NULL; - char *token = NULL; - struct cli_cmd_word *word = NULL; - struct cli_cmd_word *next = NULL; + int ret = 0; + char **tokenp = NULL; + char *token = NULL; + struct cli_cmd_word *word = NULL; + struct cli_cmd_word *next = NULL; - word = &tree->root; + word = &tree->root; - for (tokenp = tokens; (token = *tokenp); tokenp++) { - if (!__is_word (token)) - break; + for (tokenp = tokens; (token = *tokenp); tokenp++) { + if (!__is_word(token)) + break; - next = cli_cmd_nextword (word, token); - if (!next) - next = cli_cmd_newword (word, token); - - word = next; - if (!word) - break; - } + next = cli_cmd_nextword(word, token); + if (!next) + next = cli_cmd_newword(word, token); + word = next; if (!word) - return -1; + break; + } - if (word->cbkfn) { - /* warning - command already registered */ - } + if (!word) + return -1; - word->cbkfn = cbkfn; - word->desc = desc; + if (word->cbkfn) { + /* warning - command already registered */ + } - /* end of static strings in command template */ + word->cbkfn = cbkfn; + word->desc = desc; + word->pattern = pattern; - /* TODO: autocompletion beyond this point is just "nice to have" */ + /* end of static strings in command template */ - return ret; -} + /* TODO: autocompletion beyond this point is just "nice to have" */ + return ret; +} int -cli_cmd_register (struct cli_cmd_tree *tree, const char *template, - cli_cmd_cbk_t cbk, const char *desc) +cli_cmd_register(struct cli_cmd_tree *tree, struct cli_cmd *cmd) { - char **tokens = NULL; - int ret = 0; + char **tokens = NULL; + int ret = 0; - if (!template) - return -1; + GF_ASSERT(cmd); - tokens = cli_cmd_tokenize (template); - if (!tokens) - return -1; + if (cmd->reg_cbk) + cmd->reg_cbk(cmd); - ret = cli_cmd_ingest (tree, tokens, cbk, desc); - if (ret) - goto err; + if (cmd->disable) { + ret = 0; + goto out; + } - return 0; -err: - if (tokens) - cli_cmd_tokens_destroy (tokens); + tokens = cli_cmd_tokenize(cmd->pattern); + if (!tokens) { + ret = -1; + goto out; + } - return ret; -} + ret = cli_cmd_ingest(tree, tokens, cmd->cbk, cmd->desc, cmd->pattern); + if (ret) { + ret = -1; + goto out; + } + + ret = 0; +out: + if (tokens) + cli_cmd_tokens_destroy(tokens); + + gf_log("cli", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} |
