diff --git a/src/StringView/StringView.c b/src/StringView/StringView.c index 20b06ec..95f2e88 100644 --- a/src/StringView/StringView.c +++ b/src/StringView/StringView.c @@ -133,6 +133,22 @@ StringView StringView_Slice(StringView string, size_t start, size_t end) return slice; } +bool StringView_Partition(StringView* left, StringView* right, StringView source, StringView delim) +{ + if (source.length == 0) return false; + + size_t offset = StringView_FindStringOffset(source, delim); + if (offset != SIZE_MAX) { + if (left != NULL) *left = StringView_Slice(source, 0, offset); + if (right != NULL) *right = StringView_Slice(source, offset + delim.length, source.length); + } else { + if (left != NULL) *left = source; + if (right != NULL) *right = STRINGVIEW_NONE; + } + + return offset != SIZE_MAX; +} + bool StringView_NextSplit(StringView* dest, StringView* source, StringView delim) { if (source->length == 0) return false; @@ -149,6 +165,23 @@ bool StringView_NextSplit(StringView* dest, StringView* source, StringView delim return true; } +bool StringView_LastSplit(StringView* dest, StringView* source, StringView delim) +{ + StringView s = *source; + while (s.length != 0 && ! StringView_EndsWith(s, delim)) { + s.length -= 1; + } + + if (s.length == 0) { + return false; + } else { + *dest = StringView_Slice(*source, s.length, source->length); + s.length -= delim.length; + *source = s; + return true; + } +} + StringView StringView_StripLeft(StringView sv, StringView strip) { while (StringView_StartsWith(sv, strip)) { diff --git a/src/StringView/StringView.h b/src/StringView/StringView.h index 8be710c..3c57de9 100644 --- a/src/StringView/StringView.h +++ b/src/StringView/StringView.h @@ -46,7 +46,9 @@ size_t StringView_FindStringOffset(StringView haystack, StringView needle); StringView StringView_FindString(StringView haystack, StringView needle); StringView StringView_Slice(StringView string, size_t start, size_t end); // start and end are offsets +bool StringView_Partition(StringView* left, StringView* right, StringView source, StringView delim); bool StringView_NextSplit(StringView* dest, StringView* source, StringView delim); +bool StringView_LastSplit(StringView* dest, StringView* source, StringView delim); StringView StringView_StripLeft(StringView sv, StringView strip); StringView StringView_StripRight(StringView sv, StringView strip); diff --git a/tests/StringView.test.c b/tests/StringView.test.c index 3fd93b7..9f0a4c0 100644 --- a/tests/StringView.test.c +++ b/tests/StringView.test.c @@ -29,8 +29,24 @@ void test_split(void) return; } +void test_fext(void) +{ + const char* filepath = "database.sqlite.old"; + + StringView sourceSV = StringView_FromString(filepath); + StringView delim = StringView_FromString("."); + StringView split; + + assert(StringView_LastSplit(&split, &sourceSV, delim)); + assert(StringView_Equal(split, StringView_FromString("old"))); + assert(StringView_Equal(sourceSV, StringView_FromString("database.sqlite"))); + + return; +} + int main() { test_split(); + test_fext(); return 0; }