Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
ce260f73
Commit
ce260f73
authored
Nov 30, 2010
by
antirez
Browse files
minor merge conflicts merging cli-help branch fixed
parents
d8d528e9
c54afb6d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
ce260f73
...
...
@@ -16,4 +16,7 @@ clean:
$(TARGETS)
:
cd
src
&&
$(MAKE)
$@
src/help.h
:
@
./utils/generate-command-help.rb
>
$@
dummy
:
deps/linenoise/example.c
View file @
ce260f73
...
...
@@ -2,9 +2,18 @@
#include <stdlib.h>
#include "linenoise.h"
void
completion
(
const
char
*
buf
,
linenoiseCompletions
*
lc
)
{
if
(
buf
[
0
]
==
'h'
)
{
linenoiseAddCompletion
(
lc
,
"hello"
);
linenoiseAddCompletion
(
lc
,
"hello there"
);
}
}
int
main
(
void
)
{
char
*
line
;
linenoiseSetCompletionCallback
(
completion
);
linenoiseHistoryLoad
(
"history.txt"
);
/* Load the history at startup */
while
((
line
=
linenoise
(
"hello> "
))
!=
NULL
)
{
if
(
line
[
0
]
!=
'\0'
)
{
...
...
deps/linenoise/linenoise.c
View file @
ce260f73
...
...
@@ -79,10 +79,12 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "linenoise.h"
#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100
#define LINENOISE_MAX_LINE 4096
static
char
*
unsupported_term
[]
=
{
"dumb"
,
"cons25"
,
NULL
};
static
linenoiseCompletionCallback
*
completionCallback
=
NULL
;
static
struct
termios
orig_termios
;
/* in order to restore at exit */
static
int
rawmode
=
0
;
/* for atexit() function to check if restore is needed*/
...
...
@@ -195,6 +197,74 @@ static void refreshLine(int fd, const char *prompt, char *buf, size_t len, size_
if
(
write
(
fd
,
seq
,
strlen
(
seq
))
==
-
1
)
return
;
}
static
void
beep
()
{
fprintf
(
stderr
,
"\x7"
);
fflush
(
stderr
);
}
static
void
freeCompletions
(
linenoiseCompletions
*
lc
)
{
size_t
i
;
for
(
i
=
0
;
i
<
lc
->
len
;
i
++
)
free
(
lc
->
cvec
[
i
]);
if
(
lc
->
cvec
!=
NULL
)
free
(
lc
->
cvec
);
}
static
int
completeLine
(
int
fd
,
const
char
*
prompt
,
char
*
buf
,
size_t
buflen
,
size_t
*
len
,
size_t
*
pos
,
size_t
cols
)
{
linenoiseCompletions
lc
=
{
0
,
NULL
};
int
nread
,
nwritten
;
char
c
=
0
;
completionCallback
(
buf
,
&
lc
);
if
(
lc
.
len
==
0
)
{
beep
();
}
else
{
size_t
stop
=
0
,
i
=
0
;
size_t
clen
;
while
(
!
stop
)
{
/* Show completion or original buffer */
if
(
i
<
lc
.
len
)
{
clen
=
strlen
(
lc
.
cvec
[
i
]);
refreshLine
(
fd
,
prompt
,
lc
.
cvec
[
i
],
clen
,
clen
,
cols
);
}
else
{
refreshLine
(
fd
,
prompt
,
buf
,
*
len
,
*
pos
,
cols
);
}
nread
=
read
(
fd
,
&
c
,
1
);
if
(
nread
<=
0
)
{
freeCompletions
(
&
lc
);
return
-
1
;
}
switch
(
c
)
{
case
9
:
/* tab */
i
=
(
i
+
1
)
%
(
lc
.
len
+
1
);
if
(
i
==
lc
.
len
)
beep
();
break
;
case
27
:
/* escape */
/* Re-show original buffer */
if
(
i
<
lc
.
len
)
{
refreshLine
(
fd
,
prompt
,
buf
,
*
len
,
*
pos
,
cols
);
}
stop
=
1
;
break
;
default:
/* Update buffer and return */
if
(
i
<
lc
.
len
)
{
nwritten
=
snprintf
(
buf
,
buflen
,
"%s"
,
lc
.
cvec
[
i
]);
*
len
=
*
pos
=
nwritten
;
}
stop
=
1
;
break
;
}
}
}
freeCompletions
(
&
lc
);
return
c
;
/* Return last read character */
}
static
int
linenoisePrompt
(
int
fd
,
char
*
buf
,
size_t
buflen
,
const
char
*
prompt
)
{
size_t
plen
=
strlen
(
prompt
);
size_t
pos
=
0
;
...
...
@@ -217,6 +287,18 @@ static int linenoisePrompt(int fd, char *buf, size_t buflen, const char *prompt)
nread
=
read
(
fd
,
&
c
,
1
);
if
(
nread
<=
0
)
return
len
;
/* Only autocomplete when the callback is set. It returns < 0 when
* there was an error reading from fd. Otherwise it will return the
* character that should be handled next. */
if
(
c
==
9
&&
completionCallback
!=
NULL
)
{
c
=
completeLine
(
fd
,
prompt
,
buf
,
buflen
,
&
len
,
&
pos
,
cols
);
/* Return on errors */
if
(
c
<
0
)
return
len
;
/* Read next character when 0 */
if
(
c
==
0
)
continue
;
}
switch
(
c
)
{
case
13
:
/* enter */
case
4
:
/* ctrl-d */
...
...
@@ -402,6 +484,19 @@ char *linenoise(const char *prompt) {
}
}
/* Register a callback function to be called for tab-completion. */
void
linenoiseSetCompletionCallback
(
linenoiseCompletionCallback
*
fn
)
{
completionCallback
=
fn
;
}
void
linenoiseAddCompletion
(
linenoiseCompletions
*
lc
,
char
*
str
)
{
size_t
len
=
strlen
(
str
);
char
*
copy
=
malloc
(
len
+
1
);
memcpy
(
copy
,
str
,
len
+
1
);
lc
->
cvec
=
realloc
(
lc
->
cvec
,
sizeof
(
char
*
)
*
(
lc
->
len
+
1
));
lc
->
cvec
[
lc
->
len
++
]
=
copy
;
}
/* Using a circular buffer is smarter, but a bit more complex to handle. */
int
linenoiseHistoryAdd
(
const
char
*
line
)
{
char
*
linecopy
;
...
...
deps/linenoise/linenoise.h
View file @
ce260f73
...
...
@@ -34,6 +34,15 @@
#ifndef __LINENOISE_H
#define __LINENOISE_H
typedef
struct
linenoiseCompletions
{
size_t
len
;
char
**
cvec
;
}
linenoiseCompletions
;
typedef
void
(
linenoiseCompletionCallback
)(
const
char
*
,
linenoiseCompletions
*
);
void
linenoiseSetCompletionCallback
(
linenoiseCompletionCallback
*
);
void
linenoiseAddCompletion
(
linenoiseCompletions
*
,
char
*
);
char
*
linenoise
(
const
char
*
prompt
);
int
linenoiseHistoryAdd
(
const
char
*
line
);
int
linenoiseHistorySetMaxLen
(
int
len
);
...
...
src/help.h
0 → 100644
View file @
ce260f73
/* Automatically generated by utils/generate-command-help.rb, do not edit. */
#ifndef __REDIS_HELP_H
#define __REDIS_HELP_H
static
char
*
commandGroups
[]
=
{
"generic"
,
"string"
,
"list"
,
"set"
,
"sorted_set"
,
"hash"
,
"pubsub"
,
"transactions"
,
"connection"
,
"server"
};
struct
commandHelp
{
char
*
name
;
char
*
params
;
char
*
summary
;
int
group
;
char
*
since
;
}
commandHelp
[]
=
{
{
"APPEND"
,
"key value"
,
"Append a value to a key"
,
1
,
"1.3.3"
},
{
"AUTH"
,
"password"
,
"Authenticate to the server"
,
8
,
"0.08"
},
{
"BGREWRITEAOF"
,
"-"
,
"Asynchronously rewrite the append-only file"
,
9
,
"1.07"
},
{
"BGSAVE"
,
"-"
,
"Asynchronously save the dataset to disk"
,
9
,
"0.07"
},
{
"BLPOP"
,
"key [key ...] timeout"
,
"Remove and get the first element in a list, or block until one is available"
,
2
,
"1.3.1"
},
{
"BRPOP"
,
"key [key ...] timeout"
,
"Remove and get the last element in a list, or block until one is available"
,
2
,
"1.3.1"
},
{
"CONFIG GET"
,
"parameter"
,
"Get the value of a configuration parameter"
,
9
,
"2.0"
},
{
"CONFIG SET"
,
"parameter value"
,
"Set a configuration parameter to the given value"
,
9
,
"2.0"
},
{
"DBSIZE"
,
"-"
,
"Return the number of keys in the selected database"
,
9
,
"0.07"
},
{
"DEBUG OBJECT"
,
"key"
,
"Get debugging information about a key"
,
9
,
"0.101"
},
{
"DEBUG SEGFAULT"
,
"-"
,
"Make the server crash"
,
9
,
"0.101"
},
{
"DECR"
,
"key decrement"
,
"Decrement the integer value of a key by one"
,
1
,
"0.07"
},
{
"DECRBY"
,
"key decrement"
,
"Decrement the integer value of a key by the given number"
,
1
,
"0.07"
},
{
"DEL"
,
"key [key ...]"
,
"Delete a key"
,
0
,
"0.07"
},
{
"DISCARD"
,
"-"
,
"Discard all commands issued after MULTI"
,
7
,
"1.3.3"
},
{
"ECHO"
,
"message"
,
"Echo the given string"
,
8
,
"0.07"
},
{
"EXEC"
,
"-"
,
"Execute all commands issued after MULTI"
,
7
,
"1.1.95"
},
{
"EXISTS"
,
"key"
,
"Determine if a key exists"
,
9
,
"0.07"
},
{
"EXPIRE"
,
"key seconds"
,
"Set a key's time to live in seconds"
,
0
,
"0.09"
},
{
"EXPIREAT"
,
"key timestamp"
,
"Set the expiration for a key as a UNIX timestamp"
,
0
,
"1.1"
},
{
"FLUSHALL"
,
"-"
,
"Remove all keys from all databases"
,
9
,
"0.07"
},
{
"FLUSHDB"
,
"-"
,
"Remove all keys from the current database"
,
9
,
"0.07"
},
{
"GET"
,
"key"
,
"Get the value of a key"
,
1
,
"0.07"
},
{
"GETSET"
,
"key value"
,
"Set the string value of a key and return its old value"
,
1
,
"0.091"
},
{
"HDEL"
,
"key field"
,
"Delete a hash field"
,
5
,
"1.3.10"
},
{
"HEXISTS"
,
"key field"
,
"Determine if a hash field exists"
,
5
,
"1.3.10"
},
{
"HGET"
,
"key field"
,
"Get the value of a hash field"
,
5
,
"1.3.10"
},
{
"HGETALL"
,
"key"
,
"Get all the fields and values in a hash"
,
5
,
"1.3.10"
},
{
"HINCRBY"
,
"key field increment"
,
"Increment the integer value of a hash field by the given number"
,
5
,
"1.3.10"
},
{
"HKEYS"
,
"key"
,
"Get all the fields in a hash"
,
5
,
"1.3.10"
},
{
"HLEN"
,
"key"
,
"Get the number of fields in a hash"
,
5
,
"1.3.10"
},
{
"HMGET"
,
"key field [field ...]"
,
"Get the values of all the given hash fields"
,
5
,
"1.3.10"
},
{
"HMSET"
,
"key field value [field value ...]"
,
"Set multiple hash fields to multiple values"
,
5
,
"1.3.8"
},
{
"HSET"
,
"key field value"
,
"Set the string value of a hash field"
,
5
,
"1.3.10"
},
{
"HSETNX"
,
"key field value"
,
"Set the value of a hash field, only if the field does not exist"
,
5
,
"1.3.8"
},
{
"HVALS"
,
"key"
,
"Get all the values in a hash"
,
5
,
"1.3.10"
},
{
"INCR"
,
"key"
,
"Increment the integer value of a key by one"
,
1
,
"0.07"
},
{
"INCRBY"
,
"key increment"
,
"Increment the integer value of a key by the given number"
,
1
,
"0.07"
},
{
"INFO"
,
"-"
,
"Get information and statistics about the server"
,
9
,
"0.07"
},
{
"KEYS"
,
"pattern"
,
"Find all keys matching the given pattern"
,
0
,
"0.07"
},
{
"LASTSAVE"
,
"-"
,
"Get the UNIX time stamp of the last successful save to disk"
,
9
,
"0.07"
},
{
"LINDEX"
,
"key index"
,
"Get an element from a list by its index"
,
2
,
"0.07"
},
{
"LINSERT"
,
"key BEFORE|AFTER pivot value"
,
"Insert an element before or after another element in a list"
,
2
,
"2.1.1"
},
{
"LLEN"
,
"key"
,
"Get the length of a list"
,
2
,
"0.07"
},
{
"LPOP"
,
"key"
,
"Remove and get the first element in a list"
,
2
,
"0.07"
},
{
"LPUSH"
,
"key value"
,
"Prepend a value to a list"
,
2
,
"0.07"
},
{
"LPUSHX"
,
"key value"
,
"Prepend a value to a list, only if the list exists"
,
2
,
"2.1.1"
},
{
"LRANGE"
,
"key start stop"
,
"Get a range of elements from a list"
,
2
,
"0.07"
},
{
"LREM"
,
"key count value"
,
"Remove elements from a list"
,
2
,
"0.07"
},
{
"LSET"
,
"key index value"
,
"Set the value of an element in a list by its index"
,
2
,
"0.07"
},
{
"LTRIM"
,
"key start stop"
,
"Trim a list to the specified range"
,
2
,
"0.07"
},
{
"MGET"
,
"key [key ...]"
,
"Get the values of all the given keys"
,
1
,
"0.07"
},
{
"MONITOR"
,
"-"
,
"Listen for all requests received by the server in real time"
,
9
,
"0.07"
},
{
"MOVE"
,
"key db"
,
"Move a key to another database"
,
0
,
"0.07"
},
{
"MSET"
,
"key value [key value ...]"
,
"Set multiple keys to multiple values"
,
1
,
"1.001"
},
{
"MSETNX"
,
"key value [key value ...]"
,
"Set multiple keys to multiple values, only if none of the keys exist"
,
1
,
"1.001"
},
{
"MULTI"
,
"-"
,
"Mark the start of a transaction block"
,
7
,
"1.1.95"
},
{
"PERSIST"
,
"key"
,
"Remove the expiration from a key"
,
0
,
"2.1.2"
},
{
"PING"
,
"-"
,
"Ping the server"
,
8
,
"0.07"
},
{
"PSUBSCRIBE"
,
"pattern"
,
"Listen for messages published to channels matching the given patterns"
,
6
,
"1.3.8"
},
{
"PUBLISH"
,
"channel message"
,
"Post a message to a channel"
,
6
,
"1.3.8"
},
{
"PUNSUBSCRIBE"
,
"[pattern [pattern ...]]"
,
"Stop listening for messages posted to channels matching the given patterns"
,
6
,
"1.3.8"
},
{
"QUIT"
,
"-"
,
"Close the connection"
,
8
,
"0.07"
},
{
"RANDOMKEY"
,
"-"
,
"Return a random key from the keyspace"
,
0
,
"0.07"
},
{
"RENAME"
,
"old new"
,
"Rename a key"
,
0
,
"0.07"
},
{
"RENAMENX"
,
"old new"
,
"Rename a key, only if the new key does not exist"
,
0
,
"0.07"
},
{
"RPOP"
,
"key"
,
"Remove and get the last element in a list"
,
2
,
"0.07"
},
{
"RPOPLPUSH"
,
"source destination"
,
"Remove the last element in a list, append it to another list and return it"
,
2
,
"1.1"
},
{
"RPUSH"
,
"key value"
,
"Append a value to a list"
,
2
,
"0.07"
},
{
"RPUSHX"
,
"key value"
,
"Append a value to a list, only if the list exists"
,
2
,
"2.1.1"
},
{
"SADD"
,
"key member"
,
"Add a member to a set"
,
3
,
"0.07"
},
{
"SAVE"
,
"-"
,
"Synchronously save the dataset to disk"
,
9
,
"0.07"
},
{
"SCARD"
,
"key"
,
"Get the number of members in a set"
,
3
,
"0.07"
},
{
"SDIFF"
,
"key [key ...]"
,
"Subtract multiple sets"
,
3
,
"0.100"
},
{
"SDIFFSTORE"
,
"destination key [key ...]"
,
"Subtract multiple sets and store the resulting set in a key"
,
3
,
"0.100"
},
{
"SELECT"
,
"index"
,
"Change the selected database for the current connection"
,
8
,
"0.07"
},
{
"SET"
,
"key value"
,
"Set the string value of a key"
,
1
,
"0.07"
},
{
"SETEX"
,
"key timestamp value"
,
"Set the value and expiration of a key"
,
1
,
"1.3.10"
},
{
"SETNX"
,
"key value"
,
"Set the value of a key, only if the key does not exist"
,
1
,
"0.07"
},
{
"SHUTDOWN"
,
"-"
,
"Synchronously save the dataset to disk and then shut down the server"
,
9
,
"0.07"
},
{
"SINTER"
,
"key [key ...]"
,
"Intersect multiple sets"
,
3
,
"0.07"
},
{
"SINTERSTORE"
,
"destination key [key ...]"
,
"Intersect multiple sets and store the resulting set in a key"
,
3
,
"0.07"
},
{
"SISMEMBER"
,
"key member"
,
"Determine if a given value is a member of a set"
,
3
,
"0.07"
},
{
"SLAVEOF"
,
"host port"
,
"Make the server a slave of another instance, or promote it as master"
,
9
,
"0.100"
},
{
"SMEMBERS"
,
"key"
,
"Get all the members in a set"
,
3
,
"0.07"
},
{
"SMOVE"
,
"source destination member"
,
"Move a member from one set to another"
,
3
,
"0.091"
},
{
"SORT"
,
"key [BY pattern] [LIMIT start count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]"
,
"Sort the elements in a list, set or sorted set"
,
0
,
"0.07"
},
{
"SPOP"
,
"key"
,
"Remove and return a random member from a set"
,
3
,
"0.101"
},
{
"SRANDMEMBER"
,
"key"
,
"Get a random member from a set"
,
3
,
"1.001"
},
{
"SREM"
,
"key member"
,
"Remove a member from a set"
,
3
,
"0.07"
},
{
"STRLEN"
,
"key"
,
"Get the length of the value stored in a key"
,
1
,
"2.1.2"
},
{
"SUBSCRIBE"
,
"channel"
,
"Listen for messages published to the given channels"
,
6
,
"1.3.8"
},
{
"SUBSTR"
,
"key start stop"
,
"Get a substring of the string stored at a key"
,
1
,
"1.3.4"
},
{
"SUNION"
,
"key [key ...]"
,
"Add multiple sets"
,
3
,
"0.091"
},
{
"SUNIONSTORE"
,
"destination key [key ...]"
,
"Add multiple sets and store the resulting set in a key"
,
3
,
"0.091"
},
{
"SYNC"
,
"-"
,
"Internal command used for replication"
,
9
,
"0.07"
},
{
"TTL"
,
"key"
,
"Get the time to live for a key"
,
0
,
"0.100"
},
{
"TYPE"
,
"key"
,
"Determine the type stored at key"
,
0
,
"0.07"
},
{
"UNSUBSCRIBE"
,
"[channel [channel ...]]"
,
"Stop listening for messages posted to the given channels"
,
6
,
"1.3.8"
},
{
"UNWATCH"
,
"-"
,
"Forget about all watched keys"
,
7
,
"2.1.0"
},
{
"WATCH"
,
"key [key ...]"
,
"Watch the given keys to determine execution of the MULTI/EXEC block"
,
7
,
"2.1.0"
},
{
"ZADD"
,
"key score member"
,
"Add a member to a sorted set, or update its score if it already exists"
,
4
,
"1.1"
},
{
"ZCARD"
,
"key"
,
"Get the number of members in a sorted set"
,
4
,
"1.1"
},
{
"ZCOUNT"
,
"key min max"
,
"Count the members in a sorted set with scores within the given values"
,
4
,
"1.3.3"
},
{
"ZINCRBY"
,
"key increment member"
,
"Increment the score of a member in a sorted set"
,
4
,
"1.1"
},
{
"ZINTERSTORE"
,
"destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]"
,
"Intersect multiple sorted sets and store the resulting sorted set in a new key"
,
4
,
"1.3.10"
},
{
"ZRANGE"
,
"key start stop"
,
"Return a range of members in a sorted set, by index"
,
4
,
"1.1"
},
{
"ZRANGEBYSCORE"
,
"key min max"
,
"Return a range of members in a sorted set, by score"
,
4
,
"1.050"
},
{
"ZRANK"
,
"key member"
,
"Determine the index of a member in a sorted set"
,
4
,
"1.3.4"
},
{
"ZREM"
,
"key member"
,
"Remove a member from a sorted set"
,
4
,
"1.1"
},
{
"ZREMRANGEBYRANK"
,
"key start stop"
,
"Remove all members in a sorted set within the given indexes"
,
4
,
"1.3.4"
},
{
"ZREMRANGEBYSCORE"
,
"key min max"
,
"Remove all members in a sorted set within the given scores"
,
4
,
"1.1"
},
{
"ZREVRANGE"
,
"key start stop"
,
"Return a range of members in a sorted set, by index, with scores ordered from high to low"
,
4
,
"1.1"
},
{
"ZREVRANK"
,
"key member"
,
"Determine the index of a member in a sorted set, with scores ordered from high to low"
,
4
,
"1.3.4"
},
{
"ZSCORE"
,
"key member"
,
"Get the score associated with the given member in a sorted set"
,
4
,
"1.1"
},
{
"ZUNIONSTORE"
,
"destination key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]"
,
"Add multiple sorted sets and store the resulting sorted set in a new key"
,
4
,
"1.3.10"
}
};
#endif
src/redis-cli.c
View file @
ce260f73
...
...
@@ -39,11 +39,13 @@
#include <errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <assert.h>
#include "hiredis.h"
#include "sds.h"
#include "zmalloc.h"
#include "linenoise.h"
#include "help.h"
#define REDIS_NOTUSED(V) ((void) V)
...
...
@@ -83,6 +85,149 @@ static long long mstime(void) {
return
mst
;
}
/*------------------------------------------------------------------------------
* 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
);
printf
(
"
\x1b
[33msummary:
\x1b
[0m %s
\r\n
"
,
help
->
summary
);
printf
(
"
\x1b
[33msince:
\x1b
[0m %s
\r\n
"
,
help
->
since
);
if
(
group
)
{
printf
(
"
\x1b
[33mgroup:
\x1b
[0m %s
\r\n
"
,
commandGroups
[
help
->
group
]);
}
}
/* Print generic help. */
static
void
cliOutputGenericHelp
()
{
printf
(
"redis-cli %s
\r\n
"
"Type:
\"
help @<group>
\"
to get a list of commands in <group>
\r\n
"
"
\"
help <command>
\"
for help on <command>
\r\n
"
"
\"
help <tab>
\"
to get a list of possible help topics
\r\n
"
"
\"
quit
\"
to exit
\r\n
"
,
REDIS_VERSION
);
}
/* Output all command help, filtering by group or command name. */
static
void
cliOutputHelp
(
int
argc
,
char
**
argv
)
{
int
i
,
j
,
len
;
int
group
=
-
1
;
helpEntry
*
entry
;
struct
commandHelp
*
help
;
if
(
argc
==
0
)
{
cliOutputGenericHelp
();
return
;
}
else
if
(
argc
>
0
&&
argv
[
0
][
0
]
==
'@'
)
{
len
=
sizeof
(
commandGroups
)
/
sizeof
(
char
*
);
for
(
i
=
0
;
i
<
len
;
i
++
)
{
if
(
strcasecmp
(
argv
[
0
]
+
1
,
commandGroups
[
i
])
==
0
)
{
group
=
i
;
break
;
}
}
}
assert
(
argc
>
0
);
for
(
i
=
0
;
i
<
helpEntriesLen
;
i
++
)
{
entry
=
&
helpEntries
[
i
];
if
(
entry
->
type
!=
CLI_HELP_COMMAND
)
continue
;
help
=
entry
->
org
;
if
(
group
==
-
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
)
{
cliOutputCommandHelp
(
help
,
0
);
}
}
}
printf
(
"
\r\n
"
);
}
static
void
completionCallback
(
const
char
*
buf
,
linenoiseCompletions
*
lc
)
{
size_t
startpos
=
0
;
int
mask
;
int
i
;
size_t
matchlen
;
sds
tmp
;
if
(
strncasecmp
(
buf
,
"help "
,
5
)
==
0
)
{
startpos
=
5
;
while
(
isspace
(
buf
[
startpos
]))
startpos
++
;
mask
=
CLI_HELP_COMMAND
|
CLI_HELP_GROUP
;
}
else
{
mask
=
CLI_HELP_COMMAND
;
}
for
(
i
=
0
;
i
<
helpEntriesLen
;
i
++
)
{
if
(
!
(
helpEntries
[
i
].
type
&
mask
))
continue
;
matchlen
=
strlen
(
buf
+
startpos
);
if
(
strncasecmp
(
buf
+
startpos
,
helpEntries
[
i
].
full
,
matchlen
)
==
0
)
{
tmp
=
sdsnewlen
(
buf
,
startpos
);
tmp
=
sdscat
(
tmp
,
helpEntries
[
i
].
full
);
linenoiseAddCompletion
(
lc
,
tmp
);
sdsfree
(
tmp
);
}
}
}
/*------------------------------------------------------------------------------
* Networking / parsing
*--------------------------------------------------------------------------- */
...
...
@@ -252,22 +397,6 @@ static int cliReadReply() {
return
REDIS_OK
;
}
static
void
showInteractiveHelp
(
void
)
{
printf
(
"
\n
"
"Welcome to redis-cli "
REDIS_VERSION
"!
\n
"
"Just type any valid Redis command to see a pretty printed output.
\n
"
"
\n
"
"It is possible to quote strings, like in:
\n
"
" set
\"
my key
\"
\"
some string
\\
xff
\\
n
\"\n
"
"
\n
"
"You can find a list of valid Redis commands at
\n
"
" http://code.google.com/p/redis/wiki/CommandReference
\n
"
"
\n
"
"Note: redis-cli supports line editing, use up/down arrows for history."
"
\n\n
"
);
}
static
int
cliSendCommand
(
int
argc
,
char
**
argv
,
int
repeat
)
{
char
*
command
=
argv
[
0
];
size_t
*
argvlen
;
...
...
@@ -279,8 +408,8 @@ static int cliSendCommand(int argc, char **argv, int repeat) {
}
config
.
raw_output
=
!
strcasecmp
(
command
,
"info"
);
if
(
!
strcasecmp
(
command
,
"help"
))
{
showInteractiveHelp
(
);
if
(
!
strcasecmp
(
command
,
"help"
)
||
!
strcasecmp
(
command
,
"?"
)
)
{
cliOutputHelp
(
--
argc
,
++
argv
);
return
REDIS_OK
;
}
if
(
!
strcasecmp
(
command
,
"shutdown"
))
config
.
shutdown
=
1
;
...
...
@@ -412,6 +541,8 @@ static void repl() {
sds
*
argv
;
config
.
interactive
=
1
;
linenoiseSetCompletionCallback
(
completionCallback
);
while
((
line
=
linenoise
(
context
?
"redis> "
:
"not connected> "
))
!=
NULL
)
{
if
(
line
[
0
]
!=
'\0'
)
{
argv
=
sdssplitargs
(
line
,
&
argc
);
...
...
@@ -489,6 +620,7 @@ int main(int argc, char **argv) {
config
.
historyfile
=
NULL
;
config
.
tty
=
isatty
(
fileno
(
stdout
))
||
(
getenv
(
"FAKETTY"
)
!=
NULL
);
config
.
mb_sep
=
'\n'
;
cliInitHelp
();
if
(
getenv
(
"HOME"
)
!=
NULL
)
{
config
.
historyfile
=
malloc
(
256
);
...
...
utils/generate-command-help.rb
0 → 100755
View file @
ce260f73
#!/usr/bin/env ruby
GROUPS
=
[
"generic"
,
"string"
,
"list"
,
"set"
,
"sorted_set"
,
"hash"
,
"pubsub"
,
"transactions"
,
"connection"
,
"server"
].
freeze
GROUPS_BY_NAME
=
Hash
[
*
GROUPS
.
each_with_index
.
map
do
|
n
,
i
|
[
n
,
i
]
end
.
flatten
].
freeze
def
argument
arg
name
=
arg
[
"name"
].
is_a?
(
Array
)
?
arg
[
"name"
].
join
(
" "
)
:
arg
[
"name"
]
name
=
arg
[
"enum"
].
join
"|"
if
"enum"
==
arg
[
"type"
]
name
=
arg
[
"command"
]
+
" "
+
name
if
arg
[
"command"
]
if
arg
[
"multiple"
]
name
=
"
#{
name
}
[
#{
name
}
...]"
end
if
arg
[
"optional"
]
name
=
"[
#{
name
}
]"
end
name
end
def
arguments
command
return
"-"
unless
command
[
"arguments"
]
command
[
"arguments"
].
map
do
|
arg
|
argument
arg
end
.
join
" "
end
def
commands
return
@commands
if
@commands
require
"net/http"
require
"net/https"
require
"json"
require
"uri"
url
=
URI
.
parse
"https://github.com/antirez/redis-doc/raw/master/commands.json"
client
=
Net
::
HTTP
.
new
url
.
host
,
url
.
port
client
.
use_ssl
=
true
response
=
client
.
get
url
.
path
if
response
.
is_a?
(
Net
::
HTTPSuccess
)
@commands
=
JSON
.
parse
(
response
.
body
)
else
response
.
error!
end
end
def
generate_groups
GROUPS
.
map
do
|
n
|
"
\"
#{
n
}
\"
"
end
.
join
(
",
\n
"
);
end
def
generate_commands
commands
.
to_a
.
sort
do
|
x
,
y
|
x
[
0
]
<=>
y
[
0
]
end
.
map
do
|
key
,
command
|
group
=
GROUPS_BY_NAME
[
command
[
"group"
]]
if
group
.
nil?
STDERR
.
puts
"Please update groups array in
#{
__FILE__
}
"
raise
"Unknown group
#{
command
[
"group"
]
}
"
end
ret
=
<<-
SPEC
{ "
#{
key
}
",
"
#{
arguments
(
command
)
}
",
"
#{
command
[
"summary"
]
}
",
#{
group
}
,
"
#{
command
[
"since"
]
}
" }
SPEC
ret
.
strip
end
.
join
(
",
\n
"
)
end
# Write to stdout
puts
<<-
HELP_H
/* Automatically generated by
#{
__FILE__
}
, do not edit. */
#ifndef __REDIS_HELP_H
#define __REDIS_HELP_H
static char *commandGroups[] = {
#{
generate_groups
}
};
struct commandHelp {
char *name;
char *params;
char *summary;
int group;
char *since;
} commandHelp[] = {
#{
generate_commands
}
};
#endif
HELP_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment