mirror of
https://github.com/fluencelabs/redis
synced 2025-03-29 05:41:03 +00:00
redis-cli: integrate help.h with COMMAND output.
Use the COMMAND output to fill with partial information the built-in help. This makes redis-cli able to at least complete commands that are exported by the Redis server it is connected to, but were not available in the help.h file when the redis-cli binary was compiled.
This commit is contained in:
parent
f9ee039a76
commit
8eb43bf72c
@ -130,6 +130,7 @@ static void usage(void);
|
|||||||
static void slaveMode(void);
|
static void slaveMode(void);
|
||||||
char *redisGitSHA1(void);
|
char *redisGitSHA1(void);
|
||||||
char *redisGitDirty(void);
|
char *redisGitDirty(void);
|
||||||
|
static int cliConnect(int force);
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
* Utility functions
|
* Utility functions
|
||||||
@ -238,11 +239,11 @@ static void cliInitHelp(void) {
|
|||||||
helpEntry tmp;
|
helpEntry tmp;
|
||||||
|
|
||||||
helpEntriesLen = len = commandslen+groupslen;
|
helpEntriesLen = len = commandslen+groupslen;
|
||||||
helpEntries = malloc(sizeof(helpEntry)*len);
|
helpEntries = zmalloc(sizeof(helpEntry)*len);
|
||||||
|
|
||||||
for (i = 0; i < groupslen; i++) {
|
for (i = 0; i < groupslen; i++) {
|
||||||
tmp.argc = 1;
|
tmp.argc = 1;
|
||||||
tmp.argv = malloc(sizeof(sds));
|
tmp.argv = zmalloc(sizeof(sds));
|
||||||
tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",commandGroups[i]);
|
tmp.argv[0] = sdscatprintf(sdsempty(),"@%s",commandGroups[i]);
|
||||||
tmp.full = tmp.argv[0];
|
tmp.full = tmp.argv[0];
|
||||||
tmp.type = CLI_HELP_GROUP;
|
tmp.type = CLI_HELP_GROUP;
|
||||||
@ -259,6 +260,64 @@ static void cliInitHelp(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* cliInitHelp() setups the helpEntries array with the command and group
|
||||||
|
* names from the help.h file. However the Redis instance we are connecting
|
||||||
|
* to may support more commands, so this function integrates the previous
|
||||||
|
* entries with additional entries obtained using the COMMAND command
|
||||||
|
* available in recent versions of Redis. */
|
||||||
|
static void cliIntegrateHelp(void) {
|
||||||
|
if (cliConnect(0) == REDIS_ERR) return;
|
||||||
|
|
||||||
|
redisReply *reply = redisCommand(context, "COMMAND");
|
||||||
|
if(reply == NULL || reply->type != REDIS_REPLY_ARRAY) return;
|
||||||
|
|
||||||
|
/* Scan the array reported by COMMAND and fill only the entries that
|
||||||
|
* don't already match what we have. */
|
||||||
|
for (size_t j = 0; j < reply->elements; j++) {
|
||||||
|
redisReply *entry = reply->element[j];
|
||||||
|
char *cmdname = entry->element[0]->str;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < helpEntriesLen; i++) {
|
||||||
|
helpEntry *he = helpEntries+i;
|
||||||
|
if (!strcasecmp(he->argv[0],cmdname))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i != helpEntriesLen) continue;
|
||||||
|
printf("%s\n", cmdname);
|
||||||
|
|
||||||
|
helpEntriesLen++;
|
||||||
|
helpEntries = zrealloc(helpEntries,sizeof(helpEntry)*helpEntriesLen);
|
||||||
|
helpEntry *new = helpEntries+(helpEntriesLen-1);
|
||||||
|
|
||||||
|
new->argc = 1;
|
||||||
|
new->argv = zmalloc(sizeof(sds));
|
||||||
|
new->argv[0] = sdsnew(cmdname);
|
||||||
|
new->full = new->argv[0];
|
||||||
|
new->type = CLI_HELP_COMMAND;
|
||||||
|
sdstoupper(new->argv[0]);
|
||||||
|
|
||||||
|
struct commandHelp *ch = zmalloc(sizeof(*ch));
|
||||||
|
ch->name = new->argv[0];
|
||||||
|
ch->params = sdsempty();
|
||||||
|
int args = llabs(entry->element[1]->integer);
|
||||||
|
if (entry->element[3]->integer == 1) {
|
||||||
|
ch->params = sdscat(ch->params,"key ");
|
||||||
|
args--;
|
||||||
|
}
|
||||||
|
while(args--) ch->params = sdscat(ch->params,"arg ");
|
||||||
|
if (entry->element[1]->integer < 0)
|
||||||
|
ch->params = sdscat(ch->params,"...options...");
|
||||||
|
ch->summary = "Help not available";
|
||||||
|
ch->group = 0;
|
||||||
|
ch->since = "not known";
|
||||||
|
new->org = ch;
|
||||||
|
}
|
||||||
|
freeReplyObject(reply);
|
||||||
|
|
||||||
|
printf("%s\n", helpEntries[80].full);
|
||||||
|
}
|
||||||
|
|
||||||
/* Output command help to stdout. */
|
/* Output command help to stdout. */
|
||||||
static void cliOutputCommandHelp(struct commandHelp *help, int group) {
|
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);
|
printf("\r\n \x1b[1m%s\x1b[0m \x1b[90m%s\x1b[0m\r\n", help->name, help->params);
|
||||||
@ -828,7 +887,7 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Setup argument length */
|
/* Setup argument length */
|
||||||
argvlen = malloc(argc*sizeof(size_t));
|
argvlen = zmalloc(argc*sizeof(size_t));
|
||||||
for (j = 0; j < argc; j++)
|
for (j = 0; j < argc; j++)
|
||||||
argvlen[j] = sdslen(argv[j]);
|
argvlen[j] = sdslen(argv[j]);
|
||||||
|
|
||||||
@ -851,12 +910,12 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
|
|||||||
printf("Entering slave output mode... (press Ctrl-C to quit)\n");
|
printf("Entering slave output mode... (press Ctrl-C to quit)\n");
|
||||||
slaveMode();
|
slaveMode();
|
||||||
config.slave_mode = 0;
|
config.slave_mode = 0;
|
||||||
free(argvlen);
|
zfree(argvlen);
|
||||||
return REDIS_ERR; /* Error = slaveMode lost connection to master */
|
return REDIS_ERR; /* Error = slaveMode lost connection to master */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cliReadReply(output_raw) != REDIS_OK) {
|
if (cliReadReply(output_raw) != REDIS_OK) {
|
||||||
free(argvlen);
|
zfree(argvlen);
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
} else {
|
} else {
|
||||||
/* Store database number when SELECT was successfully executed. */
|
/* Store database number when SELECT was successfully executed. */
|
||||||
@ -871,7 +930,7 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
|
|||||||
fflush(stdout); /* Make it grep friendly */
|
fflush(stdout); /* Make it grep friendly */
|
||||||
}
|
}
|
||||||
|
|
||||||
free(argvlen);
|
zfree(argvlen);
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,7 +1294,7 @@ static void repl(void) {
|
|||||||
|
|
||||||
if (argv == NULL) {
|
if (argv == NULL) {
|
||||||
printf("Invalid argument(s)\n");
|
printf("Invalid argument(s)\n");
|
||||||
free(line);
|
linenoiseFree(line);
|
||||||
continue;
|
continue;
|
||||||
} else if (argc > 0) {
|
} else if (argc > 0) {
|
||||||
if (strcasecmp(argv[0],"quit") == 0 ||
|
if (strcasecmp(argv[0],"quit") == 0 ||
|
||||||
@ -1294,7 +1353,7 @@ static void repl(void) {
|
|||||||
sdsfreesplitres(argv,argc);
|
sdsfreesplitres(argv,argc);
|
||||||
}
|
}
|
||||||
/* linenoise() returns malloc-ed lines like readline() */
|
/* linenoise() returns malloc-ed lines like readline() */
|
||||||
free(line);
|
linenoiseFree(line);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -2159,7 +2218,7 @@ static char *getInfoField(char *info, char *field) {
|
|||||||
n1 = strchr(p,'\r');
|
n1 = strchr(p,'\r');
|
||||||
n2 = strchr(p,',');
|
n2 = strchr(p,',');
|
||||||
if (n2 && n2 < n1) n1 = n2;
|
if (n2 && n2 < n1) n1 = n2;
|
||||||
result = malloc(sizeof(char)*(n1-p)+1);
|
result = zmalloc(sizeof(char)*(n1-p)+1);
|
||||||
memcpy(result,p,(n1-p));
|
memcpy(result,p,(n1-p));
|
||||||
result[n1-p] = '\0';
|
result[n1-p] = '\0';
|
||||||
return result;
|
return result;
|
||||||
@ -2173,7 +2232,7 @@ static long getLongInfoField(char *info, char *field) {
|
|||||||
|
|
||||||
if (!value) return LONG_MIN;
|
if (!value) return LONG_MIN;
|
||||||
l = strtol(value,NULL,10);
|
l = strtol(value,NULL,10);
|
||||||
free(value);
|
zfree(value);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2536,6 +2595,7 @@ int main(int argc, char **argv) {
|
|||||||
config.output = OUTPUT_STANDARD;
|
config.output = OUTPUT_STANDARD;
|
||||||
config.mb_delim = sdsnew("\n");
|
config.mb_delim = sdsnew("\n");
|
||||||
cliInitHelp();
|
cliInitHelp();
|
||||||
|
cliIntegrateHelp();
|
||||||
|
|
||||||
firstarg = parseOptions(argc,argv);
|
firstarg = parseOptions(argc,argv);
|
||||||
argc -= firstarg;
|
argc -= firstarg;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user