Many changes, building many targets at the same time
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -10,6 +10,7 @@
|
||||
*.10x
|
||||
*.sublime-project
|
||||
*.sublime-workspace
|
||||
*.rdbg
|
||||
backup.*
|
||||
bld
|
||||
imgui.ini
|
||||
|
||||
@@ -5,3 +5,4 @@ cl -Fe:bld.exe ../build_tool/main.cpp -FC -WX -W3 -wd4200 -diagnostics:column -n
|
||||
cd ..
|
||||
rem build\bld.exe clear_cache
|
||||
build\bld.exe
|
||||
rem build\bld.exe cc=clang
|
||||
|
||||
2
build.sh
2
build.sh
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
gcc -o bld build_tool/main.cpp -g
|
||||
g++ -o bld build_tool/main.cpp -g
|
||||
./bld
|
||||
|
||||
@@ -7,8 +7,9 @@ int main(int argc, char **argv) {
|
||||
Array<S8_String> cmd = CMD_Make(argv, argc);
|
||||
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_filesystem.c");
|
||||
Compile(cc, "../tests/test_thread.cpp");
|
||||
// Compile(cc, "../tests/test_main.cpp");
|
||||
// Compile(cc, "../tests/test_filesystem.c");
|
||||
|
||||
return ReturnValue;
|
||||
}
|
||||
@@ -18,43 +19,46 @@ void Compile(S8_String cc, S8_String file) {
|
||||
|
||||
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 (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");
|
||||
S8_String name = Fmt("/Fe:%.*s", S8_Expand(exe));
|
||||
Array<S8_String> flags = {Perm};
|
||||
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") {
|
||||
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";
|
||||
if (is_cpp) flags += "-std=c++11";
|
||||
flags += Fmt("-o %.*s", S8_Expand(exe));
|
||||
|
||||
if (S8_EndsWith(file, ".cpp")) {
|
||||
cc = "clang++";
|
||||
flags += "-std=c++11";
|
||||
}
|
||||
|
||||
S8_String name = Fmt("-o %.*s", S8_Expand(exe));
|
||||
result = Run(cc + file + name + flags);
|
||||
result = Run(cc + file + flags);
|
||||
}
|
||||
else {
|
||||
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";
|
||||
if (is_cpp) flags += "-std=c++11";
|
||||
flags += Fmt("-o %.*s", S8_Expand(exe));
|
||||
|
||||
if (S8_EndsWith(file, ".cpp")) {
|
||||
cc = "g++";
|
||||
flags += "-std=c++11";
|
||||
}
|
||||
|
||||
S8_String name = Fmt("-o %.*s", S8_Expand(exe));
|
||||
result = Run(cc + file + name + flags);
|
||||
result = Run(cc + file + flags);
|
||||
}
|
||||
|
||||
if (result == 0) result = OS_SystemF(IF_WINDOWS_ELSE("", "./") "%.*s", S8_Expand(exe));
|
||||
|
||||
@@ -45,7 +45,7 @@ Array<S8_String> Split(char *str) {
|
||||
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;
|
||||
For(list) char_count += it.len;
|
||||
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 sep_size = (node_count - 1) * separator.len;
|
||||
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);
|
||||
For(list) {
|
||||
IO_Assert(string.len + it.len <= size);
|
||||
@@ -70,6 +70,10 @@ S8_String Merge(Array<S8_String> list, S8_String separator = " "_s) {
|
||||
return string;
|
||||
}
|
||||
|
||||
S8_String Merge(Array<S8_String> list, S8_String separator = " ") {
|
||||
return Merge(Perm, list, separator);
|
||||
}
|
||||
|
||||
S8_String Fmt(const char *str, ...) {
|
||||
S8_FORMAT(Perm, str, str_fmt);
|
||||
return str_fmt;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#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_NoStd = "-fno-exceptions";
|
||||
S8_String GCC_Debug = "-fsanitize=address -g";
|
||||
|
||||
|
||||
139
build_tool/process.cpp
Normal file
139
build_tool/process.cpp
Normal 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
|
||||
@@ -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.
|
||||
- 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 instead?
|
||||
- Use allocators instead of concrete Arenas
|
||||
- Add proper string arrays and utilities for build files
|
||||
- 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/load_library.c"
|
||||
#include "filesystem.c"
|
||||
|
||||
// #if LANG_CPP
|
||||
// #include "string.cpp"
|
||||
// #endif
|
||||
@@ -28,5 +28,4 @@
|
||||
#define ARRAY_SET_DEFAULT_ALLOCATOR \
|
||||
if (!allocator.p) allocator = M_GetSystemAllocator();
|
||||
#include "../standalone_libraries/array.hpp"
|
||||
// #include "string.hpp"
|
||||
#endif
|
||||
|
||||
@@ -46,7 +46,7 @@ OS_API S8_String OS_GetExePath(MA_Arena *arena) {
|
||||
DWORD wsize = GetModuleFileNameW(0, wbuffer, MA_LENGTHOF(wbuffer));
|
||||
IO_Assert(wsize != 0);
|
||||
|
||||
S8_String path = UTF_CreateStringFromWidechar(arena, wbuffer, wsize);
|
||||
S8_String path = S8_FromWidecharEx(arena, wbuffer, wsize);
|
||||
S8_NormalizePathUnsafe(path);
|
||||
return path;
|
||||
}
|
||||
@@ -66,7 +66,7 @@ OS_API S8_String OS_GetWorkingDir(MA_Arena *arena) {
|
||||
wbuffer[wsize++] = '/';
|
||||
wbuffer[wsize] = 0;
|
||||
|
||||
S8_String path = UTF_CreateStringFromWidechar(arena, wbuffer, wsize);
|
||||
S8_String path = S8_FromWidecharEx(arena, wbuffer, wsize);
|
||||
S8_NormalizePathUnsafe(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);
|
||||
if (written == 0)
|
||||
return S8_MakeEmpty();
|
||||
S8_String path = UTF_CreateStringFromWidechar(arena, wpath_abs, written);
|
||||
S8_String path = S8_FromWidecharEx(arena, wpath_abs, written);
|
||||
S8_NormalizePathUnsafe(path);
|
||||
return path;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ OS_API void OS_Advance(OS_FileIter *it) {
|
||||
if (data->cFileName[0] == '.' && data->cFileName[1] == 0) continue;
|
||||
|
||||
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 *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);
|
||||
@@ -674,14 +674,6 @@ OS_API int OS_SystemF(const char *string, ...) {
|
||||
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) {
|
||||
S8_String c = OS_ReadFile(arena, filepath);
|
||||
if (c.str == 0) return false;
|
||||
|
||||
@@ -1,6 +1,21 @@
|
||||
#include "clexer.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
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define CL_PRIVATE_FUNCTION __attribute__((unused)) static
|
||||
|
||||
@@ -31,7 +31,7 @@ IO_StaticFunc int IO_Strlen(char *string) {
|
||||
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, ...) {
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
// can be bigger then the buffer. Allocate enough memory to fit in that
|
||||
// case.
|
||||
@@ -127,7 +127,7 @@ IO_API bool IO__FatalError(char *msg) {
|
||||
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) {
|
||||
IO_User_OutputMessage(kind, file, line, msg, len);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ typedef enum IO_ErrorResult {
|
||||
#define IO__PrintfFormat(fmt, va)
|
||||
#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__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")
|
||||
|
||||
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 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 IO_ErrorResult IO_OutputError(char *str, int len);
|
||||
IO_API void IO_Exit(int error_code);
|
||||
|
||||
@@ -103,13 +103,13 @@
|
||||
#endif
|
||||
|
||||
#if OS_WINDOWS
|
||||
#define OS_NAME "Windows"
|
||||
#define OS_NAME "windows"
|
||||
#elif OS_LINUX
|
||||
#define OS_NAME "Linux"
|
||||
#define OS_NAME "linux"
|
||||
#elif OS_MAC
|
||||
#define OS_NAME "MacOS"
|
||||
#define OS_NAME "mac_os"
|
||||
#else
|
||||
#error couldn't figure out OS
|
||||
#error couldnt figure out OS
|
||||
#endif
|
||||
|
||||
// #if COMPILER_CLANG
|
||||
|
||||
@@ -529,3 +529,38 @@ S8_API S8_String S8_AddF(S8_Allocator allocator, S8_List *list, const char *str,
|
||||
S8_AddNode(allocator, list, 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
|
||||
@@ -80,6 +80,11 @@ struct S8_List {
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct S16_String {
|
||||
wchar_t *str;
|
||||
int64_t len;
|
||||
} S16_String;
|
||||
|
||||
typedef int S8_FindFlag;
|
||||
enum {
|
||||
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_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)
|
||||
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); }
|
||||
|
||||
@@ -159,6 +159,9 @@ UTF_API int64_t UTF_CreateCharFromWidechar(char *buffer, int64_t buffer_size, wc
|
||||
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) {
|
||||
int64_t outlen = 0;
|
||||
for (int64_t i = 0; i < inlen;) {
|
||||
|
||||
128
tests/test_thread.cpp
Normal file
128
tests/test_thread.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user