Skip to content

Commit 3079b44

Browse files
committed
FFstrbuf: adds more functions to match separated strings
1. ffStrbufMatchSeparatedIgnCaseNS 2. ffStrbufSeparatedContainNS 3. ffStrbufSeparatedContainNS
1 parent 4039006 commit 3079b44

File tree

3 files changed

+140
-1
lines changed

3 files changed

+140
-1
lines changed

src/util/FFstrbuf.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf)
730730
return changed;
731731
}
732732

733-
/// @brief Check if a separated string contains a substring.
733+
/// @brief Check if a separated string (comp) contains a substring (strbuf).
734734
/// @param strbuf The substring to check.
735735
/// @param compLength The length of the separated string to check.
736736
/// @param comp The separated string to check.
@@ -759,6 +759,31 @@ bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const
759759
return false;
760760
}
761761

762+
/// @brief Case insensitive version of ffStrbufMatchSeparatedNS.
763+
bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
764+
{
765+
if (strbuf->length == 0)
766+
return true;
767+
768+
if (compLength == 0)
769+
return false;
770+
771+
for (const char* p = comp; p < comp + compLength;)
772+
{
773+
const char* colon = memchr(p, separator, compLength);
774+
if (colon == NULL)
775+
return strcasecmp(strbuf->chars, p) == 0;
776+
777+
uint32_t substrLength = (uint32_t) (colon - p);
778+
if (strbuf->length == substrLength && strncasecmp(strbuf->chars, p, substrLength) == 0)
779+
return true;
780+
781+
p = colon + 1;
782+
}
783+
784+
return false;
785+
}
786+
762787
int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
763788
{
764789
if (codepoint <= 0x7F) {
@@ -790,3 +815,42 @@ int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint)
790815
ffStrbufAppendS(strbuf, "�"); // U+FFFD REPLACEMENT CHARACTER
791816
return 1;
792817
}
818+
819+
/// @brief Check if a separated string (strbuf) contains a substring (comp).
820+
/// @param strbuf The separated to check.
821+
/// @param compLength The length of the separated string to check.
822+
/// @param comp The substring to check.
823+
/// @param separator The separator character.
824+
bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
825+
{
826+
uint32_t startIndex = 0;
827+
while(startIndex < strbuf->length)
828+
{
829+
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
830+
831+
uint32_t folderLength = colonIndex - startIndex;
832+
if (folderLength == compLength && memcmp(strbuf->chars + startIndex, comp, compLength) == 0)
833+
return true;
834+
835+
startIndex = colonIndex + 1;
836+
}
837+
838+
return false;
839+
}
840+
841+
bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator)
842+
{
843+
uint32_t startIndex = 0;
844+
while(startIndex < strbuf->length)
845+
{
846+
uint32_t colonIndex = ffStrbufNextIndexC(strbuf, startIndex, separator);
847+
848+
uint32_t folderLength = colonIndex - startIndex;
849+
if (folderLength == compLength && strncasecmp(strbuf->chars + startIndex, comp, compLength) == 0)
850+
return true;
851+
852+
startIndex = colonIndex + 1;
853+
}
854+
855+
return false;
856+
}

src/util/FFstrbuf.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,9 @@ bool ffStrbufGetline(char** lineptr, size_t* n, FFstrbuf* buffer);
100100
void ffStrbufGetlineRestore(char** lineptr, size_t* n, FFstrbuf* buffer);
101101
bool ffStrbufRemoveDupWhitespaces(FFstrbuf* strbuf);
102102
bool ffStrbufMatchSeparatedNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
103+
bool ffStrbufMatchSeparatedIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
104+
bool ffStrbufSeparatedContainNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
105+
bool ffStrbufSeparatedContainIgnCaseNS(const FFstrbuf* strbuf, uint32_t compLength, const char* comp, char separator);
103106

104107
int ffStrbufAppendUtf32CodePoint(FFstrbuf* strbuf, uint32_t codepoint);
105108

@@ -566,4 +569,34 @@ static inline bool ffStrbufMatchSeparated(const FFstrbuf* strbuf, const FFstrbuf
566569
return ffStrbufMatchSeparatedNS(strbuf, comp->length, comp->chars, separator);
567570
}
568571

572+
static inline bool ffStrbufMatchSeparatedIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
573+
{
574+
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
575+
}
576+
577+
static inline bool ffStrbufMatchSeparatedIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
578+
{
579+
return ffStrbufMatchSeparatedIgnCaseNS(strbuf, comp->length, comp->chars, separator);
580+
}
581+
582+
static inline bool ffStrbufSeparatedContainS(const FFstrbuf* strbuf, const char* comp, char separator)
583+
{
584+
return ffStrbufSeparatedContainNS(strbuf, (uint32_t) strlen(comp), comp, separator);
585+
}
586+
587+
static inline bool ffStrbufSeparatedContain(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
588+
{
589+
return ffStrbufSeparatedContainNS(strbuf, comp->length, comp->chars, separator);
590+
}
591+
592+
static inline bool ffStrbufSeparatedContainIgnCaseS(const FFstrbuf* strbuf, const char* comp, char separator)
593+
{
594+
return ffStrbufSeparatedContainIgnCaseNS(strbuf, (uint32_t) strlen(comp), comp, separator);
595+
}
596+
597+
static inline bool ffStrbufSeparatedContainIgnCase(const FFstrbuf* strbuf, const FFstrbuf* comp, char separator)
598+
{
599+
return ffStrbufSeparatedContainIgnCaseNS(strbuf, comp->length, comp->chars, separator);
600+
}
601+
569602
#define FF_STRBUF_AUTO_DESTROY FFstrbuf __attribute__((__cleanup__(ffStrbufDestroy)))

tests/strbuf.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,48 @@ int main(void)
663663
VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abc:", ':') == true);
664664
VERIFY(ffStrbufMatchSeparatedS(&strbuf, "abc:", ':') == true);
665665
VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abc", ':') == true);
666+
VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":ABC", ':') == false);
667+
VERIFY(ffStrbufMatchSeparatedS(&strbuf, ":abcdef", ':') == false);
668+
}
669+
670+
{
671+
ffStrbufSetStatic(&strbuf, "ABC");
672+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:def:ghi", ' ') == false);
673+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:def:ghi", ':') == true);
674+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def:ghi", ' ') == false);
675+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def:ghi", ':') == false);
676+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "def", ':') == false);
677+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc", ':') == true);
678+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "", ' ') == false);
679+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abc:", ':') == true);
680+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, "abc:", ':') == true);
681+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abc", ':') == true);
682+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":ABC", ':') == true);
683+
VERIFY(ffStrbufMatchSeparatedIgnCaseS(&strbuf, ":abcdef", ':') == false);
684+
}
685+
686+
{
687+
ffStrbufSetStatic(&strbuf, "abc:def:ghi");
688+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "abc", ' ') == false);
689+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "abc", ':') == true);
690+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "def", ' ') == false);
691+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "def", ':') == true);
692+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "DEF", ':') == false);
693+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "a", ':') == false);
694+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "e", ':') == false);
695+
VERIFY(ffStrbufSeparatedContainS(&strbuf, "i", ':') == false);
696+
}
697+
698+
{
699+
ffStrbufSetStatic(&strbuf, "ABC:DEF:GHI");
700+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "abc", ' ') == false);
701+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "abc", ':') == true);
702+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "def", ' ') == false);
703+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "def", ':') == true);
704+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "DEF", ':') == true);
705+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "a", ':') == false);
706+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "e", ':') == false);
707+
VERIFY(ffStrbufSeparatedContainIgnCaseS(&strbuf, "i", ':') == false);
666708
}
667709

668710
{

0 commit comments

Comments
 (0)