[Freeswitch-svn] [commit] r7251 - in freeswitch/trunk: docs src

Freeswitch SVN brian at freeswitch.org
Wed Jan 16 15:18:09 EST 2008


Author: brian
Date: Wed Jan 16 15:18:09 2008
New Revision: 7251

Modified:
   freeswitch/trunk/docs/AUTHORS
   freeswitch/trunk/src/switch_utils.c

Log:
add patch from FSCORE-89 thank you

Modified: freeswitch/trunk/docs/AUTHORS
==============================================================================
--- freeswitch/trunk/docs/AUTHORS	(original)
+++ freeswitch/trunk/docs/AUTHORS	Wed Jan 16 15:18:09 2008
@@ -34,7 +34,8 @@
  Matt Klein <mklein at nmedia.net>
  Jonas Gauffin <jonas at gauffin dot org> - Bugfixes and additions in mod_spidermonkey_odbc
  Damjan Jovanovic <moctodliamgtavojtodnajmad backwards> - mod_java
- 
+ Juan Jose Comellas <juanjo at comellas.org> - Patch to switch_utils for arg parsing.
+
 A big THANK YOU goes to:
 
 Justin Cassidy - Build related cleanups and automatic build setup.

Modified: freeswitch/trunk/src/switch_utils.c
==============================================================================
--- freeswitch/trunk/src/switch_utils.c	(original)
+++ freeswitch/trunk/src/switch_utils.c	Wed Jan 16 15:18:09 2008
@@ -24,6 +24,7 @@
  * Contributor(s):
  * 
  * Anthony Minessale II <anthmct at yahoo.com>
+ * Juan Jose Comellas <juanjo at comellas.org>
  *
  *
  * switch_utils.c -- Compatability and Helper Code
@@ -1004,62 +1005,182 @@
 	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)
 {
-	int argc;
-	char *ptr;
-	int quot = 0;
-	char qc = '\'';
-	int x;
+	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;
+}
 
-	if (!buf || !array || !arraylen) {
-		return 0;
+/* Helper function used when separating strings to remove quotes, leading /
+   trailing spaces, and to convert escaped characters. */
+static char *cleanup_separated_string(char *str)
+{
+	char *ptr;
+	char *dest;
+	char *start;
+	char *end = NULL;
+	int inside_quotes = 0;
+
+	/* Skip initial whitespace */
+	for (ptr = str; *ptr == ' '; ++ptr) {
+	}
+
+	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;
+}
 
-	memset(array, 0, arraylen * sizeof(*array));
+/* 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;
 
-	ptr = buf;
+	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;
-			}
 		}
 	}
+	/* strip quotes, escaped chars and leading / trailing spaces */
+	for (i = 0; i < count; ++i) {
+		array[i] = cleanup_separated_string(array[i]);
+	}
+	return count;
+}
+
+/* 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;
 
-	if (*ptr) {
-		array[argc++] = ptr;
-	}
+	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;
 
-	/* strip quotes and leading / trailing spaces */
-	for (x = 0; x < argc; x++) {
-		char *p;
+			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;
 
-		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';
+			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)



More information about the Freeswitch-svn mailing list