diff --git a/Code/Dqn.h b/Code/Dqn.h index 4e20373..5713d8c 100644 --- a/Code/Dqn.h +++ b/Code/Dqn.h @@ -213,8 +213,8 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri #define DQN_LEN_AND_STR(string) Dqn_CharCount(str), string #define DQN_STR_AND_LEN(string) string, Dqn_CharCount(string) #define DQN_STR_AND_LEN_I(string) string, (int)Dqn_CharCount(string) -#define DQN_FOR_EACH(i, limit) for (isize (i) = 0; (i) < (isize)(limit); ++(i)) -#define DQN_FOR_EACH_REVERSE(i, limit) for (isize (i) = (isize)(limit-1); (i) >= 0; --(i)) +#define DQN_FOR_EACH(i, limit) for (Dqn_isize (i) = 0; (i) < (Dqn_isize)(limit); ++(i)) +#define DQN_FOR_EACH_REVERSE(i, limit) for (Dqn_isize (i) = (Dqn_isize)(limit-1); (i) >= 0; --(i)) #define DQN_BYTES(val) (val) #define DQN_KILOBYTES(val) (1024ULL * DQN_BYTES(val)) @@ -241,6 +241,7 @@ STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char comma, char peri #include #include +#if defined(DQN_USE_PRIMITIVE_TYPEDEFS) using usize = size_t; using isize = ptrdiff_t; @@ -266,18 +267,45 @@ const u32 U32_MAX = UINT32_MAX; const f32 F32_MAX = FLT_MAX; const isize ISIZE_MAX = PTRDIFF_MAX; const usize USIZE_MAX = SIZE_MAX; +#endif -template -DQN_HEADER_COPY_PROTOTYPE(constexpr usize, Dqn_ArrayCount(T const (&)[N])) { return N; } +using Dqn_usize = size_t; +using Dqn_isize = ptrdiff_t; -template -DQN_HEADER_COPY_PROTOTYPE(constexpr isize, Dqn_ArrayCountI(T const (&)[N])) { return N; } +using Dqn_f64 = double; +using Dqn_f32 = float; -template -DQN_HEADER_COPY_PROTOTYPE(constexpr usize, Dqn_CharCount(char const (&)[N])) { return N - 1; } +using Dqn_i64 = int64_t; +using Dqn_i32 = int32_t; +using Dqn_i16 = int16_t; +using Dqn_i8 = int8_t; -template -DQN_HEADER_COPY_PROTOTYPE(constexpr isize, Dqn_CharCountI(char const (&)[N])) { return N - 1; } +using Dqn_uchar = unsigned char; +using Dqn_uint = unsigned int; +using Dqn_u64 = uint64_t; +using Dqn_u32 = uint32_t; +using Dqn_u16 = uint16_t; +using Dqn_u8 = uint8_t; + +using Dqn_b32 = int32_t; + +const Dqn_i32 DQN_I32_MAX = INT32_MAX; +const Dqn_u32 DQN_U32_MAX = UINT32_MAX; +const Dqn_f32 DQN_F32_MAX = FLT_MAX; +const Dqn_isize DQN_ISIZE_MAX = PTRDIFF_MAX; +const Dqn_usize DQN_USIZE_MAX = SIZE_MAX; + +template +DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_usize, Dqn_ArrayCount(T const (&)[N])) { return N; } + +template +DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_isize, Dqn_ArrayCountI(T const (&)[N])) { return N; } + +template +DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_usize, Dqn_CharCount(char const (&)[N])) { return N - 1; } + +template +DQN_HEADER_COPY_PROTOTYPE(constexpr Dqn_isize, Dqn_CharCountI(char const (&)[N])) { return N - 1; } template struct DqnDefer @@ -324,7 +352,7 @@ DQN_HEADER_COPY_PROTOTYPE(constexpr inline char const *, Dqn_LogTypeTag(Dqn_LogT DQN_HEADER_COPY_BEGIN // NOTE: Set the callback to get called whenever a log message has been printed -#define DQN_LOG_CALLBACK(name) void name(Dqn_LogType type, char const *file, usize file_len, char const *func, usize func_len, usize line, char const *log_str) +#define DQN_LOG_CALLBACK(name) void name(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *log_str) typedef DQN_LOG_CALLBACK(Dqn_LogCallback); Dqn_LogCallback *Dqn_log_callback; @@ -343,15 +371,15 @@ DQN_HEADER_COPY_END DQN_HEADER_COPY_BEGIN union Dqn_V2I { - struct { i32 x, y; }; - struct { i32 w, h; }; - struct { i32 min, max; }; - i32 e[2]; + struct { Dqn_i32 x, y; }; + struct { Dqn_i32 w, h; }; + struct { Dqn_i32 min, max; }; + Dqn_i32 e[2]; constexpr Dqn_V2I() = default; - constexpr Dqn_V2I(f32 x_, f32 y_): x((i32)x_), y((i32)y_) {} - constexpr Dqn_V2I(i32 x_, i32 y_): x(x_), y(y_) {} - constexpr Dqn_V2I(i32 xy): x(xy), y(xy) {} + constexpr Dqn_V2I(Dqn_f32 x_, Dqn_f32 y_): x((Dqn_i32)x_), y((Dqn_i32)y_) {} + constexpr Dqn_V2I(Dqn_i32 x_, Dqn_i32 y_): x(x_), y(y_) {} + constexpr Dqn_V2I(Dqn_i32 xy): x(xy), y(xy) {} constexpr bool operator!=(Dqn_V2I other) const { return !(*this == other); } constexpr bool operator==(Dqn_V2I other) const { return (x == other.x) && (y == other.y); } @@ -362,31 +390,31 @@ union Dqn_V2I constexpr Dqn_V2I operator- (Dqn_V2I other) const { Dqn_V2I result(x - other.x, y - other.y); return result; } constexpr Dqn_V2I operator+ (Dqn_V2I other) const { Dqn_V2I result(x + other.x, y + other.y); return result; } constexpr Dqn_V2I operator* (Dqn_V2I other) const { Dqn_V2I result(x * other.x, y * other.y); return result; } - constexpr Dqn_V2I operator* (f32 other) const { Dqn_V2I result(x * other, y * other); return result; } - constexpr Dqn_V2I operator* (i32 other) const { Dqn_V2I result(x * other, y * other); return result; } + constexpr Dqn_V2I operator* (Dqn_f32 other) const { Dqn_V2I result(x * other, y * other); return result; } + constexpr Dqn_V2I operator* (Dqn_i32 other) const { Dqn_V2I result(x * other, y * other); return result; } constexpr Dqn_V2I operator/ (Dqn_V2I other) const { Dqn_V2I result(x / other.x, y / other.y); return result; } - constexpr Dqn_V2I operator/ (f32 other) const { Dqn_V2I result(x / other, y / other); return result; } - constexpr Dqn_V2I operator/ (i32 other) const { Dqn_V2I result(x / other, y / other); return result; } + constexpr Dqn_V2I operator/ (Dqn_f32 other) const { Dqn_V2I result(x / other, y / other); return result; } + constexpr Dqn_V2I operator/ (Dqn_i32 other) const { Dqn_V2I result(x / other, y / other); return result; } constexpr Dqn_V2I &operator*=(Dqn_V2I other) { *this = *this * other; return *this; } - constexpr Dqn_V2I &operator*=(f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2I &operator*=(i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2I &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2I &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } constexpr Dqn_V2I &operator-=(Dqn_V2I other) { *this = *this - other; return *this; } constexpr Dqn_V2I &operator+=(Dqn_V2I other) { *this = *this + other; return *this; } }; union Dqn_V2 { - struct { f32 x, y; }; - struct { f32 w, h; }; - struct { f32 min, max; }; - f32 e[2]; + struct { Dqn_f32 x, y; }; + struct { Dqn_f32 w, h; }; + struct { Dqn_f32 min, max; }; + Dqn_f32 e[2]; constexpr Dqn_V2() = default; - constexpr Dqn_V2(f32 a) : x(a), y(a) {} - constexpr Dqn_V2(i32 a) : x((f32)a), y((f32)a) {} - constexpr Dqn_V2(f32 x_, f32 y_): x(x_), y(y_) {} - constexpr Dqn_V2(i32 x_, i32 y_): x((f32)x_), y((f32)y_) {} - constexpr Dqn_V2(Dqn_V2I a) : x((f32)a.x), y((f32)a.y) {} + constexpr Dqn_V2(Dqn_f32 a) : x(a), y(a) {} + constexpr Dqn_V2(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a) {} + constexpr Dqn_V2(Dqn_f32 x_, Dqn_f32 y_): x(x_), y(y_) {} + constexpr Dqn_V2(Dqn_i32 x_, Dqn_i32 y_): x((Dqn_f32)x_), y((Dqn_f32)y_) {} + constexpr Dqn_V2(Dqn_V2I a) : x((Dqn_f32)a.x), y((Dqn_f32)a.y) {} constexpr bool operator!=(Dqn_V2 other) const { return !(*this == other); } constexpr bool operator==(Dqn_V2 other) const { return (x == other.x) && (y == other.y); } @@ -397,71 +425,71 @@ union Dqn_V2 constexpr Dqn_V2 operator- (Dqn_V2 other) const { Dqn_V2 result(x - other.x, y - other.y); return result; } constexpr Dqn_V2 operator+ (Dqn_V2 other) const { Dqn_V2 result(x + other.x, y + other.y); return result; } constexpr Dqn_V2 operator* (Dqn_V2 other) const { Dqn_V2 result(x * other.x, y * other.y); return result; } - constexpr Dqn_V2 operator* (f32 other) const { Dqn_V2 result(x * other, y * other); return result; } - constexpr Dqn_V2 operator* (i32 other) const { Dqn_V2 result(x * other, y * other); return result; } + constexpr Dqn_V2 operator* (Dqn_f32 other) const { Dqn_V2 result(x * other, y * other); return result; } + constexpr Dqn_V2 operator* (Dqn_i32 other) const { Dqn_V2 result(x * other, y * other); return result; } constexpr Dqn_V2 operator/ (Dqn_V2 other) const { Dqn_V2 result(x / other.x, y / other.y); return result; } - constexpr Dqn_V2 operator/ (f32 other) const { Dqn_V2 result(x / other, y / other); return result; } - constexpr Dqn_V2 operator/ (i32 other) const { Dqn_V2 result(x / other, y / other); return result; } + constexpr Dqn_V2 operator/ (Dqn_f32 other) const { Dqn_V2 result(x / other, y / other); return result; } + constexpr Dqn_V2 operator/ (Dqn_i32 other) const { Dqn_V2 result(x / other, y / other); return result; } constexpr Dqn_V2 &operator*=(Dqn_V2 other) { *this = *this * other; return *this; } - constexpr Dqn_V2 &operator*=(f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V2 &operator*=(i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } constexpr Dqn_V2 &operator/=(Dqn_V2 other) { *this = *this / other; return *this; } - constexpr Dqn_V2 &operator/=(f32 other) { *this = *this / other; return *this; } - constexpr Dqn_V2 &operator/=(i32 other) { *this = *this / other; return *this; } + constexpr Dqn_V2 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } + constexpr Dqn_V2 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } constexpr Dqn_V2 &operator-=(Dqn_V2 other) { *this = *this - other; return *this; } constexpr Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; } }; union Dqn_V3 { - struct { f32 x, y, z; }; - struct { f32 r, g, b; }; + struct { Dqn_f32 x, y, z; }; + struct { Dqn_f32 r, g, b; }; Dqn_V2 xy; - f32 e[3]; + Dqn_f32 e[3]; constexpr Dqn_V3() = default; - constexpr Dqn_V3(f32 a) : x(a), y(a), z(a) {} - constexpr Dqn_V3(i32 a) : x((f32)a), y((f32)a), z((f32)a) {} - constexpr Dqn_V3(f32 x_, f32 y_, f32 z_): x(x_), y(y_), z(z_) {} - constexpr Dqn_V3(i32 x_, i32 y_, f32 z_): x((f32)x_), y((f32)y_), z((f32)z_) {} - constexpr Dqn_V3(Dqn_V2 xy, f32 z_) : x(xy.x), y(xy.y), z(z_) {} + constexpr Dqn_V3(Dqn_f32 a) : x(a), y(a), z(a) {} + constexpr Dqn_V3(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a), z((Dqn_f32)a) {} + constexpr Dqn_V3(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_): x(x_), y(y_), z(z_) {} + constexpr Dqn_V3(Dqn_i32 x_, Dqn_i32 y_, Dqn_f32 z_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_) {} + constexpr Dqn_V3(Dqn_V2 xy, Dqn_f32 z_) : x(xy.x), y(xy.y), z(z_) {} - constexpr bool operator!= (Dqn_V3 other) const { return !(*this == other); } - constexpr bool operator== (Dqn_V3 other) const { return (x == other.x) && (y == other.y) && (z == other.z); } - constexpr bool operator>= (Dqn_V3 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); } - constexpr bool operator<= (Dqn_V3 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); } - constexpr bool operator< (Dqn_V3 other) const { return (x < other.x) && (y < other.y) && (z < other.z); } - constexpr bool operator> (Dqn_V3 other) const { return (x > other.x) && (y > other.y) && (z > other.z); } - constexpr Dqn_V3 operator- (Dqn_V3 other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; } - constexpr Dqn_V3 operator+ (Dqn_V3 other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; } - constexpr Dqn_V3 operator* (Dqn_V3 other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; } - constexpr Dqn_V3 operator* (f32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } - constexpr Dqn_V3 operator* (i32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } - constexpr Dqn_V3 operator/ (Dqn_V3 other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; } - constexpr Dqn_V3 operator/ (f32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } - constexpr Dqn_V3 operator/ (i32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } - constexpr Dqn_V3 &operator*=(Dqn_V3 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator*=(f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator*=(i32 other) { *this = *this * other; return *this; } - constexpr Dqn_V3 &operator/=(Dqn_V3 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator/=(f32 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator/=(i32 other) { *this = *this / other; return *this; } - constexpr Dqn_V3 &operator-=(Dqn_V3 other) { *this = *this - other; return *this; } - constexpr Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } + constexpr bool operator!= (Dqn_V3 other) const { return !(*this == other); } + constexpr bool operator== (Dqn_V3 other) const { return (x == other.x) && (y == other.y) && (z == other.z); } + constexpr bool operator>= (Dqn_V3 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); } + constexpr bool operator<= (Dqn_V3 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); } + constexpr bool operator< (Dqn_V3 other) const { return (x < other.x) && (y < other.y) && (z < other.z); } + constexpr bool operator> (Dqn_V3 other) const { return (x > other.x) && (y > other.y) && (z > other.z); } + constexpr Dqn_V3 operator- (Dqn_V3 other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; } + constexpr Dqn_V3 operator+ (Dqn_V3 other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; } + constexpr Dqn_V3 operator* (Dqn_V3 other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; } + constexpr Dqn_V3 operator* (Dqn_f32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } + constexpr Dqn_V3 operator* (Dqn_i32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } + constexpr Dqn_V3 operator/ (Dqn_V3 other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; } + constexpr Dqn_V3 operator/ (Dqn_f32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } + constexpr Dqn_V3 operator/ (Dqn_i32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } + constexpr Dqn_V3 &operator*=(Dqn_V3 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_V3 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator-=(Dqn_V3 other) { *this = *this - other; return *this; } + constexpr Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } }; union Dqn_V4 { - struct { f32 x, y, z, w; }; - struct { f32 r, g, b, a; }; + struct { Dqn_f32 x, y, z, w; }; + struct { Dqn_f32 r, g, b, a; }; Dqn_V3 rgb; - f32 e[4]; + Dqn_f32 e[4]; constexpr Dqn_V4() = default; - constexpr Dqn_V4(f32 xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} - constexpr Dqn_V4(f32 x_, f32 y_, f32 z_, f32 w_): x(x_), y(y_), z(z_), w(w_) {} - constexpr Dqn_V4(i32 x_, i32 y_, i32 z_, i32 w_): x((f32)x_), y((f32)y_), z((f32)z_), w((f32)w_) {} - constexpr Dqn_V4(Dqn_V3 xyz, f32 w_) : x(xyz.x), y(xyz.y), z(xyz.z), w(w_) {} + constexpr Dqn_V4(Dqn_f32 xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} + constexpr Dqn_V4(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_, Dqn_f32 w_): x(x_), y(y_), z(z_), w(w_) {} + constexpr Dqn_V4(Dqn_i32 x_, Dqn_i32 y_, Dqn_i32 z_, Dqn_i32 w_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_), w((Dqn_f32)w_) {} + constexpr Dqn_V4(Dqn_V3 xyz, Dqn_f32 w_) : x(xyz.x), y(xyz.y), z(xyz.z), w(w_) {} constexpr bool operator!=(Dqn_V4 other) const { return !(*this == other); } constexpr bool operator==(Dqn_V4 other) const { return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); } @@ -472,12 +500,12 @@ union Dqn_V4 constexpr Dqn_V4 operator- (Dqn_V4 other) const { Dqn_V4 result(x - other.x, y - other.y, z - other.z, w - other.w); return result; } constexpr Dqn_V4 operator+ (Dqn_V4 other) const { Dqn_V4 result(x + other.x, y + other.y, z + other.z, w + other.w); return result; } constexpr Dqn_V4 operator* (Dqn_V4 other) const { Dqn_V4 result(x * other.x, y * other.y, z * other.z, w * other.w); return result; } - constexpr Dqn_V4 operator* (f32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } - constexpr Dqn_V4 operator* (i32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } - constexpr Dqn_V4 operator/ (f32 other) const { Dqn_V4 result(x / other, y / other, z / other, w / other); return result; } + constexpr Dqn_V4 operator* (Dqn_f32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } + constexpr Dqn_V4 operator* (Dqn_i32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } + constexpr Dqn_V4 operator/ (Dqn_f32 other) const { Dqn_V4 result(x / other, y / other, z / other, w / other); return result; } constexpr Dqn_V4 &operator*=(Dqn_V4 other) { *this = *this * other; return *this; } - constexpr Dqn_V4 &operator*=(f32 other) { *this = *this * other; return *this; } - constexpr Dqn_V4 &operator*=(i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V4 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V4 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } constexpr Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; } constexpr Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; } }; @@ -499,22 +527,20 @@ struct Dqn_RectI32 union Dqn_Mat4 { - f32 e[16]; + Dqn_f32 e[16]; Dqn_V4 row[4]; - f32 row_major[4][4]; - f32 operator[](usize i) const { return e[i]; } + Dqn_f32 row_major[4][4]; + Dqn_f32 operator[](Dqn_usize i) const { return e[i]; } }; DQN_HEADER_COPY_END -template -DQN_HEADER_COPY_PROTOTYPE(int, Dqn_MemCmpType(T const *ptr1, T const *ptr2)) +DQN_HEADER_COPY_PROTOTYPE(template int, Dqn_MemCmpType(T const *ptr1, T const *ptr2)) { int result = memcmp(ptr1, ptr2, sizeof(T)); return result; } -template -DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_MemZero(T *src)) +DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_MemZero(T *src)) { T *result = static_cast(Dqn_MemSet(src, 0, sizeof(T))); return result; @@ -525,16 +551,17 @@ DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_MemZero(T *src)) // @ NOTE: Dqn_MemArena // @ // @ ------------------------------------------------------------------------------------------------- -using MemSize = usize; -struct MemBlock +DQN_HEADER_COPY_BEGIN +using Dqn_MemSize = Dqn_usize; +struct Dqn_MemBlock { // NOTE: Read only state - b32 allocated_by_user_or_fixed_mem; - void *memory; - MemSize size; - MemSize used; - MemBlock *prev; - MemBlock *next; + Dqn_b32 allocated_by_user_or_fixed_mem; + void *memory; + Dqn_MemSize size; + Dqn_MemSize used; + Dqn_MemBlock *prev; + Dqn_MemBlock *next; }; enum Dqn_MemArenaFlag @@ -542,7 +569,6 @@ enum Dqn_MemArenaFlag Dqn_MemArenaFlag_NoCRTAllocation = (1 << 0), // If my_calloc/my_free aren't null, it defaults to calloc and free, setting this flag disables that }; -// TODO(doyle): We should try support function pointer syntax (maybe) for inspection typedef void *(Dqn_MemArenaCallocFunction)(size_t bytes); typedef void (Dqn_MemArenaFreeFunction) (void *ptr, size_t bytes_to_free); struct Dqn_MemArena @@ -550,15 +576,15 @@ struct Dqn_MemArena // NOTE: Configuration (fill once) Dqn_MemArenaCallocFunction *my_calloc; // If nullptr, use CRT calloc unless disabled in flags Dqn_MemArenaFreeFunction *my_free; // If nullptr, use CRT free unless disabled in flags - u32 flags; + Dqn_u32 flags; // NOTE: Read Only - u8 fixed_mem[DQN_KILOBYTES(16)]; - MemBlock fixed_mem_block; - MemBlock *curr_mem_block; - MemBlock *top_mem_block; - MemSize highest_used_mark; - int total_allocated_mem_blocks; + Dqn_u8 fixed_mem[DQN_KILOBYTES(16)]; + Dqn_MemBlock fixed_mem_block; + Dqn_MemBlock *curr_mem_block; + Dqn_MemBlock *top_mem_block; + Dqn_MemSize highest_used_mark; + int total_allocated_mem_blocks; }; struct Dqn_MemArenaScopedRegion @@ -566,28 +592,26 @@ struct Dqn_MemArenaScopedRegion Dqn_MemArenaScopedRegion(Dqn_MemArena *arena); ~Dqn_MemArenaScopedRegion(); Dqn_MemArena *arena; - MemBlock *curr_mem_block; - usize curr_mem_block_used; - MemBlock *top_mem_block; + Dqn_MemBlock *curr_mem_block; + Dqn_usize curr_mem_block_used; + Dqn_MemBlock *top_mem_block; }; -DQN_HEADER_COPY_BEGIN -#define DQN_DEBUG_MEM_ARENA_LOGGING -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) - #define DQN_DEBUG_ARGS , char const *file, isize file_len, char const *func, isize func_len, isize line +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + #define DQN_DEBUG_ARGS , char const *file, Dqn_isize file_len, char const *func, Dqn_isize func_len, Dqn_isize line #define DQN_DEBUG_PARAMS , DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__ #else #define DQN_DEBUG_ARGS #define DQN_DEBUG_PARAMS #endif -#define MEM_ARENA_ALLOC(arena, size) Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS); -#define MEM_ARENA_ALLOC_ARRAY(arena, T, num) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS); -#define MEM_ARENA_ALLOC_STRUCT(arena, T) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS); -#define MEM_ARENA_RESERVE(arena, size) Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS); -#define MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS); -#define MEM_ARENA_CLEAR_USED(arena) Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS); -#define MEM_ARENA_FREE(arena) Dqn_MemArena_Free +#define DQN_MEM_ARENA_ALLOC(arena, size) Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, num) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_ALLOC_STRUCT(arena, T) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_RESERVE(arena, size) Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_CLEAR_USED(arena) Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_FREE(arena) Dqn_MemArena_Free DQN_HEADER_COPY_END // ------------------------------------------------------------------------------------------------- @@ -598,30 +622,30 @@ DQN_HEADER_COPY_END struct Dqn_StringBuilderBuffer { char *mem; - MemSize size; - MemSize used; + Dqn_MemSize size; + Dqn_MemSize used; Dqn_StringBuilderBuffer *next; }; -usize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4); -template +Dqn_usize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4); +template struct Dqn_StringBuilder { void *(*my_malloc)(size_t bytes) = malloc; // Set to nullptr to disable heap allocation void (*my_free) (void *ptr) = free; // Set to nullptr to disable heap allocation char fixed_mem[N]; - MemSize fixed_mem_used; + Dqn_MemSize fixed_mem_used; Dqn_StringBuilderBuffer *next_mem_buf; Dqn_StringBuilderBuffer *last_mem_buf; - isize string_len; + Dqn_isize string_len; }; -template FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(Dqn_StringBuilder *builder, usize size_required) +template FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(Dqn_StringBuilder *builder, Dqn_usize size_required) { char *result = builder->fixed_mem + builder->fixed_mem_used; - usize space = Dqn_ArrayCount(builder->fixed_mem) - builder->fixed_mem_used; - usize *usage = &builder->fixed_mem_used; + Dqn_usize space = Dqn_ArrayCount(builder->fixed_mem) - builder->fixed_mem_used; + Dqn_usize *usage = &builder->fixed_mem_used; if (builder->last_mem_buf) { @@ -638,7 +662,7 @@ template FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUs return nullptr; // NOTE: Need to allocate new buf - usize allocation_size = sizeof(*builder->last_mem_buf) + DQN_MAX(size_required, DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE); + Dqn_usize allocation_size = sizeof(*builder->last_mem_buf) + DQN_MAX(size_required, DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE); void *memory = builder->my_malloc(allocation_size); auto *new_buf = reinterpret_cast(memory); *new_buf = {}; @@ -670,7 +694,7 @@ template FILE_SCOPE char *Dqn_StringBuilder__GetWriteBufferAndUpdateUs return result; } -template FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuilder const *builder, char *dest, isize dest_size) +template FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuilder const *builder, char *dest, Dqn_isize dest_size) { // NOTE: No data appended to builder, just allocate am empty string. But // always allocate, so we avoid adding making nullptr part of the possible @@ -687,7 +711,7 @@ template FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuil memcpy(buf_ptr, builder->fixed_mem, builder->fixed_mem_used); buf_ptr += builder->fixed_mem_used; - isize remaining_space = end - buf_ptr; + Dqn_isize remaining_space = end - buf_ptr; DQN_ASSERT(remaining_space >= 0); for (Dqn_StringBuilderBuffer *string_buf = builder->next_mem_buf; @@ -710,45 +734,45 @@ template FILE_SCOPE void Dqn_StringBuilder__BuildOutput(Dqn_StringBuil // @ // @ ----------------------------------------------------------------------------------------------- // @ The necessary length to build the string, it returns the length including the null-terminator -DQN_HEADER_COPY_PROTOTYPE(template isize, Dqn_StringBuilder_BuildLen(Dqn_StringBuilder const *builder)) +DQN_HEADER_COPY_PROTOTYPE(template Dqn_isize, Dqn_StringBuilder_BuildLen(Dqn_StringBuilder const *builder)) { - isize result = builder->string_len + 1; + Dqn_isize result = builder->string_len + 1; return result; } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder const *builder, char *dest, usize dest_size)) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder const *builder, char *dest, Dqn_usize dest_size)) { Dqn_StringBuilder__BuildOutput(builder, dest, dest_size); } -DQN_HEADER_COPY_PROTOTYPE(template char *, Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder *builder, isize *len = nullptr)) +DQN_HEADER_COPY_PROTOTYPE(template char *, Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder *builder, Dqn_isize *len = nullptr)) { - isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder); + Dqn_isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder); auto *result = static_cast(malloc(len_w_null_terminator)); if (len) *len = len_w_null_terminator; Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator); return result; } -DQN_HEADER_COPY_PROTOTYPE(template , char *Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder *builder, Dqn_MemArena *arena, isize *len = nullptr)) +DQN_HEADER_COPY_PROTOTYPE(template char *, Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder *builder, Dqn_MemArena *arena, Dqn_isize *len = nullptr)) { - isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder); - char *result = MEM_ARENA_ALLOC_ARRAY(arena, char, len_w_null_terminator); + Dqn_isize len_w_null_terminator = Dqn_StringBuilder_BuildLen(builder); + char *result = DQN_MEM_ARENA_ALLOC_ARRAY(arena, char, len_w_null_terminator); if (len) *len = len_w_null_terminator; Dqn_StringBuilder__BuildOutput(builder, result, len_w_null_terminator); return result; } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder *builder, char const *fmt, va_list va)) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder *builder, char const *fmt, va_list va)) { if (!fmt) return; - isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1; + Dqn_isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1; char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, require); stbsp_vsnprintf(buf, static_cast(require), fmt, va); builder->string_len += (require - 1); // -1 to exclude null terminator } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder *builder, char const *fmt, ...)) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder *builder, char const *fmt, ...)) { va_list va; va_start(va, fmt); @@ -756,18 +780,18 @@ DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_FmtAppend(D va_end(va); } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_Append(Dqn_StringBuilder *builder, char const *str, isize len = -1)) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_Append(Dqn_StringBuilder *builder, char const *str, Dqn_isize len = -1)) { if (!str) return; - if (len == -1) len = (isize)strlen(str); - isize len_w_null_terminator = len + 1; + if (len == -1) len = (Dqn_isize)strlen(str); + Dqn_isize len_w_null_terminator = len + 1; char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, len_w_null_terminator); Dqn_MemCopy(buf, str, len); builder->string_len += len; buf[len] = 0; } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_AppendChar(Dqn_StringBuilder *builder, char ch)) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_AppendChar(Dqn_StringBuilder *builder, char ch)) { char *buf = Dqn_StringBuilder__GetWriteBufferAndUpdateUsage(builder, 1 + 1 /*null terminator*/); *buf++ = ch; @@ -777,99 +801,108 @@ DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_StringBuilder_AppendChar( // @ ------------------------------------------------------------------------------------------------- // @ -// @ NOTE: (Memory) Slices +// @ NOTE: Dqn_Slices // @ // @ ------------------------------------------------------------------------------------------------- template -struct Slice +struct Dqn_Slice { union { T *data; T *buf; T *str; }; - union { isize size; isize len; }; + union { Dqn_isize size; Dqn_isize len; }; - Slice() = default; - Slice(T *str, isize len) { this->str = str; this->len = len; } + Dqn_Slice() = default; + Dqn_Slice(T *str, Dqn_isize len) { this->str = str; this->len = len; } - T const &operator[] (isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T &operator[] (isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } T const *begin () const { return data; } T const *end () const { return data + len; } T *begin () { return data; } T *end () { return data + len; } - T const *operator+ (isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } - T *operator+ (isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T const *operator+ (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T *operator+ (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } }; -#define SLICE_LITERAL(string) Slice(DQN_STR_AND_LEN(string)) +#define SLICE_LITERAL(string) Dqn_Slice(DQN_STR_AND_LEN(string)) -DQN_HEADER_COPY_PROTOTYPE(template , inline Slice Slice_CopyNullTerminated(Dqn_MemArena *arena, T const *src, isize len)) +DQN_HEADER_COPY_PROTOTYPE(template inline Dqn_Slice, Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, T const *src, Dqn_isize len)) { - Slice result = {}; + Dqn_Slice result = {}; result.len = len; - result.buf = MEM_ARENA_ALLOC_ARRAY(arena, T, len + 1); + result.buf = DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, len + 1); Dqn_MemCopy(result.buf, src, len * sizeof(T)); result.buf[len] = 0; return result; } -DQN_HEADER_COPY_PROTOTYPE(template , inline Slice Slice_CopyNullTerminated(Dqn_MemArena *arena, Slice const src)) +DQN_HEADER_COPY_PROTOTYPE(template inline Dqn_Slice, Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, Dqn_Slice const src)) { - Slice result = Slice_CopyNullTerminated(arena, src.buf, src.len); + Dqn_Slice result = Dqn_Slice_CopyNullTerminated(arena, src.buf, src.len); return result; } -DQN_HEADER_COPY_PROTOTYPE(template , inline Slice Slice_Copy(Dqn_MemArena *arena, T const *src, isize len)) +DQN_HEADER_COPY_PROTOTYPE(template inline Dqn_Slice, Dqn_Slice_Copy(Dqn_MemArena *arena, T const *src, Dqn_isize len)) { - Slice result = {}; + Dqn_Slice result = {}; result.len = len; - result.buf = MEM_ARENA_ALLOC_ARRAY(arena, T, len); + result.buf = DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, len); MemCopy(result.buf, src, len * sizeof(T)); return result; } -DQN_HEADER_COPY_PROTOTYPE(template , inline Slice Slice_Copy(Dqn_MemArena *arena, Slice const src)) +DQN_HEADER_COPY_PROTOTYPE(template inline Dqn_Slice, Dqn_Slice_Copy(Dqn_MemArena *arena, Dqn_Slice const src)) { - Slice result = Slice_Copy(arena, src.buf, src.len); + Dqn_Slice result = Dqn_Slice_Copy(arena, src.buf, src.len); return result; } -// @ ------------------------------------------------------------------------------------------------- -// @ -// @ NOTE: Asprintf (Allocate Sprintf) -// @ -// @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(template Slice, AsprintfSlice(T *arena, char const *fmt, va_list va)) +DQN_HEADER_COPY_PROTOTYPE(template inline bool, Dqn_Slice_Equals(Dqn_Slice const a, Dqn_Slice const b)) { - Slice result = {}; + bool result = false; + if (a.len != b.len) return result; + result = (memcmp(a.buf, b.buf, a.len) == 0); + return result; +} + + +// @ ------------------------------------------------------------------------------------------------- +// @ +// @ NOTE: Dqn_Asprintf (Allocate Sprintf) +// @ +// @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_PROTOTYPE(template Dqn_Slice, Dqn_AsprintfSlice(T *arena, char const *fmt, va_list va)) +{ + Dqn_Slice result = {}; result.len = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1; - result.buf = MEM_ARENA_ALLOC_ARRAY(arena, char, result.len); - stbsp_vsnprintf(result.buf, Dqn_SafeTruncateISizeToInt(result.len), fmt, va); + result.buf = DQN_MEM_ARENA_ALLOC_ARRAY(arena, char, result.len); + stbsp_vsnprintf(result.buf, Dqn_Safe_TruncateISizeToInt(result.len), fmt, va); result.buf[result.len - 1] = 0; return result; } -DQN_HEADER_COPY_PROTOTYPE(template Slice, AsprintfSlice(T *arena, char const *fmt, ...)) +DQN_HEADER_COPY_PROTOTYPE(template Dqn_Slice, Dqn_AsprintfSlice(T *arena, char const *fmt, ...)) { va_list va; va_start(va, fmt); - Slice result = AsprintfSlice(arena, fmt, va); + Dqn_Slice result = Dqn_AsprintfSlice(arena, fmt, va); va_end(va); return result; } -DQN_HEADER_COPY_PROTOTYPE(template char *, Asprintf(T *arena, int *len, char const *fmt, ...)) +DQN_HEADER_COPY_PROTOTYPE(template char *, Dqn_Asprintf(T *arena, int *len, char const *fmt, ...)) { va_list va; va_start(va, fmt); - Slice result = AsprintfSlice(arena, fmt, va); + Dqn_Slice result = Dqn_AsprintfSlice(arena, fmt, va); va_end(va); if (len) *len = result.len; return result.str; } -DQN_HEADER_COPY_PROTOTYPE(template char *, Asprintf(T *arena, char const *fmt, ...)) +DQN_HEADER_COPY_PROTOTYPE(template char *, Dqn_Asprintf(T *arena, char const *fmt, ...)) { va_list va; va_start(va, fmt); - Slice result = AsprintfSlice(arena, fmt, va); + Dqn_Slice result = Dqn_AsprintfSlice(arena, fmt, va); va_end(va); return result.str; } @@ -879,22 +912,36 @@ DQN_HEADER_COPY_PROTOTYPE(template char *, Asprintf(T *arena, char // @ NOTE: Dqn_FixedArray // @ // @ ------------------------------------------------------------------------------------------------- + +template void Dqn__EraseStableFromCArray(T *array, Dqn_isize len, Dqn_isize max, Dqn_isize index) +{ + DQN_ASSERT(index >= 0 && index < len); + DQN_ASSERT(len <= max); + Dqn_isize next_index = DQN_MIN(index + 1, len); + Dqn_usize bytes_to_copy = (len - next_index) * sizeof(T); + Dqn_MemMove(array + index, array + next_index, bytes_to_copy); +} + +DQN_HEADER_COPY_BEGIN #define DQN_FIXED_ARRAY_TEMPLATE template #define DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray DQN_FIXED_ARRAY_TEMPLATE struct Dqn_FixedArray { - T data[MAX_]; - isize len; - isize Max() const { return MAX_; } - T const &operator[] (isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T &operator[] (isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T const *begin () const { return data; } - T const *end () const { return data + len; } - T *begin () { return data; } - T *end () { return data + len; } - T const *operator+ (isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } - T *operator+ (isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T data[MAX_]; + Dqn_isize len; + Dqn_isize Max() const { return MAX_; } + + T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T *begin () { return data; } + T *end () { return data + len; } + T *operator+ (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + + T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T const *begin () const { return data; } + T const *end () const { return data + len; } + T const *operator+ (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } }; +DQN_HEADER_COPY_END DQN_FIXED_ARRAY_TEMPLATE DQN_HEADER_COPY_PROTOTYPE(DQN_FIXED_ARRAY_TEMPLATE_DECL, Dqn_FixedArray_Init(T const *item, int num)) @@ -905,7 +952,7 @@ DQN_HEADER_COPY_PROTOTYPE(DQN_FIXED_ARRAY_TEMPLATE_DECL, Dqn_FixedArray_Init(T c } DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *items, isize num)) +DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *items, Dqn_isize num)) { DQN_ASSERT(a->len + num <= MAX_); T *result = static_cast(Dqn_MemCopy(a->data + a->len, items, sizeof(T) * num)); @@ -922,7 +969,7 @@ DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL } DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Make(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, isize num)) +DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Make(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num)) { DQN_ASSERT(a->len + num <= MAX_); T *result = a->data + a->len; @@ -936,24 +983,15 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_Clear(DQN_FIXED_ARRAY_TEMPLATE_DE a->len = 0; } -DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_EraseStableFromCArray(T *array, isize len, isize max, isize index)) -{ - DQN_ASSERT(index >= 0 && index < len); - DQN_ASSERT(len <= max); - isize next_index = DQN_MIN(index + 1, len); - usize bytes_to_copy = (len - next_index) * sizeof(T); - Dqn_MemMove(array + index, array + next_index, bytes_to_copy); -} - DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseStable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, isize index)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseStable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index)) { Dqn_EraseStableFromCArray(a->data, a->len--, a->Max(), index); } DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, isize index)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index)) { DQN_ASSERT(index >= 0 && index < a->len); if (--a->len == 0) return; @@ -962,7 +1000,7 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEM DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, isize num)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num)) { DQN_ASSERT(a->len - num >= 0); a->len -= num; @@ -977,9 +1015,9 @@ DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Peek(DQN_FIXED_ARRAY_TEMPLATE_DECL } DQN_FIXED_ARRAY_TEMPLATE -DQN_HEADER_COPY_PROTOTYPE(isize, Dqn_FixedArray_GetIndex(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *entry)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_isize, Dqn_FixedArray_GetIndex(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *entry)) { - isize result = a->end() - entry; + Dqn_isize result = a->end() - entry; return result; } @@ -1010,74 +1048,88 @@ DQN_HEADER_COPY_PROTOTYPE(T *, Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL // @ NOTE: Dqn_FixedStack // @ // @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_BEGIN template using Dqn_FixedStack = DQN_FIXED_ARRAY_TEMPLATE_DECL; template T Dqn_FixedStack_Pop (Dqn_FixedStack *array) { T result = *Dqn_FixedArray_Peek(array); Dqn_FixedArray_Pop(array, 1); return result; } template T *Dqn_FixedStack_Peek (Dqn_FixedStack *array) { return Dqn_FixedArray_Peek(array); } template T *Dqn_FixedStack_Push (Dqn_FixedStack *array, T item) { return Dqn_FixedArray_Add(array, item); } template void Dqn_FixedStack_Clear(Dqn_FixedStack *array) { Dqn_FixedArray_Clear(array); } +DQN_HEADER_COPY_END // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_StaticArray // @ // @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_BEGIN template struct Dqn_StaticArray { T *data; - isize len; - isize max; - T const operator[](isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - T operator[](isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + Dqn_isize len; + Dqn_isize max; + T const operator[](Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T operator[](Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } T const *begin () const { return data; } T const *end () const { return data + len; } T *begin () { return data; } T *end () { return data + len; } - T const *operator+(isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } - T *operator+(isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T const *operator+(Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T *operator+(Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } }; -template Dqn_StaticArray Dqn_StaticArray_InitMemory (T *memory, isize max, isize len = 0) { Dqn_StaticArray result = {}; result.data = memory; result.len = len; result.max = max; return result; } -template T *Dqn_StaticArray_Add (Dqn_StaticArray *a, T const *items, isize num) { DQN_ASSERT(a->len + num <= a->max); T *result = static_cast(Dqn_MemCopy(a->data + a->len, items, sizeof(T) * num)); a->len += num; return result; } -template T *Dqn_StaticArray_Add (Dqn_StaticArray *a, T const item) { DQN_ASSERT(a->len < a->max); a->data[a->len++] = item; return &a->data[a->len - 1]; } -template T *Dqn_StaticArray_Make (Dqn_StaticArray *a, isize num) { DQN_ASSERT(a->len + num <= a->max); T *result = a->data + a->len; a->len += num; return result;} -template void Dqn_StaticArray_Clear (Dqn_StaticArray *a) { a->len = 0; } -template void Dqn_StaticArray_EraseStable (Dqn_StaticArray *a, isize index) { Dqn_EraseStableFromCArray(a->data, a->len--, a->max, index); } -template void Dqn_StaticArray_EraseUnstable(Dqn_StaticArray *a, isize index) { DQN_ASSERT(index >= 0 && index < a->len); if (--a->len == 0) return; a->data[index] = a->data[a->len]; } -template void Dqn_StaticArray_Pop (Dqn_StaticArray *a, isize num) { DQN_ASSERT(a->len - num >= 0); a->len -= num; } -template T *Dqn_StaticArray_Peek (Dqn_StaticArray *a) { T *result = (a->len == 0) ? nullptr : a->data + (a->len - 1); return result; } +DQN_HEADER_COPY_END + +DQN_HEADER_COPY_PROTOTYPE(template Dqn_StaticArray , Dqn_StaticArray_InitMemory (T *memory, Dqn_isize max, Dqn_isize len = 0)) { Dqn_StaticArray result = {}; result.data = memory; result.len = len; result.max = max; return result; } +DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_StaticArray_Add (Dqn_StaticArray *a, T const *items, Dqn_isize num)) { DQN_ASSERT(a->len + num <= a->max); T *result = static_cast(Dqn_MemCopy(a->data + a->len, items, sizeof(T) * num)); a->len += num; return result; } +DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_StaticArray_Add (Dqn_StaticArray *a, T const item)) { DQN_ASSERT(a->len < a->max); a->data[a->len++] = item; return &a->data[a->len - 1]; } +DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_StaticArray_Make (Dqn_StaticArray *a, Dqn_isize num)) { DQN_ASSERT(a->len + num <= a->max); T *result = a->data + a->len; a->len += num; return result;} +DQN_HEADER_COPY_PROTOTYPE(template void , Dqn_StaticArray_Clear (Dqn_StaticArray *a)) { a->len = 0; } +DQN_HEADER_COPY_PROTOTYPE(template void , Dqn_StaticArray_EraseStable (Dqn_StaticArray *a, Dqn_isize index)) { Dqn_EraseStableFromCArray(a->data, a->len--, a->max, index); } +DQN_HEADER_COPY_PROTOTYPE(template void , Dqn_StaticArray_EraseUnstable(Dqn_StaticArray *a, Dqn_isize index)) { DQN_ASSERT(index >= 0 && index < a->len); if (--a->len == 0) return; a->data[index] = a->data[a->len]; } +DQN_HEADER_COPY_PROTOTYPE(template void , Dqn_StaticArray_Pop (Dqn_StaticArray *a, Dqn_isize num)) { DQN_ASSERT(a->len - num >= 0); a->len -= num; } +DQN_HEADER_COPY_PROTOTYPE(template T *, Dqn_StaticArray_Peek (Dqn_StaticArray *a)) { T *result = (a->len == 0) ? nullptr : a->data + (a->len - 1); return result; } // @ ------------------------------------------------------------------------------------------------- // @ // @ NOTE: Dqn_FixedString // @ // @ ------------------------------------------------------------------------------------------------- -template +DQN_HEADER_COPY_BEGIN +template struct Dqn_FixedString { union { char data[MAX_]; char str[MAX_]; char buf[MAX_]; }; - isize len; - isize Max() const { return MAX_; } + Dqn_isize len; + Dqn_isize Max() const { return MAX_; } Dqn_FixedString() { data[0] = 0; len = 0; } - Dqn_FixedString(char const *fmt, ...); + Dqn_FixedString(char const *fmt, ...) + { + *this = {}; + va_list va; + va_start(va, fmt); + Dqn_FixedString_AppendVFmt(this, fmt, va); + va_end(va); + } - char const &operator[] (isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } - char &operator[] (isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + char const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + char &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } char const *begin () const { return data; } char const *end () const { return data + len; } char *begin () { return data; } char *end () { return data + len; } }; +DQN_HEADER_COPY_END -template void Dqn_FixedString_Clear (Dqn_FixedString *str) { *str = {}; } -template void Dqn_FixedString_AppendVFmt(Dqn_FixedString *str, char const *fmt, va_list va) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_FixedString_Clear(Dqn_FixedString *str)) { *str = {}; } +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_FixedString_AppendVFmt(Dqn_FixedString *str, char const *fmt, va_list va)) { - isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1; - isize space = MAX_ - str->len; + Dqn_isize require = stbsp_vsnprintf(nullptr, 0, fmt, va) + 1; + Dqn_isize space = MAX_ - str->len; DQN_ASSERT(require <= space); str->len += stbsp_vsnprintf(str->data + str->len, static_cast(space), fmt, va); } -template void Dqn_FixedString_AppendFmt(Dqn_FixedString *str, char const *fmt, ...) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_FixedString_AppendFmt(Dqn_FixedString *str, char const *fmt, ...)) { va_list va; va_start(va, fmt); @@ -1085,33 +1137,31 @@ template void Dqn_FixedString_AppendFmt(Dqn_FixedString *str, va_end(va); } -template void Dqn_FixedString_Append(Dqn_FixedString *str, char const *src, isize len = -1) +DQN_HEADER_COPY_PROTOTYPE(template void, Dqn_FixedString_Append(Dqn_FixedString *str, char const *src, Dqn_isize len = -1)) { - if (len == -1) len = (isize)strlen(src); - isize space = MAX_ - str->len; + if (len == -1) len = (Dqn_isize)strlen(src); + Dqn_isize space = MAX_ - str->len; DQN_ASSERT(len <= space); memcpy(str->data + str->len, src, len); str->len += len; str->str[str->len] = 0; } -template Dqn_FixedString::Dqn_FixedString(char const *fmt, ...) -{ - *this = {}; - va_list va; - va_start(va, fmt); - Dqn_FixedString_AppendVFmt(this, fmt, va); - va_end(va); -} - -struct U64Str +// @ ------------------------------------------------------------------------------------------------- +// @ +// @ NOTE: Dqn_Dqn_U64Str +// @ +// @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_BEGIN +struct Dqn_U64Str { // Points to the start of the str in the buffer, not necessarily buf since // we write into the buffer in reverse char *start; - char buf[27]; // NOTE(doyle): 27 is the maximum size of u64 including commas + char buf[27]; // NOTE(doyle): 27 is the maximum size of Dqn_u64 including commas int len; }; +DQN_HEADER_COPY_END #endif // DQN_H #ifdef DQN_IMPLEMENTATION @@ -1145,7 +1195,7 @@ DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemMove(void *dest, void const *src, size_ return result; } -DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemSet(void *src, char ch, usize num_bytes)) +DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemSet(void *src, char ch, Dqn_usize num_bytes)) { void *result = memset(src, ch, num_bytes); return result; @@ -1156,11 +1206,11 @@ DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemSet(void *src, char ch, usize num_bytes // @ NOTE: Logging // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_LogV(Dqn_LogType type, char const *file, usize file_len, char const *func, usize func_len, usize line, char const *fmt, va_list va)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_LogV(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va)) { char const *file_ptr = file; - usize file_ptr_len = file_len; - for (usize i = (file_ptr_len - 1); i >= 0; --i) + Dqn_usize file_ptr_len = file_len; + for (Dqn_usize i = (file_ptr_len - 1); i >= 0; --i) { if (file_ptr[i] == '\\' || file_ptr[i] == '/') { @@ -1185,7 +1235,7 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_LogV(Dqn_LogType type, char const *file, usi fprintf(handle, "\n"); } -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Log(Dqn_LogType type, char const *file, usize file_len, char const *func, usize func_len, usize line, char const *fmt, ...)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Log(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...)) { va_list va; va_start(va, fmt); @@ -1195,24 +1245,24 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Log(Dqn_LogType type, char const *file, usiz // @ ------------------------------------------------------------------------------------------------- // @ -// @ NOTE: Dqn_MemArena Internal +// @ NOTE: Dqn_MemArena // @ // @ ------------------------------------------------------------------------------------------------- -FILE_SCOPE MemBlock *Dqn_MemArena__AllocateBlock(Dqn_MemArena *arena, usize requested_size) +FILE_SCOPE Dqn_MemBlock *Dqn_MemArena__AllocateBlock(Dqn_MemArena *arena, Dqn_usize requested_size) { - usize mem_block_size = DQN_MAX(Dqn_ArrayCount(arena->fixed_mem), requested_size); - usize const allocate_size = sizeof(*arena->curr_mem_block) + mem_block_size; - MemBlock *result = nullptr; + Dqn_usize mem_block_size = DQN_MAX(Dqn_ArrayCount(arena->fixed_mem), requested_size); + Dqn_usize const allocate_size = sizeof(*arena->curr_mem_block) + mem_block_size; + Dqn_MemBlock *result = nullptr; if (arena->my_calloc) { DQN_ASSERT(arena->my_free); - result = static_cast(arena->my_calloc(allocate_size)); + result = static_cast(arena->my_calloc(allocate_size)); } else { if (!(arena->flags & Dqn_MemArenaFlag_NoCRTAllocation)) - result = static_cast(calloc(1, allocate_size)); + result = static_cast(calloc(1, allocate_size)); } if (!result) @@ -1220,12 +1270,12 @@ FILE_SCOPE MemBlock *Dqn_MemArena__AllocateBlock(Dqn_MemArena *arena, usize requ *result = {}; result->size = mem_block_size; - result->memory = reinterpret_cast(result) + sizeof(*result); + result->memory = reinterpret_cast(result) + sizeof(*result); arena->total_allocated_mem_blocks++; return result; } -FILE_SCOPE void Dqn_MemArena__FreeBlock(Dqn_MemArena *arena, MemBlock *block) +FILE_SCOPE void Dqn_MemArena__FreeBlock(Dqn_MemArena *arena, Dqn_MemBlock *block) { if (!block) return; @@ -1251,7 +1301,7 @@ FILE_SCOPE void Dqn_MemArena__FreeBlock(Dqn_MemArena *arena, MemBlock *block) } } -FILE_SCOPE void Dqn_MemArena__AttachBlock(Dqn_MemArena *arena, MemBlock *new_block) +FILE_SCOPE void Dqn_MemArena__AttachBlock(Dqn_MemArena *arena, Dqn_MemBlock *new_block) { DQN_ASSERT(arena->curr_mem_block); DQN_ASSERT(arena->top_mem_block->next == nullptr); @@ -1275,22 +1325,17 @@ FILE_SCOPE void Dqn_MemArena__LazyInit(Dqn_MemArena *arena) } -// @ ------------------------------------------------------------------------------------------------- -// @ -// @ NOTE: Dqn_MemArena -// @ -// @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, usize size DQN_DEBUG_ARGS)) +DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) { -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) (void)file; (void)file_len; (void)func; (void)func_len; (void)line; #endif Dqn_MemArena__LazyInit(arena); - b32 need_new_mem_block = true; + Dqn_b32 need_new_mem_block = true; - for (MemBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next) + for (Dqn_MemBlock *mem_block = arena->curr_mem_block; mem_block; mem_block = mem_block->next) { - b32 can_fit_in_block = (mem_block->used + size) <= mem_block->size; + Dqn_b32 can_fit_in_block = (mem_block->used + size) <= mem_block->size; if (can_fit_in_block) { arena->curr_mem_block = mem_block; @@ -1301,13 +1346,13 @@ DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, usize if (need_new_mem_block) { - MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); + Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); if (!new_block) return nullptr; Dqn_MemArena__AttachBlock(arena, new_block); arena->curr_mem_block = arena->top_mem_block; } - void *result = static_cast(arena->curr_mem_block->memory) + arena->curr_mem_block->used; + void *result = static_cast(arena->curr_mem_block->memory) + arena->curr_mem_block->used; arena->curr_mem_block->used += size; DQN_ASSERT(arena->curr_mem_block->used <= arena->curr_mem_block->size); return result; @@ -1315,12 +1360,12 @@ DQN_HEADER_COPY_PROTOTYPE(void *, Dqn_MemArena_Alloc(Dqn_MemArena *arena, usize DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS)) { -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) (void)file; (void)file_len; (void)func; (void)func_len; (void)line; #endif - for (MemBlock *mem_block = arena->top_mem_block; mem_block;) + for (Dqn_MemBlock *mem_block = arena->top_mem_block; mem_block;) { - MemBlock *block_to_free = mem_block; + Dqn_MemBlock *block_to_free = mem_block; mem_block = block_to_free->prev; Dqn_MemArena__FreeBlock(arena, block_to_free); } @@ -1334,32 +1379,32 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ arena->my_free = my_free; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_MemArena_Reserve(Dqn_MemArena *arena, usize size DQN_DEBUG_ARGS)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS)) { -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) (void)file; (void)file_len; (void)func; (void)func_len; (void)line; #endif Dqn_MemArena__LazyInit(arena); - MemSize remaining_space = arena->top_mem_block->size - arena->top_mem_block->used; + Dqn_MemSize remaining_space = arena->top_mem_block->size - arena->top_mem_block->used; if (remaining_space >= size) return true; - MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); + Dqn_MemBlock *new_block = Dqn_MemArena__AllocateBlock(arena, size); if (!new_block) return false; Dqn_MemArena__AttachBlock(arena, new_block); return true; } -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, usize size DQN_DEBUG_ARGS)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS)) { -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) (void)file; (void)file_len; (void)func; (void)func_len; (void)line; #endif DQN_ASSERT_MSG(size >= sizeof(*arena->curr_mem_block), - "(%zu >= %zu) There needs to be enough space to encode the MemBlock struct into the memory buffer", size, sizeof(*arena->curr_mem_block)); + "(%zu >= %zu) There needs to be enough space to encode the Dqn_MemBlock struct into the memory buffer", size, sizeof(*arena->curr_mem_block)); Dqn_MemArena__LazyInit(arena); - auto *mem_block = static_cast(memory); + auto *mem_block = static_cast(memory); *mem_block = {}; - mem_block->memory = static_cast(memory) + sizeof(*mem_block); + mem_block->memory = static_cast(memory) + sizeof(*mem_block); mem_block->size = size - sizeof(*mem_block); mem_block->allocated_by_user_or_fixed_mem = true; Dqn_MemArena__AttachBlock(arena, mem_block); @@ -1367,10 +1412,10 @@ DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, vo DQN_HEADER_COPY_PROTOTYPE(void, Dqn_MemArena_ClearUsed(Dqn_MemArena *arena DQN_DEBUG_ARGS)) { -#if defined(DQN_DEBUG_MEM_ARENA_LOGGING) +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) (void)file; (void)file_len; (void)func; (void)func_len; (void)line; #endif - for (MemBlock *mem_block = arena->top_mem_block; mem_block; mem_block = mem_block->prev) + for (Dqn_MemBlock *mem_block = arena->top_mem_block; mem_block; mem_block = mem_block->prev) mem_block->used = 0; arena->curr_mem_block = &arena->fixed_mem_block; } @@ -1392,14 +1437,14 @@ Dqn_MemArenaScopedRegion::~Dqn_MemArenaScopedRegion() { while (this->top_mem_block != this->arena->top_mem_block) { - MemBlock *block_to_free = this->arena->top_mem_block; + Dqn_MemBlock *block_to_free = this->arena->top_mem_block; if (this->arena->curr_mem_block == block_to_free) this->arena->curr_mem_block = block_to_free->prev; this->arena->top_mem_block = block_to_free->prev; Dqn_MemArena__FreeBlock(this->arena, block_to_free); } - for (MemBlock *mem_block = this->arena->top_mem_block; mem_block != this->curr_mem_block; mem_block = mem_block->prev) + for (Dqn_MemBlock *mem_block = this->arena->top_mem_block; mem_block != this->curr_mem_block; mem_block = mem_block->prev) mem_block->used = 0; this->arena->curr_mem_block->used = this->curr_mem_block_used; @@ -1412,7 +1457,7 @@ Dqn_MemArenaScopedRegion::~Dqn_MemArenaScopedRegion() // @ ------------------------------------------------------------------------------------------------- DQN_HEADER_COPY_PROTOTYPE(Dqn_V2I, Dqn_V2_ToV2I(Dqn_V2 a)) { - Dqn_V2I result(static_cast(a.x), static_cast(a.y)); + Dqn_V2I result(static_cast(a.x), static_cast(a.y)); return result; } @@ -1428,25 +1473,25 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_V2_Abs(Dqn_V2 a)) return result; } -DQN_HEADER_COPY_PROTOTYPE(f32, Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_f32, Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b)) { - f32 result = (a.x * b.x) + (a.y * b.y); + Dqn_f32 result = (a.x * b.x) + (a.y * b.y); return result; } -DQN_HEADER_COPY_PROTOTYPE(f32, Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_f32, Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b)) { - f32 x_side = b.x - a.x; - f32 y_side = b.y - a.y; - f32 result = DQN_SQUARED(x_side) + DQN_SQUARED(y_side); + Dqn_f32 x_side = b.x - a.x; + Dqn_f32 y_side = b.y - a.y; + Dqn_f32 result = DQN_SQUARED(x_side) + DQN_SQUARED(y_side); return result; } DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_V2_Normalise(Dqn_V2 a)) { - f32 length_sq = DQN_SQUARED(a.x) + DQN_SQUARED(a.y); - f32 length = sqrtf(length_sq); + Dqn_f32 length_sq = DQN_SQUARED(a.x) + DQN_SQUARED(a.y); + Dqn_f32 length = sqrtf(length_sq); Dqn_V2 result = a / length; return result; } @@ -1458,9 +1503,9 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_V2_Perpendicular(Dqn_V2 a)) return result; } -DQN_HEADER_COPY_PROTOTYPE(f32, Dqn_V4_Dot(Dqn_V4 const *a, Dqn_V4 const *b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_f32, Dqn_V4_Dot(Dqn_V4 const *a, Dqn_V4 const *b)) { - f32 result = (a->x * b->x) + (a->y * b->y) + (a->z * b->z) + (a->w * b->w); + Dqn_f32 result = (a->x * b->x) + (a->y * b->y) + (a->z * b->z) + (a->w * b->w); return result; } @@ -1489,16 +1534,16 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_Rect_Center(Dqn_Rect rect)) } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p)) { - b32 result = (p.x >= rect.min.x && p.x <= rect.max.x && p.y >= rect.min.y && p.y <= rect.max.y); + Dqn_b32 result = (p.x >= rect.min.x && p.x <= rect.max.x && p.y >= rect.min.y && p.y <= rect.max.y); return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b)) { - b32 result = (b.min >= a.min && b.max <= a.max); + Dqn_b32 result = (b.min >= a.min && b.max <= a.max); return result; } @@ -1545,7 +1590,7 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_V2I, Dqn_RectI32_Size(Dqn_RectI32 rect)) // @ NOTE: Math Utils // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_LerpV2(Dqn_V2 a, f32 t, Dqn_V2 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_V2, Dqn_LerpV2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b)) { Dqn_V2 result = {}; result.x = a.x + ((b.x - a.x) * t); @@ -1570,7 +1615,7 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_Identity()) return result; } -DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_Scale3f(f32 x, f32 y, f32 z)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_Scale3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z)) { Dqn_Mat4 result = { @@ -1588,7 +1633,7 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_ScaleV3(Dqn_V3 vec)) return result; } -DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_Translate3f(f32 x, f32 y, f32 z)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, Dqn_Mat4_Translate3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z)) { Dqn_Mat4 result = { @@ -1632,7 +1677,7 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_Mat4, operator*(Dqn_Mat4 const &a, Dqn_Mat4 const DQN_HEADER_COPY_PROTOTYPE(Dqn_V4, operator*(Dqn_Mat4 const &mat, Dqn_V4 const &vec)) { - f32 x = vec.x, y = vec.y, z = vec.z, w = vec.w; + Dqn_f32 x = vec.x, y = vec.y, z = vec.z, w = vec.w; Dqn_V4 result = { (mat[0] * x) + (mat[1] * y) + (mat[2] * z) + (mat[3] * w), @@ -1649,28 +1694,28 @@ DQN_HEADER_COPY_PROTOTYPE(Dqn_V4, operator*(Dqn_Mat4 const &mat, Dqn_V4 const &v // @ NOTE: Helper Functions // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_BitUnsetInplace(u32 *flags, u32 bitfield)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Bit_UnsetInplace(Dqn_u32 *flags, Dqn_u32 bitfield)) { *flags = (*flags & ~bitfield); } -DQN_HEADER_COPY_PROTOTYPE(void, Dqn_BitSetInplace(u32 *flags, u32 bitfield)) +DQN_HEADER_COPY_PROTOTYPE(void, Dqn_Bit_SetInplace(Dqn_u32 *flags, Dqn_u32 bitfield)) { *flags = (*flags | bitfield); } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_BitIsSet(u32 flags, u32 bitfield)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Bit_IsSet(Dqn_u32 flags, Dqn_u32 bitfield)) { - b32 result = (flags & bitfield); + Dqn_b32 result = (flags & bitfield); return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_BitIsNotSet(u32 flags, u32 bitfield)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Bit_IsNotSet(Dqn_u32 flags, Dqn_u32 bitfield)) { - b32 result = !(flags & bitfield); + Dqn_b32 result = !(flags & bitfield); return result; } @@ -1680,45 +1725,38 @@ DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_BitIsNotSet(u32 flags, u32 bitfield)) // @ NOTE: Safe Arithmetic // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(i64, Dqn_SafeAddI64(i64 a, i64 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_i64, Dqn_Safe_AddI64(Dqn_i64 a, Dqn_i64 b)) { DQN_ASSERT_MSG(a <= INT64_MAX - b, "%zu <= %zu", a, INT64_MAX - b); - i64 result = a + b; + Dqn_i64 result = a + b; return result; } -DQN_HEADER_COPY_PROTOTYPE(i64, Dqn_SafeMulI64(i64 a, i64 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_i64, Dqn_Safe_MulI64(Dqn_i64 a, Dqn_i64 b)) { DQN_ASSERT_MSG(a <= INT64_MAX / b , "%zu <= %zu", a, INT64_MAX / b); - i64 result = a * b; + Dqn_i64 result = a * b; return result; } -DQN_HEADER_COPY_PROTOTYPE(u64, Dqn_SafeAddU64(u64 a, u64 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_u64, Dqn_Safe_AddU64(Dqn_u64 a, Dqn_u64 b)) { DQN_ASSERT_MSG(a <= UINT64_MAX - b, "%zu <= %zu", a, UINT64_MAX - b); - u64 result = a + b; + Dqn_u64 result = a + b; return result; } -DQN_HEADER_COPY_PROTOTYPE(u64, Dqn_SafeMulU64(u64 a, u64 b)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_u64, Dqn_Safe_MulU64(Dqn_u64 a, Dqn_u64 b)) { DQN_ASSERT_MSG(a <= UINT64_MAX / b , "%zu <= %zu", a, UINT64_MAX / b); - u64 result = a * b; + Dqn_u64 result = a * b; return result; } - - -// @ ------------------------------------------------------------------------------------------------- -// @ -// @ NOTE: SafeTruncate -// @ -// @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateISizeToInt(isize val)) +DQN_HEADER_COPY_PROTOTYPE(int, Dqn_Safe_TruncateISizeToInt(Dqn_isize val)) { DQN_ASSERT_MSG(val >= INT_MIN && val <= INT_MAX, "%zd >= %zd && %zd <= %zd", val, INT_MIN, val, INT_MAX); auto result = (int)val; @@ -1726,31 +1764,31 @@ DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateISizeToInt(isize val)) } -DQN_HEADER_COPY_PROTOTYPE(i32, Dqn_SafeTruncateISizeToI32(isize val)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_i32, Dqn_Safe_TruncateISizeToI32(Dqn_isize val)) { DQN_ASSERT_MSG(val >= INT32_MIN && val <= INT32_MAX, "%zd >= %zd && %zd <= %zd", val, INT32_MIN, val, INT32_MAX); - auto result = (i32)val; + auto result = (Dqn_i32)val; return result; } -DQN_HEADER_COPY_PROTOTYPE(i8, SafeTruncateISizeToI8(isize val)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_i8, Dqn_Safe_TruncateISizeToI8(Dqn_isize val)) { DQN_ASSERT_MSG(val >= INT8_MIN && val <= INT8_MAX, "%zd >= %zd && %zd <= %zd", val, INT8_MIN, val, INT8_MAX); - auto result = (i8)val; + auto result = (Dqn_i8)val; return result; } -DQN_HEADER_COPY_PROTOTYPE(u32, Dqn_SafeTruncateUSizeToU32(u64 val)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_u32, Dqn_Safe_TruncateUSizeToU32(Dqn_u64 val)) { DQN_ASSERT_MSG(val <= UINT32_MAX, "%zu <= %zu", val, UINT32_MAX); - auto result = (u32)val; + auto result = (Dqn_u32)val; return result; } -DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateUSizeToI32(usize val)) +DQN_HEADER_COPY_PROTOTYPE(int, Dqn_Safe_TruncateUSizeToI32(Dqn_usize val)) { DQN_ASSERT_MSG(val <= INT32_MAX, "%zu <= %zd", val, INT32_MAX); auto result = (int)val; @@ -1758,7 +1796,7 @@ DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateUSizeToI32(usize val)) } -DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateUSizeToInt(usize val)) +DQN_HEADER_COPY_PROTOTYPE(int, Dqn_Safe_TruncateUSizeToInt(Dqn_usize val)) { DQN_ASSERT_MSG(val <= INT_MAX, "%zu <= %zd", val, INT_MAX); auto result = (int)val; @@ -1771,30 +1809,30 @@ DQN_HEADER_COPY_PROTOTYPE(int, Dqn_SafeTruncateUSizeToInt(usize val)) // @ NOTE: Char Helpers // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_CharIsAlpha(char ch)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Char_IsAlpha(char ch)) { - b32 result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); + Dqn_b32 result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_CharIsDigit(char ch)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Char_IsDigit(char ch)) { - b32 result = (ch >= '0' && ch <= '9'); + Dqn_b32 result = (ch >= '0' && ch <= '9'); return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_CharIsAlphaNum(char ch)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Char_IsAlphaNum(char ch)) { - b32 result = Dqn_CharIsAlpha(ch) || Dqn_CharIsDigit(ch); + Dqn_b32 result = Dqn_Char_IsAlpha(ch) || Dqn_Char_IsDigit(ch); return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_CharIsWhitespace(char ch)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Char_IsWhitespace(char ch)) { - b32 result = (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + Dqn_b32 result = (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); return result; } @@ -1803,40 +1841,27 @@ DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_CharIsWhitespace(char ch)) // @ NOTE: String Helpers // @ // @ ------------------------------------------------------------------------------------------------- -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_StrCmp(char const *a, isize a_len, char const *b, isize b_len = -1)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Str_Equals(char const *a, Dqn_isize a_len, char const *b, Dqn_isize b_len = -1)) { if (b_len == -1) b_len = strlen(b); if (a_len != b_len) return false; return (strncmp(a, b, a_len) == 0); } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_StrCmp(Slice const a, Slice const b)) -{ - b32 result = Dqn_StrCmp(a.str, a.len, b.str, b.len); - return result; -} - - -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_StrCmp(Slice const a, Slice const b)) -{ - b32 result = Dqn_StrCmp(a.str, a.len, b.str, b.len); - return result; -} - -DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_StrMultiFind(char const *buf, char const *find_list[], isize const *find_string_lens, isize find_len, isize *match_index, isize buf_len = -1)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_FindMulti(char const *buf, char const *find_list[], Dqn_isize const *find_string_lens, Dqn_isize find_len, Dqn_isize *match_index, Dqn_isize buf_len = -1)) { char const *result = nullptr; if (find_len == 0) return result; - if (buf_len < 0) buf_len = (isize)strlen(buf); + if (buf_len < 0) buf_len = (Dqn_isize)strlen(buf); char const *buf_end = buf + buf_len; for (; *buf; ++buf) { - isize remaining = static_cast(buf_end - buf); + Dqn_isize remaining = static_cast(buf_end - buf); DQN_FOR_EACH(find_index, find_len) { char const *find = find_list[find_index]; - isize find_str_len = find_string_lens[find_index]; + Dqn_isize find_str_len = find_string_lens[find_index]; if (remaining < find_str_len) continue; if (strncmp(buf, find, find_str_len) == 0) @@ -1851,17 +1876,17 @@ DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_StrMultiFind(char const *buf, char c return result; } -DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_StrFind(char const *buf, char const *find, isize buf_len = -1, isize find_len = -1)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_Find(char const *buf, char const *find, Dqn_isize buf_len = -1, Dqn_isize find_len = -1)) { if (find_len == 0) return nullptr; - if (buf_len < 0) buf_len = (isize)strlen(buf); - if (find_len < 0) find_len = (isize)strlen(find); + if (buf_len < 0) buf_len = (Dqn_isize)strlen(buf); + if (find_len < 0) find_len = (Dqn_isize)strlen(find); char const *buf_end = buf + buf_len; char const *result = nullptr; for (; *buf; ++buf) { - isize remaining = static_cast(buf_end - buf); + Dqn_isize remaining = static_cast(buf_end - buf); if (remaining < find_len) break; if (strncmp(buf, find, find_len) == 0) @@ -1873,14 +1898,14 @@ DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_StrFind(char const *buf, char const return result; } -DQN_HEADER_COPY_PROTOTYPE(b32, Dqn_StrMatch(char const *src, char const *find, int find_len)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_b32, Dqn_Str_Match(char const *src, char const *find, int find_len)) { - if (find_len == -1) find_len = Dqn_SafeTruncateUSizeToInt(strlen(find)); - b32 result = (strncmp(src, find, find_len) == 0); + if (find_len == -1) find_len = Dqn_Safe_TruncateUSizeToInt(strlen(find)); + Dqn_b32 result = (strncmp(src, find, find_len) == 0); return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToChar(char const *src, char ch)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToChar(char const *src, char ch)) { char const *result = src; while (result && result[0] && result[0] != ch) ++result; @@ -1888,99 +1913,99 @@ DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToChar(char const *src, char c } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextAlphaNum(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextAlphaNum(char const *src)) { char const *result = src; - while (result && result[0] && !Dqn_CharIsAlphaNum(result[0])) ++result; + while (result && result[0] && !Dqn_Char_IsAlphaNum(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextDigit(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextDigit(char const *src)) { char const *result = src; - while (result && result[0] && !Dqn_CharIsDigit(result[0])) ++result; + while (result && result[0] && !Dqn_Char_IsDigit(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextChar(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextChar(char const *src)) { char const *result = src; - while (result && result[0] && !Dqn_CharIsAlpha(result[0])) ++result; + while (result && result[0] && !Dqn_Char_IsAlpha(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextWord(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextWord(char const *src)) { char const *result = src; - while (result && result[0] && !Dqn_CharIsWhitespace(result[0])) ++result; - while (result && result[0] && Dqn_CharIsWhitespace(result[0])) ++result; + while (result && result[0] && !Dqn_Char_IsWhitespace(result[0])) ++result; + while (result && result[0] && Dqn_Char_IsWhitespace(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextWhitespace(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextWhitespace(char const *src)) { char const *result = src; - while (result && result[0] && !Dqn_CharIsWhitespace(result[0])) ++result; + while (result && result[0] && !Dqn_Char_IsWhitespace(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipWhitespace(char const *src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipWhitespace(char const *src)) { char const *result = src; - while (result && result[0] && Dqn_CharIsWhitespace(result[0])) ++result; + while (result && result[0] && Dqn_Char_IsWhitespace(result[0])) ++result; return result; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToCharInPlace(char const **src, char ch)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToCharInPlace(char const **src, char ch)) { - *src = Dqn_StrSkipToChar(*src, ch); + *src = Dqn_Str_SkipToChar(*src, ch); return *src; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextAlphaNumInPlace(char const **src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextAlphaNumInPlace(char const **src)) { - *src = Dqn_StrSkipToNextAlphaNum(*src); + *src = Dqn_Str_SkipToNextAlphaNum(*src); return *src; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextCharInPlace(char const **src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextCharInPlace(char const **src)) { - *src = Dqn_StrSkipToNextChar(*src); + *src = Dqn_Str_SkipToNextChar(*src); return *src; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextWhitespaceInPlace(char const **src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextWhitespaceInPlace(char const **src)) { - *src = Dqn_StrSkipToNextWhitespace(*src); + *src = Dqn_Str_SkipToNextWhitespace(*src); return *src; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipToNextWordInPlace(char const **src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipToNextWordInPlace(char const **src)) { - *src = Dqn_StrSkipToNextWord(*src); + *src = Dqn_Str_SkipToNextWord(*src); return *src; } -DQN_HEADER_COPY_PROTOTYPE(char, const *Dqn_StrSkipWhitespaceInPlace(char const **src)) +DQN_HEADER_COPY_PROTOTYPE(char const *, Dqn_Str_SkipWhitespaceInPlace(char const **src)) { - *src = Dqn_StrSkipWhitespace(*src); + *src = Dqn_Str_SkipWhitespace(*src); return *src; } -DQN_HEADER_COPY_PROTOTYPE(u64, Dqn_StrToU64(char const *buf, int len = -1)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_u64, Dqn_Str_ToU64(char const *buf, int len = -1)) { - u64 result = 0; + Dqn_u64 result = 0; if (!buf) return result; - if (len == -1) len = Dqn_SafeTruncateUSizeToInt(strlen(buf)); + if (len == -1) len = Dqn_Safe_TruncateUSizeToInt(strlen(buf)); if (len == 0) return result; - char const *buf_ptr = Dqn_StrSkipWhitespace(buf); + char const *buf_ptr = Dqn_Str_SkipWhitespace(buf); len -= static_cast(buf_ptr - buf); for (int buf_index = 0; buf_index < len; ++buf_index) { @@ -1988,26 +2013,26 @@ DQN_HEADER_COPY_PROTOTYPE(u64, Dqn_StrToU64(char const *buf, int len = -1)) if (ch == ',') continue; if (ch < '0' || ch > '9') break; - u64 val = ch - '0'; - result = Dqn_SafeAddU64(result, val); - result = Dqn_SafeMulU64(result, 10); + Dqn_u64 val = ch - '0'; + result = Dqn_Safe_AddU64(result, val); + result = Dqn_Safe_MulU64(result, 10); } result /= 10; return result; } -DQN_HEADER_COPY_PROTOTYPE(i64, Dqn_StrToI64(char const *buf, int len = -1)) +DQN_HEADER_COPY_PROTOTYPE(Dqn_i64, Dqn_Str_ToI64(char const *buf, int len = -1)) { - i64 result = 0; + Dqn_i64 result = 0; if (!buf) return result; - if (len == -1) len = Dqn_SafeTruncateUSizeToInt(strlen(buf)); + if (len == -1) len = Dqn_Safe_TruncateUSizeToInt(strlen(buf)); if (len == 0) return result; - char const *buf_ptr = Dqn_StrSkipWhitespace(buf); + char const *buf_ptr = Dqn_Str_SkipWhitespace(buf); len -= static_cast(buf_ptr - buf); - b32 negative = (buf[0] == '-'); + Dqn_b32 negative = (buf[0] == '-'); if (negative) { ++buf_ptr; @@ -2020,9 +2045,9 @@ DQN_HEADER_COPY_PROTOTYPE(i64, Dqn_StrToI64(char const *buf, int len = -1)) if (ch == ',') continue; if (ch < '0' || ch > '9') break; - i64 val = ch - '0'; - result = Dqn_SafeAddI64(result, val); - result = Dqn_SafeMulI64(result, 10); + Dqn_i64 val = ch - '0'; + result = Dqn_Safe_AddI64(result, val); + result = Dqn_Safe_MulI64(result, 10); } result /= 10; @@ -2030,14 +2055,19 @@ DQN_HEADER_COPY_PROTOTYPE(i64, Dqn_StrToI64(char const *buf, int len = -1)) return result; } -DQN_HEADER_COPY_PROTOTYPE(char *, Dqn_FileReadWithArena(Dqn_MemArena *arena, char const *file, isize *file_size)) +// @ ------------------------------------------------------------------------------------------------- +// @ +// @ NOTE: File +// @ +// @ ------------------------------------------------------------------------------------------------- +DQN_HEADER_COPY_PROTOTYPE(char *, Dqn_File_ReadWithArena(Dqn_MemArena *arena, char const *file, Dqn_isize *file_size)) { FILE *file_handle = fopen(file, "rb"); fseek(file_handle, 0, SEEK_END); - usize file_size_ = ftell(file_handle); + Dqn_usize file_size_ = ftell(file_handle); rewind(file_handle); - auto *result = (char *)MEM_ARENA_ALLOC(arena, file_size_ + 1); + auto *result = (char *)DQN_MEM_ARENA_ALLOC(arena, file_size_ + 1); DQN_ASSERT(result); result[file_size_] = 0; @@ -2053,7 +2083,6 @@ DQN_HEADER_COPY_PROTOTYPE(char *, Dqn_FileReadWithArena(Dqn_MemArena *arena, cha #endif // DQN_IMPLEMENTATION #ifdef STB_SPRINTF_IMPLEMENTATION - #include // for va_arg() #define stbsp__uint32 unsigned int diff --git a/Code/DqnHeader.h b/Code/DqnHeader.h index 89ec903..0346571 100644 --- a/Code/DqnHeader.h +++ b/Code/DqnHeader.h @@ -1,8 +1,51 @@ #ifndef DQN_HEADER_H #define DQN_HEADER_H + +// NOTE: Copy the function prototype, all functions will be whitespaced aligned to the longest return type of the file +// NOTE: If you function contains a comma NOT in the argument list (i.e. multiple template parameters), this macro does NOT work. +// Please use the DQN_HEADER_COPY_BEGIN and DQN_HEADER_COPY_END unfortunately. #define DQN_HEADER_COPY_PROTOTYPE(func_return, func_name_and_types) func_return func_name_and_types + +// NOTE: Copy all contents from the file between the begin and end macro #define DQN_HEADER_COPY_BEGIN #define DQN_HEADER_COPY_END + +// NOTE: Copy comments by writing comments with the prefix, "// @" +// @ Hello this comment will be copied to the output + +// NOTE: Example Input +#if 0 + #include "DqnHeader.h" + + // @ ptr1: Pointer to the first block of memory + // @ ptr2: Pointer to the second block of memory + // @ num_bytes: The number of bytes to compare in both blocks of memory + DQN_HEADER_COPY_PROTOTYPE(int, Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes)) + { + int result = memcmp(ptr1, ptr2, num_bytes); + return result; + } + + DQN_HEADER_COPY_BEGIN + struct HelloWorld + { + int foo, bar; + }; + DQN_HEADER_COPY_END +#endif + +// NOTE: Example Output +#if 0 + // @ ptr1: Pointer to the first block of memory + // @ ptr2: Pointer to the second block of memory + // @ num_bytes: The number of bytes to compare in both blocks of memory + int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes); + struct HelloWorld + { + int foo, bar; + }; +#endif + #endif /* DQN_HEADER_H */ #ifdef DQN_HEADER_IMPLEMENTATION @@ -10,12 +53,13 @@ #define _CRT_SECURE_NO_WARNINGS // NOTE: Undefined at end of file #include +#define DQN_USE_PRIMITIVE_TYPEDEFS #define DQN_IMPLEMENTATION #include "Dqn.h" -char const *Dqn_Header__ParseFunctionReturnType(char const *ptr, isize *len) +char const *ParseFunctionReturnType(char const *ptr, isize *len) { - char const *result = Dqn_StrSkipWhitespace(ptr); + char const *result = Dqn_Str_SkipWhitespace(ptr); isize result_len = 0; for (int scope = 0; ptr; ptr++) // NOTE: Parse the function return type { @@ -37,7 +81,7 @@ char const *Dqn_Header__ParseFunctionReturnType(char const *ptr, isize *len) return result; } -char const *Dqn_Header__ParseFunctionNameAndParameters(char const *ptr, isize *len) +char const *ParseFunctionNameAndParameters(char const *ptr, isize *len) { char const *result = ptr; int result_len = 0; @@ -56,7 +100,7 @@ char const *Dqn_Header__ParseFunctionNameAndParameters(char const *ptr, isize *l return result; } -char const *Dqn_Header__ParseFunctionComment(char const *ptr, isize *len) +char const *ParseFunctionComment(char const *ptr, isize *len) { while (ptr[0] != '"') ptr++; ptr++; @@ -80,11 +124,35 @@ char const *Dqn_Header__ParseFunctionComment(char const *ptr, isize *len) } +enum struct HeaderEntryType +{ + Prototype, + Comment, + CopyBegin, + Count +}; + +struct HeaderEntry +{ + HeaderEntryType type; + union + { + struct + { + Dqn_Slice return_val; + Dqn_Slice name_and_args; + } function_decl; + + Dqn_Slice comment; + Dqn_Slice copy_range; + }; +}; + int main(int argc, char *argv[]) { if (argc < 1) { - fprintf(stdout, "DqnHeader Usage: %s [, ...]\n", argv[0]); + fprintf(stdout, "Header Usage: %s [, ...]\n", argv[0]); return 0; } @@ -93,7 +161,7 @@ int main(int argc, char *argv[]) { char const *file = argv[arg_index]; isize buf_size = 0; - char *buf = Dqn_FileReadWithArena(&arena, file, &buf_size); + char *buf = Dqn_File_ReadWithArena(&arena, file, &buf_size); if (!buf) { fprintf(stderr, "Failed to read file: %s\n", file); @@ -105,14 +173,6 @@ int main(int argc, char *argv[]) char constexpr HEADER_COPY_BEGIN[] = "DQN_HEADER_COPY_BEGIN"; char constexpr HEADER_COPY_END[] = "DQN_HEADER_COPY_END"; - enum struct FindString - { - HeaderPrototype, - HeaderComment, - HeaderCopyBegin, - Count - }; - char const *find_list[] = {HEADER_COPY_PROTOTYPE, HEADER_COMMENT, HEADER_COPY_BEGIN}; isize constexpr find_string_lens[] = { Dqn_CharCountI(HEADER_COPY_PROTOTYPE), @@ -120,68 +180,130 @@ int main(int argc, char *argv[]) Dqn_CharCountI(HEADER_COPY_BEGIN), }; + isize num_header_entries = 0; + { + char const *ptr = buf; + char const *ptr_end = buf + buf_size; + isize ptr_len = buf_size; + isize matched_find_index = -1; + for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len); + token; + token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len)) + { + ptr = token + find_string_lens[matched_find_index]; + num_header_entries++; + ptr_len = ptr_end - ptr; + } + } + + HeaderEntry *header_entries = DQN_MEM_ARENA_ALLOC_ARRAY(&arena, HeaderEntry, num_header_entries); + isize header_entries_index = 0; + isize max_prototype_return_val = 0; + char const *ptr = buf; char const *ptr_end = buf + buf_size; isize ptr_len = buf_size; isize matched_find_index = -1; - for (char const *token = Dqn_StrMultiFind(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len); + for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len); token; - token = Dqn_StrMultiFind(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len)) + token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len)) { - if (matched_find_index == (isize)FindString::HeaderPrototype) + HeaderEntry *entry = header_entries + header_entries_index++; + entry->type = static_cast(matched_find_index); + if (matched_find_index == (isize)HeaderEntryType::Prototype) { ptr = token + find_string_lens[matched_find_index] + 1 /*macro start parenthesis*/; isize func_type_len = 0; - char const *func_type = Dqn_Header__ParseFunctionReturnType(ptr, &func_type_len); + char const *func_type = ParseFunctionReturnType(ptr, &func_type_len); ptr = func_type + func_type_len + 1; // Ptr is at macro comma, skip the comma - ptr = Dqn_StrSkipWhitespace(ptr); + ptr = Dqn_Str_SkipWhitespace(ptr); isize func_name_len = 0; - char const *func_name = Dqn_Header__ParseFunctionNameAndParameters(ptr, &func_name_len); + char const *func_name = ParseFunctionNameAndParameters(ptr, &func_name_len); + entry->function_decl.return_val = Dqn_AsprintfSlice(&arena, "%.*s", func_type_len, func_type); + entry->function_decl.name_and_args = Dqn_AsprintfSlice(&arena, "%.*s", func_name_len, func_name); ptr = func_name + func_name_len + 1; // Ptr is at macro closing paren, skip the paren - fprintf(stdout, "%.*s %.*s;\n", (int)func_type_len, func_type, (int)func_name_len, func_name); + + max_prototype_return_val = DQN_MAX(max_prototype_return_val, func_type_len); } - else if (matched_find_index == (isize)FindString::HeaderComment) + else if (matched_find_index == (isize)HeaderEntryType::Comment) { char const *comment_start = token; ptr = token; while (ptr[0] != '\n' && ptr[0] != '\r') ptr++; - isize comment_len = ptr - comment_start; - fprintf(stdout, "%.*s\n", (int)comment_len, comment_start); + + entry->comment.buf = DQN_MEM_ARENA_ALLOC_ARRAY(&arena, char, comment_len); + DQN_FOR_EACH(comment_index, comment_len) + { + // NOTE: We capture "// @", and we want to skip the @ symbol, its ugly which is at the index 3 + // Also if a space is given after the '@' symbol then skip that too. + char ch = comment_start[comment_index]; + if (comment_index == 3 && ch == '@') continue; + if (comment_index == 4 && ch == ' ') continue; + entry->comment.buf[entry->comment.len++] = ch; + } + + while (entry->comment.len > 0 && Dqn_Char_IsWhitespace(entry->comment.buf[entry->comment.len - 1])) + entry->comment.len--; ptr = comment_start + comment_len; } - else if (matched_find_index == (isize)FindString::HeaderCopyBegin) + else if (matched_find_index == (isize)HeaderEntryType::CopyBegin) { ptr = token + find_string_lens[matched_find_index]; - ptr = Dqn_StrSkipWhitespace(ptr); + ptr = Dqn_Str_SkipWhitespace(ptr); char const *copy_start = ptr; - char const *copy_end = Dqn_StrFind(ptr, HEADER_COPY_END, ptr_len, Dqn_CharCountI(HEADER_COPY_END)); + char const *copy_end = Dqn_Str_Find(ptr, HEADER_COPY_END, ptr_len, Dqn_CharCountI(HEADER_COPY_END)); if (!copy_end) { fprintf(stderr, "Header copy begin macro: %s not matched with a copy end macro: %s", HEADER_COPY_BEGIN, HEADER_COPY_END); return -1; } - isize copy_len = copy_end - copy_start; - auto mem_scope = Dqn_MemArenaScopedRegion(&arena); - char *sanitised_copy = (char *)MEM_ARENA_ALLOC(&arena, copy_len); - isize sanitised_len = 0; + isize copy_len = copy_end - copy_start; + entry->copy_range.buf = (char *)DQN_MEM_ARENA_ALLOC(&arena, copy_len); DQN_FOR_EACH(copy_index, copy_len) { char ch = copy_start[copy_index]; if (ch == '\r') continue; - sanitised_copy[sanitised_len++] = ch; + entry->copy_range.buf[entry->copy_range.len++] = ch; } - ptr = copy_end; - fprintf(stdout, "%.*s\n", (int)sanitised_len, sanitised_copy); } ptr_len = ptr_end - ptr; } + DQN_ASSERT(header_entries_index == num_header_entries); + + DQN_FOR_EACH(entry_index, header_entries_index) + { + HeaderEntry const *entry = header_entries + entry_index; + switch(entry->type) + { + case HeaderEntryType::Prototype: + { + isize remaining_space = max_prototype_return_val - entry->function_decl.return_val.len + 1; + fprintf(stdout, "%.*s", (int)entry->function_decl.return_val.len, entry->function_decl.return_val.str); + DQN_FOR_EACH(space, remaining_space) fputs(" ", stdout); + fprintf(stdout, " %.*s;\n", (int)entry->function_decl.name_and_args.len, entry->function_decl.name_and_args.str); + } + break; + + case HeaderEntryType::Comment: + { + fprintf(stdout, "%.*s\n", (int)entry->comment.len, entry->comment.buf); + } + break; + + case HeaderEntryType::CopyBegin: + { + fprintf(stdout, "%.*s\n", (int)entry->copy_range.len, entry->copy_range.buf); + } + break; + } + } } } diff --git a/Code/DqnHeader_Generated.h b/Code/DqnHeader_Generated.h new file mode 100644 index 0000000..55742d8 --- /dev/null +++ b/Code/DqnHeader_Generated.h @@ -0,0 +1,556 @@ +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Typedefs, Macros, Utils +// +// ------------------------------------------------------------------------------------------------- +constexpr Dqn_usize Dqn_ArrayCount(T const (&)[N]); +constexpr Dqn_isize Dqn_ArrayCountI(T const (&)[N]); +constexpr Dqn_usize Dqn_CharCount(char const (&)[N]); +constexpr Dqn_isize Dqn_CharCountI(char const (&)[N]); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Logging +// +// ------------------------------------------------------------------------------------------------- +constexpr inline char const * Dqn_LogTypeTag(Dqn_LogType type); +// NOTE: Set the callback to get called whenever a log message has been printed +#define DQN_LOG_CALLBACK(name) void name(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *log_str) +typedef DQN_LOG_CALLBACK(Dqn_LogCallback); +Dqn_LogCallback *Dqn_log_callback; + +#define DQN_LOG_E(fmt, ...) Dqn_Log(Dqn_LogType::Error, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) +#define DQN_LOG_D(fmt, ...) Dqn_Log(Dqn_LogType::Debug, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) +#define DQN_LOG_W(fmt, ...) Dqn_Log(Dqn_LogType::Warning, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) +#define DQN_LOG_I(fmt, ...) Dqn_Log(Dqn_LogType::Info, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) +#define DQN_LOG_M(fmt, ...) Dqn_Log(Dqn_LogType::Info, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) +#define DQN_LOG(log_type, fmt, ...) Dqn_Log(log_type, DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__, fmt, ## __VA_ARGS__) + +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Math +// +// ------------------------------------------------------------------------------------------------- +union Dqn_V2I +{ + struct { Dqn_i32 x, y; }; + struct { Dqn_i32 w, h; }; + struct { Dqn_i32 min, max; }; + Dqn_i32 e[2]; + + constexpr Dqn_V2I() = default; + constexpr Dqn_V2I(Dqn_f32 x_, Dqn_f32 y_): x((Dqn_i32)x_), y((Dqn_i32)y_) {} + constexpr Dqn_V2I(Dqn_i32 x_, Dqn_i32 y_): x(x_), y(y_) {} + constexpr Dqn_V2I(Dqn_i32 xy): x(xy), y(xy) {} + + constexpr bool operator!=(Dqn_V2I other) const { return !(*this == other); } + constexpr bool operator==(Dqn_V2I other) const { return (x == other.x) && (y == other.y); } + constexpr bool operator>=(Dqn_V2I other) const { return (x >= other.x) && (y >= other.y); } + constexpr bool operator<=(Dqn_V2I other) const { return (x <= other.x) && (y <= other.y); } + constexpr bool operator< (Dqn_V2I other) const { return (x < other.x) && (y < other.y); } + constexpr bool operator> (Dqn_V2I other) const { return (x > other.x) && (y > other.y); } + constexpr Dqn_V2I operator- (Dqn_V2I other) const { Dqn_V2I result(x - other.x, y - other.y); return result; } + constexpr Dqn_V2I operator+ (Dqn_V2I other) const { Dqn_V2I result(x + other.x, y + other.y); return result; } + constexpr Dqn_V2I operator* (Dqn_V2I other) const { Dqn_V2I result(x * other.x, y * other.y); return result; } + constexpr Dqn_V2I operator* (Dqn_f32 other) const { Dqn_V2I result(x * other, y * other); return result; } + constexpr Dqn_V2I operator* (Dqn_i32 other) const { Dqn_V2I result(x * other, y * other); return result; } + constexpr Dqn_V2I operator/ (Dqn_V2I other) const { Dqn_V2I result(x / other.x, y / other.y); return result; } + constexpr Dqn_V2I operator/ (Dqn_f32 other) const { Dqn_V2I result(x / other, y / other); return result; } + constexpr Dqn_V2I operator/ (Dqn_i32 other) const { Dqn_V2I result(x / other, y / other); return result; } + constexpr Dqn_V2I &operator*=(Dqn_V2I other) { *this = *this * other; return *this; } + constexpr Dqn_V2I &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2I &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2I &operator-=(Dqn_V2I other) { *this = *this - other; return *this; } + constexpr Dqn_V2I &operator+=(Dqn_V2I other) { *this = *this + other; return *this; } +}; + +union Dqn_V2 +{ + struct { Dqn_f32 x, y; }; + struct { Dqn_f32 w, h; }; + struct { Dqn_f32 min, max; }; + Dqn_f32 e[2]; + + constexpr Dqn_V2() = default; + constexpr Dqn_V2(Dqn_f32 a) : x(a), y(a) {} + constexpr Dqn_V2(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a) {} + constexpr Dqn_V2(Dqn_f32 x_, Dqn_f32 y_): x(x_), y(y_) {} + constexpr Dqn_V2(Dqn_i32 x_, Dqn_i32 y_): x((Dqn_f32)x_), y((Dqn_f32)y_) {} + constexpr Dqn_V2(Dqn_V2I a) : x((Dqn_f32)a.x), y((Dqn_f32)a.y) {} + + constexpr bool operator!=(Dqn_V2 other) const { return !(*this == other); } + constexpr bool operator==(Dqn_V2 other) const { return (x == other.x) && (y == other.y); } + constexpr bool operator>=(Dqn_V2 other) const { return (x >= other.x) && (y >= other.y); } + constexpr bool operator<=(Dqn_V2 other) const { return (x <= other.x) && (y <= other.y); } + constexpr bool operator< (Dqn_V2 other) const { return (x < other.x) && (y < other.y); } + constexpr bool operator> (Dqn_V2 other) const { return (x > other.x) && (y > other.y); } + constexpr Dqn_V2 operator- (Dqn_V2 other) const { Dqn_V2 result(x - other.x, y - other.y); return result; } + constexpr Dqn_V2 operator+ (Dqn_V2 other) const { Dqn_V2 result(x + other.x, y + other.y); return result; } + constexpr Dqn_V2 operator* (Dqn_V2 other) const { Dqn_V2 result(x * other.x, y * other.y); return result; } + constexpr Dqn_V2 operator* (Dqn_f32 other) const { Dqn_V2 result(x * other, y * other); return result; } + constexpr Dqn_V2 operator* (Dqn_i32 other) const { Dqn_V2 result(x * other, y * other); return result; } + constexpr Dqn_V2 operator/ (Dqn_V2 other) const { Dqn_V2 result(x / other.x, y / other.y); return result; } + constexpr Dqn_V2 operator/ (Dqn_f32 other) const { Dqn_V2 result(x / other, y / other); return result; } + constexpr Dqn_V2 operator/ (Dqn_i32 other) const { Dqn_V2 result(x / other, y / other); return result; } + constexpr Dqn_V2 &operator*=(Dqn_V2 other) { *this = *this * other; return *this; } + constexpr Dqn_V2 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V2 &operator/=(Dqn_V2 other) { *this = *this / other; return *this; } + constexpr Dqn_V2 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } + constexpr Dqn_V2 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } + constexpr Dqn_V2 &operator-=(Dqn_V2 other) { *this = *this - other; return *this; } + constexpr Dqn_V2 &operator+=(Dqn_V2 other) { *this = *this + other; return *this; } +}; + +union Dqn_V3 +{ + struct { Dqn_f32 x, y, z; }; + struct { Dqn_f32 r, g, b; }; + Dqn_V2 xy; + Dqn_f32 e[3]; + + constexpr Dqn_V3() = default; + constexpr Dqn_V3(Dqn_f32 a) : x(a), y(a), z(a) {} + constexpr Dqn_V3(Dqn_i32 a) : x((Dqn_f32)a), y((Dqn_f32)a), z((Dqn_f32)a) {} + constexpr Dqn_V3(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_): x(x_), y(y_), z(z_) {} + constexpr Dqn_V3(Dqn_i32 x_, Dqn_i32 y_, Dqn_f32 z_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_) {} + constexpr Dqn_V3(Dqn_V2 xy, Dqn_f32 z_) : x(xy.x), y(xy.y), z(z_) {} + + constexpr bool operator!= (Dqn_V3 other) const { return !(*this == other); } + constexpr bool operator== (Dqn_V3 other) const { return (x == other.x) && (y == other.y) && (z == other.z); } + constexpr bool operator>= (Dqn_V3 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z); } + constexpr bool operator<= (Dqn_V3 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z); } + constexpr bool operator< (Dqn_V3 other) const { return (x < other.x) && (y < other.y) && (z < other.z); } + constexpr bool operator> (Dqn_V3 other) const { return (x > other.x) && (y > other.y) && (z > other.z); } + constexpr Dqn_V3 operator- (Dqn_V3 other) const { Dqn_V3 result(x - other.x, y - other.y, z - other.z); return result; } + constexpr Dqn_V3 operator+ (Dqn_V3 other) const { Dqn_V3 result(x + other.x, y + other.y, z + other.z); return result; } + constexpr Dqn_V3 operator* (Dqn_V3 other) const { Dqn_V3 result(x * other.x, y * other.y, z * other.z); return result; } + constexpr Dqn_V3 operator* (Dqn_f32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } + constexpr Dqn_V3 operator* (Dqn_i32 other) const { Dqn_V3 result(x * other, y * other, z * other); return result; } + constexpr Dqn_V3 operator/ (Dqn_V3 other) const { Dqn_V3 result(x / other.x, y / other.y, z / other.z); return result; } + constexpr Dqn_V3 operator/ (Dqn_f32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } + constexpr Dqn_V3 operator/ (Dqn_i32 other) const { Dqn_V3 result(x / other, y / other, z / other); return result; } + constexpr Dqn_V3 &operator*=(Dqn_V3 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_V3 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_f32 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator/=(Dqn_i32 other) { *this = *this / other; return *this; } + constexpr Dqn_V3 &operator-=(Dqn_V3 other) { *this = *this - other; return *this; } + constexpr Dqn_V3 &operator+=(Dqn_V3 other) { *this = *this + other; return *this; } +}; + +union Dqn_V4 +{ + struct { Dqn_f32 x, y, z, w; }; + struct { Dqn_f32 r, g, b, a; }; + Dqn_V3 rgb; + Dqn_f32 e[4]; + + constexpr Dqn_V4() = default; + constexpr Dqn_V4(Dqn_f32 xyzw) : x(xyzw), y(xyzw), z(xyzw), w(xyzw) {} + constexpr Dqn_V4(Dqn_f32 x_, Dqn_f32 y_, Dqn_f32 z_, Dqn_f32 w_): x(x_), y(y_), z(z_), w(w_) {} + constexpr Dqn_V4(Dqn_i32 x_, Dqn_i32 y_, Dqn_i32 z_, Dqn_i32 w_): x((Dqn_f32)x_), y((Dqn_f32)y_), z((Dqn_f32)z_), w((Dqn_f32)w_) {} + constexpr Dqn_V4(Dqn_V3 xyz, Dqn_f32 w_) : x(xyz.x), y(xyz.y), z(xyz.z), w(w_) {} + + constexpr bool operator!=(Dqn_V4 other) const { return !(*this == other); } + constexpr bool operator==(Dqn_V4 other) const { return (x == other.x) && (y == other.y) && (z == other.z) && (w == other.w); } + constexpr bool operator>=(Dqn_V4 other) const { return (x >= other.x) && (y >= other.y) && (z >= other.z) && (w >= other.w); } + constexpr bool operator<=(Dqn_V4 other) const { return (x <= other.x) && (y <= other.y) && (z <= other.z) && (w <= other.w); } + constexpr bool operator< (Dqn_V4 other) const { return (x < other.x) && (y < other.y) && (z < other.z) && (w < other.w); } + constexpr bool operator> (Dqn_V4 other) const { return (x > other.x) && (y > other.y) && (z > other.z) && (w > other.w); } + constexpr Dqn_V4 operator- (Dqn_V4 other) const { Dqn_V4 result(x - other.x, y - other.y, z - other.z, w - other.w); return result; } + constexpr Dqn_V4 operator+ (Dqn_V4 other) const { Dqn_V4 result(x + other.x, y + other.y, z + other.z, w + other.w); return result; } + constexpr Dqn_V4 operator* (Dqn_V4 other) const { Dqn_V4 result(x * other.x, y * other.y, z * other.z, w * other.w); return result; } + constexpr Dqn_V4 operator* (Dqn_f32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } + constexpr Dqn_V4 operator* (Dqn_i32 other) const { Dqn_V4 result(x * other, y * other, z * other, w * other); return result; } + constexpr Dqn_V4 operator/ (Dqn_f32 other) const { Dqn_V4 result(x / other, y / other, z / other, w / other); return result; } + constexpr Dqn_V4 &operator*=(Dqn_V4 other) { *this = *this * other; return *this; } + constexpr Dqn_V4 &operator*=(Dqn_f32 other) { *this = *this * other; return *this; } + constexpr Dqn_V4 &operator*=(Dqn_i32 other) { *this = *this * other; return *this; } + constexpr Dqn_V4 &operator-=(Dqn_V4 other) { *this = *this - other; return *this; } + constexpr Dqn_V4 &operator+=(Dqn_V4 other) { *this = *this + other; return *this; } +}; + +struct Dqn_Rect +{ + Dqn_V2 min, max; + Dqn_Rect() = default; + Dqn_Rect(Dqn_V2 min, Dqn_V2 max) : min(min), max(max) {} + Dqn_Rect(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {} +}; + +struct Dqn_RectI32 +{ + Dqn_V2I min, max; + Dqn_RectI32() = default; + Dqn_RectI32(Dqn_V2I min, Dqn_V2I max) : min(min), max(max) {} +}; + +union Dqn_Mat4 +{ + Dqn_f32 e[16]; + Dqn_V4 row[4]; + Dqn_f32 row_major[4][4]; + Dqn_f32 operator[](Dqn_usize i) const { return e[i]; } +}; + +template int Dqn_MemCmpType(T const *ptr1, T const *ptr2); +template T * Dqn_MemZero(T *src); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_MemArena +// +// ------------------------------------------------------------------------------------------------- +using Dqn_MemSize = Dqn_usize; +struct Dqn_MemBlock +{ + // NOTE: Read only state + Dqn_b32 allocated_by_user_or_fixed_mem; + void *memory; + Dqn_MemSize size; + Dqn_MemSize used; + Dqn_MemBlock *prev; + Dqn_MemBlock *next; +}; + +enum Dqn_MemArenaFlag +{ + Dqn_MemArenaFlag_NoCRTAllocation = (1 << 0), // If my_calloc/my_free aren't null, it defaults to calloc and free, setting this flag disables that +}; + +typedef void *(Dqn_MemArenaCallocFunction)(size_t bytes); +typedef void (Dqn_MemArenaFreeFunction) (void *ptr, size_t bytes_to_free); +struct Dqn_MemArena +{ + // NOTE: Configuration (fill once) + Dqn_MemArenaCallocFunction *my_calloc; // If nullptr, use CRT calloc unless disabled in flags + Dqn_MemArenaFreeFunction *my_free; // If nullptr, use CRT free unless disabled in flags + Dqn_u32 flags; + + // NOTE: Read Only + Dqn_u8 fixed_mem[DQN_KILOBYTES(16)]; + Dqn_MemBlock fixed_mem_block; + Dqn_MemBlock *curr_mem_block; + Dqn_MemBlock *top_mem_block; + Dqn_MemSize highest_used_mark; + int total_allocated_mem_blocks; +}; + +struct Dqn_MemArenaScopedRegion +{ + Dqn_MemArenaScopedRegion(Dqn_MemArena *arena); + ~Dqn_MemArenaScopedRegion(); + Dqn_MemArena *arena; + Dqn_MemBlock *curr_mem_block; + Dqn_usize curr_mem_block_used; + Dqn_MemBlock *top_mem_block; +}; + +#if defined(DQN_DEBUG_DQN_MEM_ARENA_LOGGING) + #define DQN_DEBUG_ARGS , char const *file, Dqn_isize file_len, char const *func, Dqn_isize func_len, Dqn_isize line + #define DQN_DEBUG_PARAMS , DQN_STR_AND_LEN(__FILE__), DQN_STR_AND_LEN(__func__), __LINE__ +#else + #define DQN_DEBUG_ARGS + #define DQN_DEBUG_PARAMS +#endif + +#define DQN_MEM_ARENA_ALLOC(arena, size) Dqn_MemArena_Alloc(arena, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_ALLOC_ARRAY(arena, T, num) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) * num DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_ALLOC_STRUCT(arena, T) (T *)Dqn_MemArena_Alloc(arena, sizeof(T) DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_RESERVE(arena, size) Dqn_MemArena_Reserve(arena, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_RESERVE_FROM(arena, src, size) Dqn_MemArena_ReserveFrom(arena, src, size DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_CLEAR_USED(arena) Dqn_MemArena_ClearUsed(arena DQN_DEBUG_PARAMS); +#define DQN_MEM_ARENA_FREE(arena) Dqn_MemArena_Free + +// ----------------------------------------------------------------------------------------------- +// +// NOTE: String Builder +// +// ----------------------------------------------------------------------------------------------- +// The necessary length to build the string, it returns the length including the null-terminator +template Dqn_isize Dqn_StringBuilder_BuildLen(Dqn_StringBuilder const *builder); +template void Dqn_StringBuilder_BuildInBuffer(Dqn_StringBuilder const *builder, char *dest, Dqn_usize dest_size); +template char * Dqn_StringBuilder_BuildFromMalloc(Dqn_StringBuilder *builder, Dqn_isize *len = nullptr); +template char * Dqn_StringBuilder_BuildFromArena(Dqn_StringBuilder *builder, Dqn_MemArena *arena, Dqn_isize *len = nullptr); +template void Dqn_StringBuilder_VFmtAppend(Dqn_StringBuilder *builder, char const *fmt, va_list va); +template void Dqn_StringBuilder_FmtAppend(Dqn_StringBuilder *builder, char const *fmt, ...); +template void Dqn_StringBuilder_Append(Dqn_StringBuilder *builder, char const *str, Dqn_isize len = -1); +template void Dqn_StringBuilder_AppendChar(Dqn_StringBuilder *builder, char ch); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_Slices +// +// ------------------------------------------------------------------------------------------------- +template inline Dqn_Slice Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, T const *src, Dqn_isize len); +template inline Dqn_Slice Dqn_Slice_CopyNullTerminated(Dqn_MemArena *arena, Dqn_Slice const src); +template inline Dqn_Slice Dqn_Slice_Copy(Dqn_MemArena *arena, T const *src, Dqn_isize len); +template inline Dqn_Slice Dqn_Slice_Copy(Dqn_MemArena *arena, Dqn_Slice const src); +template inline bool Dqn_Slice_Equals(Dqn_Slice const a, Dqn_Slice const b); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_Asprintf (Allocate Sprintf) +// +// ------------------------------------------------------------------------------------------------- +template Dqn_Slice Dqn_AsprintfSlice(T *arena, char const *fmt, va_list va); +template Dqn_Slice Dqn_AsprintfSlice(T *arena, char const *fmt, ...); +template char * Dqn_Asprintf(T *arena, int *len, char const *fmt, ...); +template char * Dqn_Asprintf(T *arena, char const *fmt, ...); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_FixedArray +// +// ------------------------------------------------------------------------------------------------- +#define DQN_FIXED_ARRAY_TEMPLATE template +#define DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray +DQN_FIXED_ARRAY_TEMPLATE struct Dqn_FixedArray +{ + T data[MAX_]; + Dqn_isize len; + Dqn_isize Max() const { return MAX_; } + + T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T *begin () { return data; } + T *end () { return data + len; } + T *operator+ (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + + T const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T const *begin () const { return data; } + T const *end () const { return data + len; } + T const *operator+ (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } +}; + +DQN_FIXED_ARRAY_TEMPLATE_DECL Dqn_FixedArray_Init(T const *item, int num); +T * Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *items, Dqn_isize num); +T * Dqn_FixedArray_Add(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const item); +T * Dqn_FixedArray_Make(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num); +void Dqn_FixedArray_Clear(DQN_FIXED_ARRAY_TEMPLATE_DECL *a); +void Dqn_FixedArray_EraseStable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index); +void Dqn_FixedArray_EraseUnstable(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize index); +void Dqn_FixedArray_Pop(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, Dqn_isize num); +T * Dqn_FixedArray_Peek(DQN_FIXED_ARRAY_TEMPLATE_DECL *a); +Dqn_isize Dqn_FixedArray_GetIndex(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T const *entry); +T * Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, EqualityProc IsEqual); +T * Dqn_FixedArray_Find(DQN_FIXED_ARRAY_TEMPLATE_DECL *a, T *entry); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_FixedStack +// +// ------------------------------------------------------------------------------------------------- +template using Dqn_FixedStack = DQN_FIXED_ARRAY_TEMPLATE_DECL; +template T Dqn_FixedStack_Pop (Dqn_FixedStack *array) { T result = *Dqn_FixedArray_Peek(array); Dqn_FixedArray_Pop(array, 1); return result; } +template T *Dqn_FixedStack_Peek (Dqn_FixedStack *array) { return Dqn_FixedArray_Peek(array); } +template T *Dqn_FixedStack_Push (Dqn_FixedStack *array, T item) { return Dqn_FixedArray_Add(array, item); } +template void Dqn_FixedStack_Clear(Dqn_FixedStack *array) { Dqn_FixedArray_Clear(array); } + +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_StaticArray +// +// ------------------------------------------------------------------------------------------------- +template struct Dqn_StaticArray +{ + T *data; + Dqn_isize len; + Dqn_isize max; + T const operator[](Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T operator[](Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + T const *begin () const { return data; } + T const *end () const { return data + len; } + T *begin () { return data; } + T *end () { return data + len; } + T const *operator+(Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } + T *operator+(Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data + i; } +}; + +template Dqn_StaticArray Dqn_StaticArray_InitMemory (T *memory, Dqn_isize max, Dqn_isize len = 0); +template T * Dqn_StaticArray_Add (Dqn_StaticArray *a, T const *items, Dqn_isize num); +template T * Dqn_StaticArray_Add (Dqn_StaticArray *a, T const item); +template T * Dqn_StaticArray_Make (Dqn_StaticArray *a, Dqn_isize num); +template void Dqn_StaticArray_Clear (Dqn_StaticArray *a); +template void Dqn_StaticArray_EraseStable (Dqn_StaticArray *a, Dqn_isize index); +template void Dqn_StaticArray_EraseUnstable(Dqn_StaticArray *a, Dqn_isize index); +template void Dqn_StaticArray_Pop (Dqn_StaticArray *a, Dqn_isize num); +template T * Dqn_StaticArray_Peek (Dqn_StaticArray *a); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_FixedString +// +// ------------------------------------------------------------------------------------------------- +template +struct Dqn_FixedString +{ + union { char data[MAX_]; char str[MAX_]; char buf[MAX_]; }; + Dqn_isize len; + Dqn_isize Max() const { return MAX_; } + + Dqn_FixedString() { data[0] = 0; len = 0; } + Dqn_FixedString(char const *fmt, ...) + { + *this = {}; + va_list va; + va_start(va, fmt); + Dqn_FixedString_AppendVFmt(this, fmt, va); + va_end(va); + } + + char const &operator[] (Dqn_isize i) const { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + char &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i < len, "%d >= 0 && %d < %d", i, len); return data[i]; } + char const *begin () const { return data; } + char const *end () const { return data + len; } + char *begin () { return data; } + char *end () { return data + len; } +}; + +template void Dqn_FixedString_Clear(Dqn_FixedString *str); +template void Dqn_FixedString_AppendVFmt(Dqn_FixedString *str, char const *fmt, va_list va); +template void Dqn_FixedString_AppendFmt(Dqn_FixedString *str, char const *fmt, ...); +template void Dqn_FixedString_Append(Dqn_FixedString *str, char const *src, Dqn_isize len = -1); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_Dqn_U64Str +// +// ------------------------------------------------------------------------------------------------- +struct Dqn_U64Str +{ + // Points to the start of the str in the buffer, not necessarily buf since + // we write into the buffer in reverse + char *start; + char buf[27]; // NOTE(doyle): 27 is the maximum size of Dqn_u64 including commas + int len; +}; + +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Helpers +// +// ------------------------------------------------------------------------------------------------- +int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes); +void * Dqn_MemCopy(void *dest, void const *src, size_t num_bytes); +void * Dqn_MemMove(void *dest, void const *src, size_t num_bytes); +void * Dqn_MemSet(void *src, char ch, Dqn_usize num_bytes); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Logging +// +// ------------------------------------------------------------------------------------------------- +void Dqn_LogV(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, va_list va); +void Dqn_Log(Dqn_LogType type, char const *file, Dqn_usize file_len, char const *func, Dqn_usize func_len, Dqn_usize line, char const *fmt, ...); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_MemArena +// +// ------------------------------------------------------------------------------------------------- +void * Dqn_MemArena_Alloc(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); +void Dqn_MemArena_Free(Dqn_MemArena *arena DQN_DEBUG_ARGS); +Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size DQN_DEBUG_ARGS); +void Dqn_MemArena_ReserveFrom(Dqn_MemArena *arena, void *memory, Dqn_usize size DQN_DEBUG_ARGS); +void Dqn_MemArena_ClearUsed(Dqn_MemArena *arena DQN_DEBUG_ARGS); +Dqn_MemArenaScopedRegion Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Vectors +// +// ------------------------------------------------------------------------------------------------- +Dqn_V2I Dqn_V2_ToV2I(Dqn_V2 a); +Dqn_V2 Dqn_V2_Max(Dqn_V2 a, Dqn_V2 b); +Dqn_V2 Dqn_V2_Abs(Dqn_V2 a); +Dqn_f32 Dqn_V2_Dot(Dqn_V2 a, Dqn_V2 b); +Dqn_f32 Dqn_V2_LengthSq(Dqn_V2 a, Dqn_V2 b); +Dqn_V2 Dqn_V2_Normalise(Dqn_V2 a); +Dqn_V2 Dqn_V2_Perpendicular(Dqn_V2 a); +Dqn_f32 Dqn_V4_Dot(Dqn_V4 const *a, Dqn_V4 const *b); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Rect +// +// ------------------------------------------------------------------------------------------------- +Dqn_Rect Dqn_Rect_InitFromPosAndSize(Dqn_V2 pos, Dqn_V2 size); +Dqn_V2 Dqn_Rect_Center(Dqn_Rect rect); +Dqn_b32 Dqn_Rect_ContainsPoint(Dqn_Rect rect, Dqn_V2 p); +Dqn_b32 Dqn_Rect_ContainsRect(Dqn_Rect a, Dqn_Rect b); +Dqn_V2 Dqn_Rect_Size(Dqn_Rect rect); +Dqn_Rect Dqn_Rect_Move(Dqn_Rect src, Dqn_V2 move_amount); +Dqn_Rect Dqn_Rect_Union(Dqn_Rect a, Dqn_Rect b); +Dqn_Rect Dqn_Rect_FromRectI32(Dqn_RectI32 a); +Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Math Utils +// +// ------------------------------------------------------------------------------------------------- +Dqn_V2 Dqn_LerpV2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Dqn_Mat4 +// +// ------------------------------------------------------------------------------------------------- +Dqn_Mat4 Dqn_Mat4_Identity(); +Dqn_Mat4 Dqn_Mat4_Scale3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z); +Dqn_Mat4 Dqn_Mat4_ScaleV3(Dqn_V3 vec); +Dqn_Mat4 Dqn_Mat4_Translate3f(Dqn_f32 x, Dqn_f32 y, Dqn_f32 z); +Dqn_Mat4 Dqn_Mat4_TranslateV3(Dqn_V3 vec); +Dqn_Mat4 operator*(Dqn_Mat4 const &a, Dqn_Mat4 const &b); +Dqn_V4 operator*(Dqn_Mat4 const &mat, Dqn_V4 const &vec); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Helper Functions +// +// ------------------------------------------------------------------------------------------------- +void Dqn_Bit_UnsetInplace(Dqn_u32 *flags, Dqn_u32 bitfield); +void Dqn_Bit_SetInplace(Dqn_u32 *flags, Dqn_u32 bitfield); +Dqn_b32 Dqn_Bit_IsSet(Dqn_u32 flags, Dqn_u32 bitfield); +Dqn_b32 Dqn_Bit_IsNotSet(Dqn_u32 flags, Dqn_u32 bitfield); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Safe Arithmetic +// +// ------------------------------------------------------------------------------------------------- +Dqn_i64 Dqn_Safe_AddI64(Dqn_i64 a, Dqn_i64 b); +Dqn_i64 Dqn_Safe_MulI64(Dqn_i64 a, Dqn_i64 b); +Dqn_u64 Dqn_Safe_AddU64(Dqn_u64 a, Dqn_u64 b); +Dqn_u64 Dqn_Safe_MulU64(Dqn_u64 a, Dqn_u64 b); +int Dqn_Safe_TruncateISizeToInt(Dqn_isize val); +Dqn_i32 Dqn_Safe_TruncateISizeToI32(Dqn_isize val); +Dqn_i8 Dqn_Safe_TruncateISizeToI8(Dqn_isize val); +Dqn_u32 Dqn_Safe_TruncateUSizeToU32(Dqn_u64 val); +int Dqn_Safe_TruncateUSizeToI32(Dqn_usize val); +int Dqn_Safe_TruncateUSizeToInt(Dqn_usize val); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: Char Helpers +// +// ------------------------------------------------------------------------------------------------- +Dqn_b32 Dqn_Char_IsAlpha(char ch); +Dqn_b32 Dqn_Char_IsDigit(char ch); +Dqn_b32 Dqn_Char_IsAlphaNum(char ch); +Dqn_b32 Dqn_Char_IsWhitespace(char ch); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: String Helpers +// +// ------------------------------------------------------------------------------------------------- +Dqn_b32 Dqn_Str_Equals(char const *a, Dqn_isize a_len, char const *b, Dqn_isize b_len = -1); +char const * Dqn_Str_FindMulti(char const *buf, char const *find_list[], Dqn_isize const *find_string_lens, Dqn_isize find_len, Dqn_isize *match_index, Dqn_isize buf_len = -1); +char const * Dqn_Str_Find(char const *buf, char const *find, Dqn_isize buf_len = -1, Dqn_isize find_len = -1); +Dqn_b32 Dqn_Str_Match(char const *src, char const *find, int find_len); +char const * Dqn_Str_SkipToChar(char const *src, char ch); +char const * Dqn_Str_SkipToNextAlphaNum(char const *src); +char const * Dqn_Str_SkipToNextDigit(char const *src); +char const * Dqn_Str_SkipToNextChar(char const *src); +char const * Dqn_Str_SkipToNextWord(char const *src); +char const * Dqn_Str_SkipToNextWhitespace(char const *src); +char const * Dqn_Str_SkipWhitespace(char const *src); +char const * Dqn_Str_SkipToCharInPlace(char const **src, char ch); +char const * Dqn_Str_SkipToNextAlphaNumInPlace(char const **src); +char const * Dqn_Str_SkipToNextCharInPlace(char const **src); +char const * Dqn_Str_SkipToNextWhitespaceInPlace(char const **src); +char const * Dqn_Str_SkipToNextWordInPlace(char const **src); +char const * Dqn_Str_SkipWhitespaceInPlace(char const **src); +Dqn_u64 Dqn_Str_ToU64(char const *buf, int len = -1); +Dqn_i64 Dqn_Str_ToI64(char const *buf, int len = -1); +// ------------------------------------------------------------------------------------------------- +// +// NOTE: File +// +// ------------------------------------------------------------------------------------------------- +char * Dqn_File_ReadWithArena(Dqn_MemArena *arena, char const *file, Dqn_isize *file_size); diff --git a/Code/DqnInspect.h b/Code/DqnInspect.h deleted file mode 100644 index 52632fc..0000000 --- a/Code/DqnInspect.h +++ /dev/null @@ -1,2533 +0,0 @@ -#ifndef DQN_INSPECT_H -#define DQN_INSPECT_H - -#define _CRT_SECURE_NO_WARNINGS // NOTE: Undefined at end of file -#include - -// -// DqnInspect.h - Minimal Inspection System, Single Header, CRT Dependencies Only -// Public Domain or MIT License (see bottom of file) -// ================================================================================================= - -// -// HOW TO BUILD AND INSPECT ANNOTATED CODE -// ================================================================================================= -// Define in the preprocessor, DQN_INSPECT_EXECUTABLE_IMPLEMENTATION and compile -// Dqn_Inspect.h to produce the metaprogram binary. Run the binary on the -// desired C++ source files. The inspected file will be printed out to stdout. -// -// DqnInspect.exe YourSourceCode.cpp > YourSourceCode_Inspected.cpp - -// -// HOW TO ANNOTATE CODE -// ================================================================================================= -// This header only file contains all the necessary definitions for inspected -// members and should be included in all files containing information you wish -// to inspect. You may inspect C-like POD data structures, such as in the following -// example. -// - -// -// INSPECT USAGE -// ================================================================================================= - -/* - InspectedStruct foo = {}; - InspectedEnum bar = InspectedEnum::HelloWorld; - - printf("%s\n", DqnInspect_EnumString(bar)); // Prints "HelloWorld" - - // Print out each member of the struct - DqnInspect_Struct const *inspector = DqnReflect_GetStruct(&foo); - for (int i = 0; i < inspector->members_len; ++i) - printf("%s\n", inspect_struct->members[i].name); -*/ - -// -// ANNOTATION EXAMPLE -// ================================================================================================= -// See Data/DqnInspect_TestData.h - -// TODO(doyle): Make the enum system similar to struct members for consistency? -// TODO(doyle): Handle namespaces .. maybe. - -#define DQN_INSPECT -#define DQN_INSPECT_META(...) -#define DQN_INSPECT_FUNCTION(...) - -struct DqnInspectMetadata -{ - enum struct DqnInspectDeclType decl_type; - enum struct DqnInspectMetaType meta_type; - void const *data; -}; - -struct DqnInspectMember -{ - size_t id; // Unique ID, does not conflict with ID in InspectStruct either - enum struct DqnInspectMemberType name_type; - char const * name; - int name_len; - int pod_struct_offset; - - // The declaration type without any pointer or const modifiers, including template expressions - enum struct DqnInspectDeclType base_decl_type; - char const * base_decl_type_str; - int base_decl_type_len; - - // Includes the template expression if there is any in declaration - enum struct DqnInspectDeclType decl_type; - char const * decl_type_str; - int decl_type_len; - int decl_type_sizeof; - - // If there's a template this will be the topmost of the declaration i.e. for vector - // this will just be DqnInspectDeclType::vector_ - enum struct DqnInspectDeclType template_parent_decl_type; - - enum struct DqnInspectDeclType template_child_decl_type; - char const * template_child_expr; - int template_child_expr_len; - - int array_dimensions; // > 0 means array - - // NOTE: Supports maximum of 8 dimensions. 0 if unknown (i.e. just a pointer) - int array_compile_time_size[8]; - - DqnInspectMetadata const *metadata; - int metadata_len; -}; - -struct DqnInspectStruct -{ - size_t id; // Same as InspectMember, they are in the same number space and do not conflict - char const *name; - int name_len; - DqnInspectMember const *members; - int members_len; -}; - -inline DqnInspectMetadata const *DqnInspectMember_FindMetadata(DqnInspectMember const *member, - enum struct DqnInspectMetaType meta_type, - enum struct DqnInspectDeclType *decl_types = nullptr, - int num_decl_types = 0) -{ - for (size_t metadata_index = 0; - metadata_index < member->metadata_len; - ++metadata_index) - { - DqnInspectMetadata const *metadata = member->metadata + metadata_index; - if (metadata->meta_type == meta_type) - { - if (!decl_types || num_decl_types == 0) - return metadata; - - for (size_t decl_type_index = 0; decl_type_index < num_decl_types; ++decl_type_index) - { - DqnInspectDeclType const *decl_type = decl_types + decl_type_index; - if (metadata->decl_type == *decl_type) - { - return metadata; - } - } - } - } - - return nullptr; -} - -inline DqnInspectMetadata const *DqnInspectMember_FindMetadata(DqnInspectMember const *member, - enum struct DqnInspectMetaType meta_type, - enum struct DqnInspectDeclType decl_type) -{ - DqnInspectMetadata const *result = DqnInspectMember_FindMetadata(member, meta_type, &decl_type, 1); - return result; -} - -// NOTE(doyle): For compiler testing -// #include "../Data/DqnInspect_TestData.h" -// #include "../Data/DqnInspect_TestDataGenerated.cpp" - -#ifdef DQN_INSPECT_EXECUTABLE_IMPLEMENTATION - -#include -#include -#include -#include -#include -#include - -#include -#include - -static const int SPACES_PER_INDENT = 4; - -using usize = size_t; -using isize = ptrdiff_t; -using i64 = int64_t; -using i32 = int32_t; -using b32 = int32_t; -using u8 = uint8_t; - -template -struct Defer -{ - Proc proc; - Defer(Proc p) : proc(p) {} - ~Defer() { proc(); } -}; - -struct DeferHelper -{ - template - Defer operator+(Lambda lambda) { return Defer(lambda); } -}; - -template -unsigned short ArrayCount(T (&)[N]) { return N; } - -template -unsigned short CharCount(T (&)[N]) { return N - 1; } - -#define INSPECT_MAX(a, b) ((a) > (b)) ? (a) : (b) -#define INSPECT_MIN(a, b) ((a) < (b)) ? (a) : (b) -#define TOKEN_COMBINE(x, y) x ## y -#define TOKEN_COMBINE2(x, y) TOKEN_COMBINE(x, y) -#define DEFER auto const TOKEN_COMBINE(defer_lambda_, __COUNTER__) = DeferHelper() + [&]() - -#define KILOBYTE(val) (1024ULL * (val)) -#define MEGABYTE(val) (1024ULL * KILOBYTE(val)) - -#define SLICE_LITERAL(str) Slice{str, CharCount(str)} -template -struct Slice -{ - Slice() = default; - Slice(T *str, int len) : str(str) , len(len) { } - T *str; - int len; - - bool operator<(Slice const &rhs) const - { - if (this->len == rhs.len) - return (memcmp(this->str, rhs.str, this->len) < 0); - return this->len < rhs.len; - } -}; - -template -b32 Slice_Cmp(T const a, T const b) -{ - if (a.len != b.len) - return false; - b32 result = (memcmp(a.str, b.str, a.len) == 0); - return result; -} - -template -struct LinkedList -{ - T value; - LinkedList *next; -}; - -// -// Memory Utilities -// - -struct MemArena -{ - void *memory; - usize size; - usize used; -}; - -struct MemArenaScopedRegion -{ - MemArenaScopedRegion (MemArena *arena_, usize used_) : arena(arena_), used(used_) {} - ~MemArenaScopedRegion() { arena->used = used; } - MemArena *arena; - usize used; -}; - -static MemArena global_main_arena; - -#define MEM_ARENA_ALLOC_ARRAY(arena, Type, num) static_cast(MemArena_Alloc(arena, sizeof(Type) * num)) -#define MEM_ARENA_ALLOC_STRUCT(arena, Type) static_cast(MemArena_Alloc(arena, sizeof(Type))) -MemArena MemArena_Init(void *memory, usize size) -{ - MemArena result = {}; - result.memory = memory; - result.size = size; - result.used = 0; - return result; -} - -MemArenaScopedRegion MemArena_MakeScopedRegion(MemArena *arena) -{ - return MemArenaScopedRegion(arena, arena->used); -} - -void *MemArena_Alloc(MemArena *arena, usize size) -{ - assert(arena->used + size <= arena->size); - void *result = static_cast(arena->memory) + arena->used; - arena->used += size; - return result; -} - -template void EraseStableFromCArray(T *array, isize len, isize max, isize index); -#define FIXED_ARRAY_TEMPLATE_DECL template -FIXED_ARRAY_TEMPLATE_DECL struct FixedArray -{ - FixedArray() = default; - T data[MAX_]; - isize len; - isize Max() const { return MAX_; } - T const &operator[] (isize i) const { assert(i >= 0 && i < len); return data[i]; } - T &operator[] (isize i) { assert(i >= 0 && i < len); return data[i]; } - T const *begin () const { return data; } - T const *end () const { return data + len; } - T *begin () { return data; } - T *end () { return data + len; } -}; -FIXED_ARRAY_TEMPLATE_DECL FixedArray FixedArray_Init (T const *item, int num) { FixedArray result = {}; FixedArray_Add(&result, item, num); return result; } -FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Add (FixedArray *a, T const *items, int num) { assert(a->len + num <= MAX_); T *result = static_cast(MemCopy(a->data + a->len, items, sizeof(T) * num)); a->len += num; return result; } -FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Add (FixedArray *a, T const item) { assert(a->len < MAX_); a->data[a->len++] = item; return &a->data[a->len - 1]; } -FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Make (FixedArray *a, int num) { assert(a->len + num <= MAX_); T *result = a->data + a->len; a->len += num; return result;} -FIXED_ARRAY_TEMPLATE_DECL void FixedArray_Clear (FixedArray *a) { a->len = 0; } -FIXED_ARRAY_TEMPLATE_DECL void FixedArray_EraseStable (FixedArray *a, isize index) { EraseStableFromCArray(a->data, a->len--, a.Max(), index); } -FIXED_ARRAY_TEMPLATE_DECL void FixedArray_EraseUnstable(FixedArray *a, isize index) { assert(index >= 0 && index < a->len); if (--a->len == 0) return; a->data[index] = a->data[a->len]; } - -// -// String Utilities -// - -b32 CharIsAlpha (char ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); } -b32 CharIsDigit (char ch) { return (ch >= '0' && ch <= '9'); } -b32 CharIsAlphaNum (char ch) { return CharIsAlpha(ch) || CharIsDigit(ch); } -b32 CharIsWhitespace(char ch) { return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); } - -char const *StrSkipToChar(char const *src, char ch) -{ - char const *result = src; - while (result && result[0] && result[0] != ch) ++result; - return result; -} - -char const *StrSkipToNextAlphaNum(char const *src) -{ - char const *result = src; - while (result && result[0] && !CharIsAlphaNum(result[0])) ++result; - return result; -} - -char const *StrSkipToNextDigit(char const *src) -{ - char const *result = src; - while (result && result[0] && !CharIsDigit(result[0])) ++result; - return result; -} - -char const *StrSkipToNextChar(char const *src) -{ - char const *result = src; - while (result && result[0] && !CharIsAlpha(result[0])) ++result; - return result; -} - -char const *StrSkipToNextWord(char const *src) -{ - char const *result = src; - while (result && result[0] && !CharIsWhitespace(result[0])) ++result; - while (result && result[0] && CharIsWhitespace(result[0])) ++result; - return result; -} - -char const *StrSkipToNextWhitespace(char const *src) -{ - char const *result = src; - while (result && result[0] && !CharIsWhitespace(result[0])) ++result; - return result; -} - -char const *StrSkipWhitespace(char const *src) -{ - char const *result = src; - while (result && result[0] && CharIsWhitespace(result[0])) ++result; - return result; -} - -char const *StrSkipToNextWordInplace(char const **src) { *src = StrSkipToNextWord(*src); return *src; } -char const *StrSkipWhitespaceInplace(char const **src) { *src = StrSkipWhitespace(*src); return *src; } - -char *StrFind(Slice src, Slice find) -{ - char *buf_ptr = src.str; - char *buf_end = buf_ptr + src.len; - char *result = nullptr; - - for (;*buf_ptr; ++buf_ptr) - { - int len_remaining = static_cast(buf_end - buf_ptr); - if (len_remaining < find.len) break; - - if (strncmp(buf_ptr, find.str, find.len) == 0) - { - result = buf_ptr; - break; - } - } - return result; -} - -Slice RemoveConsecutiveSpaces(Slice input) -{ - Slice result = input; - for (size_t i = 0; i < (result.len - 1); ++i) - { - char curr = result.str[i]; - char next = result.str[i + 1]; - if (curr == ' ' && next == ' ') - { - char const *end = result.str + result.len; - char const *str = (result.str + (i + 1)); - int bytes_to_shift = static_cast(end - str); - memcpy(result.str + i, str, bytes_to_shift); - --result.len; - --i; - } - } - - return result; -} - -Slice TrimSpaceAround(Slice const input) -{ - Slice result = input; - while (result.str[0] == ' ' && result.len > 0) - { - ++result.str; - --result.len; - } - - while (result.len > 0 && result.str[result.len - 1] == ' ') - --result.len; - - return result; -} - -Slice Asprintf(MemArena *arena, char const *fmt, ...) -{ - va_list va; - va_start(va, fmt); - Slice result = {}; - result.len = vsnprintf(nullptr, 0, fmt, va); - result.str = MEM_ARENA_ALLOC_ARRAY(arena, char, result.len + 1); - vsnprintf(result.str, result.len + 1, fmt, va); - result.str[result.len] = 0; - va_end(va); - return result; -} - -// -// CPP Tokenisers/Tokens -// - -#define CPP_TOKEN_TYPE_X_MACRO \ - X(EndOfStream, "End Of Stream") \ - X(LeftBrace, "{") \ - X(RightBrace, "}") \ - X(LeftSqBracket, "[") \ - X(RightSqBracket, "]") \ - X(OpenParen, "(") \ - X(CloseParen, ")") \ - X(Comma, ",") \ - X(Colon, ":") \ - X(FwdSlash, "/") \ - X(Comment, "comment") \ - X(LessThan, "<") \ - X(GreaterThan, ">") \ - X(Equals, "=") \ - X(String, "\"") \ - X(SemiColon, ";") \ - X(Identifier, "Identifier") \ - X(Number, "[0-9]") \ - X(Asterisks, "*") \ - X(Ampersand, "&") \ - X(VarArgs, "Variable Args (...)") \ - X(InspectCode, "DQN_INSPECT") \ - X(InspectFunction, "DQN_INSPECT_FUNCTION") \ - X(Hash, "#") - -#define X(decl, str) decl, -enum struct CPPTokenType -{ - CPP_TOKEN_TYPE_X_MACRO -}; -#undef X - -#define X(decl, str) str, -char const *CPPTokenType_Strings[] -{ - CPP_TOKEN_TYPE_X_MACRO -}; -#undef X - -struct CPPToken -{ - CPPTokenType type; - char *str; - int len; -}; - -#define ARRAY_COUNT(array) sizeof(array)/sizeof(array[0]) -struct CPPVariableDecl -{ - b32 type_has_const; - Slice type_without_ptr_const_modifiers; - Slice type; - Slice name; - Slice template_child_expr; - b32 array_has_const; - int array_dimensions; - b32 array_dimensions_has_compile_time_size[8]; // TODO(doyle): Max of 8 dimensions, whotf needs more? - Slice default_value; -}; - -static_assert(ARRAY_COUNT(((DqnInspectMember *)0)->array_compile_time_size) == ARRAY_COUNT(((CPPVariableDecl *)0)->array_dimensions_has_compile_time_size), - "Sizes must match otherwise overflow on writing our Inspection data"); - -template -struct CPPDeclLinkedList -{ - CPPDeclLinkedList *metadata_list; - T value; - CPPDeclLinkedList *next; -}; - -struct CPPTokeniser -{ - CPPToken *tokens; - int tokens_index; - int tokens_len; - int tokens_max; - - int indent_level; -}; - -void FprintfIndented(FILE *output_file, int indent_level, char const *fmt, ...) -{ - int const num_spaces = SPACES_PER_INDENT * indent_level; - fprintf(output_file, "%*s", num_spaces, ""); - - va_list va; - va_start(va, fmt); - vfprintf(output_file, fmt, va); - va_end(va); -} - -CPPToken CPPTokeniser_NextToken(CPPTokeniser *tokeniser, int amount = 1) -{ - CPPToken result = tokeniser->tokens[tokeniser->tokens_index]; - if (result.type != CPPTokenType::EndOfStream) - { - for (int i = 0; i < amount; i++) - { - result = tokeniser->tokens[tokeniser->tokens_index++]; - if (result.type == CPPTokenType::LeftBrace) tokeniser->indent_level++; - else if (result.type == CPPTokenType::RightBrace) tokeniser->indent_level--; - assert(tokeniser->indent_level >= 0); - - if (result.type == CPPTokenType::EndOfStream) - break; - } - } - return result; -} - -CPPToken CPPTokeniser_PeekToken(CPPTokeniser *tokeniser) -{ - CPPToken result = tokeniser->tokens[tokeniser->tokens_index]; - return result; -} - -void CPPTokeniser_RewindToken(CPPTokeniser *tokeniser) -{ - tokeniser->tokens[--tokeniser->tokens_index]; -} - -CPPToken CPPTokeniser_PrevToken(CPPTokeniser *tokeniser) -{ - CPPToken result = {}; - result.type = CPPTokenType::EndOfStream; - if (tokeniser->tokens_index > 0) - result = tokeniser->tokens[tokeniser->tokens_index - 1]; - return result; -} - -CPPToken *CPPTokeniser_MakeToken(CPPTokeniser *tokeniser) -{ - assert(tokeniser->tokens_len < tokeniser->tokens_max); - CPPToken *result = tokeniser->tokens + tokeniser->tokens_len++; - return result; -} - -bool CPPTokeniser_AcceptTokenIfType(CPPTokeniser *tokeniser, CPPTokenType type, CPPToken *token) -{ - CPPToken check = CPPTokeniser_PeekToken(tokeniser); - bool result = (check.type == type); - if (result) - { - CPPTokeniser_NextToken(tokeniser); - if (token) *token = check; - } - - return result; -} - -// -// CPP Parsing Helpers -// - -b32 IsIdentifierToken(CPPToken token, Slice expect_str) -{ - b32 result = (token.type == CPPTokenType::Identifier) && (Slice_Cmp(Slice(token.str, token.len), expect_str)); - return result; -} - -b32 ExpectToken(CPPToken token, CPPTokenType type) -{ - b32 result = token.type == type; - if (!result) - { - fprintf(stdout, "Expected token type: %s received: %.*s\n", CPPTokenType_Strings[(int)type], token.len, token.str); - fprintf(stdout, "Context: %.*s\n\n", (token.len > 100) ? 100 : token.len, token.str); - } - return result; -} - -// -// CPP Parsing Functions -// - -#if 0 -DQN_INSPECT enum struct EnumWithMetadata -{ - Rect DQN_INSPECT_META(char const *FilePath = "Rect.vert", V3 Coords = V3(1, 2, 3)), - Square DQN_INSPECT_META(char *file_path = "Rect.vert"), - Count, -}; -#endif - -int ConsumeIdentifier(CPPTokeniser *tokeniser, Slice identifier, CPPToken *token = nullptr) -{ - int result = 0; - CPPToken last_token = {}; - for (CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - peek_token.type == CPPTokenType::Identifier && - Slice_Cmp(identifier, Slice(peek_token.str, peek_token.len)); - ++result) - { - last_token = peek_token; - CPPTokeniser_NextToken(tokeniser); - peek_token = CPPTokeniser_PeekToken(tokeniser); - } - - if (token && last_token.type != CPPTokenType::EndOfStream) *token = last_token; - return result; -} - - -int ConsumeToken(CPPTokeniser *tokeniser, CPPTokenType type, CPPToken *token = nullptr) -{ - int result = 0; - CPPToken last_token = {}; - for (CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - peek_token.type == type; - ++result) - { - last_token = peek_token; - CPPTokeniser_NextToken(tokeniser); - peek_token = CPPTokeniser_PeekToken(tokeniser); - } - - if (token && last_token.type != CPPTokenType::EndOfStream) *token = last_token; - return result; -} - -int ConsumeAsterisks(CPPTokeniser *tokeniser, CPPToken *token = nullptr) -{ - int result = ConsumeToken(tokeniser, CPPTokenType::Asterisks, token); - return result; -} - -b32 ConsumeConstIdentifier(CPPTokeniser *tokeniser, CPPToken *token = nullptr) -{ - b32 result = false; - CPPToken last_const_token = {}; - for (CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - IsIdentifierToken(peek_token, SLICE_LITERAL("const")); - peek_token = CPPTokeniser_PeekToken(tokeniser)) - { - last_const_token = peek_token; - result = true; - CPPTokeniser_NextToken(tokeniser); - } - - if (token && last_const_token.type != CPPTokenType::EndOfStream) *token = last_const_token; - return result; -} - -void SkipFunctionParam(CPPTokeniser *tokeniser) -{ - CPPToken token = CPPTokeniser_PeekToken(tokeniser); - while (token.type != CPPTokenType::EndOfStream) - { - if (token.type == CPPTokenType::OpenParen) - { - for (int level = 1; level != 0;) - { - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - if (token.type == CPPTokenType::OpenParen) level++; - if (token.type == CPPTokenType::CloseParen) level--; - } - - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - } - - if (token.type == CPPTokenType::LeftBrace) - { - for (int level = 1; level != 0;) - { - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - if (token.type == CPPTokenType::LeftBrace) level++; - if (token.type == CPPTokenType::RightBrace) level--; - } - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - } - - if (token.type == CPPTokenType::CloseParen) - break; - - if (token.type == CPPTokenType::Comma) - break; - - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - } -} - -CPPDeclLinkedList *ParseCPPInspectMeta(CPPTokeniser *tokeniser); -// NOTE(doyle): Doesn't parse the ending semicolon so we can reuse this function for parsing function arguments -CPPDeclLinkedList *ParseCPPTypeAndVariableDecl(CPPTokeniser *tokeniser, b32 parse_function_param) -{ - CPPDeclLinkedList *result = nullptr; - CPPDeclLinkedList *link_iterator = nullptr; - - b32 type_has_const = ConsumeConstIdentifier(tokeniser); - ConsumeIdentifier(tokeniser, SLICE_LITERAL("enum")); - ConsumeIdentifier(tokeniser, SLICE_LITERAL("struct")); - ConsumeIdentifier(tokeniser, SLICE_LITERAL("class")); - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (token.type != CPPTokenType::Identifier && token.type != CPPTokenType::VarArgs) - return result; - - CPPToken variable_type = token; - for (int total_asterisks_count = 0;;) - { - Slice variable_template_child_expr = {}; - if (CPPTokeniser_AcceptTokenIfType(tokeniser, CPPTokenType::LessThan, &token)) - { - CPPToken template_start_token = token; - int template_depth = 1; - while (template_depth != 0 && token.type != CPPTokenType::EndOfStream) - { - token = CPPTokeniser_NextToken(tokeniser); - if (token.type == CPPTokenType::LessThan) - template_depth++; - else if (token.type == CPPTokenType::GreaterThan) - template_depth--; - } - - if (template_depth == 0) - { - char *expr_start = template_start_token.str + 1; - char *expr_end = token.str; - int expr_len = static_cast(expr_end - expr_start); - - variable_template_child_expr.str = expr_start; - variable_template_child_expr.len = expr_len; - } - - for (int ch_index = 0; ch_index < variable_template_child_expr.len; ++ch_index) - { - if (variable_template_child_expr.str[ch_index] == ',') - variable_template_child_expr.str[ch_index] = '_'; - } - } - - CPPToken end_of_type_wo_modifiers = token; - CPPToken last_modifier_token = {}; - ConsumeToken(tokeniser, CPPTokenType::Ampersand, &last_modifier_token); - total_asterisks_count = ConsumeAsterisks(tokeniser, &last_modifier_token); - b32 array_has_const = false; - if (ConsumeConstIdentifier(tokeniser, &last_modifier_token)) - { - if (type_has_const) - array_has_const = true; // Then this const is applying on the pointer type - else - type_has_const = true; - - total_asterisks_count += ConsumeAsterisks(tokeniser, &last_modifier_token); - ConsumeConstIdentifier(tokeniser, &last_modifier_token); - } - - ConsumeToken(tokeniser, CPPTokenType::Ampersand, &last_modifier_token); - - CPPToken variable_name = {}; - if (variable_type.type == CPPTokenType::Identifier) - { - token = CPPTokeniser_PeekToken(tokeniser); - variable_name = token; - if (variable_name.type != CPPTokenType::Identifier) - break; - - CPPTokeniser_NextToken(tokeniser); - } - - // Allocate A Member Declaration - auto *link = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPDeclLinkedList); - *link = {}; - if (!result) result = link; // Set result to first linked list entry - else link_iterator->next = link; - auto *prev_link = link_iterator; - link_iterator = link; - - Slice variable_type_str_lit = {variable_type.str, variable_type.len}; - if (last_modifier_token.type != CPPTokenType::EndOfStream) - { - if (!prev_link) - { - variable_type_str_lit.len = - static_cast((last_modifier_token.str + (last_modifier_token.len - 1)) - variable_type.str) + 1; - } - else - { - CPPTokeniser copy_tokeniser = *tokeniser; - CPPTokeniser_RewindToken(©_tokeniser); - CPPToken rewind_token = CPPTokeniser_PeekToken(©_tokeniser); - while (rewind_token.type != CPPTokenType::Comma) - { - CPPTokeniser_RewindToken(©_tokeniser); - rewind_token = CPPTokeniser_PeekToken(©_tokeniser); - } - - Slice comma_to_var_name = {}; - comma_to_var_name.str = rewind_token.str + 1; - comma_to_var_name.len = static_cast(variable_name.str - comma_to_var_name.str); - comma_to_var_name = TrimSpaceAround(comma_to_var_name); - - if (parse_function_param) - { - variable_type_str_lit = Asprintf(&global_main_arena, - "%.*s", - comma_to_var_name.len, - comma_to_var_name.str); - } - else - { - // If not function param, we're parsing something of the likes - // int var, const *var1 - - // In which case you want to pull the base variable type, - // crrently stored in variable_type and then you want to - // pull in everything from the comma to var1, to grab the - // pointer modifiers on the type. - variable_type_str_lit = Asprintf(&global_main_arena, - "%.*s %.*s", - variable_type.len, - variable_type.str, - comma_to_var_name.len, - comma_to_var_name.str); - } - } - } - variable_type_str_lit = TrimSpaceAround(variable_type_str_lit); - variable_type_str_lit = RemoveConsecutiveSpaces(variable_type_str_lit); - - link->value.type_has_const = type_has_const; - link->value.type_without_ptr_const_modifiers = Slice(variable_type.str, variable_type.len); - link->value.type = variable_type_str_lit; - link->value.name = Slice(variable_name.str, variable_name.len); - link->value.template_child_expr = variable_template_child_expr; - link->value.array_has_const = array_has_const; - link->value.array_dimensions = total_asterisks_count; - - for (token = CPPTokeniser_PeekToken(tokeniser); - token.type == CPPTokenType::LeftSqBracket && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) - { - // TODO(doyle): Parsing array size is difficult if it's an expression, so maybe don't do it at all - int token_count_after_left_sq_bracket = 0; - while (token.type != CPPTokenType::RightSqBracket && token.type != CPPTokenType::EndOfStream) - { - token_count_after_left_sq_bracket++; - token = CPPTokeniser_NextToken(tokeniser); - } - - if (token_count_after_left_sq_bracket > 0) - { - // NOTE(doyle): There is some sort of contents in the bracket, so, this array has a compile time size - link->value.array_dimensions_has_compile_time_size[link->value.array_dimensions] = true; - } - ++link->value.array_dimensions; - } - assert(link->value.array_dimensions < ArrayCount(link->value.array_dimensions_has_compile_time_size)); - - if (IsIdentifierToken(token, SLICE_LITERAL("DQN_INSPECT_META"))) - { - link->metadata_list = ParseCPPInspectMeta(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - } - - if (token.type == CPPTokenType::Equals) - { - token = CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - char *default_value_start = token.str; - - if (token.type == CPPTokenType::String) // NOTE(doyle): Include the quotes in the param value - default_value_start--; - - SkipFunctionParam(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - if (token.type != CPPTokenType::Comma && token.type != CPPTokenType::CloseParen) - continue; - - char *default_value_end = token.str; - link->value.default_value = Slice(default_value_start, static_cast(default_value_end - default_value_start)); - } - - if (token.type == CPPTokenType::Comma) - { - if (parse_function_param) - { - CPPTokeniser_NextToken(tokeniser); - variable_type = CPPTokeniser_PeekToken(tokeniser); - } - token = CPPTokeniser_NextToken(tokeniser); - } - else - { - break; - } - } - - return result; -} - -CPPDeclLinkedList *ParseCPPInspectMeta(CPPTokeniser *tokeniser) -{ - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier) || !IsIdentifierToken(token, SLICE_LITERAL("DQN_INSPECT_META"))) - return nullptr; - - token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::OpenParen)) return nullptr; - - CPPDeclLinkedList *result = ParseCPPTypeAndVariableDecl(tokeniser, true); - CPPTokeniser_AcceptTokenIfType(tokeniser, CPPTokenType::CloseParen, nullptr); - return result; -} - -enum struct ParsedCodeType -{ - Invalid, - Struct, - Enum, - Function, -}; - -struct ParsedEnum -{ - b32 struct_or_class_decl; - Slice name; - CPPDeclLinkedList> *members; -}; - -struct ParsedStruct -{ - Slice name; - CPPDeclLinkedList *members; -}; - - -struct ParsedFunction -{ - Slice return_type; - Slice name; - CPPDeclLinkedList *members; - b32 has_comments; - LinkedList> comments; -}; - -struct ParsedCode -{ - ParsedCodeType type; - union - { - ParsedEnum parsed_enum; - ParsedFunction parsed_func; - ParsedStruct parsed_struct; - }; -}; - -struct ParsingResult -{ - std::vector code; - int file_include_contents_hash_define_len; - char *file_include_contents_hash_define; - int max_func_return_type_decl_len; - int max_func_name_decl_len; - Slice file_name; -}; - - -b32 ParseCPPEnum(CPPTokeniser *tokeniser, ParsedEnum *parsed_enum) -{ - *parsed_enum = {}; - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier) || !IsIdentifierToken(token, SLICE_LITERAL("enum"))) - return false; - - token = CPPTokeniser_NextToken(tokeniser); - if (IsIdentifierToken(token, SLICE_LITERAL("class")) || - IsIdentifierToken(token, SLICE_LITERAL("struct"))) - { - parsed_enum->struct_or_class_decl = true; - token = CPPTokeniser_NextToken(tokeniser); - } - - if (!ExpectToken(token, CPPTokenType::Identifier)) - return false; - - int original_indent_level = tokeniser->indent_level; - CPPToken const enum_name = token; - token = CPPTokeniser_NextToken(tokeniser); - - if (!ExpectToken(token, CPPTokenType::LeftBrace)) - return false; - - parsed_enum->name = Slice(enum_name.str, enum_name.len); - { - CPPDeclLinkedList> *link_iterator = nullptr; - for (token = CPPTokeniser_NextToken(tokeniser); - tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) - { - if (token.type == CPPTokenType::Identifier) - { - auto *link = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPDeclLinkedList>); - *link = {}; - if (!link_iterator) parsed_enum->members = link; // Set members to first linked list entry - else link_iterator->next = link; - link_iterator = link; - - link->value = Slice(token.str, token.len); - CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - if (IsIdentifierToken(peek_token, SLICE_LITERAL("DQN_INSPECT_META"))) - { - link->metadata_list = ParseCPPInspectMeta(tokeniser); - } - } - } - } - - return true; -} - -b32 ParseCPPVariableType(CPPTokeniser *tokeniser, Slice *type) -{ - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier)) - return false; - - char *var_type_start = token.str; - ConsumeConstIdentifier(tokeniser); - - // - // Parse Template If Any - // - Slice template_child_expr = {}; - { - CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - if (peek_token.type == CPPTokenType::LessThan) - { - token = CPPTokeniser_NextToken(tokeniser); - int template_depth = 1; - while (template_depth != 0 && token.type != CPPTokenType::EndOfStream) - { - token = CPPTokeniser_NextToken(tokeniser); - if (token.type == CPPTokenType::LessThan) - template_depth++; - else if (token.type == CPPTokenType::GreaterThan) - template_depth--; - } - - if (template_depth == 0) - { - char *expr_start = peek_token.str + 1; - char *expr_end = token.str; - int expr_len = static_cast(expr_end - expr_start); - - template_child_expr.str = expr_start; - template_child_expr.len = expr_len; - } - } - } - - int total_asterisks_count = ConsumeAsterisks(tokeniser); - if (ConsumeConstIdentifier(tokeniser)) - { - total_asterisks_count += ConsumeAsterisks(tokeniser); - ConsumeConstIdentifier(tokeniser); - } - - CPPToken var_name = CPPTokeniser_PeekToken(tokeniser); - if (!ExpectToken(var_name, CPPTokenType::Identifier)) - return false; - - char *var_type_end = var_name.str; - if (type) - { - type->str = var_type_start; - type->len = static_cast(var_type_end - var_type_start); - - // NOTE(doyle): Remove space(s) at the end of the return type if - // any, because we parse the function type weirdly by getting the - // identifier for the function name and looking one token back. - while (type->len >= 1 && CharIsWhitespace(type->str[type->len - 1])) - type->len--; - } - - return true; -} - -b32 ParseCPPStruct(CPPTokeniser *tokeniser, ParsedStruct *parsed_struct) -{ - *parsed_struct = {}; - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier) || - (!IsIdentifierToken(token, SLICE_LITERAL("struct")) && !IsIdentifierToken(token, SLICE_LITERAL("class")))) - return false; - - int const original_indent_level = tokeniser->indent_level; - token = CPPTokeniser_NextToken(tokeniser); - - if (token.type != CPPTokenType::LeftBrace) - { - if (!ExpectToken(token, CPPTokenType::Identifier)) return false; - parsed_struct->name = Slice(token.str, token.len); - } - - { - CPPDeclLinkedList *link_iterator = nullptr; - for (token = CPPTokeniser_NextToken(tokeniser); - tokeniser->indent_level != original_indent_level && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) - { - if (token.type == CPPTokenType::Identifier) - { - CPPTokeniser_RewindToken(tokeniser); - CPPDeclLinkedList *link = ParseCPPTypeAndVariableDecl(tokeniser, false); - if (!parsed_struct->members) parsed_struct->members = link; - if (!link_iterator) link_iterator = link; - else - { - for (;link_iterator->next; link_iterator = link_iterator->next) // TODO(doyle): Meh - ; - link_iterator->next = link; - } - } - } - } - - // TODO(doyle): Don't support anonymous/nameless structs yet - if (parsed_struct->name.len == 0) - return false; - - return true; -} - -b32 ParseCPPInspectFunction(CPPTokeniser *tokeniser, ParsedFunction *parsed_func) -{ - *parsed_func = {}; - CPPToken token = CPPTokeniser_NextToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::InspectFunction)) - return false; - - struct FunctionDefaultParam - { - Slice name; - Slice value; - }; - - // - // NOTE: Parse default params in the inspect prototype macro - // - LinkedList *default_param_list = nullptr; - { - LinkedList *link_iterator = nullptr; - if (!CPPTokeniser_AcceptTokenIfType(tokeniser, CPPTokenType::OpenParen, &token)) - return false; - - for (token = CPPTokeniser_NextToken(tokeniser); - token.type != CPPTokenType::CloseParen && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) - { - if (token.type == CPPTokenType::Comma) - continue; - - Slice default_param_name = Slice(token.str, token.len); - if (token.type != CPPTokenType::Identifier) - { - SkipFunctionParam(tokeniser); - continue; - } - - token = CPPTokeniser_NextToken(tokeniser); - if (token.type != CPPTokenType::Equals) - { - SkipFunctionParam(tokeniser); - continue; - } - - token = CPPTokeniser_PeekToken(tokeniser); - char *default_value_start = token.str; - - if (token.type == CPPTokenType::String) // NOTE(doyle): Include the quotes in the param value - default_value_start--; - - SkipFunctionParam(tokeniser); - CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser); - if (peek_token.type != CPPTokenType::Comma && peek_token.type != CPPTokenType::CloseParen) - continue; - - char *default_value_end = peek_token.str; - - auto *link = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, LinkedList); - *link = {}; - if (!default_param_list) default_param_list = link; - else link_iterator->next = link; - link_iterator = link; - - link->value.name = default_param_name; - link->value.value = Slice(default_value_start, static_cast(default_value_end - default_value_start)); - } - } - - struct FunctionParam - { - Slice type; - Slice name; - - // NOTE(doyle): This is resolved after function parsing, iterate over - // the default params specified in the macro and match them to the - // first param that has the same name - Slice default_value; - }; - - // Grab all following comments - { - LinkedList> *comments = &parsed_func->comments; - while (CPPTokeniser_AcceptTokenIfType(tokeniser, CPPTokenType::Comment, &token)) - { - parsed_func->has_comments = true; - if (comments->value.str > 0) - { - comments->next = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, LinkedList>); - comments = comments->next; - } - - comments->value = Slice(token.str, token.len); - } - } - - - // Grab return type token - { - token = CPPTokeniser_PeekToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier)) return false; - if (!ParseCPPVariableType(tokeniser, &parsed_func->return_type)) return false; - } - - // Grab function name token - { - token = CPPTokeniser_PeekToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::Identifier)) return false; - - char *name_start = token.str; - while (token.type != CPPTokenType::OpenParen && token.type != CPPTokenType::EndOfStream) - { - CPPTokeniser_NextToken(tokeniser); - token = CPPTokeniser_PeekToken(tokeniser); - } - - if (!ExpectToken(token, CPPTokenType::OpenParen)) return false; - char *name_end = token.str; - parsed_func->name = Slice(name_start, static_cast(name_end - name_start)); - } - - token = CPPTokeniser_PeekToken(tokeniser); - if (!ExpectToken(token, CPPTokenType::OpenParen)) - return false; - - // - // NOTE: Parse CPP Function Parameters - // - { - CPPDeclLinkedList *link_iterator = nullptr; - token = CPPTokeniser_NextToken(tokeniser); - for (token = CPPTokeniser_NextToken(tokeniser); - token.type != CPPTokenType::CloseParen && token.type != CPPTokenType::EndOfStream; - token = CPPTokeniser_NextToken(tokeniser)) - { - if (token.type == CPPTokenType::Identifier || token.type == CPPTokenType::VarArgs) - { - CPPTokeniser_RewindToken(tokeniser); - CPPDeclLinkedList *link = ParseCPPTypeAndVariableDecl(tokeniser, true); - if (!parsed_func->members) parsed_func->members = link; - if (!link_iterator) link_iterator = link; - else - { - for (;link_iterator->next; link_iterator = link_iterator->next) // TODO(doyle): Meh - ; - link_iterator->next = link; - } - } - } - } - - // - // NOTE: Map Default Parameters in the inspect prototype macro to the actual declaration in the CPP Prototype - // - for (LinkedList const *default_link = default_param_list; default_link; default_link = default_link->next) - { - FunctionDefaultParam const *default_param = &default_link->value; - for (CPPDeclLinkedList *param_link = parsed_func->members; param_link; param_link = param_link->next) - { - CPPVariableDecl *decl = ¶m_link->value; - if (Slice_Cmp(decl->name, default_param->name)) - { - decl->default_value = default_param->value; - break; - } - } - } - - return true; -} - -enum struct InspectMode -{ - All, - Code, - Function -}; - -char *EnumOrStructOrFunctionLexer(CPPTokeniser *tokeniser, char *ptr, b32 lexing_function) -{ - // NOTE(doyle): If we're lexing a function we're doing DQN_INSPECT_GENERATE_PROTOTYPE() - // Where we want to lex the macro and then the function following it, so 2 iterations - int iterations = lexing_function ? 2 : 1; - - for (int i = 0; i < iterations; ++i) - { - int indent_level = 0; - bool started_lexing_brace_scope = false; - bool started_lexing_function = false; - int paren_level = 0; - for (; ptr;) - { - while (CharIsWhitespace(ptr[0])) ptr++; - if (!ptr[0]) break; - - CPPToken *token = CPPTokeniser_MakeToken(tokeniser); - token->str = ptr++; - token->len = 1; - switch(token->str[0]) - { - case '{': { token->type = CPPTokenType::LeftBrace; started_lexing_brace_scope = true; indent_level++; } break; - case '}': { token->type = CPPTokenType::RightBrace; indent_level--; } break; - case '[': { token->type = CPPTokenType::LeftSqBracket; } break; - case ']': { token->type = CPPTokenType::RightSqBracket; } break; - case '(': { token->type = CPPTokenType::OpenParen; started_lexing_function = true; paren_level++; } break; - case ')': { token->type = CPPTokenType::CloseParen; paren_level--; } break; - case ',': { token->type = CPPTokenType::Comma; } break; - case ';': { token->type = CPPTokenType::SemiColon; } break; - case '=': { token->type = CPPTokenType::Equals; } break; - case '<': { token->type = CPPTokenType::LessThan; } break; - case '>': { token->type = CPPTokenType::GreaterThan; } break; - case ':': { token->type = CPPTokenType::Colon; } break; - case '*': { token->type = CPPTokenType::Asterisks; } break; - case '&': { token->type = CPPTokenType::Ampersand; } break; - - case '.': - { - if (token->str[1] == '.' && token->str[2] == '.') - { - token->type = CPPTokenType::VarArgs; - token->len = 3; - ptr += 2; - } - else - { - token->len = 0; // NOTE: Skip - } - } - break; - - case '/': - { - token->type = CPPTokenType::FwdSlash; - if (ptr[0] == '/' || ptr[0] == '*') - { - token->type = CPPTokenType::Comment; - if (ptr[0] == '/') - { - ptr++; - while (ptr[0] == ' ' || ptr[0] == '\t') ptr++; - token->str = ptr; - while (ptr[0] != '\n') ptr++; - } - else - { - for (;;) - { - while (ptr[0] != '*') ptr++; - ptr++; - if (ptr[0] == '\\') break; - token->len = static_cast(ptr - token->str); - } - } - - token->len = static_cast(ptr - token->str); - if (token->len >= 1) - if (ptr[-1] == '\r') token->len--; - } - } - break; - - default: - { - ptr--; - if (ptr[0] == '"') - { - token->type = CPPTokenType::String; - for (token->str = ++ptr;;) - { - while (ptr[0] != '"') ptr++; - token->len = static_cast(ptr - token->str); - if (ptr[-1] != '\\') - { - ptr++; - break; - } - } - } - else - { - if (CharIsDigit(ptr[0]) || ptr[0] == '-' || ptr[0] == '*') - { - while (CharIsDigit(ptr[0]) || ptr[0] == 'x' || ptr[0] == 'b' || ptr[0] == 'e' || ptr[0] == '.' || ptr[0] == 'f' || ptr[0] == '-' || ptr[0] == '+') - ptr++; - - token->type = CPPTokenType::Number; - } - else - { - token->type = CPPTokenType::Identifier; - if (CharIsAlpha(ptr[0]) || ptr[0] == '_') - { - ptr++; - while (CharIsAlphaNum(ptr[0]) || ptr[0] == '_') ptr++; - } - } - - token->len = static_cast(ptr - token->str); - } - - } - break; - } - - if (token->len == 0 && token->type != CPPTokenType::Comment) - { - *token = {}; - tokeniser->tokens_len--; - } - else - { - if (lexing_function) - { - if (started_lexing_function && paren_level == 0) - break; - } - else - { - if (started_lexing_brace_scope && indent_level == 0) - break; - } - } - } - } - - return ptr; -} - -void FprintDeclType(FILE *output_file, Slice const type, Slice const template_child_expr) -{ - Slice const array[] = - { - type, - template_child_expr - }; - - for (int array_index = 0; array_index < ArrayCount(array); ++array_index) - { - Slice const *slice = array + array_index; - if (array_index > 0 && slice->len > 0) - fputc('_', output_file); - - for (int i = 0; i < slice->len; ++i) - { - char ch = slice->str[i]; - if (ch == '*') - { - char prev_ch = slice->str[i - 1]; - if (prev_ch != ' ' && prev_ch != '*') fputc('_', output_file); - - fputs("Ptr", output_file); - if (i < (slice->len - 1)) fputc('_', output_file); - } - else - { - if (ch != '>') - { - if (ch == ' ' || ch == '<') ch = '_'; - fputc(ch, output_file); - } - } - } - } - - fputc('_', output_file); -} - -int main(int argc, char *argv[]) -{ - if (argc < 1) - { - fprintf(stdout, - "Usage: %s [code|generate_prototypes] [, ...]\n" - "Options: If ommitted, both modes are run\n" - " code Only generate the inspection data for structs/enums marked with DQN_INSPECT\n" - " generate_prototypes Only generate the function prototypes for functions marked with DQN_INSPECT_GENERATE_PROTOTYPE(...)\n", - argv[0]); - return 0; - } - - usize starting_arg_index = 1; - char const *mode_str = argv[1]; - InspectMode mode = InspectMode::All; - if (strcmp(mode_str, "code") == 0) mode = InspectMode::Code; - else if (strcmp(mode_str, "function") == 0) mode = InspectMode::Function; - - if (mode != InspectMode::All) - starting_arg_index++; - - usize main_arena_mem_size = MEGABYTE(8); - void *main_arena_mem = malloc(main_arena_mem_size); - global_main_arena = MemArena_Init(main_arena_mem, main_arena_mem_size); -#if 0 - FILE *output_file = fopen("DqnInspect_Generated.cpp", "w"); -#else - FILE *output_file = stdout; -#endif - - fprintf(output_file, - "// This is an auto generated file using DqnInspect\n\n"); - - if (mode == InspectMode::All || mode == InspectMode::Code) - { - fprintf(output_file, - " // NOTE: These macros are undefined at the end of the file so to not pollute namespace\n" - "#define ARRAY_COUNT(array) sizeof(array)/sizeof((array)[0])\n" - "#define CHAR_COUNT(str) (ARRAY_COUNT(str) - 1)\n" - "#define STR_AND_LEN(str) str, CHAR_COUNT(str)\n" - "\n" - ); - } - - std::vector parsing_results_per_file = {}; - parsing_results_per_file.reserve(64); - - for (usize arg_index = starting_arg_index; arg_index < argc; ++arg_index) - { - char *file_name = argv[arg_index]; - FILE *file = fopen(file_name, "rb"); - fseek(file, 0, SEEK_END); - usize file_size = ftell(file); - rewind(file); - - char *file_buf = (char *)MemArena_Alloc(&global_main_arena, file_size + 1); - file_buf[file_size] = 0; - - if (fread(file_buf, file_size, 1, file) != 1) - { - fprintf(stderr, "Failed to fread: %zu bytes into buffer from file: %s\n", file_size, file_name); - continue; - } - - ParsingResult parsing_results = {}; - parsing_results.code.reserve(128); - int const file_name_len = (int)strlen(file_name); - { - char *extracted_file_name_buf = static_cast(MemArena_Alloc(&global_main_arena, file_name_len)); - int extracted_file_name_len = 0; - - for (int i = file_name_len - 1; i >= 0; i--, extracted_file_name_len++) - { - char ch = file_name[i]; - if (ch == '.') - ch = '_'; - - if (ch >= 'a' && ch <= 'z') ch -= 'a' - 'A'; - - if (ch == '\\' || ch == '/') - break; - - extracted_file_name_buf[i] = ch; - } - - parsing_results.file_include_contents_hash_define = extracted_file_name_buf + file_name_len - extracted_file_name_len; - parsing_results.file_include_contents_hash_define_len = extracted_file_name_len; - parsing_results.file_name = Slice(file_name, file_name_len); - } - - CPPTokeniser tokeniser = {}; - tokeniser.tokens_max = 16384; - tokeniser.tokens = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, CPPToken, tokeniser.tokens_max); - - Slice const INSPECT_FUNCTION = SLICE_LITERAL("DQN_INSPECT_FUNCTION"); - Slice const INSPECT_PREFIX = SLICE_LITERAL("DQN_INSPECT"); - char *file_buf_end = file_buf + file_size; - Slice buffer = Slice(file_buf, static_cast(file_size)); - - for (char *ptr = StrFind(buffer, INSPECT_PREFIX); - ptr; - ptr = StrFind(buffer, INSPECT_PREFIX)) - { - char *marker_str = ptr; - int marker_len = static_cast(file_buf_end - ptr); - - DEFER - { - buffer.str = ptr; - buffer.len = static_cast(file_buf_end - ptr); - }; - - CPPTokenType inspect_type = CPPTokenType::InspectCode; - if (Slice_Cmp(Slice(ptr, INSPECT_FUNCTION.len), INSPECT_FUNCTION)) - { - inspect_type = CPPTokenType::InspectFunction; - } - - if (inspect_type == CPPTokenType::InspectCode) - { - ptr += INSPECT_PREFIX.len; - if (mode == InspectMode::Function) continue; - } - else - { - ptr += INSPECT_FUNCTION.len; - if (mode == InspectMode::Code) continue; - } - - CPPToken *inspect_token = CPPTokeniser_MakeToken(&tokeniser); - inspect_token->type = inspect_type; - inspect_token->str = marker_str; - inspect_token->len = marker_len; - ptr = EnumOrStructOrFunctionLexer(&tokeniser, ptr, inspect_type == CPPTokenType::InspectFunction); - - } - - CPPToken *sentinel = CPPTokeniser_MakeToken(&tokeniser); - sentinel->type = CPPTokenType::EndOfStream; - - for (CPPToken token = CPPTokeniser_PeekToken(&tokeniser); - ; - token = CPPTokeniser_PeekToken(&tokeniser)) - { - ParsedCode parsed_code = {}; - if (token.type == CPPTokenType::InspectCode || token.type == CPPTokenType::InspectFunction) - { - if (token.type == CPPTokenType::InspectCode) - { - token = CPPTokeniser_NextToken(&tokeniser); - token = CPPTokeniser_PeekToken(&tokeniser); - - if (IsIdentifierToken(token, SLICE_LITERAL("enum"))) - { - if (ParseCPPEnum(&tokeniser, &parsed_code.parsed_enum)) - parsed_code.type = ParsedCodeType::Enum; - } - else if (IsIdentifierToken(token, SLICE_LITERAL("struct")) || IsIdentifierToken(token, SLICE_LITERAL("class"))) - { - if (ParseCPPStruct(&tokeniser, &parsed_code.parsed_struct)) - parsed_code.type = ParsedCodeType::Struct; - } - } - else - { - if (ParseCPPInspectFunction(&tokeniser, &parsed_code.parsed_func)) - { - parsed_code.type = ParsedCodeType::Function; - parsing_results.max_func_return_type_decl_len = INSPECT_MAX(parsing_results.max_func_return_type_decl_len, parsed_code.parsed_func.return_type.len); - parsing_results.max_func_name_decl_len = INSPECT_MAX(parsing_results.max_func_name_decl_len, parsed_code.parsed_func.name.len); - } - } - } - else - { - token = CPPTokeniser_NextToken(&tokeniser); - } - - if (parsed_code.type != ParsedCodeType::Invalid) - parsing_results.code.push_back(parsed_code); - - if (token.type == CPPTokenType::EndOfStream) - break; - } - parsing_results_per_file.push_back(std::move(parsing_results)); - } - - int indent_level = 0; - if (mode == InspectMode::All || mode == InspectMode::Code) - { - // - // NOTE: Build the global definition table - // - { - std::set> member_type_table; - for (ParsingResult &parsing_results : parsing_results_per_file) - { - for (ParsedCode &code : parsing_results.code) - { - switch(code.type) - { - case ParsedCodeType::Enum: - { - ParsedEnum const *parsed_enum = &code.parsed_enum; - member_type_table.insert(parsed_enum->name); - for (CPPDeclLinkedList> const *link = parsed_enum->members; - link; - link = link->next) - { - Slice entry = Asprintf(&global_main_arena, "%.*s_%.*s", - parsed_enum->name.len, parsed_enum->name.str, - link->value.len, link->value.str - ); - member_type_table.insert(entry); - } - - } - break; - - case ParsedCodeType::Struct: - { - ParsedStruct const *parsed_struct = &code.parsed_struct; - member_type_table.insert(parsed_struct->name); - for (CPPDeclLinkedList const *link = parsed_struct->members; - link; - link = link->next) - { - Slice entry = Asprintf(&global_main_arena, "%.*s_%.*s", - parsed_struct->name.len, parsed_struct->name.str, - link->value.name.len, link->value.name.str - ); - member_type_table.insert(entry); - } - } - break; - } - } - } - - FprintfIndented(output_file, indent_level, "enum struct DqnInspectMemberType\n{\n"); - indent_level++; - for (Slice const &member : member_type_table) - { - FprintfIndented(output_file, indent_level, "%.*s,\n", member.len, member.str); - } - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - // - // NOTE: Build the global type table - // - { - std::set> unique_decl_type_table; - for (ParsingResult &parsing_results : parsing_results_per_file) - { - for (ParsedCode &code : parsing_results.code) - { - switch(code.type) - { - case ParsedCodeType::Enum: - { - ParsedEnum const *parsed_enum = &code.parsed_enum; - unique_decl_type_table.insert(parsed_enum->name); - } - break; - - case ParsedCodeType::Struct: - { - ParsedStruct const *parsed_struct = &code.parsed_struct; - unique_decl_type_table.insert(parsed_struct->name); - - for (CPPDeclLinkedList const *link = parsed_struct->members; - link; - link = link->next) - { - CPPVariableDecl const *decl = &link->value; - - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s", decl->type.len, decl->type.str)); - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s", decl->type_without_ptr_const_modifiers.len, decl->type_without_ptr_const_modifiers.str)); - if (decl->template_child_expr.len > 0) - { - if (!CharIsDigit(decl->template_child_expr.str[0])) - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s", decl->template_child_expr.len, decl->template_child_expr.str)); - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s<%.*s>", decl->type.len, decl->type.str, decl->template_child_expr.len, decl->template_child_expr.str)); - } - - for (CPPDeclLinkedList const *meta_link = link->metadata_list; - meta_link; - meta_link = meta_link->next) - { - CPPVariableDecl const *meta_decl = &meta_link->value; - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s", meta_decl->type.len, meta_decl->type.str)); - if (meta_decl->template_child_expr.len > 0) - { - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s", meta_decl->template_child_expr.len, meta_decl->template_child_expr.str)); - unique_decl_type_table.insert(Asprintf(&global_main_arena, "%.*s<%.*s>", meta_decl->type.len, meta_decl->type.str, meta_decl->template_child_expr.len, meta_decl->template_child_expr.str)); - } - } - } - } - break; - } - } - } - - FprintfIndented(output_file, indent_level, "enum struct DqnInspectDeclType\n{\n"); - indent_level++; - FprintfIndented(output_file, indent_level, "NotAvailable_,\n"); - for (Slice const &type : unique_decl_type_table) - { - FprintfIndented(output_file, indent_level, ""); - FprintDeclType(output_file, type, {}); - fprintf(output_file, ",\n"); - } - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - // - // NOTE: Build the global metadata type table - // - { - std::set> unique_meta_types; - for (ParsingResult &parsing_results : parsing_results_per_file) - { - for (ParsedCode &code : parsing_results.code) - { - switch(code.type) - { - case ParsedCodeType::Struct: - { - ParsedStruct const *parsed_struct = &code.parsed_struct; - for (CPPDeclLinkedList const *member = parsed_struct->members; member; member = member->next) - { - for (CPPDeclLinkedList const *metadata_link = member->metadata_list; - metadata_link; - metadata_link = metadata_link->next) - { - CPPVariableDecl const *metadata = &metadata_link->value; - unique_meta_types.insert(metadata->name); - } - } - } - break; - } - } - } - - FprintfIndented(output_file, indent_level, "enum struct DqnInspectMetaType\n{\n"); - indent_level++; - for (Slice const &metadata : unique_meta_types) - FprintfIndented(output_file, indent_level, "%.*s,\n", metadata.len, metadata.str); - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - } - - assert(indent_level == 0); - size_t unique_id = 0; - for (ParsingResult &parsing_results : parsing_results_per_file) - { - fprintf(output_file, - "//\n" - "// %.*s\n" - "//\n" - "\n" - "#if !defined(DQN_INSPECT_DISABLE_%.*s) && !defined(DQN_INSPECT_%.*s)\n" - "#define DQN_INSPECT_%.*s\n" - "\n", - parsing_results.file_name.len, - parsing_results.file_name.str, - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define, - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define, - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define - ); - - for (ParsedCode &code : parsing_results.code) - { - switch(code.type) - { - case ParsedCodeType::Enum: - { - ParsedEnum const *parsed_enum = &code.parsed_enum; - // - // NOTE: Write Stringified Enum Array - // - { - FprintfIndented(output_file, indent_level, "char const *DqnInspect_%.*s_Strings[] = {", parsed_enum->name.len, parsed_enum->name.str); - indent_level++; - for (CPPDeclLinkedList> const *link = parsed_enum->members; link; link = link->next) - { - Slice const enum_value = link->value; - fprintf(output_file, "\"%.*s\", ", enum_value.len, enum_value.str); - } - - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - // - // NOTE: Write DqnInspectEnum_Stringify Function - // - { - FprintfIndented(output_file, indent_level, "char const *DqnInspectEnum_Stringify(%.*s val, int *len = nullptr)\n{\n", parsed_enum->name.len, parsed_enum->name.str); - indent_level++; - DEFER - { - FprintfIndented(output_file, indent_level, "return nullptr;\n"); - indent_level--; - FprintfIndented(output_file, indent_level, "}\n\n"); - }; - - struct SourceCode - { - Slice decl; - Slice enum_value; - }; - - LinkedList src_code = {}; - int longest_decl_len = 0; - { - LinkedList *curr_src_code = nullptr; - char const *fmt = (parsed_enum->struct_or_class_decl) ? "if (val == %.*s::%.*s) " : "if (val == %.*s) "; - for (CPPDeclLinkedList> *link = parsed_enum->members; link; link = link->next) - { - if (!curr_src_code) curr_src_code = &src_code; - else - { - curr_src_code->next = static_cast *>(MemArena_Alloc(&global_main_arena, sizeof(*curr_src_code))); - curr_src_code = curr_src_code->next; - } - - Slice enum_value = link->value; - int required_len = 0; - - if (parsed_enum->struct_or_class_decl) required_len = snprintf(nullptr, 0, fmt, parsed_enum->name.len, parsed_enum->name.str, enum_value.len, enum_value.str) + 1; - else required_len = snprintf(nullptr, 0, fmt, enum_value.len, enum_value.str) + 1; - - longest_decl_len = INSPECT_MAX(longest_decl_len, required_len); - curr_src_code->value.decl.str = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, char, required_len); - curr_src_code->value.decl.len = required_len; - curr_src_code->value.enum_value = enum_value; - - if (parsed_enum->struct_or_class_decl) snprintf(curr_src_code->value.decl.str, curr_src_code->value.decl.len, fmt, parsed_enum->name.len, parsed_enum->name.str, enum_value.len, enum_value.str); - else snprintf(curr_src_code->value.decl.str, curr_src_code->value.decl.len, fmt, enum_value.len, enum_value.str); - } - curr_src_code->next = nullptr; - } - - int enum_index = 0; - for (LinkedList *src_code_ptr = &src_code; - src_code_ptr; - src_code_ptr = src_code_ptr->next, ++enum_index) - { - Slice enum_value = src_code_ptr->value.enum_value; - int padding = longest_decl_len - src_code_ptr->value.decl.len; - FprintfIndented(output_file, indent_level, "%.*s%*s", src_code_ptr->value.decl.len, src_code_ptr->value.decl.str, padding, ""); - fprintf(output_file, - "{ if (len) *len = CHAR_COUNT(\"%.*s\"); return DqnInspect_%.*s_Strings[%d]; }\n", - enum_value.len, enum_value.str, - parsed_enum->name.len, parsed_enum->name.str, - enum_index); - } - } - - // - // NOTE: Write DqnInspectEnum_Count Function - // - { - int count = 0; - for (CPPDeclLinkedList> *link = parsed_enum->members; link; link = link->next) count++; - FprintfIndented(output_file, indent_level, "constexpr int DqnInspectEnum_Count(%.*s) { return %d; }\n\n", parsed_enum->name.len, parsed_enum->name.str, count); - } - - // - // NOTE: Write User Annotated Metadata Getter Functions - // - { - struct CPPDeclToMetaValue - { - Slice cpp_decl; - Slice value; - }; - - // i.e. DataType cpp_decl DQN_INSPECT_META(type1 name1 = value, type2 name2 = value2, ...); - struct MetadataEntry - { - Slice type; - Slice name; - FixedArray cpp_decl_to_val; - }; - - FixedArray metadata_entries = {}; - for (CPPDeclLinkedList> *link = parsed_enum->members; - link; - link = link->next) - { - for (CPPDeclLinkedList const *metadata_link = link->metadata_list; - metadata_link; - metadata_link = metadata_link->next) - { - MetadataEntry *metadata_entry_to_append_to = nullptr; - for (MetadataEntry &check_metadata_entry : metadata_entries) - { - if (Slice_Cmp(check_metadata_entry.type, metadata_link->value.type) && Slice_Cmp(check_metadata_entry.name, metadata_link->value.name)) - { - metadata_entry_to_append_to = &check_metadata_entry; - break; - } - } - - if (!metadata_entry_to_append_to) - { - metadata_entry_to_append_to = FixedArray_Make(&metadata_entries, 1); - metadata_entry_to_append_to->type = metadata_link->value.type; - metadata_entry_to_append_to->name = metadata_link->value.name; - } - - CPPDeclToMetaValue decl_to_val = {}; - decl_to_val.cpp_decl = Slice(link->value.str, link->value.len); - decl_to_val.value = metadata_link->value.default_value; - FixedArray_Add(&metadata_entry_to_append_to->cpp_decl_to_val, decl_to_val); - } - } - - for (MetadataEntry const &metadata : metadata_entries) - { - Slice const char_type = SLICE_LITERAL("char"); - Slice const bool_types[] = - { - SLICE_LITERAL("bool"), - SLICE_LITERAL("b32"), - }; - - b32 is_char_type = (metadata.type.len >= char_type.len && strncmp(metadata.type.str, char_type.str, char_type.len) == 0); - b32 is_bool_type = false; - for (size_t i = 0; i < ArrayCount(bool_types) && !is_char_type; i++) - { - Slice const *bool_type = bool_types + i; - is_bool_type = (metadata.type.len >= bool_type->len && strncmp(metadata.type.str, bool_type->str, bool_type->len) == 0); - if (is_bool_type) break; - } - - if (is_char_type || is_bool_type) - { - FprintfIndented(output_file, indent_level, - "%.*s DqnInspectMetadata_%.*s(%.*s val)\n{\n", - metadata.type.len, metadata.type.str, - metadata.name.len, metadata.name.str, - parsed_enum->name.len, parsed_enum->name.str); - - indent_level++; - DEFER - { - if (is_char_type) - FprintfIndented(output_file, indent_level, "return nullptr;\n"); - else - FprintfIndented(output_file, indent_level, "return false;\n"); - indent_level--; - FprintfIndented(output_file, indent_level, "}\n\n"); - }; - - for (CPPDeclToMetaValue const &decl_to_val : metadata.cpp_decl_to_val) - { - Slice const *cpp_decl = &decl_to_val.cpp_decl; - Slice const *value = &decl_to_val.value; - - if (parsed_enum->struct_or_class_decl) - { - FprintfIndented(output_file, indent_level, - "if (val == %.*s::%.*s) ", - parsed_enum->name.len, parsed_enum->name.str, - cpp_decl->len, cpp_decl->str); - } - else - { - FprintfIndented(output_file, indent_level, - "if (val == %.*s) ", - cpp_decl->len, cpp_decl->str); - } - fprintf(output_file, "{ return %.*s; }\n", value->len, value->str); - } - } - else - { - FprintfIndented(output_file, indent_level, - "bool DqnInspectMetadata_%.*s(%.*s val, %.*s *value = nullptr)\n{\n", - metadata.name.len, metadata.name.str, - parsed_enum->name.len, parsed_enum->name.str, - metadata.type.len, metadata.type.str - ); - - indent_level++; - DEFER - { - FprintfIndented(output_file, indent_level, "return false;\n"); - indent_level--; - FprintfIndented(output_file, indent_level, "}\n\n"); - }; - - for (CPPDeclToMetaValue const &decl_to_val : metadata.cpp_decl_to_val) - { - Slice const *cpp_decl = &decl_to_val.cpp_decl; - Slice const *value = &decl_to_val.value; - - if (parsed_enum->struct_or_class_decl) - { - FprintfIndented(output_file, indent_level, - "if (val == %.*s::%.*s) ", - parsed_enum->name.len, parsed_enum->name.str, - cpp_decl->len, cpp_decl->str); - } - else - { - FprintfIndented(output_file, indent_level, - "if (val == %.*s) ", - cpp_decl->len, cpp_decl->str); - } - fprintf(output_file, "{ *value = %.*s; return true; }\n", value->len, value->str); - } - } - - } - } - } - break; - - case ParsedCodeType::Struct: - { - ParsedStruct const *parsed_struct = &code.parsed_struct; - // - // NOTE: Write Metadata Global Variables - // - for (CPPDeclLinkedList const *member = parsed_struct->members; member; member = member->next) - { - CPPVariableDecl const *decl = &member->value; - for (CPPDeclLinkedList const *metadata_link = member->metadata_list; - metadata_link; - metadata_link = metadata_link->next) - { - CPPVariableDecl const *metadata = &metadata_link->value; - FprintfIndented(output_file, indent_level, - "%.*s DqnInspectMetadata_%.*s_%.*s_%.*s = %.*s;\n", - metadata->type.len, metadata->type.str, - parsed_struct->name.len, parsed_struct->name.str, - decl->name.len, decl->name.str, - metadata->name.len, metadata->name.str, - metadata->default_value.len, metadata->default_value.str - ); - } - } - FprintfIndented(output_file, indent_level, "\n"); - - // - // NOTE: Write metadata for each member - // - for (CPPDeclLinkedList const *member = parsed_struct->members; member; member = member->next) - { - CPPVariableDecl const *decl = &member->value; - - if (!member->metadata_list) - continue; - - FprintfIndented(output_file, indent_level, - "DqnInspectMetadata const DqnInspectMetadata_%.*s_%.*s[] =\n{\n", - parsed_struct->name.len, parsed_struct->name.str, - decl->name.len, decl->name.str - ); - - indent_level++; - for (CPPDeclLinkedList const *metadata_link = member->metadata_list; - metadata_link; - metadata_link = metadata_link->next) - { - CPPVariableDecl const *metadata = &metadata_link->value; - FprintfIndented(output_file, indent_level, "{ DqnInspectDeclType::"); - FprintDeclType(output_file, metadata->type, metadata->template_child_expr); - fprintf(output_file, - ", DqnInspectMetaType::%.*s, &DqnInspectMetadata_%.*s_%.*s_%.*s},\n", - metadata->name.len, metadata->name.str, - - // NOTE: Assign variant data to void *, &DqnInspectMetdata ... - parsed_struct->name.len, parsed_struct->name.str, - decl->name.len, decl->name.str, - metadata->name.len, metadata->name.str - ); - } - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - - // - // NOTE: Write DqnInspectMember Definition - // - { - FprintfIndented(output_file, indent_level, "DqnInspectMember const DqnInspect_%.*s_Members[] =\n{\n", parsed_struct->name.len, parsed_struct->name.str); - indent_level++; - - for (CPPDeclLinkedList const *member = parsed_struct->members; member; member = member->next) - { - CPPVariableDecl const *decl = &member->value; - FprintfIndented(output_file, indent_level, "{\n"); - indent_level++; - - FprintfIndented(output_file, indent_level, "%zu, // id\n", unique_id++); - FprintfIndented(output_file, indent_level, "DqnInspectMemberType::%.*s_%.*s, ", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - fprintf(output_file, "STR_AND_LEN(\"%.*s\"),\n", decl->name.len, decl->name.str); - - // NOTE: Write pod_struct_offset - { - FprintfIndented(output_file, indent_level, "offsetof(%.*s, %.*s),\n", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - } - - // NOTE: Write base_decl_type - { - FprintfIndented(output_file, indent_level, "DqnInspectDeclType::"); - FprintDeclType(output_file, decl->type_without_ptr_const_modifiers, {}); - - // NOTE: Write base_decl_type_str, base_decl_type_len - fprintf(output_file, ", STR_AND_LEN(\"%.*s\"),\n", decl->type_without_ptr_const_modifiers.len, decl->type_without_ptr_const_modifiers.str); - } - - - // NOTE: Write decl_type - { - FprintfIndented(output_file, indent_level, "DqnInspectDeclType::"); - FprintDeclType(output_file, decl->type, decl->template_child_expr); - } - - // NOTE: Write decl_type_str, decl_type_len - { - if (decl->template_child_expr.len > 0) - fprintf(output_file, ", STR_AND_LEN(\"%.*s<%.*s>\"),\n", decl->type.len, decl->type.str, decl->template_child_expr.len, decl->template_child_expr.str); - else - fprintf(output_file, ", STR_AND_LEN(\"%.*s\"),\n", decl->type.len, decl->type.str); - } - - // NOTE: Write decl_type_sizeof - { - FprintfIndented(output_file, indent_level, "sizeof(((%.*s *)0)->%.*s), // full_decl_type_sizeof\n", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - } - - // NOTE: Write template_parent_decl_type - { - FprintfIndented(output_file, indent_level, "DqnInspectDeclType::"); - FprintDeclType(output_file, decl->type, {}); - fprintf(output_file, ", "); - } - - // NOTE: Write template_decl_type - { - if (decl->template_child_expr.len > 0 && !CharIsDigit(decl->template_child_expr.str[0])) - { - fprintf(output_file, "DqnInspectDeclType::"); - FprintDeclType(output_file, decl->template_child_expr, {}); - } - else - { - fprintf(output_file, "DqnInspectDeclType::NotAvailable_"); - } - fprintf(output_file, ",\n"); - } - - // NOTE: Write template_child_expr, template_child_expr_len - { - if (decl->template_child_expr.len > 0) - FprintfIndented(output_file, indent_level, "STR_AND_LEN(\"%.*s\"), // template_child_expr\n", decl->template_child_expr.len, decl->template_child_expr.str); - else - FprintfIndented(output_file, indent_level, "nullptr, 0, // template_child_expr and template_child_expr_len\n"); - } - - FprintfIndented(output_file, indent_level, "%d, // array_dimensions\n", decl->array_dimensions); - - FprintfIndented(output_file, indent_level, "{"); - for (int dimensions_index = 0; - dimensions_index < ArrayCount(decl->array_dimensions_has_compile_time_size); - ++dimensions_index) - { - bool has_compile_time_size = decl->array_dimensions_has_compile_time_size[dimensions_index]; - if (has_compile_time_size) - { - fprintf(output_file, "ARRAY_COUNT(((%.*s *)0)->%.*s)", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - } - else - { - fputc('0', output_file); - } - - if (dimensions_index < ArrayCount(decl->array_dimensions_has_compile_time_size) - 1) - fputs(", ", output_file); - } - fprintf(output_file, "}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown,\n"); - - if (member->metadata_list) - { - FprintfIndented(output_file, indent_level, "DqnInspectMetadata_%.*s_%.*s, ", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - fprintf(output_file, "ARRAY_COUNT(DqnInspectMetadata_%.*s_%.*s),", parsed_struct->name.len, parsed_struct->name.str, decl->name.len, decl->name.str); - } - else - { - FprintfIndented(output_file, indent_level, "nullptr, 0,"); - } - fprintf(output_file, " // metadata array\n"); - - indent_level--; - FprintfIndented(output_file, indent_level, "},\n"); - } - - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - } - - // - // NOTE: Write DqnInspect_Struct Definition - // - { - FprintfIndented(output_file, indent_level, "DqnInspectStruct const DqnInspect_%.*s_Struct =\n{\n", parsed_struct->name.len, parsed_struct->name.str); - indent_level++; - - FprintfIndented(output_file, indent_level, "%zu, // id\n", unique_id++); - FprintfIndented(output_file, indent_level, "STR_AND_LEN(\"%.*s\"),\n", parsed_struct->name.len, parsed_struct->name.str); - FprintfIndented(output_file, indent_level, "DqnInspect_%.*s_Members, // members\n", parsed_struct->name.len, parsed_struct->name.str); - FprintfIndented(output_file, indent_level, "ARRAY_COUNT(DqnInspect_%.*s_Members) // members_len\n", parsed_struct->name.len, parsed_struct->name.str); - - indent_level--; - FprintfIndented(output_file, indent_level, "};\n\n"); - assert(indent_level == 0); - } - - // - // NOTE: Write DqnInspect_Struct getter - // - { - FprintfIndented(output_file, indent_level, "DqnInspectStruct const *DqnInspect_Struct(%.*s const *)\n", parsed_struct->name.len, parsed_struct->name.str); - FprintfIndented(output_file, indent_level, "{\n"); - indent_level++; - FprintfIndented(output_file, indent_level, "DqnInspectStruct const *result = &DqnInspect_%.*s_Struct;\n", parsed_struct->name.len, parsed_struct->name.str); - FprintfIndented(output_file, indent_level, "return result;\n"); - indent_level--; - FprintfIndented(output_file, indent_level, "}\n\n"); - } - } - break; - - case ParsedCodeType::Function: - { - ParsedFunction *parsed_func = &code.parsed_func; - if (parsed_func->has_comments) - { - for (LinkedList> const *comment_link = &parsed_func->comments; - comment_link; - comment_link = comment_link->next) - { - Slice const comment = comment_link->value; - if (comment.len == 0) fprintf(output_file, "//\n"); - else fprintf(output_file, "// %.*s\n", comment.len, comment.str); - } - } - - { - Slice return_type = parsed_func->return_type; - Slice func_name = parsed_func->name; - - int spaces_remaining = parsing_results.max_func_return_type_decl_len - return_type.len; - FprintfIndented(output_file, indent_level, "%.*s ", return_type.len, return_type.str); - for (int i = 0; i < spaces_remaining; ++i) fprintf(output_file, " "); - - spaces_remaining = parsing_results.max_func_name_decl_len - func_name.len; - FprintfIndented(output_file, indent_level, "%.*s", func_name.len, func_name.str); - for (int i = 0; i < spaces_remaining; ++i) fprintf(output_file, " "); - - FprintfIndented(output_file, indent_level, "("); - } - - for (CPPDeclLinkedList *param_link = parsed_func->members; param_link; param_link = param_link->next) - { - CPPVariableDecl *decl = ¶m_link->value; - fprintf(output_file, "%.*s", decl->type.len, decl->type.str); - - if (decl->name.len > 0) - fprintf(output_file, " %.*s", decl->name.len, decl->name.str); - - if (decl->default_value.len > 0) - fprintf(output_file, " = %.*s", decl->default_value.len, decl->default_value.str); - - if (param_link->next) - fprintf(output_file, ", "); - } - fprintf(output_file, ");\n"); - } - break; - } - } - - fprintf(output_file, "\n#endif // DQN_INSPECT_%.*s\n\n", - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define); - } - - // - // NOTE: After all the definitions have been written, write the function - // that maps the member_type to the DqnInspectStruct's declared above - // - if (mode == InspectMode::All || mode == InspectMode::Code) - { - FprintfIndented(output_file, indent_level, "DqnInspectStruct const *DqnInspect_Struct(DqnInspectDeclType type)\n{\n"); - indent_level++; - FprintfIndented(output_file, indent_level, "(void)type;\n"); - - for (ParsingResult &parsing_results : parsing_results_per_file) - { - fprintf(output_file, - "#ifdef DQN_INSPECT_%.*s\n", - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define - ); - - for (ParsedCode &code : parsing_results.code) - { - switch(code.type) - { - case ParsedCodeType::Struct: - { - ParsedStruct const *parsed_struct = &code.parsed_struct; - FprintfIndented(output_file, indent_level, "if (type == DqnInspectDeclType::%.*s_) return &DqnInspect_%.*s_Struct;\n", parsed_struct->name.len, parsed_struct->name.str, parsed_struct->name.len, parsed_struct->name.str); - } - break; - } - } - - fprintf(output_file, "#endif // DQN_INSPECT_%.*s\n\n", - parsing_results.file_include_contents_hash_define_len, - parsing_results.file_include_contents_hash_define); - } - FprintfIndented(output_file, indent_level, "return nullptr;\n"); - indent_level--; - FprintfIndented(output_file, indent_level, "}\n\n"); - - fprintf(output_file, - "\n#undef ARRAY_COUNT\n" - "#undef CHAR_COUNT\n" - "#undef STR_AND_LEN\n"); - } - - fclose(output_file); - - return 0; -} - -#endif // DQN_INSPECT_EXECUTABLE_IMPLEMENTATION -#endif // DQN_INSPECT_H - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2019 doy-lee -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------- -*/ - -#undef _CRT_SECURE_NO_WARNINGS diff --git a/Data/DqnInspect_TestData.h b/Data/DqnInspect_TestData.h deleted file mode 100644 index 373754e..0000000 --- a/Data/DqnInspect_TestData.h +++ /dev/null @@ -1,53 +0,0 @@ -struct V3 { - V3(float a, float b, float c) { (void)a; (void)b; (void)c; } - float a, b, c; -}; -struct V4 { float test; }; - -template -struct Array { T data[Size]; }; - -enum struct OpenGLShader { Vertex, Count, }; - -DQN_INSPECT struct SampleStruct -{ - int ebo DQN_INSPECT_META(char const *DisplayName = "Element Buffer Object"), vbo, vao DQN_INSPECT_META(char const *DisplayName = "Vertex Array Object", int OpenGLVersion = 330); - const int *const a; - int const *const b, c, *d, *e; - V4 draw_color DQN_INSPECT_META(char const *DisplayName = "HelloWorld"); -// #if 0 -// #endif - Array lights; - Array camera_matrixes; - char **bitmaps; - int shaders[(int)OpenGLShader::Count]; - void *win32_handle; - V3 lighting_ambient_coeff; - int draw_call_count; - - const int f; - int const g; - int *const h; - int const* i; - int ****const j, k, **l, *m; - -}; - -DQN_INSPECT enum struct EnumWithMetadata -{ - Rect DQN_INSPECT_META(char const *FilePath = "Rect.vert", V3 Coords = V3(1, 2, 3)), - Square DQN_INSPECT_META(char const *FilePath = "Square.vert"), - Count, -}; - -DQN_INSPECT_FUNCTION(b = {}, c = nullptr, e = false, f = 1, g = "Hello world") -void Function1(int a, float b, char const *c, bool e, int f, char *g) -{ - (void)a; (void)b; (void)c; (void)e; (void)f; (void)g; -} - -DQN_INSPECT_FUNCTION(foo = V3(10, 20, 50), bar = {120, 150, 20}) -void *Function2(V3 foo, V3 bar, ...) { (void)foo; (void)bar; return nullptr; } - -DQN_INSPECT_FUNCTION() -Array const *const Function3(Array const *foobar) { (void)foobar; return {}; } diff --git a/Data/DqnInspect_TestDataGenerated.cpp b/Data/DqnInspect_TestDataGenerated.cpp deleted file mode 100644 index 4555d77..0000000 --- a/Data/DqnInspect_TestDataGenerated.cpp +++ /dev/null @@ -1,425 +0,0 @@ -// This is an auto generated file using DqnInspect - - // NOTE: These macros are undefined at the end of the file so to not pollute namespace -#define ARRAY_COUNT(array) sizeof(array)/sizeof((array)[0]) -#define CHAR_COUNT(str) (ARRAY_COUNT(str) - 1) -#define STR_AND_LEN(str) str, CHAR_COUNT(str) - -enum struct DqnInspectMemberType -{ - SampleStruct, - SampleStruct_a, - SampleStruct_b, - SampleStruct_c, - SampleStruct_d, - SampleStruct_e, - SampleStruct_f, - SampleStruct_g, - SampleStruct_h, - SampleStruct_i, - SampleStruct_j, - SampleStruct_k, - SampleStruct_l, - SampleStruct_m, - EnumWithMetadata, - SampleStruct_ebo, - SampleStruct_vao, - SampleStruct_vbo, - SampleStruct_lights, - SampleStruct_bitmaps, - SampleStruct_shaders, - EnumWithMetadata_Rect, - EnumWithMetadata_Count, - EnumWithMetadata_Square, - SampleStruct_draw_color, - SampleStruct_win32_handle, - SampleStruct_camera_matrixes, - SampleStruct_draw_call_count, - SampleStruct_lighting_ambient_coeff, -}; - -enum struct DqnInspectDeclType -{ - NotAvailable_, - V3_, - V4_, - int_, - Array_, - int_Ptr_, - V3,_32_, - V4,_32_, - int_Ptr_Ptr_, - void_Ptr_, - char_Ptr_Ptr_, - int_const_, - int_Ptr_const_, - int_const_Ptr_, - SampleStruct_, - char_const_Ptr_, - Array_V3,_32_, - Array_V4,_32_, - int_Ptr_Ptr_Ptr_Ptr_const_, - EnumWithMetadata_, - int_const_Ptr_const_, -}; - -enum struct DqnInspectMetaType -{ - DisplayName, - OpenGLVersion, -}; - -// -// ..\Data\DqnInspect_TestData.h -// - -#ifndef DQN_INSPECT_DQNINSPECT_TESTDATA_H -#define DQN_INSPECT_DQNINSPECT_TESTDATA_H - -char const * DqnInspectMetadata_SampleStruct_ebo_DisplayName = "Element Buffer Object"; -char const * DqnInspectMetadata_SampleStruct_vao_DisplayName = "Vertex Array Object"; -int DqnInspectMetadata_SampleStruct_vao_OpenGLVersion = 330; -char const * DqnInspectMetadata_SampleStruct_draw_color_DisplayName = "HelloWorld"; - -DqnInspectMetadata const DqnInspectMetadata_SampleStruct_ebo[] = -{ - { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_ebo_DisplayName}, -}; - -DqnInspectMetadata const DqnInspectMetadata_SampleStruct_vao[] = -{ - { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_vao_DisplayName}, - { DqnInspectDeclType::int_, DqnInspectMetaType::OpenGLVersion, &DqnInspectMetadata_SampleStruct_vao_OpenGLVersion}, -}; - -DqnInspectMetadata const DqnInspectMetadata_SampleStruct_draw_color[] = -{ - { DqnInspectDeclType::char_const_Ptr_, DqnInspectMetaType::DisplayName, &DqnInspectMetadata_SampleStruct_draw_color_DisplayName}, -}; - -DqnInspectMember const DqnInspect_SampleStruct_Members[] = -{ - { - DqnInspectMemberType::SampleStruct_ebo, STR_AND_LEN("ebo"), - offsetof(SampleStruct, ebo), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->ebo), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - DqnInspectMetadata_SampleStruct_ebo, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_ebo), // metadata array - }, - { - DqnInspectMemberType::SampleStruct_vbo, STR_AND_LEN("vbo"), - offsetof(SampleStruct, vbo), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->vbo), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_vao, STR_AND_LEN("vao"), - offsetof(SampleStruct, vao), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->vao), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - DqnInspectMetadata_SampleStruct_vao, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_vao), // metadata array - }, - { - DqnInspectMemberType::SampleStruct_a, STR_AND_LEN("a"), - offsetof(SampleStruct, a), - DqnInspectDeclType::int_Ptr_const_, STR_AND_LEN("int *const"), - sizeof(((SampleStruct *)0)->a), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_const_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_b, STR_AND_LEN("b"), - offsetof(SampleStruct, b), - DqnInspectDeclType::int_const_Ptr_const_, STR_AND_LEN("int const *const"), - sizeof(((SampleStruct *)0)->b), // full_decl_type_sizeof - DqnInspectDeclType::int_const_Ptr_const_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_c, STR_AND_LEN("c"), - offsetof(SampleStruct, c), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->c), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_d, STR_AND_LEN("d"), - offsetof(SampleStruct, d), - DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"), - sizeof(((SampleStruct *)0)->d), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_e, STR_AND_LEN("e"), - offsetof(SampleStruct, e), - DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"), - sizeof(((SampleStruct *)0)->e), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_draw_color, STR_AND_LEN("draw_color"), - offsetof(SampleStruct, draw_color), - DqnInspectDeclType::V4_, STR_AND_LEN("V4"), - sizeof(((SampleStruct *)0)->draw_color), // full_decl_type_sizeof - DqnInspectDeclType::V4_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - DqnInspectMetadata_SampleStruct_draw_color, ARRAY_COUNT(DqnInspectMetadata_SampleStruct_draw_color), // metadata array - }, - { - DqnInspectMemberType::SampleStruct_lights, STR_AND_LEN("lights"), - offsetof(SampleStruct, lights), - DqnInspectDeclType::Array_V3,_32_, STR_AND_LEN("Array"), - sizeof(((SampleStruct *)0)->lights), // full_decl_type_sizeof - DqnInspectDeclType::Array_, DqnInspectDeclType::V3,_32_, - STR_AND_LEN("V3, 32"), // template_child_expr - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_camera_matrixes, STR_AND_LEN("camera_matrixes"), - offsetof(SampleStruct, camera_matrixes), - DqnInspectDeclType::Array_V4,_32_, STR_AND_LEN("Array"), - sizeof(((SampleStruct *)0)->camera_matrixes), // full_decl_type_sizeof - DqnInspectDeclType::Array_, DqnInspectDeclType::V4,_32_, - STR_AND_LEN("V4, 32"), // template_child_expr - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_bitmaps, STR_AND_LEN("bitmaps"), - offsetof(SampleStruct, bitmaps), - DqnInspectDeclType::char_Ptr_Ptr_, STR_AND_LEN("char **"), - sizeof(((SampleStruct *)0)->bitmaps), // full_decl_type_sizeof - DqnInspectDeclType::char_Ptr_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 2, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_shaders, STR_AND_LEN("shaders"), - offsetof(SampleStruct, shaders), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->shaders), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {ARRAY_COUNT(((SampleStruct *)0)->shaders), 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_win32_handle, STR_AND_LEN("win32_handle"), - offsetof(SampleStruct, win32_handle), - DqnInspectDeclType::void_Ptr_, STR_AND_LEN("void *"), - sizeof(((SampleStruct *)0)->win32_handle), // full_decl_type_sizeof - DqnInspectDeclType::void_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_lighting_ambient_coeff, STR_AND_LEN("lighting_ambient_coeff"), - offsetof(SampleStruct, lighting_ambient_coeff), - DqnInspectDeclType::V3_, STR_AND_LEN("V3"), - sizeof(((SampleStruct *)0)->lighting_ambient_coeff), // full_decl_type_sizeof - DqnInspectDeclType::V3_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_draw_call_count, STR_AND_LEN("draw_call_count"), - offsetof(SampleStruct, draw_call_count), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->draw_call_count), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_f, STR_AND_LEN("f"), - offsetof(SampleStruct, f), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->f), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_g, STR_AND_LEN("g"), - offsetof(SampleStruct, g), - DqnInspectDeclType::int_const_, STR_AND_LEN("int const"), - sizeof(((SampleStruct *)0)->g), // full_decl_type_sizeof - DqnInspectDeclType::int_const_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_h, STR_AND_LEN("h"), - offsetof(SampleStruct, h), - DqnInspectDeclType::int_Ptr_const_, STR_AND_LEN("int *const"), - sizeof(((SampleStruct *)0)->h), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_const_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_i, STR_AND_LEN("i"), - offsetof(SampleStruct, i), - DqnInspectDeclType::int_const_Ptr_, STR_AND_LEN("int const*"), - sizeof(((SampleStruct *)0)->i), // full_decl_type_sizeof - DqnInspectDeclType::int_const_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_j, STR_AND_LEN("j"), - offsetof(SampleStruct, j), - DqnInspectDeclType::int_Ptr_Ptr_Ptr_Ptr_const_, STR_AND_LEN("int ****const"), - sizeof(((SampleStruct *)0)->j), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_Ptr_Ptr_Ptr_const_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 4, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_k, STR_AND_LEN("k"), - offsetof(SampleStruct, k), - DqnInspectDeclType::int_, STR_AND_LEN("int"), - sizeof(((SampleStruct *)0)->k), // full_decl_type_sizeof - DqnInspectDeclType::int_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 0, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_l, STR_AND_LEN("l"), - offsetof(SampleStruct, l), - DqnInspectDeclType::int_Ptr_Ptr_, STR_AND_LEN("int **"), - sizeof(((SampleStruct *)0)->l), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 2, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, - { - DqnInspectMemberType::SampleStruct_m, STR_AND_LEN("m"), - offsetof(SampleStruct, m), - DqnInspectDeclType::int_Ptr_, STR_AND_LEN("int *"), - sizeof(((SampleStruct *)0)->m), // full_decl_type_sizeof - DqnInspectDeclType::int_Ptr_, DqnInspectDeclType::NotAvailable_, - nullptr, 0, // template_child_expr and template_child_expr_len - 1, // array_dimensions - {0, 0, 0, 0, 0, 0, 0, 0}, // array_compile_time_size 0, max 8 dimensions, 0 if unknown, - nullptr, 0, // metadata array - }, -}; - -DqnInspectStruct const DqnInspect_SampleStruct_Struct = -{ - STR_AND_LEN("SampleStruct"), - DqnInspect_SampleStruct_Members, // members - ARRAY_COUNT(DqnInspect_SampleStruct_Members) // members_len -}; - -DqnInspectStruct const *DqnInspect_Struct(SampleStruct const *) -{ - DqnInspectStruct const *result = &DqnInspect_SampleStruct_Struct; - return result; -} - -char const *DqnInspect_EnumWithMetadata_Strings[] = {"Rect", "Square", "Count", }; - -char const *DqnInspectEnum_Stringify(EnumWithMetadata val, int *len = nullptr) -{ - if (val == EnumWithMetadata::Rect) { if (len) *len = CHAR_COUNT("Rect"); return DqnInspect_EnumWithMetadata_Strings[0]; } - if (val == EnumWithMetadata::Square) { if (len) *len = CHAR_COUNT("Square"); return DqnInspect_EnumWithMetadata_Strings[1]; } - if (val == EnumWithMetadata::Count) { if (len) *len = CHAR_COUNT("Count"); return DqnInspect_EnumWithMetadata_Strings[2]; } - return nullptr; -} - -int DqnInspectEnum_Count(EnumWithMetadata) { return 3; } - -char const * DqnInspectMetadata_FilePath(EnumWithMetadata val) -{ - if (val == EnumWithMetadata::Rect) { return "Rect.vert"; } - if (val == EnumWithMetadata::Square) { return "Square.vert"; } - return nullptr; -} - -bool DqnInspectMetadata_Coords(EnumWithMetadata val, V3 *value = nullptr) -{ - if (val == EnumWithMetadata::Rect) { *value = V3(1, 2, 3); return true; } - return false; -} - -void Function1(int a, float b = {}, char const * c = nullptr, bool e = false, int f = 1, char * g = "Hello world"); -void * Function2(V3 foo = V3(10, 20, 50), V3 bar = {120, 150, 20}, ...); -Array const *const Function3(Array const * foobar); - -#endif // DQN_INSPECT_DQNINSPECT_TESTDATA_H - -DqnInspectStruct const *DqnInspect_Struct(DqnInspectDeclType type) -{ - (void)type; -#ifdef DQN_INSPECT_DQNINSPECT_TESTDATA_H - if (type == DqnInspectDeclType::SampleStruct_) return &DqnInspect_SampleStruct_Struct; -#endif // DQN_INSPECT_DQNINSPECT_TESTDATA_H - - return nullptr; -} - - -#undef ARRAY_COUNT -#undef CHAR_COUNT -#undef STR_AND_LEN diff --git a/Project/Msvc/DqnInspect.sln b/Project/Msvc/DqnInspect.sln deleted file mode 100644 index 2bf2e2a..0000000 --- a/Project/Msvc/DqnInspect.sln +++ /dev/null @@ -1,33 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.168 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "DqnInspect", "..\..\Bin\DqnInspect.exe", "{52E81ACE-0533-48AA-878A-78CAFC30857B}" - ProjectSection(DebuggerProjectSystem) = preProject - PortSupplier = 00000000-0000-0000-0000-000000000000 - Executable = F:\Home\Code\dqn\Bin\DqnInspect.exe - RemoteMachine = THAI-XPS13 - StartingDirectory = F:\Home\Code\dqn\Data\ - Arguments = DqnInspect_TestData.h - Environment = Default - LaunchingEngine = 00000000-0000-0000-0000-000000000000 - UseLegacyDebugEngines = No - LaunchSQLEngine = No - AttachLaunchAction = No - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {52E81ACE-0533-48AA-878A-78CAFC30857B}.Release|x64.ActiveCfg = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {38BBCDD2-0DF9-4BD5-B72B-50926B5827FE} - EndGlobalSection -EndGlobal diff --git a/readme.md b/readme.md index d6904d8..e29294f 100644 --- a/readme.md +++ b/readme.md @@ -1,43 +1,53 @@ # Dqn Personal utility library. -## DqnInspect -A simple C++ introspection metaprogram designed as a prebuild step and generates type information for the inspected types. It is a minimal single header file licensed in the public domain with only CRT dependencies. It is only able to parse C-like C++, i.e. Plain Old Data types only. +## DqnHeader +A simple C++ introspection metaprogram designed as a prebuild step and generates a summary of function prototypes and comments in a header file based on annotations. It is not designed to be used as a header file for compilation and will most likely fail syntax rules if tried. The generated file is written to stdout. +### Build +Build DqnHeader by defining `DQN_HEADER_IMPLEMENTATION` before compiling and execute it as follows + +`DqnHeader.exe SourceCode.h > GeneratedFile.h` + ### Usage -Annotate the C++ code using `DQN_INSPECT`, i.e. +Include `DqnHeader.h` in a file and use the macros, annotations as described. + * Extract function prototypes using the `DQN_HEADER_COPY_PROTOTYPE` macro + * Copy comments by writing comments with `// @` as the prefix + * Copy many lines of code by enclosing it in `DQN_HEADER_COPY_BEGIN` and `DQN_HEADER_COPY_END` macros ``` -DQN_INSPECT struct Entity +#include "DqnHeader.h" + +// @ ptr1: Pointer to the first block of memory +// @ ptr2: Pointer to the second block of memory +// @ num_bytes: The number of bytes to compare in both blocks of memory +DQN_HEADER_COPY_PROTOTYPE(int, Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes)) { - V2 pos; - V2 size; + int result = memcmp(ptr1, ptr2, num_bytes); + return result; } -DQN_INSPECT enum struct SomeEnum +DQN_HEADER_COPY_BEGIN +struct HelloWorld { - Hello, - Foo -} -``` - -And then build DqnInspect by defining `DQN_INSPECT_EXECUTABLE_IMPLEMENTATION` before compiling and execute it as follows - -`DqnInspect.exe SourceCode.h > SourceCodeInspected.h` - -Include and use the file in code + int foo, bar; +}; +DQN_HEADER_COPY_END ``` -#include "DqnReflect.h" -#include "SourceCode.h" -#include "SourceCodeInspected.h" -SomeEnum enum = SomeEnum::Hello; -printf("%s\n", DqnInspect_EnumString(enum)); // prints Hello -Entity entity = {}; -DqnInspect_Struct const *inspector = DqnInspect_GetStruct(&entity); -for (int i = 0; i < inspector->members_len; ++i) - printf("%s\n", inspector->members[i].name); +Which generates the following output + ``` +// @ ptr1: Pointer to the first block of memory +// @ ptr2: Pointer to the second block of memory +// @ num_bytes: The number of bytes to compare in both blocks of memory +int Dqn_MemCmp(void const *ptr1, void const *ptr2, size_t num_bytes); +struct HelloWorld +{ + int foo, bar; +}; +``` +