105 lines
3.6 KiB
C
105 lines
3.6 KiB
C
#pragma once
|
|
|
|
struct String {
|
|
char *data;
|
|
int64_t len;
|
|
|
|
String() = default;
|
|
String(char *s) : data(s), len(strlen(s)) {}
|
|
String(char *s, int64_t l) : data((char *)s), len(l) {}
|
|
String(const char *s) : data((char *)s), len(strlen((char *)s)) {}
|
|
String(const char *s, int64_t l) : data((char *)s), len(l) {}
|
|
|
|
|
|
char &operator[](int64_t index) {
|
|
Assert(index < len);
|
|
return data[index];
|
|
}
|
|
char *begin() { return data; }
|
|
char *end() { return data + len; }
|
|
|
|
struct ReverseIter {
|
|
char *data;
|
|
String *arr;
|
|
|
|
ReverseIter operator++(int) {
|
|
ReverseIter ret = *this;
|
|
data -= 1;
|
|
return ret;
|
|
}
|
|
ReverseIter &operator++() {
|
|
data -= 1;
|
|
return *this;
|
|
}
|
|
|
|
char &operator*() { return data[0]; }
|
|
char *operator->() { return data; }
|
|
|
|
friend bool operator==(const ReverseIter &a, const ReverseIter &b) { return a.data == b.data; };
|
|
friend bool operator!=(const ReverseIter &a, const ReverseIter &b) { return a.data != b.data; };
|
|
|
|
ReverseIter begin() { return ReverseIter{arr->end() - 1, arr}; }
|
|
ReverseIter end() { return ReverseIter{arr->begin() - 1, arr}; }
|
|
};
|
|
ReverseIter reverse() { return {this->end() - 1, this}; }
|
|
};
|
|
|
|
API char ToLowerCase(char a);
|
|
API char ToUpperCase(char a);
|
|
API bool IsWhitespace(char w);
|
|
API bool IsAlphabetic(char a);
|
|
API bool IsIdent(char a);
|
|
API bool IsDigit(char a);
|
|
API bool IsAlphanumeric(char a);
|
|
API bool IsSymbol(char w);
|
|
API bool IsNonWord(char w);
|
|
API bool IsWord(char w);
|
|
API bool IsBrace(char c);
|
|
API bool IsParen(char c);
|
|
|
|
API bool EndsWith(String a, String end, unsigned ignore_case = false);
|
|
API bool StartsWith(String a, String start, unsigned ignore_case = false);
|
|
API bool AreEqual(String a, String b, unsigned ignore_case = false);
|
|
inline bool operator==(String a, String b) { return AreEqual(a, b); }
|
|
inline bool operator!=(String a, String b) { return !AreEqual(a, b); }
|
|
|
|
API String Trim(String string);
|
|
API String TrimEnd(String string);
|
|
API String Chop(String a, int64_t len);
|
|
API String Skip(String a, int64_t len);
|
|
API String GetPostfix(String a, int64_t len);
|
|
API String GetPrefix(String a, int64_t len);
|
|
API String GetSlice(String arr, int64_t first_index = 0, int64_t one_past_last_index = SLICE_LAST);
|
|
API String CutLastSlash(String *s);
|
|
API String ChopLastSlash(String s);
|
|
API String ChopLastPeriod(String s);
|
|
API String SkipToLastSlash(String s);
|
|
API String SkipToLastPeriod(String s);
|
|
API String CutPrefix(String *string, int64_t len);
|
|
API String CutPostfix(String *string, int64_t len);
|
|
|
|
API String Copy(Allocator allocator, String string);
|
|
API String Copy(Allocator allocator, char *string);
|
|
API void NormalizePathInPlace(String s);
|
|
API String NormalizePath(Allocator allocator, String s);
|
|
|
|
API String FormatV(Allocator allocator, const char *data, va_list args1);
|
|
API String Format(Allocator allocator, const char *data, ...);
|
|
#define STRING_FORMAT(allocator, data, result) \
|
|
va_list args1; \
|
|
va_start(args1, data); \
|
|
String result = FormatV(allocator, data, args1); \
|
|
va_end(args1)
|
|
|
|
|
|
typedef int SeekFlag;
|
|
enum {
|
|
SeekFlag_None = 0,
|
|
SeekFlag_IgnoreCase = 1,
|
|
SeekFlag_MatchFindLast = 2,
|
|
};
|
|
API bool Seek(String string, String find, int64_t *index_out = NULL, SeekFlag flags = SeekFlag_None);
|
|
|
|
API Array<String> Split(Allocator allocator, String string, String delimiter = " ");
|
|
API String Merge(Allocator allocator, Array<String> list, String separator);
|
|
API Int GetSize(Array<String> array); |