//////////////////////////////////////////////////////////// //~ Formatting types #define DefaultFmtPrecision 3 #define IntChars ("0123456789abcdef") Enum(FmtKind) { FmtKind_None, /* Arbitrary magic numbers for argument validation */ FmtKind_Char = 0x0f5281df, FmtKind_String = 0x0a5ffa9a, FmtKind_Uint = 0x0746f19b, FmtKind_Sint = 0x08603694, FmtKind_Hex = 0x0a3d0792, FmtKind_Ptr = 0x0c4519e4, FmtKind_Float = 0x04814143, FmtKind_Uid = 0x3d1cd407, FmtKind_Handle = 0x6ead3bec, FmtKind_End = 0x0ecbc5ae }; Struct(FmtArg) { FmtKind kind; u32 precision; u32 zfill; union { u8 c; String string; u64 uint; i64 sint; void *ptr; f64 f; Uid uid; struct { u64 h64[2]; } handle; } value; }; //////////////////////////////////////////////////////////// //~ Unicode types Struct(CodepointIter) { u32 codepoint; /* Internal */ String src; u64 pos; }; //////////////////////////////////////////////////////////// //~ Conversion helpers String StringFromChar(Arena *arena, char c); String StringFromU64(Arena *arena, u64 n, u64 base, u64 zfill); String StringFromI64(Arena *arena, i64 n, u64 base, u64 zfill); String StringFromPtr(Arena *arena, void *ptr); String StringFromF64(Arena *arena, f64 f, u32 precision); String StringFromhandle(Arena *arena, u64 v0, u64 v1); String StringFromUid(Arena *arena, Uid uid); //////////////////////////////////////////////////////////// //~ String helpers String PushString(Arena *arena, String src); String PushStringToBuff(String dst, String src); String RepeatString(Arena *arena, String src, u64 count); String CatString(Arena *arena, String str1, String str2); StringArray SplitString(Arena *arena, String str, String delim); String IndentString(Arena *arena, String str, u32 indent); String LowerString(Arena *arena, String str); b32 MatchString(String str1, String str2); b32 StringContains(String str, String substring); b32 StringBeginsWith(String str, String substring); b32 StringEndsWith(String str, String substring); //////////////////////////////////////////////////////////// //~ Trimming helpers String TrimLeft(String s, String pattern); String TrimRight(String s, String pattern); String Trim(String s, String pattern); String TrimWhitespace(String s); //////////////////////////////////////////////////////////// //~ String list helpers StringListNode *PushStringToList(Arena *arena, StringList *l, String s); String StringFromList(Arena *arena, StringList l, String separator); //////////////////////////////////////////////////////////// //~ Formatting //- Format arg helpers #define FmtChar(v) (FmtArg) {.kind = FmtKind_Char, .value.c = (v)} #define FmtString(v) (FmtArg) {.kind = FmtKind_String, .value.string = (v)} #define FmtUint(v) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v)} #define FmtUintZ(v, z) (FmtArg) {.kind = FmtKind_Uint, .value.uint = (v), .zfill = (z)} #define FmtSint(v) (FmtArg) {.kind = FmtKind_Sint, .value.sint = (v)} #define FmtHex(v) (FmtArg) {.kind = FmtKind_Hex, .value.uint = (v)} #define FmtPtr(v) (FmtArg) {.kind = FmtKind_Ptr, .value.ptr = (v)} #define FmtFloat(v) FmtFloatP(v, DefaultFmtPrecision) #define FmtFloatP(v, p) (FmtArg) {.kind = FmtKind_Float, .value.f = (v), .precision = (p)} #define FmtHandle(v) (FmtArg) {.kind = FmtKind_Handle, .value.handle.h64[0] = (v).idx, .value.handle.h64[1] = (v).gen} #define FmtUid(v) (FmtArg) {.kind = FmtKind_Uid, .value.uid = (v) } #define FmtEnd (FmtArg) {.kind = FmtKind_End} //- Format functions #define StringF(arena, lit, ...) FormatString_((arena), Lit(lit), __VA_ARGS__, FmtEnd) #define FormatString(arena, fmt, ...) FormatString_((arena), (fmt), __VA_ARGS__, FmtEnd) String FormatString_(Arena *arena, String fmt, ...); String FormatStringV(Arena *arena, String fmt, va_list args); //////////////////////////////////////////////////////////// //~ Unicode operations //- Iter CodepointIter InitCodepointIter(String str); b32 NextCodepoint(CodepointIter *iter); //- Decode string String StringFromString16(Arena *arena, String16 str16); String StringFromString32(Arena *arena, String32 str32); //- Encode string String16 String16FromString(Arena *arena, String str8); String32 String32FromString(Arena *arena, String str8); //////////////////////////////////////////////////////////// //~ Legacy null-terminated C string operations //- Narrow strings u64 CstrLenNoLimit(char *cstr); u64 CstrLen(char *cstr, u64 limit); char *CstrFromString(Arena *arena, String src); char *CstrFromStringToBuff(String dest_buff, String src); String StringFromCstrNoLimit(char *cstr); String StringFromCstr(char *cstr, u64 limit); //- Wide strings u64 WstrLenNoLimit(wchar_t *wstr); u64 WstrLen(wchar_t *wstr, u64 limit); wchar_t *WstrFromString(Arena *arena, String src); wchar_t *WstrFromString16(Arena *arena, String16 src); String StringFromWstrNoLimit(Arena *arena, wchar_t *wstr); String StringFromWstr(Arena *arena, wchar_t *wstr, u64 limit); String16 String16FromWstrNoLimit(wchar_t *wstr); String16 String16FromWstr(wchar_t *wstr, u64 limit);