]> git.saurik.com Git - redis.git/commitdiff
Merge master and move argument splitting patch to sds.c
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Wed, 25 Aug 2010 07:54:02 +0000 (09:54 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Wed, 25 Aug 2010 11:08:43 +0000 (13:08 +0200)
1  2 
src/redis-cli.c
src/sds.c

diff --cc src/redis-cli.c
index 43cbc55e60cd888dc53b036ec5246af0c405cd34,a2a909ba3d5a3ca510871479ef1e4265a50fd523..1bd0798b3f695d213096807963a19a0962acd317
@@@ -182,12 -186,11 +187,12 @@@ static int cliReadMultiBulkReply(int fd
          printf("(empty list or set)\n");
      }
      while(elements--) {
 -        printf("%d. ", c);
 +        if (config.tty) printf("%d. ", c);
-         if (cliReadReply(fd)) return 1;
+         if (cliReadReply(fd)) retval = 1;
 +        if (elements) printf("%c",config.mb_sep);
          c++;
      }
-     return 0;
+     return retval;
  }
  
  static int cliReadReply(int fd) {
@@@ -458,18 -387,27 +395,30 @@@ static void repl() 
  
      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) {
 +            if (argv == NULL) {
 +                printf("Invalid argument(s)\n");
 +                continue;
 +            } else if (argc > 0) {
                  if (strcasecmp(argv[0],"quit") == 0 ||
                      strcasecmp(argv[0],"exit") == 0)
-                         exit(0);
-                 else
-                     cliSendCommand(argc, argv, 1);
+                 {
+                     exit(0);
+                 } else {
+                     int err;
+                     if ((err = cliSendCommand(argc, argv, 1)) != 0) {
+                         if (err == ECONNRESET) {
+                             printf("Reconnecting... ");
+                             fflush(stdout);
+                             if (cliConnect(1) == -1) exit(1);
+                             printf("OK\n");
+                             cliSendCommand(argc,argv,1);
+                         }
+                     }
+                 }
              }
              /* Free the argument vector */
              for (j = 0; j < argc; j++)
diff --cc src/sds.c
index 5e67f04437a9bcd2bda3db6318bdb0fb4a6752b3,4878f8a625714ce4190555953954f5e24fbcd2af..d7d23c45a859a7aba07981637d7e25def7df8bf1
+++ b/src/sds.c
@@@ -382,3 -382,80 +382,92 @@@ sds sdscatrepr(sds s, char *p, size_t l
      }
      return sdscatlen(s,"\"",1);
  }
 -            int done = 0;
+ /* 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" */
 -                        done = 1;
++            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 == '"') {
++                        /* closing quote must be followed by a space */
++                        if (*(p+1) && !isspace(*(p+1))) goto err;
++                        done=1;
++                    } else if (!*p) {
++                        /* unterminated quotes */
++                        goto err;
+                     } 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;
+         }
+     }
++
++err:
++    while(*argc--)
++        sdsfree(vector[*argc]);
++    zfree(vector);
++    if (current) sdsfree(current);
++    return NULL;
+ }