diff options
Diffstat (limited to 'cli/src/cli-rl.c')
| -rw-r--r-- | cli/src/cli-rl.c | 531 |
1 files changed, 265 insertions, 266 deletions
diff --git a/cli/src/cli-rl.c b/cli/src/cli-rl.c index 9a37a77de5e..7a38a0b882a 100644 --- a/cli/src/cli-rl.c +++ b/cli/src/cli-rl.c @@ -1,38 +1,23 @@ /* - Copyright (c) 2010-2011 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 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 - General Public License for more details. - - You should have received a copy of the GNU 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. + 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> #include <stdlib.h> #include <stdint.h> #include <pthread.h> -#ifndef _CONFIG_H -#define _CONFIG_H -#include "config.h" -#endif - #include "cli.h" #include "cli-cmd.h" #include "cli-mem-types.h" -#include "event.h" +#include <glusterfs/gf-event.h> #include <fnmatch.h> @@ -42,362 +27,376 @@ #include <readline/readline.h> #include <readline/history.h> - int -cli_rl_out (struct cli_state *state, const char *fmt, va_list ap) +cli_rl_out(struct cli_state *state, const char *fmt, va_list ap) { - int tmp_rl_point = rl_point; - int n = rl_end; - int i = 0; - int ret = 0; - - if (rl_end >= 0 ) { - rl_kill_text (0, rl_end); - rl_redisplay (); - } + int tmp_rl_point = rl_point; + int n = rl_end; + int ret = 0; - printf ("\r"); + if (rl_end >= 0) { + rl_kill_text(0, rl_end); + rl_redisplay(); + } - for (i = 0; i <= strlen (state->prompt); i++) - printf (" "); + printf("\r%*s\r", (int)strlen(state->prompt), ""); - printf ("\r"); + ret = vprintf(fmt, ap); - ret = vprintf (fmt, ap); + printf("\n"); + fflush(stdout); - printf ("\n"); - fflush(stdout); + if (n) { + rl_do_undo(); + rl_point = tmp_rl_point; + rl_reset_line_state(); + } - if (n) { - rl_do_undo (); - rl_point = tmp_rl_point; - rl_reset_line_state (); - } - - return ret; + return ret; } - -void -cli_rl_process_line (char *line) +int +cli_rl_err(struct cli_state *state, const char *fmt, va_list ap) { - struct cli_state *state = NULL; - int ret = 0; + int tmp_rl_point = rl_point; + int n = rl_end; + int ret = 0; - state = global_state; + if (rl_end >= 0) { + rl_kill_text(0, rl_end); + rl_redisplay(); + } - state->rl_processing = 1; - { - ret = cli_cmd_process_line (state, line); - if (ret) - gf_log (THIS->name, GF_LOG_WARNING, - "failed to process line"); + fprintf(stderr, "\r%*s\r", (int)strlen(state->prompt), ""); - add_history (line); - } - state->rl_processing = 0; + ret = vfprintf(stderr, fmt, ap); -} + fprintf(stderr, "\n"); + fflush(stderr); + if (n) { + rl_do_undo(); + rl_point = tmp_rl_point; + rl_reset_line_state(); + } -int -cli_rl_stdin (int fd, int idx, void *data, - int poll_out, int poll_in, int poll_err) + return ret; +} + +void +cli_rl_process_line(char *line) { - rl_callback_read_char (); + struct cli_state *state = NULL; + int ret = 0; - return 0; + state = global_state; + + state->rl_processing = 1; + { + ret = cli_cmd_process_line(state, line); + if (ret) + gf_log(THIS->name, GF_LOG_WARNING, "failed to process line"); + + add_history(line); + } + state->rl_processing = 0; } +void +cli_rl_stdin(int fd, int idx, int gen, void *data, int poll_out, int poll_in, + int poll_err, char event_thread_died) +{ + struct cli_state *state = NULL; + + state = data; + + rl_callback_read_char(); + + gf_event_handled(state->ctx->event_pool, fd, idx, gen); + + return; +} char * -cli_rl_autocomplete_entry (const char *text, int times) +cli_rl_autocomplete_entry(const char *text, int times) { - struct cli_state *state = NULL; - char *retp = NULL; + struct cli_state *state = NULL; + char *retp = NULL; - state = global_state; + state = global_state; - if (!state->matchesp) - return NULL; + if (!state->matchesp) + return NULL; - retp = *state->matchesp; + retp = *state->matchesp; - state->matchesp++; + state->matchesp++; - return retp ? strdup (retp) : NULL; + return retp ? strdup(retp) : NULL; } - int -cli_rl_token_count (const char *text) +cli_rl_token_count(const char *text) { - int count = 0; - const char *trav = NULL; - int is_spc = 1; - - for (trav = text; *trav; trav++) { - if (*trav == ' ') { - is_spc = 1; - } else { - if (is_spc) { - count++; - is_spc = 0; - } - } + int count = 0; + const char *trav = NULL; + int is_spc = 1; + + for (trav = text; *trav; trav++) { + if (*trav == ' ') { + is_spc = 1; + } else { + if (is_spc) { + count++; + is_spc = 0; + } } + } - if (is_spc) - /* what needs to be autocompleted is a full - new word, and not extend the last word - */ - count++; + if (is_spc) + /* what needs to be autocompleted is a full + new word, and not extend the last word + */ + count++; - return count; + return count; } - char ** -cli_rl_tokenize (const char *text) +cli_rl_tokenize(const char *text) { - int count = 0; - char **tokens = NULL; - char **tokenp = NULL; - char *token = NULL; - char *copy = NULL; - char *saveptr = NULL; - int i = 0; - - count = cli_rl_token_count (text); - - tokens = calloc (count + 1, sizeof (*tokens)); - if (!tokens) - return NULL; - - copy = strdup (text); - if (!copy) - goto out; - - tokenp = tokens; - - for (token = strtok_r (copy, " \t\r\n", &saveptr); token; - token = strtok_r (NULL, " \t\r\n", &saveptr)) { - *tokenp = strdup (token); - - if (!*tokenp) - goto out; - tokenp++; - i++; - - } + int count = 0; + char **tokens = NULL; + char **tokenp = NULL; + char *token = NULL; + char *copy = NULL; + char *saveptr = NULL; + int i = 0; + + count = cli_rl_token_count(text); + + tokens = calloc(count + 1, sizeof(*tokens)); + if (!tokens) + return NULL; - if (i < count) { - /* symbolize that what needs to be autocompleted is - the full set of possible nextwords, and not extend - the last word - */ - *tokenp = strdup (""); - if (!*tokenp) - goto out; - tokenp++; - i++; - } + copy = strdup(text); + if (!copy) + goto out; + + tokenp = tokens; + + for (token = strtok_r(copy, " \t\r\n", &saveptr); token; + token = strtok_r(NULL, " \t\r\n", &saveptr)) { + *tokenp = strdup(token); + + if (!*tokenp) + goto out; + tokenp++; + i++; + } + + if (i < count) { + /* symbolize that what needs to be autocompleted is + the full set of possible nextwords, and not extend + the last word + */ + *tokenp = strdup(""); + if (!*tokenp) + goto out; + tokenp++; + i++; + } out: - if (copy) - free (copy); + free(copy); - if (i < count) { - cli_cmd_tokens_destroy (tokens); - tokens = NULL; - } + if (i < count) { + cli_cmd_tokens_destroy(tokens); + tokens = NULL; + } - return tokens; + return tokens; } - char ** -cli_rl_get_matches (struct cli_state *state, struct cli_cmd_word *word, - const char *text) +cli_rl_get_matches(struct cli_state *state, struct cli_cmd_word *word, + const char *text) { - char **matches = NULL; - char **matchesp = NULL; - struct cli_cmd_word **next = NULL; - int count = 0; - int len = 0; + char **matches = NULL; + char **matchesp = NULL; + struct cli_cmd_word **next = NULL; + int count = 0; + int len = 0; - len = strlen (text); + len = strlen(text); - if (!word->nextwords) - return NULL; + if (!word->nextwords) + return NULL; - for (next = word->nextwords; *next; next++) - count++; + for (next = word->nextwords; *next; next++) + count++; - matches = calloc (count + 1, sizeof (*matches)); - matchesp = matches; + matches = calloc(count + 1, sizeof(*matches)); + matchesp = matches; - for (next = word->nextwords; *next; next++) { - if ((*next)->match) { - continue; - } + for (next = word->nextwords; *next; next++) { + if ((*next)->match) { + continue; + } - if (strncmp ((*next)->word, text, len) == 0) { - *matchesp = strdup ((*next)->word); - matchesp++; - } + if (strncmp((*next)->word, text, len) == 0) { + *matchesp = strdup((*next)->word); + matchesp++; } + } - return matches; + return matches; } - int -cli_rl_autocomplete_prepare (struct cli_state *state, const char *text) +cli_rl_autocomplete_prepare(struct cli_state *state, const char *text) { - struct cli_cmd_word *word = NULL; - struct cli_cmd_word *next = NULL; - char **tokens = NULL; - char **tokenp = NULL; - char *token = NULL; - char **matches = NULL; - - tokens = cli_rl_tokenize (text); - if (!tokens) - return 0; - - word = &state->tree.root; - - for (tokenp = tokens; (token = *tokenp); tokenp++) { - if (!*(tokenp+1)) { - /* last word */ - break; - } - - next = cli_cmd_nextword (word, token); - word = next; - if (!word) - break; + struct cli_cmd_word *word = NULL; + struct cli_cmd_word *next = NULL; + char **tokens = NULL; + char **tokenp = NULL; + char *token = NULL; + char **matches = NULL; + + tokens = cli_rl_tokenize(text); + if (!tokens) + return 0; + + word = &state->tree.root; + + for (tokenp = tokens; (token = *tokenp); tokenp++) { + if (!*(tokenp + 1)) { + /* last word */ + break; } + next = cli_cmd_nextword(word, token); + word = next; if (!word) - goto out; + break; + } + + if (!word || !token) + goto out; - matches = cli_rl_get_matches (state, word, token); + matches = cli_rl_get_matches(state, word, token); - state->matches = matches; - state->matchesp = matches; + state->matches = matches; + state->matchesp = matches; out: - cli_cmd_tokens_destroy (tokens); - return 0; + cli_cmd_tokens_destroy(tokens); + return 0; } - int -cli_rl_autocomplete_cleanup (struct cli_state *state) +cli_rl_autocomplete_cleanup(struct cli_state *state) { - if (state->matches) - cli_cmd_tokens_destroy (state->matches); + if (state->matches) + cli_cmd_tokens_destroy(state->matches); - state->matches = NULL; - state->matchesp = NULL; + state->matches = NULL; + state->matchesp = NULL; - return 0; + return 0; } - char ** -cli_rl_autocomplete (const char *text, int start, int end) +cli_rl_autocomplete(const char *text, int start, int end) { - struct cli_state *state = NULL; - char **matches = NULL; - char save = 0; + struct cli_state *state = NULL; + char **matches = NULL; + char save = 0; - state = global_state; + state = global_state; - /* hack to make the autocompletion code neater */ - /* fake it as though the cursor is at the end of line */ + /* hack to make the autocompletion code neater */ + /* fake it as though the cursor is at the end of line */ - save = rl_line_buffer[rl_point]; - rl_line_buffer[rl_point] = 0; + save = rl_line_buffer[rl_point]; + rl_line_buffer[rl_point] = 0; - cli_rl_autocomplete_prepare (state, rl_line_buffer); + cli_rl_autocomplete_prepare(state, rl_line_buffer); - matches = rl_completion_matches (text, cli_rl_autocomplete_entry); + matches = rl_completion_matches(text, cli_rl_autocomplete_entry); - cli_rl_autocomplete_cleanup (state); + cli_rl_autocomplete_cleanup(state); - rl_line_buffer[rl_point] = save; + rl_line_buffer[rl_point] = save; - return matches; + return matches; } - static char * -complete_none (const char *txt, int times) +complete_none(const char *txt, int times) { - return NULL; + return NULL; } - void * -cli_rl_input (void *_data) +cli_rl_input(void *_data) { - struct cli_state *state = NULL; - char *line = NULL; + struct cli_state *state = NULL; + char *line = NULL; - state = _data; + state = _data; - for (;;) { - line = readline (state->prompt); - if (!line) - break; + fprintf(stderr, + "Welcome to gluster prompt, type 'help' to see the available " + "commands.\n"); + for (;;) { + line = readline(state->prompt); + if (!line) + exit(0); // break; - cli_rl_process_line (line); + if (*line) + cli_rl_process_line(line); - free (line); - } + free(line); + } - return NULL; + return NULL; } - int -cli_rl_enable (struct cli_state *state) +cli_rl_enable(struct cli_state *state) { - int ret = 0; - - rl_pre_input_hook = NULL; - rl_attempted_completion_function = cli_rl_autocomplete; - rl_completion_entry_function = complete_none; - - if (!state->rl_async) { - ret = pthread_create (&state->input, NULL, - cli_rl_input, state); - if (ret == 0) - state->rl_enabled = 1; - goto out; - } + int ret = 0; + + rl_pre_input_hook = NULL; + rl_attempted_completion_function = cli_rl_autocomplete; + rl_completion_entry_function = complete_none; - ret = event_register (state->ctx->event_pool, 0, cli_rl_stdin, state, - 1, 0); - if (ret == -1) - goto out; + if (!state->rl_async) { + ret = pthread_create(&state->input, NULL, cli_rl_input, state); + if (ret == 0) + state->rl_enabled = 1; + goto out; + } - state->rl_enabled = 1; - rl_callback_handler_install (state->prompt, cli_rl_process_line); + ret = gf_event_register(state->ctx->event_pool, 0, cli_rl_stdin, state, 1, + 0, 0); + if (ret == -1) + goto out; + + state->rl_enabled = 1; + rl_callback_handler_install(state->prompt, cli_rl_process_line); out: - return state->rl_enabled; + return state->rl_enabled; } #else /* HAVE_READLINE */ int -cli_rl_enable (struct cli_state *state) +cli_rl_enable(struct cli_state *state) { - return 0; + return 0; } #endif /* HAVE_READLINE */ |
