X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/41945ba6ae4e365b39730f56ec0489551f8b42df..7ecd4644e7fe48309d4b8445ec62c7fe8c0443ff:/src/redis-cli.c diff --git a/src/redis-cli.c b/src/redis-cli.c index dd67ff84..2aedcc4a 100644 --- a/src/redis-cli.c +++ b/src/redis-cli.c @@ -89,6 +89,50 @@ static long long mstime(void) { * Help functions *--------------------------------------------------------------------------- */ +#define CLI_HELP_COMMAND 1 +#define CLI_HELP_GROUP 2 + +typedef struct { + int type; + int argc; + sds *argv; + sds full; + + /* Only used for help on commands */ + struct commandHelp *org; +} helpEntry; + +static helpEntry *helpEntries; +static int helpEntriesLen; + +static void cliInitHelp() { + int commandslen = sizeof(commandHelp)/sizeof(struct commandHelp); + int groupslen = sizeof(commandGroups)/sizeof(char*); + int i, len, pos = 0; + helpEntry tmp; + + helpEntriesLen = len = commandslen+groupslen; + helpEntries = malloc(sizeof(helpEntry)*len); + + for (i = 0; i < groupslen; i++) { + tmp.argc = 1; + tmp.argv = malloc(sizeof(sds)); + tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",commandGroups[i]); + tmp.full = tmp.argv[0]; + tmp.type = CLI_HELP_GROUP; + tmp.org = NULL; + helpEntries[pos++] = tmp; + } + + for (i = 0; i < commandslen; i++) { + tmp.argv = sdssplitargs(commandHelp[i].name,&tmp.argc); + tmp.full = sdsnew(commandHelp[i].name); + tmp.type = CLI_HELP_COMMAND; + tmp.org = &commandHelp[i]; + helpEntries[pos++] = tmp; + } +} + /* Output command help to stdout. */ static void cliOutputCommandHelp(struct commandHelp *help, int group) { printf("\r\n \x1b[1m%s\x1b[0m \x1b[90m%s\x1b[0m\r\n", help->name, help->params); @@ -113,9 +157,10 @@ static void cliOutputGenericHelp() { /* Output all command help, filtering by group or command name. */ static void cliOutputHelp(int argc, char **argv) { - int i, len; - struct commandHelp *help; + int i, j, len; int group = -1; + helpEntry *entry; + struct commandHelp *help; if (argc == 0) { cliOutputGenericHelp(); @@ -130,13 +175,21 @@ static void cliOutputHelp(int argc, char **argv) { } } - len = sizeof(commandHelp)/sizeof(struct commandHelp); assert(argc > 0); - for (i = 0; i < len; i++) { - help = &commandHelp[i]; + for (i = 0; i < helpEntriesLen; i++) { + entry = &helpEntries[i]; + if (entry->type != CLI_HELP_COMMAND) continue; + + help = entry->org; if (group == -1) { - if (strcasecmp(help->name, argv[0]) == 0) { - cliOutputCommandHelp(help,1); + /* Compare all arguments */ + if (argc == entry->argc) { + for (j = 0; j < argc; j++) { + if (strcasecmp(argv[j],entry->argv[j]) != 0) break; + } + if (j == argc) { + cliOutputCommandHelp(help,1); + } } } else { if (group == help->group) { @@ -147,69 +200,30 @@ static void cliOutputHelp(int argc, char **argv) { printf("\r\n"); } -#define CLI_COMPLETE_COMMAND 1 -#define CLI_COMPLETE_GROUP 2 - -typedef struct { - char *name; - int type; -} completionEntry; - -static completionEntry *completionEntries; -static int completionEntriesLen; - -/* Build 2 different arrays for completion. One for raw command completion and one - * for completion using HELP (including groups). */ -static void cliInitHelp() { - int commandslen = sizeof(commandHelp)/sizeof(struct commandHelp); - int groupslen = sizeof(commandGroups)/sizeof(char*); - int i, len, pos = 0; - completionEntry tmp; - - completionEntriesLen = len = commandslen+groupslen; - completionEntries = malloc(sizeof(completionEntry)*len); - - for (i = 0; i < groupslen; i++) { - tmp.name = malloc(strlen(commandGroups[i]+2)); - sprintf(tmp.name,"@%s",commandGroups[i]); - tmp.type = CLI_COMPLETE_GROUP; - completionEntries[pos++] = tmp; - } - - for (i = 0; i < commandslen; i++) { - tmp.name = commandHelp[i].name; - tmp.type = CLI_COMPLETE_COMMAND; - completionEntries[pos++] = tmp; - } -} - static void completionCallback(const char *buf, linenoiseCompletions *lc) { size_t startpos = 0; int mask; int i; size_t matchlen; - char *tmp; - size_t tmpsize; + sds tmp; if (strncasecmp(buf,"help ",5) == 0) { startpos = 5; while (isspace(buf[startpos])) startpos++; - mask = CLI_COMPLETE_COMMAND | CLI_COMPLETE_GROUP; + mask = CLI_HELP_COMMAND | CLI_HELP_GROUP; } else { - mask = CLI_COMPLETE_COMMAND; + mask = CLI_HELP_COMMAND; } - for (i = 0; i < completionEntriesLen; i++) { - if (!(completionEntries[i].type & mask)) continue; + for (i = 0; i < helpEntriesLen; i++) { + if (!(helpEntries[i].type & mask)) continue; matchlen = strlen(buf+startpos); - if (strncasecmp(buf+startpos,completionEntries[i].name,matchlen) == 0) { - tmpsize = startpos+strlen(completionEntries[i].name)+1; - tmp = malloc(tmpsize); - memcpy(tmp,buf,startpos); - memcpy(tmp+startpos,completionEntries[i].name,tmpsize-startpos); + if (strncasecmp(buf+startpos,helpEntries[i].full,matchlen) == 0) { + tmp = sdsnewlen(buf,startpos); + tmp = sdscat(tmp,helpEntries[i].full); linenoiseAddCompletion(lc,tmp); - free(tmp); + sdsfree(tmp); } } } @@ -388,6 +402,11 @@ static int cliSendCommand(int argc, char **argv, int repeat) { size_t *argvlen; int j; + if (context == NULL) { + printf("Not connected, please use: connect \n"); + return REDIS_OK; + } + config.raw_output = !strcasecmp(command,"info"); if (!strcasecmp(command,"help") || !strcasecmp(command,"?")) { cliOutputHelp(--argc, ++argv); @@ -434,7 +453,8 @@ static int parseOptions(int argc, char **argv) { int lastarg = i==argc-1; if (!strcmp(argv[i],"-h") && !lastarg) { - config.hostip = argv[i+1]; + sdsfree(config.hostip); + config.hostip = sdsnew(argv[i+1]); i++; } else if (!strcmp(argv[i],"-h") && lastarg) { usage(); @@ -522,7 +542,8 @@ static void repl() { config.interactive = 1; linenoiseSetCompletionCallback(completionCallback); - while((line = linenoise("redis> ")) != NULL) { + + while((line = linenoise(context ? "redis> " : "not connected> ")) != NULL) { if (line[0] != '\0') { argv = sdssplitargs(line,&argc); linenoiseHistoryAdd(line); @@ -535,14 +556,18 @@ static void repl() { strcasecmp(argv[0],"exit") == 0) { exit(0); + } else if (argc == 3 && !strcasecmp(argv[0],"connect")) { + sdsfree(config.hostip); + config.hostip = sdsnew(argv[1]); + config.hostport = atoi(argv[2]); + cliConnect(1); + } else if (argc == 1 && !strcasecmp(argv[0],"clear")) { + linenoiseClearScreen(); } else { long long start_time = mstime(), elapsed; if (cliSendCommand(argc,argv,1) != REDIS_OK) { - printf("Reconnecting... "); - fflush(stdout); - if (cliConnect(1) != REDIS_OK) exit(1); - printf("OK\n"); + cliConnect(1); /* If we still cannot send the command, * print error and abort. */ @@ -582,7 +607,7 @@ static int noninteractive(int argc, char **argv) { int main(int argc, char **argv) { int firstarg; - config.hostip = "127.0.0.1"; + config.hostip = sdsnew("127.0.0.1"); config.hostport = 6379; config.hostsocket = NULL; config.repeat = 1;