Improve flags in string library
This commit is contained in:
@@ -74,7 +74,7 @@ S8_API bool S8_AreEqual(S8_String a, S8_String b, unsigned ignore_case) {
|
||||
for (int64_t i = 0; i < a.len; i++) {
|
||||
char A = a.str[i];
|
||||
char B = b.str[i];
|
||||
if (ignore_case & S8_IGNORE_CASE) {
|
||||
if (ignore_case) {
|
||||
A = CHAR_ToLowerCase(A);
|
||||
B = CHAR_ToLowerCase(B);
|
||||
}
|
||||
@@ -169,6 +169,10 @@ S8_API S8_String S8_GetPrefix(S8_String string, int64_t len) {
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_String S8_GetNameNoExtension(S8_String s) {
|
||||
return S8_SkipToLastSlash(S8_ChopLastPeriod(s));
|
||||
}
|
||||
|
||||
S8_API S8_String S8_Slice(S8_String string, int64_t first_index, int64_t one_past_last_index) {
|
||||
if (one_past_last_index < 0) one_past_last_index = string.len + one_past_last_index + 1;
|
||||
if (first_index < 0) first_index = string.len + first_index;
|
||||
@@ -245,13 +249,14 @@ S8_API S8_String S8_ToUpperCase(S8_Allocator allocator, S8_String s) {
|
||||
return copy;
|
||||
}
|
||||
|
||||
S8_API bool S8_Find(S8_String string, S8_String find, unsigned flags, int64_t *index_out) {
|
||||
S8_API bool S8_Find(S8_String string, S8_String find, S8_FindFlag flags, int64_t *index_out) {
|
||||
bool ignore_case = flags & S8_FindFlag_IgnoreCase ? true : false;
|
||||
bool result = false;
|
||||
if (flags & S8_MATCH_FIND_LAST) {
|
||||
if (flags & S8_FindFlag_MatchFindLast) {
|
||||
for (int64_t i = string.len; i != 0; i--) {
|
||||
int64_t index = i - 1;
|
||||
S8_String substring = S8_Slice(string, index, index + find.len);
|
||||
if (S8_AreEqual(substring, find, flags)) {
|
||||
if (S8_AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = index;
|
||||
result = true;
|
||||
@@ -262,7 +267,7 @@ S8_API bool S8_Find(S8_String string, S8_String find, unsigned flags, int64_t *i
|
||||
else {
|
||||
for (int64_t i = 0; i < string.len; i++) {
|
||||
S8_String substring = S8_Slice(string, i, i + find.len);
|
||||
if (S8_AreEqual(substring, find, flags)) {
|
||||
if (S8_AreEqual(substring, find, ignore_case)) {
|
||||
if (index_out)
|
||||
*index_out = i;
|
||||
result = true;
|
||||
@@ -274,14 +279,15 @@ S8_API bool S8_Find(S8_String string, S8_String find, unsigned flags, int64_t *i
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_List S8_Split(S8_Allocator allocator, S8_String string, S8_String find, unsigned flags) {
|
||||
S8_ASSERT((flags & S8_MATCH_FIND_LAST) == 0);
|
||||
S8_API S8_List S8_Split(S8_Allocator allocator, S8_String string, S8_String find, S8_SplitFlag flags) {
|
||||
S8_List result = S8_MakeEmptyList();
|
||||
int64_t index = 0;
|
||||
while (S8_Find(string, find, flags, &index)) {
|
||||
|
||||
S8_FindFlag find_flag = flags & S8_SplitFlag_IgnoreCase ? S8_FindFlag_IgnoreCase : S8_FindFlag_None;
|
||||
while (S8_Find(string, find, find_flag, &index)) {
|
||||
S8_String before_match = S8_Make(string.str, index);
|
||||
S8_AddNode(allocator, &result, before_match);
|
||||
if (flags & S8_SPLIT_INCLUSIVE) {
|
||||
if (flags & S8_SplitFlag_SplitInclusive) {
|
||||
S8_String match = S8_Make(string.str + index, find.len);
|
||||
S8_AddNode(allocator, &result, match);
|
||||
}
|
||||
@@ -294,7 +300,7 @@ S8_API S8_List S8_Split(S8_Allocator allocator, S8_String string, S8_String find
|
||||
S8_API S8_String S8_MergeWithSeparator(S8_Allocator allocator, S8_List list, S8_String separator) {
|
||||
if (list.node_count == 0) return S8_MakeEmpty();
|
||||
if (list.char_count == 0) return S8_MakeEmpty();
|
||||
// S8_ASSERT((flags & S8_MATCH_FIND_LAST) == 0);
|
||||
|
||||
int64_t base_size = (list.char_count + 1);
|
||||
int64_t sep_size = (list.node_count - 1) * separator.len;
|
||||
int64_t size = base_size + sep_size;
|
||||
@@ -318,11 +324,11 @@ S8_API S8_String S8_Merge(S8_Allocator allocator, S8_List list) {
|
||||
return S8_MergeWithSeparator(allocator, list, S8_Lit(""));
|
||||
}
|
||||
|
||||
S8_API S8_String S8_ReplaceAll(S8_Allocator allocator, S8_String string, S8_String replace, S8_String with, unsigned flags) {
|
||||
S8_ASSERT((flags & S8_MATCH_FIND_LAST) == 0);
|
||||
S8_List list = S8_Split(allocator, string, replace, flags | S8_SPLIT_INCLUSIVE);
|
||||
S8_API S8_String S8_ReplaceAll(S8_Allocator allocator, S8_String string, S8_String replace, S8_String with, bool ignore_case) {
|
||||
S8_SplitFlag split_flag = ignore_case ? S8_SplitFlag_IgnoreCase : S8_SplitFlag_None;
|
||||
S8_List list = S8_Split(allocator, string, replace, split_flag | S8_SplitFlag_SplitInclusive);
|
||||
for (S8_Node *it = list.first; it; it = it->next) {
|
||||
if (S8_AreEqual(it->string, replace, flags)) {
|
||||
if (S8_AreEqual(it->string, replace, ignore_case)) {
|
||||
S8_ReplaceNodeString(&list, it, with);
|
||||
}
|
||||
}
|
||||
@@ -330,11 +336,12 @@ S8_API S8_String S8_ReplaceAll(S8_Allocator allocator, S8_String string, S8_Stri
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_List S8_FindAll(S8_Allocator allocator, S8_String string, S8_String find, unsigned flags) { // @untested
|
||||
S8_ASSERT((flags & S8_MATCH_FIND_LAST) == 0);
|
||||
S8_API S8_List S8_FindAll(S8_Allocator allocator, S8_String string, S8_String find, bool ignore_case) { // @untested
|
||||
S8_List result = S8_MakeEmptyList();
|
||||
int64_t index = 0;
|
||||
while (S8_Find(string, find, flags, &index)) {
|
||||
|
||||
S8_FindFlag find_flag = ignore_case ? S8_FindFlag_IgnoreCase : 0;
|
||||
while (S8_Find(string, find, find_flag, &index)) {
|
||||
S8_String match = S8_Make(string.str + index, find.len);
|
||||
S8_AddNode(allocator, &result, match);
|
||||
string = S8_Skip(string, index + find.len);
|
||||
@@ -344,20 +351,20 @@ S8_API S8_List S8_FindAll(S8_Allocator allocator, S8_String string, S8_String fi
|
||||
|
||||
S8_API S8_String S8_ChopLastSlash(S8_String s) {
|
||||
S8_String result = s;
|
||||
S8_Find(s, S8_Lit("/"), S8_MATCH_FIND_LAST, &result.len);
|
||||
S8_Find(s, S8_Lit("/"), S8_FindFlag_MatchFindLast, &result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_String S8_ChopLastPeriod(S8_String s) {
|
||||
S8_String result = s;
|
||||
S8_Find(s, S8_Lit("."), S8_MATCH_FIND_LAST, &result.len);
|
||||
S8_Find(s, S8_Lit("."), S8_FindFlag_MatchFindLast, &result.len);
|
||||
return result;
|
||||
}
|
||||
|
||||
S8_API S8_String S8_SkipToLastSlash(S8_String s) {
|
||||
int64_t pos;
|
||||
S8_String result = s;
|
||||
if (S8_Find(s, S8_Lit("/"), S8_MATCH_FIND_LAST, &pos)) {
|
||||
if (S8_Find(s, S8_Lit("/"), S8_FindFlag_MatchFindLast, &pos)) {
|
||||
result = S8_Skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
@@ -366,7 +373,7 @@ S8_API S8_String S8_SkipToLastSlash(S8_String s) {
|
||||
S8_API S8_String S8_SkipToLastPeriod(S8_String s) {
|
||||
int64_t pos;
|
||||
S8_String result = s;
|
||||
if (S8_Find(s, S8_Lit("."), S8_MATCH_FIND_LAST, &pos)) {
|
||||
if (S8_Find(s, S8_Lit("."), S8_FindFlag_MatchFindLast, &pos)) {
|
||||
result = S8_Skip(result, pos + 1);
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define S8_IF_CPP(x) x
|
||||
#else
|
||||
#define S8_IF_CPP(x)
|
||||
#endif
|
||||
|
||||
#ifndef S8_Allocator
|
||||
struct MA_Arena;
|
||||
#define S8_Allocator MA_Arena *
|
||||
@@ -19,12 +25,26 @@ struct MA_Arena;
|
||||
typedef struct S8_String S8_String;
|
||||
typedef struct S8_Node S8_Node;
|
||||
typedef struct S8_List S8_List;
|
||||
S8_API int64_t S8_Length(char *string);
|
||||
|
||||
struct S8_String {
|
||||
char *str;
|
||||
int64_t len;
|
||||
};
|
||||
|
||||
// #ifdef __cplusplus
|
||||
// struct String : S8_String {
|
||||
// String() = default;
|
||||
// String(char *s) : S8_String{s, S8_Length(s)} {}
|
||||
// String(char *s, int64_t l) : S8_String{s, l} {}
|
||||
// String(const char *s) : S8_String{(char *)s, S8_Length((char *)s)} {}
|
||||
// String(const char *s, int64_t l) : S8_String{(char *)s, l} {}
|
||||
// String(S8_String s) : S8_String{s.str, s.len} {}
|
||||
|
||||
// // @todo add unicode iterator
|
||||
// };
|
||||
// #endif
|
||||
|
||||
struct S8_Node {
|
||||
S8_Node *next;
|
||||
S8_String string;
|
||||
@@ -37,11 +57,20 @@ struct S8_List {
|
||||
S8_Node *last;
|
||||
};
|
||||
|
||||
const int S8_IgnoreCase = true;
|
||||
|
||||
typedef int S8_FindFlag;
|
||||
enum {
|
||||
S8_NO_FLAGS = 0,
|
||||
S8_IGNORE_CASE = 1,
|
||||
S8_SPLIT_INCLUSIVE = 4,
|
||||
S8_MATCH_FIND_LAST = 32,
|
||||
S8_FindFlag_None = 0,
|
||||
S8_FindFlag_IgnoreCase = 1,
|
||||
S8_FindFlag_MatchFindLast = 2,
|
||||
};
|
||||
|
||||
typedef int S8_SplitFlag;
|
||||
enum {
|
||||
S8_SplitFlag_None = 0,
|
||||
S8_SplitFlag_IgnoreCase = 1,
|
||||
S8_SplitFlag_SplitInclusive = 2,
|
||||
};
|
||||
|
||||
#if defined(__has_attribute)
|
||||
@@ -80,9 +109,9 @@ S8_API bool CHAR_IsAlphabetic(char a);
|
||||
S8_API bool CHAR_IsIdent(char a);
|
||||
S8_API bool CHAR_IsDigit(char a);
|
||||
S8_API bool CHAR_IsAlphanumeric(char a);
|
||||
S8_API bool S8_AreEqual(S8_String a, S8_String b, unsigned ignore_case);
|
||||
S8_API bool S8_EndsWith(S8_String a, S8_String end, unsigned ignore_case);
|
||||
S8_API bool S8_StartsWith(S8_String a, S8_String start, unsigned ignore_case);
|
||||
S8_API bool S8_AreEqual(S8_String a, S8_String b, unsigned ignore_case S8_IF_CPP(= false));
|
||||
S8_API bool S8_EndsWith(S8_String a, S8_String end, unsigned ignore_case S8_IF_CPP(= false));
|
||||
S8_API bool S8_StartsWith(S8_String a, S8_String start, unsigned ignore_case S8_IF_CPP(= false));
|
||||
S8_API S8_String S8_Make(char *str, int64_t len);
|
||||
S8_API S8_String S8_Copy(S8_Allocator allocator, S8_String string);
|
||||
S8_API void S8_NormalizePath(S8_String s);
|
||||
@@ -95,26 +124,28 @@ S8_API S8_String S8_Trim(S8_String string);
|
||||
S8_API S8_String S8_TrimEnd(S8_String string);
|
||||
S8_API S8_String S8_ToLowerCase(S8_Allocator allocator, S8_String s);
|
||||
S8_API S8_String S8_ToUpperCase(S8_Allocator allocator, S8_String s);
|
||||
S8_API bool S8_Find(S8_String string, S8_String find, unsigned flags, int64_t *index_out);
|
||||
S8_API S8_List S8_Split(S8_Allocator allocator, S8_String string, S8_String find, unsigned flags);
|
||||
S8_API S8_String S8_MergeWithSeparator(S8_Allocator allocator, S8_List list, S8_String separator);
|
||||
S8_API S8_String S8_Merge(S8_Allocator allocator, S8_List list);
|
||||
S8_API S8_String S8_ReplaceAll(S8_Allocator allocator, S8_String string, S8_String replace, S8_String with, unsigned flags);
|
||||
S8_API S8_List S8_FindAll(S8_Allocator allocator, S8_String string, S8_String find, unsigned flags);
|
||||
S8_API bool S8_Find(S8_String string, S8_String find, S8_FindFlag flags S8_IF_CPP(= S8_FindFlag_None), int64_t *index_out S8_IF_CPP(= 0));
|
||||
S8_API S8_String S8_ChopLastSlash(S8_String s);
|
||||
S8_API S8_String S8_ChopLastPeriod(S8_String s);
|
||||
S8_API S8_String S8_SkipToLastSlash(S8_String s);
|
||||
S8_API S8_String S8_SkipToLastPeriod(S8_String s);
|
||||
S8_API S8_String S8_GetNameNoExt(S8_String s);
|
||||
S8_API bool S8_IsPointerInside(S8_String string, char *p);
|
||||
S8_API S8_String S8_SkipToP(S8_String string, char *p);
|
||||
S8_API S8_String S8_SkipPast(S8_String string, S8_String a);
|
||||
S8_API int64_t S8_Length(char *string);
|
||||
S8_API int64_t S8_WideLength(wchar_t *string);
|
||||
S8_API S8_String S8_MakeFromChar(char *string);
|
||||
S8_API S8_String S8_MakeEmpty(void);
|
||||
S8_API S8_List S8_MakeEmptyList(void);
|
||||
S8_API S8_String S8_FormatV(S8_Allocator allocator, const char *str, va_list args1);
|
||||
S8_API S8_String S8_Format(S8_Allocator allocator, const char *str, ...) S8__PrintfFormat(2, 3);
|
||||
|
||||
S8_API S8_List S8_Split(S8_Allocator allocator, S8_String string, S8_String find, S8_SplitFlag flags S8_IF_CPP(= S8_SplitFlag_None));
|
||||
S8_API S8_String S8_MergeWithSeparator(S8_Allocator allocator, S8_List list, S8_String separator S8_IF_CPP(= " "_s));
|
||||
S8_API S8_String S8_Merge(S8_Allocator allocator, S8_List list);
|
||||
S8_API S8_String S8_ReplaceAll(S8_Allocator allocator, S8_String string, S8_String replace, S8_String with, bool ignore_case S8_IF_CPP(= false));
|
||||
S8_API S8_List S8_FindAll(S8_Allocator allocator, S8_String string, S8_String find, bool ignore_case S8_IF_CPP(= false));
|
||||
|
||||
S8_API S8_Node *S8_CreateNode(S8_Allocator allocator, S8_String string);
|
||||
S8_API void S8_ReplaceNodeString(S8_List *list, S8_Node *node, S8_String new_string);
|
||||
S8_API void S8_AddExistingNode(S8_List *list, S8_Node *node);
|
||||
|
||||
Reference in New Issue
Block a user