From 4220e3ca6aa28b2cb877f52b3118e4a304cacb8c Mon Sep 17 00:00:00 2001 From: Johan Wikman Date: Tue, 26 Sep 2017 13:34:11 +0300 Subject: [PATCH] MXS-1450 Add more string trimming functions - trim_leading - trim_trailing Implemented trim in terms of trim_leading and trim_trailing --- include/maxscale/utils.h | 34 +++++++++++++++ server/core/test/testutils.cc | 78 ++++++++++++++++++++++++++++------- server/core/utils.c | 42 ++++++++++--------- 3 files changed, 121 insertions(+), 33 deletions(-) diff --git a/include/maxscale/utils.h b/include/maxscale/utils.h index 2b1188b86..aa68d8323 100644 --- a/include/maxscale/utils.h +++ b/include/maxscale/utils.h @@ -81,7 +81,41 @@ void gw_sha1_2_str(const uint8_t *in, int in_len, const uint8_t *in2, int in2_le int gw_getsockerrno(int fd); char *create_hex_sha1_sha1_passwd(char *passwd); +/** + * Trim leading whitespace from a string. + * + * @param str String to trim. + * @return @c str + * + * @note If there is leading whitespace, the string is moved so that + * the returned pointer is always the same as the one given as + * argument. + */ +char* trim_leading(char* str); + +/** + * Trim trailing whitespace from a string. + * + * @param str String to trim. + * @return @c str + * + * @note The returned pointer is always the same the one given as + * argument. + */ +char* trim_trailing(char* str); + +/** + * Trim leading and trailing whitespace from a string. + * + * @param str String to trim. + * @return @c str + * + * @note If there is leading whitespace, the string is moved so that + * the returned pointer is always the same the one given as + * argument. + */ char* trim(char *str); + char* squeeze_whitespace(char* str); bool strip_escape_chars(char*); diff --git a/server/core/test/testutils.cc b/server/core/test/testutils.cc index 9e19ecf66..6dcb3bb53 100644 --- a/server/core/test/testutils.cc +++ b/server/core/test/testutils.cc @@ -13,32 +13,67 @@ #include #include +#include + +using std::cout; +using std::endl; namespace { -#define TRIM_TEST_CASE_ENTRY(zFrom, zTo) { zFrom, zTo } +#define TRIM_TCE(zFrom, zTo) { zFrom, zTo } struct TRIM_TEST_CASE { const char* zFrom; const char* zTo; -} trim_testcases[] = +}; + +TRIM_TEST_CASE trim_testcases[] = { - TRIM_TEST_CASE_ENTRY("", ""), - TRIM_TEST_CASE_ENTRY("a", "a"), - TRIM_TEST_CASE_ENTRY(" a", "a"), - TRIM_TEST_CASE_ENTRY("a ", "a"), - TRIM_TEST_CASE_ENTRY("a ", "a"), - TRIM_TEST_CASE_ENTRY(" a ", "a"), - TRIM_TEST_CASE_ENTRY(" a", "a"), - TRIM_TEST_CASE_ENTRY("a ", "a"), - TRIM_TEST_CASE_ENTRY(" a ", "a"), - TRIM_TEST_CASE_ENTRY(" a b ", "a b"), + TRIM_TCE("", ""), + TRIM_TCE("a", "a"), + TRIM_TCE(" a", "a"), + TRIM_TCE("a ", "a"), + TRIM_TCE(" a ", "a"), + TRIM_TCE(" a", "a"), + TRIM_TCE("a ", "a"), + TRIM_TCE(" a ", "a"), + TRIM_TCE(" a b ", "a b"), }; const int n_trim_testcases = sizeof(trim_testcases) / sizeof(trim_testcases[0]); +TRIM_TEST_CASE trim_leading_testcases[] = +{ + TRIM_TCE("", ""), + TRIM_TCE("a", "a"), + TRIM_TCE(" a", "a"), + TRIM_TCE("a ", "a "), + TRIM_TCE(" a ", "a "), + TRIM_TCE(" a", "a"), + TRIM_TCE("a ", "a "), + TRIM_TCE(" a ", "a "), + TRIM_TCE(" a b ", "a b "), +}; + +const int n_trim_leading_testcases = sizeof(trim_leading_testcases) / sizeof(trim_leading_testcases[0]); + +TRIM_TEST_CASE trim_trailing_testcases[] = +{ + TRIM_TCE("", ""), + TRIM_TCE("a", "a"), + TRIM_TCE(" a", " a"), + TRIM_TCE("a ", "a"), + TRIM_TCE(" a ", " a"), + TRIM_TCE(" a", " a"), + TRIM_TCE("a ", "a"), + TRIM_TCE(" a ", " a"), + TRIM_TCE(" a b ", " a b"), +}; + +const int n_trim_trailing_testcases = sizeof(trim_trailing_testcases) / sizeof(trim_trailing_testcases[0]); + int test(TRIM_TEST_CASE* pTest_cases, int n_test_cases, char* (*p)(char*)) { @@ -63,18 +98,33 @@ int test(TRIM_TEST_CASE* pTest_cases, int n_test_cases, char* (*p)(char*)) return rv; } -int test1() +int test_trim() { + cout << "trim()" << endl; return test(trim_testcases, n_trim_testcases, trim); } +int test_trim_leading() +{ + cout << "trim_leading()" << endl; + return test(trim_leading_testcases, n_trim_leading_testcases, trim_leading); +} + +int test_trim_trailing() +{ + cout << "trim_trailing()" << endl; + return test(trim_trailing_testcases, n_trim_trailing_testcases, trim_trailing); +} + } int main(int argc, char* argv[]) { int rv = 0; - rv += test1(); + rv += test_trim(); + rv += test_trim_leading(); + rv += test_trim_trailing(); return rv; } diff --git a/server/core/utils.c b/server/core/utils.c index 265bfc3bc..9801c0feb 100644 --- a/server/core/utils.c +++ b/server/core/utils.c @@ -433,13 +433,24 @@ bool mxs_mkdir_all(const char *path, int mask) return mkdir_all_internal(local_path, (mode_t)mask); } -/** - * Trim leading and trailing whitespace from a string - * - * @param str String to trim - * @return Trimmed string - */ -char* trim(char *str) +char* trim_leading(char* str) +{ + char* ptr = str; + + while (isspace(*ptr)) + { + ptr++; + } + + if (ptr != str) + { + memmove(str, ptr, strlen(ptr) + 1); + } + + return str; +} + +char* trim_trailing(char* str) { char* ptr = strchr(str, '\0') - 1; @@ -453,21 +464,14 @@ char* trim(char *str) *(ptr + 1) = '\0'; } - ptr = str; - - while (isspace(*ptr)) - { - ptr++; - } - - if (ptr != str) - { - memmove(str, ptr, strlen(ptr) + 1); - } - return str; } +char* trim(char *str) +{ + return trim_leading(trim_trailing(str)); +} + /** * Replace all whitespace with spaces and squeeze repeating whitespace characters *