]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add patch from FSCORE-89 thank you
authorBrian West <brian@freeswitch.org>
Wed, 16 Jan 2008 20:18:09 +0000 (20:18 +0000)
committerBrian West <brian@freeswitch.org>
Wed, 16 Jan 2008 20:18:09 +0000 (20:18 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7251 d0543943-73ff-0310-b7d9-9358b9ac24b2

docs/AUTHORS
src/switch_utils.c

index e014de015876057f2bd7b9865f366c4955bb39e2..11920cc49bc90887e1b3bdc926039c2d7e91185c 100644 (file)
@@ -34,7 +34,8 @@ that much better:
  Matt Klein <mklein@nmedia.net>\r
  Jonas Gauffin <jonas at gauffin dot org> - Bugfixes and additions in mod_spidermonkey_odbc\r
  Damjan Jovanovic <moctodliamgtavojtodnajmad backwards> - mod_java\r
\r
+ Juan Jose Comellas <juanjo@comellas.org> - Patch to switch_utils for arg parsing.\r
+\r
 A big THANK YOU goes to:\r
 \r
 Justin Cassidy - Build related cleanups and automatic build setup.\r
index a33214e1b0b767b6bb9a09a95de0a9b1f0d047de..caefa2eadb5d08622f6a96c5ab4470968aa5851c 100644 (file)
@@ -24,6 +24,7 @@
  * Contributor(s):
  * 
  * Anthony Minessale II <anthmct@yahoo.com>
+ * Juan Jose Comellas <juanjo@comellas.org>
  *
  *
  * switch_utils.c -- Compatability and Helper Code
@@ -1004,62 +1005,182 @@ SWITCH_DECLARE(char *) switch_escape_char(switch_memory_pool_t *pool, char *in,
        return data;
 }
 
+/* Helper function used when separating strings to unescape a character. The
+   supported characters are:
 
-SWITCH_DECLARE(unsigned int) switch_separate_string(char *buf, char delim, char **array, int arraylen)
+   \n  linefeed
+   \r  carriage return
+   \t  tab
+   \s  space
+
+   Any other character is returned as it was received. */
+static char unescape_char(char escaped)
+{
+       char unescaped;
+       
+       switch (escaped) {
+               case 'n':
+                       unescaped = '\n';
+                       break;
+               case 'r':
+                       unescaped = '\r';
+                       break;
+               case 't':
+                       unescaped = '\t';
+                       break;
+               case 's':
+                       unescaped = ' ';
+                       break;
+               default:
+                       unescaped = escaped;
+       }
+       return unescaped;
+}
+
+/* Helper function used when separating strings to remove quotes, leading /
+   trailing spaces, and to convert escaped characters. */
+static char *cleanup_separated_string(char *str)
 {
-       int argc;
        char *ptr;
-       int quot = 0;
-       char qc = '\'';
-       int x;
+       char *dest;
+       char *start;
+       char *end = NULL;
+       int inside_quotes = 0;
 
-       if (!buf || !array || !arraylen) {
-               return 0;
+       /* Skip initial whitespace */
+       for (ptr = str; *ptr == ' '; ++ptr) {
        }
 
-       memset(array, 0, arraylen * sizeof(*array));
+       for (start = dest = ptr; *ptr; ++ptr) {
+               if (*ptr == '\\') {
+                       ++ptr;
+                       *dest++ = unescape_char(*ptr);
+                       end = dest;
+               } else if (*ptr == '\'') {
+                       inside_quotes = (1 - inside_quotes);
+               } else {
+                       *dest++ = *ptr;
+                       if (*ptr != ' ' || inside_quotes) {
+                               end = dest;
+                       }
+               }
+       }
+       if (end) {
+               *end = '\0';
+       }
+       return start;
+}
 
-       ptr = buf;
+/* Separate a string using a delimiter that is not a space */
+static unsigned int separate_string_char_delim(char *buf, char delim, char **array, int arraylen)
+{
+       enum tokenizer_state {
+               START,
+               FIND_DELIM
+       } state = START;
+
+       unsigned int count = 0;
+       char *ptr = buf;
+       int  inside_quotes = 0;
+       int i;
+       
+       while (*ptr && count < arraylen) {
+               switch (state) {
+                       case START:
+                               array[count++] = ptr;
+                               state = FIND_DELIM;
+                               break;
 
-       for (argc = 0; *ptr && (argc < arraylen - 1); argc++) {
-               array[argc] = ptr;
-               for (; *ptr; ptr++) {
-                       if (*ptr == qc) {
-                               if (quot) {
-                                       quot--;
-                               } else {
-                                       quot++;
+                       case FIND_DELIM:
+                               /* escaped characters are copied verbatim to the destination string */
+                               if (*ptr == '\\') {
+                                       ++ptr;
+                               } else if (*ptr == '\'') {
+                                       inside_quotes = (1 - inside_quotes);
+                               } else if (*ptr == delim && !inside_quotes) {
+                                       *ptr = '\0';
+                                       state = START;
                                }
-                       } else if ((*ptr == delim) && !quot) {
-                               *ptr++ = '\0';
+                               ++ptr;
                                break;
-                       }
                }
        }
-
-       if (*ptr) {
-               array[argc++] = ptr;
+       /* strip quotes, escaped chars and leading / trailing spaces */
+       for (i = 0; i < count; ++i) {
+               array[i] = cleanup_separated_string(array[i]);
        }
+       return count;
+}
 
-       /* strip quotes and leading / trailing spaces */
-       for (x = 0; x < argc; x++) {
-               char *p;
+/* Separate a string using a delimiter that is a space */
+static unsigned int separate_string_blank_delim(char *buf, char **array, int arraylen)
+{
+       enum tokenizer_state {
+               START,
+               SKIP_INITIAL_SPACE,
+               FIND_DELIM,
+               SKIP_ENDING_SPACE
+       } state = START;
+
+       unsigned int count = 0;
+       char *ptr = buf;
+       int  inside_quotes = 0;
+       int i;
 
-               while(*(array[x]) == ' ') {
-                       (array[x])++;
-               }
-               p = array[x];
-               while((p = strchr(array[x], qc))) {
-                       memmove(p, p+1, strlen(p));
-                       p++;
-               }
-               p = array[x] + (strlen(array[x]) - 1);
-               while(*p == ' ') {
-                       *p-- = '\0';
+       while (*ptr && count < arraylen) {
+               switch (state) {
+                       case START:
+                               array[count++] = ptr;
+                               state = SKIP_INITIAL_SPACE;
+                               break;
+
+                       case SKIP_INITIAL_SPACE:
+                               if (*ptr == ' ') {
+                                       ++ptr;
+                               } else {
+                                       state = FIND_DELIM;
+                               }
+                               break;
+
+                       case FIND_DELIM:
+                               if (*ptr == '\\') {
+                                       ++ptr;
+                               } else if (*ptr == '\'') {
+                                       inside_quotes = (1 - inside_quotes);
+                               } else if (*ptr == ' ' && !inside_quotes) {
+                                       *ptr = '\0';
+                                       state = SKIP_ENDING_SPACE;
+                               }
+                               ++ptr;
+                               break;
+
+                       case SKIP_ENDING_SPACE:
+                               if (*ptr == ' ') {
+                                       ++ptr;
+                               } else {
+                                       state = START;
+                               }
+                               break;
                }
        }
+       /* strip quotes, escaped chars and leading / trailing spaces */
+       for (i = 0; i < count; ++i) {
+               array[i] = cleanup_separated_string(array[i]);
+       }
+       return count;
+}
+
+SWITCH_DECLARE(unsigned int) switch_separate_string(char *buf, char delim, char **array, int arraylen)
+{
+       if (!buf || !array || !arraylen) {
+               return 0;
+       }
+
+       memset(array, 0, arraylen * sizeof (*array));
 
-       return argc;
+       return (delim == ' ' ?
+                       separate_string_blank_delim(buf, array, arraylen) :
+                       separate_string_char_delim(buf, delim, array, arraylen));
 }
 
 SWITCH_DECLARE(const char *) switch_cut_path(const char *in)