BLI_string: add BLI_string_elem_split_by_delim
Add a utility function to check if one string contains another when split by a delimiter.
This commit is contained in:
@@ -562,6 +562,27 @@ int BLI_string_find_split_words(const char *str,
|
||||
int r_words[][2],
|
||||
int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 4);
|
||||
|
||||
/**
|
||||
* A version of `STR_ELEM(..)` that treats `haystack` as multiple elements split by `delim`.
|
||||
* Return true when `needle` is found in `haystack`.
|
||||
*
|
||||
* \param haystack: The string to search in.
|
||||
* \param delim: The delimiter which divides haystack.
|
||||
* \param needle: The string to search for
|
||||
* (must not contain `delim` or the result will never be true).
|
||||
*
|
||||
* The following guarantees are made:
|
||||
* - Only an exact match returns true, requiring the strings length and case be match.
|
||||
* - Successive delimiters are supported.
|
||||
* - An empty needle will match against:
|
||||
* - A blank string.
|
||||
* - Delimiters at the beginning or end of the string
|
||||
* - Two successive delimiters.
|
||||
*/
|
||||
bool BLI_string_elem_split_by_delim(const char *haystack,
|
||||
const char delim,
|
||||
const char *needle) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 3);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Copy/Format Macros
|
||||
* Avoid repeating destination with `sizeof(..)`.
|
||||
|
||||
@@ -1117,6 +1117,24 @@ int BLI_string_find_split_words(
|
||||
return n;
|
||||
}
|
||||
|
||||
bool BLI_string_elem_split_by_delim(const char *haystack, const char delim, const char *needle)
|
||||
{
|
||||
/* May be zero, returns true when an empty span exists. */
|
||||
const size_t needle_len = strlen(needle);
|
||||
const char *p = haystack;
|
||||
while (true) {
|
||||
const char *p_next = BLI_strchr_or_end(p, delim);
|
||||
if (((size_t)(p_next - p) == needle_len) && (memcmp(p, needle, needle_len) == 0)) {
|
||||
return true;
|
||||
}
|
||||
if (*p_next == '\0') {
|
||||
break;
|
||||
}
|
||||
p = p_next + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
@@ -1085,6 +1085,56 @@ TEST_F(StringFindSplitWords, LimitChars)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Element
|
||||
* \{ */
|
||||
|
||||
/* #BLI_string_elem_split_by_delim */
|
||||
|
||||
TEST(string, StringElemEmpty)
|
||||
{
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim("A", ':', ""));
|
||||
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("", ':', ""));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim(":", ':', ""));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("::", ':', ""));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("A:", ':', ""));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim(":A", ':', ""));
|
||||
}
|
||||
|
||||
TEST(string, StringElemSingle)
|
||||
{
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("A", ':', "A"));
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim("A", ':', "B"));
|
||||
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("B", 'A', "B"));
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim("A", 'A', "A"));
|
||||
}
|
||||
|
||||
TEST(string, StringElemComplex)
|
||||
{
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST", ':', "TEST"));
|
||||
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim(":TEST", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST:", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim(":TEST:", ':', "TEST"));
|
||||
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("::TEST", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST::", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("::TEST::", ':', "TEST"));
|
||||
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim(":TEST ", ':', "TEST"));
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim(" TEST:", ':', "TEST"));
|
||||
EXPECT_FALSE(BLI_string_elem_split_by_delim(": TEST :", ':', "TEST"));
|
||||
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("A:B:TEST", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("TEST:A:B", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim("A:TEST:B", ':', "TEST"));
|
||||
EXPECT_TRUE(BLI_string_elem_split_by_delim(":A:TEST:B:", ':', "TEST"));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Search (Case Insensitive)
|
||||
* \{ */
|
||||
|
||||
Reference in New Issue
Block a user