diff --git a/src/bxstring.c b/src/bxstring.c index 8fcb67b..4bc4629 100644 --- a/src/bxstring.c +++ b/src/bxstring.c @@ -398,6 +398,24 @@ bxstr_t *bxs_trim(bxstr_t *pString) +uint32_t *bxs_ltrim(bxstr_t *pString, size_t max) +{ + if (pString == NULL) { + return NULL; + } + + size_t num_trimmed = BMIN(max, pString->num_chars_visible); + for (size_t i = 0; i < max; i++) { + if (!is_blank(pString->memory[pString->visible_char[i]])) { + num_trimmed = i; + break; + } + } + return u32_strdup(pString->memory + pString->first_char[num_trimmed]); +} + + + bxstr_t *bxs_rtrim(bxstr_t *pString) { if (pString == NULL) { diff --git a/src/bxstring.h b/src/bxstring.h index 9d022c8..bc1a1ad 100644 --- a/src/bxstring.h +++ b/src/bxstring.h @@ -179,6 +179,16 @@ uint32_t *bxs_unindent_ptr(bxstr_t *pString); bxstr_t *bxs_trim(bxstr_t *pString); +/** + * Create a new string from which up to `max` leading spaces have been removed along with associated invisible + * characters. + * @param pString the string to trim, which will not be modified + * @param max the maximum number of leading spaces to remove + * @return a new, trimmed string + */ +uint32_t *bxs_ltrim(bxstr_t *pString, size_t max); + + /** * Create a new string from which all trailing whitespace have been removed. * @param pString the string to trim, which will not be modified diff --git a/utest/bxstring_test.c b/utest/bxstring_test.c index 3843c19..8543830 100644 --- a/utest/bxstring_test.c +++ b/utest/bxstring_test.c @@ -914,6 +914,95 @@ void test_bxs_trim_none(void **state) +void test_bxs_ltrim2(void **state) +{ + UNUSED(state); + + uint32_t *ustr32 = u32_strconv_from_arg("\xe2\x80\x83 \x1b[38;5;203m\xe2\x80\x82\x1b[0m X", "UTF-8"); + /* em-space, space, en-space, space, X */ + bxstr_t *bxstr = bxs_from_unicode(ustr32); + uint32_t *expected = u32_strconv_from_arg("\x1b[38;5;203m\xe2\x80\x82\x1b[0m X", "UTF-8"); + + uint32_t *actual = bxs_ltrim(bxstr, 2); + + assert_non_null(actual); + assert_int_equal(0, u32_strcmp(expected, actual)); + + BFREE(ustr32); + BFREE(actual); + BFREE(expected); + bxs_free(bxstr); +} + + + +void test_bxs_ltrim5(void **state) +{ + UNUSED(state); + + uint32_t *ustr32 = u32_strconv_from_arg("\xe2\x80\x83 \x1b[38;5;203m\xe2\x80\x82\x1b[0m abc", "UTF-8"); + /* em-space, space, en-space, space, abc */ + bxstr_t *bxstr = bxs_from_unicode(ustr32); + uint32_t *expected = u32_strconv_from_arg("abc", "ASCII"); + + uint32_t *actual = bxs_ltrim(bxstr, 5); + + assert_non_null(actual); + assert_int_equal(0, u32_strcmp(expected, actual)); + + BFREE(ustr32); + BFREE(actual); + BFREE(expected); + bxs_free(bxstr); +} + + + +void test_bxs_ltrim_empty(void **state) +{ + UNUSED(state); + + uint32_t *actual = bxs_ltrim(NULL, 2); + assert_null(actual); + + uint32_t *ustr32 = u32_strconv_from_arg("\xe2\x80\x83 \x1b[38;5;203m\xe2\x80\x82\x1b[0m X", "UTF-8"); + /* em-space, space, en-space, space, X */ + bxstr_t *bxstr = bxs_from_unicode(ustr32); + + actual = bxs_ltrim(bxstr, 0); + assert_ptr_not_equal(ustr32, actual); + assert_int_equal(0, u32_strcmp(ustr32, actual)); + + BFREE(ustr32); + BFREE(actual); + bxs_free(bxstr); +} + + + +void test_bxs_ltrim_max(void **state) +{ + UNUSED(state); + + uint32_t *ustr32 = u32_strconv_from_arg("\xe2\x80\x83 \x1b[38;5;203m\xe2\x80\x82\x1b[0m ", "UTF-8"); + /* em-space, space, en-space, space */ + bxstr_t *bxstr = bxs_from_unicode(ustr32); + uint32_t *expected = new_empty_string32(); + + uint32_t *actual = bxs_ltrim(bxstr, 20); + + assert_non_null(actual); + assert_int_equal(0, u32_strlen(actual)); + assert_int_equal(0, u32_strcmp(expected, actual)); + + BFREE(ustr32); + BFREE(actual); + BFREE(expected); + bxs_free(bxstr); +} + + + void test_bxs_rtrim(void **state) { UNUSED(state); diff --git a/utest/bxstring_test.h b/utest/bxstring_test.h index 1a5c9c6..04a171a 100644 --- a/utest/bxstring_test.h +++ b/utest/bxstring_test.h @@ -67,6 +67,11 @@ void test_bxs_trim(void **state); void test_bxs_trim_blanks(void **state); void test_bxs_trim_none(void **state); +void test_bxs_ltrim2(void **state); +void test_bxs_ltrim5(void **state); +void test_bxs_ltrim_empty(void **state); +void test_bxs_ltrim_max(void **state); + void test_bxs_rtrim(void **state); void test_bxs_rtrim_empty(void **state); diff --git a/utest/main.c b/utest/main.c index b7871ce..bbcc3b0 100644 --- a/utest/main.c +++ b/utest/main.c @@ -157,6 +157,10 @@ int main(void) cmocka_unit_test_setup(test_bxs_trim, beforeTest), cmocka_unit_test_setup(test_bxs_trim_blanks, beforeTest), cmocka_unit_test_setup(test_bxs_trim_none, beforeTest), + cmocka_unit_test_setup(test_bxs_ltrim2, beforeTest), + cmocka_unit_test_setup(test_bxs_ltrim5, beforeTest), + cmocka_unit_test_setup(test_bxs_ltrim_empty, beforeTest), + cmocka_unit_test_setup(test_bxs_ltrim_max, beforeTest), cmocka_unit_test_setup(test_bxs_rtrim, beforeTest), cmocka_unit_test_setup(test_bxs_rtrim_empty, beforeTest), cmocka_unit_test_setup(test_bxs_append_spaces, beforeTest),