diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 943d0de82..802b79a80 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -398,7 +398,8 @@ bool ffStrbufSubstrBefore(FFstrbuf* strbuf, uint32_t index) if(strbuf->allocated == 0) { //static string - ffStrbufInitNS(strbuf, strbuf->length, strbuf->chars); + if (index < strbuf->length) + ffStrbufInitNS(strbuf, index, strbuf->chars); return true; } @@ -461,6 +462,26 @@ bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c) return true; } +bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end) +{ + if (__builtin_expect(start >= end, false)) + { + ffStrbufClear(strbuf); + return false; + } + + if (__builtin_expect(start == 0, false)) return ffStrbufSubstrBefore(strbuf, end); + if (__builtin_expect(end >= strbuf->length, false)) return ffStrbufSubstrAfter(strbuf, start - 1); + + uint32_t len = end - start; + ffStrbufEnsureFixedLengthFree(strbuf, len); // In case of static string + memmove(strbuf->chars, strbuf->chars + start, len); + + strbuf->length = len; + strbuf->chars[len] = '\0'; + return true; +} + uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c) { uint32_t result = 0; diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index d7fdab354..3d551d435 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -73,6 +73,7 @@ bool ffStrbufSubstrAfter(FFstrbuf* strbuf, uint32_t index); // Not including the bool ffStrbufSubstrAfterFirstC(FFstrbuf* strbuf, char c); bool ffStrbufSubstrAfterFirstS(FFstrbuf* strbuf, const char* str); bool ffStrbufSubstrAfterLastC(FFstrbuf* strbuf, char c); +bool ffStrbufSubstr(FFstrbuf* strbuf, uint32_t start, uint32_t end); FF_C_NODISCARD uint32_t ffStrbufCountC(const FFstrbuf* strbuf, char c); diff --git a/tests/strbuf.c b/tests/strbuf.c index 8d2c0131c..9781f0d75 100644 --- a/tests/strbuf.c +++ b/tests/strbuf.c @@ -665,6 +665,52 @@ int main(void) VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abc", ':') == true); } + { + ffStrbufSetStatic(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 0, 1); // start, end + VERIFY(ffStrbufEqualS(&strbuf, "a")); + + ffStrbufSetStatic(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 1, 1); + VERIFY(ffStrbufEqualS(&strbuf, "")); + + ffStrbufSetStatic(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 2, 1); + VERIFY(ffStrbufEqualS(&strbuf, "")); + + ffStrbufSetStatic(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 2, 3); + VERIFY(ffStrbufEqualS(&strbuf, "c")); + + ffStrbufSetStatic(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 0, 3); + VERIFY(ffStrbufEqualS(&strbuf, "abc")); + } + + { + ffStrbufSetS(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 0, 1); // start, end + VERIFY(ffStrbufEqualS(&strbuf, "a")); + + ffStrbufSetS(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 1, 1); + VERIFY(ffStrbufEqualS(&strbuf, "")); + + ffStrbufSetS(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 2, 1); + VERIFY(ffStrbufEqualS(&strbuf, "")); + + ffStrbufSetS(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 2, 3); + VERIFY(ffStrbufEqualS(&strbuf, "c")); + + ffStrbufSetS(&strbuf, "abc"); + ffStrbufSubstr(&strbuf, 0, 3); + VERIFY(ffStrbufEqualS(&strbuf, "abc")); + + ffStrbufDestroy(&strbuf); + } + //Success puts("\e[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET); }