diff --git a/src/bxstring.c b/src/bxstring.c index de389ca..6c0b6ff 100644 --- a/src/bxstring.c +++ b/src/bxstring.c @@ -351,6 +351,25 @@ int bxs_is_empty(bxstr_t *pString) +int bxs_is_visible_char(bxstr_t *pString, size_t idx) +{ + int result = 0; + if (pString != NULL) { + for (size_t i = 0; i <= idx && i < pString->num_chars_visible; i++) { + if (pString->visible_char[i] == idx) { + result = 1; + break; + } + else if (pString->visible_char[i] > idx) { + break; + } + } + } + return result; +} + + + int bxs_strcmp(bxstr_t *s1, bxstr_t *s2) { if (s1 == NULL) { diff --git a/src/bxstring.h b/src/bxstring.h index f3f2f83..f035220 100644 --- a/src/bxstring.h +++ b/src/bxstring.h @@ -156,6 +156,16 @@ char *bxs_to_output(bxstr_t *pString); int bxs_is_empty(bxstr_t *pString); +/** + * Determine if the character at position `idx` in the given `pString` is a visible character. If `idx` is out of + * bounds, this function will return 0. + * @param pString the string to check (may be NULL, which means no visible characters) + * @param idx the index in `pString` of the character to check (zero-based) + * @return 1 for visible, 0 for not visible + */ +int bxs_is_visible_char(bxstr_t *pString, size_t idx); + + /** * Determine whether the given `pString` is a valid string under at least one condition. This will return `false` for * strings which should really never occur anywhere. diff --git a/utest/bxstring_test.c b/utest/bxstring_test.c index fdfb81f..b8e88cf 100644 --- a/utest/bxstring_test.c +++ b/utest/bxstring_test.c @@ -906,6 +906,32 @@ void test_bxs_is_empty_null(void **state) +void test_bxs_is_visible_char(void **state) +{ + UNUSED(state); + + uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203mX\x1b[0m \x1b[38;5;203mY\x1b[0m", "ASCII"); + assert_non_null(ustr32); + bxstr_t *input = bxs_from_unicode(ustr32); + + assert_int_equal(0, bxs_is_visible_char(NULL, 4)); + assert_int_equal(0, bxs_is_visible_char(input, 1000)); + assert_int_equal(0, bxs_is_visible_char(input, 0)); + assert_int_equal(0, bxs_is_visible_char(input, 1)); + assert_int_equal(0, bxs_is_visible_char(input, 31)); + assert_int_equal(0, bxs_is_visible_char(input, 32)); + assert_int_equal(0, bxs_is_visible_char(input, 33)); + + assert_int_equal(1, bxs_is_visible_char(input, 11)); + assert_int_equal(1, bxs_is_visible_char(input, 16)); + assert_int_equal(1, bxs_is_visible_char(input, 28)); + + BFREE(ustr32); + bxs_free(input); +} + + + void test_bxs_strcmp(void **state) { UNUSED(state); diff --git a/utest/bxstring_test.h b/utest/bxstring_test.h index 459f192..7778a22 100644 --- a/utest/bxstring_test.h +++ b/utest/bxstring_test.h @@ -67,6 +67,8 @@ void test_bxs_to_output(void **state); void test_bxs_is_empty_null(void **state); +void test_bxs_is_visible_char(void **state); + void test_bxs_strcmp(void **state); void test_bxs_valid_anywhere_error(void **state); diff --git a/utest/main.c b/utest/main.c index fd4f1ab..9425a7d 100644 --- a/utest/main.c +++ b/utest/main.c @@ -153,6 +153,7 @@ int main(void) cmocka_unit_test_setup(test_bxs_rtrim_empty, beforeTest), cmocka_unit_test_setup(test_bxs_to_output, beforeTest), cmocka_unit_test_setup(test_bxs_is_empty_null, beforeTest), + cmocka_unit_test_setup(test_bxs_is_visible_char, beforeTest), cmocka_unit_test_setup(test_bxs_strcmp, beforeTest), cmocka_unit_test_setup(test_bxs_valid_anywhere_error, beforeTest), cmocka_unit_test_setup(test_bxs_valid_in_filename_error, beforeTest),