Compare commits

...

10 Commits

Author SHA1 Message Date
Krzosa Karol
7660402d08 Remove flags from build tool
Some checks failed
/ run-and-compile-ubuntu (push) Has been cancelled
/ run-and-compile-mac (push) Has been cancelled
/ run-and-compile-windows (push) Has been cancelled
2024-03-16 12:01:52 +01:00
Krzosa Karol
18100a87fb Fix const char 2024-03-16 11:55:44 +01:00
Krzosa Karol
da575e8877 Fix warnings 2024-03-16 11:51:13 +01:00
Krzosa Karol
1a1432592a Disable clang address sanitizer 2024-03-16 11:45:53 +01:00
Krzosa Karol
71d36352cb Fix memcpy in arena 2024-03-16 11:40:26 +01:00
Krzosa Karol
1b48585308 Add stubs, wanted to compile to wasm 2024-03-15 16:23:33 +01:00
Krzosa Karol
0c4d19c9b8 Add int cmd kind 2024-03-15 06:53:55 +01:00
Krzosa Karol
6c4c141344 Improve build tool 2024-03-14 11:20:30 +01:00
Krzosa Karol
c944ceac4b IO Thread local on callback, build system thread local on perm arena 2024-03-10 19:22:16 +01:00
Krzosa Karol
bc12273f2a CmdParser improvements 2024-03-04 17:28:57 +01:00
14 changed files with 258 additions and 187 deletions

View File

@@ -3,6 +3,4 @@ mkdir build
cd build
cl -Fe:bld.exe ../build_tool/main.cpp -FC -WX -W3 -wd4200 -diagnostics:column -nologo -Zi -D_CRT_SECURE_NO_WARNINGS
cd ..
rem build\bld.exe clear_cache
build\bld.exe
rem build\bld.exe cc=clang

View File

@@ -58,7 +58,6 @@ int main(int argc, char **argv) {
Array<S8_String> flags = {scratch};
flags += "-g -Wno-write-strings";
flags += "-fdiagnostics-absolute-paths";
flags += "-fsanitize=address";
if (is_cpp) flags += "-fno-exceptions";
if (is_cpp) flags += "-fno-rtti";
if (is_cpp) flags += "-std=c++11";

View File

@@ -12,9 +12,8 @@
#define AND_CL_STRING_TERMINATE_ON_NEW_LINE
#include "../standalone_libraries/clexer.c"
MA_Arena PernamentArena;
MA_Arena *Perm = &PernamentArena;
Table<S8_String> CMDLine;
thread_local MA_Arena PernamentArena;
thread_local MA_Arena *Perm = &PernamentArena;
#include "cache.cpp"
#include "easy_strings.cpp"

View File

@@ -7,16 +7,7 @@ int main(int argument_count, char **arguments) {
IO_Printf("WORKING DIR: %.*s\n", S8_Expand(working_dir));
Array<S8_String> cmd = CMD_Make(arguments, argument_count);
if (CMD_Match(cmd, "clear_cache")) {
for (OS_FileIter it = OS_IterateFiles(Perm, "./"); OS_IsValid(it); OS_Advance(&it)) {
if (!it.is_directory && S8_EndsWith(it.filename, ".cache", true)) {
OS_DeleteFile(it.absolute_path);
}
}
return 0;
}
S8_String cc = CMD_Get(cmd, "cc", IF_WINDOWS("cl") IF_MAC("clang") IF_LINUX("gcc"));
S8_String cc = CMD_Get(cmd, "cc", IF_WINDOWS("cl") IF_MAC("clang") IF_LINUX("gcc"));
// Search for build file in the project directory
S8_String build_file = {};
@@ -31,45 +22,41 @@ int main(int argument_count, char **arguments) {
IO_Printf("Couldnt find build file in current dir: %.*s, exiting ... \n", S8_Expand(working_dir));
IO_Printf("- Proper build file contains 'build_file.c' in it's name\n");
IO_Printf("- Alternative compiler can be chosen like this: bld cc=clang\n");
IO_Printf("- Cache can be cleared like this: bld clear_cache\n");
return 0;
}
}
SRC_InitCache(Perm, "build_tool.cache");
S8_String name_no_ext = S8_GetNameNoExt(build_file);
S8_String exe_name = S8_Format(Perm, "%.*s.exe", S8_Expand(name_no_ext));
S8_String exe_name = S8_Format(Perm, "%.*s.exe", S8_Expand(name_no_ext));
// Compile the build file only if code changed
if (SRC_WasModified(build_file, exe_name)) {
double time = OS_GetTime();
int result = 0;
double time = OS_GetTime();
int result = 0;
if (cc == "cl") {
Array<S8_String> flags = {Perm};
flags += "-nologo -Zi";
flags += "-WX -W3 -wd4200 -diagnostics:column";
flags += Fmt("/Fe:%.*s", S8_Expand(exe_name));
flags += Fmt("/Fe:%.*s /Fd:%.*s.pdb", S8_Expand(exe_name), S8_Expand(exe_name));
result = Run(cc + build_file + flags);
}
else if (cc == "clang") {
} else if (cc == "clang") {
Array<S8_String> flags = {Perm};
cc = "clang++";
flags += "-std=c++11 -g";
flags += "-fdiagnostics-absolute-paths";
flags += "-Wno-writable-strings";
flags += "-fno-exceptions";
flags += "-fno-rtti";
flags += "-lm";
flags += Fmt("-o %.*s", S8_Expand(exe_name));
result = Run(cc + build_file + flags);
}
else {
} else {
IO_Assert(cc == "gcc");
cc = "g++";
Array<S8_String> flags = {Perm};
flags += "-std=c++11 -g";
flags += "-Wno-write-strings";
flags += "-fno-exceptions";
flags += "-fno-rtti";
flags += "-lm";
flags += Fmt("-o %.*s", S8_Expand(exe_name));
result = Run(cc + build_file + flags);
@@ -77,6 +64,7 @@ int main(int argument_count, char **arguments) {
if (result != 0) {
IO_Printf("FAILED compilation of the build file!\n");
OS_DeleteFile("build_tool.cache");
return 1;
}
time = OS_GetTime() - time;
@@ -86,10 +74,11 @@ int main(int argument_count, char **arguments) {
// Run the build file
double time = OS_GetTime();
if (build_file.str) {
exe_name = OS_GetAbsolutePath(Perm, exe_name);
exe_name = OS_GetAbsolutePath(Perm, exe_name);
int result = Run(exe_name + cmd);
if (result != 0) {
IO_Printf("FAILED execution of the build file!\n");
OS_DeleteFile("build_tool.cache");
return 1;
}
}

View File

@@ -1,6 +1,6 @@
CmdParser MakeCmdParser(MA_Arena *arena, int argc, char **argv) {
CmdParser result = {argc, argv, arena};
CmdParser MakeCmdParser(MA_Arena *arena, int argc, char **argv, const char *custom_help) {
CmdParser result = {argc, argv, arena, custom_help};
return result;
}
@@ -13,6 +13,15 @@ void AddBool(CmdParser *p, bool *result, const char *name, const char *help) {
SLL_QUEUE_ADD(p->fdecl, p->ldecl, decl);
}
void AddInt(CmdParser *p, int *result, const char *name, const char *help) {
CmdDecl *decl = MA_PushStruct(p->arena, CmdDecl);
decl->kind = CmdDeclKind_Int;
decl->name = S8_MakeFromChar((char *)name);
decl->help = S8_MakeFromChar((char *)help);
decl->int_result = result;
SLL_QUEUE_ADD(p->fdecl, p->ldecl, decl);
}
void AddList(CmdParser *p, S8_List *result, const char *name, const char *help) {
CmdDecl *decl = MA_PushStruct(p->arena, CmdDecl);
decl->kind = CmdDeclKind_List;
@@ -54,8 +63,9 @@ S8_String StrEnumValues(MA_Arena *arena, CmdDecl *decl) {
}
void PrintCmdUsage(CmdParser *p) {
IO_Printf("\nhere are the supported commands:\n");
IO_Printf("%s\nCommands:\n", p->custom_help);
for (CmdDecl *it = p->fdecl; it; it = it->next) {
IO_Printf(" ");
if (it->kind == CmdDeclKind_List) {
S8_String example = S8_Format(p->arena, "-%.*s a b c", S8_Expand(it->name));
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
@@ -64,7 +74,10 @@ void PrintCmdUsage(CmdParser *p) {
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
} else if (it->kind == CmdDeclKind_Enum) {
S8_String enum_vals = StrEnumValues(p->arena, it);
S8_String example = S8_Format(p->arena, "-%.*s %.*s", S8_Expand(it->name), S8_Expand(enum_vals));
S8_String example = S8_Format(p->arena, "-%.*s %.*s", S8_Expand(it->name), S8_Expand(enum_vals));
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
} else if (it->kind == CmdDeclKind_Int) {
S8_String example = S8_Format(p->arena, "-%.*s 8", S8_Expand(it->name));
IO_Printf("%-30.*s %.*s\n", S8_Expand(example), S8_Expand(it->help));
} else IO_Todo();
}
@@ -72,7 +85,6 @@ void PrintCmdUsage(CmdParser *p) {
bool InvalidCmdArg(CmdParser *p, S8_String arg) {
IO_Printf("invalid command line argument: %.*s\n", S8_Expand(arg));
PrintCmdUsage(p);
return false;
}
@@ -96,8 +108,26 @@ bool ParseCmd(MA_Arena *arg_arena, CmdParser *p) {
if (decl->kind == CmdDeclKind_Bool) {
*decl->bool_result = !*decl->bool_result;
} else if (decl->kind == CmdDeclKind_Int) {
if (i + 1 >= p->argc) {
IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg));
return false;
}
S8_String num = S8_MakeFromChar(p->argv[++i]);
for (int i = 0; i < num.len; i += 1) {
if (!CHAR_IsDigit(num.str[i])) {
IO_Printf("expected argument to be a number, got instead: %.*s", S8_Expand(num));
return false;
}
}
int count = atoi(num.str);
decl->int_result[0] = count;
} else if (decl->kind == CmdDeclKind_Enum) {
if (i + 1 >= p->argc) { IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg)); PrintCmdUsage(p); return false; }
if (i + 1 >= p->argc) {
IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg));
return false;
}
S8_String option_from_cmd = S8_MakeFromChar(p->argv[++i]);
bool found_option = false;
@@ -105,7 +135,7 @@ bool ParseCmd(MA_Arena *arg_arena, CmdParser *p) {
S8_String option = S8_MakeFromChar((char *)decl->enum_options[i]);
if (S8_AreEqual(option, option_from_cmd, true)) {
*decl->enum_result = i;
found_option = true;
found_option = true;
break;
}
}
@@ -113,18 +143,23 @@ bool ParseCmd(MA_Arena *arg_arena, CmdParser *p) {
if (!found_option) {
IO_Printf("expected one of the enum values: %.*s", S8_Expand(StrEnumValues(p->arena, decl)));
IO_Printf(" got instead: %.*s\n", S8_Expand(option_from_cmd));
PrintCmdUsage(p);
return false;
}
} else if (decl->kind == CmdDeclKind_List) {
if (i + 1 >= p->argc) { IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg)); PrintCmdUsage(p); return false; }
if (i + 1 >= p->argc) {
IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg));
return false;
}
i += 1;
for (int counter = 0; i < p->argc; i += 1, counter += 1) {
S8_String arg = S8_MakeFromChar(p->argv[i]);
if (arg.str[0] == '-') {
if (counter == 0) { IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg)); PrintCmdUsage(p); return false; }
if (counter == 0) {
IO_Printf("expected at least 1 argument after %.*s\n", S8_Expand(arg));
return false;
}
i -= 1;
break;
}
@@ -133,48 +168,19 @@ bool ParseCmd(MA_Arena *arg_arena, CmdParser *p) {
}
} else IO_Todo();
} else {
if (p->require_one_standalone_arg && p->args.node_count == 0) {
S8_AddNode(arg_arena, &p->args, arg);
} else {
return InvalidCmdArg(p, arg);
}
}
else return InvalidCmdArg(p, arg);
}
if (p->require_one_standalone_arg && p->args.node_count == 0) {
PrintCmdUsage(p);
return false;
}
return true;
}
// ./a.exe -scratch
// ./a.exe -quick
// ./a.exe -run_tests a.test b.test c.test
// ./a.exe --break_on_error
// ./a.exe -build=release
// ./a.exe --help
//
void TestCmdParser() {
char *argv[] = {
"exe",
"--build_scratch",
"-tests",
"a", "b", "c",
"--things", "1234", "asdsa",
"-build", "release",
};
int argc = MA_Lengthof(argv);
MA_Checkpoint scratch = MA_GetScratch();
bool build_scratch = false;
S8_List test_list = {0};
S8_List test_things = {0};
int build_profile = 0;
const char *build_profiles[] = {"debug", "release"};
int build_profiles_count = MA_Lengthof(build_profiles);
CmdParser p = MakeCmdParser(scratch.arena, argc, argv);
AddBool(&p, &build_scratch, "build_scratch", "builds a sandbox where I experiment with things");
AddList(&p, &test_list, "tests", "list of specific tests to run");
AddList(&p, &test_things, "things", "list of things");
AddEnum(&p, &build_profile, "build", "choose build profile", build_profiles, build_profiles_count);
bool success = ParseCmd(scratch.arena, &p);
IO_Assertf(success, "failed to parse cmd");
IO_Assert(build_scratch);
IO_Assert(test_list.node_count == 3);
IO_Assert(test_things.node_count == 2);
IO_Assert(build_profile == 1);
MA_ReleaseScratch(scratch);
}

View File

@@ -1,6 +1,7 @@
typedef enum {
CmdDeclKind_Bool,
CmdDeclKind_Int,
CmdDeclKind_List,
CmdDeclKind_Enum,
} CmdDeclKind;
@@ -14,6 +15,7 @@ struct CmdDecl {
bool *bool_result;
S8_List *list_result;
int *int_result;
int *enum_result;
const char **enum_options;
@@ -22,10 +24,14 @@ struct CmdDecl {
typedef struct CmdParser CmdParser;
struct CmdParser {
int argc;
char **argv;
MA_Arena *arena;
int argc;
char **argv;
MA_Arena *arena;
const char *custom_help;
CmdDecl *fdecl;
CmdDecl *ldecl;
CmdDecl *fdecl;
CmdDecl *ldecl;
bool require_one_standalone_arg;
S8_List args;
};

View File

@@ -20,11 +20,3 @@
#include "filesystem.c"
#include "cmd.c"
/*
- I think it's okay to say that strings being null terminated should be mostly treated as NOT terminated but leave some
leeway for big buffers and other such things. Just make sure to not relay on it because it's easier unless specified.
- Not sure if we should assume that strings should use allocators or arenas, for now it's arenas because I don't have other use cases
@todo
- Remove static buffers from filesystem, use scratch arenas, more secure, data corruption instead of control flow corruption
*/

View File

@@ -381,7 +381,7 @@ OS_API OS_Date OS_GetDate(void) {
return result;
}
#else
#elif __linux__ || __APPLE__ || __unix__
#include <unistd.h>
#include <limits.h>
#include <sys/stat.h>
@@ -690,9 +690,9 @@ OS_API OS_Result OS_WriteFile(S8_String path, S8_String string) {
return result;
}
#endif
#endif
#if _WIN32 || __linux__ || __APPLE__ || __unix__
OS_API int OS_SystemF(const char *string, ...) {
MA_Checkpoint scratch = MA_GetScratch();
S8_FORMAT(scratch.arena, string, result);
@@ -746,3 +746,4 @@ OS_API S8_String OS_ExpandIncludes(MA_Arena *arena, S8_String filepath) {
}
return result;
}
#endif

View File

@@ -4,20 +4,6 @@
#define MA_Assertf(x, ...) assert(x)
#endif
#ifndef MA_MemoryZero
#include <string.h>
MA_API void MA_MemoryZero(void *p, size_t size) {
memset(p, 0, size);
}
#endif
#ifndef MA_MemoryCopy
#include <string.h>
MA_API void MA_MemoryCopy(void *dst, void *src, size_t size) {
memcpy(dst, src, size);
}
#endif
#ifndef MA_CMalloc
#include <stdlib.h>
#define MA_CMalloc(x) malloc(x)
@@ -41,14 +27,14 @@ MA_API void MA_MemoryCopy(void *dst, void *src, size_t size) {
#endif
MA_THREAD_LOCAL MA_SourceLoc MA_SavedSourceLoc;
MA_API void MA_SaveSourceLocEx(const char *file, int line) {
MA_API void MA_SaveSourceLocEx(const char *file, int line) {
MA_SavedSourceLoc.file = file;
MA_SavedSourceLoc.line = line;
}
MA_API size_t MA_GetAlignOffset(size_t size, size_t align) {
size_t mask = align - 1;
size_t val = size & mask;
size_t val = size & mask;
if (val) {
val = align - val;
}
@@ -67,10 +53,10 @@ MA_API size_t MA_AlignDown(size_t size, size_t align) {
}
MA_StaticFunc uint8_t *MV__AdvanceCommit(MV_Memory *m, size_t *commit_size, size_t page_size) {
size_t aligned_up_commit = MA_AlignUp(*commit_size, page_size);
size_t to_be_total_commited_size = aligned_up_commit + m->commit;
size_t aligned_up_commit = MA_AlignUp(*commit_size, page_size);
size_t to_be_total_commited_size = aligned_up_commit + m->commit;
size_t to_be_total_commited_size_clamped_to_reserve = MA_CLAMP_TOP(to_be_total_commited_size, m->reserve);
size_t adjusted_to_boundary_commit = to_be_total_commited_size_clamped_to_reserve - m->commit;
size_t adjusted_to_boundary_commit = to_be_total_commited_size_clamped_to_reserve - m->commit;
MA_Assertf(adjusted_to_boundary_commit, "Reached the virtual memory reserved boundary");
*commit_size = adjusted_to_boundary_commit;
@@ -83,9 +69,9 @@ MA_StaticFunc uint8_t *MV__AdvanceCommit(MV_Memory *m, size_t *commit_size, size
MA_API void MA_PopToPos(MA_Arena *arena, size_t pos) {
MA_Assertf(arena->len >= arena->base_len, "Bug: arena->len shouldn't ever be smaller then arena->base_len");
pos = MA_CLAMP(pos, arena->base_len, arena->len);
pos = MA_CLAMP(pos, arena->base_len, arena->len);
size_t size = arena->len - pos;
arena->len = pos;
arena->len = pos;
ASAN_POISON_MEMORY_REGION(arena->memory.data + arena->len, size);
}
@@ -103,7 +89,7 @@ MA_API void MA_Reset(MA_Arena *arena) {
MA_StaticFunc size_t MA__AlignLen(MA_Arena *a) {
size_t align_offset = a->alignment ? MA_GetAlignOffset((uintptr_t)a->memory.data + (uintptr_t)a->len, a->alignment) : 0;
size_t aligned = a->len + align_offset;
size_t aligned = a->len + align_offset;
return aligned;
}
@@ -117,8 +103,8 @@ MA_API uint8_t *MA_GetTop(MA_Arena *a) {
}
MA_API void *MA__PushSizeNonZeroed(MA_Arena *a, size_t size) {
size_t align_offset = a->alignment ? MA_GetAlignOffset((uintptr_t)a->memory.data + (uintptr_t)a->len, a->alignment) : 0;
size_t aligned_len = a->len + align_offset;
size_t align_offset = a->alignment ? MA_GetAlignOffset((uintptr_t)a->memory.data + (uintptr_t)a->len, a->alignment) : 0;
size_t aligned_len = a->len + align_offset;
size_t size_with_alignment = size + align_offset;
if (a->len + size_with_alignment > a->memory.commit) {
@@ -163,10 +149,10 @@ MA_API void *MA__PushCopy(MA_Arena *arena, void *p, size_t size) {
MA_API MA_Arena MA_PushArena(MA_Arena *arena, size_t size) {
MA_Arena result;
MA_MemoryZero(&result, sizeof(result));
result.memory.data = MA_PushArrayNonZeroed(arena, uint8_t, size);
result.memory.commit = size;
result.memory.data = MA_PushArrayNonZeroed(arena, uint8_t, size);
result.memory.commit = size;
result.memory.reserve = size;
result.alignment = arena->alignment;
result.alignment = arena->alignment;
return result;
}
@@ -187,26 +173,26 @@ MA_API void MA_MakeSureInitialized(MA_Arena *a) {
}
MA_API MA_Arena *MA_Bootstrap(void) {
MA_Arena bootstrap_arena = {0};
MA_Arena *arena = MA_PushStruct(&bootstrap_arena, MA_Arena);
*arena = bootstrap_arena;
arena->base_len = arena->len;
MA_Arena bootstrap_arena = {0};
MA_Arena *arena = MA_PushStruct(&bootstrap_arena, MA_Arena);
*arena = bootstrap_arena;
arena->base_len = arena->len;
return arena;
}
MA_API M_Allocator MA_BootstrapExclusive(void) {
MA_Arena bootstrap_arena = {0};
MA_Arena *arena = MA_PushStruct(&bootstrap_arena, MA_Arena);
*arena = bootstrap_arena;
arena->base_len = arena->len;
MA_Arena bootstrap_arena = {0};
MA_Arena *arena = MA_PushStruct(&bootstrap_arena, MA_Arena);
*arena = bootstrap_arena;
arena->base_len = arena->len;
return MA_GetExclusiveAllocator(arena);
}
MA_API void MA_InitFromBuffer(MA_Arena *arena, void *buffer, size_t size) {
arena->memory.data = (uint8_t *)buffer;
arena->memory.commit = size;
arena->memory.data = (uint8_t *)buffer;
arena->memory.commit = size;
arena->memory.reserve = size;
arena->alignment = MA_DEFAULT_ALIGNMENT;
arena->alignment = MA_DEFAULT_ALIGNMENT;
ASAN_POISON_MEMORY_REGION(arena->memory.data, arena->memory.reserve);
}
@@ -225,15 +211,15 @@ MA_API MA_Arena MA_Create() {
MA_API bool MA_IsPointerInside(MA_Arena *arena, void *p) {
uintptr_t pointer = (uintptr_t)p;
uintptr_t start = (uintptr_t)arena->memory.data;
uintptr_t stop = start + (uintptr_t)arena->len;
bool result = pointer >= start && pointer < stop;
uintptr_t start = (uintptr_t)arena->memory.data;
uintptr_t stop = start + (uintptr_t)arena->len;
bool result = pointer >= start && pointer < stop;
return result;
}
MA_API MA_Checkpoint MA_Save(MA_Arena *arena) {
MA_Checkpoint result;
result.pos = arena->len;
result.pos = arena->len;
result.arena = arena;
return result;
}
@@ -311,7 +297,7 @@ MA_API void *MA_ExclusiveAllocatorProc(void *allocator, M_AllocatorOp kind, void
if (kind == M_AllocatorOp_Reallocate) {
if (size > old_size) {
size_t size_to_push = size - old_size;
void *result = MA__PushSizeNonZeroed(arena, size_to_push);
void *result = MA__PushSizeNonZeroed(arena, size_to_push);
if (!p) p = result;
return p;
}
@@ -339,7 +325,7 @@ MA_API M_Allocator MA_GetAllocator(MA_Arena *arena) {
MA_API M_Allocator M_GetSystemAllocator(void) {
M_Allocator allocator;
allocator.obj = 0;
allocator.p = M_ClibAllocatorProc;
allocator.p = M_ClibAllocatorProc;
return allocator;
}
@@ -350,7 +336,7 @@ MA_API MA_Checkpoint MA_GetScratchEx(MA_Arena **conflicts, int conflict_count) {
MA_Arena *unoccupied = 0;
for (int i = 0; i < MA_Lengthof(MA_ScratchArenaPool); i += 1) {
MA_Arena *from_pool = MA_ScratchArenaPool + i;
unoccupied = from_pool;
unoccupied = from_pool;
for (int conflict_i = 0; conflict_i < conflict_count; conflict_i += 1) {
MA_Arena *from_conflict = conflicts[conflict_i];
if (from_pool == from_conflict) {
@@ -395,7 +381,7 @@ MA_API MV_Memory MV_Reserve(size_t size) {
MV_Memory result;
MA_MemoryZero(&result, sizeof(result));
size_t adjusted_size = MA_AlignUp(size, MV__WIN32_PAGE_SIZE);
result.data = (uint8_t *)VirtualAlloc(0, adjusted_size, MEM_RESERVE, PAGE_READWRITE);
result.data = (uint8_t *)VirtualAlloc(0, adjusted_size, MEM_RESERVE, PAGE_READWRITE);
MA_Assertf(result.data, "Failed to reserve virtual memory");
result.reserve = adjusted_size;
return result;
@@ -420,12 +406,12 @@ MA_API void MV_Deallocate(MV_Memory *m) {
}
MA_API bool MV_DecommitPos(MV_Memory *m, size_t pos) {
size_t aligned = MA_AlignDown(pos, MV__WIN32_PAGE_SIZE);
size_t adjusted_pos = MA_CLAMP_TOP(aligned, m->commit);
size_t aligned = MA_AlignDown(pos, MV__WIN32_PAGE_SIZE);
size_t adjusted_pos = MA_CLAMP_TOP(aligned, m->commit);
size_t size_to_decommit = m->commit - adjusted_pos;
if (size_to_decommit) {
uint8_t *base_address = m->data + adjusted_pos;
BOOL result = VirtualFree(base_address, size_to_decommit, MEM_DECOMMIT);
BOOL result = VirtualFree(base_address, size_to_decommit, MEM_DECOMMIT);
if (result) {
m->commit -= size_to_decommit;
return true;
@@ -434,7 +420,7 @@ MA_API bool MV_DecommitPos(MV_Memory *m, size_t pos) {
return false;
}
#else
#elif __unix__ || __linux__ || __APPLE__
#include <sys/mman.h>
#define MV__UNIX_PAGE_SIZE 4096
MA_API MV_Memory MV_Reserve(size_t size) {
@@ -465,4 +451,17 @@ MA_API void MV_Deallocate(MV_Memory *m) {
int result = munmap(m->data, m->reserve);
MA_Assertf(result == 0, "Failed to release virtual memory using munmap");
}
#else
MA_API MV_Memory MV_Reserve(size_t size) {
MV_Memory result = {0};
return result;
}
MA_API bool MV_Commit(MV_Memory *m, size_t commit) {
return false;
}
MA_API void MV_Deallocate(MV_Memory *m) {
}
#endif

View File

@@ -55,6 +55,16 @@ typedef struct MA_SourceLoc MA_SourceLoc;
#endif
#endif
#ifndef MA_MemoryZero
#include <string.h>
#define MA_MemoryZero(p, size) memset(p, 0, size)
#endif
#ifndef MA_MemoryCopy
#include <string.h>
#define MA_MemoryCopy(dst, src, size) memcpy(dst, src, size);
#endif
typedef enum M_AllocatorOp {
M_AllocatorOp_Invalid,
M_AllocatorOp_Allocate,
@@ -158,8 +168,6 @@ MA_API void MA_PopSize(MA_Arena *arena, size_t size);
MA_API void MA_DeallocateArena(MA_Arena *arena);
MA_API void MA_Reset(MA_Arena *arena);
MA_API void MA_MemoryZero(void *p, size_t size);
MA_API void MA_MemoryCopy(void *dst, void *src, size_t size);
MA_API size_t MA_GetAlignOffset(size_t size, size_t align);
MA_API size_t MA_AlignUp(size_t size, size_t align);
MA_API size_t MA_AlignDown(size_t size, size_t align);

View File

@@ -31,19 +31,19 @@ IO_StaticFunc int IO_Strlen(char *string) {
return len;
}
void (*IO_User_OutputMessage)(int kind, const char *file, int line, char *str, int len);
IO_THREAD_LOCAL void (*IO_User_OutputMessage)(int kind, const char *file, int line, char *str, int len);
IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) {
va_list args1;
va_list args2;
char buff[2048];
char buff[2048];
va_start(args1, msg);
va_copy(args2, args1);
int size = IO_VSNPRINTF(buff, sizeof(buff), msg, args2);
va_end(args2);
char *new_buffer = 0;
char *new_buffer = 0;
char *user_message = buff;
if (size >= sizeof(buff)) {
size += 4;
@@ -55,14 +55,14 @@ IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) {
IO_ErrorResult ret = IO_ErrorResult_Continue;
{
char buff2[2048];
char buff2[2048];
char *result = buff2;
char *b = 0;
int size2 = IO_SNPRINTF(buff2, sizeof(buff2), "%s(%d): error: %s \n", file, line, user_message);
char *b = 0;
int size2 = IO_SNPRINTF(buff2, sizeof(buff2), "%s(%d): error: %s \n", file, line, user_message);
if (size2 >= sizeof(buff2)) {
size2 += 4;
b = (char *)IO_ALLOCATE(size2);
size2 = IO_SNPRINTF(b, size2, "%s(%d): error: %s \n", file, line, user_message);
b = (char *)IO_ALLOCATE(size2);
size2 = IO_SNPRINTF(b, size2, "%s(%d): error: %s \n", file, line, user_message);
result = b;
}
@@ -89,7 +89,7 @@ IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ..
// case.
va_list args1;
va_list args2;
char buff[2048];
char buff[2048];
va_start(args1, msg);
va_copy(args2, args1);
@@ -97,7 +97,7 @@ IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ..
va_end(args2);
char *new_buffer = 0;
char *result = buff;
char *result = buff;
if (size >= sizeof(buff)) {
size += 4;
new_buffer = (char *)IO_ALLOCATE(size);
@@ -108,8 +108,7 @@ IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ..
if (IO_User_OutputMessage) {
IO_User_OutputMessage(kind, file, line, result, size);
}
else {
} else {
IO_OutputMessage(result, size);
}
@@ -118,9 +117,9 @@ IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ..
}
}
IO_API bool IO__FatalError(char *msg) {
int len = IO_Strlen(msg);
IO_ErrorResult result = IO_OutputError(msg, len);
IO_API bool IO__FatalError(const char *msg) {
int len = IO_Strlen((char *)msg);
IO_ErrorResult result = IO_OutputError((char *)msg, len);
if (result == IO_ErrorResult_Exit) {
IO_Exit(1);
}
@@ -130,8 +129,7 @@ IO_API bool IO__FatalError(char *msg) {
IO_API void IO_Print(int kind, const char *file, int line, char *msg, int len) {
if (IO_User_OutputMessage) {
IO_User_OutputMessage(kind, file, line, msg, len);
}
else {
} else {
IO_OutputMessage(msg, len);
}
}
@@ -177,7 +175,7 @@ IO_API IO_ErrorResult IO_OutputError(char *str, int len) {
// Limit size of error output message
char tmp = 0;
if (len > 4096) {
tmp = str[4096];
tmp = str[4096];
str[4096] = 0;
}
@@ -188,8 +186,7 @@ IO_API IO_ErrorResult IO_OutputError(char *str, int len) {
}
result = IO_ErrorResult_Exit;
}
else {
} else {
result = IO_ErrorResult_Break;
}
@@ -203,9 +200,8 @@ IO_API IO_ErrorResult IO_OutputError(char *str, int len) {
IO_API void IO_Exit(int error_code) {
ExitProcess(error_code);
}
#else // _WIN32 else // LIBC
#elif __linux__ || __unix__ || __APPLE__
#include <stdio.h>
IO_API IO_ErrorResult IO_OutputError(char *str, int len) {
fprintf(stderr, "%.*s", len, str);
return IO_ErrorResult_Exit;
@@ -222,4 +218,19 @@ IO_API void IO_Exit(int error_code) {
IO_API bool IO_IsDebuggerPresent(void) {
return false;
}
#else
IO_API IO_ErrorResult IO_OutputError(char *str, int len) {
return IO_ErrorResult_Exit;
}
IO_API void IO_OutputMessage(char *str, int len) {
}
IO_API void IO_Exit(int error_code) {
}
IO_API bool IO_IsDebuggerPresent(void) {
return false;
}
#endif // LIBC

View File

@@ -22,6 +22,22 @@ typedef enum IO_ErrorResult {
#define IO_DebugBreak() (__builtin_trap(), 0)
#endif
#ifndef IO_THREAD_LOCAL
#if defined(__cplusplus) && __cplusplus >= 201103L
#define IO_THREAD_LOCAL thread_local
#elif defined(__GNUC__)
#define IO_THREAD_LOCAL __thread
#elif defined(_MSC_VER)
#define IO_THREAD_LOCAL __declspec(thread)
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
#define IO_THREAD_LOCAL _Thread_local
#elif defined(__TINYC__)
#define IO_THREAD_LOCAL _Thread_local
#else
#error Couldnt figure out thread local, needs to be provided manually
#endif
#endif
#if defined(__has_attribute)
#if __has_attribute(format)
#define IO__PrintfFormat(fmt, va) __attribute__((format(printf, fmt, va)))
@@ -33,14 +49,14 @@ typedef enum IO_ErrorResult {
#endif
typedef void IO_MessageHandler(int kind, const char *file, int line, char *str, int len);
extern void (*IO_User_OutputMessage)(int kind, const char *file, int line, char *str, int len);
extern IO_THREAD_LOCAL void (*IO_User_OutputMessage)(int kind, const char *file, int line, char *str, int len);
#define IO__STRINGIFY(x) #x
#define IO__TOSTRING(x) IO__STRINGIFY(x)
#define IO_LINE IO__TOSTRING(__LINE__)
#define IO_Assert(x) !(x) && IO__FatalError((char *)(__FILE__ "(" IO_LINE "): " \
"error: " #x "\n")) && \
#define IO_Assert(x) !(x) && IO__FatalError((__FILE__ "(" IO_LINE "): " \
"error: " #x "\n")) && \
IO_DebugBreak()
#define IO_FatalErrorf(...) \
do { \
@@ -69,22 +85,22 @@ extern void (*IO_User_OutputMessage)(int kind, const char *file, int line, char
IO_InvalidCodepath(); \
}
#define IO_InvalidCodepath() IO_FatalError("This codepath is invalid")
#define IO_InvalidDefaultCase() \
default: { \
IO_FatalError("Entered invalid switch statement case"); \
}
#define IO_InvalidDefaultCase() \
default: { \
IO_FatalError("Entered invalid switch statement case"); \
}
#define IO_Todo() IO_FatalError("This codepath is not implemented yet")
IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) IO__PrintfFormat(3, 4);
IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ...) IO__PrintfFormat(4, 5);
IO_API bool IO__FatalError(char *msg);
IO_API void IO_Print(int kind, const char *file, int line, char *msg, int len);
IO_API void IO_OutputMessage(char *str, int len);
IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) IO__PrintfFormat(3, 4);
IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ...) IO__PrintfFormat(4, 5);
IO_API bool IO__FatalError(const char *msg);
IO_API void IO_Print(int kind, const char *file, int line, char *msg, int len);
IO_API void IO_OutputMessage(char *str, int len);
IO_API IO_ErrorResult IO_OutputError(char *str, int len);
IO_API void IO_Exit(int error_code);
IO_API bool IO_IsDebuggerPresent(void);
IO_API void IO_Exit(int error_code);
IO_API bool IO_IsDebuggerPresent(void);
static const int IO_KindPrintf = 1;
static const int IO_KindPrintf = 1;
static const int IO_KindWarningf = 2;
#define IO_Printf(...) IO__Printf(IO_KindPrintf, __FILE__, __LINE__, __VA_ARGS__)

View File

@@ -11,6 +11,7 @@
#elif defined(__linux__)
#define OS_POSIX 1
#define OS_LINUX 1
#elif OS_WASM
#else
#error Unsupported platform
#endif
@@ -109,6 +110,8 @@
#define OS_NAME "linux"
#elif OS_MAC
#define OS_NAME "mac_os"
#elif OS_WASM
#define OS_NAME "wasm"
#else
#error couldnt figure out OS
#endif

View File

@@ -4,6 +4,51 @@
#include "test_arena.cpp"
#include "test_lexer.cpp"
// ./a.exe -scratch
// ./a.exe -quick
// ./a.exe -run_tests a.test b.test c.test
// ./a.exe --break_on_error
// ./a.exe -build=release
// ./a.exe --help
//
void TestCmdParser() {
const char *argv[] = {
"exe",
"--build_scratch",
"-tests",
"a",
"b",
"c",
"--things",
"1234",
"asdsa",
"-build",
"release",
};
int argc = MA_Lengthof(argv);
MA_Checkpoint scratch = MA_GetScratch();
bool build_scratch = false;
S8_List test_list = {0};
S8_List test_things = {0};
int build_profile = 0;
const char *build_profiles[] = {"debug", "release"};
int build_profiles_count = MA_Lengthof(build_profiles);
CmdParser p = MakeCmdParser(scratch.arena, argc, (char **)argv, "this is a test");
AddBool(&p, &build_scratch, "build_scratch", "builds a sandbox where I experiment with things");
AddList(&p, &test_list, "tests", "list of specific tests to run");
AddList(&p, &test_things, "things", "list of things");
AddEnum(&p, &build_profile, "build", "choose build profile", build_profiles, build_profiles_count);
bool success = ParseCmd(scratch.arena, &p);
IO_Assertf(success, "failed to parse cmd");
IO_Assert(build_scratch);
IO_Assert(test_list.node_count == 3);
IO_Assert(test_things.node_count == 2);
IO_Assert(build_profile == 1);
MA_ReleaseScratch(scratch);
}
int main() {
TestSimpleInsertAndIntegrity();
TestStrings();
@@ -20,7 +65,6 @@ int main() {
TestBootstrapExclusive();
TestBootstrapArenaClear();
// @todo: github worker fails on this:
TestClexer();
// Unicode iteration over codepoints using For
@@ -40,7 +84,7 @@ int main() {
// List iteration using For
{
MA_Scratch scratch;
S8_List list = {};
S8_List list = {};
S8_AddF(scratch, &list, "1");
S8_AddF(scratch, &list, "2");
S8_AddF(scratch, &list, "3");