summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/buffer.c4
-rw-r--r--common/compat.c1
-rw-r--r--common/sock_any.c1
-rw-r--r--common/stringx.c201
-rw-r--r--common/stringx.h9
5 files changed, 214 insertions, 2 deletions
diff --git a/common/buffer.c b/common/buffer.c
index 25494c9..088c2df 100644
--- a/common/buffer.c
+++ b/common/buffer.c
@@ -40,6 +40,8 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
+#include <unistd.h>
+#include <ctype.h>
/* -----------------------------------------------------------------------
* Memory Buffer
@@ -368,7 +370,7 @@ char* ha_bufparseline(ha_buffer_t* buf, int trim)
if(trim)
{
/* Knock out any previous whitespace */
- while(buf->_pp < buf->_rp && isblank(*(buf->_pp)))
+ while(buf->_pp < buf->_rp && strchr (" \t", *(buf->_pp)))
buf->_pp++;
}
diff --git a/common/compat.c b/common/compat.c
index 081a7ee..3ab7ae2 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -33,6 +33,7 @@
#include "compat.h"
#include <stdlib.h>
+#include <ctype.h>
#ifndef HAVE_REALLOCF
diff --git a/common/sock_any.c b/common/sock_any.c
index 714154a..5972e62 100644
--- a/common/sock_any.c
+++ b/common/sock_any.c
@@ -44,6 +44,7 @@
#include <netdb.h>
#include <string.h>
#include <stdio.h>
+#include <ctype.h>
#include "sock_any.h"
diff --git a/common/stringx.c b/common/stringx.c
index 2246cf8..24cf9d1 100644
--- a/common/stringx.c
+++ b/common/stringx.c
@@ -36,9 +36,16 @@
*
*/
-#include <string.h>
#include "stringx.h"
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#define WHITESPACE " \t\r\n\v"
+
const char* trim_start(const char* data)
{
while(*data && isspace(*data))
@@ -64,3 +71,195 @@ char* trim_space(char* data)
data = (char*)trim_start(data);
return trim_end(data);
}
+
+static int
+is_escaped (const char *string, const char *at)
+{
+ int escaped = 0;
+ while (at > string) {
+ at = at - 1;
+ if (*at != '\\')
+ break;
+ escaped = !escaped;
+ }
+ return escaped;
+}
+
+void
+str_unescape (char *str)
+{
+ int len = strlen (str);
+ char *at;
+
+ while (len > 0) {
+ at = strchr (str, '\\');
+ if (!at)
+ break;
+
+ len -= at - str;
+ str = at + 1;
+ --len;
+ memmove (at, str, len);
+ at[len] = 0;
+ }
+}
+
+char**
+str_array_parse_quoted (const char *data)
+{
+ char **array;
+ const char *at;
+ char quote;
+ int n;
+
+ assert (data);
+
+ array = str_array_create (NULL);
+
+ for (n = 0; 1; ++n) {
+ quote = 0;
+
+ /* Strip all leading blanks */
+ while (data && data[0] && strchr (WHITESPACE, data[0]))
+ ++data;
+
+ if (!data || !data[0])
+ break;
+
+ /* See if the next character is a quote */
+ if (data[0] == '\'' || data[0] == '\"') {
+ quote = data[0];
+ ++data;
+ }
+
+ if (quote) {
+ at = data;
+ do {
+ ++data;
+ data = strchr (data, quote);
+ } while (data && is_escaped (at, data));
+
+ if (!data) {
+ array = str_array_append (array, at);
+ } else {
+ array = str_array_appendn (array, at, data - at);
+ ++data;
+ }
+
+ str_unescape (array[n]);
+ } else {
+ at = data;
+ do {
+ ++data;
+ data = data + strcspn (data, WHITESPACE);
+ } while (*data && is_escaped (at, data));
+
+ array = str_array_appendn (array, at, data - at);
+ str_unescape (array[n]);
+ }
+
+ if (!array)
+ break;
+ }
+
+ return array;
+}
+
+char**
+str_array_create (const char *first, ...)
+{
+ char **array;
+ char *value;
+ va_list va;
+
+ array = calloc (32, sizeof (char*));
+ if (!array)
+ return NULL;
+
+ if (first) {
+ array[0] = strdup (first);
+ if (!array[0]) {
+ free (array);
+ return NULL;
+ }
+
+ va_start (va, first);
+ while ((value = va_arg (va, char*)) != NULL) {
+ array = str_array_append (array, value);
+ if (!array)
+ break;
+ }
+ va_end (va);
+ }
+
+ return array;
+}
+
+unsigned int
+str_array_length (char **array)
+{
+ unsigned int length = 0;
+
+ assert (array);
+
+ while (*array) {
+ ++length;
+ ++array;
+ }
+ return length;
+}
+
+char**
+str_array_append (char **array, const char *next)
+{
+ assert (array);
+ assert (next);
+
+ return str_array_appendn (array, next, strlen (next));
+}
+
+char**
+str_array_appendn (char **array, const char *next, unsigned int len)
+{
+ char **narray;
+ int num;
+
+ assert (array);
+ assert (next || !len);
+
+ num = str_array_length (array);
+
+ /*
+ * Actually because of intelligent libc this is not
+ * as inefficient as it looks.
+ */
+ narray = realloc (array, (num + 2) * sizeof (char*));
+ if (!narray) {
+ str_array_free (array);
+ return NULL;
+ }
+
+ narray[num] = malloc (len + 1);
+ if (!narray[num]) {
+ str_array_free (narray);
+ return NULL;
+ }
+ memcpy (narray[num], next, len);
+ narray[num][len] = 0;
+ narray[num + 1] = NULL;
+
+ return narray;
+}
+
+void
+str_array_free (char **array)
+{
+ char **a;
+
+ if (!array);
+ return;
+
+ for (a = array; *a; ++a)
+ free (*a);
+ free (array);
+}
diff --git a/common/stringx.h b/common/stringx.h
index c9a2832..4216d4f 100644
--- a/common/stringx.h
+++ b/common/stringx.h
@@ -43,4 +43,13 @@ const char* trim_start(const char* data);
char* trim_end(char* data);
char* trim_space(char* data);
+void str_unescape (char *str);
+
+unsigned int str_array_length (char **array);
+char** str_array_parse_quoted (const char *data);
+char** str_array_create (const char *first, ...);
+char** str_array_append (char **array, const char *next);
+char** str_array_appendn (char **array, const char *next, unsigned int len);
+void str_array_free (char **array);
+
#endif /* __STRINGX_H__ */