Move source code into Source folder and add a single header generator"

This commit is contained in:
doylet 2025-06-26 22:14:18 +10:00
parent a41a9d550d
commit 7259cbf296
80 changed files with 18259 additions and 47 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -2,21 +2,6 @@
#include "../dn_clangd.h"
/*
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// $$$$$$$\
// $$ __$$\
// $$ | $$ | $$$$$$\ $$$$$$$\ $$$$$$\
// $$$$$$$\ | \____$$\ $$ _____|$$ __$$\
// $$ __$$\ $$$$$$$ |\$$$$$$\ $$$$$$$$ |
// $$ | $$ |$$ __$$ | \____$$\ $$ ____|
// $$$$$$$ |\$$$$$$$ |$$$$$$$ |\$$$$$$$\
// \_______/ \_______|\_______/ \_______|
//
////////////////////////////////////////////////////////////////////////////////////////////////////
*/
// NOTE: [$INTR] Intrinsics ////////////////////////////////////////////////////////////////////////
#if !defined(DN_PLATFORM_ARM64) && !defined(DN_PLATFORM_EMSCRIPTEN)
#if defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG)

View File

@ -499,6 +499,14 @@ DN_API DN_Str8 DN_Str8_FileExtension(DN_Str8 path)
return result;
}
DN_API DN_Str8 DN_Str8_FileDirectoryFromPath(DN_Str8 path)
{
DN_Str8 separators[] = {DN_STR8("/"), DN_STR8("\\")};
DN_Str8BinarySplitResult split = DN_Str8_BinarySplitLastArray(path, separators, DN_ArrayCountU(separators));
DN_Str8 result = split.lhs;
return result;
}
DN_API DN_Str8ToU64Result DN_Str8_ToU64(DN_Str8 string, char separator)
{
// NOTE: Argument check

View File

@ -204,6 +204,7 @@ DN_API DN_Str8 DN_Str8_FileNameFrom
DN_API DN_Str8 DN_Str8_FileNameNoExtension (DN_Str8 path);
DN_API DN_Str8 DN_Str8_FilePathNoExtension (DN_Str8 path);
DN_API DN_Str8 DN_Str8_FileExtension (DN_Str8 path);
DN_API DN_Str8 DN_Str8_FileDirectoryFromPath (DN_Str8 path);
DN_API DN_Str8ToU64Result DN_Str8_ToU64 (DN_Str8 string, char separator);
DN_API DN_Str8ToI64Result DN_Str8_ToI64 (DN_Str8 string, char separator);

View File

@ -3,16 +3,6 @@
#include <new> // operator new
#if defined(DN_PLATFORM_EMSCRIPTEN) || defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_ARM64)
#include "dn_os_posix.h"
#elif defined(DN_PLATFORM_WIN32)
#include "dn_os_windows.h"
#include "dn_os_w32.h"
#else
#error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs
#endif
#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS)
#include <pthread.h>
#include <semaphore.h>

57
Source/dn_base_inc.h Normal file
View File

@ -0,0 +1,57 @@
#if !defined(DN_BASE_INC_H)
#define DN_BASE_INC_H
// NOTE: DN configuration
// All the following configuration options are optional. If omitted, DN has default behaviours to
// handle the various options.
//
// Platform Target
// Define one of the following directives to configure this library to compile for that platform.
// By default, the library will auto-detect the current host platform and select that as the
// target platform.
//
// DN_PLATFORM_EMSCRIPTEN
// DN_PLATFORM_POSIX
// DN_PLATFORM_WIN32
//
// For example
//
// #define DN_PLATFORM_WIN32
//
// Will ensure that <Windows.h> is included and the OS layer is implemented using Win32
// primitives.
//
// Static functions
// All public functions in the DN library are prefixed with the macro '#define DN_API'. By
// default 'DN_API' is not defined to anything. Define
//
// DN_STATIC_API
//
// To replace all the prefixed with 'static' ensuring that the functions in the library do not
// export an entry into the linking table and thereby optimise compilation times as the linker
// will not try to resolve symbols from other translation units from the the unit including the
// DN library.
//
// Using the in-built replacement header for <Windows.h> (requires dn_os_inc.h)
// If you are building DN for the Windows platform, <Windows.h> is a large legacy header that
// applications have to link to use Windows syscalls. By default DN library uses a replacement
// header for all the Windows functions that it uses in the OS layer removing the need to include
// <Windows.h> to improve compilation times. This can be disabled by defining:
//
// DN_NO_WINDOWS_H_REPLACEMENT_HEADER
//
// To instead use <Windows.h>. DN automatically detects if <Windows.h> is included in an earlier
// translation unit and will automatically disable the in-built replacement header in which case
// this does not need to be defined.
#include "Base/dn_base_compiler.h"
#include "Base/dn_base.h"
#include "Base/dn_base_os.h"
#include "Base/dn_base_assert.h"
#include "Base/dn_base_mem.h"
#include "Base/dn_base_log.h"
#include "Base/dn_base_string.h"
#include "Base/dn_base_containers.h"
#include "Base/dn_base_convert.h"
#endif // !defined(DN_BASE_INC_H)

View File

@ -1,6 +1,15 @@
#if !defined(DN_OS_INC_H)
#define DN_OS_INC_H
#if defined(DN_PLATFORM_WIN32)
#include "OS/dn_os_windows.h"
#include "OS/dn_os_w32.h"
#elif defined(DN_PLATFORM_POSIX)
#include "OS/dn_os_posix.h"
#else
#error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs
#endif
#include "OS/dn_os_tls.h"
#include "OS/dn_os.h"
#include "OS/dn_os_allocator.h"
@ -8,11 +17,4 @@
#include "OS/dn_os_print.h"
#include "OS/dn_os_string.h"
#if defined(DN_PLATFORM_WIN32)
#include "OS/dn_os_windows.h"
#include "OS/dn_os_w32.h"
#elif defined(DN_PLATFORM_POSIX)
#include "OS/dn_os_posix.h"
#endif
#endif // DN_OS_INC_H

View File

@ -13,7 +13,7 @@ pushd Build
REM O2 Optimisation Level 2
REM Oi Use CPU Intrinsics
REM Z7 Combine multi-debug files to one debug file
set common_flags=-D DN_UNIT_TESTS_WITH_KECCAK %script_dir%\Extra\dn_tests_main.cpp
set common_flags=-D DN_UNIT_TESTS_WITH_KECCAK %script_dir%\Source\Extra\dn_tests_main.cpp
set msvc_driver_flags=%common_flags% -MT -EHa -GR- -Od -Oi -Z7 -wd4201 -W4 -nologo
@ -33,8 +33,12 @@ pushd Build
echo [BUILD] MSVC's cl detected, compiling ...
set msvc_cmd=cl %msvc_compile_flags% %msvc_link_flags%
powershell -Command "$time = Measure-Command { !msvc_cmd! | Out-Default }; Write-Host '[BUILD] msvc:'$time.TotalSeconds's'; exit $LASTEXITCODE" || exit /b 1
call cl %script_dir%\single_header_generator.cpp -nologo -link
call single_header_generator.exe %script_dir%\Source %script_dir%\Single_Header
)
REM REM clang-cl ===================================================================================
set has_clang_cl=1
where /q clang-cl || set has_clang_cl=0

View File

@ -1,14 +0,0 @@
#if !defined(DN_BASE_INC_H)
#define DN_BASE_INC_H
#include "Base/dn_base_compiler.h"
#include "Base/dn_base.h"
#include "Base/dn_base_os.h"
#include "Base/dn_base_assert.h"
#include "Base/dn_base_mem.h"
#include "Base/dn_base_log.h"
#include "Base/dn_base_string.h"
#include "Base/dn_base_containers.h"
#include "Base/dn_base_convert.h"
#endif // !defined(DN_BASE_INC_H)

166
single_header_generator.cpp Normal file
View File

@ -0,0 +1,166 @@
#define USE_SINGLE_HEADER 1
#if USE_SINGLE_HEADER
#include "Single_Header/dn_single_header.h"
#else
#include "Source/dn_base_inc.h"
#include "Source/dn_os_inc.h"
#include "Source/dn_core_inc.h"
#endif
#if USE_SINGLE_HEADER
#include "Single_Header/dn_single_header.cpp"
#else
#include "Source/dn_base_inc.cpp"
#include "Source/dn_os_inc.cpp"
#include "Source/dn_core_inc.cpp"
#endif
enum FileType
{
FileType_Header,
FileType_Impl,
FileType_Count
};
struct File
{
FileType type;
DN_Str8 file_name;
};
static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
{
DN_OSErrSink *err = DN_OS_ErrSinkBeginDefault();
DN_Str8 buffer = DN_OS_ReadAllFromTLS(cpp_path, err);
DN_OS_ErrSinkEndAndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path);
for (DN_Str8 inc_walker = buffer;;) {
DN_Str8BinarySplitResult split = DN_Str8_BinarySplit(inc_walker, DN_STR8("\n"));
if (!DN_Str8_HasData(split.lhs))
break;
inc_walker = split.rhs;
// NOTE: Trim the whitespace, mainly for windows, the file we read will have \r\n whereas we just want to emit \n
DN_Str8 line = DN_Str8_TrimTailWhitespace(split.lhs);
// NOTE: Comment out any #include "../dn_.*" matches if we encounter one
DN_Str8FindResult find = DN_Str8_FindStr8(line, DN_STR8("#include \"../dn_"), DN_Str8EqCase_Sensitive);
{
if (find.found) {
line = DN_Str8_InitFFromTLS("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer));
// The only time we use '../dn_.*' is for LSP purposes, so we
// don't care about inlining it, hence we don't set 'include_file'
}
}
// NOTE: Inline any other relative includes if we encounter one
// (Right now DN only includes stb_sprintf with a relative path)
DN_Str8 extra_include_path = {};
if (!find.found) {
find = DN_Str8_FindStr8(line, DN_STR8("#include \""), DN_Str8EqCase_Sensitive);
if (find.found) {
line = DN_Str8_InitFFromTLS("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer));
DN_Str8 rel_include_path = DN_Str8_TrimWhitespaceAround(find.after_match_to_end_of_buffer);
DN_Str8 root_dir = DN_Str8_FileDirectoryFromPath(cpp_path);
extra_include_path = DN_OS_PathFFromTLS("%S/%S", root_dir, DN_Str8_TrimSuffix(rel_include_path, DN_STR8("\"")));
}
}
DN_Str8Builder_AppendRef(dest, line);
DN_Str8Builder_AppendRef(dest, DN_STR8("\n"));
if (extra_include_path.size)
AppendCppFileLineByLine(dest, extra_include_path);
}
}
int main(int argc, char **argv)
{
DN_Core dn = {};
DN_OSCore os = {};
DN_OS_Init(&os, nullptr);
DN_Core_Init(&dn, DN_CoreOnInit_Nil);
if (argc != 3) {
DN_OS_PrintErrF("USAGE: %s <path/to/dn/Source> <output_dir>", argv[0]);
return -1;
}
DN_Str8 dn_root_dir = DN_Str8_InitCStr8(argv[1]);
DN_Str8 output_dir = DN_Str8_InitCStr8(argv[2]);
if (!DN_OS_MakeDir(output_dir)) {
DN_OS_PrintErrF("Failed to make requested output directory: %S", output_dir);
return -1;
}
File const FILES[] = {
{FileType_Header, DN_STR8("dn_base_inc.h")},
{FileType_Header, DN_STR8("dn_os_inc.h")},
{FileType_Header, DN_STR8("dn_core_inc.h")},
{FileType_Impl, DN_STR8("dn_base_inc.cpp")},
{FileType_Impl, DN_STR8("dn_os_inc.cpp")},
{FileType_Impl, DN_STR8("dn_core_inc.cpp")},
};
for (DN_ForIndexU(type, FileType_Count)) {
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
DN_Str8Builder builder = DN_Str8Builder_InitFromTLS();
for (DN_ForItCArray(it, File const, FILES)) {
if (it.data->type != type)
continue;
// NOTE: Parse the include files in the *_inc.[h|cpp] files
DN_Str8 path = DN_OS_PathFFromTLS("%S/%S", dn_root_dir, it.data->file_name);
{
DN_OSErrSink *err = DN_OS_ErrSinkBeginDefault();
DN_Str8 file_buffer = DN_OS_ReadAllFromTLS(path, err);
DN_OS_ErrSinkEndAndExitIfErrorF(err, -1, "Failed to load file");
// NOTE: Walk the top-level dn_*_inc.[h|cpp] files
for (DN_Str8 walker = file_buffer;;) {
DN_Str8BinarySplitResult split = DN_Str8_BinarySplit(walker, DN_STR8("\n"));
if (!DN_Str8_HasData(split.lhs))
break;
// NOTE: Parse the line, if it was a #include, extract it into this string
DN_Str8 include_file = {};
{
walker = split.rhs;
DN_Str8 line = DN_Str8_TrimTailWhitespace(split.lhs);
// NOTE: Comment out any #include "dn_.*" matches if we encounter one
DN_Str8FindResult find = DN_Str8_FindStr8(line, DN_STR8("#include \""), DN_Str8EqCase_Sensitive);
{
if (find.found && DN_Str8_FindStr8(line, DN_STR8("dn_"), DN_Str8EqCase_Sensitive).found) {
line = DN_Str8_InitFFromTLS("%S// DN: Single header generator inlined this file => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer));
include_file = DN_Str8_BinarySplit(find.after_match_to_end_of_buffer, DN_STR8("\"")).lhs;
DN_Assert(include_file.size);
}
}
// NOTE: Record the line
DN_Str8Builder_AppendRef(&builder, line);
DN_Str8Builder_AppendRef(&builder, DN_STR8("\n"));
}
if (include_file.size) { // NOTE: If the line was a include file, we will inline the included file
DN_Str8 include_path = DN_OS_PathFFromTLS("%S/%S", dn_root_dir, include_file);
AppendCppFileLineByLine(&builder, include_path);
}
}
}
}
DN_OSDateTime date = DN_OS_DateLocalTimeNow();
DN_Str8Builder_PrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds);
DN_Str8 suffix = type == FileType_Header ? DN_STR8("h") : DN_STR8("cpp");
DN_Str8 buffer = DN_Str8_TrimWhitespaceAround(DN_Str8Builder_BuildFromTLS(&builder));
DN_Str8 single_header_path = DN_OS_PathFFromTLS("%S/dn_single_header.%S", output_dir, suffix);
DN_OSErrSink *err = DN_OS_ErrSinkBeginDefault();
DN_OS_WriteAllSafe(single_header_path, buffer, err);
DN_OS_ErrSinkEndAndExitIfErrorF(err, -1, "Failed to write Single header file '%S'", single_header_path);
}
}