From: Stephan Bosch Date: Wed, 27 Apr 2016 10:46:02 +0000 (+0200) Subject: lib: Finished string trimming functions to trim characters from beginning and/or... X-Git-Tag: 2.3.0.rc1~3892 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e2d420dc4bbb06de56ca225c1d9eb79456c792c5;p=thirdparty%2Fdovecot%2Fcore.git lib: Finished string trimming functions to trim characters from beginning and/or end of a string. This also restructures the code to avoid code duplication as much as possible. --- diff --git a/src/lib/strfuncs.c b/src/lib/strfuncs.c index 602ceb4637..db877141a5 100644 --- a/src/lib/strfuncs.c +++ b/src/lib/strfuncs.c @@ -13,6 +13,11 @@ #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) diff --git a/src/lib/strfuncs.h b/src/lib/strfuncs.h index c84533bacd..8465236113 100644 --- a/src/lib/strfuncs.h +++ b/src/lib/strfuncs.h @@ -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; diff --git a/src/lib/test-strfuncs.c b/src/lib/test-strfuncs.c index 96921dee43..26d7ee4c87 100644 --- a/src/lib/test-strfuncs.c +++ b/src/lib/test-strfuncs.c @@ -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();