| @@ -1,4 +1,5 @@ | |||||
| CompileFlags: | CompileFlags: | ||||
| Add: | Add: | ||||
| - [-std=c99, -xc] | |||||
| - -std=c99 | |||||
| - -xc | |||||
| - -DOS_LINUX | - -DOS_LINUX | ||||
| @@ -5,6 +5,7 @@ int main(int argc, char **argv) { | |||||
| Arena *arena = arenaAlloc(Megabytes(64)); | Arena *arena = arenaAlloc(Megabytes(64)); | ||||
| StringList args = getArgs(arena, argc, argv); | StringList args = getArgs(arena, argc, argv); | ||||
| print("Args:\n"); | |||||
| printStrList(args); | printStrList(args); | ||||
| printStrList(strSplit(arena, s("-"), s("the-quick-brown-fox-jumps-over-the-lazy-dog"))); | printStrList(strSplit(arena, s("-"), s("the-quick-brown-fox-jumps-over-the-lazy-dog"))); | ||||
| @@ -1,3 +1,7 @@ | |||||
| #!/bin/bash | #!/bin/bash | ||||
| g++ -g -g3 -lm -DOS_LINUX=1 -DENABLE_ASSERT=1 ./app.cpp -o ./target/app | |||||
| clang -g -g3 -lm -DOS_LINUX=1 -DENABLE_ASSERT=1 ./app.c -o ./target/app | |||||
| if [[ $1 == "run" ]] then | |||||
| ./target/app | |||||
| fi | |||||
| @@ -1,6 +1,6 @@ | |||||
| #include "os.c" | #include "os.c" | ||||
| #include "math.h" | #include "math.h" | ||||
| #include "string.h" // memmove | |||||
| #include "string.h" // for memmove | |||||
| #include "core.h" | #include "core.h" | ||||
| #define STB_SPRINTF_IMPLEMENTATION | #define STB_SPRINTF_IMPLEMENTATION | ||||
| #include "vendor/stb_sprintf.h" | #include "vendor/stb_sprintf.h" | ||||
| @@ -165,8 +165,6 @@ string strPrintf(Arena *arena, const char *fmt, ...) { | |||||
| return result; | return result; | ||||
| } | } | ||||
| #define ListSlice(__ls_list__, __ls_start__, __ls_stop__) (__ls_stop__ > l.head || __ls_start__ > __ls_stop__ ? {0} : { l.data + start, stop - start, stop - start, }) | |||||
| string strSlice(string str, size_t start, size_t stop) { | string strSlice(string str, size_t start, size_t stop) { | ||||
| if (stop == 0) { | if (stop == 0) { | ||||
| stop = str.length; | stop = str.length; | ||||
| @@ -228,7 +226,7 @@ StringList strSplit(Arena *arena, string splitStr, string inputStr) { | |||||
| result.data = (string *)beginning; | result.data = (string *)beginning; | ||||
| result.length = splitCount; | result.length = splitCount; | ||||
| result.head = splitCount; | |||||
| result.capacity = splitCount; | |||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -247,14 +245,14 @@ ParsePositiveIntResult parsePositiveInt(string str, size_t *lengthPointer) { | |||||
| result *= 10; | result *= 10; | ||||
| result += str.str[i] - '0'; | result += str.str[i] - '0'; | ||||
| } | } | ||||
| return (ParsePositiveIntResult){ result, true }; | |||||
| return (ParsePositiveIntResult){ .result=result, .valid=true }; | |||||
| } else { | } else { | ||||
| return (ParsePositiveIntResult){0, false}; | |||||
| return (ParsePositiveIntResult){ .result=0, .valid=false}; | |||||
| } | } | ||||
| } | } | ||||
| ParsePositiveReal32Result parsePositiveReal32(string str, size_t *lengthPointer) { | ParsePositiveReal32Result parsePositiveReal32(string str, size_t *lengthPointer) { | ||||
| ParsePositiveReal32Result result = {NAN, false}; | |||||
| ParsePositiveReal32Result result = { .result=NAN, .valid=false}; | |||||
| string wholePartStr = (string){0}; | string wholePartStr = (string){0}; | ||||
| string fractionalPartStr = (string){0}; | string fractionalPartStr = (string){0}; | ||||
| @@ -307,9 +305,8 @@ UnixTimestamp getSystemUnixTime() { | |||||
| } | } | ||||
| Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp) { | Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp) { | ||||
| struct tm timestamp = {0}; | |||||
| gmtime_r((time_t *)unixTimestamp, ×tamp); | |||||
| return timestamp; | |||||
| struct tm *timestamp = gmtime((time_t *)unixTimestamp); | |||||
| return *timestamp; | |||||
| } | } | ||||
| string formatTimeHmsUnix(Arena *arena, UnixTimestamp time) { | string formatTimeHmsUnix(Arena *arena, UnixTimestamp time) { | ||||
| @@ -406,7 +403,7 @@ void printIntList(IntList l) { | |||||
| } | } | ||||
| print("%i", l.data[i]); | print("%i", l.data[i]); | ||||
| } | } | ||||
| print(" } length: %zu, head: %zu\n", l.length, l.head); | |||||
| print(" } length: %zu, capacity: %zu\n", l.length, l.capacity); | |||||
| } | } | ||||
| void printStrList(StringList l) { | void printStrList(StringList l) { | ||||
| @@ -417,7 +414,7 @@ void printStrList(StringList l) { | |||||
| } | } | ||||
| print("\"%S\"", l.data[i]); | print("\"%S\"", l.data[i]); | ||||
| } | } | ||||
| print(" } length: %zu, head: %zu\n", l.length, l.head); | |||||
| print(" } length: %zu, capacity: %zu\n", l.length, l.capacity); | |||||
| } | } | ||||
| int intCompare(const void *a, const void *b) { | int intCompare(const void *a, const void *b) { | ||||
| @@ -2,10 +2,8 @@ | |||||
| #define CORE_H | #define CORE_H | ||||
| // cstdlib includes | // cstdlib includes | ||||
| #include "math.h" | |||||
| #include "stdbool.h" | #include "stdbool.h" | ||||
| #include "stdint.h" // necessary for int type sizes | #include "stdint.h" // necessary for int type sizes | ||||
| #include "stdio.h" | |||||
| #include "time.h" // TODO(djledda): try not to depend on this one | #include "time.h" // TODO(djledda): try not to depend on this one | ||||
| // ### Misc macros ### | // ### Misc macros ### | ||||
| @@ -139,7 +137,7 @@ inline function Vec4 vec4(real32 x, real32 y, real32 z, real32 w) { | |||||
| typedef struct {\ | typedef struct {\ | ||||
| type* data;\ | type* data;\ | ||||
| size_t length;\ | size_t length;\ | ||||
| size_t head;\ | |||||
| size_t capacity;\ | |||||
| } prefix ## List | } prefix ## List | ||||
| DefineList(string, String); | DefineList(string, String); | ||||
| @@ -152,12 +150,14 @@ DefineList(string, String); | |||||
| #define ArrayAsList(type, array) (type){ array, ArrayCount(array), ArrayCount(array) } | #define ArrayAsList(type, array) (type){ array, ArrayCount(array), ArrayCount(array) } | ||||
| #define AppendList(list, element) \ | #define AppendList(list, element) \ | ||||
| if ((list)->head < (list)->length) { \ | |||||
| (list)->data[(list)->head++] = (element); \ | |||||
| if ((list)->length < (list)->capacity) { \ | |||||
| (list)->data[(list)->length++] = (element); \ | |||||
| } | } | ||||
| #define ZeroListFull(list) memset((list)->data, 0, (list)->head * sizeof(T)) | |||||
| #define ZeroList(list) (list)->head = 0; \ | |||||
| memset((list)->data, 0, (list)->head * sizeof(T)); | |||||
| #define ZeroListFull(list) memset((list)->data, 0, (list)->length * sizeof(T)) | |||||
| #define ZeroList(list) (list)->length = 0; \ | |||||
| memset((list)->data, 0, (list)->length * sizeof(T)); | |||||
| #define ListSlice(list, start, stop) (stop > list.length || start > stop ? {0} : { list.data + start, stop - start, stop - start, }) | |||||
| #define ListTail(list, start) ListSlice(list, list.length) | |||||
| // ### Strings ### | // ### Strings ### | ||||
| struct string { | struct string { | ||||
| @@ -189,9 +189,16 @@ StringList strSplit(Arena *arena, string splitStr, string inputStr); | |||||
| string strPrintfv(Arena *arena, const char *fmt, va_list args); | string strPrintfv(Arena *arena, const char *fmt, va_list args); | ||||
| string strPrintf(Arena *arena, const char *fmt, ...); | string strPrintf(Arena *arena, const char *fmt, ...); | ||||
| typedef struct { uint8 result; bool valid; } ParsePositiveIntResult; | |||||
| typedef struct { | |||||
| uint8 result; | |||||
| bool valid; | |||||
| } ParsePositiveIntResult; | |||||
| ParsePositiveIntResult parsePositiveInt(string str, size_t *lengthPointer); | ParsePositiveIntResult parsePositiveInt(string str, size_t *lengthPointer); | ||||
| typedef struct { real32 result; bool valid; } ParsePositiveReal32Result; | |||||
| typedef struct { | |||||
| real32 result; | |||||
| bool valid; | |||||
| } ParsePositiveReal32Result; | |||||
| ParsePositiveReal32Result parsePositiveReal32(string str, size_t *lengthPointer); | ParsePositiveReal32Result parsePositiveReal32(string str, size_t *lengthPointer); | ||||
| inline function bool isNumeric(char c); | inline function bool isNumeric(char c); | ||||
| @@ -272,8 +279,8 @@ void printStrList(StringList l); | |||||
| extern void (*print)(const char *fmt, ...); | extern void (*print)(const char *fmt, ...); | ||||
| // ### Loops ### | // ### Loops ### | ||||
| #define EachIn(list, it) size_t it = 0; it < (list).head; it++ | |||||
| #define EachInReversed(list, it) size_t it = (list).head - 1; it >= 0 && it < (list).head; it-- | |||||
| #define EachIn(list, it) size_t it = 0; it < (list).length; it++ | |||||
| #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 | #define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it | ||||
| // ### Misc ### | // ### Misc ### | ||||
| @@ -5,7 +5,8 @@ | |||||
| #include "sys/mman.h" | #include "sys/mman.h" | ||||
| #include "sys/stat.h" | #include "sys/stat.h" | ||||
| #include "unistd.h" | |||||
| #include "unistd.h" // POSIX Standard | |||||
| #include "stdio.h" | |||||
| void *os_alloc(size_t capacity) { | void *os_alloc(size_t capacity) { | ||||
| return mmap(0, capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | return mmap(0, capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||||
| @@ -78,14 +79,14 @@ void os_print(StdStream target, const char *fmt, va_list argList) { | |||||
| string result = strPrintfv(temp.arena, fmt, argList); | string result = strPrintfv(temp.arena, fmt, argList); | ||||
| // TODO(djledda): finish implementation without cstdlib | // TODO(djledda): finish implementation without cstdlib | ||||
| switch (target) { | switch (target) { | ||||
| case StdStream_stdin: | |||||
| case StdStream_stdin: | |||||
| write(0, (const void *)result.str, result.length); | write(0, (const void *)result.str, result.length); | ||||
| break; | break; | ||||
| case StdStream_stderr: | |||||
| case StdStream_stderr: | |||||
| fflush(stderr); | fflush(stderr); | ||||
| write(2, (const void *)result.str, result.length); | write(2, (const void *)result.str, result.length); | ||||
| break; | break; | ||||
| case StdStream_stdout: | |||||
| case StdStream_stdout: | |||||
| default: | default: | ||||
| fflush(stdout); | fflush(stdout); | ||||
| write(1, (const void *)result.str, result.length); | write(1, (const void *)result.str, result.length); | ||||