diff --git a/include/bx/string.h b/include/bx/string.h index 196e547..7ed6fbf 100644 --- a/include/bx/string.h +++ b/include/bx/string.h @@ -248,11 +248,11 @@ namespace bx /// Returns StringView of word or empty. StringView strWord(const StringView& _str); - /// - StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len); + /// Returns substring in string. + StringView strSubstr(const StringView& _str, int32_t _start, int32_t _len = INT32_MAX); /// Find matching block. - const char* strmb(const char* _str, char _open, char _close); + StringView strFindBlock(const StringView& _str, char _open, char _close); // Normalize string to sane line endings. void eolLF(char* _out, int32_t _size, const char* _str); diff --git a/src/string.cpp b/src/string.cpp index f7815e9..86847a2 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -606,26 +606,41 @@ namespace bx return StringView(ptr, term); } - const char* strmb(const char* _str, char _open, char _close) + StringView strFindBlock(const StringView& _str, char _open, char _close) { - int count = 0; - for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++) + const char* curr = _str.getPtr(); + const char* term = _str.getTerm(); + const char* start = NULL; + + int32_t count = 0; + for (char ch = *curr; curr != term && count >= 0; ch = *(++curr) ) { if (ch == _open) { - count++; + if (0 == count) + { + start = curr; + } + + ++count; } else if (ch == _close) { - count--; + --count; + + if (NULL == start) + { + break; + } + if (0 == count) { - return _str-1; + return StringView(start, curr+1); } } } - return NULL; + return StringView(term, term); } void eolLF(char* _out, int32_t _size, const char* _str) diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 15e67dc..180d5ea 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -457,3 +457,13 @@ TEST_CASE("strWord", "") REQUIRE(bx::strWord(" abvgd-1389.0").isEmpty() ); REQUIRE(0 == bx::strCmp(bx::strWord("abvgd-1389.0"), "abvgd") ); } + +TEST_CASE("strFindBlock", "") +{ + const bx::StringView test0("{ { {} {} abvgd; {} } }"); + const bx::StringView test1(test0, 1); + + bx::StringView result = bx::strFindBlock(test1, '{', '}'); + printf("%.*s", result.getLength(), result.getPtr() ); + REQUIRE(19 == result.getLength() ); +}