#ifndef STRING_H #define STRING_H struct string_array { u64 count; struct string *strings; }; /* ========================== * * Conversion * ========================== */ struct string string_from_char(struct arena *arena, char c); struct string string_from_uint(struct arena *arena, u64 n, u64 base, u64 zfill); struct string string_from_int(struct arena *arena, i64 n, u64 base, u64 zfill); struct string string_from_ptr(struct arena *arena, void *ptr); struct string string_from_float(struct arena *arena, f64 f, u32 precision); struct string string_from_handle(struct arena *arena, u64 v0, u64 v1); struct string string_from_uid(struct arena *arena, struct uid uid); /* ========================== * * String operations * ========================== */ struct string string_copy(struct arena *arena, struct string src); struct string string_copy_to_string(struct string dst, struct string src); struct string string_repeat(struct arena *arena, struct string src, u64 count); struct string string_cat(struct arena *arena, struct string str1, struct string str2); struct string_array string_split(struct arena *arena, struct string str, struct string delim); struct string string_indent(struct arena *arena, struct string str, u32 indent); struct string string_lower(struct arena *arena, struct string str); b32 string_eq(struct string str1, struct string str2); i32 string_cmp(struct string str1, struct string str2); b32 string_contains(struct string str, struct string substring); b32 string_starts_with(struct string str, struct string substring); b32 string_ends_with(struct string str, struct string substring); /* ========================== * * Format * ========================== */ #define DEFAULT_FMT_PRECISION 3 enum fmt_type { FMT_TYPE_NONE, /* Arbitrary magic numbers to avoid accidental non-fmt arguments */ FMT_TYPE_CHAR = 0x0f5281df, FMT_TYPE_STR = 0x0a5ffa9a, FMT_TYPE_UINT = 0x0746f19b, FMT_TYPE_SINT = 0x08603694, FMT_TYPE_HEX = 0x0a3d0792, FMT_TYPE_PTR = 0x0c4519e4, FMT_TYPE_FLOAT = 0x04814143, FMT_TYPE_HANDLE = 0x0f112992, FMT_TYPE_UID = 0x0beb23dd, FMT_TYPE_END = 0x0ecbc5ae }; struct fmt_arg { enum fmt_type type; u32 precision; u32 zfill; union { u8 c; struct string string; u64 uint; i64 sint; void *ptr; f64 f; struct { u64 h64[2]; } handle; struct uid uid; } value; }; #define FMT_END (struct fmt_arg) {.type = FMT_TYPE_END} #define FMT_CHAR(v) (struct fmt_arg) {.type = FMT_TYPE_CHAR, .value.c = (v)} #define FMT_STR(v) (struct fmt_arg) {.type = FMT_TYPE_STR, .value.string = (v)} #define FMT_UINT(v) (struct fmt_arg) {.type = FMT_TYPE_UINT, .value.uint = (v)} #define FMT_UINT_Z(v, z) (struct fmt_arg) {.type = FMT_TYPE_UINT, .value.uint = (v), .zfill = (z)} #define FMT_SINT(v) (struct fmt_arg) {.type = FMT_TYPE_SINT, .value.sint = (v)} #define FMT_HEX(v) (struct fmt_arg) {.type = FMT_TYPE_HEX, .value.uint = (v)} #define FMT_PTR(v) (struct fmt_arg) {.type = FMT_TYPE_PTR, .value.ptr = (v)} #define FMT_FLOAT(v) FMT_FLOAT_P(v, DEFAULT_FMT_PRECISION) #define FMT_FLOAT_P(v, p) (struct fmt_arg) {.type = FMT_TYPE_FLOAT, .value.f = (v), .precision = (p)} #define FMT_HANDLE(v) (struct fmt_arg) {.type = FMT_TYPE_HANDLE, .value.handle.h64[0] = (v).idx, .value.handle.h64[1] = (v).gen} #define FMT_UID(v) (struct fmt_arg) {.type = FMT_TYPE_UID, .value.uid = (v) } #define string_format(arena, fmt, ...) _string_format((arena), (fmt), __VA_ARGS__, FMT_END) struct string _string_format(struct arena *arena, struct string fmt, ...); struct string string_formatv(struct arena *arena, struct string fmt, va_list args); /* ========================== * * Unicode * ========================== */ struct string_codepoint_iter { u32 codepoint; /* Internal */ struct string src; u64 pos; }; struct string_codepoint_iter string_codepoint_iter_begin(struct string str); b32 string_codepoint_iter_next(struct string_codepoint_iter *iter); void string_codepoint_iter_end(struct string_codepoint_iter *iter); struct string string_from_string16(struct arena *arena, struct string16 str16); struct string string_from_string32(struct arena *arena, struct string32 str32); struct string16 string16_from_string(struct arena *arena, struct string str8); struct string32 string32_from_string(struct arena *arena, struct string str8); /* ========================== * * Legacy strings * ========================== */ u64 cstr_len_no_limit(char *cstr); u64 cstr_len(char *cstr, u64 limit); char *cstr_from_string(struct arena *arena, struct string src); char *cstr_buff_from_string(struct string dest_buff, struct string src); struct string string_from_cstr_no_limit(char *cstr); struct string string_from_cstr(char *cstr, u64 limit); u64 wstr_len_no_limit(wchar_t *wstr); u64 wstr_len(wchar_t *wstr, u64 limit); wchar_t *wstr_from_string(struct arena *arena, struct string src); wchar_t *wstr_from_string16(struct arena *arena, struct string16 src); struct string string_from_wstr_no_limit(struct arena *arena, wchar_t *wstr); struct string string_from_wstr(struct arena *arena, wchar_t *wstr, u64 limit); struct string16 string16_from_wstr_no_limit(wchar_t *wstr); struct string16 string16_from_wstr(wchar_t *wstr, u64 limit); #endif