summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2010-08-05 11:36:39 +0200
committerantirez <antirez@gmail.com>2010-08-05 11:36:39 +0200
commitcbce5171451eb53f1370aacc30decd74512347ac (patch)
treee63e5efce72c10a2ba29f117ee7545988e7b8785
parent1fb4e8def723ac836ba96e5369f22a0bf463578d (diff)
downloadredis-cbce5171451eb53f1370aacc30decd74512347ac.tar.gz
redis cli argument splitting is general and is now moved into the sds.c lib
-rw-r--r--src/redis-cli.c70
-rw-r--r--src/sds.c77
-rw-r--r--src/sds.h1
3 files changed, 81 insertions, 67 deletions
diff --git a/src/redis-cli.c b/src/redis-cli.c
index dac828625..b4a108904 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -366,79 +366,15 @@ static char **convertToSds(int count, char** args) {
return sds;
}
-static char **splitArguments(char *line, int *argc) {
- char *p = line;
- char *current = NULL;
- char **vector = NULL;
-
- *argc = 0;
- while(1) {
- /* skip blanks */
- while(*p && isspace(*p)) p++;
- if (*p) {
- /* get a token */
- int inq=0; /* set to 1 if we are in "quotes" */
- int done = 0;
-
- if (current == NULL) current = sdsempty();
- while(!done) {
- if (inq) {
- if (*p == '\\' && *(p+1)) {
- char c;
-
- p++;
- switch(*p) {
- case 'n': c = '\n'; break;
- case 'r': c = '\r'; break;
- case 't': c = '\t'; break;
- case 'b': c = '\b'; break;
- case 'a': c = '\a'; break;
- default: c = *p; break;
- }
- current = sdscatlen(current,&c,1);
- } else if (*p == '"') {
- done = 1;
- } else {
- current = sdscatlen(current,p,1);
- }
- } else {
- switch(*p) {
- case ' ':
- case '\n':
- case '\r':
- case '\t':
- case '\0':
- done=1;
- break;
- case '"':
- inq=1;
- break;
- default:
- current = sdscatlen(current,p,1);
- break;
- }
- }
- if (*p) p++;
- }
- /* add the token to the vector */
- vector = zrealloc(vector,((*argc)+1)*sizeof(char*));
- vector[*argc] = current;
- (*argc)++;
- current = NULL;
- } else {
- return vector;
- }
- }
-}
-
#define LINE_BUFLEN 4096
static void repl() {
int argc, j;
- char *line, **argv;
+ char *line;
+ sds *argv;
while((line = linenoise("redis> ")) != NULL) {
if (line[0] != '\0') {
- argv = splitArguments(line,&argc);
+ argv = sdssplitargs(line,&argc);
linenoiseHistoryAdd(line);
if (config.historyfile) linenoiseHistorySave(config.historyfile);
if (argc > 0) {
diff --git a/src/sds.c b/src/sds.c
index 5e67f0443..4878f8a62 100644
--- a/src/sds.c
+++ b/src/sds.c
@@ -382,3 +382,80 @@ sds sdscatrepr(sds s, char *p, size_t len) {
}
return sdscatlen(s,"\"",1);
}
+
+/* Split a line into arguments, where every argument can be in the
+ * following programming-language REPL-alike form:
+ *
+ * foo bar "newline are supported\n" and "\xff\x00otherstuff"
+ *
+ * The number of arguments is stored into *argc, and an array
+ * of sds is returned. The caller should sdsfree() all the returned
+ * strings and finally zfree() the array itself.
+ *
+ * Note that sdscatrepr() is able to convert back a string into
+ * a quoted string in the same format sdssplitargs() is able to parse.
+ */
+sds *sdssplitargs(char *line, int *argc) {
+ char *p = line;
+ char *current = NULL;
+ char **vector = NULL;
+
+ *argc = 0;
+ while(1) {
+ /* skip blanks */
+ while(*p && isspace(*p)) p++;
+ if (*p) {
+ /* get a token */
+ int inq=0; /* set to 1 if we are in "quotes" */
+ int done = 0;
+
+ if (current == NULL) current = sdsempty();
+ while(!done) {
+ if (inq) {
+ if (*p == '\\' && *(p+1)) {
+ char c;
+
+ p++;
+ switch(*p) {
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'b': c = '\b'; break;
+ case 'a': c = '\a'; break;
+ default: c = *p; break;
+ }
+ current = sdscatlen(current,&c,1);
+ } else if (*p == '"') {
+ done = 1;
+ } else {
+ current = sdscatlen(current,p,1);
+ }
+ } else {
+ switch(*p) {
+ case ' ':
+ case '\n':
+ case '\r':
+ case '\t':
+ case '\0':
+ done=1;
+ break;
+ case '"':
+ inq=1;
+ break;
+ default:
+ current = sdscatlen(current,p,1);
+ break;
+ }
+ }
+ if (*p) p++;
+ }
+ /* add the token to the vector */
+ vector = zrealloc(vector,((*argc)+1)*sizeof(char*));
+ vector[*argc] = current;
+ (*argc)++;
+ current = NULL;
+ } else {
+ return vector;
+ }
+ }
+}
diff --git a/src/sds.h b/src/sds.h
index ef3a418f2..a0e224f5a 100644
--- a/src/sds.h
+++ b/src/sds.h
@@ -70,5 +70,6 @@ void sdstolower(sds s);
void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, char *p, size_t len);
+sds *sdssplitargs(char *line, int *argc);
#endif