|
- #ifndef CORE_H
- #define CORE_H
-
- // cstdlib includes
- #include "stdbool.h"
- #include "stdint.h" // necessary for int type sizes
- #include "time.h" // TODO(djledda): try not to depend on this one
-
- // ### Misc macros ###
- #if DJSTDLIB_DEBUG
- #define Assert(expression) if (!(expression)) {*(volatile int *)0 = 0;}
- #else
- #define Assert(expression)
- #endif
-
- #define function static
- #define global static
- #define local_persist static
- #define Forever for (;;)
-
- #define DeferLoop(begin_stmnt, end_stmnt) for(int __defer_i = ((begin_stmnt), 0); __defer_i < 1; (++__defer_i, (end_stmnt)))
-
- // ### Types ###
- typedef int8_t int8;
- typedef int16_t int16;
- typedef int32_t int32;
- typedef int64_t int64;
- typedef uint8_t uint8;
- typedef uint16_t uint16;
- typedef uint32_t uint32;
- typedef uint64_t uint64;
- typedef char byte;
- typedef float real32;
- typedef double real64;
- typedef struct string string;
-
- // ### Sizes and Numbers ###
- #define Bytes(n) (n)
- #define Kilobytes(n) (n << 10)
- #define Megabytes(n) (n << 20)
- #define Gigabytes(n) (((uint64)n) << 30)
- #define Terabytes(n) (((uint64)n) << 40)
-
- #define Thousand(n) ((n)*1000)
- #define Million(n) ((n)*1000000)
- #define Billion(n) ((n)*1000000000LL)
-
- #define ArrayCount(arr) (sizeof(arr) / sizeof((arr)[0]))
- #define MemberSize(type, memberName) sizeof(((type *)0)->memberName)
- #define MemberSizeUnderlying(type, memberName) sizeof(*((type *)0)->memberName)
-
- // ### Arenas ###
- typedef struct Arena Arena;
- struct Arena {
- void *memory;
- size_t capacity;
- size_t head;
- };
-
- typedef struct Scratch Scratch;
- struct Scratch {
- Arena *arena;
- size_t start;
- };
-
- void *pushSize(Arena *arena, size_t bytes);
- void *pushSizeFill(Arena *arena, size_t bytes, byte fill);
- Arena *arenaAlloc(size_t capacity);
- void arenaFree(Arena *arena);
- void arenaFreeFrom(Arena *arena, size_t pos);
- void arenaPopTo(Arena *arena, void *pos);
-
- void initialiseDjStdCore();
-
- Scratch scratchStart(Arena **conflicts, size_t conflictCount);
- void scratchEnd(Scratch scratch);
-
- #define PushArray(arena, type, size) (type *)pushSize(arena, sizeof(type) * (size))
- #define PushArrayZero(arena, type, size) (type *)pushSizeFill(arena, sizeof(type) * (size), 0)
- #define PushStruct(arena, type) (type *)pushSize(arena, sizeof(type))
- #define PushStructZero(arena, type) (type *)pushSizeFill(arena, sizeof(type), 0)
- #define WithScratch(scratchName) Scratch scratchName; DeferLoop(scratchName = scratchStart(0, 0), scratchEnd(scratchName))
-
- // ### Vectors ###
- typedef union Vec2 Vec2;
- union Vec2 {
- struct {
- real32 x;
- real32 y;
- };
- real32 vec[2];
- };
- inline function Vec2 vec2(real32 x, real32 y) {
- Vec2 result = {0};
- result.x = x;
- result.y = y;
- return result;
- }
-
- typedef union Vec3 Vec3;
- union Vec3 {
- struct {
- real32 x;
- real32 y;
- real32 z;
- };
- real32 vec[3];
- };
- inline function Vec3 vec3(real32 x, real32 y, real32 z) {
- Vec3 result = {0};
- result.x = x;
- result.y = y;
- result.z = z;
- return result;
- }
-
- typedef union Vec4 Vec4;
- union Vec4 {
- struct {
- real32 r;
- real32 g;
- real32 b;
- real32 a;
- };
- struct {
- real32 x;
- real32 y;
- real32 z;
- real32 w;
- };
- real32 vec[4];
- };
- inline function Vec4 vec4(real32 x, real32 y, real32 z, real32 w) {
- Vec4 result = {0};
- result.x = x;
- result.y = y;
- result.z = z;
- result.w = w;
- return result;
- }
-
- // ### Lists ###
- #define DefineList(type, prefix) \
- typedef struct prefix ## List prefix ## List;\
- struct prefix ## List {\
- type *data;\
- size_t length;\
- size_t capacity;\
- };\
- typedef type prefix ## List ## _underlying
- #define ListElementSize(list) MemberSizeUnderlying(list, data)
-
- DefineList(string, String);
-
- #define PushList(arena, type, size) (type){ .data=pushSize(arena, ListElementSize(type)*(size)), .length=0, .capacity=(size) }
- #define PushListZero(arena, type, size) (type){ .data=pushSizeFill(arena, ListElementSize(type)*(size), 0), .length=0, .capacity=(size) }
- #define PushFullList(arena, type, size) (type){ .data=pushSize(arena, ListElementSize(type)*size), .length=(size), .capacity=(size) }
- #define PushFullListZero(arena, type, size) (type){ .data=pushSizeFill(arena, ListElementSize(type)*(size), 0), .length=(size), .capacity=(size) }
-
- #define EmptyList() { NULL, 0, 0 }
- #define __ArrayAsList(array) { .data=(array), .length=ArrayCount(array), .capacity=ArrayCount(array) }
- #define AsList(listtype, ...) (listtype)__ArrayAsList(((listtype##_underlying[])__VA_ARGS__))
-
- // TODO(dledda): clone list
- // TODO(dledda): list back element accessor
- #define AppendList(list, element) \
- if ((list)->length < (list)->capacity) { \
- (list)->data[(list)->length++] = (element); \
- }
- #define ZeroListFull(list) memset((list)->data, 0, (list)->length * sizeof((list)->data[0]))
- #define ZeroList(list) (list)->length = 0; \
- memset((list)->data, 0, (list)->length * sizeof((list)->data[0]))
-
- // Following two macros do not use pointers due to copying
- #define ListSlice(list, start, stop) {\
- .data= (stop > (list).length || start > stop) ? 0 : (list).data + start,\
- .length=(stop > (list).length || start > stop) ? 0 : stop - start,\
- .capacity=(stop > (list).length || start > stop) ? 0 : stop - start,\
- }
- #define ListTail(list, start) ListSlice(list, start, (list).length)
-
- #define ListRemove(list, index)\
- if ((index) >= 0 && (index) < (list)->length) {\
- memcpy((list)->data + (index), (list)->data + (index) + 1, ((list)->length - (i + 1))*sizeof(*((list)->data)));\
- (list)->length -= 1;\
- }
-
- // ### Strings ###
- struct string {
- char *str;
- size_t length;
- };
- #define STB_SPRINTF_DECORATE(name) stb_##name // define this before including if you want to change the names
- #include "vendor/stb_sprintf.h"
-
- #define s(lit) ((string){(char *)(lit), sizeof(lit) - 1})
- #define PushString(arena, length) ((string){ (char *)pushSize(arena, length), (length) })
- #define PushStringFill(arena, length, characterByte) ((string){ (char *)pushSizeFill(arena, length, characterByte), (length) })
-
- // C Strings
- DefineList(char, Char);
- const char *cstringFromCharList(Arena *arena, CharList buf);
- const char *cstring(Arena *arena, string str);
- size_t calcStringLen(const char *str);
- string strFromCString(Arena *arena, const char *str);
-
- bool strEql(string s1, string s2);
- bool strStartsWith(string str, string testStr);
- bool stringContains(string str, char c);
-
- string strReverse(Arena *arena, string str);
- string strSlice(string str, size_t start, size_t stop);
- string strSliceCStr(char *data, size_t start, size_t stop);
- StringList strSplit(Arena *arena, string splitStr, string inputStr);
- string strPrintfv(Arena *arena, const char *fmt, va_list args);
- string strPrintf(Arena *arena, const char *fmt, ...);
-
- #define DefineResult(type, prefix) \
- typedef struct prefix ## Result prefix ## Result;\
- struct prefix ## Result {\
- type result;\
- bool valid;\
- };\
- typedef type prefix ## Result ## _underlying
-
- DefineResult(int32, Int32);
- Int32Result parsePositiveInt(string str);
-
- DefineResult(real32, Real32);
- Real32Result parsePositiveReal32(string str);
-
- inline function bool isNumeric(char c);
-
- // ### Cmdline ###
- StringList getArgs(Arena *arena, int argc, char **argv);
-
- // ### Time ###
- typedef uint64 UnixTimestamp;
- typedef struct tm Timestamp;
-
- UnixTimestamp getSystemUnixTime();
- Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp);
- string formatTimeHmsUnix(Arena *arena, UnixTimestamp time);
- string formatTimeHms(Arena *arena, Timestamp *time);
- string formatTimeYmdUnix(Arena *arena, UnixTimestamp time);
- string formatTimeYmd(Arena *arena, Timestamp *time);
-
- // ### Linked Lists ###
- // TODO(djledda): implement basic linked lists (based on arenas?)
-
- // ### Logging ###
- typedef enum {
- StdStream_stdout,
- StdStream_stdin,
- StdStream_stderr,
- } StdStream;
-
- #define ANSI_INSTRUCTION(ansiCode) "\x1b[" #ansiCode
- #define ANSI_INSTRUCTION_STR(ansiCodeStr) "\x1b[" ansiCodeStr
- #define ANSI_GRAPHIC_INSTRUCTION(ansiCode) "\x1b[" #ansiCode "m"
- #define ANSI_GRAPHIC_INSTRUCTION_STR(ansiCodeStr) "\x1b[" ansiCodeStr "m"
- #define ANSI_RESET ANSI_INSTRUCTION(0)
-
- #define ANSI_fg_black 30
- #define ANSI_fg_red 31
- #define ANSI_fg_green 32
- #define ANSI_fg_yellow 33
- #define ANSI_fg_blue 34
- #define ANSI_fg_magenta 35
- #define ANSI_fg_cyan 36
- #define ANSI_fg_white 37
-
- #define ANSI_fg_bblack 90
- #define ANSI_fg_bred 91
- #define ANSI_fg_bgreen 92
- #define ANSI_fg_byellow 93
- #define ANSI_fg_bblue 94
- #define ANSI_fg_bmagenta 95
- #define ANSI_fg_bcyan 96
- #define ANSI_fg_bwhite 97
-
- #define ANSI_bg_black 40
- #define ANSI_bg_red 41
- #define ANSI_bg_green 42
- #define ANSI_bg_yellow 43
- #define ANSI_bg_blue 44
- #define ANSI_bg_magenta 45
- #define ANSI_bg_cyan 46
- #define ANSI_bg_white 47
-
- #define ANSI_bg_bblack 100
- #define ANSI_bg_bred 101
- #define ANSI_bg_bgreen 102
- #define ANSI_bg_byellow 103
- #define ANSI_bg_bblue 104
- #define ANSI_bg_bmagenta 105
- #define ANSI_bg_bcyan 106
- #define ANSI_bg_bwhite 107
-
- #define COLOR_TEXT(text, foregroundcolor) ANSI_INSTRUCTION_FROM_ENUM(foregroundcolor) text ANSI_RESET
- #define COLOR_TEXT_BG(text, backgroundcolor) ANSI_INSTRUCTION_FROM_ENUM(backgroundcolor) text ANSI_RESET
- #define COLOR_TEXT_FG_BG(text, foregroundcolor, backgroundcolor) ANSI_INSTRUCTION_FROM_ENUM(foregroundcolor) ANSI_INSTRUCTION_FROM_ENUM(backgroundcolor) text ANSI_RESET
- #define COLOR_TEXT_RGB(text, red, green, blue) ANSI_INSTRUCTION_STR("38;2;" #red ";" #green ";" #blue) text ANSI_RESET
-
- DefineList(int, Int);
- void printIntList(IntList l);
- void printStrList(StringList l);
- void setStdout();
- void setStderr();
- extern void (*print)(const char *fmt, ...);
- extern void (*println)(const char *fmt, ...);
-
- // ### Loops ###
- #define EachIn(list, it) size_t it = 0; it < (list).length; it++
- #define EachEl(list, type, element) type *element = (list).data; element < (list).data + (list).length; element += 1
- #define EachInReversed(list, it) size_t it = (list).length - 1; it >= 0 && it < (list).length; it--
- #define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it
-
- // ### Misc ###
- int intCompare(const void *a, const void *b);
-
- #endif
|