200 lines
7.5 KiB
C
200 lines
7.5 KiB
C
////////////////////////////////////////////////////////////
|
|
//~ Formatting types
|
|
|
|
#define DefaultFmtPrecision 6
|
|
#define Base16Chars ("0123456789abcdef")
|
|
|
|
Enum(FmtArgKind)
|
|
{
|
|
FmtArgKind_None,
|
|
|
|
// Arbitrary magic numbers for argument validation
|
|
FmtArgKind_Char = 0xf5281df,
|
|
FmtArgKind_String = 0xa5ffa9a,
|
|
|
|
FmtArgKind_Uint = 0x746f19b,
|
|
FmtArgKind_Uint2 = 0x83429d9,
|
|
FmtArgKind_Uint3 = 0x1b4b749,
|
|
FmtArgKind_Uint4 = 0xf8eb3cf,
|
|
|
|
FmtArgKind_Sint = 0x8603694,
|
|
FmtArgKind_Sint2 = 0x335a803,
|
|
FmtArgKind_Sint3 = 0xe5e4ab1,
|
|
FmtArgKind_Sint4 = 0xe1fd7ad,
|
|
|
|
FmtArgKind_Float = 0x4814143,
|
|
FmtArgKind_Float2 = 0x4260065,
|
|
FmtArgKind_Float3 = 0x0d28ab7,
|
|
FmtArgKind_Float4 = 0x76fe314,
|
|
|
|
FmtArgKind_Hex = 0xa3d0792,
|
|
FmtArgKind_Ptr = 0xc4519e4,
|
|
FmtArgKind_Uid = 0xd1cd407,
|
|
FmtArgKind_Handle = 0xead3bec,
|
|
|
|
FmtArgKind_End = 0xecbc5ae
|
|
};
|
|
|
|
Struct(FmtArg)
|
|
{
|
|
FmtArgKind kind;
|
|
u32 p; // Precision
|
|
u32 z; // Z-fill
|
|
union
|
|
{
|
|
u8 c;
|
|
String string;
|
|
Vec4U64 uints;
|
|
Vec4I64 sints;
|
|
Vec4F64 floats;
|
|
void *ptr;
|
|
Uid uid;
|
|
u64 handle;
|
|
} value;
|
|
};
|
|
|
|
Struct(FmtArgArray)
|
|
{
|
|
u64 count;
|
|
FmtArg *args;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Unicode types
|
|
|
|
Struct(CodepointIter)
|
|
{
|
|
u32 codepoint;
|
|
|
|
// Internal
|
|
String src;
|
|
u64 pos;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Conversion helpers
|
|
|
|
String StringFromBool(Arena *arena, b32 b);
|
|
String StringFromChar(Arena *arena, char c);
|
|
String StringFromUint(Arena *arena, u64 n, u64 base, u64 zfill);
|
|
String StringFromUints(Arena *arena, u64 uints_count, u64 *uints, u64 base, u64 zfill);
|
|
String StringFromSint(Arena *arena, i64 n, u64 base, u64 zfill);
|
|
String StringFromFloat(Arena *arena, f64 src, u32 precision);
|
|
String StringFromPtr(Arena *arena, void *ptr);
|
|
String StringFromhandle(Arena *arena, u64 v);
|
|
String StringFromUid(Arena *arena, Uid uid);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ String helpers
|
|
|
|
String PushString(Arena *arena, String src);
|
|
String CopyString(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 ReplaceString(Arena *arena, String str, String old_pattern, String new_pattern);
|
|
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);
|
|
String StringFromArray(Arena *arena, StringArray a);
|
|
String PathFromString(Arena *arena, String str, u8 path_delimiter);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ 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
|
|
|
|
#define FMTARG(_kind, ...) ((FmtArg) { .kind = (_kind), .p = DefaultFmtPrecision, __VA_ARGS__ })
|
|
|
|
#define FmtChar(v, ...) FMTARG(FmtArgKind_Char, .value.c = (v), __VA_ARGS__)
|
|
#define FmtString(v, ...) FMTARG(FmtArgKind_String, .value.string = (v), __VA_ARGS__)
|
|
|
|
|
|
#define FmtUint(v, ...) FMTARG(FmtArgKind_Uint, .value.uints = VEC4U64((v), 0, 0, 0), __VA_ARGS__)
|
|
#define FmtUint2(v, ...) FMTARG(FmtArgKind_Uint2, .value.uints = VEC4U64((v).x, (v).y, 0, 0), __VA_ARGS__)
|
|
#define FmtUint3(v, ...) FMTARG(FmtArgKind_Uint3, .value.uints = VEC4U64((v).x, (v).y, (v).z, 0), __VA_ARGS__)
|
|
#define FmtUint4(v, ...) FMTARG(FmtArgKind_Uint4, .value.uints = VEC4U64((v).x, (v).y, (v).z, (v).w), __VA_ARGS__)
|
|
|
|
#define FmtSint(v, ...) FMTARG(FmtArgKind_Sint, .value.sints = VEC4I64((v), 0, 0, 0), __VA_ARGS__)
|
|
#define FmtSint2(v, ...) FMTARG(FmtArgKind_Sint2, .value.sints = VEC4I64((v).x, (v).y, 0, 0), __VA_ARGS__)
|
|
#define FmtSint3(v, ...) FMTARG(FmtArgKind_Sint3, .value.sints = VEC4I64((v).x, (v).y, (v).z, 0), __VA_ARGS__)
|
|
#define FmtSint4(v, ...) FMTARG(FmtArgKind_Sint4, .value.sints = VEC4I64((v).x, (v).y, (v).z, (v).w), __VA_ARGS__)
|
|
|
|
#define FmtFloat(v, ...) FMTARG(FmtArgKind_Float, .value.floats = VEC4F64((v), 0, 0, 0), __VA_ARGS__)
|
|
#define FmtFloat2(v, ...) FMTARG(FmtArgKind_Float2, .value.floats = VEC4F64((v).x, (v).y, 0, 0), __VA_ARGS__)
|
|
#define FmtFloat3(v, ...) FMTARG(FmtArgKind_Float3, .value.floats = VEC4F64((v).x, (v).y, (v).z, 0), __VA_ARGS__)
|
|
#define FmtFloat4(v, ...) FMTARG(FmtArgKind_Float4, .value.floats = VEC4F64((v).x, (v).y, (v).z, (v).w), __VA_ARGS__)
|
|
|
|
#define FmtHex(v, ...) FMTARG(FmtArgKind_Hex, .value.uints.x = (v), __VA_ARGS__)
|
|
#define FmtPtr(v, ...) FMTARG(FmtArgKind_Ptr, .value.ptr = (v), __VA_ARGS__)
|
|
#define FmtHandle(v, ...) FMTARG(FmtArgKind_Handle, .value.handle = (v), __VA_ARGS__)
|
|
#define FmtUid(v, ...) FMTARG(FmtArgKind_Uid, .value.uid = (v), __VA_ARGS__)
|
|
|
|
#define FmtEnd FMTARG(FmtArgKind_End) // Denotes end of VA list
|
|
|
|
String FormatString(Arena *arena, String fmt, FmtArgArray args);
|
|
String StringF_(Arena *arena, String fmt, ...);
|
|
#define StringF(arena, lit, ...) StringF_((arena), Lit(lit), __VA_ARGS__, FmtEnd)
|
|
|
|
FmtArgArray FmtArgsFromVaList(Arena *arena, va_list vl);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Unicode
|
|
|
|
//- 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);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Base64
|
|
|
|
u64 Base64LenFromStringLen(u64 len);
|
|
u64 StringLenFromBase64Len(u64 len);
|
|
|
|
String Base64FromString(Arena *arena, String str);
|
|
String StringFromBase64(Arena *arena, String str);
|
|
|
|
////////////////////////////////////////////////////////////
|
|
//~ Null-terminated strings
|
|
|
|
//- 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);
|