dovecot-2.1: Added t_strsplit_tab()

dovecot at dovecot.org dovecot at dovecot.org
Thu Apr 19 23:07:06 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.1/rev/7eb9688c266f
changeset: 14434:7eb9688c266f
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Apr 19 23:00:16 2012 +0300
description:
Added t_strsplit_tab()

diffstat:

 src/lib/strfuncs.c      |  41 ++++++++++++++++++++++++++++++++++++
 src/lib/strfuncs.h      |   2 +
 src/lib/test-strfuncs.c |  55 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 98 insertions(+), 0 deletions(-)

diffs (136 lines):

diff -r 9104a9074a5a -r 7eb9688c266f src/lib/strfuncs.c
--- a/src/lib/strfuncs.c	Thu Apr 19 22:17:34 2012 +0300
+++ b/src/lib/strfuncs.c	Thu Apr 19 23:00:16 2012 +0300
@@ -463,6 +463,47 @@
 	return split_str(pool, data, separators, TRUE);
 }
 
+const char **t_strsplit_tab(const char *data)
+{
+        const char **array;
+	char *dest;
+        unsigned int i, array_idx, array_size, dest_size;
+
+	if (*data == '\0')
+		return t_new(const char *, 1);
+
+	array_size = 1;
+	dest_size = 128;
+	dest = t_buffer_get(dest_size+1);
+	for (i = 0; data[i] != '\0'; i++) {
+		if (i >= dest_size) {
+			dest_size = nearest_power(dest_size+1);
+			dest = t_buffer_reget(dest, dest_size+1);
+		}
+		if (data[i] != '\t')
+			dest[i] = data[i];
+		else {
+			dest[i] = '\0';
+			array_size++;
+		}
+	}
+	i_assert(i <= dest_size);
+	dest[i] = '\0';
+	t_buffer_alloc(i+1);
+	dest_size = i;
+
+	array = t_new(const char *, array_size + 1);
+	array[0] = dest; array_idx = 1;
+
+	for (i = 0; i < dest_size; i++) {
+		if (dest[i] == '\0')
+			array[array_idx++] = dest+i+1;
+	}
+	i_assert(array_idx == array_size);
+	array[array_idx] = NULL;
+        return array;
+}
+
 void p_strsplit_free(pool_t pool, char **arr)
 {
 	p_free(pool, arr[0]);
diff -r 9104a9074a5a -r 7eb9688c266f src/lib/strfuncs.h
--- a/src/lib/strfuncs.h	Thu Apr 19 22:17:34 2012 +0300
+++ b/src/lib/strfuncs.h	Thu Apr 19 23:00:16 2012 +0300
@@ -66,6 +66,8 @@
 const char **t_strsplit_spaces(const char *data, const char *separators)
 	ATTR_MALLOC;
 void p_strsplit_free(pool_t pool, char **arr);
+/* Optimized version of t_strsplit(data, "\t") */
+const char **t_strsplit_tab(const char *data);
 
 const char *dec2str(uintmax_t number);
 
diff -r 9104a9074a5a -r 7eb9688c266f src/lib/test-strfuncs.c
--- a/src/lib/test-strfuncs.c	Thu Apr 19 22:17:34 2012 +0300
+++ b/src/lib/test-strfuncs.c	Thu Apr 19 23:00:16 2012 +0300
@@ -2,6 +2,8 @@
 
 #include "test-lib.h"
 
+#include <stdlib.h>
+
 static void test_p_strarray_dup(void)
 {
 	const char *input[][3] = {
@@ -27,7 +29,60 @@
 	test_end();
 }
 
+static void strsplit_verify(const char *str)
+{
+	T_BEGIN {
+		const char **s1, **s2;
+		unsigned int i;
+
+		s1 = t_strsplit_tab(str);
+		s2 = t_strsplit(str, "\t");
+		for (i = 0; s1[i] != NULL; i++) {
+			test_assert(s2[i] != NULL);
+			test_assert(strcmp(s1[i], s2[i]) == 0);
+		}
+		test_assert(s2[i] == NULL);
+	} T_END;
+}
+
+static void test_t_strsplit_tab(void)
+{
+	char buf[4096];
+	unsigned int i, j, max;
+
+	test_begin("t_strsplit_tab");
+	strsplit_verify("");
+	strsplit_verify("\t");
+	strsplit_verify("\t\t");
+	strsplit_verify("foo");
+	strsplit_verify("foo\tbar");
+	strsplit_verify("foo\tbar\tbaz");
+	strsplit_verify("foo\t\tbaz");
+	buf[sizeof(buf)-1] = '\0';
+	for (i = 0; i < sizeof(buf)-1; i++)
+		buf[i] = '\t';
+	strsplit_verify(buf);
+	for (j = 0; j < 256; j++) {
+		memset(buf, '\t', j);
+		buf[j+1] = '\0';
+		strsplit_verify(buf);
+	}
+	for (j = 0; j < 100; j++) {
+		max = (rand() % sizeof(buf)) + 1;
+		buf[--max] = '\0';
+		for (i = 0; i < max; i++) {
+			if (rand() % 10 == 0)
+				buf[i] = '\t';
+			else
+				buf[i] = 'x';
+		}
+		strsplit_verify(buf);
+	}
+	test_end();
+}
+
 void test_strfuncs(void)
 {
 	test_p_strarray_dup();
+	test_t_strsplit_tab();
 }


More information about the dovecot-cvs mailing list