]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Finished string trimming functions to trim characters from beginning and/or...
authorStephan Bosch <stephan@rename-it.nl>
Wed, 27 Apr 2016 10:46:02 +0000 (12:46 +0200)
committerGitLab <gitlab@git.dovecot.net>
Fri, 29 Apr 2016 19:12:17 +0000 (22:12 +0300)
This also restructures the code to avoid code duplication as much as possible.

src/lib/strfuncs.c
src/lib/strfuncs.h
src/lib/test-strfuncs.c

index 602ceb4637c27a1ce3044979215ed8d4d0ee70c7..db877141a54e7ede96ee7321989f5c87a94b82b9 100644 (file)
 
 #define STRCONCAT_BUFSIZE 512
 
+enum _str_trim_sides {
+       STR_TRIM_LEFT = BIT(0),
+       STR_TRIM_RIGHT = BIT(1),
+};
+
 const unsigned char uchar_nul = '\0';
 
 int i_snprintf(char *dest, size_t max_chars, const char *format, ...)
@@ -365,42 +370,70 @@ const char *t_str_ucase(const char *str)
        return str_ucase(t_strdup_noconst(str));
 }
 
-#if 0 /* FIXME: wait for v2.3 due to a collision with pigeonhole */
-const char *t_str_trim(const char *str, const char *chars)
+static void str_trim_parse(const char *str,
+       const char *chars, enum _str_trim_sides sides,
+       const char **begin_r, const char **end_r)
 {
-       const char *p, *pend, *begin;
+       const char *p, *pend, *begin, *end;
+
+       *begin_r = *end_r = NULL;
 
        pend = str + strlen(str);
        if (pend == str)
-               return "";
+               return;
 
        p = str;
-       while (p < pend && strchr(chars, *p) != NULL)
-               p++;
+       if ((sides & STR_TRIM_LEFT) != 0) {
+               while (p < pend && strchr(chars, *p) != NULL)
+                       p++;
+               if (p == pend)
+                       return;
+       }
        begin = p;
 
-       p = pend - 1;
-       while (p > begin && strchr(chars, *p) != NULL)
-               p--;
+       p = pend;
+       if ((sides & STR_TRIM_RIGHT) != 0) {
+               while (p > begin && strchr(chars, *(p-1)) != NULL)
+                       p--;
+               if (p == begin)
+                       return;
+       }
+       end = p;
+
+       *begin_r = begin;
+       *end_r = end;
+}
+
+const char *t_str_trim(const char *str, const char *chars)
+{
+       const char *begin, *end;
 
-       if (p <= begin)
+       str_trim_parse(str, chars,
+               STR_TRIM_LEFT | STR_TRIM_RIGHT, &begin, &end);
+       if (begin == NULL)
                return "";
-       return t_strdup_until(begin, p+1);
+       return t_strdup_until(begin, end);
 }
-#endif
 
-const char *str_ltrim(const char *str, const char *chars)
+const char *p_str_trim(pool_t pool, const char *str, const char *chars)
 {
-       const char *p;
+       const char *begin, *end;
 
-       if (*str == '\0')
+       str_trim_parse(str, chars,
+               STR_TRIM_LEFT | STR_TRIM_RIGHT, &begin, &end);
+       if (begin == NULL)
                return "";
+       return p_strdup_until(pool, begin, end);
+}
 
-       p = str;
-       while (*p != '\0' && strchr(chars, *p) != NULL)
-               p++;
+const char *str_ltrim(const char *str, const char *chars)
+{
+       const char *begin, *end;
 
-       return p;
+       str_trim_parse(str, chars, STR_TRIM_LEFT, &begin, &end);
+       if (begin == NULL)
+               return "";
+       return begin;
 }
 
 const char *t_str_ltrim(const char *str, const char *chars)
@@ -408,20 +441,29 @@ const char *t_str_ltrim(const char *str, const char *chars)
        return t_strdup(str_ltrim(str, chars));
 }
 
+const char *p_str_ltrim(pool_t pool, const char *str, const char *chars)
+{
+       return p_strdup(pool, str_ltrim(str, chars));
+}
+
 const char *t_str_rtrim(const char *str, const char *chars)
 {
-       const char *p, *pend;
+       const char *begin, *end;
 
-       pend = str + strlen(str);
-       if (pend == str)
+       str_trim_parse(str, chars, STR_TRIM_RIGHT, &begin, &end);
+       if (begin == NULL)
                return "";
+       return t_strdup_until(begin, end);
+}
+
+const char *p_str_rtrim(pool_t pool, const char *str, const char *chars)
+{
+       const char *begin, *end;
 
-       p = pend - 1;
-       while (p > str && strchr(chars, *p) != NULL)
-               p--;
-       if (p <= str)
+       str_trim_parse(str, chars, STR_TRIM_RIGHT, &begin, &end);
+       if (begin == NULL)
                return "";
-       return t_strdup_until(str, p+1);
+       return p_strdup_until(pool, begin, end);
 }
 
 int null_strcmp(const char *s1, const char *s2)
index c84533bacd945357880994e0ec594d7f4f52716d..84652361136ee6054eed5617f14b7f5ce7696493 100644 (file)
@@ -54,10 +54,13 @@ const char *t_str_lcase(const char *str);
 const char *t_str_ucase(const char *str);
 
 /* Trim matching chars from either side of the string */
+const char *t_str_trim(const char *str, const char *chars);
+const char *p_str_trim(pool_t pool, const char *str, const char *chars);
 const char *str_ltrim(const char *str, const char *chars);
 const char *t_str_ltrim(const char *str, const char *chars);
+const char *p_str_ltrim(pool_t pool, const char *str, const char *chars);
 const char *t_str_rtrim(const char *str, const char *chars);
-/*const char *t_str_trim(const char *str, const char *chars);*/
+const char *p_str_rtrim(pool_t pool, const char *str, const char *chars);
 
 int null_strcmp(const char *s1, const char *s2) ATTR_PURE;
 int bsearch_strcmp(const char *key, const char *const *member) ATTR_PURE;
index 96921dee437fdf27872073e73b1831726bf4a3c8..26d7ee4c872a7bd3005ffc9ec178e6c0cbf623a9 100644 (file)
@@ -109,10 +109,13 @@ static void test_t_str_replace(void)
        test_end();
 }
 
-#if 0
 static void test_t_str_trim(void)
 {
        test_begin("t_str_trim");
+       test_assert(strcmp(t_str_trim("", " "), "") == 0);
+       test_assert(strcmp(t_str_trim(" ", " "), "") == 0);
+       test_assert(strcmp(t_str_trim(" \t ", "\t "), "") == 0);
+       test_assert(strcmp(t_str_trim("f \t ", "\t "), "f") == 0);
        test_assert(strcmp(t_str_trim("foo", ""), "foo") == 0);
        test_assert(strcmp(t_str_trim("foo", " "), "foo") == 0);
        test_assert(strcmp(t_str_trim("foo ", " "), "foo") == 0);
@@ -125,11 +128,14 @@ static void test_t_str_trim(void)
        test_assert(strcmp(t_str_trim("\tfoo\tfoo\t", "\t \r"), "foo\tfoo") == 0);
        test_end();
 }
-#endif
 
 static void test_t_str_ltrim(void)
 {
        test_begin("t_str_ltrim");
+       test_assert(strcmp(t_str_ltrim("", " "), "") == 0);
+       test_assert(strcmp(t_str_ltrim(" ", " "), "") == 0);
+       test_assert(strcmp(t_str_ltrim(" \t ", "\t "), "") == 0);
+       test_assert(strcmp(t_str_ltrim(" \t f", "\t "), "f") == 0);
        test_assert(strcmp(t_str_ltrim("foo", ""), "foo") == 0);
        test_assert(strcmp(t_str_ltrim("foo", " "), "foo") == 0);
        test_assert(strcmp(t_str_ltrim("foo ", " "), "foo ") == 0);
@@ -146,6 +152,10 @@ static void test_t_str_ltrim(void)
 static void test_t_str_rtrim(void)
 {
        test_begin("t_str_rtrim");
+       test_assert(strcmp(t_str_rtrim("", " "), "") == 0);
+       test_assert(strcmp(t_str_rtrim(" ", " "), "") == 0);
+       test_assert(strcmp(t_str_rtrim(" \t ", "\t "), "") == 0);
+       test_assert(strcmp(t_str_rtrim("f \t ", "\t "), "f") == 0);
        test_assert(strcmp(t_str_rtrim("foo", ""), "foo") == 0);
        test_assert(strcmp(t_str_rtrim("foo", " "), "foo") == 0);
        test_assert(strcmp(t_str_rtrim("foo ", " "), "foo") == 0);
@@ -221,7 +231,7 @@ void test_strfuncs(void)
        test_t_strsplit();
        test_t_strsplit_tab();
        test_t_str_replace();
-       /*test_t_str_trim();*/
+       test_t_str_trim();
        test_t_str_ltrim();
        test_t_str_rtrim();
        test_t_strarray_join();