Many changes, building many targets at the same time

This commit is contained in:
Krzosa Karol
2024-01-27 19:32:12 +01:00
parent e39cd78546
commit 43f770b790
18 changed files with 386 additions and 58 deletions

1
.gitignore vendored
View File

@@ -10,6 +10,7 @@
*.10x *.10x
*.sublime-project *.sublime-project
*.sublime-workspace *.sublime-workspace
*.rdbg
backup.* backup.*
bld bld
imgui.ini imgui.ini

View File

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

View File

@@ -1,3 +1,3 @@
#!/usr/bin/env bash #!/usr/bin/env bash
gcc -o bld build_tool/main.cpp -g g++ -o bld build_tool/main.cpp -g
./bld ./bld

View File

@@ -7,8 +7,9 @@ int main(int argc, char **argv) {
Array<S8_String> cmd = CMD_Make(argv, argc); Array<S8_String> cmd = CMD_Make(argv, argc);
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"));
Compile(cc, "../tests/test_main.cpp"); Compile(cc, "../tests/test_thread.cpp");
Compile(cc, "../tests/test_filesystem.c"); // Compile(cc, "../tests/test_main.cpp");
// Compile(cc, "../tests/test_filesystem.c");
return ReturnValue; return ReturnValue;
} }
@@ -18,43 +19,46 @@ void Compile(S8_String cc, S8_String file) {
S8_String name_no_ext = S8_GetNameNoExt(file); S8_String name_no_ext = S8_GetNameNoExt(file);
S8_String exe = Fmt("%.*s.exe", S8_Expand(name_no_ext)); S8_String exe = Fmt("%.*s.exe", S8_Expand(name_no_ext));
bool is_cpp = S8_EndsWith(file, ".cpp");
if (cc == "cl") { if (cc == "cl") {
Array<S8_String> flags = Split("/MP /Zi -D_CRT_SECURE_NO_WARNINGS /GF /Gm- /Oi");
flags += Split("/FC /WX /W3 /wd4200 /diagnostics:column /nologo");
flags += Split("/GR- /EHa-");
flags += Split("-RTC1");
Array<S8_String> link = Split("/link /incremental:no"); Array<S8_String> flags = {Perm};
S8_String name = Fmt("/Fe:%.*s", S8_Expand(exe)); flags += "/MP /Zi -D_CRT_SECURE_NO_WARNINGS";
flags += "/FC /WX /W3 /wd4200 /diagnostics:column /nologo";
flags += "/GF /Gm- /Oi";
flags += "/GR- /EHa-";
flags += "/D_DEBUG -RTC1 -Od";
flags += Fmt("/Fe:%.*s", S8_Expand(exe));
result = Run(cc + file + name + flags + link); Array<S8_String> link = {Perm};
link += "/link /incremental:no";
result = Run(cc + file + flags + link);
} }
else if (cc == "clang") { else if (cc == "clang") {
Array<S8_String> flags = Split("-g -Wno-write-strings -fdiagnostics-absolute-paths"); if (is_cpp) cc = "clang++";
Array<S8_String> flags = {Perm};
flags += "-g -Wno-write-strings";
flags += "-fdiagnostics-absolute-paths";
flags += "-fsanitize=address"; flags += "-fsanitize=address";
if (is_cpp) flags += "-std=c++11";
flags += Fmt("-o %.*s", S8_Expand(exe));
if (S8_EndsWith(file, ".cpp")) { result = Run(cc + file + flags);
cc = "clang++";
flags += "-std=c++11";
}
S8_String name = Fmt("-o %.*s", S8_Expand(exe));
result = Run(cc + file + name + flags);
} }
else { else {
IO_Assert(cc == "gcc"); IO_Assert(cc == "gcc");
if (is_cpp) cc = "g++";
Array<S8_String> flags = Split("-g -Wno-write-strings"); Array<S8_String> flags = {Perm};
flags += "-g -Wno-write-strings";
flags += "-fsanitize=address"; flags += "-fsanitize=address";
if (is_cpp) flags += "-std=c++11";
flags += Fmt("-o %.*s", S8_Expand(exe));
if (S8_EndsWith(file, ".cpp")) { result = Run(cc + file + flags);
cc = "g++";
flags += "-std=c++11";
}
S8_String name = Fmt("-o %.*s", S8_Expand(exe));
result = Run(cc + file + name + flags);
} }
if (result == 0) result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%.*s", S8_Expand(exe)); if (result == 0) result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%.*s", S8_Expand(exe));

View File

@@ -45,7 +45,7 @@ Array<S8_String> Split(char *str) {
return result; return result;
} }
S8_String Merge(Array<S8_String> list, S8_String separator = " "_s) { S8_String Merge(MA_Arena *arena, Array<S8_String> list, S8_String separator = " "_s) {
int64_t char_count = 0; int64_t char_count = 0;
For(list) char_count += it.len; For(list) char_count += it.len;
if (char_count == 0) return {}; if (char_count == 0) return {};
@@ -54,7 +54,7 @@ S8_String Merge(Array<S8_String> list, S8_String separator = " "_s) {
int64_t base_size = (char_count + 1); int64_t base_size = (char_count + 1);
int64_t sep_size = (node_count - 1) * separator.len; int64_t sep_size = (node_count - 1) * separator.len;
int64_t size = base_size + sep_size; int64_t size = base_size + sep_size;
char *buff = (char *)MA_PushSize(Perm, sizeof(char) * size); char *buff = (char *)MA_PushSize(arena, sizeof(char) * (size + 1));
S8_String string = S8_Make(buff, 0); S8_String string = S8_Make(buff, 0);
For(list) { For(list) {
IO_Assert(string.len + it.len <= size); IO_Assert(string.len + it.len <= size);
@@ -70,6 +70,10 @@ S8_String Merge(Array<S8_String> list, S8_String separator = " "_s) {
return string; return string;
} }
S8_String Merge(Array<S8_String> list, S8_String separator = " ") {
return Merge(Perm, list, separator);
}
S8_String Fmt(const char *str, ...) { S8_String Fmt(const char *str, ...) {
S8_FORMAT(Perm, str, str_fmt); S8_FORMAT(Perm, str, str_fmt);
return str_fmt; return str_fmt;

View File

@@ -1,5 +1,5 @@
#ifndef _CRT_SECURE_NO_WARNINGS #ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#endif #endif
#include "../core_library/core.c" #include "../core_library/core.c"
@@ -53,4 +53,3 @@ S8_String Clang_Debug = "-fsanitize=address -g";
S8_String GCC_Flags = "-Wno-write-strings"; S8_String GCC_Flags = "-Wno-write-strings";
S8_String GCC_NoStd = "-fno-exceptions"; S8_String GCC_NoStd = "-fno-exceptions";
S8_String GCC_Debug = "-fsanitize=address -g"; S8_String GCC_Debug = "-fsanitize=address -g";

139
build_tool/process.cpp Normal file
View File

@@ -0,0 +1,139 @@
struct TH_Process {
bool is_valid;
char platform[32];
};
#if OS_WINDOWS
TH_Process TH_CreateProcess(S8_String in_cmd, S8_String in_working_dir = "") {
MA_Scratch scratch;
if (in_working_dir != "" && !OS_IsAbsolute(in_working_dir)) {
in_working_dir = OS_GetAbsolutePath(scratch, in_working_dir);
}
wchar_t *application_name = NULL;
wchar_t *cmd = S8_ToWidechar(scratch, in_cmd);
BOOL inherit_handles = FALSE;
DWORD creation_flags = 0;
void *enviroment = NULL;
wchar_t *working_dir = in_working_dir == "" ? NULL : S8_ToWidechar(scratch, in_working_dir);
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(STARTUPINFOW);
TH_Process result = {};
IO_Assert(sizeof(result.platform) >= sizeof(PROCESS_INFORMATION));
PROCESS_INFORMATION *process_info = (PROCESS_INFORMATION *)result.platform;
BOOL success = CreateProcessW(application_name, cmd, NULL, NULL, inherit_handles, creation_flags, enviroment, working_dir, &startup_info, process_info);
result.is_valid = true;
if (!success) {
result.is_valid = false;
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL);
LocalFree(lpMsgBuf);
IO_FatalErrorf("Failed to create process \nworking_dir: %.*s\ncmd: %.*s\nwindows_message: %s", S8_Expand(in_working_dir), S8_Expand(in_cmd), lpMsgBuf);
}
return result;
}
int TH_WaitForProcessExit(TH_Process *process) {
IO_Assert(process->is_valid);
PROCESS_INFORMATION *pi = (PROCESS_INFORMATION *)process->platform;
WaitForSingleObject(pi->hProcess, INFINITE);
DWORD exit_code;
BOOL err = GetExitCodeProcess(pi->hProcess, &exit_code);
IO_Assert(err != 0);
CloseHandle(pi->hProcess);
CloseHandle(pi->hThread);
process[0] = {};
return (int)exit_code;
}
#else
#include <spawn.h>
#include <sys/wait.h>
struct TH_UnixProcess {
pid_t pid;
};
extern char **environ;
TH_Process TH_CreateProcess(S8_String cmd, S8_String working_dir = "") {
MA_Scratch scratch;
if (working_dir != "" && !OS_IsAbsolute(working_dir)) {
working_dir = OS_GetAbsolutePath(scratch, working_dir);
}
TH_Process result = {};
IO_Assert(sizeof(result.platform) >= sizeof(TH_UnixProcess));
TH_UnixProcess *u = (TH_UnixProcess *)result.platform;
S8_String exec_file = cmd;
S8_String argv = "";
int64_t pos;
if (S8_Seek(cmd, S8_Lit(" "), 0, &pos)) {
exec_file = S8_GetPrefix(cmd, pos);
argv = S8_Skip(cmd, pos + 1);
}
exec_file = S8_Copy(scratch, exec_file);
// Split string on whitespace and conform with argv format
Array<char *> args = {scratch};
{
args.add(exec_file.str);
for (int64_t i = 0; i < argv.len;) {
while (i < argv.len && CHAR_IsWhitespace(argv.str[i])) {
i += 1;
}
S8_String word = {argv.str + i, 0};
while (i < argv.len && !CHAR_IsWhitespace(argv.str[i])) {
word.len += 1;
i += 1;
}
word = S8_Copy(scratch, word);
args.add(word.str);
}
args.add(NULL);
}
S8_String prev_dir = {};
if (working_dir != "") prev_dir = OS_GetWorkingDir(scratch);
if (working_dir != "") OS_SetWorkingDir(working_dir);
int err = posix_spawnp(&u->pid, exec_file.str, NULL, NULL, args.data, environ);
if (err == 0) {
result.is_valid = true;
}
else {
perror("Failed to create process");
IO_FatalErrorf("Failed to create process \nworking_dir: %.*s\ncmd: %.*s", S8_Expand(working_dir), S8_Expand(cmd));
}
if (working_dir != "") OS_SetWorkingDir(prev_dir);
return result;
}
int TH_WaitForProcessExit(TH_Process *process) {
if (!process->is_valid) return 1;
TH_UnixProcess *u = (TH_UnixProcess *)process->platform;
int status = 0;
int pid = waitpid(u->pid, &status, 0);
IO_Assert(pid != -1);
int result = 0;
if (WIFEXITED(status)) {
result = WEXITSTATUS(status);
}
else {
result = 1;
}
process[0] = {};
return result;
}
#endif

View File

@@ -3,6 +3,8 @@
leeway for big buffers and other such things. Just make sure to not relay on it because it's easier unless specified. 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 - 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 @todo
- Remove static buffers from filesystem, use scratch arenas instead?
- Use allocators instead of concrete Arenas
- Add proper string arrays and utilities for build files - Add proper string arrays and utilities for build files
- also add String Arrays and String Builder, temp allocators hook ins for nicer api - also add String Arrays and String Builder, temp allocators hook ins for nicer api
*/ */
@@ -28,7 +30,3 @@
#include "../standalone_libraries/hash.c" #include "../standalone_libraries/hash.c"
#include "../standalone_libraries/load_library.c" #include "../standalone_libraries/load_library.c"
#include "filesystem.c" #include "filesystem.c"
// #if LANG_CPP
// #include "string.cpp"
// #endif

View File

@@ -28,5 +28,4 @@
#define ARRAY_SET_DEFAULT_ALLOCATOR \ #define ARRAY_SET_DEFAULT_ALLOCATOR \
if (!allocator.p) allocator = M_GetSystemAllocator(); if (!allocator.p) allocator = M_GetSystemAllocator();
#include "../standalone_libraries/array.hpp" #include "../standalone_libraries/array.hpp"
// #include "string.hpp"
#endif #endif

View File

@@ -46,7 +46,7 @@ OS_API S8_String OS_GetExePath(MA_Arena *arena) {
DWORD wsize = GetModuleFileNameW(0, wbuffer, MA_LENGTHOF(wbuffer)); DWORD wsize = GetModuleFileNameW(0, wbuffer, MA_LENGTHOF(wbuffer));
IO_Assert(wsize != 0); IO_Assert(wsize != 0);
S8_String path = UTF_CreateStringFromWidechar(arena, wbuffer, wsize); S8_String path = S8_FromWidecharEx(arena, wbuffer, wsize);
S8_NormalizePathUnsafe(path); S8_NormalizePathUnsafe(path);
return path; return path;
} }
@@ -66,7 +66,7 @@ OS_API S8_String OS_GetWorkingDir(MA_Arena *arena) {
wbuffer[wsize++] = '/'; wbuffer[wsize++] = '/';
wbuffer[wsize] = 0; wbuffer[wsize] = 0;
S8_String path = UTF_CreateStringFromWidechar(arena, wbuffer, wsize); S8_String path = S8_FromWidecharEx(arena, wbuffer, wsize);
S8_NormalizePathUnsafe(path); S8_NormalizePathUnsafe(path);
return path; return path;
} }
@@ -84,7 +84,7 @@ OS_API S8_String OS_GetAbsolutePath(MA_Arena *arena, S8_String relative) {
DWORD written = GetFullPathNameW((wchar_t *)wpath, MA_LENGTHOF(wpath_abs), wpath_abs, 0); DWORD written = GetFullPathNameW((wchar_t *)wpath, MA_LENGTHOF(wpath_abs), wpath_abs, 0);
if (written == 0) if (written == 0)
return S8_MakeEmpty(); return S8_MakeEmpty();
S8_String path = UTF_CreateStringFromWidechar(arena, wpath_abs, written); S8_String path = S8_FromWidecharEx(arena, wpath_abs, written);
S8_NormalizePathUnsafe(path); S8_NormalizePathUnsafe(path);
return path; return path;
} }
@@ -152,7 +152,7 @@ OS_API void OS_Advance(OS_FileIter *it) {
if (data->cFileName[0] == '.' && data->cFileName[1] == 0) continue; if (data->cFileName[0] == '.' && data->cFileName[1] == 0) continue;
it->is_directory = data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; it->is_directory = data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
it->filename = UTF_CreateStringFromWidechar(it->arena, data->cFileName, S8_WideLength(data->cFileName)); it->filename = S8_FromWidecharEx(it->arena, data->cFileName, S8_WideLength(data->cFileName));
const char *is_dir = it->is_directory ? "/" : ""; const char *is_dir = it->is_directory ? "/" : "";
const char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/"; const char *separator = it->path.str[it->path.len - 1] == '/' ? "" : "/";
it->relative_path = S8_Format(it->arena, "%.*s%s%.*s%s", S8_Expand(it->path), separator, S8_Expand(it->filename), is_dir); it->relative_path = S8_Format(it->arena, "%.*s%s%.*s%s", S8_Expand(it->path), separator, S8_Expand(it->filename), is_dir);
@@ -674,14 +674,6 @@ OS_API int OS_SystemF(const char *string, ...) {
return error_code; return error_code;
} }
OS_API S8_String UTF_CreateStringFromWidechar(MA_Arena *arena, wchar_t *wstr, int64_t wsize) {
int64_t buffer_size = (wsize + 1) * 2;
char *buffer = (char *)MA_PushSizeNonZeroed(arena, buffer_size);
int64_t size = UTF_CreateCharFromWidechar(buffer, buffer_size, wstr, wsize);
IO_Assert(size < buffer_size);
return S8_Make(buffer, size);
}
OS_API bool OS_ExpandIncludesList(MA_Arena *arena, S8_List *out, S8_String filepath) { OS_API bool OS_ExpandIncludesList(MA_Arena *arena, S8_List *out, S8_String filepath) {
S8_String c = OS_ReadFile(arena, filepath); S8_String c = OS_ReadFile(arena, filepath);
if (c.str == 0) return false; if (c.str == 0) return false;

View File

@@ -1,6 +1,21 @@
#include "clexer.h" #include "clexer.h"
#include <stdarg.h> #include <stdarg.h>
/*
- I'm pretty sure I can remove allocations for most of the current functions.
- I also can fix ResolvePath stuff so that it uses string+len and doesn't need allocations
- Add lexing options like in stb_c_lexer.h
Instead of AND_CL_STRING_TERMINATE_ON_NEW_LINE he is doing some weird cool stuff with redefining
https://github.com/nothings/stb/blob/master/stb_c_lexer.h
CL_MULTILINE_SSTRINGS
CL_DOLLAR_IDENT
- Add proper string parsing, as additional function, CL_ParseString() or something, this is the only one that would need allocations
*/
#ifndef CL_PRIVATE_FUNCTION #ifndef CL_PRIVATE_FUNCTION
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#define CL_PRIVATE_FUNCTION __attribute__((unused)) static #define CL_PRIVATE_FUNCTION __attribute__((unused)) static

View File

@@ -31,7 +31,7 @@ IO_StaticFunc int IO_Strlen(char *string) {
return len; return len;
} }
void (*IO_User_OutputMessage)(int kind, char *file, int line, char *str, int len); 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, ...) { IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) {
va_list args1; va_list args1;
@@ -83,7 +83,7 @@ IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) {
return ret == IO_ErrorResult_Break; return ret == IO_ErrorResult_Break;
} }
IO_API void IO__Printf(int kind, char *file, int line, const char *msg, ...) { IO_API void IO__Printf(int kind, const char *file, int line, const char *msg, ...) {
// First try to use a static buffer. That can fail because the message // First try to use a static buffer. That can fail because the message
// can be bigger then the buffer. Allocate enough memory to fit in that // can be bigger then the buffer. Allocate enough memory to fit in that
// case. // case.
@@ -127,7 +127,7 @@ IO_API bool IO__FatalError(char *msg) {
return result == IO_ErrorResult_Break; return result == IO_ErrorResult_Break;
} }
IO_API void IO_Print(int kind, char *file, int line, char *msg, int len) { IO_API void IO_Print(int kind, const char *file, int line, char *msg, int len) {
if (IO_User_OutputMessage) { if (IO_User_OutputMessage) {
IO_User_OutputMessage(kind, file, line, msg, len); IO_User_OutputMessage(kind, file, line, msg, len);
} }

View File

@@ -31,7 +31,7 @@ typedef enum IO_ErrorResult {
#define IO__PrintfFormat(fmt, va) #define IO__PrintfFormat(fmt, va)
#endif #endif
extern void (*IO_User_OutputMessage)(int kind, char *file, int line, char *str, int len); extern void (*IO_User_OutputMessage)(int kind, const char *file, int line, char *str, int len);
#define IO__STRINGIFY(x) #x #define IO__STRINGIFY(x) #x
#define IO__TOSTRING(x) IO__STRINGIFY(x) #define IO__TOSTRING(x) IO__STRINGIFY(x)
@@ -74,9 +74,9 @@ extern void (*IO_User_OutputMessage)(int kind, char *file, int line, char *str,
#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__PrintfFormat(3, 4); IO_API bool IO__FatalErrorf(const char *file, int line, const char *msg, ...) IO__PrintfFormat(3, 4);
IO_API void IO__Printf(int kind, char *file, int line, const char *msg, ...) IO__PrintfFormat(4, 5); 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 bool IO__FatalError(char *msg);
IO_API void IO_Print(int kind, char *file, int line, char *msg, int len); 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 void IO_OutputMessage(char *str, int len);
IO_API IO_ErrorResult IO_OutputError(char *str, int len); IO_API IO_ErrorResult IO_OutputError(char *str, int len);
IO_API void IO_Exit(int error_code); IO_API void IO_Exit(int error_code);

View File

@@ -103,13 +103,13 @@
#endif #endif
#if OS_WINDOWS #if OS_WINDOWS
#define OS_NAME "Windows" #define OS_NAME "windows"
#elif OS_LINUX #elif OS_LINUX
#define OS_NAME "Linux" #define OS_NAME "linux"
#elif OS_MAC #elif OS_MAC
#define OS_NAME "MacOS" #define OS_NAME "mac_os"
#else #else
#error couldn't figure out OS #error couldnt figure out OS
#endif #endif
// #if COMPILER_CLANG // #if COMPILER_CLANG

View File

@@ -529,3 +529,38 @@ S8_API S8_String S8_AddF(S8_Allocator allocator, S8_List *list, const char *str,
S8_AddNode(allocator, list, result); S8_AddNode(allocator, list, result);
return result; return result;
} }
#ifdef UTF_HEADER
S8_API S16_String S8_ToWidecharEx(S8_Allocator allocator, S8_String string) {
S8_ASSERT(sizeof(wchar_t) == 2);
wchar_t *buffer = (wchar_t *)S8_ALLOCATE(allocator, sizeof(wchar_t) * (string.len + 1));
int64_t size = UTF_CreateWidecharFromChar(buffer, string.len + 1, string.str, string.len);
S16_String result = {buffer, size};
return result;
}
S8_API wchar_t *S8_ToWidechar(S8_Allocator allocator, S8_String string) {
S16_String result = S8_ToWidecharEx(allocator, string);
return result.str;
}
S8_API S8_String S8_FromWidecharEx(S8_Allocator allocator, wchar_t *wstring, int64_t wsize) {
S8_ASSERT(sizeof(wchar_t) == 2);
int64_t buffer_size = (wsize + 1) * 2;
char *buffer = (char *)S8_ALLOCATE(allocator, buffer_size);
int64_t size = UTF_CreateCharFromWidechar(buffer, buffer_size, wstring, wsize);
S8_String result = S8_Make(buffer, size);
S8_ASSERT(size < buffer_size);
return result;
}
S8_API S8_String S8_FromWidechar(S8_Allocator allocator, wchar_t *wstring) {
int64_t size = S8_WideLength(wstring);
S8_String result = S8_FromWidecharEx(allocator, wstring, size);
return result;
}
#endif

View File

@@ -80,6 +80,11 @@ struct S8_List {
#endif #endif
}; };
typedef struct S16_String {
wchar_t *str;
int64_t len;
} S16_String;
typedef int S8_FindFlag; typedef int S8_FindFlag;
enum { enum {
S8_FindFlag_None = 0, S8_FindFlag_None = 0,
@@ -177,6 +182,11 @@ S8_API S8_Node *S8_AddNode(S8_Allocator allocator, S8_List *list, S8_String stri
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__PrintfFormat(3, 4); S8_API S8_String S8_AddF(S8_Allocator allocator, S8_List *list, const char *str, ...) S8__PrintfFormat(3, 4);
S8_API S16_String S8_ToWidecharEx(S8_Allocator allocator, S8_String string);
S8_API wchar_t *S8_ToWidechar(S8_Allocator allocator, S8_String string);
S8_API S8_String S8_FromWidecharEx(S8_Allocator allocator, wchar_t *wstring, int64_t wsize);
S8_API S8_String S8_FromWidechar(S8_Allocator allocator, wchar_t *wstring);
#if defined(__cplusplus) #if defined(__cplusplus)
inline S8_String operator""_s(const char *str, size_t size) { return {(char *)str, (int64_t)size}; } inline S8_String operator""_s(const char *str, size_t size) { return {(char *)str, (int64_t)size}; }
inline bool operator==(S8_String a, S8_String b) { return S8_AreEqual(a, b, 0); } inline bool operator==(S8_String a, S8_String b) { return S8_AreEqual(a, b, 0); }

View File

@@ -159,6 +159,9 @@ UTF_API int64_t UTF_CreateCharFromWidechar(char *buffer, int64_t buffer_size, wc
return outlen; return outlen;
} }
// @todo: the api here is from one side cool but from other kind of weird
// int64_t size = UTF_CreateWidecharFromChar(wcmd, cmd.len + 1, cmd.str, cmd.len);
// the "+ 1" part is bothering me, but if it wrote one past buffer_size, that would be worse
UTF_API int64_t UTF_CreateWidecharFromChar(wchar_t *buffer, int64_t buffer_size, char *in, int64_t inlen) { UTF_API int64_t UTF_CreateWidecharFromChar(wchar_t *buffer, int64_t buffer_size, char *in, int64_t inlen) {
int64_t outlen = 0; int64_t outlen = 0;
for (int64_t i = 0; i < inlen;) { for (int64_t i = 0; i < inlen;) {

128
tests/test_thread.cpp Normal file
View File

@@ -0,0 +1,128 @@
#include "../build_tool/library.cpp"
#include "../build_tool/process.cpp"
int main() {
MA_Scratch scratch;
S8_String working_dir = OS_GetWorkingDir(scratch);
Array<S8_String> exes = {scratch};
Array<TH_Process> proc = {scratch};
Array<S8_String> files = {scratch};
files.add("../../tests/test_main.cpp");
files.add("../../tests/test_filesystem.c");
For2(file, files) {
S8_String name_no_ext = S8_GetNameNoExt(file);
S8_String exe = Fmt("%.*s.exe", S8_Expand(name_no_ext));
bool is_cpp = S8_EndsWith(file, ".cpp");
#if OS_WINDOWS
// Setup CL Debug
{
S8_String cc = "cl";
Array<S8_String> flags = {scratch};
flags += "/MP /Zi -D_CRT_SECURE_NO_WARNINGS";
flags += "/FC /WX /W3 /wd4200 /diagnostics:column /nologo";
flags += "/GF /Gm- /Oi";
flags += "/GR- /EHa-";
flags += Fmt("/Fe:%.*s", S8_Expand(exe));
Array<S8_String> debug = {scratch};
debug += "/D_DEBUG -RTC1 -Od";
Array<S8_String> release = {scratch};
release += "-O2 -MT -DNDEBUG -GL";
Array<S8_String> link = {scratch};
link += "/link /incremental:no";
S8_String dir_debug = Fmt("%.*s/%.*s_cl_debug_" OS_NAME, S8_Expand(working_dir), S8_Expand(name_no_ext));
S8_String dir_release = Fmt("%.*s/%.*s_cl_release_" OS_NAME, S8_Expand(working_dir), S8_Expand(name_no_ext));
OS_MakeDir(dir_debug);
OS_MakeDir(dir_release);
Array<S8_String> cmd_debug = cc + file + flags + debug + link;
Array<S8_String> cmd_release = cc + file + flags + release + link;
S8_String cmd_debug_m = Merge(cmd_debug);
S8_String cmd_release_m = Merge(cmd_release);
TH_Process p1 = TH_CreateProcess(cmd_debug_m, dir_debug);
TH_Process p2 = TH_CreateProcess(cmd_release_m, dir_release);
proc.add(p1);
proc.add(p2);
exes.add(Fmt("%.*s/%.*s", S8_Expand(dir_debug), S8_Expand(exe)));
exes.add(Fmt("%.*s/%.*s", S8_Expand(dir_release), S8_Expand(exe)));
}
#endif
{
S8_String cc = is_cpp ? "clang++" : "clang";
Array<S8_String> flags = {scratch};
flags += "-g -Wno-write-strings";
flags += "-fdiagnostics-absolute-paths";
flags += "-fsanitize=address";
if (is_cpp) flags += "-std=c++11";
flags += Fmt("-o %.*s", S8_Expand(exe));
S8_String dir = Fmt("%.*s/%.*s_debug_clang_" OS_NAME, S8_Expand(working_dir), S8_Expand(name_no_ext));
OS_MakeDir(dir);
S8_String cmd = Merge(cc + file + flags);
TH_Process p = TH_CreateProcess(cmd, dir);
proc.add(p);
exes.add(Fmt("%.*s/%.*s", S8_Expand(dir), S8_Expand(exe)));
}
#if OS_LINUX
{
S8_String cc = is_cpp ? "g++" : "gcc";
Array<S8_String> flags = {scratch};
flags += "-g -Wno-write-strings";
flags += "-fsanitize=address";
if (is_cpp) flags += "-std=c++11";
flags += Fmt("-o %.*s", S8_Expand(exe));
S8_String dir = Fmt("%.*s/%.*s_debug_gcc_" OS_NAME, S8_Expand(working_dir), S8_Expand(name_no_ext));
OS_MakeDir(dir);
S8_String cmd = Merge(cc + file + flags);
TH_Process p = TH_CreateProcess(cmd, dir);
proc.add(p);
exes.add(Fmt("%.*s/%.*s", S8_Expand(dir), S8_Expand(exe)));
}
#endif
}
//
// Wait for all compilation to finalize
//
int result = 0;
For(proc) {
int exit_code = TH_WaitForProcessExit(&it);
if (exit_code != 0) result = exit_code;
}
//
// Run exes if there were no errors
//
if (result == 0) {
proc.reset();
For(exes) {
TH_Process p = TH_CreateProcess(it);
proc.add(p);
}
For(proc) {
int exit_code = TH_WaitForProcessExit(&it);
if (exit_code != 0) result = exit_code;
}
}
return result;
}