Restructuring and add format strings typechecking for clang

This commit is contained in:
Krzosa Karol
2024-01-12 09:54:41 +01:00
parent a3c0a63ee2
commit f68500a804
13 changed files with 61 additions and 46 deletions

View File

@@ -5,13 +5,13 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: sudo apt install g++ - run: sudo apt install g++
- run: g++ code/build_main.cpp -o bld && ./bld - run: g++ tools/build_main.cpp -o bld && ./bld
run-and-compile-mac: run-and-compile-mac:
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: brew install llvm - run: brew install llvm
- run: clang++ code/build_main.cpp -std=c++11 -o bld && ./bld - run: clang++ tools/build_main.cpp -std=c++11 -o bld && ./bld
run-and-compile-windows: run-and-compile-windows:
runs-on: windows-latest runs-on: windows-latest
steps: steps:

View File

@@ -3,7 +3,6 @@ call ../misc/compile_setup.bat
mkdir build mkdir build
cd build cd build
cl -Fe:bld.exe ../code/build_main.cpp -WX -W3 -wd4200 -diagnostics:column -nologo -Zi -D_CRT_SECURE_NO_WARNINGS cl -Fe:bld.exe ../tools/build_main.cpp -WX -W3 -wd4200 -diagnostics:column -nologo -Zi -D_CRT_SECURE_NO_WARNINGS
cd .. cd ..
build\bld.exe build\bld.exe

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
gcc -o bld code/build_main.cpp -g gcc -o bld tools/build_main.cpp -g
./bld ./bld

View File

@@ -1,4 +1,4 @@
#include "code/build_lib.cpp" #include "tools/build_lib.cpp"
void CompileFiles(Strs cc, Strs files); void CompileFiles(Strs cc, Strs files);
int ReturnValue = 0; int ReturnValue = 0;
@@ -21,17 +21,17 @@ void CompileFiles(Strs cc, Strs files) {
Str exe = FilenameWithoutExt(files[0]); Str exe = FilenameWithoutExt(files[0]);
Str filestr = Merge(files); Str filestr = Merge(files);
if (cc == "gcc") { if (cc == "gcc") {
result = OS_SystemF("g++ -o %Q.exe %Q -g -Wno-write-strings -fsanitize=address", exe, filestr); result = OS_SystemF("g++ -o %.*s.exe %.*s -g -Wno-write-strings -fsanitize=address", S8_Expand(exe), S8_Expand(filestr));
} }
else if (cc == "clang") { else if (cc == "clang") {
result = OS_SystemF("clang++ -std=c++11 -o %Q.exe %Q -g -Wno-writable-strings -fsanitize=address", exe, filestr); result = OS_SystemF("clang++ -std=c++11 -o %.*s.exe %.*s -fdiagnostics-absolute-paths -g -Wno-writable-strings -fsanitize=address", S8_Expand(exe), S8_Expand(filestr));
} }
else { else {
result = OS_SystemF("cl -Fe:%Q.exe %Q -Zi -WX -W3 -wd4200 -diagnostics:column -nologo -D_CRT_SECURE_NO_WARNINGS -fsanitize=address -RTC1", exe, filestr); result = OS_SystemF("cl -Fe:%.*s.exe %.*s -FC -Zi -WX -W3 -wd4200 -diagnostics:column -nologo -D_CRT_SECURE_NO_WARNINGS -fsanitize=address -RTC1", S8_Expand(exe), S8_Expand(filestr));
} }
if (result == 0) { if (result == 0) {
result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%Q.exe", exe); result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%.*s.exe", S8_Expand(exe));
} }
else { else {
ReturnValue = result; ReturnValue = result;

View File

@@ -169,7 +169,8 @@ OS_API S8_List OS_ListDir(MA_Arena *arena, S8_String path, unsigned flags) {
bool dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; bool dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
S8_String filename = UTF_CreateStringFromWidechar(scratch.arena, ffd.cFileName, S8_WideLength(ffd.cFileName)); S8_String filename = UTF_CreateStringFromWidechar(scratch.arena, ffd.cFileName, S8_WideLength(ffd.cFileName));
S8_String rel_abs_path = S8_Format(scratch.arena, "%Q/%Q%Q", it->string, filename, dir ? S8_Lit("/") : S8_Lit("")); S8_String is_dir = dir ? S8_Lit("/") : S8_Lit("");
S8_String rel_abs_path = S8_Format(scratch.arena, "%.*s/%.*s%.*s", S8_Expand(it->string), S8_Expand(filename), S8_Expand(is_dir));
if (flags & OS_RELATIVE_PATHS) { if (flags & OS_RELATIVE_PATHS) {
S8_Add(arena, &result, rel_abs_path); S8_Add(arena, &result, rel_abs_path);
} }
@@ -498,12 +499,12 @@ OS_API S8_List OS_ListDir(MA_Arena *arena, S8_String path, unsigned flags) {
continue; continue;
} }
S8_String n = S8_Format(scratch.arena, "%Q/%s", path, dir->d_name); S8_String n = S8_Format(scratch.arena, "%.*s/%s", S8_Expand(path), dir->d_name);
if ((flags & OS_RELATIVE_PATHS) == 0) { if ((flags & OS_RELATIVE_PATHS) == 0) {
n = OS_GetAbsolutePath(scratch.arena, n); n = OS_GetAbsolutePath(scratch.arena, n);
} }
if (dir->d_type == DT_DIR) { if (dir->d_type == DT_DIR) {
n = S8_Format(scratch.arena, "%Q/", n); n = S8_Format(scratch.arena, "%.*s/", S8_Expand(n));
} }
S8_AddNode(arena, &result, S8_Copy(arena, n)); S8_AddNode(arena, &result, S8_Copy(arena, n));
@@ -525,18 +526,18 @@ OS_API OS_Result OS_MakeDir(S8_String path) {
OS_API OS_Result OS_CopyFile(S8_String from, S8_String to, bool overwrite) { OS_API OS_Result OS_CopyFile(S8_String from, S8_String to, bool overwrite) {
const char *ow = overwrite ? "-n" : ""; const char *ow = overwrite ? "-n" : "";
int result = OS_SystemF("cp %s %Q %Q", ow, from, to); int result = OS_SystemF("cp %s %.*s %.*s", ow, S8_Expand(from), S8_Expand(to));
return result == 0 ? OS_SUCCESS : OS_FAILURE; return result == 0 ? OS_SUCCESS : OS_FAILURE;
} }
OS_API OS_Result OS_DeleteFile(S8_String path) { OS_API OS_Result OS_DeleteFile(S8_String path) {
int result = OS_SystemF("rm %Q"); int result = OS_SystemF("rm %.*s", S8_Expand(path));
return result == 0 ? OS_SUCCESS : OS_FAILURE; return result == 0 ? OS_SUCCESS : OS_FAILURE;
} }
OS_API OS_Result OS_DeleteDir(S8_String path, unsigned flags) { OS_API OS_Result OS_DeleteDir(S8_String path, unsigned flags) {
IO_Assert(flags & OS_RECURSIVE); IO_Assert(flags & OS_RECURSIVE);
int result = OS_SystemF("rm -r %Q"); int result = OS_SystemF("rm -r %.*s", S8_Expand(path));
return result == 0 ? OS_SUCCESS : OS_FAILURE; return result == 0 ? OS_SUCCESS : OS_FAILURE;
} }

View File

@@ -9,15 +9,11 @@
#endif #endif
#endif #endif
//@begin gen_structs
typedef struct RandomSeed RandomSeed; typedef struct RandomSeed RandomSeed;
//@end gen_structs
struct RandomSeed { struct RandomSeed {
uint64_t a; uint64_t a;
}; };
//@begin gen_api_funcs
HASH_API_FUNCTION uint64_t HashBytes(void *data, uint64_t size); HASH_API_FUNCTION uint64_t HashBytes(void *data, uint64_t size);
HASH_API_FUNCTION RandomSeed MakeRandomSeed(uint64_t value); HASH_API_FUNCTION RandomSeed MakeRandomSeed(uint64_t value);
HASH_API_FUNCTION uint64_t GetRandomU64(RandomSeed *state); HASH_API_FUNCTION uint64_t GetRandomU64(RandomSeed *state);
@@ -25,7 +21,6 @@ HASH_API_FUNCTION int GetRandomRangeI(RandomSeed *seed, int first, int last_incl
HASH_API_FUNCTION double GetRandomNormal(RandomSeed *series); HASH_API_FUNCTION double GetRandomNormal(RandomSeed *series);
HASH_API_FUNCTION double GetRandomNormalRange(RandomSeed *seed, double min, double max); HASH_API_FUNCTION double GetRandomNormalRange(RandomSeed *seed, double min, double max);
HASH_API_FUNCTION uint64_t HashMix(uint64_t x, uint64_t y); HASH_API_FUNCTION uint64_t HashMix(uint64_t x, uint64_t y);
//@end gen_api_funcs
#define WRAP_AROUND_POWER_OF_2(x, pow2) (((x) & ((pow2)-1llu))) #define WRAP_AROUND_POWER_OF_2(x, pow2) (((x) & ((pow2)-1llu)))
static inline float GetRandomNormalF(RandomSeed *series) { return (float)GetRandomNormal(series); } static inline float GetRandomNormalF(RandomSeed *series) { return (float)GetRandomNormal(series); }

View File

@@ -21,6 +21,16 @@ typedef enum IO_ErrorResult {
#define IO_DebugBreak() (IO_Exit(1), 0) #define IO_DebugBreak() (IO_Exit(1), 0)
#endif #endif
#if defined(__has_attribute)
#if __has_attribute(format)
#define IO__PrintfFormat(fmt, va) __attribute__((format(printf, fmt, va)))
#endif
#endif
#ifndef IO__PrintfFormat
#define IO__PrintfFormat(fmt, va)
#endif
extern void (*IO_User_OutputMessage)(char *str, int len); extern void (*IO_User_OutputMessage)(char *str, int len);
#define IO__STRINGIFY(x) #x #define IO__STRINGIFY(x) #x
@@ -63,8 +73,8 @@ extern void (*IO_User_OutputMessage)(char *str, int len);
} }
#define IO_Todo() IO_FatalError("This codepath is not implemented yet") #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_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) IO__PrintfFormat(3, 4);
IO_API void IO_Printf(const char *msg, ...); IO_API void IO_Printf(const char *msg, ...) IO__PrintfFormat(1, 2);
IO_API bool IO__FatalError(char *msg); IO_API bool IO__FatalError(char *msg);
IO_API void IO_Print(char *msg); IO_API void IO_Print(char *msg);
IO_API void IO_OutputMessage(char *str, int len); IO_API void IO_OutputMessage(char *str, int len);

View File

@@ -14,7 +14,7 @@ LIB_Library LIB_LoadLibrary(char *str) {
} }
void *LIB_LoadSymbol(LIB_Library lib, char *symbol) { void *LIB_LoadSymbol(LIB_Library lib, char *symbol) {
void *result = GetProcAddress((HMODULE)lib, symbol); void *result = (void *)GetProcAddress((HMODULE)lib, symbol);
return result; return result;
} }

View File

@@ -44,6 +44,16 @@ enum {
S8_MATCH_FIND_LAST = 32, S8_MATCH_FIND_LAST = 32,
}; };
#if defined(__has_attribute)
#if __has_attribute(format)
#define S8__PrintfFormat(fmt, va) __attribute__((format(printf, fmt, va)))
#endif
#endif
#ifndef S8__PrintfFormat
#define S8__PrintfFormat(fmt, va)
#endif
#define S8_Lit(string) S8_Make((char *)string, sizeof(string) - 1) #define S8_Lit(string) S8_Make((char *)string, sizeof(string) - 1)
#define S8_ConstLit(string) \ #define S8_ConstLit(string) \
{ string, sizeof(string) - 1 } { string, sizeof(string) - 1 }
@@ -104,7 +114,7 @@ S8_API S8_String S8_MakeFromChar(char *string);
S8_API S8_String S8_MakeEmpty(void); S8_API S8_String S8_MakeEmpty(void);
S8_API S8_List S8_MakeEmptyList(void); S8_API S8_List S8_MakeEmptyList(void);
S8_API S8_String S8_FormatV(S8_Allocator allocator, const char *str, va_list args1); S8_API S8_String S8_FormatV(S8_Allocator allocator, const char *str, va_list args1);
S8_API S8_String S8_Format(S8_Allocator allocator, const char *str, ...); S8_API S8_String S8_Format(S8_Allocator allocator, const char *str, ...) S8__PrintfFormat(2, 3);
S8_API S8_Node *S8_CreateNode(S8_Allocator allocator, S8_String string); S8_API S8_Node *S8_CreateNode(S8_Allocator allocator, S8_String string);
S8_API void S8_ReplaceNodeString(S8_List *list, S8_Node *node, S8_String new_string); S8_API void S8_ReplaceNodeString(S8_List *list, S8_Node *node, S8_String new_string);
S8_API void S8_AddExistingNode(S8_List *list, S8_Node *node); S8_API void S8_AddExistingNode(S8_List *list, S8_Node *node);
@@ -115,4 +125,4 @@ S8_API S8_List S8_CopyList(S8_Allocator allocator, S8_List a);
S8_API S8_List S8_ConcatLists(S8_Allocator allocator, S8_List a, S8_List b); S8_API S8_List S8_ConcatLists(S8_Allocator allocator, S8_List a, S8_List b);
S8_API S8_Node *S8_AddNode(S8_Allocator allocator, S8_List *list, S8_String string); S8_API S8_Node *S8_AddNode(S8_Allocator allocator, S8_List *list, S8_String string);
S8_API S8_Node *S8_Add(S8_Allocator allocator, S8_List *list, S8_String string); S8_API S8_Node *S8_Add(S8_Allocator allocator, S8_List *list, S8_String string);
S8_API S8_String S8_AddF(S8_Allocator allocator, S8_List *list, const char *str, ...); S8_API S8_String S8_AddF(S8_Allocator allocator, S8_List *list, const char *str, ...) S8__PrintfFormat(3, 4);

View File

@@ -38,10 +38,10 @@
#define TABLE_ASSERT(x) assert(x) #define TABLE_ASSERT(x) assert(x)
#endif #endif
#ifndef TABLE_SET_DEFAULT_ALLOCATOR
#define TABLE_SET_DEFAULT_ALLOCATOR
// Example: // Example:
// #define TABLE_SET_DEFAULT_ALLOCATOR if (!allocator) allocator = global_heap; // #define TABLE_SET_DEFAULT_ALLOCATOR if (!allocator) allocator = global_heap;
#ifndef TABLE_SET_DEFAULT_ALLOCATOR
#define TABLE_SET_DEFAULT_ALLOCATOR
#endif #endif
#ifndef TABLE_HASH_BYTES #ifndef TABLE_HASH_BYTES

View File

@@ -55,10 +55,6 @@ int main() {
S8_String dir_path = OS_GetExeDir(&arena); S8_String dir_path = OS_GetExeDir(&arena);
S8_String work_path = OS_GetWorkingDir(&arena); S8_String work_path = OS_GetWorkingDir(&arena);
S8_String abs_path = OS_GetAbsolutePath(&arena, read_file_path); S8_String abs_path = OS_GetAbsolutePath(&arena, read_file_path);
// IO_Printf("Exe path = %Q\n", exe_path);
// IO_Printf("Dir path = %Q\n", dir_path);
// IO_Printf("Working path = %Q\n", work_path);
// IO_Printf("Abs path = %Q\n", abs_path);
IO_Assert(OS_IsDir(dir_path)); IO_Assert(OS_IsDir(dir_path));
IO_Assert(!OS_IsFile(dir_path)); IO_Assert(!OS_IsFile(dir_path));

View File

@@ -23,6 +23,10 @@ RELEASE_LINK = -opt:ref -opt:icf
/RTC1 = runtime error checks /RTC1 = runtime error checks
/opt:ref = eliminates functions and data that are never referenced /opt:ref = eliminates functions and data that are never referenced
/opt:icf = eliminates redundant 'COMDAT's /opt:icf = eliminates redundant 'COMDAT's
----------------- CLANG -----------------
FLAGS = -fdiagnostics-absolute-paths -g -Wno-writable-strings
DEBUG = -fsanitize=address
*/ */
#ifndef _CRT_SECURE_NO_WARNINGS #ifndef _CRT_SECURE_NO_WARNINGS
@@ -37,7 +41,7 @@ RELEASE_LINK = -opt:ref -opt:icf
#define CL_VSNPRINTF stbsp_vsnprintf #define CL_VSNPRINTF stbsp_vsnprintf
#define CL_SNPRINTF stbsp_snprintf #define CL_SNPRINTF stbsp_snprintf
#define AND_CL_STRING_TERMINATE_ON_NEW_LINE #define AND_CL_STRING_TERMINATE_ON_NEW_LINE
#include "clexer.c" #include "../code/clexer.c"
#define SRC_CACHE_ENTRY_COUNT 1024 #define SRC_CACHE_ENTRY_COUNT 1024
struct SRC_CacheEntry { struct SRC_CacheEntry {
@@ -316,7 +320,7 @@ void MakeDir(char *str) { OS_MakeDir(S8_MakeFromChar(str)); }
void ChangeDir(char *str) { OS_SetWorkingDir(S8_MakeFromChar(str)); } void ChangeDir(char *str) { OS_SetWorkingDir(S8_MakeFromChar(str)); }
int Run(Strs s) { int Run(Strs s) {
Str cmd = Merge(s); Str cmd = Merge(s);
return OS_SystemF("%Q", cmd); return OS_SystemF("%.*s", S8_Expand(cmd));
} }
Strs ListDir(char *dir) { Strs ListDir(char *dir) {
@@ -328,9 +332,9 @@ Strs ListDir(char *dir) {
void ReportError(S8_String it) { void ReportError(S8_String it) {
IO_FatalErrorf("Invalid command line argument syntax! Expected a key value pair!\n" IO_FatalErrorf("Invalid command line argument syntax! Expected a key value pair!\n"
"Here is the wrong argument: %Q\n" "Here is the wrong argument: %.*s\n"
"Here is a good example: bld.exe profile=release platform=windows\n", "Here is a good example: bld.exe profile=release platform=windows\n",
it); S8_Expand(it));
} }
#ifndef BUILD_MAIN #ifndef BUILD_MAIN
@@ -347,7 +351,7 @@ int main(int argc, char **argv) {
S8_String value = S8_Skip(it, idx + 1); S8_String value = S8_Skip(it, idx + 1);
if (key.len == 0) ReportError(it); if (key.len == 0) ReportError(it);
if (value.len == 0) ReportError(it); if (value.len == 0) ReportError(it);
IO_Printf("[%d] %Q = %Q\n", i, key, value); IO_Printf("[%d] %.*s = %.*s\n", i, S8_Expand(key), S8_Expand(value));
CMDLine.put(key, value); CMDLine.put(key, value);
} }

View File

@@ -4,7 +4,8 @@
int main(int argument_count, char **arguments) { int main(int argument_count, char **arguments) {
OS_MakeDir(S8_Lit("build")); OS_MakeDir(S8_Lit("build"));
OS_SetWorkingDir(S8_Lit("build")); OS_SetWorkingDir(S8_Lit("build"));
IO_Printf("WORKING DIR: %Q\n", OS_GetWorkingDir(Perm)); S8_String working_dir = OS_GetWorkingDir(Perm);
IO_Printf("WORKING DIR: %.*s\n", S8_Expand(working_dir));
S8_String cc = ON_WINDOWS("cl"_s) ON_MAC("clang"_s) ON_LINUX("gcc"_s); S8_String cc = ON_WINDOWS("cl"_s) ON_MAC("clang"_s) ON_LINUX("gcc"_s);
S8_String cache_filename = "build_tool.cache"_s; S8_String cache_filename = "build_tool.cache"_s;
@@ -17,7 +18,7 @@ int main(int argument_count, char **arguments) {
break; break;
} }
cmdline_args = S8_Format(Perm, "%Q%Q ", cmdline_args, arg); cmdline_args = S8_Format(Perm, "%.*s%.*s ", S8_Expand(cmdline_args), S8_Expand(arg));
} }
SRC_InitCache(Perm, cache_filename); SRC_InitCache(Perm, cache_filename);
@@ -33,29 +34,28 @@ int main(int argument_count, char **arguments) {
} }
if (build_file.str == 0) { if (build_file.str == 0) {
IO_Printf("IDLE Nothing to do, couldnt find build file in current dir: %Q, exiting ... \n", OS_GetWorkingDir(Perm)); IO_Printf("IDLE Nothing to do, couldnt find build file in current dir: %.*s, exiting ... \n", S8_Expand(working_dir));
return 0; return 0;
} }
} }
S8_String a = S8_ChopLastPeriod(build_file); S8_String a = S8_ChopLastPeriod(build_file);
S8_String b = S8_SkipToLastSlash(a); S8_String b = S8_SkipToLastSlash(a);
S8_String exe_name = S8_Format(Perm, "%Q.exe", b); S8_String exe_name = S8_Format(Perm, "%.*s.exe", S8_Expand(b));
// @todo: add search path?
// Compile the build file only if code changed // Compile the build file only if code changed
if (SRC_WasModified(build_file, exe_name)) { if (SRC_WasModified(build_file, exe_name)) {
double time = OS_GetTime(); double time = OS_GetTime();
int result = 0; int result = 0;
if (cc == "cl"_s) { if (cc == "cl"_s) {
result = OS_SystemF("cl %Q -Fe:%Q -WX -W3 -wd4200 -diagnostics:column -nologo -Zi", build_file, exe_name); result = OS_SystemF("cl %.*s -Fe:%.*s -WX -W3 -wd4200 -diagnostics:column -nologo -Zi", S8_Expand(build_file), S8_Expand(exe_name));
} }
else if (cc == "clang"_s) { else if (cc == "clang"_s) {
result = OS_SystemF("clang++ -std=c++11 -Wno-writable-strings %Q -o %Q -g", build_file, exe_name); result = OS_SystemF("clang++ -std=c++11 -Wno-writable-strings %.*s -o %.*s -g", S8_Expand(build_file), S8_Expand(exe_name));
} }
else { else {
IO_Assert(cc == "gcc"_s); IO_Assert(cc == "gcc"_s);
result = OS_SystemF("gcc -Wno-write-strings %Q -o %Q -g", build_file, exe_name); result = OS_SystemF("gcc -Wno-write-strings %.*s -o %.*s -g", S8_Expand(build_file), S8_Expand(exe_name));
} }
if (result != 0) { if (result != 0) {
@@ -69,7 +69,7 @@ int main(int argument_count, char **arguments) {
// Run the build file // Run the build file
double time = OS_GetTime(); double time = OS_GetTime();
if (build_file.str) { if (build_file.str) {
int result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%Q %Q", exe_name, cmdline_args); int result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%.*s %.*s", S8_Expand(exe_name), S8_Expand(cmdline_args));
if (result != 0) { if (result != 0) {
printf("FAILED execution of the build file!\n"); printf("FAILED execution of the build file!\n");
return 1; return 1;