mirror of
				https://github.com/Ed94/gencpp.git
				synced 2025-11-03 15:26:12 -08:00 
			
		
		
		
	Compare commits
	
		
			19 Commits
		
	
	
		
			v0.18-Alph
			...
			v0.19-Alph
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 81a0376c99 | |||
| 1417a68757 | |||
| 1e4d5ce630 | |||
| 0f2763a115 | |||
| 420f452d35 | |||
| 908c385de5 | |||
| c1878265c8 | |||
| 23742868c4 | |||
| 2e5e31ed3b | |||
| 00df336610 | |||
| d89c9a6072 | |||
| 6aa99ac1d5 | |||
| 3989f5fa83 | |||
| f90c0a59b6 | |||
| 33f992ef56 | |||
| 0542204b35 | |||
| e5616c5879 | |||
| 40a256f6c3 | |||
| b8e1aa6eb7 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -29,3 +29,5 @@ release/**
 | 
				
			|||||||
! **/Unreal/validate.unreal.cpp
 | 
					! **/Unreal/validate.unreal.cpp
 | 
				
			||||||
project/auxillary/vis_ast/dependencies/temp
 | 
					project/auxillary/vis_ast/dependencies/temp
 | 
				
			||||||
test/gen/original
 | 
					test/gen/original
 | 
				
			||||||
 | 
					singleheader/gen/scratch.hpp
 | 
				
			||||||
 | 
					test/gen/scratch.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							@@ -41,6 +41,15 @@
 | 
				
			|||||||
			"cwd": "${workspaceFolder}/singleheader/",
 | 
								"cwd": "${workspaceFolder}/singleheader/",
 | 
				
			||||||
			"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
 | 
								"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"type": "cppvsdbg",
 | 
				
			||||||
 | 
								"request": "launch",
 | 
				
			||||||
 | 
								"name": "Debug unreal vsdbg",
 | 
				
			||||||
 | 
								"program": "${workspaceFolder}/unreal_engine/build/unreal.exe",
 | 
				
			||||||
 | 
								"args": [],
 | 
				
			||||||
 | 
								"cwd": "${workspaceFolder}/unreal_engine/",
 | 
				
			||||||
 | 
								"visualizerFile": "${workspaceFolder}/scripts/gencpp.natvis"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			"type": "cppvsdbg",
 | 
								"type": "cppvsdbg",
 | 
				
			||||||
			"request": "launch",
 | 
								"request": "launch",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								Readme.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Readme.md
									
									
									
									
									
								
							@@ -67,7 +67,7 @@ Example using each construction interface:
 | 
				
			|||||||
Validation and construction through a functional interface.
 | 
					Validation and construction through a functional interface.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```cpp
 | 
					```cpp
 | 
				
			||||||
Code t_uw           = def_type( name(uw) );
 | 
					Code t_uw           = def_type( name(usize) );
 | 
				
			||||||
Code t_allocator    = def_type( name(allocator) );
 | 
					Code t_allocator    = def_type( name(allocator) );
 | 
				
			||||||
Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
 | 
					Code t_string_const = def_type( name(char), def_specifiers( args( ESpecifier::Const, ESpecifier::Ptr ) ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,8 +90,8 @@ Validation through ast construction.
 | 
				
			|||||||
Code header = parse_struct( code(
 | 
					Code header = parse_struct( code(
 | 
				
			||||||
    struct ArrayHeader
 | 
					    struct ArrayHeader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uw        Num;
 | 
					        usize        Num;
 | 
				
			||||||
        uw        Capacity;
 | 
					        usize        Capacity;
 | 
				
			||||||
        allocator Allocator;
 | 
					        allocator Allocator;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
));
 | 
					));
 | 
				
			||||||
@@ -106,8 +106,8 @@ No validation, just glorified text injection.
 | 
				
			|||||||
Code header = code_str(
 | 
					Code header = code_str(
 | 
				
			||||||
    struct ArrayHeader
 | 
					    struct ArrayHeader
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uw        Num;
 | 
					        usize        Num;
 | 
				
			||||||
        uw        Capacity;
 | 
					        usize        Capacity;
 | 
				
			||||||
        allocator Allocator;
 | 
					        allocator Allocator;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
@@ -123,8 +123,8 @@ All three constrcuton interfaces will generate the following C code:
 | 
				
			|||||||
```cpp
 | 
					```cpp
 | 
				
			||||||
struct ArrayHeader
 | 
					struct ArrayHeader
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uw        Num;
 | 
					    usize        Num;
 | 
				
			||||||
    uw        Capacity;
 | 
					    usize        Capacity;
 | 
				
			||||||
    allocator Allocator;
 | 
					    allocator Allocator;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -136,7 +136,7 @@ The width dictates how much the static array can hold before it must give way to
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
```cpp
 | 
					```cpp
 | 
				
			||||||
constexpr static
 | 
					constexpr static
 | 
				
			||||||
uw ArrSpecs_Cap =
 | 
					usize ArrSpecs_Cap =
 | 
				
			||||||
(
 | 
					(
 | 
				
			||||||
    AST_POD_Size
 | 
					    AST_POD_Size
 | 
				
			||||||
    - sizeof(AST*) * 3
 | 
					    - sizeof(AST*) * 3
 | 
				
			||||||
@@ -158,7 +158,7 @@ Data Notes:
 | 
				
			|||||||
  * Most of the work is just defining the allocation procedure:
 | 
					  * Most of the work is just defining the allocation procedure:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```cpp
 | 
					```cpp
 | 
				
			||||||
    void* ( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
 | 
					    void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
 | 
					* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										10
									
								
								gencpp.10x
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								gencpp.10x
									
									
									
									
									
								
							@@ -6,6 +6,7 @@
 | 
				
			|||||||
		<SyncFiles>true</SyncFiles>
 | 
							<SyncFiles>true</SyncFiles>
 | 
				
			||||||
		<Recursive>true</Recursive>
 | 
							<Recursive>true</Recursive>
 | 
				
			||||||
		<ShowEmptyFolders>true</ShowEmptyFolders>
 | 
							<ShowEmptyFolders>true</ShowEmptyFolders>
 | 
				
			||||||
 | 
							<IncludeFilesWithoutExt>false</IncludeFilesWithoutExt>
 | 
				
			||||||
		<IsVirtual>false</IsVirtual>
 | 
							<IsVirtual>false</IsVirtual>
 | 
				
			||||||
		<IsFolder>false</IsFolder>
 | 
							<IsFolder>false</IsFolder>
 | 
				
			||||||
		<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
 | 
							<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
 | 
				
			||||||
@@ -14,12 +15,13 @@
 | 
				
			|||||||
		<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
 | 
							<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
 | 
				
			||||||
		<BuildWorkingDirectory></BuildWorkingDirectory>
 | 
							<BuildWorkingDirectory></BuildWorkingDirectory>
 | 
				
			||||||
		<CancelBuild></CancelBuild>
 | 
							<CancelBuild></CancelBuild>
 | 
				
			||||||
		<RunCommand>./test/gen/build/gencpp.exe</RunCommand>
 | 
							<Exe>./test/gen/build/gencpp.exe</Exe>
 | 
				
			||||||
		<RunCommandWorkingDirectory></RunCommandWorkingDirectory>
 | 
							<Args></Args>
 | 
				
			||||||
 | 
							<WorkingDirectory></WorkingDirectory>
 | 
				
			||||||
		<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
 | 
							<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
 | 
				
			||||||
		<ExePathCommand>./test/gen/build/gencpp.exe</ExePathCommand>
 | 
					 | 
				
			||||||
		<DebugSln></DebugSln>
 | 
							<DebugSln></DebugSln>
 | 
				
			||||||
		<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
 | 
							<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
 | 
				
			||||||
 | 
							<CaptureExeOutput>false</CaptureExeOutput>
 | 
				
			||||||
		<Configurations>
 | 
							<Configurations>
 | 
				
			||||||
			<Configuration>Debug</Configuration>
 | 
								<Configuration>Debug</Configuration>
 | 
				
			||||||
			<Configuration>Release</Configuration>
 | 
								<Configuration>Release</Configuration>
 | 
				
			||||||
@@ -44,6 +46,8 @@
 | 
				
			|||||||
			<Define>GEN_SYSTEM_WINDOWS</Define>
 | 
								<Define>GEN_SYSTEM_WINDOWS</Define>
 | 
				
			||||||
			<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
 | 
								<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
 | 
				
			||||||
			<Define>GEN_EXECUTION_EXPRESSION_SUPPORT</Define>
 | 
								<Define>GEN_EXECUTION_EXPRESSION_SUPPORT</Define>
 | 
				
			||||||
 | 
								<Define>GEN_BENCHMARK</Define>
 | 
				
			||||||
 | 
								<Define>GEN_COMPILER_MSVC</Define>
 | 
				
			||||||
		</Defines>
 | 
							</Defines>
 | 
				
			||||||
		<ConfigProperties>
 | 
							<ConfigProperties>
 | 
				
			||||||
			<ConfigAndPlatform>
 | 
								<ConfigAndPlatform>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,14 +27,14 @@ void Builder::pad_lines( s32 num )
 | 
				
			|||||||
void Builder::print( Code code )
 | 
					void Builder::print( Code code )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	String   str = code->to_string();
 | 
						String   str = code->to_string();
 | 
				
			||||||
	// const sw len = str.length();
 | 
						// const ssize len = str.length();
 | 
				
			||||||
	// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
 | 
						// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
 | 
				
			||||||
	Buffer.append( str );
 | 
						Buffer.append( str );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Builder::print_fmt( char const* fmt, ... )
 | 
					void Builder::print_fmt( char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw   res;
 | 
						ssize   res;
 | 
				
			||||||
	char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
 | 
						char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
@@ -48,7 +48,7 @@ void Builder::print_fmt( char const* fmt, ... )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Builder::write()
 | 
					void Builder::write()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	bool result = file_write( & File, Buffer, Buffer.length() );
 | 
						b32 result = file_write( & File, Buffer, Buffer.length() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( result == false )
 | 
						if ( result == false )
 | 
				
			||||||
		log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
 | 
							log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & File ) );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
					#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
				
			||||||
#	include "scanner.hpp"
 | 
					#	include "scanner.hpp"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
// This is a simple file reader that reads the entire file into memory.
 | 
					// This is a simple file reader that reads the entire file into memory.
 | 
				
			||||||
// It has an extra option to skip the first few lines for undesired includes.
 | 
					// It has an extra option to skip the first few lines for undesired includes.
 | 
				
			||||||
// This is done so that includes can be kept in dependency and component files so that intellisense works.
 | 
					// This is done so that includes can be kept in dependency and component files so that intellisense works.
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
Code scan_file( char const* path )
 | 
					Code scan_file( char const* path )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FileInfo file;
 | 
						FileInfo file;
 | 
				
			||||||
@@ -16,7 +17,7 @@ Code scan_file( char const* path )
 | 
				
			|||||||
		GEN_FATAL( "scan_file: Could not open: %s", path );
 | 
							GEN_FATAL( "scan_file: Could not open: %s", path );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw fsize = file_size( & file );
 | 
						ssize fsize = file_size( & file );
 | 
				
			||||||
	if ( fsize <= 0 )
 | 
						if ( fsize <= 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		GEN_FATAL("scan_file: %s is empty", path );
 | 
							GEN_FATAL("scan_file: %s is empty", path );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,126 +0,0 @@
 | 
				
			|||||||
Clear-Host
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_root     = git rev-parse --show-toplevel
 | 
					 | 
				
			||||||
$path_scripts  = Join-Path $path_root 'scripts'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$target_arch        = Join-Path $path_scripts 'helpers/target_arch.psm1'
 | 
					 | 
				
			||||||
$devshell           = Join-Path $path_scripts 'helpers/devshell.ps1'
 | 
					 | 
				
			||||||
$format_cpp	        = Join-Path $path_scripts 'helpers/format_cpp.psm1'
 | 
					 | 
				
			||||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
 | 
					 | 
				
			||||||
$vendor_toolchain   = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_project  = Join-Path $path_root     'project'
 | 
					 | 
				
			||||||
$path_aux      = Join-Path $path_project  'auxillary'
 | 
					 | 
				
			||||||
$path_vis_root = Join-Path $path_aux      'vis_ast'
 | 
					 | 
				
			||||||
$path_binaries = Join-Path $path_vis_root 'binaries'
 | 
					 | 
				
			||||||
$path_build    = Join-Path $path_vis_root 'build'
 | 
					 | 
				
			||||||
$path_code     = Join-Path $path_vis_root 'code'
 | 
					 | 
				
			||||||
$path_deps     = Join-Path $path_vis_root 'dependencies'
 | 
					 | 
				
			||||||
$path_win32    = Join-Path $path_code     'win32'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Import-Module $target_arch
 | 
					 | 
				
			||||||
Import-Module $format_cpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#region Arguments
 | 
					 | 
				
			||||||
$vendor           = $null
 | 
					 | 
				
			||||||
$optimize         = $null
 | 
					 | 
				
			||||||
$debug 	          = $null
 | 
					 | 
				
			||||||
$analysis	      = $false
 | 
					 | 
				
			||||||
$dev              = $false
 | 
					 | 
				
			||||||
$verbose          = $null
 | 
					 | 
				
			||||||
$platform         = $null
 | 
					 | 
				
			||||||
$module_specified = $false
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[array] $vendors = @( "clang", "msvc" )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This is a really lazy way of parsing the args, could use actual params down the line...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( $args ) { $args | ForEach-Object {
 | 
					 | 
				
			||||||
switch ($_){
 | 
					 | 
				
			||||||
 { $_ -in $vendors }   { $vendor    = $_; break }
 | 
					 | 
				
			||||||
 "optimize"            { $optimize  = $true }
 | 
					 | 
				
			||||||
 "debug"               { $debug     = $true }
 | 
					 | 
				
			||||||
 "analysis"            { $analysis  = $true }
 | 
					 | 
				
			||||||
 "dev"                 { $dev       = $true }
 | 
					 | 
				
			||||||
 "verbose"             { $verbose   = $true }
 | 
					 | 
				
			||||||
 "platform"            { $platform  = $true; $module_specified = $true }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
}}
 | 
					 | 
				
			||||||
#endregion Argument
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( -not $module_specified )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	$platform = $true
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Load up toolchain configuraion
 | 
					 | 
				
			||||||
. $vendor_toolchain
 | 
					 | 
				
			||||||
. $incremental_checks
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
write-host "Building Vis AST with $vendor"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( (Test-Path $path_build) -eq $false ) {
 | 
					 | 
				
			||||||
	New-Item $path_build -ItemType Directory
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( (Test-Path $path_binaries) -eq $false ) {
 | 
					 | 
				
			||||||
	New-Item $path_binaries -ItemType Directory
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_raylib     = join-path $path_deps   'raylib'
 | 
					 | 
				
			||||||
$path_raylib_inc = join-path $path_raylib 'include'
 | 
					 | 
				
			||||||
$path_raylib_lib = join-path $path_raylib 'lib'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_raylib_dll     = join-path $path_raylib_lib 'raylib.dll'
 | 
					 | 
				
			||||||
$path_raylib_dll_bin = join-path $path_binaries   'raylib.dll'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Copy-Item $path_raylib_dll $path_raylib_dll_bin -Force
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$includes = @(
 | 
					 | 
				
			||||||
	$path_code,
 | 
					 | 
				
			||||||
	$path_deps
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
write-host $path_code
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
foreach ( $include in $includes ) {
 | 
					 | 
				
			||||||
	Write-Host 'include: ' $include
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Microsoft
 | 
					 | 
				
			||||||
$lib_gdi32  = 'Gdi32.lib'
 | 
					 | 
				
			||||||
$lib_xinput = 'Xinput.lib'
 | 
					 | 
				
			||||||
$lib_user32 = 'User32.lib'
 | 
					 | 
				
			||||||
$lib_winmm  = 'Winmm.lib'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$stack_size = 1024 * 1024 * 4
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$compiler_args = @(
 | 
					 | 
				
			||||||
	( $flag_define + 'UNICODE'),
 | 
					 | 
				
			||||||
	( $flag_define + '_UNICODE')
 | 
					 | 
				
			||||||
	( $flag_define + 'INTELLISENSE_DIRECTIVES=0'),
 | 
					 | 
				
			||||||
	( $flag_define + 'RL_USE_LIBTYPE_SHARED')
 | 
					 | 
				
			||||||
	# ($flag_set_stack_size + $stack_size)
 | 
					 | 
				
			||||||
	$flag_wall
 | 
					 | 
				
			||||||
	$flag_warnings_as_errors
 | 
					 | 
				
			||||||
	$flag_optimize_intrinsics
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( $dev ) {
 | 
					 | 
				
			||||||
	$compiler_args += ( $flag_define + 'Build_Development=1' )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
else {
 | 
					 | 
				
			||||||
	$compiler_args += ( $flag_define + 'Build_Development=0' )
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$linker_args = @(
 | 
					 | 
				
			||||||
	$flag_link_win_subsystem_windows,
 | 
					 | 
				
			||||||
	$flag_link_optiiize_references,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	( join-path $path_raylib_lib 'raylib.lib' )
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$unit       = join-path $path_code     'vis_ast_windows.cpp'
 | 
					 | 
				
			||||||
$executable = join-path $path_binaries 'vis_ast.exe'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
					 | 
				
			||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
$path_root     = git rev-parse --show-toplevel
 | 
					 | 
				
			||||||
$path_scripts  = Join-Path $path_root 'scripts'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$target_arch        = Join-Path $path_scripts 'helpers/target_arch.psm1'
 | 
					 | 
				
			||||||
$devshell           = Join-Path $path_scripts 'helpers/devshell.ps1'
 | 
					 | 
				
			||||||
$format_cpp	        = Join-Path $path_scripts 'helpers/format_cpp.psm1'
 | 
					 | 
				
			||||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
 | 
					 | 
				
			||||||
$vendor_toolchain   = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_project  = Join-Path $path_root     'project'
 | 
					 | 
				
			||||||
$path_aux      = Join-Path $path_project  'auxillary'
 | 
					 | 
				
			||||||
$path_vis_root = Join-Path $path_aux      'vis_ast'
 | 
					 | 
				
			||||||
$path_binaries = Join-Path $path_vis_root 'binaries'
 | 
					 | 
				
			||||||
$path_build    = Join-Path $path_vis_root 'build'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( test-path $path_build ) {
 | 
					 | 
				
			||||||
	remove-item $path_build -Recurse
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( test-path $path_binaries ) {
 | 
					 | 
				
			||||||
	remove-item $path_binaries -recurse
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,25 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
#if INTELLISENSE_DIRECTIVES
 | 
					 | 
				
			||||||
#include "vendor/compiler.hpp"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define global        static // Global variables
 | 
					 | 
				
			||||||
#define internal      static // Internal linkage
 | 
					 | 
				
			||||||
#define local_persist static // Local Persisting variables
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define api_c extern "C"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define ccast( type, value ) ( const_cast< type >( (value) ) )
 | 
					 | 
				
			||||||
#define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
 | 
					 | 
				
			||||||
#define rcast( type, value ) reinterpret_cast< type >( value )
 | 
					 | 
				
			||||||
#define scast( type, value ) static_cast< type >( value )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define do_once()   for ( local_persist b32 once = true; once; once = false )
 | 
					 | 
				
			||||||
#define stmt( ... ) do { __VA_ARGS__; } while ( 0 )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define array_count( array ) ( sizeof( array ) / sizeof( ( array )[0] ) )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define kilobytes( x ) ( ( x ) * ( s64 )( 1024 ) )
 | 
					 | 
				
			||||||
#define megabytes( x ) ( kilobytes( x ) * ( s64 )( 1024 ) )
 | 
					 | 
				
			||||||
#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) )
 | 
					 | 
				
			||||||
#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) )
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
// Platform architecture
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined( _WIN64 ) || defined( __x86_64__ ) || defined( _M_X64 ) || defined( __64BIT__ ) || defined( __powerpc64__ ) || defined( __ppc64__ ) || defined( __aarch64__ )
 | 
					 | 
				
			||||||
#	ifndef ARCH_64_BIT
 | 
					 | 
				
			||||||
#		define ARCH_64_BIT 1
 | 
					 | 
				
			||||||
#	endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	error A 32-bit architecture is not supported
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
// Platform compiler
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined( _MSC_VER )
 | 
					 | 
				
			||||||
#	define Compiler_MSVC 1
 | 
					 | 
				
			||||||
#elif defined( __clang__ )
 | 
					 | 
				
			||||||
#	define Compiler_Clang 1
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	error "Unknown compiler"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined( __has_attribute )
 | 
					 | 
				
			||||||
#	define HAS_ATTRIBUTE( attribute ) __has_attribute( attribute )
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	define HAS_ATTRIBUTE( attribute ) ( 0 )
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef Compiler_Clang
 | 
					 | 
				
			||||||
#	define compiler_decorated_func_name __PRETTY_NAME__
 | 
					 | 
				
			||||||
#elif defined(Compiler_MSVC)
 | 
					 | 
				
			||||||
#	define compiler_decorated_func_name __FUNCDNAME__
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,34 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
#if INTELLISENSE_DIRECTIVES
 | 
					 | 
				
			||||||
#include "compiler.hpp"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef Compiler_MSVC
 | 
					 | 
				
			||||||
#pragma warning( disable: 4201 ) // Support for non-standard nameless struct or union extesnion
 | 
					 | 
				
			||||||
#pragma warning( disable: 4100 ) // Support for unreferenced formal parameters
 | 
					 | 
				
			||||||
#pragma warning( disable: 4800 ) // Support implicit conversion to bools
 | 
					 | 
				
			||||||
#pragma warning( disable: 4365 ) // Support for signed/unsigned mismatch auto-conversion
 | 
					 | 
				
			||||||
#pragma warning( disable: 4189 ) // Support for unused variables
 | 
					 | 
				
			||||||
#pragma warning( disable: 4514 ) // Support for unused inline functions
 | 
					 | 
				
			||||||
#pragma warning( disable: 4505 ) // Support for unused static functions
 | 
					 | 
				
			||||||
#pragma warning( disable: 5045 ) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
 | 
					 | 
				
			||||||
#pragma warning( disable: 5264 ) // Support for 'const' variables unused
 | 
					 | 
				
			||||||
#pragma warning( disable: 4820 ) // Support auto-adding padding to structs
 | 
					 | 
				
			||||||
#pragma warning( disable: 4711 ) // Support automatic inline expansion
 | 
					 | 
				
			||||||
#pragma warning( disable: 4710 ) // Support automatic inline expansion
 | 
					 | 
				
			||||||
#pragma warning( disable: 4805 ) // Support comparisons of s32 to bool.
 | 
					 | 
				
			||||||
#pragma warning( disable: 5246 ) // Support for initialization of subobject without braces.
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef Compiler_Clang
 | 
					 | 
				
			||||||
#pragma clang diagnostic push
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunused-const-variable"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wswitch"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunused-variable"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunused-local-typedef"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wvarargs"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunused-function"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wunused-but-set-variable"
 | 
					 | 
				
			||||||
#pragma clang diagnostic ignored "-Wmissing-braces"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,22 +0,0 @@
 | 
				
			|||||||
// Platform OS detection
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined( _WIN32 ) || defined( _WIN64 )
 | 
					 | 
				
			||||||
#	ifndef System_Windows
 | 
					 | 
				
			||||||
#		define System_Windows 1
 | 
					 | 
				
			||||||
#	endif
 | 
					 | 
				
			||||||
#elif defined( __APPLE__ ) && defined( __MACH__ )
 | 
					 | 
				
			||||||
#	ifndef System_MacOS
 | 
					 | 
				
			||||||
#		define System_MacOS 1
 | 
					 | 
				
			||||||
#	endif
 | 
					 | 
				
			||||||
#elif defined( __unix__ )
 | 
					 | 
				
			||||||
#	if defined( __linux__ )
 | 
					 | 
				
			||||||
#		ifndef System_Linux
 | 
					 | 
				
			||||||
#			define System_linux 1
 | 
					 | 
				
			||||||
#		endif
 | 
					 | 
				
			||||||
#	else
 | 
					 | 
				
			||||||
#		error This UNIX operating system is not supported
 | 
					 | 
				
			||||||
#	endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	error This operating system is not supported
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
@@ -1,45 +0,0 @@
 | 
				
			|||||||
#if INTELLISENSE_DIRECTIVES
 | 
					 | 
				
			||||||
#include "win32.hpp"
 | 
					 | 
				
			||||||
#include "raylib/include/raylib.h"
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int __stdcall WinMain( HINSTANCE instance, HINSTANCE prev_instance, char* commandline, int num_cmd_show)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Initialization
 | 
					 | 
				
			||||||
    //--------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
    const int screenWidth = 800;
 | 
					 | 
				
			||||||
    const int screenHeight = 450;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rl::init_window(screenWidth, screenHeight, "raylib [core] example - basic window");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    rl::set_target_fps(60);               // Set our game to run at 60 frames-per-second
 | 
					 | 
				
			||||||
    //--------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Main game loop
 | 
					 | 
				
			||||||
    while (!rl::window_should_close())    // Detect window close button or ESC key
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Update
 | 
					 | 
				
			||||||
        //----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
        // TODO: Update your variables here
 | 
					 | 
				
			||||||
        //----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Draw
 | 
					 | 
				
			||||||
        //----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
        rl::begin_drawing();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            rl::clear_background(RL_RAYWHITE);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            rl::draw_text("Congrats! You created your first window!", 190, 200, 20, RL_LIGHTGRAY);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        rl::end_drawing();
 | 
					 | 
				
			||||||
        //----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // De-Initialization
 | 
					 | 
				
			||||||
    //--------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
    rl::close_window();        // Close window and OpenGL context
 | 
					 | 
				
			||||||
    //--------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using HINSTANCE = void*;
 | 
					 | 
				
			||||||
@@ -1,14 +0,0 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "platform/vendor/arch.hpp"
 | 
					 | 
				
			||||||
#include "platform/vendor/compiler.hpp"
 | 
					 | 
				
			||||||
#include "platform/vendor/compiler_ignores.hpp"
 | 
					 | 
				
			||||||
#include "platform/vendor/os.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "platform/macros.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "platform/win32/types.hpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "raylib/include/raylib.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "platform/win32/launch.cpp"
 | 
					 | 
				
			||||||
@@ -1,285 +0,0 @@
 | 
				
			|||||||
/**********************************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   raylib configuration flags
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   This file defines all the configuration flags for the different raylib modules
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   LICENSE: zlib/libpng
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Copyright (c) 2018-2023 Ahmad Fatoum & Ramon Santamaria (@raysan5)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   This software is provided "as-is", without any express or implied warranty. In no event
 | 
					 | 
				
			||||||
*   will the authors be held liable for any damages arising from the use of this software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Permission is granted to anyone to use this software for any purpose, including commercial
 | 
					 | 
				
			||||||
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     1. The origin of this software must not be misrepresented; you must not claim that you
 | 
					 | 
				
			||||||
*     wrote the original software. If you use this software in a product, an acknowledgment
 | 
					 | 
				
			||||||
*     in the product documentation would be appreciated but is not required.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
 | 
					 | 
				
			||||||
*     as being the original software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     3. This notice may not be removed or altered from any source distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
**********************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef CONFIG_H
 | 
					 | 
				
			||||||
#define CONFIG_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module selection - Some modules could be avoided
 | 
					 | 
				
			||||||
// Mandatory modules: rcore, rlgl, utils
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MODULE_RSHAPES          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MODULE_RTEXTURES        1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MODULE_RTEXT            1       // WARNING: It requires RL_SUPPORT_MODULE_RTEXTURES to load sprite font textures
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MODULE_RMODELS          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MODULE_RAUDIO           1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rcore - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Camera module is included (rcamera.h) and multiple predefined cameras are available: free, 1st/3rd person, orbital
 | 
					 | 
				
			||||||
#define RL_SUPPORT_CAMERA_SYSTEM           1
 | 
					 | 
				
			||||||
// Gestures module is included (rgestures.h) to support gestures detection: tap, hold, swipe, drag
 | 
					 | 
				
			||||||
#define RL_SUPPORT_GESTURES_SYSTEM         1
 | 
					 | 
				
			||||||
// Include pseudo-random numbers generator (rprand.h), based on Xoshiro128** and SplitMix64
 | 
					 | 
				
			||||||
#define RL_SUPPORT_RPRAND_GENERATOR        1
 | 
					 | 
				
			||||||
// Mouse gestures are directly mapped like touches and processed by gestures system
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MOUSE_GESTURES          1
 | 
					 | 
				
			||||||
// Reconfigure standard input to receive key inputs, works with SSH connection.
 | 
					 | 
				
			||||||
#define RL_SUPPORT_SSH_KEYBOARD_RPI        1
 | 
					 | 
				
			||||||
// Setting a higher resolution can improve the accuracy of time-out intervals in wait functions.
 | 
					 | 
				
			||||||
// However, it can also reduce overall system performance, because the thread scheduler switches tasks more often.
 | 
					 | 
				
			||||||
#define RL_SUPPORT_WINMM_HIGHRES_TIMER     1
 | 
					 | 
				
			||||||
// Use busy wait loop for timing sync, if not defined, a high-resolution timer is set up and used
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_BUSY_WAIT_LOOP          1
 | 
					 | 
				
			||||||
// Use a partial-busy wait loop, in this case frame sleeps for most of the time, but then runs a busy loop at the end for accuracy
 | 
					 | 
				
			||||||
#define RL_SUPPORT_PARTIALBUSY_WAIT_LOOP    1
 | 
					 | 
				
			||||||
// Allow automatic screen capture of current screen pressing F12, defined in KeyCallback()
 | 
					 | 
				
			||||||
#define RL_SUPPORT_SCREEN_CAPTURE          1
 | 
					 | 
				
			||||||
// Allow automatic gif recording of current screen pressing CTRL+F12, defined in KeyCallback()
 | 
					 | 
				
			||||||
#define RL_SUPPORT_GIF_RECORDING           1
 | 
					 | 
				
			||||||
// Support CompressData() and DecompressData() functions
 | 
					 | 
				
			||||||
#define RL_SUPPORT_COMPRESSION_API         1
 | 
					 | 
				
			||||||
// Support automatic generated events, loading and recording of those events when required
 | 
					 | 
				
			||||||
#define RL_SUPPORT_AUTOMATION_EVENTS       1
 | 
					 | 
				
			||||||
// Support custom frame control, only for advance users
 | 
					 | 
				
			||||||
// By default end_drawing() does this job: draws everything + swap_screen_buffer() + manage frame timing + poll_input_events()
 | 
					 | 
				
			||||||
// Enabling this flag allows manual control of the frame processes, use at your own risk
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_CUSTOM_FRAME_CONTROL    1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// rcore: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_MAX_FILEPATH_CAPACITY        8192       // Maximum file paths capacity
 | 
					 | 
				
			||||||
#define RL_MAX_FILEPATH_LENGTH          4096       // Maximum length for filepaths (Linux PATH_MAX default value)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_KEYBOARD_KEYS             512       // Maximum number of keyboard keys supported
 | 
					 | 
				
			||||||
#define RL_MAX_MOUSE_BUTTONS               8       // Maximum number of mouse buttons supported
 | 
					 | 
				
			||||||
#define RL_MAX_GAMEPADS                    4       // Maximum number of gamepads supported
 | 
					 | 
				
			||||||
#define RL_MAX_GAMEPAD_AXIS                8       // Maximum number of axis supported (per gamepad)
 | 
					 | 
				
			||||||
#define RL_MAX_GAMEPAD_BUTTONS            32       // Maximum number of buttons supported (per gamepad)
 | 
					 | 
				
			||||||
#define RL_MAX_TOUCH_POINTS                8       // Maximum number of touch points supported
 | 
					 | 
				
			||||||
#define RL_MAX_KEY_PRESSED_QUEUE          16       // Maximum number of keys in the key input queue
 | 
					 | 
				
			||||||
#define RL_MAX_CHAR_PRESSED_QUEUE         16       // Maximum number of characters in the char input queue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_DECOMPRESSION_SIZE         64       // Max size allocated for decompression in MB
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_AUTOMATION_EVENTS       16384       // Maximum number of automation events to record
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rlgl - Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Enable OpenGL Debug Context (only available on OpenGL 4.3)
 | 
					 | 
				
			||||||
//#define RLGL_ENABLE_OPENGL_DEBUG_CONTEXT       1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Show OpenGL extensions and capabilities detailed logs on init
 | 
					 | 
				
			||||||
//#define RLGL_SHOW_GL_DETAILS_INFO              1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//#define RL_DEFAULT_BATCH_BUFFER_ELEMENTS    4096    // Default internal render batch elements limits
 | 
					 | 
				
			||||||
#define RL_DEFAULT_BATCH_BUFFERS               1      // Default number of batch buffers (multi-buffering)
 | 
					 | 
				
			||||||
#define RL_DEFAULT_BATCH_DRAWCALLS           256      // Default number of batch draw calls (by state changes: mode, texture)
 | 
					 | 
				
			||||||
#define RL_DEFAULT_BATCH_MAX_TEXTURE_UNITS     4      // Maximum number of textures units that can be activated on batch drawing (set_shader_value_texture())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_MATRIX_STACK_SIZE              32      // Maximum size of internal Matrix stack
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_SHADER_LOCATIONS               32      // Maximum number of shader locations supported
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_CULL_DISTANCE_NEAR               0.01      // Default projection matrix near cull distance
 | 
					 | 
				
			||||||
#define RL_CULL_DISTANCE_FAR              1000.0      // Default projection matrix far cull distance
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Default shader vertex attribute names to set location points
 | 
					 | 
				
			||||||
// NOTE: When a new shader is loaded, the following locations are tried to be set for convenience
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_POSITION     "vertexPosition"    // Bound by default to shader location: 0
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD     "vertexTexCoord"    // Bound by default to shader location: 1
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_NORMAL       "vertexNormal"      // Bound by default to shader location: 2
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_COLOR        "vertexColor"       // Bound by default to shader location: 3
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TANGENT      "vertexTangent"     // Bound by default to shader location: 4
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_ATTRIB_NAME_TEXCOORD2    "vertexTexCoord2"   // Bound by default to shader location: 5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MVP         "mvp"               // model-view-projection matrix
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_VIEW        "matView"           // view matrix
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_PROJECTION  "matProjection"     // projection matrix
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_MODEL       "matModel"          // model matrix
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_NORMAL      "matNormal"         // normal matrix (transpose(inverse(matModelView))
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_UNIFORM_NAME_COLOR       "colDiffuse"        // color diffuse (base tint color, multiplied by texture color)
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE0  "texture0"          // texture0 (texture slot active 0)
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE1  "texture1"          // texture1 (texture slot active 1)
 | 
					 | 
				
			||||||
#define RL_DEFAULT_SHADER_SAMPLER2D_NAME_TEXTURE2  "texture2"          // texture2 (texture slot active 2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rshapes - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Use QUADS instead of TRIANGLES for drawing when possible
 | 
					 | 
				
			||||||
// Some lines-based shapes could still use lines
 | 
					 | 
				
			||||||
#define RL_SUPPORT_QUADS_DRAW_MODE         1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// rshapes: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define SPLINE_SEGMENT_DIVISIONS       24       // Spline segments subdivisions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rtextures - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Selecte desired fileformats to be supported for image data loading
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_PNG      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_BMP      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_TGA      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_JPG      1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_GIF      1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_QOI      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_PSD      1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_DDS      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_HDR      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_PIC          1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_KTX      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_ASTC     1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_PKM      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_PVR      1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_SVG      1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Support image export functionality (.png, .bmp, .tga, .jpg, .qoi)
 | 
					 | 
				
			||||||
#define RL_SUPPORT_IMAGE_EXPORT            1
 | 
					 | 
				
			||||||
// Support procedural image generation functionality (gradient, spot, perlin-noise, cellular)
 | 
					 | 
				
			||||||
#define RL_SUPPORT_IMAGE_GENERATION        1
 | 
					 | 
				
			||||||
// Support multiple image editing functions to scale, adjust colors, flip, draw on images, crop...
 | 
					 | 
				
			||||||
// If not defined, still some functions are supported: image_format(), image_crop(), image_to_pot()
 | 
					 | 
				
			||||||
#define RL_SUPPORT_IMAGE_MANIPULATION      1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rtext - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Default font is loaded on window initialization to be available for the user to render simple text
 | 
					 | 
				
			||||||
// NOTE: If enabled, uses external module functions to load default raylib font
 | 
					 | 
				
			||||||
#define RL_SUPPORT_DEFAULT_FONT            1
 | 
					 | 
				
			||||||
// Selected desired font fileformats to be supported for loading
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_FNT          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_TTF          1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Support text management functions
 | 
					 | 
				
			||||||
// If not defined, still some functions are supported: text_length(), TextFormat()
 | 
					 | 
				
			||||||
#define RL_SUPPORT_TEXT_MANIPULATION       1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// On font atlas image generation [gen_image_font_atlas()], add a 3x3 pixels white rectangle
 | 
					 | 
				
			||||||
// at the bottom-right corner of the atlas. It can be useful to for shapes drawing, to allow
 | 
					 | 
				
			||||||
// drawing text and shapes with a single draw call [set_shapes_texture()].
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FONT_ATLAS_WHITE_REC    1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// rtext: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_MAX_TEXT_BUFFER_LENGTH       1024       // Size of internal static buffers used on some functions:
 | 
					 | 
				
			||||||
                                                // TextFormat(), TextSubtext(), TextToUpper(), TextToLower(), TextToPascal(), TextSplit()
 | 
					 | 
				
			||||||
#define RL_MAX_TEXTSPLIT_COUNT           128       // Maximum number of substrings to split: TextSplit()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: rmodels - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Selected desired model fileformats to be supported for loading
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_OBJ          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_MTL          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_IQM          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_GLTF         1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_VOX          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_M3D          1
 | 
					 | 
				
			||||||
// Support procedural mesh generation functions, uses external par_shapes.h library
 | 
					 | 
				
			||||||
// NOTE: Some generated meshes DO NOT include generated texture coordinates
 | 
					 | 
				
			||||||
#define RL_SUPPORT_MESH_GENERATION         1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// rmodels: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_MAX_MATERIAL_MAPS              12       // Maximum number of shader maps supported
 | 
					 | 
				
			||||||
#define RL_MAX_MESH_VERTEX_BUFFERS         7       // Maximum vertex buffers (VBO) per mesh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: raudio - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Desired audio fileformats to be supported for loading
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_WAV          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_OGG          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_MP3          1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_QOA          1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_FILEFORMAT_FLAC         1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_XM           1
 | 
					 | 
				
			||||||
#define RL_SUPPORT_FILEFORMAT_MOD          1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// raudio: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_AUDIO_DEVICE_FORMAT    ma_format_f32    // Device output format (miniaudio: float-32bit)
 | 
					 | 
				
			||||||
#define RL_AUDIO_DEVICE_CHANNELS              2    // Device output channels: stereo
 | 
					 | 
				
			||||||
#define RL_AUDIO_DEVICE_SAMPLE_RATE           0    // Device sample rate (device default)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_MAX_AUDIO_BUFFER_POOL_CHANNELS    16    // Maximum number of audio pool channels
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module: utils - Configuration Flags
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Standard file io library (stdio.h) included
 | 
					 | 
				
			||||||
#define RL_SUPPORT_STANDARD_FILEIO         1
 | 
					 | 
				
			||||||
// Show RL_TRACELOG() output messages
 | 
					 | 
				
			||||||
// NOTE: By default LOG_DEBUG traces not shown
 | 
					 | 
				
			||||||
#define RL_SUPPORT_TRACELOG                1
 | 
					 | 
				
			||||||
//#define RL_SUPPORT_TRACELOG_DEBUG          1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// utils: Configuration values
 | 
					 | 
				
			||||||
//------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_MAX_TRACELOG_MSG_LENGTH       256       // Max length of one trace-log message
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // CONFIG_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Indicates of raylib has been refactored
 | 
					 | 
				
			||||||
#ifndef RL_REFACTORED_CPP
 | 
					 | 
				
			||||||
#define RL_REFACTORED_CPP
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define RL_USE_CPP_NAMESPACE 1
 | 
					 | 
				
			||||||
#define RL_USE_CPP_MANGLING  1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if RL_USE_CPP_NAMESPACE && defined(__cplusplus)
 | 
					 | 
				
			||||||
    #pragma message("USING CPP NAMESPACE")
 | 
					 | 
				
			||||||
    #define RL_NS_BEGIN namespace rl {
 | 
					 | 
				
			||||||
    #define RL_NS_END }
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #define RL_NS_BEGIN
 | 
					 | 
				
			||||||
    #define RL_NS_END
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if RL_USE_CPP_MANGLING && defined(__cplusplus)
 | 
					 | 
				
			||||||
    #pragma message("USING CPP MANGLING")
 | 
					 | 
				
			||||||
    #define RL_EXTERN_C_BEGIN
 | 
					 | 
				
			||||||
    #define RL_EXTERN_C_END
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #ifdef __cplusplus
 | 
					 | 
				
			||||||
        #define RL_EXTERN_C_BEGIN extern "C" {
 | 
					 | 
				
			||||||
        #define RL_EXTERN_C_END   }
 | 
					 | 
				
			||||||
    #else
 | 
					 | 
				
			||||||
        #define RL_EXTERN_C_BEGIN
 | 
					 | 
				
			||||||
        #define RL_EXTERN_C_END
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,562 +0,0 @@
 | 
				
			|||||||
/*******************************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   rcamera - Basic camera system with support for multiple camera modes
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   CONFIGURATION:
 | 
					 | 
				
			||||||
*       #define RCAMERA_IMPLEMENTATION
 | 
					 | 
				
			||||||
*           Generates the implementation of the library into the included file.
 | 
					 | 
				
			||||||
*           If not defined, the library is in header only mode and can be included in other headers
 | 
					 | 
				
			||||||
*           or source files without problems. But only ONE file should hold the implementation.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*       #define RCAMERA_STANDALONE
 | 
					 | 
				
			||||||
*           If defined, the library can be used as standalone as a camera system but some
 | 
					 | 
				
			||||||
*           functions must be redefined to manage inputs accordingly.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   CONTRIBUTORS:
 | 
					 | 
				
			||||||
*       Ramon Santamaria:   Supervision, review, update and maintenance
 | 
					 | 
				
			||||||
*       Christoph Wagner:   Complete redesign, using raymath (2022)
 | 
					 | 
				
			||||||
*       Marc Palau:         Initial implementation (2014)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   LICENSE: zlib/libpng
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Copyright (c) 2022-2023 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   This software is provided "as-is", without any express or implied warranty. In no event
 | 
					 | 
				
			||||||
*   will the authors be held liable for any damages arising from the use of this software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Permission is granted to anyone to use this software for any purpose, including commercial
 | 
					 | 
				
			||||||
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     1. The origin of this software must not be misrepresented; you must not claim that you
 | 
					 | 
				
			||||||
*     wrote the original software. If you use this software in a product, an acknowledgment
 | 
					 | 
				
			||||||
*     in the product documentation would be appreciated but is not required.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
 | 
					 | 
				
			||||||
*     as being the original software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     3. This notice may not be removed or altered from any source distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
**********************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef RCAMERA_H
 | 
					 | 
				
			||||||
#define RCAMERA_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Defines and Macros
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Function specifiers definition
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Function specifiers in case library is build/used as a shared library (Windows)
 | 
					 | 
				
			||||||
// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
 | 
					 | 
				
			||||||
#if defined(_WIN32)
 | 
					 | 
				
			||||||
#if defined(RL_BUILD_LIBTYPE_SHARED)
 | 
					 | 
				
			||||||
#if defined(__TINYC__)
 | 
					 | 
				
			||||||
#define __declspec(x) __attribute__((x))
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
 | 
					 | 
				
			||||||
#elif defined(RL_USE_LIBTYPE_SHARED)
 | 
					 | 
				
			||||||
#define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef RLAPI
 | 
					 | 
				
			||||||
    #define RLAPI       // Functions defined as 'extern' by default (implicit specifiers)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RCAMERA_STANDALONE)
 | 
					 | 
				
			||||||
    #define RL_CAMERA_CULL_DISTANCE_NEAR      0.01
 | 
					 | 
				
			||||||
    #define RL_CAMERA_CULL_DISTANCE_FAR    1000.0
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #define RL_CAMERA_CULL_DISTANCE_NEAR   RL_CULL_DISTANCE_NEAR
 | 
					 | 
				
			||||||
    #define RL_CAMERA_CULL_DISTANCE_FAR    RL_CULL_DISTANCE_FAR
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Types and Structures Definition
 | 
					 | 
				
			||||||
// NOTE: Below types are required for standalone usage
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#if defined(RCAMERA_STANDALONE)
 | 
					 | 
				
			||||||
    // Vector2, 2 components
 | 
					 | 
				
			||||||
    typedef struct Vector2 {
 | 
					 | 
				
			||||||
        float x;                // Vector x component
 | 
					 | 
				
			||||||
        float y;                // Vector y component
 | 
					 | 
				
			||||||
    } Vector2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Vector3, 3 components
 | 
					 | 
				
			||||||
    typedef struct Vector3 {
 | 
					 | 
				
			||||||
        float x;                // Vector x component
 | 
					 | 
				
			||||||
        float y;                // Vector y component
 | 
					 | 
				
			||||||
        float z;                // Vector z component
 | 
					 | 
				
			||||||
    } Vector3;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Matrix, 4x4 components, column major, OpenGL style, right-handed
 | 
					 | 
				
			||||||
    typedef struct Matrix {
 | 
					 | 
				
			||||||
        float m0, m4, m8, m12;  // Matrix first row (4 components)
 | 
					 | 
				
			||||||
        float m1, m5, m9, m13;  // Matrix second row (4 components)
 | 
					 | 
				
			||||||
        float m2, m6, m10, m14; // Matrix third row (4 components)
 | 
					 | 
				
			||||||
        float m3, m7, m11, m15; // Matrix fourth row (4 components)
 | 
					 | 
				
			||||||
    } Matrix;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Camera type, defines a camera position/orientation in 3d space
 | 
					 | 
				
			||||||
    typedef struct Camera3D {
 | 
					 | 
				
			||||||
        Vector3 position;       // Camera position
 | 
					 | 
				
			||||||
        Vector3 target;         // Camera target it looks-at
 | 
					 | 
				
			||||||
        Vector3 up;             // Camera up vector (rotation over its axis)
 | 
					 | 
				
			||||||
        float fovy;             // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
 | 
					 | 
				
			||||||
        int projection;         // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
 | 
					 | 
				
			||||||
    } Camera3D;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Camera projection
 | 
					 | 
				
			||||||
    typedef enum {
 | 
					 | 
				
			||||||
        CAMERA_PERSPECTIVE = 0, // Perspective projection
 | 
					 | 
				
			||||||
        CAMERA_ORTHOGRAPHIC     // Orthographic projection
 | 
					 | 
				
			||||||
    } CameraProjection;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Camera system modes
 | 
					 | 
				
			||||||
    typedef enum {
 | 
					 | 
				
			||||||
        CAMERA_CUSTOM = 0,      // Camera custom, controlled by user (update_camera() does nothing)
 | 
					 | 
				
			||||||
        CAMERA_FREE,            // Camera free mode
 | 
					 | 
				
			||||||
        CAMERA_ORBITAL,         // Camera orbital, around target, zoom supported
 | 
					 | 
				
			||||||
        CAMERA_FIRST_PERSON,    // Camera first person
 | 
					 | 
				
			||||||
        CAMERA_THIRD_PERSON     // Camera third person
 | 
					 | 
				
			||||||
    } CameraMode;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Global Variables Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module Functions Declaration
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_EXTERN_C_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RLAPI Vector3 get_camera_forward(Camera *camera);
 | 
					 | 
				
			||||||
RLAPI Vector3 get_camera_up(Camera *camera);
 | 
					 | 
				
			||||||
RLAPI Vector3 get_camera_right(Camera *camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Camera movement
 | 
					 | 
				
			||||||
RLAPI void camera_move_forward(Camera *camera, float distance, bool moveInWorldPlane);
 | 
					 | 
				
			||||||
RLAPI void camera_move_up(Camera *camera, float distance);
 | 
					 | 
				
			||||||
RLAPI void camera_move_right(Camera *camera, float distance, bool moveInWorldPlane);
 | 
					 | 
				
			||||||
RLAPI void camera_move_to_target(Camera *camera, float delta);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Camera rotation
 | 
					 | 
				
			||||||
RLAPI void camera_yaw(Camera *camera, float angle, bool rotateAroundTarget);
 | 
					 | 
				
			||||||
RLAPI void camera_pitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
 | 
					 | 
				
			||||||
RLAPI void camera_roll(Camera *camera, float angle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RLAPI Matrix get_camera_view_matrix(Camera *camera);
 | 
					 | 
				
			||||||
RLAPI Matrix get_camera_projection_matrix(Camera* camera, float aspect);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_EXTERN_C_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // RCAMERA_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***********************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   CAMERA IMPLEMENTATION
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RCAMERA_IMPLEMENTATION)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "raymath.h"        // Required for vector maths:
 | 
					 | 
				
			||||||
                            // vector3_add()
 | 
					 | 
				
			||||||
                            // vector3_subtract()
 | 
					 | 
				
			||||||
                            // vector3_scale()
 | 
					 | 
				
			||||||
                            // vector3_normalize()
 | 
					 | 
				
			||||||
                            // vector3_distance()
 | 
					 | 
				
			||||||
                            // vector3_cross_product()
 | 
					 | 
				
			||||||
                            // vector3_rotate_by_axis_angle()
 | 
					 | 
				
			||||||
                            // vector3_angle()
 | 
					 | 
				
			||||||
                            // vector3_negate()
 | 
					 | 
				
			||||||
                            // matrix_look_at()
 | 
					 | 
				
			||||||
                            // matrix_perspective()
 | 
					 | 
				
			||||||
                            // matrix_ortho()
 | 
					 | 
				
			||||||
                            // matrix_identity()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// raylib required functionality:
 | 
					 | 
				
			||||||
                            // get_mouse_delta()
 | 
					 | 
				
			||||||
                            // get_mouse_wheel_move()
 | 
					 | 
				
			||||||
                            // is_key_down()
 | 
					 | 
				
			||||||
                            // is_key_pressed()
 | 
					 | 
				
			||||||
                            // get_frame_time()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Defines and Macros
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define CAMERA_MOVE_SPEED                               0.09f
 | 
					 | 
				
			||||||
#define CAMERA_ROTATION_SPEED                           0.03f
 | 
					 | 
				
			||||||
#define CAMERA_PAN_SPEED                                0.2f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Camera mouse movement sensitivity
 | 
					 | 
				
			||||||
#define CAMERA_MOUSE_MOVE_SENSITIVITY                   0.003f     // TODO: it should be independant of framerate
 | 
					 | 
				
			||||||
#define CAMERA_MOUSE_SCROLL_SENSITIVITY                 1.5f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAMERA_ORBITAL_SPEED                            0.5f       // Radians per second
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER  8.0f
 | 
					 | 
				
			||||||
#define CAMERA_FIRST_PERSON_STEP_DIVIDER                30.0f
 | 
					 | 
				
			||||||
#define CAMERA_FIRST_PERSON_WAVING_DIVIDER              200.0f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PLAYER (used by camera)
 | 
					 | 
				
			||||||
#define PLAYER_MOVEMENT_SENSITIVITY                     20.0f
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Types and Structures Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Global Variables Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module specific Functions Declaration
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module Functions Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Returns the cameras forward vector (normalized)
 | 
					 | 
				
			||||||
Vector3 get_camera_forward(Camera *camera)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return vector3_normalize(vector3_subtract(camera->target, camera->position));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Returns the cameras up vector (normalized)
 | 
					 | 
				
			||||||
// Note: The up vector might not be perpendicular to the forward vector
 | 
					 | 
				
			||||||
Vector3 get_camera_up(Camera *camera)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return vector3_normalize(camera->up);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Returns the cameras right vector (normalized)
 | 
					 | 
				
			||||||
Vector3 get_camera_right(Camera *camera)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Vector3 forward = get_camera_forward(camera);
 | 
					 | 
				
			||||||
    Vector3 up = get_camera_up(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return vector3_cross_product(forward, up);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Moves the camera in its forward direction
 | 
					 | 
				
			||||||
void camera_move_forward(Camera *camera, float distance, bool moveInWorldPlane)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Vector3 forward = get_camera_forward(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (moveInWorldPlane)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Project vector onto world plane
 | 
					 | 
				
			||||||
        forward.y = 0;
 | 
					 | 
				
			||||||
        forward = vector3_normalize(forward);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Scale by distance
 | 
					 | 
				
			||||||
    forward = vector3_scale(forward, distance);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Move position and target
 | 
					 | 
				
			||||||
    camera->position = vector3_add(camera->position, forward);
 | 
					 | 
				
			||||||
    camera->target = vector3_add(camera->target, forward);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Moves the camera in its up direction
 | 
					 | 
				
			||||||
void camera_move_up(Camera *camera, float distance)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Vector3 up = get_camera_up(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Scale by distance
 | 
					 | 
				
			||||||
    up = vector3_scale(up, distance);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Move position and target
 | 
					 | 
				
			||||||
    camera->position = vector3_add(camera->position, up);
 | 
					 | 
				
			||||||
    camera->target = vector3_add(camera->target, up);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Moves the camera target in its current right direction
 | 
					 | 
				
			||||||
void camera_move_right(Camera *camera, float distance, bool moveInWorldPlane)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Vector3 right = get_camera_right(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (moveInWorldPlane)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Project vector onto world plane
 | 
					 | 
				
			||||||
        right.y = 0;
 | 
					 | 
				
			||||||
        right = vector3_normalize(right);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Scale by distance
 | 
					 | 
				
			||||||
    right = vector3_scale(right, distance);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Move position and target
 | 
					 | 
				
			||||||
    camera->position = vector3_add(camera->position, right);
 | 
					 | 
				
			||||||
    camera->target = vector3_add(camera->target, right);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Moves the camera position closer/farther to/from the camera target
 | 
					 | 
				
			||||||
void camera_move_to_target(Camera *camera, float delta)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float distance = vector3_distance(camera->position, camera->target);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Apply delta
 | 
					 | 
				
			||||||
    distance += delta;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Distance must be greater than 0
 | 
					 | 
				
			||||||
    if (distance <= 0) distance = 0.001f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Set new distance by moving the position along the forward vector
 | 
					 | 
				
			||||||
    Vector3 forward = get_camera_forward(camera);
 | 
					 | 
				
			||||||
    camera->position = vector3_add(camera->target, vector3_scale(forward, -distance));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Rotates the camera around its up vector
 | 
					 | 
				
			||||||
// Yaw is "looking left and right"
 | 
					 | 
				
			||||||
// If rotateAroundTarget is false, the camera rotates around its position
 | 
					 | 
				
			||||||
// Note: angle must be provided in radians
 | 
					 | 
				
			||||||
void camera_yaw(Camera *camera, float angle, bool rotateAroundTarget)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Rotation axis
 | 
					 | 
				
			||||||
    Vector3 up = get_camera_up(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // View vector
 | 
					 | 
				
			||||||
    Vector3 targetPosition = vector3_subtract(camera->target, camera->position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Rotate view vector around up axis
 | 
					 | 
				
			||||||
    targetPosition = vector3_rotate_by_axis_angle(targetPosition, up, angle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rotateAroundTarget)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Move position relative to target
 | 
					 | 
				
			||||||
        camera->position = vector3_subtract(camera->target, targetPosition);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else // rotate around camera.position
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Move target relative to position
 | 
					 | 
				
			||||||
        camera->target = vector3_add(camera->position, targetPosition);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Rotates the camera around its right vector, pitch is "looking up and down"
 | 
					 | 
				
			||||||
//  - lockView prevents camera overrotation (aka "somersaults")
 | 
					 | 
				
			||||||
//  - rotateAroundTarget defines if rotation is around target or around its position
 | 
					 | 
				
			||||||
//  - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
 | 
					 | 
				
			||||||
// NOTE: angle must be provided in radians
 | 
					 | 
				
			||||||
void camera_pitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Up direction
 | 
					 | 
				
			||||||
    Vector3 up = get_camera_up(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // View vector
 | 
					 | 
				
			||||||
    Vector3 targetPosition = vector3_subtract(camera->target, camera->position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (lockView)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // In these camera modes we clamp the Pitch angle
 | 
					 | 
				
			||||||
        // to allow only viewing straight up or down.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // clamp view up
 | 
					 | 
				
			||||||
        float maxAngleUp = vector3_angle(up, targetPosition);
 | 
					 | 
				
			||||||
        maxAngleUp -= 0.001f; // avoid numerical errors
 | 
					 | 
				
			||||||
        if (angle > maxAngleUp) angle = maxAngleUp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // clamp view down
 | 
					 | 
				
			||||||
        float maxAngleDown = vector3_angle(vector3_negate(up), targetPosition);
 | 
					 | 
				
			||||||
        maxAngleDown *= -1.0f; // downwards angle is negative
 | 
					 | 
				
			||||||
        maxAngleDown += 0.001f; // avoid numerical errors
 | 
					 | 
				
			||||||
        if (angle < maxAngleDown) angle = maxAngleDown;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Rotation axis
 | 
					 | 
				
			||||||
    Vector3 right = get_camera_right(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Rotate view vector around right axis
 | 
					 | 
				
			||||||
    targetPosition = vector3_rotate_by_axis_angle(targetPosition, right, angle);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rotateAroundTarget)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Move position relative to target
 | 
					 | 
				
			||||||
        camera->position = vector3_subtract(camera->target, targetPosition);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else // rotate around camera.position
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Move target relative to position
 | 
					 | 
				
			||||||
        camera->target = vector3_add(camera->position, targetPosition);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (rotateUp)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Rotate up direction around right axis
 | 
					 | 
				
			||||||
        camera->up = vector3_rotate_by_axis_angle(camera->up, right, angle);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Rotates the camera around its forward vector
 | 
					 | 
				
			||||||
// Roll is "turning your head sideways to the left or right"
 | 
					 | 
				
			||||||
// Note: angle must be provided in radians
 | 
					 | 
				
			||||||
void camera_roll(Camera *camera, float angle)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Rotation axis
 | 
					 | 
				
			||||||
    Vector3 forward = get_camera_forward(camera);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Rotate up direction around forward axis
 | 
					 | 
				
			||||||
    camera->up = vector3_rotate_by_axis_angle(camera->up, forward, angle);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Returns the camera view matrix
 | 
					 | 
				
			||||||
Matrix get_camera_view_matrix(Camera *camera)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return matrix_look_at(camera->position, camera->target, camera->up);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Returns the camera projection matrix
 | 
					 | 
				
			||||||
Matrix get_camera_projection_matrix(Camera *camera, float aspect)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (camera->projection == CAMERA_PERSPECTIVE)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return matrix_perspective(camera->fovy*RL_DEG2RAD, aspect, RL_CAMERA_CULL_DISTANCE_NEAR, RL_CAMERA_CULL_DISTANCE_FAR);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (camera->projection == CAMERA_ORTHOGRAPHIC)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        double top = camera->fovy/2.0;
 | 
					 | 
				
			||||||
        double right = top*aspect;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return matrix_ortho(-right, right, -top, top, RL_CAMERA_CULL_DISTANCE_NEAR, RL_CAMERA_CULL_DISTANCE_FAR);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return matrix_identity();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(RCAMERA_STANDALONE)
 | 
					 | 
				
			||||||
// Update camera position for selected mode
 | 
					 | 
				
			||||||
// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
 | 
					 | 
				
			||||||
void update_camera(Camera *camera, int mode)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    Vector2 mousePositionDelta = get_mouse_delta();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
 | 
					 | 
				
			||||||
    bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
 | 
					 | 
				
			||||||
    bool lockView = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
 | 
					 | 
				
			||||||
    bool rotateUp = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (mode == CAMERA_ORBITAL)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Orbital can just orbit
 | 
					 | 
				
			||||||
        Matrix rotation = matrix_rotate(get_camera_up(camera), CAMERA_ORBITAL_SPEED*get_frame_time());
 | 
					 | 
				
			||||||
        Vector3 view = vector3_subtract(camera->position, camera->target);
 | 
					 | 
				
			||||||
        view = vector3_transform(view, rotation);
 | 
					 | 
				
			||||||
        camera->position = vector3_add(camera->target, view);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Camera rotation
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_DOWN)) camera_pitch(camera, -CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_UP)) camera_pitch(camera, CAMERA_ROTATION_SPEED, lockView, rotateAroundTarget, rotateUp);
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_RIGHT)) camera_yaw(camera, -CAMERA_ROTATION_SPEED, rotateAroundTarget);
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_LEFT)) camera_yaw(camera, CAMERA_ROTATION_SPEED, rotateAroundTarget);
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_Q)) camera_roll(camera, -CAMERA_ROTATION_SPEED);
 | 
					 | 
				
			||||||
        if (is_key_down(KEY_E)) camera_roll(camera, CAMERA_ROTATION_SPEED);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Camera movement
 | 
					 | 
				
			||||||
        if (!is_gamepad_available(0))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Camera pan (for CAMERA_FREE)
 | 
					 | 
				
			||||||
            if ((mode == CAMERA_FREE) && (is_mouse_button_down(MOUSE_BUTTON_MIDDLE)))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                const Vector2 mouseDelta = get_mouse_delta();
 | 
					 | 
				
			||||||
                if (mouseDelta.x > 0.0f) camera_move_right(camera, CAMERA_PAN_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
                if (mouseDelta.x < 0.0f) camera_move_right(camera, -CAMERA_PAN_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
                if (mouseDelta.y > 0.0f) camera_move_up(camera, -CAMERA_PAN_SPEED);
 | 
					 | 
				
			||||||
                if (mouseDelta.y < 0.0f) camera_move_up(camera, CAMERA_PAN_SPEED);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // Mouse support
 | 
					 | 
				
			||||||
                camera_yaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
 | 
					 | 
				
			||||||
                camera_pitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Keyboard support
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_W)) camera_move_forward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_A)) camera_move_right(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_S)) camera_move_forward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_D)) camera_move_right(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // Gamepad controller support
 | 
					 | 
				
			||||||
            camera_yaw(camera, -(get_gamepad_axis_movement(0, GAMEPAD_AXIS_RIGHT_X) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
 | 
					 | 
				
			||||||
            camera_pitch(camera, -(get_gamepad_axis_movement(0, GAMEPAD_AXIS_RIGHT_Y) * 2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) camera_move_forward(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) camera_move_right(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) camera_move_forward(camera, -CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
            if (get_gamepad_axis_movement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) camera_move_right(camera, CAMERA_MOVE_SPEED, moveInWorldPlane);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (mode == CAMERA_FREE)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_SPACE)) camera_move_up(camera, CAMERA_MOVE_SPEED);
 | 
					 | 
				
			||||||
            if (is_key_down(KEY_LEFT_CONTROL)) camera_move_up(camera, -CAMERA_MOVE_SPEED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // Zoom target distance
 | 
					 | 
				
			||||||
        camera_move_to_target(camera, -get_mouse_wheel_move());
 | 
					 | 
				
			||||||
        if (is_key_pressed(KEY_KP_SUBTRACT)) camera_move_to_target(camera, 2.0f);
 | 
					 | 
				
			||||||
        if (is_key_pressed(KEY_KP_ADD)) camera_move_to_target(camera, -2.0f);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif // !RCAMERA_STANDALONE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Update camera movement, movement/rotation values should be provided by user
 | 
					 | 
				
			||||||
void update_camera_pro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Required values
 | 
					 | 
				
			||||||
    // movement.x - Move forward/backward
 | 
					 | 
				
			||||||
    // movement.y - Move right/left
 | 
					 | 
				
			||||||
    // movement.z - Move up/down
 | 
					 | 
				
			||||||
    // rotation.x - yaw
 | 
					 | 
				
			||||||
    // rotation.y - pitch
 | 
					 | 
				
			||||||
    // rotation.z - roll
 | 
					 | 
				
			||||||
    // zoom - Move towards target
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool lockView = true;
 | 
					 | 
				
			||||||
    bool rotateAroundTarget = false;
 | 
					 | 
				
			||||||
    bool rotateUp = false;
 | 
					 | 
				
			||||||
    bool moveInWorldPlane = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Camera rotation
 | 
					 | 
				
			||||||
    camera_pitch(camera, -rotation.y*RL_DEG2RAD, lockView, rotateAroundTarget, rotateUp);
 | 
					 | 
				
			||||||
    camera_yaw(camera, -rotation.x*RL_DEG2RAD, rotateAroundTarget);
 | 
					 | 
				
			||||||
    camera_roll(camera, rotation.z*RL_DEG2RAD);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Camera movement
 | 
					 | 
				
			||||||
    camera_move_forward(camera, movement.x, moveInWorldPlane);
 | 
					 | 
				
			||||||
    camera_move_right(camera, movement.y, moveInWorldPlane);
 | 
					 | 
				
			||||||
    camera_move_up(camera, movement.z);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Zoom target distance
 | 
					 | 
				
			||||||
    camera_move_to_target(camera, zoom);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // RCAMERA_IMPLEMENTATION
 | 
					 | 
				
			||||||
@@ -1,579 +0,0 @@
 | 
				
			|||||||
/**********************************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   rgestures - Gestures system, gestures processing based on input events (touch/mouse)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   CONFIGURATION:
 | 
					 | 
				
			||||||
*       #define RGESTURES_IMPLEMENTATION
 | 
					 | 
				
			||||||
*           Generates the implementation of the library into the included file.
 | 
					 | 
				
			||||||
*           If not defined, the library is in header only mode and can be included in other headers
 | 
					 | 
				
			||||||
*           or source files without problems. But only ONE file should hold the implementation.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*       #define RGESTURES_STANDALONE
 | 
					 | 
				
			||||||
*           If defined, the library can be used as standalone to process gesture events with
 | 
					 | 
				
			||||||
*           no external dependencies.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   CONTRIBUTORS:
 | 
					 | 
				
			||||||
*       Marc Palau:         Initial implementation (2014)
 | 
					 | 
				
			||||||
*       Albert Martos:      Complete redesign and testing (2015)
 | 
					 | 
				
			||||||
*       Ian Eito:           Complete redesign and testing (2015)
 | 
					 | 
				
			||||||
*       Ramon Santamaria:   Supervision, review, update and maintenance
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   LICENSE: zlib/libpng
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   This software is provided "as-is", without any express or implied warranty. In no event
 | 
					 | 
				
			||||||
*   will the authors be held liable for any damages arising from the use of this software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Permission is granted to anyone to use this software for any purpose, including commercial
 | 
					 | 
				
			||||||
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     1. The origin of this software must not be misrepresented; you must not claim that you
 | 
					 | 
				
			||||||
*     wrote the original software. If you use this software in a product, an acknowledgment
 | 
					 | 
				
			||||||
*     in the product documentation would be appreciated but is not required.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
 | 
					 | 
				
			||||||
*     as being the original software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     3. This notice may not be removed or altered from any source distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
**********************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef RGESTURES_H
 | 
					 | 
				
			||||||
#define RGESTURES_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef RL_PI
 | 
					 | 
				
			||||||
    #define RL_PI 3.14159265358979323846
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Defines and Macros
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#ifndef RL_MAX_TOUCH_POINTS
 | 
					 | 
				
			||||||
    #define RL_MAX_TOUCH_POINTS        8        // Maximum number of touch points supported
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Types and Structures Definition
 | 
					 | 
				
			||||||
// NOTE: Below types are required for standalone usage
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Boolean type
 | 
					 | 
				
			||||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
 | 
					 | 
				
			||||||
    #include <stdbool.h>
 | 
					 | 
				
			||||||
#elif !defined(__cplusplus) && !defined(bool) && !defined(RL_BOOL_TYPE)
 | 
					 | 
				
			||||||
    typedef enum bool { false = 0, true = !false } bool;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "config.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(RL_VECTOR2_TYPE)
 | 
					 | 
				
			||||||
// Vector2 type
 | 
					 | 
				
			||||||
typedef struct Vector2 {
 | 
					 | 
				
			||||||
    float x;
 | 
					 | 
				
			||||||
    float y;
 | 
					 | 
				
			||||||
} Vector2;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RGESTURES_STANDALONE)
 | 
					 | 
				
			||||||
// Gestures type
 | 
					 | 
				
			||||||
// NOTE: It could be used as flags to enable only some gestures
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    GESTURE_NONE        = 0,
 | 
					 | 
				
			||||||
    GESTURE_TAP         = 1,
 | 
					 | 
				
			||||||
    GESTURE_DOUBLETAP   = 2,
 | 
					 | 
				
			||||||
    GESTURE_HOLD        = 4,
 | 
					 | 
				
			||||||
    GESTURE_DRAG        = 8,
 | 
					 | 
				
			||||||
    GESTURE_SWIPE_RIGHT = 16,
 | 
					 | 
				
			||||||
    GESTURE_SWIPE_LEFT  = 32,
 | 
					 | 
				
			||||||
    GESTURE_SWIPE_UP    = 64,
 | 
					 | 
				
			||||||
    GESTURE_SWIPE_DOWN  = 128,
 | 
					 | 
				
			||||||
    GESTURE_PINCH_IN    = 256,
 | 
					 | 
				
			||||||
    GESTURE_PINCH_OUT   = 512
 | 
					 | 
				
			||||||
} Gesture;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    TOUCH_ACTION_UP = 0,
 | 
					 | 
				
			||||||
    TOUCH_ACTION_DOWN,
 | 
					 | 
				
			||||||
    TOUCH_ACTION_MOVE,
 | 
					 | 
				
			||||||
    TOUCH_ACTION_CANCEL
 | 
					 | 
				
			||||||
} TouchAction;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Gesture event
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    int touchAction;
 | 
					 | 
				
			||||||
    int pointCount;
 | 
					 | 
				
			||||||
    int pointId[RL_MAX_TOUCH_POINTS];
 | 
					 | 
				
			||||||
    Vector2 position[RL_MAX_TOUCH_POINTS];
 | 
					 | 
				
			||||||
} GestureEvent;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Global Variables Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module Functions Declaration
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_EXTERN_C_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void process_gesture_event(GestureEvent event);           // Process gesture event and translate it into gestures
 | 
					 | 
				
			||||||
void update_gestures(void);                              // Update gestures detected (must be called every frame)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RGESTURES_STANDALONE)
 | 
					 | 
				
			||||||
void set_gestures_enabled(unsigned int flags);            // Enable a set of gestures using flags
 | 
					 | 
				
			||||||
bool is_gesture_detected(int gesture);                    // Check if a gesture have been detected
 | 
					 | 
				
			||||||
int get_gesture_detected(void);                           // Get latest detected gesture
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
float get_gesture_hold_duration(void);                     // Get gesture hold time in seconds
 | 
					 | 
				
			||||||
Vector2 get_gesture_drag_vector(void);                     // Get gesture drag vector
 | 
					 | 
				
			||||||
float get_gesture_drag_angle(void);                        // Get gesture drag angle
 | 
					 | 
				
			||||||
Vector2 get_gesture_pinch_vector(void);                    // Get gesture pinch delta
 | 
					 | 
				
			||||||
float get_gesture_pinch_angle(void);                       // Get gesture pinch angle
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_EXTERN_C_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // RGESTURES_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/***********************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   RGESTURES IMPLEMENTATION
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RGESTURES_IMPLEMENTATION)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RGESTURES_STANDALONE)
 | 
					 | 
				
			||||||
#if defined(_WIN32)
 | 
					 | 
				
			||||||
    #if defined(__cplusplus)
 | 
					 | 
				
			||||||
    extern "C" {        // Prevents name mangling of functions
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
    // Functions required to query time on Windows
 | 
					 | 
				
			||||||
    int __stdcall query_performance_counter(unsigned long long int *lpPerformanceCount);
 | 
					 | 
				
			||||||
    int __stdcall query_performance_frequency(unsigned long long int *lpFrequency);
 | 
					 | 
				
			||||||
    #if defined(__cplusplus)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
#elif defined(__linux__)
 | 
					 | 
				
			||||||
    #if _POSIX_C_SOURCE < 199309L
 | 
					 | 
				
			||||||
        #undef _POSIX_C_SOURCE
 | 
					 | 
				
			||||||
        #define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext.
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
    #include <sys/time.h>               // Required for: timespec
 | 
					 | 
				
			||||||
    #include <time.h>                   // Required for: clock_gettime()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #include <math.h>                   // Required for: sqrtf(), atan2f()
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#if defined(__APPLE__)                  // macOS also defines __MACH__
 | 
					 | 
				
			||||||
    #include <mach/clock.h>             // Required for: clock_get_time()
 | 
					 | 
				
			||||||
    #include <mach/mach.h>              // Required for: mach_timespec_t
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Defines and Macros
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#define RL_FORCE_TO_SWIPE      0.2f        // Swipe force, measured in normalized screen units/time
 | 
					 | 
				
			||||||
#define RL_MINIMUM_DRAG        0.015f      // Drag minimum force, measured in normalized screen units (0.0f to 1.0f)
 | 
					 | 
				
			||||||
#define RL_DRAG_TIMEOUT        0.3f        // Drag minimum time for web, measured in seconds
 | 
					 | 
				
			||||||
#define RL_MINIMUM_PINCH       0.005f      // Pinch minimum force, measured in normalized screen units (0.0f to 1.0f)
 | 
					 | 
				
			||||||
#define RL_TAP_TIMEOUT         0.3f        // Tap minimum time, measured in seconds
 | 
					 | 
				
			||||||
#define RL_PINCH_TIMEOUT       0.3f        // Pinch minimum time, measured in seconds
 | 
					 | 
				
			||||||
#define RL_DOUBLETAP_RANGE     0.03f       // DoubleTap range, measured in normalized screen units (0.0f to 1.0f)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_BEGIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Types and Structures Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Gestures module state context [136 bytes]
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    unsigned int current;               // Current detected gesture
 | 
					 | 
				
			||||||
    unsigned int enabledFlags;          // Enabled gestures flags
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        int firstId;                    // Touch id for first touch point
 | 
					 | 
				
			||||||
        int pointCount;                 // Touch points counter
 | 
					 | 
				
			||||||
        double eventTime;               // Time stamp when an event happened
 | 
					 | 
				
			||||||
        Vector2 upPosition;             // Touch up position
 | 
					 | 
				
			||||||
        Vector2 downPositionA;          // First touch down position
 | 
					 | 
				
			||||||
        Vector2 downPositionB;          // Second touch down position
 | 
					 | 
				
			||||||
        Vector2 downDragPosition;       // Touch drag position
 | 
					 | 
				
			||||||
        Vector2 moveDownPositionA;      // First touch down position on move
 | 
					 | 
				
			||||||
        Vector2 moveDownPositionB;      // Second touch down position on move
 | 
					 | 
				
			||||||
        Vector2 previousPositionA;      // Previous position A to compare for pinch gestures
 | 
					 | 
				
			||||||
        Vector2 previousPositionB;      // Previous position B to compare for pinch gestures
 | 
					 | 
				
			||||||
        int tapCounter;                 // TAP counter (one tap implies TOUCH_ACTION_DOWN and TOUCH_ACTION_UP actions)
 | 
					 | 
				
			||||||
    } Touch;
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        bool resetRequired;             // HOLD reset to get first touch point again
 | 
					 | 
				
			||||||
        double timeDuration;            // HOLD duration in seconds
 | 
					 | 
				
			||||||
    } Hold;
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        Vector2 vector;                 // DRAG vector (between initial and current position)
 | 
					 | 
				
			||||||
        float angle;                    // DRAG angle (relative to x-axis)
 | 
					 | 
				
			||||||
        float distance;                 // DRAG distance (from initial touch point to final) (normalized [0..1])
 | 
					 | 
				
			||||||
        float intensity;                // DRAG intensity, how far why did the DRAG (pixels per frame)
 | 
					 | 
				
			||||||
    } Drag;
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        double startTime;               // SWIPE start time to calculate drag intensity
 | 
					 | 
				
			||||||
    } Swipe;
 | 
					 | 
				
			||||||
    struct {
 | 
					 | 
				
			||||||
        Vector2 vector;                 // PINCH vector (between first and second touch points)
 | 
					 | 
				
			||||||
        float angle;                    // PINCH angle (relative to x-axis)
 | 
					 | 
				
			||||||
        float distance;                 // PINCH displacement distance (normalized [0..1])
 | 
					 | 
				
			||||||
    } Pinch;
 | 
					 | 
				
			||||||
} GesturesData;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Global Variables Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
static GesturesData GESTURES = {
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
    (unsigned int)-1,
 | 
					 | 
				
			||||||
    GESTURE_NONE,
 | 
					 | 
				
			||||||
    0b0000001111111111
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    .Touch.firstId = -1,
 | 
					 | 
				
			||||||
    .current = GESTURE_NONE,        // No current gesture detected
 | 
					 | 
				
			||||||
    .enabledFlags = 0b0000001111111111  // All gestures supported by default
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module specific Functions Declaration
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
static float rg_vector2_angle(Vector2 initialPosition, Vector2 finalPosition);
 | 
					 | 
				
			||||||
static float rg_vector2_distance(Vector2 v1, Vector2 v2);
 | 
					 | 
				
			||||||
static double rg_get_current_time(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module Functions Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Enable only desired gestures to be detected
 | 
					 | 
				
			||||||
void set_gestures_enabled(unsigned int flags)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    GESTURES.enabledFlags = flags;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Check if a gesture have been detected
 | 
					 | 
				
			||||||
bool is_gesture_detected(unsigned int gesture)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if ((GESTURES.enabledFlags & GESTURES.current) == gesture) return true;
 | 
					 | 
				
			||||||
    else return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Process gesture event and translate it into gestures
 | 
					 | 
				
			||||||
void process_gesture_event(GestureEvent event)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Reset required variables
 | 
					 | 
				
			||||||
    GESTURES.Touch.pointCount = event.pointCount;      // Required on update_gestures()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (GESTURES.Touch.pointCount == 1)     // One touch point
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (event.touchAction == TOUCH_ACTION_DOWN)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GESTURES.Touch.tapCounter++;    // Tap counter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Detect GESTURE_DOUBLE_TAP
 | 
					 | 
				
			||||||
            if ((GESTURES.current == GESTURE_NONE) && (GESTURES.Touch.tapCounter >= 2) && ((rg_get_current_time() - GESTURES.Touch.eventTime) < RL_TAP_TIMEOUT) && (rg_vector2_distance(GESTURES.Touch.downPositionA, event.position[0]) < RL_DOUBLETAP_RANGE))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                GESTURES.current = GESTURE_DOUBLETAP;
 | 
					 | 
				
			||||||
                GESTURES.Touch.tapCounter = 0;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else    // Detect GESTURE_TAP
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                GESTURES.Touch.tapCounter = 1;
 | 
					 | 
				
			||||||
                GESTURES.current = GESTURE_TAP;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Touch.downPositionA = event.position[0];
 | 
					 | 
				
			||||||
            GESTURES.Touch.downDragPosition = event.position[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Touch.upPosition = GESTURES.Touch.downPositionA;
 | 
					 | 
				
			||||||
            GESTURES.Touch.eventTime = rg_get_current_time();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Swipe.startTime = rg_get_current_time();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #ifdef __cplusplus
 | 
					 | 
				
			||||||
            GESTURES.Drag.vector = Vector2{ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #else
 | 
					 | 
				
			||||||
            GESTURES.Drag.vector = (Vector2){ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #endif
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (event.touchAction == TOUCH_ACTION_UP)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // A swipe can happen while the current gesture is drag, but (specially for web) also hold, so set upPosition for both cases
 | 
					 | 
				
			||||||
            if (GESTURES.current == GESTURE_DRAG || GESTURES.current == GESTURE_HOLD) GESTURES.Touch.upPosition = event.position[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // NOTE: GESTURES.Drag.intensity dependent on the resolution of the screen
 | 
					 | 
				
			||||||
            GESTURES.Drag.distance = rg_vector2_distance(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
 | 
					 | 
				
			||||||
            GESTURES.Drag.intensity = GESTURES.Drag.distance/(float)((rg_get_current_time() - GESTURES.Swipe.startTime));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Detect GESTURE_SWIPE
 | 
					 | 
				
			||||||
            if ((GESTURES.Drag.intensity > RL_FORCE_TO_SWIPE) && (GESTURES.current != GESTURE_DRAG))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // NOTE: Angle should be inverted in Y
 | 
					 | 
				
			||||||
                GESTURES.Drag.angle = 360.0f - rg_vector2_angle(GESTURES.Touch.downPositionA, GESTURES.Touch.upPosition);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if ((GESTURES.Drag.angle < 30) || (GESTURES.Drag.angle > 330)) GESTURES.current = GESTURE_SWIPE_RIGHT;          // Right
 | 
					 | 
				
			||||||
                else if ((GESTURES.Drag.angle >= 30) && (GESTURES.Drag.angle <= 150)) GESTURES.current = GESTURE_SWIPE_UP;      // Up
 | 
					 | 
				
			||||||
                else if ((GESTURES.Drag.angle > 150) && (GESTURES.Drag.angle < 210)) GESTURES.current = GESTURE_SWIPE_LEFT;     // Left
 | 
					 | 
				
			||||||
                else if ((GESTURES.Drag.angle >= 210) && (GESTURES.Drag.angle <= 330)) GESTURES.current = GESTURE_SWIPE_DOWN;   // Down
 | 
					 | 
				
			||||||
                else GESTURES.current = GESTURE_NONE;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                GESTURES.Drag.distance = 0.0f;
 | 
					 | 
				
			||||||
                GESTURES.Drag.intensity = 0.0f;
 | 
					 | 
				
			||||||
                GESTURES.Drag.angle = 0.0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                GESTURES.current = GESTURE_NONE;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        #if __cplusplus
 | 
					 | 
				
			||||||
            GESTURES.Touch.downDragPosition = Vector2{ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #else
 | 
					 | 
				
			||||||
            GESTURES.Touch.downDragPosition = (Vector2){ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #endif
 | 
					 | 
				
			||||||
            GESTURES.Touch.pointCount = 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (event.touchAction == TOUCH_ACTION_MOVE)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GESTURES.Touch.moveDownPositionA = event.position[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (GESTURES.current == GESTURE_HOLD)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (GESTURES.Hold.resetRequired) GESTURES.Touch.downPositionA = event.position[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                GESTURES.Hold.resetRequired = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Detect GESTURE_DRAG
 | 
					 | 
				
			||||||
                if ((rg_get_current_time() - GESTURES.Touch.eventTime) > RL_DRAG_TIMEOUT)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    GESTURES.Touch.eventTime = rg_get_current_time();
 | 
					 | 
				
			||||||
                    GESTURES.current = GESTURE_DRAG;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Drag.vector.x = GESTURES.Touch.moveDownPositionA.x - GESTURES.Touch.downDragPosition.x;
 | 
					 | 
				
			||||||
            GESTURES.Drag.vector.y = GESTURES.Touch.moveDownPositionA.y - GESTURES.Touch.downDragPosition.y;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (GESTURES.Touch.pointCount == 2)    // Two touch points
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (event.touchAction == TOUCH_ACTION_DOWN)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GESTURES.Touch.downPositionA = event.position[0];
 | 
					 | 
				
			||||||
            GESTURES.Touch.downPositionB = event.position[1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Touch.previousPositionA = GESTURES.Touch.downPositionA;
 | 
					 | 
				
			||||||
            GESTURES.Touch.previousPositionB = GESTURES.Touch.downPositionB;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //GESTURES.Pinch.distance = rg_vector2_distance(GESTURES.Touch.downPositionA, GESTURES.Touch.downPositionB);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector.x = GESTURES.Touch.downPositionB.x - GESTURES.Touch.downPositionA.x;
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector.y = GESTURES.Touch.downPositionB.y - GESTURES.Touch.downPositionA.y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.current = GESTURE_HOLD;
 | 
					 | 
				
			||||||
            GESTURES.Hold.timeDuration = rg_get_current_time();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (event.touchAction == TOUCH_ACTION_MOVE)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GESTURES.Pinch.distance = rg_vector2_distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Touch.moveDownPositionA = event.position[0];
 | 
					 | 
				
			||||||
            GESTURES.Touch.moveDownPositionB = event.position[1];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector.x = GESTURES.Touch.moveDownPositionB.x - GESTURES.Touch.moveDownPositionA.x;
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector.y = GESTURES.Touch.moveDownPositionB.y - GESTURES.Touch.moveDownPositionA.y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ((rg_vector2_distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.moveDownPositionA) >= RL_MINIMUM_PINCH) || (rg_vector2_distance(GESTURES.Touch.previousPositionB, GESTURES.Touch.moveDownPositionB) >= RL_MINIMUM_PINCH))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if ( rg_vector2_distance(GESTURES.Touch.previousPositionA, GESTURES.Touch.previousPositionB) > rg_vector2_distance(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB) ) GESTURES.current = GESTURE_PINCH_IN;
 | 
					 | 
				
			||||||
                else GESTURES.current = GESTURE_PINCH_OUT;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                GESTURES.current = GESTURE_HOLD;
 | 
					 | 
				
			||||||
                GESTURES.Hold.timeDuration = rg_get_current_time();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // NOTE: Angle should be inverted in Y
 | 
					 | 
				
			||||||
            GESTURES.Pinch.angle = 360.0f - rg_vector2_angle(GESTURES.Touch.moveDownPositionA, GESTURES.Touch.moveDownPositionB);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (event.touchAction == TOUCH_ACTION_UP)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            GESTURES.Pinch.distance = 0.0f;
 | 
					 | 
				
			||||||
            GESTURES.Pinch.angle = 0.0f;
 | 
					 | 
				
			||||||
        #if __cplusplus
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector = Vector2{ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #else
 | 
					 | 
				
			||||||
            GESTURES.Pinch.vector = (Vector2){ 0.0f, 0.0f };
 | 
					 | 
				
			||||||
        #endif
 | 
					 | 
				
			||||||
            GESTURES.Touch.pointCount = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            GESTURES.current = GESTURE_NONE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else if (GESTURES.Touch.pointCount > 2)     // More than two touch points
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        // TODO: Process gesture events for more than two points
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Update gestures detected (must be called every frame)
 | 
					 | 
				
			||||||
void update_gestures(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: Gestures are processed through system callbacks on touch events
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Detect GESTURE_HOLD
 | 
					 | 
				
			||||||
    if (((GESTURES.current == GESTURE_TAP) || (GESTURES.current == GESTURE_DOUBLETAP)) && (GESTURES.Touch.pointCount < 2))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        GESTURES.current = GESTURE_HOLD;
 | 
					 | 
				
			||||||
        GESTURES.Hold.timeDuration = rg_get_current_time();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Detect GESTURE_NONE
 | 
					 | 
				
			||||||
    if ((GESTURES.current == GESTURE_SWIPE_RIGHT) || (GESTURES.current == GESTURE_SWIPE_UP) || (GESTURES.current == GESTURE_SWIPE_LEFT) || (GESTURES.current == GESTURE_SWIPE_DOWN))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        GESTURES.current = GESTURE_NONE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get latest detected gesture
 | 
					 | 
				
			||||||
int get_gesture_detected(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // Get current gesture only if enabled
 | 
					 | 
				
			||||||
    return (GESTURES.enabledFlags & GESTURES.current);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Hold time measured in ms
 | 
					 | 
				
			||||||
float get_gesture_hold_duration(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: time is calculated on current gesture HOLD
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    double time = 0.0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (GESTURES.current == GESTURE_HOLD) time = rg_get_current_time() - GESTURES.Hold.timeDuration;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return (float)time;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get drag vector (between initial touch point to current)
 | 
					 | 
				
			||||||
Vector2 get_gesture_drag_vector(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: drag vector is calculated on one touch points TOUCH_ACTION_MOVE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return GESTURES.Drag.vector;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get drag angle
 | 
					 | 
				
			||||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise
 | 
					 | 
				
			||||||
float get_gesture_drag_angle(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: drag angle is calculated on one touch points TOUCH_ACTION_UP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return GESTURES.Drag.angle;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get distance between two pinch points
 | 
					 | 
				
			||||||
Vector2 get_gesture_pinch_vector(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: Pinch distance is calculated on two touch points TOUCH_ACTION_MOVE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return GESTURES.Pinch.vector;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Get angle between two pinch points
 | 
					 | 
				
			||||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclockwise
 | 
					 | 
				
			||||||
float get_gesture_pinch_angle(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // NOTE: pinch angle is calculated on two touch points TOUCH_ACTION_MOVE
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return GESTURES.Pinch.angle;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module specific Functions Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Get angle from two-points vector with X-axis
 | 
					 | 
				
			||||||
static float rg_vector2_angle(Vector2 v1, Vector2 v2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float angle = atan2f(v2.y - v1.y, v2.x - v1.x)*(180.0f/RL_PI);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (angle < 0) angle += 360.0f;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return angle;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Calculate distance between two Vector2
 | 
					 | 
				
			||||||
static float rg_vector2_distance(Vector2 v1, Vector2 v2)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    float result;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    float dx = v2.x - v1.x;
 | 
					 | 
				
			||||||
    float dy = v2.y - v1.y;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    result = (float)sqrt(dx*dx + dy*dy);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Time measure returned are seconds
 | 
					 | 
				
			||||||
static double rg_get_current_time(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    double time = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if !defined(RGESTURES_STANDALONE)
 | 
					 | 
				
			||||||
    time = get_time();
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#if defined(_WIN32)
 | 
					 | 
				
			||||||
    unsigned long long int clockFrequency, currentTime;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    query_performance_frequency(&clockFrequency);     // BE CAREFUL: Costly operation!
 | 
					 | 
				
			||||||
    query_performance_counter(¤tTime);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    time = (double)currentTime/clockFrequency;  // Time in seconds
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__linux__)
 | 
					 | 
				
			||||||
    // NOTE: Only for Linux-based systems
 | 
					 | 
				
			||||||
    struct timespec now;
 | 
					 | 
				
			||||||
    clock_gettime(CLOCK_MONOTONIC, &now);
 | 
					 | 
				
			||||||
    unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec;     // Time in nanoseconds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    time = ((double)nowTime*1e-9);     // Time in seconds
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__APPLE__)
 | 
					 | 
				
			||||||
    //#define CLOCK_REALTIME  CALENDAR_CLOCK    // returns UTC time since 1970-01-01
 | 
					 | 
				
			||||||
    //#define CLOCK_MONOTONIC SYSTEM_CLOCK      // returns the time since boot time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    clock_serv_t cclock;
 | 
					 | 
				
			||||||
    mach_timespec_t now;
 | 
					 | 
				
			||||||
    host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // NOTE: OS X does not have clock_gettime(), using clock_get_time()
 | 
					 | 
				
			||||||
    clock_get_time(cclock, &now);
 | 
					 | 
				
			||||||
    mach_port_deallocate(mach_task_self(), cclock);
 | 
					 | 
				
			||||||
    unsigned long long int nowTime = (unsigned long long int)now.tv_sec*1000000000LLU + (unsigned long long int)now.tv_nsec;     // Time in nanoseconds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    time = ((double)nowTime*1e-9);     // Time in seconds
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return time;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RL_NS_END
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // RGESTURES_IMPLEMENTATION
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,81 +0,0 @@
 | 
				
			|||||||
/**********************************************************************************************
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   raylib.utils - Some common utility functions
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   LICENSE: zlib/libpng
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   This software is provided "as-is", without any express or implied warranty. In no event
 | 
					 | 
				
			||||||
*   will the authors be held liable for any damages arising from the use of this software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*   Permission is granted to anyone to use this software for any purpose, including commercial
 | 
					 | 
				
			||||||
*   applications, and to alter it and redistribute it freely, subject to the following restrictions:
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     1. The origin of this software must not be misrepresented; you must not claim that you
 | 
					 | 
				
			||||||
*     wrote the original software. If you use this software in a product, an acknowledgment
 | 
					 | 
				
			||||||
*     in the product documentation would be appreciated but is not required.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     2. Altered source versions must be plainly marked as such, and must not be misrepresented
 | 
					 | 
				
			||||||
*     as being the original software.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
*     3. This notice may not be removed or altered from any source distribution.
 | 
					 | 
				
			||||||
*
 | 
					 | 
				
			||||||
**********************************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef UTILS_H
 | 
					 | 
				
			||||||
#define UTILS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(PLATFORM_ANDROID)
 | 
					 | 
				
			||||||
    #include <stdio.h>                      // Required for: FILE
 | 
					 | 
				
			||||||
    #include <android/asset_manager.h>      // Required for: AAssetManager
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(RL_SUPPORT_TRACELOG)
 | 
					 | 
				
			||||||
    #define RL_TRACELOG(level, ...) RL_NS(trace_log)(level, __VA_ARGS__)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #if defined(RL_SUPPORT_TRACELOG_DEBUG)
 | 
					 | 
				
			||||||
        #define TRACELOGD(...) RL_NS(trace_log)(LOG_DEBUG, __VA_ARGS__)
 | 
					 | 
				
			||||||
    #else
 | 
					 | 
				
			||||||
        #define TRACELOGD(...) (void)0
 | 
					 | 
				
			||||||
    #endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
    #define RL_TRACELOG(level, ...) (void)0
 | 
					 | 
				
			||||||
    #define TRACELOGD(...) (void)0
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Some basic Defines
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#if defined(PLATFORM_ANDROID)
 | 
					 | 
				
			||||||
    #define fopen(name, mode) android_fopen(name, mode)
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Types and Structures Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
//...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Global Variables Definition
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Nop...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
// Module Functions Declaration
 | 
					 | 
				
			||||||
//----------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
#if defined(__cplusplus)
 | 
					 | 
				
			||||||
extern "C" {            // Prevents name mangling of functions
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(PLATFORM_ANDROID)
 | 
					 | 
				
			||||||
void init_asset_manager(AAssetManager *manager, const char *dataPath);   // Initialize asset manager from android app
 | 
					 | 
				
			||||||
FILE *android_fopen(const char *fileName, const char *mode);           // Replacement for fopen() -> Read-only!
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if defined(__cplusplus)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // UTILS_H
 | 
					 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							@@ -1,8 +0,0 @@
 | 
				
			|||||||
#include "raudio.c"
 | 
					 | 
				
			||||||
#include "rcore.c"
 | 
					 | 
				
			||||||
#include "rglfw.c"
 | 
					 | 
				
			||||||
#include "rmodels.c"
 | 
					 | 
				
			||||||
#include "rshapes.c"
 | 
					 | 
				
			||||||
#include "rtext.c"
 | 
					 | 
				
			||||||
#include "rtextures.c"
 | 
					 | 
				
			||||||
#include "rutils.c"
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,242 +0,0 @@
 | 
				
			|||||||
// rlgl.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word RL_NOT_REFACTORED, RL_REFACTORED_CPP
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace rl_,
 | 
					 | 
				
			||||||
namespace rl,
 | 
					 | 
				
			||||||
namespace rlgl,
 | 
					 | 
				
			||||||
not word  rl
 | 
					 | 
				
			||||||
not word  rlgl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace RL_LOG_,         LOG_
 | 
					 | 
				
			||||||
namespace RL_PIXELFORMAT_, PIXELFORMAT_
 | 
					 | 
				
			||||||
namespace RL_TEXTURE_,     TEXTURE_
 | 
					 | 
				
			||||||
namespace RL_SHADER_,      SHADER_
 | 
					 | 
				
			||||||
namespace RL_BLEND_,       BLEND_
 | 
					 | 
				
			||||||
namespace RL_ATTACHMENT_,  ATTACHMENT_
 | 
					 | 
				
			||||||
namespace RL_CULL_,        CULL_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
not include rlgl.h
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word TRACELOG, RL_TRACELOG
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word RLGL, GLOBAL_DATA
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word Vector2,             Vector2
 | 
					 | 
				
			||||||
word Vector3,             Vector3
 | 
					 | 
				
			||||||
word Vector4,             Vector4
 | 
					 | 
				
			||||||
word Quaternion,          Quaternion
 | 
					 | 
				
			||||||
word Matrix,              Matrix
 | 
					 | 
				
			||||||
word Color,               Color
 | 
					 | 
				
			||||||
word Rectangle,           Rectangle
 | 
					 | 
				
			||||||
word Image,               Image
 | 
					 | 
				
			||||||
word Texture,             Texture
 | 
					 | 
				
			||||||
word Texture2D,           Texture2d
 | 
					 | 
				
			||||||
word TextureCubemap,      Texture_Cubemap
 | 
					 | 
				
			||||||
word RenderTexture,       Render_Texture
 | 
					 | 
				
			||||||
word RenderTexture2D,     Render_Texture2D
 | 
					 | 
				
			||||||
word NPatchInfo,          N_Patch_Info
 | 
					 | 
				
			||||||
word GlyphInfo,           Glyph_Info
 | 
					 | 
				
			||||||
word Font,                Font
 | 
					 | 
				
			||||||
word Camera3D,            Camera3D
 | 
					 | 
				
			||||||
word Camera,              Camera
 | 
					 | 
				
			||||||
word Camera2D,            Camera2D
 | 
					 | 
				
			||||||
word Mesh,                Mesh
 | 
					 | 
				
			||||||
word Shader,              Shader
 | 
					 | 
				
			||||||
word MaterialMap,         Material_Map
 | 
					 | 
				
			||||||
word Material,            Material
 | 
					 | 
				
			||||||
word Transform,           Transform
 | 
					 | 
				
			||||||
word BoneInfo,            Bone_Info
 | 
					 | 
				
			||||||
word Model,               Model
 | 
					 | 
				
			||||||
word ModelAnimation,      Model_Animation
 | 
					 | 
				
			||||||
word Ray,                 Ray
 | 
					 | 
				
			||||||
word RayCollision,        Ray_Collision
 | 
					 | 
				
			||||||
word BoundingBox,         Bounding_box
 | 
					 | 
				
			||||||
word Wave,                Wave
 | 
					 | 
				
			||||||
word rAudioBuffer,        Audio_Buffer
 | 
					 | 
				
			||||||
word rAudioProcessor,     Audio_Processor
 | 
					 | 
				
			||||||
word AudioStream,         Audio_Stream
 | 
					 | 
				
			||||||
word Sound,               Sound
 | 
					 | 
				
			||||||
word Music,               Music
 | 
					 | 
				
			||||||
word VrDeviceInfo,        VR_Device_Info
 | 
					 | 
				
			||||||
word VrStereoConfig,      VR_Stereo_Config
 | 
					 | 
				
			||||||
word FilePathList,        File_Path_List
 | 
					 | 
				
			||||||
word AutomationEvent,     Automation_Event
 | 
					 | 
				
			||||||
word AutomationEventList, Automation_Event_List
 | 
					 | 
				
			||||||
word Matrix,              Matrix
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word rlVertexBuffer,                 vertex_buffer
 | 
					 | 
				
			||||||
word rlDrawCall,                     draw_call
 | 
					 | 
				
			||||||
word rlRenderBatch,                  render_batch
 | 
					 | 
				
			||||||
word rlGlVersion,                    gl_version
 | 
					 | 
				
			||||||
word rlTraceLogLevel,                trace_log_level
 | 
					 | 
				
			||||||
word rlPixelFormat,                  pixel_format
 | 
					 | 
				
			||||||
word rlTextureFilter,                texture_filter
 | 
					 | 
				
			||||||
word rlShaderLocationIndex,          shader_location_index
 | 
					 | 
				
			||||||
word rlShaderUniformDataType,        shader_uniform_data_type
 | 
					 | 
				
			||||||
word rlShaderAttributeDataType,      shader_attribute_data_type
 | 
					 | 
				
			||||||
word rlBlendMode,                    blend_mode
 | 
					 | 
				
			||||||
word rlFramebufferAttachType,        framebuffer_attach_type
 | 
					 | 
				
			||||||
word rlFramebufferAttachTextureType, framebuffer_attach_texture_type
 | 
					 | 
				
			||||||
word rlCullMode,                     cull_mode
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word get_pixel_data_size, gpu_get_pixel_data_size
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
word rlMatrixMode,                       matrix_mode
 | 
					 | 
				
			||||||
word rlPushMatrix,                       push_matrix
 | 
					 | 
				
			||||||
word rlPopMatrix,                        pop_matrix
 | 
					 | 
				
			||||||
word rlLoadIdentity,                     load_identity
 | 
					 | 
				
			||||||
word rlTranslatef,                       translatef
 | 
					 | 
				
			||||||
word rlRotatef,                          rotatef
 | 
					 | 
				
			||||||
word rlScalef,                           scalef
 | 
					 | 
				
			||||||
word rlMultMatrixf,                      mult_matrixf
 | 
					 | 
				
			||||||
word rlFrustum,                          frustum
 | 
					 | 
				
			||||||
word rlOrtho,                            ortho
 | 
					 | 
				
			||||||
word rlViewport,                         viewport
 | 
					 | 
				
			||||||
word rlBegin,                            begin
 | 
					 | 
				
			||||||
word rlEnd,                              end
 | 
					 | 
				
			||||||
word rlVertex2i,                         vertex2i
 | 
					 | 
				
			||||||
word rlVertex2f,                         vertex2f
 | 
					 | 
				
			||||||
word rlVertex3f,                         vertex3f
 | 
					 | 
				
			||||||
word rlTexCoord2f,                       tex_coord2f
 | 
					 | 
				
			||||||
word rlNormal3f,                         normal3f
 | 
					 | 
				
			||||||
word rlColor4ub,                         color4ub
 | 
					 | 
				
			||||||
word rlColor3f,                          color3f
 | 
					 | 
				
			||||||
word rlColor4f,                          color4f
 | 
					 | 
				
			||||||
word rlEnableVertexArray,                enable_vertex_array
 | 
					 | 
				
			||||||
word rlDisableVertexArray,               disable_vertex_array
 | 
					 | 
				
			||||||
word rlEnableVertexBuffer,               enable_vertex_buffer
 | 
					 | 
				
			||||||
word rlDisableVertexBuffer,              disable_vertex_buffer
 | 
					 | 
				
			||||||
word rlEnableVertexBufferElement,        enable_vertex_buffer_element
 | 
					 | 
				
			||||||
word rlDisableVertexBufferElement,       disable_vertex_buffer_element
 | 
					 | 
				
			||||||
word rlEnableVertexAttribute,            enable_vertex_attribute
 | 
					 | 
				
			||||||
word rlDisableVertexAttribute,           disable_vertex_attribute
 | 
					 | 
				
			||||||
word rlEnableStatePointer,               enable_state_pointer
 | 
					 | 
				
			||||||
word rlDisableStatePointer,              disable_state_pointer
 | 
					 | 
				
			||||||
word rlActiveTextureSlot,                active_texture_slot
 | 
					 | 
				
			||||||
word rlEnableTexture,                    enable_texture
 | 
					 | 
				
			||||||
word rlDisableTexture,                   disable_texture
 | 
					 | 
				
			||||||
word rlEnableTextureCubemap,             enable_texture_cubemap
 | 
					 | 
				
			||||||
word rlDisableTextureCubemap,            disable_texture_cubemap
 | 
					 | 
				
			||||||
word rlTextureParameters,                texture_parameters
 | 
					 | 
				
			||||||
word rlCubemapParameters,                cubemap_parameters
 | 
					 | 
				
			||||||
word rlEnableShader,                     enable_shader
 | 
					 | 
				
			||||||
word rlDisableShader,                    disable_shader
 | 
					 | 
				
			||||||
word rlEnableFramebuffer,                enable_framebuffer
 | 
					 | 
				
			||||||
word rlDisableFramebuffer,               disable_framebuffer
 | 
					 | 
				
			||||||
word rlActiveDrawBuffers,                active_draw_buffers
 | 
					 | 
				
			||||||
word rlBlitFramebuffer,                  blit_framebuffer
 | 
					 | 
				
			||||||
word rlEnableColorBlend,                 enable_color_blend
 | 
					 | 
				
			||||||
word rlDisableColorBlend,                disable_color_blend
 | 
					 | 
				
			||||||
word rlEnableDepthTest,                  enable_depth_test
 | 
					 | 
				
			||||||
word rlDisableDepthTest,                 disable_depth_test
 | 
					 | 
				
			||||||
word rlEnableDepthMask,                  enable_depth_mask
 | 
					 | 
				
			||||||
word rlDisableDepthMask,                 disable_depth_mask
 | 
					 | 
				
			||||||
word rlEnableBackfaceCulling,            enable_backface_culling
 | 
					 | 
				
			||||||
word rlDisableBackfaceCulling,           disable_backface_culling
 | 
					 | 
				
			||||||
word rlSetCullFace,                      set_cull_face
 | 
					 | 
				
			||||||
word rlEnableScissorTest,                enable_scissor_test
 | 
					 | 
				
			||||||
word rlDisableScissorTest,               disable_scissor_test
 | 
					 | 
				
			||||||
word rlScissor,                          scissor
 | 
					 | 
				
			||||||
word rlEnableWireMode,                   enable_wire_mode
 | 
					 | 
				
			||||||
word rlEnablePointMode,                  enable_point_mode
 | 
					 | 
				
			||||||
word rlDisableWireMode,                  disable_wire_mode
 | 
					 | 
				
			||||||
word rlSetLineWidth,                     set_line_width
 | 
					 | 
				
			||||||
word rlGetLineWidth,                     get_line_width
 | 
					 | 
				
			||||||
word rlEnableSmoothLines,                enable_smooth_lines
 | 
					 | 
				
			||||||
word rlDisableSmoothLines,               disable_smooth_lines
 | 
					 | 
				
			||||||
word rlEnableStereoRender,               enable_stereo_render
 | 
					 | 
				
			||||||
word rlDisableStereoRender,              disable_stereo_render
 | 
					 | 
				
			||||||
word rlIsStereoRenderEnabled,            is_stereo_render_enabled
 | 
					 | 
				
			||||||
word rlClearColor,                       clear_color
 | 
					 | 
				
			||||||
word rlClearScreenBuffers,               clear_screen_buffers
 | 
					 | 
				
			||||||
word rlCheckErrors,                      check_errors
 | 
					 | 
				
			||||||
word rlSetBlendMode,                     set_blend_mode
 | 
					 | 
				
			||||||
word rlSetBlendFactors,                  set_blend_factors
 | 
					 | 
				
			||||||
word rlSetBlendFactorsSeparate,          set_blend_factors_separate
 | 
					 | 
				
			||||||
word rlglInit,                           init
 | 
					 | 
				
			||||||
word rlglClose,                          close
 | 
					 | 
				
			||||||
word rlLoadExtensions,                   load_extensions
 | 
					 | 
				
			||||||
word rlGetVersion,                       get_version
 | 
					 | 
				
			||||||
word rlSetFramebufferWidth,              set_framebuffer_width
 | 
					 | 
				
			||||||
word rlGetFramebufferWidth,              get_framebuffer_width
 | 
					 | 
				
			||||||
word rlSetFramebufferHeight,             set_framebuffer_height
 | 
					 | 
				
			||||||
word rlGetFramebufferHeight,             get_framebuffer_height
 | 
					 | 
				
			||||||
word rlGetTextureIdDefault,              get_texture_id_default
 | 
					 | 
				
			||||||
word rlGetShaderIdDefault,               get_shader_id_default
 | 
					 | 
				
			||||||
word rlLoadRenderBatch,                  load_render_batch
 | 
					 | 
				
			||||||
word rlUnloadRenderBatch,                unload_render_batch
 | 
					 | 
				
			||||||
word rlDrawRenderBatch,                  draw_render_batch
 | 
					 | 
				
			||||||
word rlSetRenderBatchActive,             set_render_batch_active
 | 
					 | 
				
			||||||
word rlDrawRenderBatchActive,            draw_render_batch_active
 | 
					 | 
				
			||||||
word rlCheckRenderBatchLimit,            check_render_batch_limit
 | 
					 | 
				
			||||||
word rlSetTexture,                       set_texture
 | 
					 | 
				
			||||||
word rlLoadVertexArray,                  load_vertex_array
 | 
					 | 
				
			||||||
word rlLoadVertexBuffer,                 load_vertex_buffer
 | 
					 | 
				
			||||||
word rlLoadVertexBufferElement,          load_vertex_buffer_element
 | 
					 | 
				
			||||||
word rlUpdateVertexBuffer,               update_vertex_buffer
 | 
					 | 
				
			||||||
word rlUpdateVertexBufferElements,       update_vertex_buffer_elements
 | 
					 | 
				
			||||||
word rlUnloadVertexArray,                unload_vertex_array
 | 
					 | 
				
			||||||
word rlUnloadVertexBuffer,               unload_vertex_buffer
 | 
					 | 
				
			||||||
word rlSetVertexAttribute,               set_vertex_attribute
 | 
					 | 
				
			||||||
word rlSetVertexAttributeDivisor,        set_vertex_attribute_divisor
 | 
					 | 
				
			||||||
word rlSetVertexAttributeDefault,        set_vertex_attribute_default
 | 
					 | 
				
			||||||
word rlDrawVertexArray,                  draw_vertex_array
 | 
					 | 
				
			||||||
word rlDrawVertexArrayElements,          draw_vertex_array_elements
 | 
					 | 
				
			||||||
word rlDrawVertexArrayInstanced,         draw_vertex_array_instanced
 | 
					 | 
				
			||||||
word rlDrawVertexArrayElementsInstanced, draw_vertex_array_elements_instanced
 | 
					 | 
				
			||||||
word rlLoadTexture,                      load_texture
 | 
					 | 
				
			||||||
word rlLoadTextureDepth,                 load_texture_depth
 | 
					 | 
				
			||||||
word rlLoadTextureCubemap,               load_texture_cubemap
 | 
					 | 
				
			||||||
word rlUpdateTexture,                    update_texture
 | 
					 | 
				
			||||||
word rlGetGlTextureFormats,              get_gl_texture_formats
 | 
					 | 
				
			||||||
word rlUnloadTexture,                    unload_texture
 | 
					 | 
				
			||||||
word rlGenTextureMipmaps,                gen_texture_mipmaps
 | 
					 | 
				
			||||||
word rlLoadFramebuffer,                  load_framebuffer
 | 
					 | 
				
			||||||
word rlFramebufferAttach,                framebuffer_attach
 | 
					 | 
				
			||||||
word rlFramebufferComplete,              framebuffer_complete
 | 
					 | 
				
			||||||
word rlUnloadFramebuffer,                unload_framebuffer
 | 
					 | 
				
			||||||
word rlLoadShaderCode,                   load_shader_code
 | 
					 | 
				
			||||||
word rlCompileShader,                    compile_shader
 | 
					 | 
				
			||||||
word rlLoadShaderProgram,                load_shader_program
 | 
					 | 
				
			||||||
word rlUnloadShaderProgram,              unload_shader_program
 | 
					 | 
				
			||||||
word rlGetLocationUniform,               get_location_uniform
 | 
					 | 
				
			||||||
word rlGetLocationAttrib,                get_location_attrib
 | 
					 | 
				
			||||||
word rlSetUniform,                       set_uniform
 | 
					 | 
				
			||||||
word rlSetUniformMatrix,                 set_uniform_matrix
 | 
					 | 
				
			||||||
word rlSetUniformSampler,                set_uniform_sampler
 | 
					 | 
				
			||||||
word rlSetShader,                        set_shader
 | 
					 | 
				
			||||||
word rlLoadComputeShaderProgram,         load_compute_shader_program
 | 
					 | 
				
			||||||
word rlComputeShaderDispatch,            compute_shader_dispatch
 | 
					 | 
				
			||||||
word rlLoadShaderBuffer,                 load_shader_buffer
 | 
					 | 
				
			||||||
word rlUnloadShaderBuffer,               unload_shader_buffer
 | 
					 | 
				
			||||||
word rlUpdateShaderBuffer,               update_shader_buffer
 | 
					 | 
				
			||||||
word rlBindShaderBuffer,                 bind_shader_buffer
 | 
					 | 
				
			||||||
word rlReadShaderBuffer,                 read_shader_buffer
 | 
					 | 
				
			||||||
word rlCopyShaderBuffer,                 copy_shader_buffer
 | 
					 | 
				
			||||||
word rlGetShaderBufferSize,              get_shader_buffer_size
 | 
					 | 
				
			||||||
word rlBindImageTexture,                 bind_image_texture
 | 
					 | 
				
			||||||
word rlGetMatrixModelview,               get_matrix_modelview
 | 
					 | 
				
			||||||
word rlGetMatrixProjection,              get_matrix_projection
 | 
					 | 
				
			||||||
word rlGetMatrixTransform,               get_matrix_transform
 | 
					 | 
				
			||||||
word rlGetMatrixProjectionStereo,        get_matrix_projection_stereo
 | 
					 | 
				
			||||||
word rlGetMatrixViewOffsetStereo,        get_matrix_view_offset_stereo
 | 
					 | 
				
			||||||
word rlSetMatrixProjection,              set_matrix_projection
 | 
					 | 
				
			||||||
word rlSetMatrixModelview,               set_matrix_modelview
 | 
					 | 
				
			||||||
word rlSetMatrixProjectionStereo,        set_matrix_projection_stereo
 | 
					 | 
				
			||||||
word rlSetMatrixViewOffsetStereo,        set_matrix_view_offset_stereo
 | 
					 | 
				
			||||||
word rlLoadDrawCube,                     load_draw_cube
 | 
					 | 
				
			||||||
word rlLoadDrawQuad,                     load_draw_quad
 | 
					 | 
				
			||||||
word rlLoadShaderDefault,                load_shader_default
 | 
					 | 
				
			||||||
word rlUnloadShaderDefault,              unload_shader_default
 | 
					 | 
				
			||||||
word rlGetPixelDataSize,                 internal_get_pixel_data_size
 | 
					 | 
				
			||||||
word rlMatrixIdentity,                   internal_matrix_identity
 | 
					 | 
				
			||||||
word rlMatrixMultiply,                   internal_matrix_multiply
 | 
					 | 
				
			||||||
word rlCheckRenderBatchLimit,            check_render_batch_limit
 | 
					 | 
				
			||||||
word rlLoadShaderDefault,                load_shader_default
 | 
					 | 
				
			||||||
word rlSetMatrixProjection,              set_matrix_projection
 | 
					 | 
				
			||||||
word rlUnloadFramebuffer,                unload_framebuffer
 | 
					 | 
				
			||||||
word rlReadScreenPixels,                 read_screen_pixels
 | 
					 | 
				
			||||||
word rlReadTexturePixels,                read_texture_pixels
 | 
					 | 
				
			||||||
word rlGetShaderLocsDefault,             get_shader_locs_default
 | 
					 | 
				
			||||||
word rlGetPixelFormatName,               get_pixel_format_name
 | 
					 | 
				
			||||||
@@ -1,322 +0,0 @@
 | 
				
			|||||||
#define GEN_DEFINE_LIBRARY_CODE_CONSTANTS
 | 
					 | 
				
			||||||
#define GEN_BENCHMARK
 | 
					 | 
				
			||||||
#define GEN_ENFORCE_STRONG_CODE_TYPES
 | 
					 | 
				
			||||||
// #define GEN_IMPLEMENTATION
 | 
					 | 
				
			||||||
#include "gen.cpp"
 | 
					 | 
				
			||||||
#include "gen.builder.cpp"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constexpr char const* path_config_h    = "config.h";
 | 
					 | 
				
			||||||
constexpr char const* path_raylib_h    = "raylib.h";
 | 
					 | 
				
			||||||
constexpr char const* path_raymath_h   = "raymath.h";
 | 
					 | 
				
			||||||
constexpr char const* path_rcamera_h   = "rcamera.h";
 | 
					 | 
				
			||||||
constexpr char const* path_rcore_h     = "rcore.h";
 | 
					 | 
				
			||||||
constexpr char const* path_rgestures_h = "rgestures.h";
 | 
					 | 
				
			||||||
constexpr char const* path_rgl_h       = "rgl.h";
 | 
					 | 
				
			||||||
constexpr char const* path_rtext_h     = "rtext.h";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constexpr char const* path_rcore_desktop_c = "rcore_desktop.c";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
constexpr char const* path_raudio_c    = "raudio.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rcore_c     = "rcore.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rglfw_c     = "rglfw.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rmodels_c   = "rmodels.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rtext_c     = "rtext.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rtextures_c = "rtextures.c";
 | 
					 | 
				
			||||||
constexpr char const* path_rutils_c    = "rutils.c";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using namespace gen;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
StringCached upper_snake_to_mixed_snake(StringCached str)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1));
 | 
					 | 
				
			||||||
    scratch.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool capitalizeNext = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (s32 index = 0; index < str.length(); ++index)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        char c = str[index];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (c == '_')
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            scratch.append(c);
 | 
					 | 
				
			||||||
            capitalizeNext = true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (capitalizeNext)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (c >= 'a' && c <= 'z')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                scratch.append(c - 32); // Convert to uppercase
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                scratch.append(c);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            capitalizeNext = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (c >= 'A' && c <= 'Z')
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                scratch.append(c + 32); // Convert to lowercase
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                scratch.append(c);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    StringCached result = get_cached_string(scratch);
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
StringCached pascal_to_lower_snake(StringCached str)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    local_persist String scratch = String::make_reserve(GlobalAllocator, kilobytes(1));
 | 
					 | 
				
			||||||
    scratch.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (s32 index = 0; index < str.length(); ++index)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        char c = str[index];
 | 
					 | 
				
			||||||
        char next = (index + 1 < str.length()) ? str[index + 1] : '\0'; // Ensure we don't go out of bounds
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Whitelist check for "2D" and "3D"
 | 
					 | 
				
			||||||
        if ((c == '2' || c == '3' | c == '4') && (next == 'D' || next == 'd'))
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            if (index > 0) // If it's not the start of the string, append an underscore
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                char* prev = str.Data + index - 1;
 | 
					 | 
				
			||||||
                if (*prev != '_') // Avoid double underscores
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    scratch.append('_');
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            scratch.append(c);
 | 
					 | 
				
			||||||
            scratch.append('d'); // Convert to lowercase
 | 
					 | 
				
			||||||
            index++; // Skip the next character since we've already processed it
 | 
					 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (c >= 'A' && c <= 'Z')
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            char* prev = (index > 0) ? str.Data + index - 1 : nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ((index > 0 && prev && *prev >= 'a' && *prev <= 'z') || 
 | 
					 | 
				
			||||||
                (prev && char_is_digit(*prev) && (next >= 'A' && next <= 'Z')))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                scratch.append('_');
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            scratch.append(c + 32);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else if (char_is_digit(c) && (next >= 'A' && next <= 'Z')) // Check for a number followed by an uppercase letter
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            scratch.append(c);
 | 
					 | 
				
			||||||
            scratch.append('_');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            scratch.append(c);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    StringCached result = get_cached_string(scratch);
 | 
					 | 
				
			||||||
    return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_define( CodeDefine& code )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local_persist String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( str_compare( elem->Name, txt("RL"), 2 ) == 0 || str_compare( elem->Name, txt("RAYLIB"), 6 ) == 0 )
 | 
					 | 
				
			||||||
		continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name_scratch.append_fmt( "%RL_%S", elem->Name );
 | 
					 | 
				
			||||||
	elem->Name = get_cached_string( name_scratch );
 | 
					 | 
				
			||||||
	name_scratch.clear();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_enum( CodeEnum& code )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	for ( Code elem : code->Body )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Untyped )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			elem->Content = upper_snake_to_mixed_snake( elem->Content );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_typename( CodeType& type )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	local_persist CodeType t_unsigned_char      = parse_type( code(unsigned char) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_unsigned_char_ptr  = parse_type( code(unsigned char*) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_unsigned_short_ptr	= parse_type( code(unsigned short*) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_int                = parse_type( code(int) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_int_ptr 		    = parse_type( code(int*) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_unsigned_int       = parse_type( code(unsigned int) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_float 	            = parse_type( code(float) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_float_ptr          = parse_type( code(float*) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	local_persist CodeType t_f32_ptr = parse_type( code(f32*) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_u8_ptr  = parse_type( code(u8*) );
 | 
					 | 
				
			||||||
	local_persist CodeType t_s32_ptr = parse_type( code(s32*) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	String type_str = type.to_string();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_unsigned_char.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_u8.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_unsigned_char_ptr.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_u8_ptr.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_unsigned_short_ptr.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_u8_ptr.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_int.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_s32.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_int_ptr.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_s32_ptr.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_unsigned_int.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_u32.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_float.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_f32.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if ( str_compare( type_str, t_float_ptr.to_string() ) == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		type.ast = t_f32_ptr.ast;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_fn( CodeFn& fn )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	StringCached original_name = fn->Name;
 | 
					 | 
				
			||||||
	fn->Name = pascal_to_lower_snake( fn->Name );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log_fmt( "%S", "Proc ID: %S -> %S", original_name, fn->Name );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ( CodeParam param : fn->Params )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		refactor_typename( param->ValueType );
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_struct( CodeStruct& code )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	for ( Code field : code->Body )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if ( field->Type == ECode::Variable )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			CodeVar var = field.cast<CodeVar>();
 | 
					 | 
				
			||||||
			refactor_typename( var->ValueType );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void refactor_file( char const* path )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	FileContents contents = file_read_contents( GlobalAllocator, true, path );
 | 
					 | 
				
			||||||
	CodeBody     code     = parse_global_body( { contents.size, rcast(char const*, contents.data) } );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	local_perist String name_scratch = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// CodeBody includes
 | 
					 | 
				
			||||||
	// CodeBody nspace_body = def_body( ECode::Namespace );
 | 
					 | 
				
			||||||
	CodeBody new_code = def_body( ECode::Global_Body );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	for ( Code elem : code )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Preprocess_Define )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			refactor_define( elem.cast<CodeDefine>() );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Enum )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			refactor_enum( elem.cast<CodeEnum>() );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Typedef )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			CodeTypedef td = elem.cast<CodeTypedef>();
 | 
					 | 
				
			||||||
			if ( td->UnderlyingType->Type == ECode::Enum )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				CodeEnum code = td->UnderlyingType.cast<CodeEnum>();
 | 
					 | 
				
			||||||
				refactor_enum( code );
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if ( td->UnderlyingType->Type == ECode::Struct )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				CodeStruct code = td->UnderlyingType.cast<CodeStruct>();
 | 
					 | 
				
			||||||
				refactor_struct( code );
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Struct )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			refactor_struct( elem.cast<CodeStruct>() );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			refactor_fn( elem.cast<CodeFn>() );
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if ( elem->Type == ECode::Extern_Linkage )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			CodeBody body = elem.cast<CodeExtern>()->Body;
 | 
					 | 
				
			||||||
			for ( Code elem : body )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if ( elem->Type == ECode::Function || elem->Type == ECode::Function_Fwd )
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					refactor_fn( elem.cast<CodeFn>() );
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			Code nspace = def_namespace( txt("raylib"), def_namespace_body( args(elem) ) );
 | 
					 | 
				
			||||||
			elem = nspace;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		new_code.append( elem );
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Builder builder = Builder::open( path );
 | 
					 | 
				
			||||||
	builder.print( new_code );
 | 
					 | 
				
			||||||
	builder.write();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	name_scratch.clear();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int gen_main()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	gen::init();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	refactor_file( path_config_h );
 | 
					 | 
				
			||||||
	refactor_file( path_raylib_h );
 | 
					 | 
				
			||||||
	refactor_file( path_rcamera_h );
 | 
					 | 
				
			||||||
	refactor_file( path_raymath_h );
 | 
					 | 
				
			||||||
	refactor_file( path_rcore_h );
 | 
					 | 
				
			||||||
	refactor_file( path_rgl_h );
 | 
					 | 
				
			||||||
	refactor_file( path_rtext_h );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	refactor_file( path_rcore_desktop_c );
 | 
					 | 
				
			||||||
	refactor_file( path_raudio_c );
 | 
					 | 
				
			||||||
	refactor_file( path_rcore_c );
 | 
					 | 
				
			||||||
	refactor_file( path_rglfw_c );
 | 
					 | 
				
			||||||
	refactor_file( path_rmodels_c );
 | 
					 | 
				
			||||||
	refactor_file( path_rtext_c );
 | 
					 | 
				
			||||||
	refactor_file( path_rutils_c );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
# Vis AST
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
AST visualizer for gencpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This is a early start to creating frontend tooling for c/c++ using gencpp as a core component.  
 | 
					 | 
				
			||||||
I'll be exploring creating an AST explorer for this library with raylib as the graphical & general platform vendor for dependencies that go beyond the scope of gencpp.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
For now I'll have its build script in this file, however it will heavily rely on gencpp's helper scripts.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Whatever sort of UX tooling I setup for this will be reused for the other tools I'll be creating for gencpp.
 | 
					 | 
				
			||||||
@@ -1,256 +0,0 @@
 | 
				
			|||||||
Clear-Host
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_root     = git rev-parse --show-toplevel
 | 
					 | 
				
			||||||
$path_scripts  = Join-Path $path_root 'scripts'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$target_arch        = Join-Path $path_scripts 'helpers/target_arch.psm1'
 | 
					 | 
				
			||||||
$devshell           = Join-Path $path_scripts 'helpers/devshell.ps1'
 | 
					 | 
				
			||||||
$format_cpp	        = Join-Path $path_scripts 'helpers/format_cpp.psm1'
 | 
					 | 
				
			||||||
$incremental_checks = Join-Path $path_scripts 'helpers/incremental_checks.ps1'
 | 
					 | 
				
			||||||
$vendor_toolchain   = Join-Path $path_scripts 'helpers/vendor_toolchain.ps1'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_project  = Join-Path $path_root     'project'
 | 
					 | 
				
			||||||
$path_aux      = Join-Path $path_project  'auxillary'
 | 
					 | 
				
			||||||
$path_vis_root = Join-Path $path_aux      'vis_ast'
 | 
					 | 
				
			||||||
$path_binaries = Join-Path $path_vis_root 'binaries'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$path_deps = Join-Path $path_vis_root 'dependencies'
 | 
					 | 
				
			||||||
$path_temp = Join-Path $path_deps     'temp'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Import-Module $target_arch
 | 
					 | 
				
			||||||
Import-Module $format_cpp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#region Arguments
 | 
					 | 
				
			||||||
$vendor           = $null
 | 
					 | 
				
			||||||
$optimize         = $null
 | 
					 | 
				
			||||||
$debug 	          = $null
 | 
					 | 
				
			||||||
$analysis	      = $false
 | 
					 | 
				
			||||||
$dev              = $false
 | 
					 | 
				
			||||||
$verbose          = $null
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[array] $vendors = @( "clang", "msvc" )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This is a really lazy way of parsing the args, could use actual params down the line...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( $args ) { $args | ForEach-Object {
 | 
					 | 
				
			||||||
switch ($_){
 | 
					 | 
				
			||||||
 { $_ -in $vendors }   { $vendor    = $_; break }
 | 
					 | 
				
			||||||
 "optimize"            { $optimize  = $true }
 | 
					 | 
				
			||||||
 "debug"               { $debug     = $true }
 | 
					 | 
				
			||||||
 "analysis"            { $analysis  = $true }
 | 
					 | 
				
			||||||
 "dev"                 { $dev       = $true }
 | 
					 | 
				
			||||||
 "verbose"             { $verbose   = $true }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
}}
 | 
					 | 
				
			||||||
#endregion Argument
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Load up toolchain configuraion
 | 
					 | 
				
			||||||
. $vendor_toolchain
 | 
					 | 
				
			||||||
. $incremental_checks
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Clear out the current content first
 | 
					 | 
				
			||||||
if ( test-path $path_temp) {
 | 
					 | 
				
			||||||
	remove-item $path_temp -Recurse
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
New-Item -ItemType Directory -Path $path_temp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if ( -not (Test-Path $path_binaries) ) {
 | 
					 | 
				
			||||||
	New-Item -ItemType Directory -Path $path_binaries
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function setup-raylib {
 | 
					 | 
				
			||||||
	$path_raylib     = join-path $path_deps   'raylib'
 | 
					 | 
				
			||||||
	$path_raylib_inc = join-path $path_raylib 'include'
 | 
					 | 
				
			||||||
	$path_raylib_lib = join-path $path_raylib 'lib'
 | 
					 | 
				
			||||||
	if ( test-path $path_raylib_inc ) {
 | 
					 | 
				
			||||||
		remove-item $path_raylib_inc -recurse
 | 
					 | 
				
			||||||
		remove-item $path_raylib_lib -recurse
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	new-item -path $path_raylib_inc -ItemType Directory
 | 
					 | 
				
			||||||
	new-item -path $path_raylib_lib -ItemType Directory
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	$url_raylib_zip  = 'https://github.com/Ed94/raylib_refactored/archive/refs/heads/refactor-support.zip'
 | 
					 | 
				
			||||||
	$path_raylib_zip = join-path $path_temp 'raylib.zip'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	$path_raylib_master      = join-path $path_temp          'raylib_refactored-refactor-support'
 | 
					 | 
				
			||||||
	$path_raylib_src         = join-path $path_raylib_master 'src'
 | 
					 | 
				
			||||||
	$path_raylib_platforms   = join-path $path_raylib_src    'platforms'
 | 
					 | 
				
			||||||
	$path_raylib_glfw_inc    = join-path $path_raylib_src    'external/glfw/include'
 | 
					 | 
				
			||||||
	$path_raylib_gputex      = join-path $path_raylib_src    'external/rl_gputex.h'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( test-path $path_raylib_master ) {
 | 
					 | 
				
			||||||
		remove-item $path_raylib_master -Recurse
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	invoke-webrequest -uri $url_raylib_zip   -outfile $path_raylib_zip
 | 
					 | 
				
			||||||
	expand-archive    -path $path_raylib_zip -destinationpath $path_temp
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	write-host "Building raylib with $vendor"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	$path_build = Join-Path $path_raylib 'build'
 | 
					 | 
				
			||||||
	if ( (Test-Path $path_build) -eq $false ) {
 | 
					 | 
				
			||||||
		New-Item $path_build -ItemType Directory
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	$raylib_headers  = Get-ChildItem -Path $path_raylib_src -Filter '*.h' -File
 | 
					 | 
				
			||||||
	$raylib_modules  = get-childitem -path $path_raylib_src -filter '*.c' -file
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Refactor with refactor.exe
 | 
					 | 
				
			||||||
	if ( $true ) {
 | 
					 | 
				
			||||||
		$path_refactor      = join-path $path_raylib 'raylib_cpp.refactor'
 | 
					 | 
				
			||||||
		$path_refactor_rlgl = join-path $path_raylib 'raylib_cpp_gl.refactor'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$files = @()
 | 
					 | 
				
			||||||
		foreach ( $header in $raylib_headers ) {
 | 
					 | 
				
			||||||
			$file_name = split-path $header -leaf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if ( -not $file_name.Equals('rlgl.h' ) ) {
 | 
					 | 
				
			||||||
				$files += "$header"
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		foreach ( $module in $raylib_modules ) {
 | 
					 | 
				
			||||||
			$files += "$module"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$files += "$path_raylib_gputex"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$platform_modules = @()
 | 
					 | 
				
			||||||
		foreach ( $module in (get-childitem -path $path_raylib_platforms -filter '*.c' -file) ) {
 | 
					 | 
				
			||||||
			$platform_modules += "$module"
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$path_rlgl = join-path $path_raylib_src 'rlgl.h'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Push-Location $path_raylib_src
 | 
					 | 
				
			||||||
			write-host "Beginning refactor...`n"
 | 
					 | 
				
			||||||
			$refactors = @(@())
 | 
					 | 
				
			||||||
			$refactorParams = @(
 | 
					 | 
				
			||||||
				# "-debug",
 | 
					 | 
				
			||||||
				"-num=$($files.Count)"
 | 
					 | 
				
			||||||
				"-src=$($files)",
 | 
					 | 
				
			||||||
				"-spec=$($path_refactor)"
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			& refactor $refactorParams
 | 
					 | 
				
			||||||
			Write-Host "`nRefactoring complete`n`n"
 | 
					 | 
				
			||||||
		Pop-Location
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Push-Location $path_raylib_platforms
 | 
					 | 
				
			||||||
		write-host "Beginning refactor...`n"
 | 
					 | 
				
			||||||
			$refactors = @(@())
 | 
					 | 
				
			||||||
			$refactorParams = @(
 | 
					 | 
				
			||||||
				# "-debug",
 | 
					 | 
				
			||||||
				"-num=$($platform_modules.Count)"
 | 
					 | 
				
			||||||
				"-src=$($platform_modules)",
 | 
					 | 
				
			||||||
				"-spec=$($path_refactor)"
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			& refactor $refactorParams
 | 
					 | 
				
			||||||
			Write-Host "`nRefactoring complete`n`n"
 | 
					 | 
				
			||||||
		Pop-Location
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Push-Location $path_raylib_src
 | 
					 | 
				
			||||||
			$gl_modules = @( "$path_rlgl", "$path_raylib_gputex" )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			write-host "Beginning refactor just for rlgl.h...`n"
 | 
					 | 
				
			||||||
			$refactors = @(@())
 | 
					 | 
				
			||||||
			$refactorParams = @(
 | 
					 | 
				
			||||||
				# "-debug",
 | 
					 | 
				
			||||||
				"-num=$($gl_modules.Count)"
 | 
					 | 
				
			||||||
				"-src=$($gl_modules)",
 | 
					 | 
				
			||||||
				"-spec=$($path_refactor_rlgl)"
 | 
					 | 
				
			||||||
			)
 | 
					 | 
				
			||||||
			& refactor $refactorParams
 | 
					 | 
				
			||||||
			Write-Host "`nRefactoring complete`n`n"
 | 
					 | 
				
			||||||
		Pop-Location
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Refactor raylib with gencpp
 | 
					 | 
				
			||||||
	if ( $false ) {
 | 
					 | 
				
			||||||
	# if ( $false ) {
 | 
					 | 
				
			||||||
		$path_gencpp = join-path $path_root 'project/gen'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$includes = @(
 | 
					 | 
				
			||||||
			$path_gencpp
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$compiler_args = @(
 | 
					 | 
				
			||||||
			($flag_define + 'GEN_TIME')
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$linker_args = @(
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$unit       = join-path $path_raylib 'raylib_refactor.cpp'
 | 
					 | 
				
			||||||
		$executable = join-path $path_build  'raylib_refactor.exe'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
					 | 
				
			||||||
		Push-Location $path_raylib_src
 | 
					 | 
				
			||||||
			if ( Test-Path( $executable ) ) {
 | 
					 | 
				
			||||||
				Measure-Command { & $executable
 | 
					 | 
				
			||||||
						| ForEach-Object {
 | 
					 | 
				
			||||||
							write-host `t $_ -ForegroundColor Green
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		Pop-Location
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		push-location $path_scripts
 | 
					 | 
				
			||||||
		# Time to format
 | 
					 | 
				
			||||||
		$fmt_includes = @()
 | 
					 | 
				
			||||||
		foreach ( $header in $raylib_headers ) {
 | 
					 | 
				
			||||||
			$fmt_includes +=  split-path $header -leaf
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		foreach ( $module in $raylib_modules ) {
 | 
					 | 
				
			||||||
			$fmt_includes +=  split-path $module -leaf
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		format-cpp $path_raylib_src $fmt_includes $null
 | 
					 | 
				
			||||||
		pop-location
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Build raylib
 | 
					 | 
				
			||||||
	if ( $true ) {
 | 
					 | 
				
			||||||
		# Microsoft
 | 
					 | 
				
			||||||
		$lib_gdi32   = 'Gdi32.lib'
 | 
					 | 
				
			||||||
		$lib_shell32 = 'Shell32.lib'
 | 
					 | 
				
			||||||
		$lib_xinput  = 'Xinput.lib'
 | 
					 | 
				
			||||||
		$lib_user32  = 'User32.lib'
 | 
					 | 
				
			||||||
		$lib_winmm   = 'Winmm.lib'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$includes = @(
 | 
					 | 
				
			||||||
			$path_raylib_src,
 | 
					 | 
				
			||||||
			$path_raylib_glfw_inc
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		foreach ($include in $includes) {
 | 
					 | 
				
			||||||
			write-host $include
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$compiler_args = @(
 | 
					 | 
				
			||||||
			($flag_define + 'PLATFORM_DESKTOP'),
 | 
					 | 
				
			||||||
			($flag_define + 'RL_BUILD_LIBTYPE_SHARED'),
 | 
					 | 
				
			||||||
			$flag_all_cpp
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
		$linker_args   = @(
 | 
					 | 
				
			||||||
			$flag_link_dll,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			# $lib_xinput,
 | 
					 | 
				
			||||||
			$lib_gdi32,
 | 
					 | 
				
			||||||
			$lib_shell32,
 | 
					 | 
				
			||||||
			$lib_user32,
 | 
					 | 
				
			||||||
			$lib_winmm
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		# $unit = join-path $path_raylib     'raylib.c'
 | 
					 | 
				
			||||||
		$dll  = join-path $path_raylib_lib 'raylib.dll'
 | 
					 | 
				
			||||||
		# $build_result = build-simple $path_build $includes $compiler_args $linker_args $unit $dll
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		$build_result = build $path_build $includes $compiler_args $linker_args $raylib_modules $dll
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Move headers to used include
 | 
					 | 
				
			||||||
	foreach ($header in $raylib_headers) {
 | 
					 | 
				
			||||||
		Copy-Item -Path $header -Destination (join-path $path_raylib_inc (split-path $header -Leaf))
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# Don't want to remove as it hampers debugging.
 | 
					 | 
				
			||||||
	# remove-item -path $path_temp -Recurse
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
setup-raylib
 | 
					 | 
				
			||||||
@@ -20,6 +20,44 @@ constexpr char const* generation_notice =
 | 
				
			|||||||
"// This file was generated automatially by gencpp's bootstrap.cpp "
 | 
					"// This file was generated automatially by gencpp's bootstrap.cpp "
 | 
				
			||||||
"(See: https://github.com/Ed94/gencpp)\n\n";
 | 
					"(See: https://github.com/Ed94/gencpp)\n\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdlib>   // for system()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void format_file( char const* path )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						String resolved_path = String::make(GlobalAllocator, to_str(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
 | 
				
			||||||
 | 
						style_arg.append("../scripts/.clang-format ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Need to execute clang format on the generated file to get it to match the original.
 | 
				
			||||||
 | 
						#define clang_format      "clang-format "
 | 
				
			||||||
 | 
						#define cf_format_inplace "-i "
 | 
				
			||||||
 | 
						#define cf_verbose        "-verbose "
 | 
				
			||||||
 | 
						String command = String::make( GlobalAllocator, clang_format );
 | 
				
			||||||
 | 
						command.append( cf_format_inplace );
 | 
				
			||||||
 | 
						command.append( cf_verbose );
 | 
				
			||||||
 | 
						command.append( style_arg );
 | 
				
			||||||
 | 
						command.append( resolved_path );
 | 
				
			||||||
 | 
							log_fmt("\tRunning clang-format on file:\n");
 | 
				
			||||||
 | 
							system( command );
 | 
				
			||||||
 | 
							log_fmt("\tclang-format finished reformatting.\n");
 | 
				
			||||||
 | 
						#undef cf_cmd
 | 
				
			||||||
 | 
						#undef cf_format_inplace
 | 
				
			||||||
 | 
						#undef cf_style
 | 
				
			||||||
 | 
						#undef cf_verbse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Code dump_to_scratch_and_retireve( Code code )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Builder ecode_file_temp = Builder::open("gen/scratch.hpp");
 | 
				
			||||||
 | 
						ecode_file_temp.print(code);
 | 
				
			||||||
 | 
						ecode_file_temp.write();
 | 
				
			||||||
 | 
						format_file("gen/scratch.hpp");
 | 
				
			||||||
 | 
						Code result = scan_file( "gen/scratch.hpp" );
 | 
				
			||||||
 | 
						remove("gen/scratch.hpp");
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gen_main()
 | 
					int gen_main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	gen::init();
 | 
						gen::init();
 | 
				
			||||||
@@ -29,7 +67,7 @@ int gen_main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	// gen_dep.hpp
 | 
						// gen_dep.hpp
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Code header_start = scan_file( "dependencies/header_start.hpp" );
 | 
							Code platform     = scan_file( "dependencies/platform.hpp" );
 | 
				
			||||||
		Code macros 	  = scan_file( "dependencies/macros.hpp" );
 | 
							Code macros 	  = scan_file( "dependencies/macros.hpp" );
 | 
				
			||||||
		Code basic_types  = scan_file( "dependencies/basic_types.hpp" );
 | 
							Code basic_types  = scan_file( "dependencies/basic_types.hpp" );
 | 
				
			||||||
		Code debug        = scan_file( "dependencies/debug.hpp" );
 | 
							Code debug        = scan_file( "dependencies/debug.hpp" );
 | 
				
			||||||
@@ -45,8 +83,8 @@ int gen_main()
 | 
				
			|||||||
		Builder
 | 
							Builder
 | 
				
			||||||
		header = Builder::open("gen/gen.dep.hpp");
 | 
							header = Builder::open("gen/gen.dep.hpp");
 | 
				
			||||||
		header.print_fmt( generation_notice );
 | 
							header.print_fmt( generation_notice );
 | 
				
			||||||
		header.print_fmt( "// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)\n\n" );
 | 
							header.print_fmt( "// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)\n" );
 | 
				
			||||||
		header.print( header_start );
 | 
							header.print( platform );
 | 
				
			||||||
		header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
							header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print( macros );
 | 
							header.print( macros );
 | 
				
			||||||
@@ -80,7 +118,7 @@ int gen_main()
 | 
				
			|||||||
		Builder
 | 
							Builder
 | 
				
			||||||
		src = Builder::open( "gen/gen.dep.cpp" );
 | 
							src = Builder::open( "gen/gen.dep.cpp" );
 | 
				
			||||||
		src.print_fmt( generation_notice );
 | 
							src.print_fmt( generation_notice );
 | 
				
			||||||
		src.print_fmt( "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n\n" );
 | 
							src.print_fmt( "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n" );
 | 
				
			||||||
		src.print( src_start );
 | 
							src.print( src_start );
 | 
				
			||||||
		src.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
							src.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -132,9 +170,13 @@ int gen_main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		header.print_fmt( "#pragma region Types\n" );
 | 
							header.print_fmt( "#pragma region Types\n" );
 | 
				
			||||||
		header.print( types );
 | 
							header.print( types );
 | 
				
			||||||
		header.print( ecode );
 | 
							header.print( fmt_newline);
 | 
				
			||||||
		header.print( eoperator );
 | 
							header.print( dump_to_scratch_and_retireve(ecode) );
 | 
				
			||||||
		header.print( especifier );
 | 
							header.print( fmt_newline);
 | 
				
			||||||
 | 
							header.print( dump_to_scratch_and_retireve(eoperator) );
 | 
				
			||||||
 | 
							header.print( fmt_newline);
 | 
				
			||||||
 | 
							header.print( dump_to_scratch_and_retireve(especifier) );
 | 
				
			||||||
 | 
							header.print( fmt_newline);
 | 
				
			||||||
		header.print_fmt( "#pragma endregion Types\n\n" );
 | 
							header.print_fmt( "#pragma endregion Types\n\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print_fmt( "#pragma region AST\n" );
 | 
							header.print_fmt( "#pragma region AST\n" );
 | 
				
			||||||
@@ -148,7 +190,8 @@ int gen_main()
 | 
				
			|||||||
		header.print_fmt( "\n#pragma region Inlines\n" );
 | 
							header.print_fmt( "\n#pragma region Inlines\n" );
 | 
				
			||||||
		header.print( inlines );
 | 
							header.print( inlines );
 | 
				
			||||||
		header.print( fmt_newline );
 | 
							header.print( fmt_newline );
 | 
				
			||||||
		header.print( ast_inlines );
 | 
							header.print( dump_to_scratch_and_retireve(ast_inlines) );
 | 
				
			||||||
 | 
							header.print( fmt_newline );
 | 
				
			||||||
		header.print_fmt( "#pragma endregion Inlines\n" );
 | 
							header.print_fmt( "#pragma endregion Inlines\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print( header_end );
 | 
							header.print( header_end );
 | 
				
			||||||
@@ -203,7 +246,7 @@ int gen_main()
 | 
				
			|||||||
		src.print_fmt( generation_notice );
 | 
							src.print_fmt( generation_notice );
 | 
				
			||||||
		src.print( push_ignores );
 | 
							src.print( push_ignores );
 | 
				
			||||||
		src.print( src_start );
 | 
							src.print( src_start );
 | 
				
			||||||
		src.print_fmt( "GEN_NS_BEGIN\n");
 | 
							src.print_fmt( "\nGEN_NS_BEGIN\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		src.print( static_data );
 | 
							src.print( static_data );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,7 +260,7 @@ int gen_main()
 | 
				
			|||||||
		src.print( interface );
 | 
							src.print( interface );
 | 
				
			||||||
		src.print( upfront );
 | 
							src.print( upfront );
 | 
				
			||||||
		src.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
							src.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
				
			||||||
		src.print( nspaced_etoktype );
 | 
							src.print( dump_to_scratch_and_retireve(nspaced_etoktype) );
 | 
				
			||||||
		src.print( lexer );
 | 
							src.print( lexer );
 | 
				
			||||||
		src.print( parser );
 | 
							src.print( parser );
 | 
				
			||||||
		src.print( parsing_interface );
 | 
							src.print( parsing_interface );
 | 
				
			||||||
@@ -278,7 +321,7 @@ int gen_main()
 | 
				
			|||||||
		header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
							header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
				
			||||||
		header.print( parsing );
 | 
							header.print( parsing );
 | 
				
			||||||
		header.print( scanner );
 | 
							header.print( scanner );
 | 
				
			||||||
		header.print_fmt( "GEN_NS_END\n" );
 | 
							header.print_fmt( "\nGEN_NS_END\n" );
 | 
				
			||||||
		header.write();
 | 
							header.write();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -293,7 +336,7 @@ int gen_main()
 | 
				
			|||||||
		src.print( def_include( txt("gen.scanner.hpp") ) );
 | 
							src.print( def_include( txt("gen.scanner.hpp") ) );
 | 
				
			||||||
		src.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
							src.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
				
			||||||
		src.print( parsing );
 | 
							src.print( parsing );
 | 
				
			||||||
		src.print( scanner );
 | 
							// src.print( scanner );
 | 
				
			||||||
		src.print_fmt( "GEN_NS_END\n" );
 | 
							src.print_fmt( "GEN_NS_END\n" );
 | 
				
			||||||
		src.write();
 | 
							src.write();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -339,13 +339,14 @@ struct AST
 | 
				
			|||||||
			};
 | 
								};
 | 
				
			||||||
			union {
 | 
								union {
 | 
				
			||||||
				AST*  ArrExpr;          // Typename
 | 
									AST*  ArrExpr;          // Typename
 | 
				
			||||||
				AST*  Body;             // Class, Constructr, Destructor, Enum, Friend, Function, Namespace, Struct, Union
 | 
									AST*  Body;             // Class, Constructor, Destructor, Enum, Friend, Function, Namespace, Struct, Union
 | 
				
			||||||
				AST*  Declaration;      // Friend, Template
 | 
									AST*  Declaration;      // Friend, Template
 | 
				
			||||||
				AST*  Value;            // Parameter, Variable
 | 
									AST*  Value;            // Parameter, Variable
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			union {
 | 
								union {
 | 
				
			||||||
				AST*  NextVar;          // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
 | 
									AST*  NextVar;          // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
 | 
				
			||||||
				AST*  SuffixSpecs;      // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
 | 
									AST*  SuffixSpecs;      // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
 | 
				
			||||||
 | 
									AST*  PostNameMacro;     // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		StringCached  Content;          // Attributes, Comment, Execution, Include
 | 
							StringCached  Content;          // Attributes, Comment, Execution, Include
 | 
				
			||||||
@@ -375,6 +376,7 @@ struct AST
 | 
				
			|||||||
		OperatorT     Op;
 | 
							OperatorT     Op;
 | 
				
			||||||
		AccessSpec    ParentAccess;
 | 
							AccessSpec    ParentAccess;
 | 
				
			||||||
		s32           NumEntries;
 | 
							s32           NumEntries;
 | 
				
			||||||
 | 
							s32           VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -407,6 +409,7 @@ struct AST_POD
 | 
				
			|||||||
			union {
 | 
								union {
 | 
				
			||||||
				AST*  NextVar;          // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
 | 
									AST*  NextVar;          // Variable; Possible way to handle comma separated variables declarations. ( , NextVar->Specs NextVar->Name NextVar->ArrExpr = NextVar->Value )
 | 
				
			||||||
				AST*  SuffixSpecs;      // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
 | 
									AST*  SuffixSpecs;      // Only used with typenames, to store the function suffix if typename is function signature. ( May not be needed )
 | 
				
			||||||
 | 
									AST*  PostNameMacro;    // Only used with parameters for specifically UE_REQUIRES (Thanks Unreal)
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		StringCached  Content;          // Attributes, Comment, Execution, Include
 | 
							StringCached  Content;          // Attributes, Comment, Execution, Include
 | 
				
			||||||
@@ -436,6 +439,7 @@ struct AST_POD
 | 
				
			|||||||
		OperatorT     Op;
 | 
							OperatorT     Op;
 | 
				
			||||||
		AccessSpec    ParentAccess;
 | 
							AccessSpec    ParentAccess;
 | 
				
			||||||
		s32           NumEntries;
 | 
							s32           NumEntries;
 | 
				
			||||||
 | 
							s32           VarConstructorInit; // Used by variables to know that initialization is using a constructor expression instead of an assignment expression.
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -211,7 +211,7 @@ struct AST_Expr
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -226,7 +226,7 @@ struct AST_Expr_Assign
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -241,7 +241,7 @@ struct AST_Expr_Alignof
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -256,7 +256,7 @@ struct AST_Expr_Binary
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -271,7 +271,7 @@ struct AST_Expr_CStyleCast
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -286,7 +286,7 @@ struct AST_Expr_FunctionalCast
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -301,7 +301,7 @@ struct AST_Expr_CppCast
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -316,7 +316,7 @@ struct AST_Expr_ProcCall
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -331,7 +331,7 @@ struct AST_Expr_Decltype
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -346,7 +346,7 @@ struct AST_Expr_Comma
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -361,7 +361,7 @@ struct AST_Expr_AMS
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -376,7 +376,7 @@ struct AST_Expr_Sizeof
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -391,7 +391,7 @@ struct AST_Expr_Subscript
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -406,7 +406,7 @@ struct AST_Expr_Ternary
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -421,7 +421,7 @@ struct AST_Expr_UnaryPrefix
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -436,7 +436,7 @@ struct AST_Expr_UnaryPostfix
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -451,7 +451,7 @@ struct AST_Expr_Element
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -644,7 +644,8 @@ struct AST_Param
 | 
				
			|||||||
			CodeType  ValueType;
 | 
								CodeType  ValueType;
 | 
				
			||||||
			Code      Macro;
 | 
								Code      Macro;
 | 
				
			||||||
			Code      Value;
 | 
								Code      Value;
 | 
				
			||||||
			char 	  _PAD_PROPERTIES_3_[ sizeof(AST*) ];
 | 
								Code     PostNameMacro; // Thanks Unreal
 | 
				
			||||||
 | 
								// char     _PAD_PROPERTIES_3_[sizeof( AST* )];
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	CodeParam         Last;
 | 
						CodeParam         Last;
 | 
				
			||||||
@@ -710,7 +711,7 @@ struct AST_Stmt
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -725,7 +726,7 @@ struct AST_Stmt_Break
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -740,7 +741,7 @@ struct AST_Stmt_Case
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -755,7 +756,7 @@ struct AST_Stmt_Continue
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -770,7 +771,7 @@ struct AST_Stmt_Decl
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -785,7 +786,7 @@ struct AST_Stmt_Do
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -800,7 +801,7 @@ struct AST_Stmt_Expr
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -815,7 +816,7 @@ struct AST_Stmt_Else
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -830,7 +831,7 @@ struct AST_Stmt_If
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -845,7 +846,7 @@ struct AST_Stmt_For
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -860,7 +861,7 @@ struct AST_Stmt_Goto
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -875,7 +876,7 @@ struct AST_Stmt_Label
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -890,7 +891,7 @@ struct AST_Stmt_Switch
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -905,7 +906,7 @@ struct AST_Stmt_While
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
							char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
 | 
				
			||||||
	}
 | 
						};
 | 
				
			||||||
	CodeExpr       Prev;
 | 
						CodeExpr       Prev;
 | 
				
			||||||
	CodeExpr       Next;
 | 
						CodeExpr       Next;
 | 
				
			||||||
	parser::Token* Tok;
 | 
						parser::Token* Tok;
 | 
				
			||||||
@@ -1115,7 +1116,7 @@ struct AST_Var
 | 
				
			|||||||
	StringCached           Name;
 | 
						StringCached           Name;
 | 
				
			||||||
	CodeT                  Type;
 | 
						CodeT                  Type;
 | 
				
			||||||
	ModuleFlag             ModuleFlags;
 | 
						ModuleFlag             ModuleFlags;
 | 
				
			||||||
	char 			       _PAD_UNUSED_[ sizeof(u32) ];
 | 
						s32                    VarConstructorInit;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
 | 
					static_assert( sizeof(AST_Var) == sizeof(AST), "ERROR: AST_Var is not the same size as AST");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -480,7 +480,7 @@ void CodeFn::to_string_def( String& result )
 | 
				
			|||||||
	if ( ast->Attributes )
 | 
						if ( ast->Attributes )
 | 
				
			||||||
		result.append_fmt( " %S ", ast->Attributes.to_string() );
 | 
							result.append_fmt( " %S ", ast->Attributes.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b32 prefix_specs = false;
 | 
						bool prefix_specs = false;
 | 
				
			||||||
	if ( ast->Specs )
 | 
						if ( ast->Specs )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( SpecifierT spec : ast->Specs )
 | 
							for ( SpecifierT spec : ast->Specs )
 | 
				
			||||||
@@ -764,7 +764,14 @@ void CodeOpCast::to_string_def( String& result )
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if ( ast->Specs )
 | 
						if ( ast->Specs )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// TODO : Add support for specifies before the operator keyword
 | 
							for ( SpecifierT spec : ast->Specs )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( ! ESpecifier::is_trailing( spec ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									StrC spec_str = ESpecifier::to_str( spec );
 | 
				
			||||||
 | 
									result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr );
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->Name && ast->Name.length() )
 | 
							if ( ast->Name && ast->Name.length() )
 | 
				
			||||||
			result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() );
 | 
								result.append_fmt( "%Soperator %S()", ast->Name, ast->ValueType.to_string() );
 | 
				
			||||||
@@ -794,7 +801,14 @@ void CodeOpCast::to_string_fwd( String& result )
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if ( ast->Specs )
 | 
						if ( ast->Specs )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// TODO : Add support for specifies before the operator keyword
 | 
							for ( SpecifierT spec : ast->Specs )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( ! ESpecifier::is_trailing( spec ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									StrC spec_str = ESpecifier::to_str( spec );
 | 
				
			||||||
 | 
									result.append_fmt( "%*s ", spec_str.Len, spec_str.Ptr );
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		result.append_fmt( "operator %S()", ast->ValueType.to_string() );
 | 
							result.append_fmt( "operator %S()", ast->ValueType.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -847,6 +861,11 @@ void CodeParam::to_string( String& result )
 | 
				
			|||||||
	else if ( ast->ValueType )
 | 
						else if ( ast->ValueType )
 | 
				
			||||||
		result.append_fmt( " %S", ast->ValueType.to_string() );
 | 
							result.append_fmt( " %S", ast->ValueType.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ast->PostNameMacro )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							result.append_fmt(" %S", ast->PostNameMacro.to_string() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ast->Value )
 | 
						if ( ast->Value )
 | 
				
			||||||
		result.append_fmt( " = %S", ast->Value.to_string() );
 | 
							result.append_fmt( " = %S", ast->Value.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1096,7 +1115,7 @@ String CodeType::to_string()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void CodeType::to_string( String& result )
 | 
					void CodeType::to_string( String& result )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	#if GEN_USE_NEW_TYPENAME_PARSING
 | 
						#if defined(GEN_USE_NEW_TYPENAME_PARSING)
 | 
				
			||||||
		if ( ast->ReturnType && ast->Params )
 | 
							if ( ast->ReturnType && ast->Params )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast->Attributes )
 | 
								if ( ast->Attributes )
 | 
				
			||||||
@@ -1253,7 +1272,7 @@ void CodeVar::to_string( String& result )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		result.append( ast->Name );
 | 
							result.append( ast->Name );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->ValueType && ast->ValueType->ArrExpr )
 | 
							if ( ast->ValueType->ArrExpr )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() );
 | 
								result.append_fmt( "[ %S ]", ast->ValueType->ArrExpr.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1266,12 +1285,20 @@ void CodeVar::to_string( String& result )
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->Value )
 | 
							if ( ast->Value )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
									result.append_fmt( "( %S ", ast->Value.to_string() );
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
				result.append_fmt( " = %S", ast->Value.to_string() );
 | 
									result.append_fmt( " = %S", ast->Value.to_string() );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Keep the chain going...
 | 
							// Keep the chain going...
 | 
				
			||||||
		if ( ast->NextVar )
 | 
							if ( ast->NextVar )
 | 
				
			||||||
			result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
								result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
								result.append( " )");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1304,11 +1331,19 @@ void CodeVar::to_string( String& result )
 | 
				
			|||||||
			result.append_fmt( " : %S", ast->BitfieldSize.to_string() );
 | 
								result.append_fmt( " : %S", ast->BitfieldSize.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->Value )
 | 
							if ( ast->Value )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
									result.append_fmt( "( %S ", ast->Value.to_string() );
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
				result.append_fmt( " = %S", ast->Value.to_string() );
 | 
									result.append_fmt( " = %S", ast->Value.to_string() );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->NextVar )
 | 
							if ( ast->NextVar )
 | 
				
			||||||
			result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
								result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
								result.append( " )");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( ast->InlineCmt )
 | 
							if ( ast->InlineCmt )
 | 
				
			||||||
			result.append_fmt(";  %S", ast->InlineCmt->Content);
 | 
								result.append_fmt(";  %S", ast->InlineCmt->Content);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
@@ -1336,11 +1371,19 @@ void CodeVar::to_string( String& result )
 | 
				
			|||||||
		result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name );
 | 
							result.append_fmt( "%S %S", ast->ValueType.to_string(), ast->Name );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ast->Value )
 | 
						if ( ast->Value )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
								result.append_fmt( "( %S ", ast->Value.to_string() );
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
			result.append_fmt( " = %S", ast->Value.to_string() );
 | 
								result.append_fmt( " = %S", ast->Value.to_string() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ast->NextVar )
 | 
						if ( ast->NextVar )
 | 
				
			||||||
		result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
							result.append_fmt( ", %S", ast->NextVar.to_string() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ast->VarConstructorInit )
 | 
				
			||||||
 | 
							result.append( " )");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result.append( ";" );
 | 
						result.append( ";" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ast->InlineCmt )
 | 
						if ( ast->InlineCmt )
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -72,7 +72,7 @@ namespace ECode
 | 
				
			|||||||
		NumTypes
 | 
							NumTypes
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StrC to_str( Type type )
 | 
						inline StrC to_str( Type type )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		local_persist StrC lookup[] {
 | 
							local_persist StrC lookup[] {
 | 
				
			||||||
			{ sizeof( "Invalid" ),             "Invalid"             },
 | 
								{ sizeof( "Invalid" ),             "Invalid"             },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,7 @@ namespace EOperator
 | 
				
			|||||||
		NumOps
 | 
							NumOps
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StrC to_str( Type op )
 | 
						inline StrC to_str( Type op )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		local_persist StrC lookup[] {
 | 
							local_persist StrC lookup[] {
 | 
				
			||||||
			{ sizeof( "INVALID" ),  "INVALID"  },
 | 
								{ sizeof( "INVALID" ),  "INVALID"  },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,12 +38,12 @@ namespace ESpecifier
 | 
				
			|||||||
		NumSpecifiers
 | 
							NumSpecifiers
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool is_trailing( Type specifier )
 | 
						inline bool is_trailing( Type specifier )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return specifier > Virtual;
 | 
							return specifier > Virtual;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	StrC to_str( Type type )
 | 
						inline StrC to_str( Type type )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		local_persist StrC lookup[] {
 | 
							local_persist StrC lookup[] {
 | 
				
			||||||
			{ sizeof( "INVALID" ),       "INVALID"       },
 | 
								{ sizeof( "INVALID" ),       "INVALID"       },
 | 
				
			||||||
@@ -76,7 +76,7 @@ namespace ESpecifier
 | 
				
			|||||||
		return lookup[type];
 | 
							return lookup[type];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Type to_type( StrC str )
 | 
						inline Type to_type( StrC str )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		local_persist u32 keymap[NumSpecifiers];
 | 
							local_persist u32 keymap[NumSpecifiers];
 | 
				
			||||||
		do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ )
 | 
							do_once_start for ( u32 index = 0; index < NumSpecifiers; index++ )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -113,7 +113,7 @@ namespace parser
 | 
				
			|||||||
			NumTokens
 | 
								NumTokens
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		StrC to_str( Type type )
 | 
							inline StrC to_str( Type type )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist StrC lookup[] {
 | 
								local_persist StrC lookup[] {
 | 
				
			||||||
				{ sizeof( "__invalid__" ),         "__invalid__"         },
 | 
									{ sizeof( "__invalid__" ),         "__invalid__"         },
 | 
				
			||||||
@@ -217,7 +217,7 @@ namespace parser
 | 
				
			|||||||
			return lookup[type];
 | 
								return lookup[type];
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Type to_type( StrC str )
 | 
							inline Type to_type( StrC str )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist u32 keymap[NumTokens];
 | 
								local_persist u32 keymap[NumTokens];
 | 
				
			||||||
			do_once_start for ( u32 index = 0; index < NumTokens; index++ )
 | 
								do_once_start for ( u32 index = 0; index < NumTokens; index++ )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,7 @@ constexpr s32 InitSize_DataArrays = 16;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// NOTE: This limits the maximum size of an allocation
 | 
					// NOTE: This limits the maximum size of an allocation
 | 
				
			||||||
// If you are generating a string larger than this, increase the size of the bucket here.
 | 
					// If you are generating a string larger than this, increase the size of the bucket here.
 | 
				
			||||||
constexpr uw  Global_BucketSize         = GEN_GLOBAL_BUCKET_SIZE;
 | 
					constexpr usize  Global_BucketSize         = GEN_GLOBAL_BUCKET_SIZE;
 | 
				
			||||||
constexpr s32 CodePool_NumBlocks        = GEN_CODEPOOL_NUM_BLOCKS;
 | 
					constexpr s32 CodePool_NumBlocks        = GEN_CODEPOOL_NUM_BLOCKS;
 | 
				
			||||||
constexpr s32 SizePer_StringArena       = GEN_SIZE_PER_STRING_ARENA;
 | 
					constexpr s32 SizePer_StringArena       = GEN_SIZE_PER_STRING_ARENA;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +63,6 @@ extern CodeAttributes attrib_api_import;
 | 
				
			|||||||
extern Code module_global_fragment;
 | 
					extern Code module_global_fragment;
 | 
				
			||||||
extern Code module_private_fragment;
 | 
					extern Code module_private_fragment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Exposed, but this is really used for parsing.
 | 
					 | 
				
			||||||
extern Code fmt_newline;
 | 
					extern Code fmt_newline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern CodePragma pragma_once;
 | 
					extern CodePragma pragma_once;
 | 
				
			||||||
@@ -123,8 +122,8 @@ extern CodeType t_typename;
 | 
				
			|||||||
	extern CodeType t_u32;
 | 
						extern CodeType t_u32;
 | 
				
			||||||
	extern CodeType t_u64;
 | 
						extern CodeType t_u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern CodeType t_sw;
 | 
						extern CodeType t_ssize;
 | 
				
			||||||
	extern CodeType t_uw;
 | 
						extern CodeType t_usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern CodeType t_f32;
 | 
						extern CodeType t_f32;
 | 
				
			||||||
	extern CodeType t_f64;
 | 
						extern CodeType t_f64;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
#include "interface.hpp"
 | 
					#include "interface.hpp"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
void AST::append( AST* other )
 | 
					void AST::append( AST* other )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( other->Parent )
 | 
						if ( other->Parent )
 | 
				
			||||||
@@ -27,6 +28,7 @@ void AST::append( AST* other )
 | 
				
			|||||||
	NumEntries++;
 | 
						NumEntries++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
Code& AST::entry( u32 idx )
 | 
					Code& AST::entry( u32 idx )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	AST** current = & Front;
 | 
						AST** current = & Front;
 | 
				
			||||||
@@ -42,21 +44,25 @@ Code& AST::entry( u32 idx )
 | 
				
			|||||||
	return * rcast( Code*, current);
 | 
						return * rcast( Code*, current);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
bool AST::has_entries()
 | 
					bool AST::has_entries()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return NumEntries;
 | 
						return NumEntries > 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
char const* AST::type_str()
 | 
					char const* AST::type_str()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return ECode::to_str( Type );
 | 
						return ECode::to_str( Type );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
AST::operator Code()
 | 
					AST::operator Code()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return { this };
 | 
						return { this };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
Code& Code::operator ++()
 | 
					Code& Code::operator ++()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( ast )
 | 
						if ( ast )
 | 
				
			||||||
@@ -65,6 +71,7 @@ Code& Code::operator ++()
 | 
				
			|||||||
	return *this;
 | 
						return *this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
void CodeClass::add_interface( CodeType type )
 | 
					void CodeClass::add_interface( CodeType type )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CodeType possible_slot = ast->ParentType;
 | 
						CodeType possible_slot = ast->ParentType;
 | 
				
			||||||
@@ -84,6 +91,7 @@ void CodeClass::add_interface( CodeType type )
 | 
				
			|||||||
	possible_slot.ast = type.ast;
 | 
						possible_slot.ast = type.ast;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
void CodeParam::append( CodeParam other )
 | 
					void CodeParam::append( CodeParam other )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	AST* self  = (AST*) ast;
 | 
						AST* self  = (AST*) ast;
 | 
				
			||||||
@@ -107,6 +115,7 @@ void CodeParam::append( CodeParam other )
 | 
				
			|||||||
	self->NumEntries++;
 | 
						self->NumEntries++;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
CodeParam CodeParam::get( s32 idx )
 | 
					CodeParam CodeParam::get( s32 idx )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CodeParam param = *this;
 | 
						CodeParam param = *this;
 | 
				
			||||||
@@ -115,24 +124,27 @@ CodeParam CodeParam::get( s32 idx )
 | 
				
			|||||||
		if ( ! ++ param )
 | 
							if ( ! ++ param )
 | 
				
			||||||
			return { nullptr };
 | 
								return { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return { (AST_Param*) param.raw()->Next };
 | 
							param = { (AST_Param*) param.raw()->Next };
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	while ( --idx );
 | 
						while ( --idx );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return { nullptr };
 | 
						return param;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
bool CodeParam::has_entries()
 | 
					bool CodeParam::has_entries()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return ast->NumEntries > 0;
 | 
						return ast->NumEntries > 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
CodeParam& CodeParam::operator ++()
 | 
					CodeParam& CodeParam::operator ++()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ast = ast->Next.ast;
 | 
						ast = ast->Next.ast;
 | 
				
			||||||
	return * this;
 | 
						return * this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
void CodeStruct::add_interface( CodeType type )
 | 
					void CodeStruct::add_interface( CodeType type )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CodeType possible_slot = ast->ParentType;
 | 
						CodeType possible_slot = ast->ParentType;
 | 
				
			||||||
@@ -152,6 +164,7 @@ void CodeStruct::add_interface( CodeType type )
 | 
				
			|||||||
	possible_slot.ast = type.ast;
 | 
						possible_slot.ast = type.ast;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
CodeBody def_body( CodeT type )
 | 
					CodeBody def_body( CodeT type )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	switch ( type )
 | 
						switch ( type )
 | 
				
			||||||
@@ -179,7 +192,8 @@ CodeBody def_body( CodeT type )
 | 
				
			|||||||
	return (CodeBody)result;
 | 
						return (CodeBody)result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
StrC token_fmt_impl( sw num, ... )
 | 
					inline
 | 
				
			||||||
 | 
					StrC token_fmt_impl( ssize num, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local_persist thread_local
 | 
						local_persist thread_local
 | 
				
			||||||
	char buf[GEN_PRINTF_MAXLEN] = { 0 };
 | 
						char buf[GEN_PRINTF_MAXLEN] = { 0 };
 | 
				
			||||||
@@ -187,7 +201,7 @@ StrC token_fmt_impl( sw num, ... )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start(va, num );
 | 
						va_start(va, num );
 | 
				
			||||||
	sw result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
 | 
						ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
 | 
				
			||||||
	va_end(va);
 | 
						va_end(va);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return { result, buf };
 | 
						return { result, buf };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ internal void deinit();
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal
 | 
					internal
 | 
				
			||||||
void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
 | 
					void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Arena* last = & Global_AllocatorBuckets.back();
 | 
						Arena* last = & Global_AllocatorBuckets.back();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -169,8 +169,8 @@ void define_constants()
 | 
				
			|||||||
	def_constant_code_type( u32 );
 | 
						def_constant_code_type( u32 );
 | 
				
			||||||
	def_constant_code_type( u64 );
 | 
						def_constant_code_type( u64 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def_constant_code_type( sw );
 | 
						def_constant_code_type( ssize );
 | 
				
			||||||
	def_constant_code_type( uw );
 | 
						def_constant_code_type( usize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	def_constant_code_type( f32 );
 | 
						def_constant_code_type( f32 );
 | 
				
			||||||
	def_constant_code_type( f64 );
 | 
						def_constant_code_type( f64 );
 | 
				
			||||||
@@ -298,8 +298,8 @@ void init()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void deinit()
 | 
					void deinit()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	uw index = 0;
 | 
						usize index = 0;
 | 
				
			||||||
	uw left  = CodePools.num();
 | 
						usize left  = CodePools.num();
 | 
				
			||||||
	do
 | 
						do
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Pool* code_pool = & CodePools[index];
 | 
							Pool* code_pool = & CodePools[index];
 | 
				
			||||||
@@ -372,9 +372,9 @@ AllocatorInfo get_string_allocator( s32 str_length )
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	Arena* last = & StringArenas.back();
 | 
						Arena* last = & StringArenas.back();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uw size_req = str_length + sizeof(String::Header) + sizeof(char*);
 | 
						usize size_req = str_length + sizeof(String::Header) + sizeof(char*);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( last->TotalUsed + size_req > last->TotalSize )
 | 
						if ( last->TotalUsed + ssize(size_req) > last->TotalSize )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
 | 
							Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -166,7 +166,7 @@ namespace parser {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ParseInfo
 | 
					struct ParseInfo
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	Arena FileMem;
 | 
						Arena FileMem;
 | 
				
			||||||
	Arena TokMem;
 | 
						Arena TokMem;
 | 
				
			||||||
	Arena CodeMem;
 | 
						Arena CodeMem;
 | 
				
			||||||
@@ -175,7 +175,7 @@ struct ParseInfo
 | 
				
			|||||||
	Array<parser::Token> Tokens;
 | 
						Array<parser::Token> Tokens;
 | 
				
			||||||
	Array<parser::Error> Errors;
 | 
						Array<parser::Error> Errors;
 | 
				
			||||||
	// Errors are allocated to a dedicated general arena.
 | 
						// Errors are allocated to a dedicated general arena.
 | 
				
			||||||
;
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CodeBody parse_file( StrC path );
 | 
					CodeBody parse_file( StrC path );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@@ -204,9 +204,9 @@ CodeVar         parse_variable     ( StrC var_def         );
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region Untyped text
 | 
					#pragma region Untyped text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw   token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va );
 | 
					ssize   token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
 | 
				
			||||||
//! Do not use directly. Use the token_fmt macro instead.
 | 
					//! Do not use directly. Use the token_fmt macro instead.
 | 
				
			||||||
StrC token_fmt_impl( sw, ... );
 | 
					StrC token_fmt_impl( ssize, ... );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Code untyped_str      ( StrC content);
 | 
					Code untyped_str      ( StrC content);
 | 
				
			||||||
Code untyped_fmt      ( char const* fmt, ... );
 | 
					Code untyped_fmt      ( char const* fmt, ... );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,10 @@
 | 
				
			|||||||
#include "interface.parsing.cpp"
 | 
					#include "interface.parsing.cpp"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
 | 
					ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char const* buf_begin = buf;
 | 
						char const* buf_begin = buf;
 | 
				
			||||||
	sw          remaining = buf_size;
 | 
						ssize          remaining = buf_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local_persist
 | 
						local_persist
 | 
				
			||||||
	Arena tok_map_arena;
 | 
						Arena tok_map_arena;
 | 
				
			||||||
@@ -37,7 +37,7 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	while ( current )
 | 
						while ( current )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw len = 0;
 | 
							ssize len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while ( current && current != '<' && remaining )
 | 
							while ( current && current != '<' && remaining )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -68,7 +68,7 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if ( value )
 | 
								if ( value )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				sw          left = value->Len;
 | 
									ssize          left = value->Len;
 | 
				
			||||||
				char const* str  = value->Ptr;
 | 
									char const* str  = value->Ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				while ( left-- )
 | 
									while ( left-- )
 | 
				
			||||||
@@ -97,7 +97,7 @@ sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
 | 
				
			|||||||
	tok_map.clear();
 | 
						tok_map.clear();
 | 
				
			||||||
	tok_map_arena.free();
 | 
						tok_map_arena.free();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw result = buf_size - remaining;
 | 
						ssize result = buf_size - remaining;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -138,7 +138,7 @@ Code untyped_fmt( char const* fmt, ...)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start(va, fmt);
 | 
						va_start(va, fmt);
 | 
				
			||||||
	sw length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
 | 
						ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
 | 
				
			||||||
	va_end(va);
 | 
						va_end(va);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Code
 | 
						Code
 | 
				
			||||||
@@ -169,7 +169,7 @@ Code untyped_token_fmt( s32 num_tokens, ... )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start(va, num_tokens);
 | 
						va_start(va, num_tokens);
 | 
				
			||||||
	sw length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
 | 
						ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
 | 
				
			||||||
	va_end(va);
 | 
						va_end(va);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Code
 | 
						Code
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1202,6 +1202,26 @@ TokArray lex( StrC content )
 | 
				
			|||||||
					move_forward();
 | 
										move_forward();
 | 
				
			||||||
					token.Length++;
 | 
										token.Length++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									// Handle number literal suffixes in a botched way
 | 
				
			||||||
 | 
									if (left && (
 | 
				
			||||||
 | 
										current == 'l' || current == 'L' ||  // long/long long
 | 
				
			||||||
 | 
										current == 'u' || current == 'U' ||  // unsigned
 | 
				
			||||||
 | 
										current == 'f' || current == 'F' ||  // float
 | 
				
			||||||
 | 
										current == 'i' || current == 'I' ||  // imaginary
 | 
				
			||||||
 | 
										current == 'z' || current == 'Z'))   // complex
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										char prev = current;
 | 
				
			||||||
 | 
										move_forward();
 | 
				
			||||||
 | 
										token.Length++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Handle 'll'/'LL' as a special case when we just processed an 'l'/'L'
 | 
				
			||||||
 | 
										if (left && (prev == 'l' || prev == 'L') && (current == 'l' || current == 'L'))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											move_forward();
 | 
				
			||||||
 | 
											token.Length++;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			goto FoundToken;
 | 
								goto FoundToken;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -169,6 +169,12 @@ if ( def.Ptr == nullptr )                                                      \
 | 
				
			|||||||
#	define eat( Type_ )   Context.Tokens.__eat( Type_ )
 | 
					#	define eat( Type_ )   Context.Tokens.__eat( Type_ )
 | 
				
			||||||
#	define left           ( Context.Tokens.Arr.num() - Context.Tokens.Idx )
 | 
					#	define left           ( Context.Tokens.Arr.num() - Context.Tokens.Idx )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef check
 | 
				
			||||||
 | 
					#define CHECK_WAS_DEFINED
 | 
				
			||||||
 | 
					#pragma push_macro("check")
 | 
				
			||||||
 | 
					#undef check
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#	define check_noskip( Type_ ) ( left && currtok_noskip.Type == Type_ )
 | 
					#	define check_noskip( Type_ ) ( left && currtok_noskip.Type == Type_ )
 | 
				
			||||||
#	define check( Type_ )        ( left && currtok.Type == Type_ )
 | 
					#	define check( Type_ )        ( left && currtok.Type == Type_ )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -481,7 +487,7 @@ Code parse_array_decl()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' )
 | 
						if ( check( TokType::Operator ) && currtok.Text[0] == '[' && currtok.Text[1] == ']' )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Code array_expr = untyped_str( get_cached_string(txt(" ")) );
 | 
							Code array_expr = untyped_str( currtok );
 | 
				
			||||||
		eat( TokType::Operator );
 | 
							eat( TokType::Operator );
 | 
				
			||||||
		// []
 | 
							// []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -554,44 +560,6 @@ Code parse_array_decl()
 | 
				
			|||||||
	return { nullptr };
 | 
						return { nullptr };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal inline
 | 
					 | 
				
			||||||
Code parse_assignment_expression()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	Code expr = { nullptr };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	eat( TokType::Operator );
 | 
					 | 
				
			||||||
	// <Attributes> <Specifiers> <ValueType> <Name> =
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Token expr_tok = currtok;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
 | 
					 | 
				
			||||||
		Context.pop();
 | 
					 | 
				
			||||||
		return CodeInvalid;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	s32 level = 0;
 | 
					 | 
				
			||||||
	while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (currtok.Type == TokType::BraceCurly_Open )
 | 
					 | 
				
			||||||
			level++;
 | 
					 | 
				
			||||||
		if (currtok.Type == TokType::BraceCurly_Close )
 | 
					 | 
				
			||||||
			level--;
 | 
					 | 
				
			||||||
		if (currtok.Type == TokType::Capture_Start)
 | 
					 | 
				
			||||||
			level++;
 | 
					 | 
				
			||||||
		else if (currtok.Type == TokType::Capture_End)
 | 
					 | 
				
			||||||
			level--;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		eat( currtok.Type );
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1;
 | 
					 | 
				
			||||||
	expr            = untyped_str( expr_tok );
 | 
					 | 
				
			||||||
	// = <Expression>
 | 
					 | 
				
			||||||
	return expr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
internal inline
 | 
					internal inline
 | 
				
			||||||
CodeAttributes parse_attributes()
 | 
					CodeAttributes parse_attributes()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1349,17 +1317,14 @@ CodeDefine parse_define()
 | 
				
			|||||||
	eat( TokType::Identifier );
 | 
						eat( TokType::Identifier );
 | 
				
			||||||
	// #define <Name>
 | 
						// #define <Name>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Defines don't necessarily need content.
 | 
					 | 
				
			||||||
#if 0
 | 
					 | 
				
			||||||
	if ( ! check( TokType::Preprocess_Content ))
 | 
						if ( ! check( TokType::Preprocess_Content ))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
 | 
							log_failure( "Error, expected content after #define %s\n%s", define->Name, Context.to_string() );
 | 
				
			||||||
		Context.pop();
 | 
							Context.pop();
 | 
				
			||||||
		return CodeInvalid;
 | 
							return CodeInvalid;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( check(TokType::Preprocess_Content) && currtok.Length != 0 )
 | 
						if ( currtok.Length == 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		define->Content = get_cached_string( currtok );
 | 
							define->Content = get_cached_string( currtok );
 | 
				
			||||||
		eat( TokType::Preprocess_Content );
 | 
							eat( TokType::Preprocess_Content );
 | 
				
			||||||
@@ -1377,6 +1342,44 @@ CodeDefine parse_define()
 | 
				
			|||||||
	return define;
 | 
						return define;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					internal inline
 | 
				
			||||||
 | 
					Code parse_assignment_expression()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Code expr = { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eat( TokType::Operator );
 | 
				
			||||||
 | 
						// <Attributes> <Specifiers> <ValueType> <Name> =
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Token expr_tok = currtok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( currtok.Type == TokType::Statement_End && currtok.Type != TokType::Comma )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							log_failure( "Expected expression after assignment operator\n%s", Context.to_string() );
 | 
				
			||||||
 | 
							Context.pop();
 | 
				
			||||||
 | 
							return CodeInvalid;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						s32 level = 0;
 | 
				
			||||||
 | 
						while ( left && currtok.Type != TokType::Statement_End && (currtok.Type != TokType::Comma || level > 0) )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (currtok.Type == TokType::BraceCurly_Open )
 | 
				
			||||||
 | 
								level++;
 | 
				
			||||||
 | 
							if (currtok.Type == TokType::BraceCurly_Close )
 | 
				
			||||||
 | 
								level--;
 | 
				
			||||||
 | 
							if (currtok.Type == TokType::Capture_Start)
 | 
				
			||||||
 | 
								level++;
 | 
				
			||||||
 | 
							else if (currtok.Type == TokType::Capture_End)
 | 
				
			||||||
 | 
								level--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							eat( currtok.Type );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expr_tok.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )expr_tok.Text - 1;
 | 
				
			||||||
 | 
						expr            = untyped_str( expr_tok );
 | 
				
			||||||
 | 
						// = <Expression>
 | 
				
			||||||
 | 
						return expr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal inline
 | 
					internal inline
 | 
				
			||||||
Code parse_forward_or_definition( TokType which, bool is_inplace )
 | 
					Code parse_forward_or_definition( TokType which, bool is_inplace )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -1407,8 +1410,6 @@ Code parse_forward_or_definition( TokType which, bool is_inplace )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return CodeInvalid;
 | 
								return CodeInvalid;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	return CodeInvalid;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Function parsing is handled in multiple places because its initial signature is shared with variable parsing
 | 
					// Function parsing is handled in multiple places because its initial signature is shared with variable parsing
 | 
				
			||||||
@@ -1755,7 +1756,6 @@ CodeBody parse_global_nspace( CodeT which )
 | 
				
			|||||||
			case TokType::Spec_Internal_Linkage:
 | 
								case TokType::Spec_Internal_Linkage:
 | 
				
			||||||
			case TokType::Spec_NeverInline:
 | 
								case TokType::Spec_NeverInline:
 | 
				
			||||||
			case TokType::Spec_Static:
 | 
								case TokType::Spec_Static:
 | 
				
			||||||
			case TokType::Spec_ThreadLocal:
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
 | 
									SpecifierT specs_found[16] { ESpecifier::NumSpecifiers };
 | 
				
			||||||
				s32        NumSpecifiers = 0;
 | 
									s32        NumSpecifiers = 0;
 | 
				
			||||||
@@ -1779,7 +1779,6 @@ CodeBody parse_global_nspace( CodeT which )
 | 
				
			|||||||
						case ESpecifier::NeverInline:
 | 
											case ESpecifier::NeverInline:
 | 
				
			||||||
						case ESpecifier::Static:
 | 
											case ESpecifier::Static:
 | 
				
			||||||
						case ESpecifier::Volatile:
 | 
											case ESpecifier::Volatile:
 | 
				
			||||||
						case ESpecifier::Thread_Local:
 | 
					 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						case ESpecifier::Consteval:
 | 
											case ESpecifier::Consteval:
 | 
				
			||||||
@@ -1857,7 +1856,7 @@ CodeBody parse_global_nspace( CodeT which )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if ( found_operator_cast_outside_class_implmentation )
 | 
									if ( found_operator_cast_outside_class_implmentation )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					member = parse_operator_cast();
 | 
										member = parse_operator_cast( specifiers );
 | 
				
			||||||
					// <Attributes> <Specifiers> <Name>::operator <Type>() { ... }
 | 
										// <Attributes> <Specifiers> <Name>::operator <Type>() { ... }
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -2300,7 +2299,7 @@ CodeOperator parse_operator_after_ret_type(
 | 
				
			|||||||
		case '<':
 | 
							case '<':
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( currtok.Text[1] == '=' )
 | 
								if ( currtok.Text[1] == '=' )
 | 
				
			||||||
				op = LesserEqual;
 | 
									op = LEqual;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			else if ( currtok.Text[1] == '<' )
 | 
								else if ( currtok.Text[1] == '<' )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
@@ -2540,7 +2539,14 @@ Code parse_operator_function_or_variable( bool expects_function, CodeAttributes
 | 
				
			|||||||
		Token name = parse_identifier();
 | 
							Token name = parse_identifier();
 | 
				
			||||||
		Context.Scope->Name = name;
 | 
							Context.Scope->Name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( check( TokType::Capture_Start) )
 | 
							bool detected_capture = check( TokType::Capture_Start );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Check three tokens ahead to make sure that were not dealing with a constructor initialization...
 | 
				
			||||||
 | 
							//                  (         350.0f    ,         <---  Could be the scenario
 | 
				
			||||||
 | 
							// Example : <Capture_Start> <Value> <Comma>
 | 
				
			||||||
 | 
							//                 idx         +1      +2
 | 
				
			||||||
 | 
							bool detected_comma = Context.Tokens.Arr[ Context.Tokens.Idx + 2 ].Type == TokType::Comma;
 | 
				
			||||||
 | 
							if ( detected_capture && ! detected_comma )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// Dealing with a function
 | 
								// Dealing with a function
 | 
				
			||||||
			result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
 | 
								result = parse_function_after_name( ModuleFlag::None, attributes, specifiers, type, name );
 | 
				
			||||||
@@ -2629,6 +2635,7 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
	CodeType type            = { nullptr };
 | 
						CodeType type            = { nullptr };
 | 
				
			||||||
	Code     value           = { nullptr };
 | 
						Code     value           = { nullptr };
 | 
				
			||||||
	Token    name            = NullToken;
 | 
						Token    name            = NullToken;
 | 
				
			||||||
 | 
						Code     post_name_macro = { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( check( TokType::Varadic_Argument ) )
 | 
						if ( check( TokType::Varadic_Argument ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -2670,6 +2677,15 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
			// ( <Macro> <ValueType> <Name>
 | 
								// ( <Macro> <ValueType> <Name>
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Unreal has yet another type of macro:
 | 
				
			||||||
 | 
							// template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)>
 | 
				
			||||||
 | 
							// class T ... and then ^this^ UE_REQUIRES shows up
 | 
				
			||||||
 | 
							// So we need to consume that.
 | 
				
			||||||
 | 
							if ( check( TokType::Preprocess_Macro ))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// In template captures you can have a typename have direct assignment without a name
 | 
							// In template captures you can have a typename have direct assignment without a name
 | 
				
			||||||
		// typename = typename ...
 | 
							// typename = typename ...
 | 
				
			||||||
		// Which would result in a static value type from a struct expansion (traditionally)
 | 
							// Which would result in a static value type from a struct expansion (traditionally)
 | 
				
			||||||
@@ -2689,7 +2705,7 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			s32 capture_level  = 0;
 | 
								s32 capture_level  = 0;
 | 
				
			||||||
			s32 template_level = 0;
 | 
								s32 template_level = 0;
 | 
				
			||||||
			while ( left && (currtok.Type != TokType::Comma) && template_level >= 0 && (CheckEndParams() || capture_level > 0 || template_level > 0) )
 | 
								while ( (left && ( currtok.Type != TokType::Comma ) && template_level >= 0 && CheckEndParams()) || (capture_level > 0 || template_level > 0) )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (currtok.Text[ 0 ] == '<')
 | 
									if (currtok.Text[ 0 ] == '<')
 | 
				
			||||||
					++ template_level;
 | 
										++ template_level;
 | 
				
			||||||
@@ -2773,6 +2789,15 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
				// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name>
 | 
									// ( <Macro> <ValueType> <Name> = <Expression>, <Macro> <ValueType> <Name>
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// Unreal has yet another type of macro:
 | 
				
			||||||
 | 
								// template<class T UE_REQUIRES(TPointerIsConvertibleFromTo<T, UInterface>::Value)>
 | 
				
			||||||
 | 
								// class T ... and then ^this^ UE_REQUIRES shows up
 | 
				
			||||||
 | 
								// So we need to consume that.
 | 
				
			||||||
 | 
								if ( check( TokType::Preprocess_Macro ))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									post_name_macro = parse_simple_preprocess( ETokType::Preprocess_Macro );
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// In template captures you can have a typename have direct assignment without a name
 | 
								// In template captures you can have a typename have direct assignment without a name
 | 
				
			||||||
			// typename = typename ...
 | 
								// typename = typename ...
 | 
				
			||||||
			// Which would result in a static value type from a struct expansion (traditionally)
 | 
								// Which would result in a static value type from a struct expansion (traditionally)
 | 
				
			||||||
@@ -2792,10 +2817,10 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				s32 capture_level  = 0;
 | 
									s32 capture_level  = 0;
 | 
				
			||||||
				s32 template_level = 0;
 | 
									s32 template_level = 0;
 | 
				
			||||||
				while ( left
 | 
									while ( (left
 | 
				
			||||||
				&& currtok.Type != TokType::Comma
 | 
									&& currtok.Type != TokType::Comma
 | 
				
			||||||
				&& template_level >= 0
 | 
									&& template_level >= 0
 | 
				
			||||||
				&& (CheckEndParams() || capture_level > 0 || template_level > 0) )
 | 
									&& CheckEndParams()) || (capture_level > 0 || template_level > 0) )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if (currtok.Text[ 0 ] == '<')
 | 
										if (currtok.Text[ 0 ] == '<')
 | 
				
			||||||
						++ template_level;
 | 
											++ template_level;
 | 
				
			||||||
@@ -2829,6 +2854,7 @@ CodeParam parse_params( bool use_template_capture )
 | 
				
			|||||||
		if ( name.Length > 0 )
 | 
							if ( name.Length > 0 )
 | 
				
			||||||
			param->Name = get_cached_string( name );
 | 
								param->Name = get_cached_string( name );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							param->PostNameMacro = post_name_macro;
 | 
				
			||||||
		param->ValueType     = type;
 | 
							param->ValueType     = type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( value )
 | 
							if ( value )
 | 
				
			||||||
@@ -2872,7 +2898,7 @@ CodePreprocessCond parse_preprocess_cond()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	CodePreprocessCond
 | 
						CodePreprocessCond
 | 
				
			||||||
	cond       = (CodePreprocessCond) make_code();
 | 
						cond       = (CodePreprocessCond) make_code();
 | 
				
			||||||
	cond->Type = scast(CodeT, currtok.Type - (s32(ETokType::Preprocess_If) - s32(ECode::Preprocess_If)) );
 | 
						cond->Type = scast(CodeT, currtok.Type - ( TokType::Preprocess_If - ECode::Preprocess_If ) );
 | 
				
			||||||
	eat( currtok.Type );
 | 
						eat( currtok.Type );
 | 
				
			||||||
	// #<Conditional>
 | 
						// #<Conditional>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3067,6 +3093,8 @@ CodeVar parse_variable_after_name(
 | 
				
			|||||||
	Code expr          = { nullptr };
 | 
						Code expr          = { nullptr };
 | 
				
			||||||
	Code bitfield_expr = { nullptr };
 | 
						Code bitfield_expr = { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						b32 using_constructor_initializer = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) )
 | 
						if ( bitfield_is_equal( u32, currtok.Flags, TF_Assign ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
 | 
							// <Attributes> <Specifiers> <ValueType> <Name> = <Expression>
 | 
				
			||||||
@@ -3098,6 +3126,33 @@ CodeVar parse_variable_after_name(
 | 
				
			|||||||
		// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
 | 
							// <Attributes> <Specifiers> <ValueType> <Name> = { <Expression> }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( currtok.Type == TokType::Capture_Start )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							eat( TokType:: Capture_Start);
 | 
				
			||||||
 | 
							// <Attributes> <Specifiers> <ValueType> <Name> (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Token expr_token = currtok;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							using_constructor_initializer = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							s32 level = 0;
 | 
				
			||||||
 | 
							while ( left && ( currtok.Type != TokType::Capture_End || level > 0 ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if ( currtok.Type == TokType::Capture_Start )
 | 
				
			||||||
 | 
									level++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								else if ( currtok.Type == TokType::Capture_End && level > 0 )
 | 
				
			||||||
 | 
									level--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								eat( currtok.Type );
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							expr_token.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)expr_token.Text;
 | 
				
			||||||
 | 
							expr              = untyped_str( expr_token );
 | 
				
			||||||
 | 
							eat( TokType::Capture_End );
 | 
				
			||||||
 | 
							// <Attributes> <Specifiers> <ValueType> <Name> ( <Expression> )
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( currtok.Type == TokType::Assign_Classifer )
 | 
						if ( currtok.Type == TokType::Assign_Classifer )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		eat( TokType::Assign_Classifer );
 | 
							eat( TokType::Assign_Classifer );
 | 
				
			||||||
@@ -3192,6 +3247,8 @@ CodeVar parse_variable_after_name(
 | 
				
			|||||||
		result->NextVar->Parent = result;
 | 
							result->NextVar->Parent = result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result->VarConstructorInit = using_constructor_initializer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Context.pop();
 | 
						Context.pop();
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -3246,7 +3303,7 @@ CodeVar parse_variable_declaration_list()
 | 
				
			|||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			eat(currtok.Type);
 | 
								// eat(currtok.Type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if ( specifiers )
 | 
								if ( specifiers )
 | 
				
			||||||
				specifiers.append( spec );
 | 
									specifiers.append( spec );
 | 
				
			||||||
@@ -3650,11 +3707,11 @@ CodeEnum parse_enum( bool inplace_def )
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					// Consume inline comments
 | 
										// Consume inline comments
 | 
				
			||||||
					if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line )
 | 
										// if ( currtok.Type == TokType::Comment && prevtok.Line == currtok.Line )
 | 
				
			||||||
					{
 | 
										// {
 | 
				
			||||||
						eat( TokType::Comment );
 | 
											// eat( TokType::Comment );
 | 
				
			||||||
						// <Name> = <Expression> <Macro>, // <Inline Comment>
 | 
											// <Name> = <Expression> <Macro>, // <Inline Comment>
 | 
				
			||||||
					}
 | 
										// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text;
 | 
										entry.Length = ( (sptr)prevtok.Text + prevtok.Length ) - (sptr)entry.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -4029,8 +4086,6 @@ CodeOpCast parse_operator_cast( CodeSpecifiers specifiers )
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	push_scope();
 | 
						push_scope();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO : Specifiers attributed to the cast
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Operator's namespace if not within same class.
 | 
						// Operator's namespace if not within same class.
 | 
				
			||||||
	Token name = NullToken;
 | 
						Token name = NullToken;
 | 
				
			||||||
	if ( check( TokType::Identifier ) )
 | 
						if ( check( TokType::Identifier ) )
 | 
				
			||||||
@@ -4399,13 +4454,10 @@ CodeType parse_type( bool from_template, bool* typedef_is_function )
 | 
				
			|||||||
	else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct
 | 
						else if ( currtok.Type == TokType::Decl_Class || currtok.Type == TokType::Decl_Enum || currtok.Type == TokType::Decl_Struct
 | 
				
			||||||
			|| currtok.Type == TokType::Decl_Union )
 | 
								|| currtok.Type == TokType::Decl_Union )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Token fwd_key = currtok;
 | 
					 | 
				
			||||||
		eat( currtok.Type );
 | 
							eat( currtok.Type );
 | 
				
			||||||
		// <Attributes> <Specifiers> <class, enum, struct, union>
 | 
							// <Attributes> <Specifiers> <class, enum, struct, union>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		name = parse_identifier();
 | 
							name = parse_identifier();
 | 
				
			||||||
		fwd_key.Length = sptr(name.Text + name.Length) - sptr(fwd_key.Text);
 | 
					 | 
				
			||||||
		name           = fwd_key;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
 | 
							// name.Length = ( ( sptr )currtok.Text + currtok.Length ) - ( sptr )name.Text;
 | 
				
			||||||
		// eat( TokType::Identifier );
 | 
							// eat( TokType::Identifier );
 | 
				
			||||||
@@ -4462,6 +4514,18 @@ else if ( currtok.Type == TokType::DeclType )
 | 
				
			|||||||
		name = currtok;
 | 
							name = currtok;
 | 
				
			||||||
		eat(TokType::Type_Typename);
 | 
							eat(TokType::Type_Typename);
 | 
				
			||||||
		// <typename>
 | 
							// <typename>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ( ! from_template )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								name                = parse_identifier();
 | 
				
			||||||
 | 
								Context.Scope->Name = name;
 | 
				
			||||||
 | 
								if ( ! name )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									log_failure( "Error, failed to type signature\n%s", Context.to_string() );
 | 
				
			||||||
 | 
									Context.pop();
 | 
				
			||||||
 | 
									return CodeInvalid;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// The usual Identifier type signature that may have namespace qualifiers
 | 
						// The usual Identifier type signature that may have namespace qualifiers
 | 
				
			||||||
@@ -5299,3 +5363,7 @@ CodeVar parse_variable()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// namespace parser
 | 
					// namespace parser
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CHECK_WAS_DEFINED
 | 
				
			||||||
 | 
					#pragma pop_macro("check")
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,4 +9,3 @@
 | 
				
			|||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
 | 
					#ifndef GEN_ROLL_OWN_DEPENDENCIES
 | 
				
			||||||
#	include "gen.dep.cpp"
 | 
					#	include "gen.dep.cpp"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -97,8 +97,8 @@ global CodeType t_u16;
 | 
				
			|||||||
global CodeType t_u32;
 | 
					global CodeType t_u32;
 | 
				
			||||||
global CodeType t_u64;
 | 
					global CodeType t_u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global CodeType t_sw;
 | 
					global CodeType t_ssize;
 | 
				
			||||||
global CodeType t_uw;
 | 
					global CodeType t_usize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global CodeType t_f32;
 | 
					global CodeType t_f32;
 | 
				
			||||||
global CodeType t_f64;
 | 
					global CodeType t_f64;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
#include "header_start.hpp"
 | 
					#include "header_start.hpp"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using LogFailType = sw(*)(char const*, ...);
 | 
					using LogFailType = ssize(*)(char const*, ...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// By default this library will either crash or exit if an error is detected while generating codes.
 | 
					// By default this library will either crash or exit if an error is detected while generating codes.
 | 
				
			||||||
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
 | 
					// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
 | 
				
			||||||
@@ -71,6 +71,7 @@ enum class ModuleFlag : u32
 | 
				
			|||||||
	Invalid,
 | 
						Invalid,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
StrC to_str( ModuleFlag flag )
 | 
					StrC to_str( ModuleFlag flag )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local_persist
 | 
						local_persist
 | 
				
			||||||
@@ -86,6 +87,7 @@ StrC to_str( ModuleFlag flag )
 | 
				
			|||||||
	return lookup[ (u32)flag ];
 | 
						return lookup[ (u32)flag ];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
 | 
					ModuleFlag operator|( ModuleFlag A, ModuleFlag B)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return (ModuleFlag)( (u32)A | (u32)B );
 | 
						return (ModuleFlag)( (u32)A | (u32)B );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -85,10 +85,10 @@ static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" );
 | 
				
			|||||||
static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
 | 
					static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
 | 
				
			||||||
static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
 | 
					static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef size_t    uw;
 | 
					typedef size_t    usize;
 | 
				
			||||||
typedef ptrdiff_t sw;
 | 
					typedef ptrdiff_t ssize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" );
 | 
					static_assert( sizeof( usize ) == sizeof( ssize ), "sizeof(usize) != sizeof(ssize)" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
 | 
					// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
 | 
				
			||||||
#if defined( _WIN64 )
 | 
					#if defined( _WIN64 )
 | 
				
			||||||
@@ -122,4 +122,13 @@ typedef s8  b8;
 | 
				
			|||||||
typedef s16 b16;
 | 
					typedef s16 b16;
 | 
				
			||||||
typedef s32 b32;
 | 
					typedef s32 b32;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using mem_ptr       = void*;
 | 
				
			||||||
 | 
					using mem_ptr_const = void const*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Type> uptr to_uptr( Type* ptr ) { return (uptr)ptr; }
 | 
				
			||||||
 | 
					template<typename Type> sptr to_sptr( Type* ptr ) { return (sptr)ptr; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Type> mem_ptr       to_mem_ptr      ( Type ptr ) { return (mem_ptr)      ptr; }
 | 
				
			||||||
 | 
					template<typename Type> mem_ptr_const to_mem_ptr_const( Type ptr ) { return (mem_ptr_const)ptr; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion Basic Types
 | 
					#pragma endregion Basic Types
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
template<class TType>             struct RemoveConst                    { typedef TType Type;       };
 | 
					template<class TType>             struct RemoveConst                    { typedef TType Type;       };
 | 
				
			||||||
template<class TType>             struct RemoveConst<const TType>       { typedef TType Type;       };
 | 
					template<class TType>             struct RemoveConst<const TType>       { typedef TType Type;       };
 | 
				
			||||||
template<class TType>             struct RemoveConst<const TType[]>     { typedef TType Type[];     };
 | 
					template<class TType>             struct RemoveConst<const TType[]>     { typedef TType Type[];     };
 | 
				
			||||||
template<class TType, uw Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; };
 | 
					template<class TType, usize Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<class TType>
 | 
					template<class TType>
 | 
				
			||||||
using TRemoveConst = typename RemoveConst<TType>::Type;
 | 
					using TRemoveConst = typename RemoveConst<TType>::Type;
 | 
				
			||||||
@@ -19,8 +19,8 @@ struct Array
 | 
				
			|||||||
	struct Header
 | 
						struct Header
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		AllocatorInfo Allocator;
 | 
							AllocatorInfo Allocator;
 | 
				
			||||||
		uw            Capacity;
 | 
							usize            Capacity;
 | 
				
			||||||
		uw            Num;
 | 
							usize            Num;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
@@ -30,7 +30,7 @@ struct Array
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Array init_reserve( AllocatorInfo allocator, sw capacity )
 | 
						Array init_reserve( AllocatorInfo allocator, ssize capacity )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) * capacity ));
 | 
							Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) * capacity ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,11 +45,16 @@ struct Array
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	uw grow_formula( uw value )
 | 
						usize grow_formula( usize value )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return 2 * value + 8;
 | 
							return 2 * value + 8;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool append( Array other )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return append( other, other.num() );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append( Type value )
 | 
						bool append( Type value )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
@@ -68,7 +73,7 @@ struct Array
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append( Type* items, uw item_num )
 | 
						bool append( Type* items, usize item_num )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -86,7 +91,7 @@ struct Array
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append_at( Type item, uw idx )
 | 
						bool append_at( Type item, usize idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -112,7 +117,7 @@ struct Array
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append_at( Type* items, uw item_num, uw idx )
 | 
						bool append_at( Type* items, usize item_num, usize idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -151,14 +156,14 @@ struct Array
 | 
				
			|||||||
		header.Num     = 0;
 | 
							header.Num     = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool fill( uw begin, uw end, Type value )
 | 
						bool fill( usize begin, usize end, Type value )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header& header = * get_header();
 | 
							Header& header = * get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( begin < 0 || end > header.Num )
 | 
							if ( begin < 0 || end > header.Num )
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = begin; idx < end; idx++ )
 | 
							for ( ssize idx = ssize(begin); idx < ssize(end); idx++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Data[ idx ] = value;
 | 
								Data[ idx ] = value;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -179,10 +184,10 @@ struct Array
 | 
				
			|||||||
		return rcast( Header*, const_cast<NonConstType*>(Data) ) - 1 ;
 | 
							return rcast( Header*, const_cast<NonConstType*>(Data) ) - 1 ;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool grow( uw min_capacity )
 | 
						bool grow( usize min_capacity )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header& header       = * get_header();
 | 
							Header& header       = * get_header();
 | 
				
			||||||
		uw      new_capacity = grow_formula( header.Capacity );
 | 
							usize      new_capacity = grow_formula( header.Capacity );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( new_capacity < min_capacity )
 | 
							if ( new_capacity < min_capacity )
 | 
				
			||||||
			new_capacity = min_capacity;
 | 
								new_capacity = min_capacity;
 | 
				
			||||||
@@ -190,7 +195,7 @@ struct Array
 | 
				
			|||||||
		return set_capacity( new_capacity );
 | 
							return set_capacity( new_capacity );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uw num( void )
 | 
						usize num( void )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return get_header()->Num;
 | 
							return get_header()->Num;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -203,7 +208,7 @@ struct Array
 | 
				
			|||||||
		header.Num--;
 | 
							header.Num--;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void remove_at( uw idx )
 | 
						void remove_at( usize idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
		GEN_ASSERT( idx < header->Num );
 | 
							GEN_ASSERT( idx < header->Num );
 | 
				
			||||||
@@ -212,7 +217,7 @@ struct Array
 | 
				
			|||||||
		header->Num--;
 | 
							header->Num--;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool reserve( uw new_capacity )
 | 
						bool reserve( usize new_capacity )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header& header = * get_header();
 | 
							Header& header = * get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -222,7 +227,7 @@ struct Array
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool resize( uw num )
 | 
						bool resize( usize num )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header* header = get_header();
 | 
							Header* header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,7 +243,7 @@ struct Array
 | 
				
			|||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool set_capacity( uw new_capacity )
 | 
						bool set_capacity( usize new_capacity )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header& header = * get_header();
 | 
							Header& header = * get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -252,7 +257,7 @@ struct Array
 | 
				
			|||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		sw      size       = sizeof( Header ) + sizeof( Type ) * new_capacity;
 | 
							ssize      size       = sizeof( Header ) + sizeof( Type ) * new_capacity;
 | 
				
			||||||
		Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
 | 
							Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( new_header == nullptr )
 | 
							if ( new_header == nullptr )
 | 
				
			||||||
@@ -300,15 +305,15 @@ struct HashTable
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct FindResult
 | 
						struct FindResult
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw HashIndex;
 | 
							ssize HashIndex;
 | 
				
			||||||
		sw PrevIndex;
 | 
							ssize PrevIndex;
 | 
				
			||||||
		sw EntryIndex;
 | 
							ssize EntryIndex;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Entry
 | 
						struct Entry
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		u64  Key;
 | 
							u64  Key;
 | 
				
			||||||
		sw   Next;
 | 
							ssize   Next;
 | 
				
			||||||
		Type Value;
 | 
							Type Value;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -322,11 +327,11 @@ struct HashTable
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	HashTable init_reserve( AllocatorInfo allocator, uw num )
 | 
						HashTable init_reserve( AllocatorInfo allocator, usize num )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		HashTable<Type> result = { { nullptr }, { nullptr } };
 | 
							HashTable<Type> result = { { nullptr }, { nullptr } };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		result.Hashes  = Array<sw>::init_reserve( allocator, num );
 | 
							result.Hashes  = Array<ssize>::init_reserve( allocator, num );
 | 
				
			||||||
		result.Hashes.get_header()->Num = num;
 | 
							result.Hashes.get_header()->Num = num;
 | 
				
			||||||
		result.Hashes.resize( num );
 | 
							result.Hashes.resize( num );
 | 
				
			||||||
		result.Hashes.fill( 0, num, -1);
 | 
							result.Hashes.fill( 0, num, -1);
 | 
				
			||||||
@@ -352,7 +357,7 @@ struct HashTable
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	Type* get( u64 key )
 | 
						Type* get( u64 key )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw idx = find( key ).EntryIndex;
 | 
							ssize idx = find( key ).EntryIndex;
 | 
				
			||||||
		if ( idx >= 0 )
 | 
							if ( idx >= 0 )
 | 
				
			||||||
			return & Entries[ idx ].Value;
 | 
								return & Entries[ idx ].Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -365,7 +370,7 @@ struct HashTable
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		GEN_ASSERT_NOT_NULL( map_proc );
 | 
							GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
							for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
								map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -377,7 +382,7 @@ struct HashTable
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		GEN_ASSERT_NOT_NULL( map_proc );
 | 
							GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
							for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
 | 
								map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -385,16 +390,16 @@ struct HashTable
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void grow()
 | 
						void grow()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw new_num = Array<Entry>::grow_formula( Entries.num() );
 | 
							ssize new_num = Array<Entry>::grow_formula( Entries.num() );
 | 
				
			||||||
		rehash( new_num );
 | 
							rehash( new_num );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void rehash( sw new_num )
 | 
						void rehash( ssize new_num )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw last_added_index;
 | 
							ssize last_added_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
 | 
							HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
 | 
				
			||||||
		for ( sw idx = 0; idx < Entries.num(); ++idx )
 | 
							for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			FindResult find_result;
 | 
								FindResult find_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -417,15 +422,15 @@ struct HashTable
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void rehash_fast()
 | 
						void rehash_fast()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw idx;
 | 
							ssize idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( idx = 0; idx < Entries.num(); idx++ )
 | 
							for ( idx = 0; idx < ssize(Entries.num()); idx++ )
 | 
				
			||||||
			Entries[ idx ].Next = -1;
 | 
								Entries[ idx ].Next = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( idx = 0; idx < Hashes.num(); idx++ )
 | 
							for ( idx = 0; idx < ssize(Hashes.num()); idx++ )
 | 
				
			||||||
			Hashes[ idx ] = -1;
 | 
								Hashes[ idx ] = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( idx = 0; idx < Entries.num(); idx++ )
 | 
							for ( idx = 0; idx < ssize(Entries.num()); idx++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Entry*     entry;
 | 
								Entry*     entry;
 | 
				
			||||||
			FindResult find_result;
 | 
								FindResult find_result;
 | 
				
			||||||
@@ -451,14 +456,14 @@ struct HashTable
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void remove_entry( sw idx )
 | 
						void remove_entry( ssize idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Entries.remove_at( idx );
 | 
							Entries.remove_at( idx );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void set( u64 key, Type value )
 | 
						void set( u64 key, Type value )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw idx;
 | 
							ssize idx;
 | 
				
			||||||
		FindResult find_result;
 | 
							FindResult find_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( full() )
 | 
							if ( full() )
 | 
				
			||||||
@@ -489,23 +494,23 @@ struct HashTable
 | 
				
			|||||||
			grow();
 | 
								grow();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw slot( u64 key )
 | 
						ssize slot( u64 key )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw idx = 0; idx < Hashes.num(); ++idx )
 | 
							for ( ssize idx = 0; idx < ssize(Hashes.num()); ++idx )
 | 
				
			||||||
			if ( Hashes[ idx ] == key )
 | 
								if ( Hashes[ idx ] == key )
 | 
				
			||||||
				return idx;
 | 
									return idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return -1;
 | 
							return -1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Array< sw>    Hashes;
 | 
						Array< ssize>    Hashes;
 | 
				
			||||||
	Array< Entry> Entries;
 | 
						Array< Entry> Entries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw add_entry( u64 key )
 | 
						ssize add_entry( u64 key )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw idx;
 | 
							ssize idx;
 | 
				
			||||||
		Entry entry = { key, -1 };
 | 
							Entry entry = { key, -1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		idx = Entries.num();
 | 
							idx = Entries.num();
 | 
				
			||||||
@@ -537,7 +542,7 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	b32 full()
 | 
						b32 full()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) );
 | 
							usize critical_load = usize( CriticalLoadScale * f32(Hashes.num()) );
 | 
				
			||||||
		b32 result = Entries.num() > critical_load;
 | 
							b32 result = Entries.num() > critical_load;
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,7 @@
 | 
				
			|||||||
	{                                                                                        \
 | 
						{                                                                                        \
 | 
				
			||||||
		if ( ! ( cond ) )                                                                    \
 | 
							if ( ! ( cond ) )                                                                    \
 | 
				
			||||||
		{                                                                                    \
 | 
							{                                                                                    \
 | 
				
			||||||
			assert_handler( #cond, __FILE__, zpl_cast( s64 ) __LINE__, msg, ##__VA_ARGS__ ); \
 | 
								assert_handler( #cond, __FILE__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \
 | 
				
			||||||
			GEN_DEBUG_TRAP();                                                                \
 | 
								GEN_DEBUG_TRAP();                                                                \
 | 
				
			||||||
		}                                                                                    \
 | 
							}                                                                                    \
 | 
				
			||||||
	} while ( 0 )
 | 
						} while ( 0 )
 | 
				
			||||||
@@ -34,10 +34,6 @@
 | 
				
			|||||||
// NOTE: Things that shouldn't happen with a message!
 | 
					// NOTE: Things that shouldn't happen with a message!
 | 
				
			||||||
#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
 | 
					#define GEN_PANIC( msg, ... ) GEN_ASSERT_MSG( 0, msg, ##__VA_ARGS__ )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
 | 
					 | 
				
			||||||
s32  assert_crash( char const* condition );
 | 
					 | 
				
			||||||
void process_exit( u32 code );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#if Build_Debug
 | 
					#if Build_Debug
 | 
				
			||||||
	#define GEN_FATAL( ... )                               \
 | 
						#define GEN_FATAL( ... )                               \
 | 
				
			||||||
	do                                                     \
 | 
						do                                                     \
 | 
				
			||||||
@@ -60,4 +56,8 @@ void process_exit( u32 code );
 | 
				
			|||||||
	while (0)
 | 
						while (0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void assert_handler( char const* condition, char const* file, s32 line, char const* msg, ... );
 | 
				
			||||||
 | 
					s32  assert_crash( char const* condition );
 | 
				
			||||||
 | 
					void process_exit( u32 code );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion Debug
 | 
					#pragma endregion Debug
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,10 +7,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
 | 
					#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_len_ )
 | 
					internal
 | 
				
			||||||
 | 
					wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	wchar_t* w_text = NULL;
 | 
						wchar_t* w_text = NULL;
 | 
				
			||||||
	sw       len = 0, w_len = 0, w_len1 = 0;
 | 
						ssize       len = 0, w_len = 0, w_len1 = 0;
 | 
				
			||||||
	if ( text == NULL )
 | 
						if ( text == NULL )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( w_len_ )
 | 
							if ( w_len_ )
 | 
				
			||||||
@@ -24,7 +25,7 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
 | 
				
			|||||||
			*w_len_ = w_len;
 | 
								*w_len_ = w_len;
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, NULL, 0 );
 | 
						w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), NULL, 0 );
 | 
				
			||||||
	if ( w_len == 0 )
 | 
						if ( w_len == 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( w_len_ )
 | 
							if ( w_len_ )
 | 
				
			||||||
@@ -32,7 +33,7 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
 | 
				
			|||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	w_text = alloc_array( a, wchar_t, w_len + 1 );
 | 
						w_text = alloc_array( a, wchar_t, w_len + 1 );
 | 
				
			||||||
	w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, w_text, zpl_cast( int ) w_len );
 | 
						w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) );
 | 
				
			||||||
	if ( w_len1 == 0 )
 | 
						if ( w_len1 == 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		free( a, w_text );
 | 
							free( a, w_text );
 | 
				
			||||||
@@ -46,7 +47,8 @@ internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_
 | 
				
			|||||||
	return w_text;
 | 
						return w_text;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_SEEK_PROC( _win32_file_seek )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_SEEK_PROC( _win32_file_seek )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	LARGE_INTEGER li_offset;
 | 
						LARGE_INTEGER li_offset;
 | 
				
			||||||
	li_offset.QuadPart = offset;
 | 
						li_offset.QuadPart = offset;
 | 
				
			||||||
@@ -60,12 +62,13 @@ internal GEN_FILE_SEEK_PROC( _win32_file_seek )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_READ_AT_PROC( _win32_file_read )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_READ_AT_PROC( _win32_file_read )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// unused( stop_at_newline );
 | 
						// unused( stop_at_newline );
 | 
				
			||||||
	b32 result = false;
 | 
						b32 result = false;
 | 
				
			||||||
	_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
 | 
						_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
 | 
				
			||||||
	DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
 | 
						DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
 | 
				
			||||||
	DWORD bytes_read_;
 | 
						DWORD bytes_read_;
 | 
				
			||||||
	if ( ReadFile( fd.p, buffer, size_, &bytes_read_, NULL ) )
 | 
						if ( ReadFile( fd.p, buffer, size_, &bytes_read_, NULL ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -77,9 +80,10 @@ internal GEN_FILE_READ_AT_PROC( _win32_file_read )
 | 
				
			|||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_WRITE_AT_PROC( _win32_file_write )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_WRITE_AT_PROC( _win32_file_write )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
 | 
						DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
 | 
				
			||||||
	DWORD bytes_written_;
 | 
						DWORD bytes_written_;
 | 
				
			||||||
	_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
 | 
						_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
 | 
				
			||||||
	if ( WriteFile( fd.p, buffer, size_, &bytes_written_, NULL ) )
 | 
						if ( WriteFile( fd.p, buffer, size_, &bytes_written_, NULL ) )
 | 
				
			||||||
@@ -91,14 +95,16 @@ internal GEN_FILE_WRITE_AT_PROC( _win32_file_write )
 | 
				
			|||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_CLOSE_PROC( _win32_file_close )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_CLOSE_PROC( _win32_file_close )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	CloseHandle( fd.p );
 | 
						CloseHandle( fd.p );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FileOperations const default_file_operations = { _win32_file_read, _win32_file_write, _win32_file_seek, _win32_file_close };
 | 
					FileOperations const default_file_operations = { _win32_file_read, _win32_file_write, _win32_file_seek, _win32_file_close };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
neverinline GEN_FILE_OPEN_PROC( _win32_file_open )
 | 
					neverinline
 | 
				
			||||||
 | 
					GEN_FILE_OPEN_PROC( _win32_file_open )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	DWORD    desired_access;
 | 
						DWORD    desired_access;
 | 
				
			||||||
	DWORD    creation_disposition;
 | 
						DWORD    creation_disposition;
 | 
				
			||||||
@@ -176,7 +182,8 @@ neverinline GEN_FILE_OPEN_PROC( _win32_file_open )
 | 
				
			|||||||
#else    // POSIX
 | 
					#else    // POSIX
 | 
				
			||||||
#	include <fcntl.h>
 | 
					#	include <fcntl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_SEEK_PROC( _posix_file_seek )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_SEEK_PROC( _posix_file_seek )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#	if defined( GEN_SYSTEM_OSX )
 | 
					#	if defined( GEN_SYSTEM_OSX )
 | 
				
			||||||
	s64 res = lseek( fd.i, offset, whence );
 | 
						s64 res = lseek( fd.i, offset, whence );
 | 
				
			||||||
@@ -190,10 +197,11 @@ internal GEN_FILE_SEEK_PROC( _posix_file_seek )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_READ_AT_PROC( _posix_file_read )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_READ_AT_PROC( _posix_file_read )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unused( stop_at_newline );
 | 
						unused( stop_at_newline );
 | 
				
			||||||
	sw res = pread( fd.i, buffer, size, offset );
 | 
						ssize res = pread( fd.i, buffer, size, offset );
 | 
				
			||||||
	if ( res < 0 )
 | 
						if ( res < 0 )
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	if ( bytes_read )
 | 
						if ( bytes_read )
 | 
				
			||||||
@@ -201,19 +209,20 @@ internal GEN_FILE_READ_AT_PROC( _posix_file_read )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_WRITE_AT_PROC( _posix_file_write )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_WRITE_AT_PROC( _posix_file_write )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw  res;
 | 
						ssize  res;
 | 
				
			||||||
	s64 curr_offset = 0;
 | 
						s64 curr_offset = 0;
 | 
				
			||||||
	_posix_file_seek( fd, 0, ESeekWhence_CURRENT, &curr_offset );
 | 
						_posix_file_seek( fd, 0, ESeekWhence_CURRENT, &curr_offset );
 | 
				
			||||||
	if ( curr_offset == offset )
 | 
						if ( curr_offset == offset )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// NOTE: Writing to stdout et al. doesn't like pwrite for numerous reasons
 | 
							// NOTE: Writing to stdout et al. doesn't like pwrite for numerous reasons
 | 
				
			||||||
		res = write( zpl_cast( int ) fd.i, buffer, size );
 | 
							res = write( scast( int, fd.i), buffer, size );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		res = pwrite( zpl_cast( int ) fd.i, buffer, size, offset );
 | 
							res = pwrite( scast( int, fd.i), buffer, size, offset );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ( res < 0 )
 | 
						if ( res < 0 )
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
@@ -222,14 +231,16 @@ internal GEN_FILE_WRITE_AT_PROC( _posix_file_write )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_CLOSE_PROC( _posix_file_close )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_CLOSE_PROC( _posix_file_close )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	close( fd.i );
 | 
						close( fd.i );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FileOperations const default_file_operations = { _posix_file_read, _posix_file_write, _posix_file_seek, _posix_file_close };
 | 
					FileOperations const default_file_operations = { _posix_file_read, _posix_file_write, _posix_file_seek, _posix_file_close };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
neverinline GEN_FILE_OPEN_PROC( _posix_file_open )
 | 
					neverinline
 | 
				
			||||||
 | 
					GEN_FILE_OPEN_PROC( _posix_file_open )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	s32 os_mode;
 | 
						s32 os_mode;
 | 
				
			||||||
	switch ( mode & GEN_FILE_MODES )
 | 
						switch ( mode & GEN_FILE_MODES )
 | 
				
			||||||
@@ -329,7 +340,7 @@ FileError file_close( FileInfo* f )
 | 
				
			|||||||
		return EFileError_INVALID;
 | 
							return EFileError_INVALID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( f->filename )
 | 
						if ( f->filename )
 | 
				
			||||||
		free( heap(), zpl_cast( char* ) f->filename );
 | 
							free( heap(), ccast( char*, f->filename ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined( GEN_SYSTEM_WINDOWS )
 | 
					#if defined( GEN_SYSTEM_WINDOWS )
 | 
				
			||||||
	if ( f->fd.p == INVALID_HANDLE_VALUE )
 | 
						if ( f->fd.p == INVALID_HANDLE_VALUE )
 | 
				
			||||||
@@ -364,14 +375,14 @@ FileError file_close( FileInfo* f )
 | 
				
			|||||||
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
 | 
					FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FileError err = EFileError_NONE;
 | 
						FileError err = EFileError_NONE;
 | 
				
			||||||
	sw        len = str_len( filename );
 | 
						ssize        len = str_len( filename );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	f->ops             = ops;
 | 
						f->ops             = ops;
 | 
				
			||||||
	f->fd              = fd;
 | 
						f->fd              = fd;
 | 
				
			||||||
	f->dir             = nullptr;
 | 
						f->dir             = nullptr;
 | 
				
			||||||
	f->last_write_time = 0;
 | 
						f->last_write_time = 0;
 | 
				
			||||||
	f->filename        = alloc_array( heap(), char, len + 1 );
 | 
						f->filename        = alloc_array( heap(), char, len + 1 );
 | 
				
			||||||
	mem_copy( zpl_cast( char* ) f->filename, zpl_cast( char* ) filename, len + 1 );
 | 
						mem_copy( ccast( char*, f->filename), ccast( char*, filename), len + 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -430,7 +441,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ( file_open( &file, filepath ) == EFileError_NONE )
 | 
						if ( file_open( &file, filepath ) == EFileError_NONE )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw fsize = zpl_cast( sw ) file_size( &file );
 | 
							ssize fsize = scast( ssize , file_size( &file ));
 | 
				
			||||||
		if ( fsize > 0 )
 | 
							if ( fsize > 0 )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			result.data = alloc( a, zero_terminate ? fsize + 1 : fsize );
 | 
								result.data = alloc( a, zero_terminate ? fsize + 1 : fsize );
 | 
				
			||||||
@@ -438,7 +449,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
 | 
				
			|||||||
			file_read_at( &file, result.data, result.size, 0 );
 | 
								file_read_at( &file, result.data, result.size, 0 );
 | 
				
			||||||
			if ( zero_terminate )
 | 
								if ( zero_terminate )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				u8* str      = zpl_cast( u8* ) result.data;
 | 
									u8* str      = rcast( u8*, result.data);
 | 
				
			||||||
				str[ fsize ] = '\0';
 | 
									str[ fsize ] = '\0';
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -452,26 +463,28 @@ struct _memory_fd
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	u8            magic;
 | 
						u8            magic;
 | 
				
			||||||
	u8*           buf;    //< zpl_array OR plain buffer if we can't write
 | 
						u8*           buf;    //< zpl_array OR plain buffer if we can't write
 | 
				
			||||||
	sw            cursor;
 | 
						ssize         cursor;
 | 
				
			||||||
	AllocatorInfo allocator;
 | 
						AllocatorInfo allocator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FileStreamFlags flags;
 | 
						FileStreamFlags flags;
 | 
				
			||||||
	sw              cap;
 | 
						ssize           cap;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN__FILE_STREAM_FD_MAGIC 37
 | 
					#define GEN__FILE_STREAM_FD_MAGIC 37
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d );
 | 
					FileDescriptor _file_stream_fd_make( _memory_fd* d );
 | 
				
			||||||
GEN_DEF_INLINE _memory_fd*    _file_stream_from_fd( FileDescriptor fd );
 | 
					_memory_fd*    _file_stream_from_fd( FileDescriptor fd );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d )
 | 
					inline
 | 
				
			||||||
 | 
					FileDescriptor _file_stream_fd_make( _memory_fd* d )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FileDescriptor fd = { 0 };
 | 
						FileDescriptor fd = { 0 };
 | 
				
			||||||
	fd.p              = ( void* )d;
 | 
						fd.p              = ( void* )d;
 | 
				
			||||||
	return fd;
 | 
						return fd;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd )
 | 
					inline
 | 
				
			||||||
 | 
					_memory_fd* _file_stream_from_fd( FileDescriptor fd )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	_memory_fd* d = ( _memory_fd* )fd.p;
 | 
						_memory_fd* d = ( _memory_fd* )fd.p;
 | 
				
			||||||
	GEN_ASSERT( d->magic == GEN__FILE_STREAM_FD_MAGIC );
 | 
						GEN_ASSERT( d->magic == GEN__FILE_STREAM_FD_MAGIC );
 | 
				
			||||||
@@ -506,7 +519,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags )
 | 
					b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( file );
 | 
						GEN_ASSERT_NOT_NULL( file );
 | 
				
			||||||
	_memory_fd* d = ( _memory_fd* )alloc( allocator, size_of( _memory_fd ) );
 | 
						_memory_fd* d = ( _memory_fd* )alloc( allocator, size_of( _memory_fd ) );
 | 
				
			||||||
@@ -543,7 +556,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw siz
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u8* file_stream_buf( FileInfo* file, sw* size )
 | 
					u8* file_stream_buf( FileInfo* file, ssize* size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( file );
 | 
						GEN_ASSERT_NOT_NULL( file );
 | 
				
			||||||
	_memory_fd* d = _file_stream_from_fd( file->fd );
 | 
						_memory_fd* d = _file_stream_from_fd( file->fd );
 | 
				
			||||||
@@ -552,10 +565,11 @@ u8* file_stream_buf( FileInfo* file, sw* size )
 | 
				
			|||||||
	return d->buf;
 | 
						return d->buf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_SEEK_PROC( _memory_file_seek )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_SEEK_PROC( _memory_file_seek )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	_memory_fd* d      = _file_stream_from_fd( fd );
 | 
						_memory_fd* d      = _file_stream_from_fd( fd );
 | 
				
			||||||
	sw          buflen = d->cap;
 | 
						ssize          buflen = d->cap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( whence == ESeekWhence_BEGIN )
 | 
						if ( whence == ESeekWhence_BEGIN )
 | 
				
			||||||
		d->cursor = 0;
 | 
							d->cursor = 0;
 | 
				
			||||||
@@ -568,7 +582,8 @@ internal GEN_FILE_SEEK_PROC( _memory_file_seek )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_READ_AT_PROC( _memory_file_read )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_READ_AT_PROC( _memory_file_read )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// unused( stop_at_newline );
 | 
						// unused( stop_at_newline );
 | 
				
			||||||
	_memory_fd* d = _file_stream_from_fd( fd );
 | 
						_memory_fd* d = _file_stream_from_fd( fd );
 | 
				
			||||||
@@ -578,23 +593,24 @@ internal GEN_FILE_READ_AT_PROC( _memory_file_read )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_WRITE_AT_PROC( _memory_file_write )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	_memory_fd* d = _file_stream_from_fd( fd );
 | 
						_memory_fd* d = _file_stream_from_fd( fd );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ! ( d->flags & ( EFileStream_CLONE_WRITABLE | EFileStream_WRITABLE ) ) )
 | 
						if ( ! ( d->flags & ( EFileStream_CLONE_WRITABLE | EFileStream_WRITABLE ) ) )
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw buflen   = d->cap;
 | 
						ssize buflen   = d->cap;
 | 
				
			||||||
	sw extralen = max( 0, size - ( buflen - offset ) );
 | 
						ssize extralen = max( 0, size - ( buflen - offset ) );
 | 
				
			||||||
	sw rwlen    = size - extralen;
 | 
						ssize rwlen    = size - extralen;
 | 
				
			||||||
	sw new_cap  = buflen + extralen;
 | 
						ssize new_cap  = buflen + extralen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( d->flags & EFileStream_CLONE_WRITABLE )
 | 
						if ( d->flags & EFileStream_CLONE_WRITABLE )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Array<u8> arr = { d->buf };
 | 
							Array<u8> arr = { d->buf };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( arr.get_header()->Capacity < new_cap )
 | 
							if ( arr.get_header()->Capacity < usize(new_cap) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ! arr.grow( ( s64 )( new_cap ) ) )
 | 
								if ( ! arr.grow( ( s64 )( new_cap ) ) )
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
@@ -622,7 +638,8 @@ internal GEN_FILE_WRITE_AT_PROC( _memory_file_write )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal GEN_FILE_CLOSE_PROC( _memory_file_close )
 | 
					internal
 | 
				
			||||||
 | 
					GEN_FILE_CLOSE_PROC( _memory_file_close )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	_memory_fd*   d         = _file_stream_from_fd( fd );
 | 
						_memory_fd*   d         = _file_stream_from_fd( fd );
 | 
				
			||||||
	AllocatorInfo allocator = d->allocator;
 | 
						AllocatorInfo allocator = d->allocator;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,8 +48,8 @@ union FileDescriptor
 | 
				
			|||||||
typedef struct FileOperations FileOperations;
 | 
					typedef struct FileOperations FileOperations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN_FILE_OPEN_PROC( name )     FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
 | 
					#define GEN_FILE_OPEN_PROC( name )     FileError name( FileDescriptor* fd, FileOperations* ops, FileMode mode, char const* filename )
 | 
				
			||||||
#define GEN_FILE_READ_AT_PROC( name )  b32 name( FileDescriptor fd, void* buffer, sw size, s64 offset, sw* bytes_read, b32 stop_at_newline )
 | 
					#define GEN_FILE_READ_AT_PROC( name )  b32 name( FileDescriptor fd, void* buffer, ssize size, s64 offset, ssize* bytes_read, b32 stop_at_newline )
 | 
				
			||||||
#define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, sw size, s64 offset, sw* bytes_written )
 | 
					#define GEN_FILE_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, ssize size, s64 offset, ssize* bytes_written )
 | 
				
			||||||
#define GEN_FILE_SEEK_PROC( name )     b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset )
 | 
					#define GEN_FILE_SEEK_PROC( name )     b32 name( FileDescriptor fd, s64 offset, SeekWhenceType whence, s64* new_offset )
 | 
				
			||||||
#define GEN_FILE_CLOSE_PROC( name )    void name( FileDescriptor fd )
 | 
					#define GEN_FILE_CLOSE_PROC( name )    void name( FileDescriptor fd )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -161,7 +161,7 @@ FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
 | 
				
			|||||||
	* @param  buffer Buffer to read to
 | 
						* @param  buffer Buffer to read to
 | 
				
			||||||
	* @param  size   Size to read
 | 
						* @param  size   Size to read
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size );
 | 
					b32 file_read( FileInfo* file, void* buffer, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Reads file at a specific offset
 | 
						* Reads file at a specific offset
 | 
				
			||||||
@@ -171,7 +171,7 @@ GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size );
 | 
				
			|||||||
	* @param  offset     Offset to read from
 | 
						* @param  offset     Offset to read from
 | 
				
			||||||
	* @param  bytes_read How much data we've actually read
 | 
						* @param  bytes_read How much data we've actually read
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offset );
 | 
					b32 file_read_at( FileInfo* file, void* buffer, ssize size, s64 offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Reads file safely
 | 
						* Reads file safely
 | 
				
			||||||
@@ -181,13 +181,13 @@ GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offs
 | 
				
			|||||||
	* @param  offset     Offset to read from
 | 
						* @param  offset     Offset to read from
 | 
				
			||||||
	* @param  bytes_read How much data we've actually read
 | 
						* @param  bytes_read How much data we've actually read
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_read_at_check( FileInfo* file, void* buffer, sw size, s64 offset, sw* bytes_read );
 | 
					b32 file_read_at_check( FileInfo* file, void* buffer, ssize size, s64 offset, ssize* bytes_read );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct FileContents
 | 
					struct FileContents
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	AllocatorInfo allocator;
 | 
						AllocatorInfo allocator;
 | 
				
			||||||
	void*         data;
 | 
						void*         data;
 | 
				
			||||||
	sw            size;
 | 
						ssize            size;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr b32 zero_terminate    = true;
 | 
					constexpr b32 zero_terminate    = true;
 | 
				
			||||||
@@ -214,20 +214,20 @@ s64 file_size( FileInfo* file );
 | 
				
			|||||||
	* @param  file
 | 
						* @param  file
 | 
				
			||||||
	* @param  offset Offset to seek to
 | 
						* @param  offset Offset to seek to
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE s64 file_seek( FileInfo* file, s64 offset );
 | 
					s64 file_seek( FileInfo* file, s64 offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Seeks the file cursor to the end of the file
 | 
						* Seeks the file cursor to the end of the file
 | 
				
			||||||
	* @param  file
 | 
						* @param  file
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE s64 file_seek_to_end( FileInfo* file );
 | 
					s64 file_seek_to_end( FileInfo* file );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Returns the length from the beginning of the file we've read so far
 | 
						* Returns the length from the beginning of the file we've read so far
 | 
				
			||||||
	* @param  file
 | 
						* @param  file
 | 
				
			||||||
	* @return      Our current position in file
 | 
						* @return      Our current position in file
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE s64 file_tell( FileInfo* file );
 | 
					s64 file_tell( FileInfo* file );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Writes to a file
 | 
						* Writes to a file
 | 
				
			||||||
@@ -235,7 +235,7 @@ GEN_DEF_INLINE s64 file_tell( FileInfo* file );
 | 
				
			|||||||
	* @param  buffer Buffer to read from
 | 
						* @param  buffer Buffer to read from
 | 
				
			||||||
	* @param  size   Size to read
 | 
						* @param  size   Size to read
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size );
 | 
					b32 file_write( FileInfo* file, void const* buffer, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Writes to file at a specific offset
 | 
						* Writes to file at a specific offset
 | 
				
			||||||
@@ -245,7 +245,7 @@ GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size );
 | 
				
			|||||||
	* @param  offset        Offset to write to
 | 
						* @param  offset        Offset to write to
 | 
				
			||||||
	* @param  bytes_written How much data we've actually written
 | 
						* @param  bytes_written How much data we've actually written
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s64 offset );
 | 
					b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Writes to file safely
 | 
						* Writes to file safely
 | 
				
			||||||
@@ -255,86 +255,7 @@ GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s
 | 
				
			|||||||
	* @param  offset        Offset to write to
 | 
						* @param  offset        Offset to write to
 | 
				
			||||||
	* @param  bytes_written How much data we've actually written
 | 
						* @param  bytes_written How much data we've actually written
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
GEN_DEF_INLINE b32 file_write_at_check( FileInfo* file, void const* buffer, sw size, s64 offset, sw* bytes_written );
 | 
					b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written );
 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE s64 file_seek( FileInfo* f, s64 offset )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	s64 new_offset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( ! f->ops.read_at )
 | 
					 | 
				
			||||||
		f->ops = default_file_operations;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return new_offset;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE s64 file_seek_to_end( FileInfo* f )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	s64 new_offset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( ! f->ops.read_at )
 | 
					 | 
				
			||||||
		f->ops = default_file_operations;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return new_offset;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE s64 file_tell( FileInfo* f )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	s64 new_offset = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( ! f->ops.read_at )
 | 
					 | 
				
			||||||
		f->ops = default_file_operations;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return new_offset;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_read( FileInfo* f, void* buffer, sw size )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	s64 cur_offset = file_tell( f );
 | 
					 | 
				
			||||||
	b32 result     = file_read_at( f, buffer, size, file_tell( f ) );
 | 
					 | 
				
			||||||
	file_seek( f, cur_offset + size );
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_read_at( FileInfo* f, void* buffer, sw size, s64 offset )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return file_read_at_check( f, buffer, size, offset, NULL );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_read_at_check( FileInfo* f, void* buffer, sw size, s64 offset, sw* bytes_read )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( ! f->ops.read_at )
 | 
					 | 
				
			||||||
		f->ops = default_file_operations;
 | 
					 | 
				
			||||||
	return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_write( FileInfo* f, void const* buffer, sw size )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	s64 cur_offset = file_tell( f );
 | 
					 | 
				
			||||||
	b32 result     = file_write_at( f, buffer, size, file_tell( f ) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	file_seek( f, cur_offset + size );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return result;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_write_at( FileInfo* f, void const* buffer, sw size, s64 offset )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return file_write_at_check( f, buffer, size, offset, NULL );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE b32 file_write_at_check( FileInfo* f, void const* buffer, sw size, s64 offset, sw* bytes_written )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( ! f->ops.read_at )
 | 
					 | 
				
			||||||
		f->ops = default_file_operations;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum FileStreamFlags : u32
 | 
					enum FileStreamFlags : u32
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -361,15 +282,103 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
 | 
				
			|||||||
	* @param  size     Buffer's size
 | 
						* @param  size     Buffer's size
 | 
				
			||||||
	* @param  flags
 | 
						* @param  flags
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags );
 | 
					b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* Retrieves the stream's underlying buffer and buffer size.
 | 
						* Retrieves the stream's underlying buffer and buffer size.
 | 
				
			||||||
	* @param file memory stream
 | 
						* @param file memory stream
 | 
				
			||||||
	* @param size (Optional) buffer size
 | 
						* @param size (Optional) buffer size
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
u8* file_stream_buf( FileInfo* file, sw* size );
 | 
					u8* file_stream_buf( FileInfo* file, ssize* size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern FileOperations const memory_file_operations;
 | 
					extern FileOperations const memory_file_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					s64 file_seek( FileInfo* f, s64 offset )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s64 new_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ! f->ops.read_at )
 | 
				
			||||||
 | 
							f->ops = default_file_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f->ops.seek( f->fd, offset, ESeekWhence_BEGIN, &new_offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return new_offset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					s64 file_seek_to_end( FileInfo* f )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s64 new_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ! f->ops.read_at )
 | 
				
			||||||
 | 
							f->ops = default_file_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f->ops.seek( f->fd, 0, ESeekWhence_END, &new_offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return new_offset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					s64 file_tell( FileInfo* f )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s64 new_offset = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( ! f->ops.read_at )
 | 
				
			||||||
 | 
							f->ops = default_file_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						f->ops.seek( f->fd, 0, ESeekWhence_CURRENT, &new_offset );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return new_offset;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_read( FileInfo* f, void* buffer, ssize size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s64 cur_offset = file_tell( f );
 | 
				
			||||||
 | 
						b32 result     = file_read_at( f, buffer, size, file_tell( f ) );
 | 
				
			||||||
 | 
						file_seek( f, cur_offset + size );
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_read_at( FileInfo* f, void* buffer, ssize size, s64 offset )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return file_read_at_check( f, buffer, size, offset, NULL );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_read_at_check( FileInfo* f, void* buffer, ssize size, s64 offset, ssize* bytes_read )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( ! f->ops.read_at )
 | 
				
			||||||
 | 
							f->ops = default_file_operations;
 | 
				
			||||||
 | 
						return f->ops.read_at( f->fd, buffer, size, offset, bytes_read, false );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_write( FileInfo* f, void const* buffer, ssize size )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						s64 cur_offset = file_tell( f );
 | 
				
			||||||
 | 
						b32 result     = file_write_at( f, buffer, size, file_tell( f ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						file_seek( f, cur_offset + size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_write_at( FileInfo* f, void const* buffer, ssize size, s64 offset )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return file_write_at_check( f, buffer, size, offset, NULL );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 file_write_at_check( FileInfo* f, void const* buffer, ssize size, s64 offset, ssize* bytes_written )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( ! f->ops.read_at )
 | 
				
			||||||
 | 
							f->ops = default_file_operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return f->ops.write_at( f->fd, buffer, size, offset, bytes_written );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion File Handling
 | 
					#pragma endregion File Handling
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,11 +27,11 @@ global u32 const _crc32_table[ 256 ] = {
 | 
				
			|||||||
	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
 | 
						0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u32 crc32( void const* data, sw len )
 | 
					u32 crc32( void const* data, ssize len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw        remaining;
 | 
						ssize        remaining;
 | 
				
			||||||
	u32       result = ~( zpl_cast( u32 ) 0 );
 | 
						u32       result = ~( scast( u32, 0) );
 | 
				
			||||||
	u8 const* c      = zpl_cast( u8 const* ) data;
 | 
						u8 const* c      = rcast( u8 const*, data);
 | 
				
			||||||
	for ( remaining = len; remaining--; c++ )
 | 
						for ( remaining = len; remaining--; c++ )
 | 
				
			||||||
		result = ( result >> 8 ) ^ ( _crc32_table[ ( result ^ *c ) & 0xff ] );
 | 
							result = ( result >> 8 ) ^ ( _crc32_table[ ( result ^ *c ) & 0xff ] );
 | 
				
			||||||
	return ~result;
 | 
						return ~result;
 | 
				
			||||||
@@ -77,11 +77,11 @@ global u64 const _crc64_table[ 256 ] = {
 | 
				
			|||||||
	0xa6df411fbfb21ca3ull, 0xdc0731d78f8795daull, 0x536fa08fdfd90e51ull, 0x29b7d047efec8728ull,
 | 
						0xa6df411fbfb21ca3ull, 0xdc0731d78f8795daull, 0x536fa08fdfd90e51ull, 0x29b7d047efec8728ull,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u64 crc64( void const* data, sw len )
 | 
					u64 crc64( void const* data, ssize len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw        remaining;
 | 
						ssize        remaining;
 | 
				
			||||||
	u64       result = ( zpl_cast( u64 ) 0 );
 | 
						u64       result = ( scast( u64, 0) );
 | 
				
			||||||
	u8 const* c      = zpl_cast( u8 const* ) data;
 | 
						u8 const* c      = rcast( u8 const*, data);
 | 
				
			||||||
	for ( remaining = len; remaining--; c++ )
 | 
						for ( remaining = len; remaining--; c++ )
 | 
				
			||||||
		result = ( result >> 8 ) ^ ( _crc64_table[ ( result ^ *c ) & 0xff ] );
 | 
							result = ( result >> 8 ) ^ ( _crc64_table[ ( result ^ *c ) & 0xff ] );
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region Hashing
 | 
					#pragma region Hashing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
u32 crc32( void const* data, sw len );
 | 
					u32 crc32( void const* data, ssize len );
 | 
				
			||||||
u64 crc64( void const* data, sw len );
 | 
					u64 crc64( void const* data, ssize len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion Hashing
 | 
					#pragma endregion Hashing
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,52 +1,77 @@
 | 
				
			|||||||
#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
					#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
				
			||||||
#   pragma once
 | 
					#   pragma once
 | 
				
			||||||
#	include "header_start.hpp"
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region Macros
 | 
					#pragma region Macros
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define zpl_cast( Type ) ( Type )
 | 
					#ifndef global
 | 
				
			||||||
 | 
					 | 
				
			||||||
// Keywords
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define global        static    // Global variables
 | 
					#define global        static    // Global variables
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef internal
 | 
				
			||||||
#define internal      static    // Internal linkage
 | 
					#define internal      static    // Internal linkage
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef local_persist
 | 
				
			||||||
#define local_persist static    // Local Persisting variables
 | 
					#define local_persist static    // Local Persisting variables
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef GEN_COMPILER_MSVC
 | 
					 | 
				
			||||||
#	define forceinline __forceinline
 | 
					 | 
				
			||||||
#	define neverinline __declspec( noinline )
 | 
					 | 
				
			||||||
#elif defined(GEN_COMPILER_GCC)
 | 
					 | 
				
			||||||
#	define forceinline inline __attribute__((__always_inline__))
 | 
					 | 
				
			||||||
#	define neverinline __attribute__( ( __noinline__ ) )
 | 
					 | 
				
			||||||
#elif defined(GEN_COMPILER_CLANG)
 | 
					 | 
				
			||||||
#if __has_attribute(__always_inline__)
 | 
					 | 
				
			||||||
#	define forceinline inline __attribute__((__always_inline__))
 | 
					 | 
				
			||||||
#	define neverinline __attribute__( ( __noinline__ ) )
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	define forceinline
 | 
					 | 
				
			||||||
#	define neverinline
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
#	define forceinline
 | 
					 | 
				
			||||||
#	define neverinline
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Bits
 | 
					#ifndef api_c
 | 
				
			||||||
 | 
					#define api_c extern "C"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef bit
 | 
				
			||||||
#define bit( Value )                             ( 1 << Value )
 | 
					#define bit( Value )                             ( 1 << Value )
 | 
				
			||||||
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
 | 
					#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Casting
 | 
					#ifndef ccast
 | 
				
			||||||
 | 
					#define ccast( type, value ) ( const_cast< type >( (value) ) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef pcast
 | 
				
			||||||
 | 
					#define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef rcast
 | 
				
			||||||
 | 
					#define rcast( type, value ) reinterpret_cast< type >( value )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef scast
 | 
				
			||||||
 | 
					#define scast( type, value ) static_cast< type >( value )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) )
 | 
					#ifndef stringize
 | 
				
			||||||
#define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) )
 | 
					#define stringize_va( ... ) #__VA_ARGS__
 | 
				
			||||||
#define rcast( Type, Value ) reinterpret_cast< Type >( Value )
 | 
					#define stringize( ... )    stringize_va( __VA_ARGS__ )
 | 
				
			||||||
#define scast( Type, Value ) static_cast< Type >( Value )
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Num Arguments (Varadics)
 | 
					#ifndef do_once
 | 
				
			||||||
// #if defined(__GNUC__) || defined(__clang__)
 | 
					#define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) )
 | 
				
			||||||
// Supports 0-50 arguments
 | 
					
 | 
				
			||||||
 | 
					#define do_once_start      \
 | 
				
			||||||
 | 
						do                     \
 | 
				
			||||||
 | 
						{                      \
 | 
				
			||||||
 | 
							local_persist      \
 | 
				
			||||||
 | 
							bool done = false; \
 | 
				
			||||||
 | 
							if ( done )        \
 | 
				
			||||||
 | 
								break;         \
 | 
				
			||||||
 | 
							done = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define do_once_end        \
 | 
				
			||||||
 | 
						}                      \
 | 
				
			||||||
 | 
						while(0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef labeled_scope_start
 | 
				
			||||||
 | 
					#define labeled_scope_start if ( false ) {
 | 
				
			||||||
 | 
					#define labeled_scope_end   }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef         compiler_decorated_func_name
 | 
				
			||||||
 | 
					#   ifdef COMPILER_CLANG
 | 
				
			||||||
 | 
					#       define  compiler_decorated_func_name __PRETTY_NAME__
 | 
				
			||||||
 | 
					#   elif defined(COMPILER_MSVC)
 | 
				
			||||||
 | 
					#   	define compiler_decorated_func_name __FUNCDNAME__
 | 
				
			||||||
 | 
					#   endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef num_args_impl
 | 
				
			||||||
#define num_args_impl( _0,                                 \
 | 
					#define num_args_impl( _0,                                 \
 | 
				
			||||||
		_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10,   \
 | 
							_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10,   \
 | 
				
			||||||
		_11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \
 | 
							_11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \
 | 
				
			||||||
@@ -76,93 +101,69 @@
 | 
				
			|||||||
		 10,  9,  8,  7,  6,  5,  4,  3,  2,  1, \
 | 
							 10,  9,  8,  7,  6,  5,  4,  3,  2,  1, \
 | 
				
			||||||
		 0                                       \
 | 
							 0                                       \
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// #else
 | 
					#ifndef clamp
 | 
				
			||||||
// This doesn't work on latest msvc so I had to use /Zc:preprocessor flag.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Supports 1-50 arguments
 | 
					 | 
				
			||||||
// #define num_args_impl(                                  \
 | 
					 | 
				
			||||||
// 		_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9, _10,   \
 | 
					 | 
				
			||||||
// 		_11, _12, _13, _14, _15, _16, _17, _18, _19, _20,  \
 | 
					 | 
				
			||||||
// 		_21, _22, _23, _24, _25, _26, _27, _28, _29, _30,  \
 | 
					 | 
				
			||||||
// 		_31, _32, _33, _34, _35, _36, _37, _38, _39, _40,  \
 | 
					 | 
				
			||||||
// 		_41, _42, _43, _44, _45, _46, _47, _48, _49, _50,  \
 | 
					 | 
				
			||||||
// 		_51, _52, _53, _54, _55, _56, _57, _58, _59, _60,  \
 | 
					 | 
				
			||||||
// 		_61, _62, _63, _64, _65, _66, _67, _68, _69, _70,  \
 | 
					 | 
				
			||||||
// 		_71, _72, _73, _74, _75, _76, _77, _78, _79, _80,  \
 | 
					 | 
				
			||||||
// 		_81, _82, _83, _84, _85, _86, _87, _88, _89, _90,  \
 | 
					 | 
				
			||||||
// 		_91, _92, _93, _94, _95, _96, _97, _98, _99, _100, \
 | 
					 | 
				
			||||||
// 		N, ...                                             \
 | 
					 | 
				
			||||||
// 	) N
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// #define num_args(...)                         \
 | 
					 | 
				
			||||||
// 	num_args_impl( __VA_ARGS__,                  \
 | 
					 | 
				
			||||||
// 		100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
 | 
					 | 
				
			||||||
// 		 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, \
 | 
					 | 
				
			||||||
// 		 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, \
 | 
					 | 
				
			||||||
// 		 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, \
 | 
					 | 
				
			||||||
// 		 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
 | 
					 | 
				
			||||||
// 		 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
 | 
					 | 
				
			||||||
// 		 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
 | 
					 | 
				
			||||||
// 		 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
 | 
					 | 
				
			||||||
// 		 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
 | 
					 | 
				
			||||||
// 		 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
 | 
					 | 
				
			||||||
// 		 10,  9,  8,  7,  6,  5,  4,  3,  2,  1  \
 | 
					 | 
				
			||||||
// 	)
 | 
					 | 
				
			||||||
// #endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Stringizing
 | 
					 | 
				
			||||||
#define stringize_va( ... ) #__VA_ARGS__
 | 
					 | 
				
			||||||
#define stringize( ... )    stringize_va( __VA_ARGS__ )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Function do once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define do_once()          \
 | 
					 | 
				
			||||||
	do                     \
 | 
					 | 
				
			||||||
	{                      \
 | 
					 | 
				
			||||||
		static             \
 | 
					 | 
				
			||||||
		bool Done = false; \
 | 
					 | 
				
			||||||
		if ( Done )        \
 | 
					 | 
				
			||||||
			return;        \
 | 
					 | 
				
			||||||
		Done = true;       \
 | 
					 | 
				
			||||||
	}                      \
 | 
					 | 
				
			||||||
	while(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define do_once_start      \
 | 
					 | 
				
			||||||
	do                     \
 | 
					 | 
				
			||||||
	{                      \
 | 
					 | 
				
			||||||
		static             \
 | 
					 | 
				
			||||||
		bool Done = false; \
 | 
					 | 
				
			||||||
		if ( Done )        \
 | 
					 | 
				
			||||||
			break;         \
 | 
					 | 
				
			||||||
		Done = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define do_once_end        \
 | 
					 | 
				
			||||||
	}                      \
 | 
					 | 
				
			||||||
	while(0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define labeled_scope_start if ( false ) {
 | 
					 | 
				
			||||||
#define labeled_scope_end   }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define clamp( x, lower, upper )      min( max( ( x ), ( lower ) ), ( upper ) )
 | 
					#define clamp( x, lower, upper )      min( max( ( x ), ( lower ) ), ( upper ) )
 | 
				
			||||||
#define count_of( x )                 ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( sw )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) )
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef count_of
 | 
				
			||||||
 | 
					#define count_of( x )                 ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( ssize )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef is_between
 | 
				
			||||||
#define is_between( x, lower, upper ) ( ( ( lower ) <= ( x ) ) && ( ( x ) <= ( upper ) ) )
 | 
					#define is_between( x, lower, upper ) ( ( ( lower ) <= ( x ) ) && ( ( x ) <= ( upper ) ) )
 | 
				
			||||||
#define max( a, b )                   ( ( a ) > ( b ) ? ( a ) : ( b ) )
 | 
					#endif
 | 
				
			||||||
#define min( a, b )                   ( ( a ) < ( b ) ? ( a ) : ( b ) )
 | 
					#ifndef size_of
 | 
				
			||||||
#define size_of( x )                  ( sw )( sizeof( x ) )
 | 
					#define size_of( x )                  ( ssize )( sizeof( x ) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef max
 | 
				
			||||||
 | 
					#define max( a, b ) ( (a > b) ? (a) : (b) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#ifndef min
 | 
				
			||||||
 | 
					#define min( a, b ) ( (a < b) ? (a) : (b) )
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined( _MSC_VER ) || defined( GEN_COMPILER_TINYC )
 | 
					#if defined( _MSC_VER ) || defined( GEN_COMPILER_TINYC )
 | 
				
			||||||
#	define offset_of( Type, element ) ( ( GEN_NS( gen_sw ) ) & ( ( ( Type* )0 )->element ) )
 | 
					#	define offset_of( Type, element ) ( ( GEN_NS( ssize ) ) & ( ( ( Type* )0 )->element ) )
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#	define offset_of( Type, element ) __builtin_offsetof( Type, element )
 | 
					#	define offset_of( Type, element ) __builtin_offsetof( Type, element )
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template< class Type >
 | 
					#ifndef        forceinline
 | 
				
			||||||
void swap( Type& a, Type& b )
 | 
					#	ifdef GEN_COMPILER_MSVC
 | 
				
			||||||
{
 | 
					#		define forceinline __forceinline
 | 
				
			||||||
	Type tmp = a;
 | 
					#		define neverinline __declspec( noinline )
 | 
				
			||||||
	a = b;
 | 
					#	elif defined(GEN_COMPILER_GCC)
 | 
				
			||||||
	b = tmp;
 | 
					#		define forceinline inline __attribute__((__always_inline__))
 | 
				
			||||||
}
 | 
					#		define neverinline __attribute__( ( __noinline__ ) )
 | 
				
			||||||
 | 
					#	elif defined(GEN_COMPILER_CLANG)
 | 
				
			||||||
 | 
					#	if __has_attribute(__always_inline__)
 | 
				
			||||||
 | 
					#		define forceinline inline __attribute__((__always_inline__))
 | 
				
			||||||
 | 
					#		define neverinline __attribute__( ( __noinline__ ) )
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
					#		define forceinline
 | 
				
			||||||
 | 
					#		define neverinline
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
					#		define forceinline
 | 
				
			||||||
 | 
					#		define neverinline
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef        neverinline
 | 
				
			||||||
 | 
					#	ifdef GEN_COMPILER_MSVC
 | 
				
			||||||
 | 
					#		define neverinline __declspec( noinline )
 | 
				
			||||||
 | 
					#	elif defined(GEN_COMPILER_GCC)
 | 
				
			||||||
 | 
					#		define neverinline __attribute__( ( __noinline__ ) )
 | 
				
			||||||
 | 
					#	elif defined(GEN_COMPILER_CLANG)
 | 
				
			||||||
 | 
					#	if __has_attribute(__always_inline__)
 | 
				
			||||||
 | 
					#		define neverinline __attribute__( ( __noinline__ ) )
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
					#		define neverinline
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
					#		define neverinline
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion Macros
 | 
					#pragma endregion Macros
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region Memory
 | 
					#pragma region Memory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* mem_copy( void* dest, void const* source, sw n )
 | 
					void* mem_copy( void* dest, void const* source, ssize n )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( dest == NULL )
 | 
						if ( dest == NULL )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -15,25 +15,25 @@ void* mem_copy( void* dest, void const* source, sw n )
 | 
				
			|||||||
	return memcpy( dest, source, n );
 | 
						return memcpy( dest, source, n );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void const* mem_find( void const* data, u8 c, sw n )
 | 
					void const* mem_find( void const* data, u8 c, ssize n )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u8 const* s = zpl_cast( u8 const* ) data;
 | 
						u8 const* s = rcast( u8 const*, data);
 | 
				
			||||||
	while ( ( zpl_cast( uptr ) s & ( sizeof( uw ) - 1 ) ) && n && *s != c )
 | 
						while ( ( rcast( uptr, s) & ( sizeof( usize ) - 1 ) ) && n && *s != c )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		s++;
 | 
							s++;
 | 
				
			||||||
		n--;
 | 
							n--;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if ( n && *s != c )
 | 
						if ( n && *s != c )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw const* w;
 | 
							ssize const* w;
 | 
				
			||||||
		sw        k = GEN__ONES * c;
 | 
							ssize        k = GEN__ONES * c;
 | 
				
			||||||
		w           = zpl_cast( sw const* ) s;
 | 
							w           = rcast( ssize const*, s);
 | 
				
			||||||
		while ( n >= size_of( sw ) && ! GEN__HAS_ZERO( *w ^ k ) )
 | 
							while ( n >= size_of( ssize ) && ! GEN__HAS_ZERO( *w ^ k ) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			w++;
 | 
								w++;
 | 
				
			||||||
			n -= size_of( sw );
 | 
								n -= size_of( ssize );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		s = zpl_cast( u8 const* ) w;
 | 
							s = rcast( u8 const*, w);
 | 
				
			||||||
		while ( n && *s != c )
 | 
							while ( n && *s != c )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			s++;
 | 
								s++;
 | 
				
			||||||
@@ -41,7 +41,7 @@ void const* mem_find( void const* data, u8 c, sw n )
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return n ? zpl_cast( void const* ) s : NULL;
 | 
						return n ? rcast( void const*, s ) : NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
 | 
					#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
 | 
				
			||||||
@@ -49,8 +49,8 @@ void const* mem_find( void const* data, u8 c, sw n )
 | 
				
			|||||||
struct _heap_stats
 | 
					struct _heap_stats
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 magic;
 | 
						u32 magic;
 | 
				
			||||||
	sw  used_memory;
 | 
						ssize  used_memory;
 | 
				
			||||||
	sw  alloc_count;
 | 
						ssize  alloc_count;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
global _heap_stats _heap_stats_info;
 | 
					global _heap_stats _heap_stats_info;
 | 
				
			||||||
@@ -61,13 +61,13 @@ void heap_stats_init( void )
 | 
				
			|||||||
	_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
 | 
						_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw heap_stats_used_memory( void )
 | 
					ssize heap_stats_used_memory( void )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
 | 
						GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
 | 
				
			||||||
	return _heap_stats_info.used_memory;
 | 
						return _heap_stats_info.used_memory;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw heap_stats_alloc_count( void )
 | 
					ssize heap_stats_alloc_count( void )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
 | 
						GEN_ASSERT_MSG( _heap_stats_info.magic == GEN_HEAP_STATS_MAGIC, "heap_stats is not initialised yet, call heap_stats_init first!" );
 | 
				
			||||||
	return _heap_stats_info.alloc_count;
 | 
						return _heap_stats_info.alloc_count;
 | 
				
			||||||
@@ -82,11 +82,11 @@ void heap_stats_check( void )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct _heap_alloc_info
 | 
					struct _heap_alloc_info
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw    size;
 | 
						ssize    size;
 | 
				
			||||||
	void* physical_start;
 | 
						void* physical_start;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
 | 
					void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void* ptr = NULL;
 | 
						void* ptr = NULL;
 | 
				
			||||||
	// unused( allocator_data );
 | 
						// unused( allocator_data );
 | 
				
			||||||
@@ -95,16 +95,16 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
 | 
				
			|||||||
		alignment = GEN_DEFAULT_MEMORY_ALIGNMENT;
 | 
							alignment = GEN_DEFAULT_MEMORY_ALIGNMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GEN_HEAP_ANALYSIS
 | 
					#ifdef GEN_HEAP_ANALYSIS
 | 
				
			||||||
	sw alloc_info_size      = size_of( _heap_alloc_info );
 | 
						ssize alloc_info_size      = size_of( _heap_alloc_info );
 | 
				
			||||||
	sw alloc_info_remainder = ( alloc_info_size % alignment );
 | 
						ssize alloc_info_remainder = ( alloc_info_size % alignment );
 | 
				
			||||||
	sw track_size           = max( alloc_info_size, alignment ) + alloc_info_remainder;
 | 
						ssize track_size           = max( alloc_info_size, alignment ) + alloc_info_remainder;
 | 
				
			||||||
	switch ( type )
 | 
						switch ( type )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		case EAllocation_FREE :
 | 
							case EAllocation_FREE :
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if ( ! old_memory )
 | 
									if ( ! old_memory )
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				_heap_alloc_info* alloc_info  = zpl_cast( _heap_alloc_info* ) old_memory - 1;
 | 
									_heap_alloc_info* alloc_info  = rcast( _heap_alloc_info*, old_memory) - 1;
 | 
				
			||||||
				_heap_stats_info.used_memory -= alloc_info->size;
 | 
									_heap_stats_info.used_memory -= alloc_info->size;
 | 
				
			||||||
				_heap_stats_info.alloc_count--;
 | 
									_heap_stats_info.alloc_count--;
 | 
				
			||||||
				old_memory = alloc_info->physical_start;
 | 
									old_memory = alloc_info->physical_start;
 | 
				
			||||||
@@ -195,11 +195,11 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
 | 
				
			|||||||
#ifdef GEN_HEAP_ANALYSIS
 | 
					#ifdef GEN_HEAP_ANALYSIS
 | 
				
			||||||
	if ( type == EAllocation_ALLOC )
 | 
						if ( type == EAllocation_ALLOC )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* )( zpl_cast( char* ) ptr + alloc_info_remainder );
 | 
							_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder );
 | 
				
			||||||
		zero_item( alloc_info );
 | 
							zero_item( alloc_info );
 | 
				
			||||||
		alloc_info->size              = size - track_size;
 | 
							alloc_info->size              = size - track_size;
 | 
				
			||||||
		alloc_info->physical_start    = ptr;
 | 
							alloc_info->physical_start    = ptr;
 | 
				
			||||||
		ptr                           = zpl_cast( void* )( alloc_info + 1 );
 | 
							ptr                           = rcast( void*, alloc_info + 1 );
 | 
				
			||||||
		_heap_stats_info.used_memory += alloc_info->size;
 | 
							_heap_stats_info.used_memory += alloc_info->size;
 | 
				
			||||||
		_heap_stats_info.alloc_count++;
 | 
							_heap_stats_info.alloc_count++;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -209,7 +209,7 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw ali
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region VirtualMemory
 | 
					#pragma region VirtualMemory
 | 
				
			||||||
VirtualMemory vm_from_memory( void* data, sw size )
 | 
					VirtualMemory vm_from_memory( void* data, ssize size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	VirtualMemory vm;
 | 
						VirtualMemory vm;
 | 
				
			||||||
	vm.data = data;
 | 
						vm.data = data;
 | 
				
			||||||
@@ -218,7 +218,7 @@ VirtualMemory vm_from_memory( void* data, sw size )
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined( GEN_SYSTEM_WINDOWS )
 | 
					#if defined( GEN_SYSTEM_WINDOWS )
 | 
				
			||||||
VirtualMemory vm_alloc( void* addr, sw size )
 | 
					VirtualMemory vm_alloc( void* addr, ssize size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	VirtualMemory vm;
 | 
						VirtualMemory vm;
 | 
				
			||||||
	GEN_ASSERT( size > 0 );
 | 
						GEN_ASSERT( size > 0 );
 | 
				
			||||||
@@ -234,7 +234,7 @@ b32 vm_free( VirtualMemory vm )
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		if ( VirtualQuery( vm.data, &info, size_of( info ) ) == 0 )
 | 
							if ( VirtualQuery( vm.data, &info, size_of( info ) ) == 0 )
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > zpl_cast( uw ) vm.size )
 | 
							if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > scast( usize, vm.size) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -246,7 +246,7 @@ b32 vm_free( VirtualMemory vm )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
 | 
					VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	VirtualMemory new_vm = { 0 };
 | 
						VirtualMemory new_vm = { 0 };
 | 
				
			||||||
	void*             ptr;
 | 
						void*             ptr;
 | 
				
			||||||
@@ -270,7 +270,7 @@ b32 vm_purge( VirtualMemory vm )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw virtual_memory_page_size( sw* alignment_out )
 | 
					ssize virtual_memory_page_size( ssize* alignment_out )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	SYSTEM_INFO info;
 | 
						SYSTEM_INFO info;
 | 
				
			||||||
	GetSystemInfo( &info );
 | 
						GetSystemInfo( &info );
 | 
				
			||||||
@@ -285,7 +285,7 @@ sw virtual_memory_page_size( sw* alignment_out )
 | 
				
			|||||||
#	ifndef MAP_ANONYMOUS
 | 
					#	ifndef MAP_ANONYMOUS
 | 
				
			||||||
#		define MAP_ANONYMOUS MAP_ANON
 | 
					#		define MAP_ANONYMOUS MAP_ANON
 | 
				
			||||||
#	endif
 | 
					#	endif
 | 
				
			||||||
VirtualMemory vm_alloc( void* addr, sw size )
 | 
					VirtualMemory vm_alloc( void* addr, ssize size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	VirtualMemory vm;
 | 
						VirtualMemory vm;
 | 
				
			||||||
	GEN_ASSERT( size > 0 );
 | 
						GEN_ASSERT( size > 0 );
 | 
				
			||||||
@@ -300,10 +300,10 @@ b32 vm_free( VirtualMemory vm )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
 | 
					VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void*  ptr;
 | 
						void*  ptr;
 | 
				
			||||||
	sw trail_size;
 | 
						ssize trail_size;
 | 
				
			||||||
	GEN_ASSERT( vm.size >= lead_size + size );
 | 
						GEN_ASSERT( vm.size >= lead_size + size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ptr        = pointer_add( vm.data, lead_size );
 | 
						ptr        = pointer_add( vm.data, lead_size );
 | 
				
			||||||
@@ -322,10 +322,10 @@ b32 vm_purge( VirtualMemory vm )
 | 
				
			|||||||
	return err != 0;
 | 
						return err != 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw virtual_memory_page_size( sw* alignment_out )
 | 
					ssize virtual_memory_page_size( ssize* alignment_out )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// TODO: Is this always true?
 | 
						// TODO: Is this always true?
 | 
				
			||||||
	sw result = zpl_cast( sw ) sysconf( _SC_PAGE_SIZE );
 | 
						ssize result = scast( ssize, sysconf( _SC_PAGE_SIZE ));
 | 
				
			||||||
	if ( alignment_out )
 | 
						if ( alignment_out )
 | 
				
			||||||
		*alignment_out = result;
 | 
							*alignment_out = result;
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
@@ -334,7 +334,7 @@ sw virtual_memory_page_size( sw* alignment_out )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma endregion VirtualMemory
 | 
					#pragma endregion VirtualMemory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
 | 
					void* Arena::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Arena* arena = rcast(Arena*, allocator_data);
 | 
						Arena* arena = rcast(Arena*, allocator_data);
 | 
				
			||||||
	void*      ptr   = NULL;
 | 
						void*      ptr   = NULL;
 | 
				
			||||||
@@ -346,10 +346,10 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a
 | 
				
			|||||||
		case EAllocation_ALLOC :
 | 
							case EAllocation_ALLOC :
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				void* end        = pointer_add( arena->PhysicalStart, arena->TotalUsed );
 | 
									void* end        = pointer_add( arena->PhysicalStart, arena->TotalUsed );
 | 
				
			||||||
				sw    total_size = align_forward_i64( size, alignment );
 | 
									ssize    total_size = align_forward_i64( size, alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				// NOTE: Out of memory
 | 
									// NOTE: Out of memory
 | 
				
			||||||
				if ( arena->TotalUsed + total_size > (sw) arena->TotalSize )
 | 
									if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					// zpl__printf_err("%s", "Arena out of memory\n");
 | 
										// zpl__printf_err("%s", "Arena out of memory\n");
 | 
				
			||||||
					GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
 | 
										GEN_FATAL("Arena out of memory! (Possibly could not fit for the largest size Arena!!)");
 | 
				
			||||||
@@ -384,9 +384,9 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw a
 | 
				
			|||||||
	return ptr;
 | 
						return ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
 | 
					void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Pool* pool = zpl_cast( Pool* ) allocator_data;
 | 
						Pool* pool = rcast( Pool*, allocator_data);
 | 
				
			||||||
	void* ptr  = NULL;
 | 
						void* ptr  = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// unused( old_size );
 | 
						// unused( old_size );
 | 
				
			||||||
@@ -401,9 +401,9 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
 | 
				
			|||||||
				GEN_ASSERT( alignment == pool->BlockAlign );
 | 
									GEN_ASSERT( alignment == pool->BlockAlign );
 | 
				
			||||||
				GEN_ASSERT( pool->FreeList != NULL );
 | 
									GEN_ASSERT( pool->FreeList != NULL );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				next_free        = *zpl_cast( uptr* ) pool->FreeList;
 | 
									next_free        = * rcast( uptr*, pool->FreeList);
 | 
				
			||||||
				ptr              = pool->FreeList;
 | 
									ptr              = pool->FreeList;
 | 
				
			||||||
				pool->FreeList   = zpl_cast( void* ) next_free;
 | 
									pool->FreeList   = rcast( void*, next_free);
 | 
				
			||||||
				pool->TotalSize += pool->BlockSize;
 | 
									pool->TotalSize += pool->BlockSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
 | 
									if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
 | 
				
			||||||
@@ -417,8 +417,8 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
 | 
				
			|||||||
				if ( old_memory == NULL )
 | 
									if ( old_memory == NULL )
 | 
				
			||||||
					return NULL;
 | 
										return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				next             = zpl_cast( uptr* ) old_memory;
 | 
									next             = rcast( uptr*, old_memory);
 | 
				
			||||||
				*next            = zpl_cast( uptr ) pool->FreeList;
 | 
									*next            = rcast( uptr, pool->FreeList);
 | 
				
			||||||
				pool->FreeList   = old_memory;
 | 
									pool->FreeList   = old_memory;
 | 
				
			||||||
				pool->TotalSize -= pool->BlockSize;
 | 
									pool->TotalSize -= pool->BlockSize;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -426,7 +426,7 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		case EAllocation_FREE_ALL :
 | 
							case EAllocation_FREE_ALL :
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				sw    actual_block_size, block_index;
 | 
									ssize    actual_block_size, block_index;
 | 
				
			||||||
				void* curr;
 | 
									void* curr;
 | 
				
			||||||
				uptr* end;
 | 
									uptr* end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -437,13 +437,13 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
 | 
				
			|||||||
				curr = pool->PhysicalStart;
 | 
									curr = pool->PhysicalStart;
 | 
				
			||||||
				for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
 | 
									for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					uptr* next = zpl_cast( uptr* ) curr;
 | 
										uptr* next = rcast( uptr*, curr);
 | 
				
			||||||
					*next      = zpl_cast( uptr ) curr + actual_block_size;
 | 
										* next     = rcast( uptr, curr) + actual_block_size;
 | 
				
			||||||
					curr       = pointer_add( curr, actual_block_size );
 | 
										curr       = pointer_add( curr, actual_block_size );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				end            = zpl_cast( uptr* ) curr;
 | 
									end            = rcast( uptr*, curr);
 | 
				
			||||||
				*end           = zpl_cast( uptr ) NULL;
 | 
									* end          = scast( uptr, NULL);
 | 
				
			||||||
				pool->FreeList = pool->PhysicalStart;
 | 
									pool->FreeList = pool->PhysicalStart;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -457,11 +457,11 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw al
 | 
				
			|||||||
	return ptr;
 | 
						return ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align )
 | 
					Pool Pool::init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	Pool pool = {};
 | 
						Pool pool = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw    actual_block_size, pool_size, block_index;
 | 
						ssize    actual_block_size, pool_size, block_index;
 | 
				
			||||||
	void *data, *curr;
 | 
						void *data, *curr;
 | 
				
			||||||
	uptr* end;
 | 
						uptr* end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -497,7 +497,7 @@ Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw b
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void Pool::clear()
 | 
					void Pool::clear()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw    actual_block_size, block_index;
 | 
						ssize    actual_block_size, block_index;
 | 
				
			||||||
	void* curr;
 | 
						void* curr;
 | 
				
			||||||
	uptr* end;
 | 
						uptr* end;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,43 +10,51 @@
 | 
				
			|||||||
#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) )
 | 
					#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) )
 | 
				
			||||||
#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) )
 | 
					#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN__ONES          ( zpl_cast( uw ) - 1 / GEN_U8_MAX )
 | 
					#define GEN__ONES          ( scast( GEN_NS usize, - 1) / GEN_U8_MAX )
 | 
				
			||||||
#define GEN__HIGHS         ( GEN__ONES * ( GEN_U8_MAX / 2 + 1 ) )
 | 
					#define GEN__HIGHS         ( GEN__ONES * ( GEN_U8_MAX / 2 + 1 ) )
 | 
				
			||||||
#define GEN__HAS_ZERO( x ) ( ( ( x ) - GEN__ONES ) & ~( x ) & GEN__HIGHS )
 | 
					#define GEN__HAS_ZERO( x ) ( ( ( x ) - GEN__ONES ) & ~( x ) & GEN__HIGHS )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template< class Type >
 | 
				
			||||||
 | 
					void swap( Type& a, Type& b )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Type tmp = a;
 | 
				
			||||||
 | 
						a = b;
 | 
				
			||||||
 | 
						b = tmp;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Checks if value is power of 2.
 | 
					//! Checks if value is power of 2.
 | 
				
			||||||
GEN_DEF_INLINE b32 is_power_of_two( sw x );
 | 
					b32 is_power_of_two( ssize x );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Aligns address to specified alignment.
 | 
					//! Aligns address to specified alignment.
 | 
				
			||||||
GEN_DEF_INLINE void* align_forward( void* ptr, sw alignment );
 | 
					void* align_forward( void* ptr, ssize alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Aligns value to a specified alignment.
 | 
					//! Aligns value to a specified alignment.
 | 
				
			||||||
GEN_DEF_INLINE s64 align_forward_i64( s64 value, sw alignment );
 | 
					s64 align_forward_i64( s64 value, ssize alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Moves pointer forward by bytes.
 | 
					//! Moves pointer forward by bytes.
 | 
				
			||||||
GEN_DEF_INLINE void* pointer_add( void* ptr, sw bytes );
 | 
					void* pointer_add( void* ptr, ssize bytes );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Moves pointer forward by bytes.
 | 
					//! Moves pointer forward by bytes.
 | 
				
			||||||
GEN_DEF_INLINE void const* pointer_add_const( void const* ptr, sw bytes );
 | 
					void const* pointer_add_const( void const* ptr, ssize bytes );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Calculates difference between two addresses.
 | 
					//! Calculates difference between two addresses.
 | 
				
			||||||
GEN_DEF_INLINE sw pointer_diff( void const* begin, void const* end );
 | 
					ssize pointer_diff( void const* begin, void const* end );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Copy non-overlapping memory from source to destination.
 | 
					//! Copy non-overlapping memory from source to destination.
 | 
				
			||||||
void* mem_copy( void* dest, void const* source, sw size );
 | 
					void* mem_copy( void* dest, void const* source, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Search for a constant value within the size limit at memory location.
 | 
					//! Search for a constant value within the size limit at memory location.
 | 
				
			||||||
void const* mem_find( void const* data, u8 byte_value, sw size );
 | 
					void const* mem_find( void const* data, u8 byte_value, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Copy memory from source to destination.
 | 
					//! Copy memory from source to destination.
 | 
				
			||||||
GEN_DEF_INLINE void* mem_move( void* dest, void const* source, sw size );
 | 
					void* mem_move( void* dest, void const* source, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Set constant value at memory location with specified size.
 | 
					//! Set constant value at memory location with specified size.
 | 
				
			||||||
GEN_DEF_INLINE void* mem_set( void* data, u8 byte_value, sw size );
 | 
					void* mem_set( void* data, u8 byte_value, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! @param ptr Memory location to clear up.
 | 
					//! @param ptr Memory location to clear up.
 | 
				
			||||||
//! @param size The size to clear up with.
 | 
					//! @param size The size to clear up with.
 | 
				
			||||||
GEN_DEF_INLINE void zero_size( void* ptr, sw size );
 | 
					void zero_size( void* ptr, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Clears up an item.
 | 
					//! Clears up an item.
 | 
				
			||||||
#define zero_item( t ) zero_size( ( t ), size_of( *( t ) ) )    // NOTE: Pass pointer of struct
 | 
					#define zero_item( t ) zero_size( ( t ), size_of( *( t ) ) )    // NOTE: Pass pointer of struct
 | 
				
			||||||
@@ -63,8 +71,8 @@ enum AllocType : u8
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using AllocatorProc = void* ( void* allocator_data, AllocType type
 | 
					using AllocatorProc = void* ( void* allocator_data, AllocType type
 | 
				
			||||||
	, sw size, sw alignment
 | 
						, ssize size, ssize alignment
 | 
				
			||||||
	, void* old_memory, sw old_size
 | 
						, void* old_memory, ssize old_size
 | 
				
			||||||
	, u64 flags );
 | 
						, u64 flags );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct AllocatorInfo
 | 
					struct AllocatorInfo
 | 
				
			||||||
@@ -87,22 +95,22 @@ enum AllocFlag
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Allocate memory with default alignment.
 | 
					//! Allocate memory with default alignment.
 | 
				
			||||||
GEN_DEF_INLINE void* alloc( AllocatorInfo a, sw size );
 | 
					void* alloc( AllocatorInfo a, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Allocate memory with specified alignment.
 | 
					//! Allocate memory with specified alignment.
 | 
				
			||||||
GEN_DEF_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment );
 | 
					void* alloc_align( AllocatorInfo a, ssize size, ssize alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Free allocated memory.
 | 
					//! Free allocated memory.
 | 
				
			||||||
GEN_DEF_INLINE void free( AllocatorInfo a, void* ptr );
 | 
					void free( AllocatorInfo a, void* ptr );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Free all memory allocated by an allocator.
 | 
					//! Free all memory allocated by an allocator.
 | 
				
			||||||
GEN_DEF_INLINE void free_all( AllocatorInfo a );
 | 
					void free_all( AllocatorInfo a );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Resize an allocated memory.
 | 
					//! Resize an allocated memory.
 | 
				
			||||||
GEN_DEF_INLINE void* resize( AllocatorInfo a, void* ptr, sw old_size, sw new_size );
 | 
					void* resize( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Resize an allocated memory with specified alignment.
 | 
					//! Resize an allocated memory with specified alignment.
 | 
				
			||||||
GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment );
 | 
					void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Allocate memory for an item.
 | 
					//! Allocate memory for an item.
 | 
				
			||||||
#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) )
 | 
					#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) )
 | 
				
			||||||
@@ -115,16 +123,16 @@ GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw n
 | 
				
			|||||||
/* call zpl_heap_stats_init at the beginning of the entry point */
 | 
					/* call zpl_heap_stats_init at the beginning of the entry point */
 | 
				
			||||||
/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
 | 
					/* you can call zpl_heap_stats_check near the end of the execution to validate any possible leaks */
 | 
				
			||||||
void  heap_stats_init( void );
 | 
					void  heap_stats_init( void );
 | 
				
			||||||
sw   heap_stats_used_memory( void );
 | 
					ssize heap_stats_used_memory( void );
 | 
				
			||||||
sw   heap_stats_alloc_count( void );
 | 
					ssize heap_stats_alloc_count( void );
 | 
				
			||||||
void  heap_stats_check( void );
 | 
					void  heap_stats_check( void );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Allocate/Resize memory using default options.
 | 
					//! Allocate/Resize memory using default options.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Use this if you don't need a "fancy" resize allocation
 | 
					//! Use this if you don't need a "fancy" resize allocation
 | 
				
			||||||
GEN_DEF_INLINE void* default_resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment );
 | 
					void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
 | 
					void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! The heap allocator backed by operating system's memory manager.
 | 
					//! The heap allocator backed by operating system's memory manager.
 | 
				
			||||||
constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; }
 | 
					constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; }
 | 
				
			||||||
@@ -135,270 +143,40 @@ constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr };
 | 
				
			|||||||
//! Helper to free memory allocated by heap allocator.
 | 
					//! Helper to free memory allocated by heap allocator.
 | 
				
			||||||
#define mfree( ptr ) free( heap(), ptr )
 | 
					#define mfree( ptr ) free( heap(), ptr )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 is_power_of_two( sw x )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( x <= 0 )
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	return ! ( x & ( x - 1 ) );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* align_forward( void* ptr, sw alignment )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uptr p;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	GEN_ASSERT( is_power_of_two( alignment ) );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p = zpl_cast( uptr ) ptr;
 | 
					 | 
				
			||||||
	return zpl_cast( void* )( ( p + ( alignment - 1 ) ) & ~( alignment - 1 ) );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE s64 align_forward_i64( s64 value, sw alignment )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return value + ( alignment - value % alignment ) % alignment;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* pointer_add( void* ptr, sw bytes )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return zpl_cast( void* )( zpl_cast( u8* ) ptr + bytes );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void const* pointer_add_const( void const* ptr, sw bytes )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return zpl_cast( void const* )( zpl_cast( u8 const* ) ptr + bytes );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE sw pointer_diff( void const* begin, void const* end )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return zpl_cast( sw )( zpl_cast( u8 const* ) end - zpl_cast( u8 const* ) begin );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* mem_move( void* dest, void const* source, sw n )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( dest == NULL )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u8*       d = zpl_cast( u8* ) dest;
 | 
					 | 
				
			||||||
	u8 const* s = zpl_cast( u8 const* ) source;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( d == s )
 | 
					 | 
				
			||||||
		return d;
 | 
					 | 
				
			||||||
	if ( s + n <= d || d + n <= s )    // NOTE: Non-overlapping
 | 
					 | 
				
			||||||
		return mem_copy( d, s, n );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( d < s )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if ( zpl_cast( uptr ) s % size_of( sw ) == zpl_cast( uptr ) d % size_of( sw ) )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			while ( zpl_cast( uptr ) d % size_of( sw ) )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if ( ! n-- )
 | 
					 | 
				
			||||||
					return dest;
 | 
					 | 
				
			||||||
				*d++ = *s++;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			while ( n >= size_of( sw ) )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				*zpl_cast( sw* ) d  = *zpl_cast( sw* ) s;
 | 
					 | 
				
			||||||
				n                  -= size_of( sw );
 | 
					 | 
				
			||||||
				d                  += size_of( sw );
 | 
					 | 
				
			||||||
				s                  += size_of( sw );
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		for ( ; n; n-- )
 | 
					 | 
				
			||||||
			*d++ = *s++;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if ( ( zpl_cast( uptr ) s % size_of( sw ) ) == ( zpl_cast( uptr ) d % size_of( sw ) ) )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			while ( zpl_cast( uptr )( d + n ) % size_of( sw ) )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				if ( ! n-- )
 | 
					 | 
				
			||||||
					return dest;
 | 
					 | 
				
			||||||
				d[ n ] = s[ n ];
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			while ( n >= size_of( sw ) )
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				n                         -= size_of( sw );
 | 
					 | 
				
			||||||
				*zpl_cast( sw* )( d + n )  = *zpl_cast( sw* )( s + n );
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		while ( n )
 | 
					 | 
				
			||||||
			n--, d[ n ] = s[ n ];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return dest;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* mem_set( void* dest, u8 c, sw n )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( dest == NULL )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	u8* s = zpl_cast( u8* ) dest;
 | 
					 | 
				
			||||||
	sw  k;
 | 
					 | 
				
			||||||
	u32 c32 = ( ( u32 )-1 ) / 255 * c;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( n == 0 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
	s[ 0 ] = s[ n - 1 ] = c;
 | 
					 | 
				
			||||||
	if ( n < 3 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
	s[ 1 ] = s[ n - 2 ] = c;
 | 
					 | 
				
			||||||
	s[ 2 ] = s[ n - 3 ] = c;
 | 
					 | 
				
			||||||
	if ( n < 7 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
	s[ 3 ] = s[ n - 4 ] = c;
 | 
					 | 
				
			||||||
	if ( n < 9 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	k  = -zpl_cast( sptr ) s & 3;
 | 
					 | 
				
			||||||
	s += k;
 | 
					 | 
				
			||||||
	n -= k;
 | 
					 | 
				
			||||||
	n &= -4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 0 )     = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 4 ) = c32;
 | 
					 | 
				
			||||||
	if ( n < 9 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 4 )      = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 8 )      = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 12 ) = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 8 )  = c32;
 | 
					 | 
				
			||||||
	if ( n < 25 )
 | 
					 | 
				
			||||||
		return dest;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 12 )     = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 16 )     = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 20 )     = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + 24 )     = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 28 ) = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 24 ) = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 20 ) = c32;
 | 
					 | 
				
			||||||
	*zpl_cast( u32* )( s + n - 16 ) = c32;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	k  = 24 + ( zpl_cast( uptr ) s & 4 );
 | 
					 | 
				
			||||||
	s += k;
 | 
					 | 
				
			||||||
	n -= k;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		u64 c64 = ( zpl_cast( u64 ) c32 << 32 ) | c32;
 | 
					 | 
				
			||||||
		while ( n > 31 )
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			*zpl_cast( u64* )( s + 0 )  = c64;
 | 
					 | 
				
			||||||
			*zpl_cast( u64* )( s + 8 )  = c64;
 | 
					 | 
				
			||||||
			*zpl_cast( u64* )( s + 16 ) = c64;
 | 
					 | 
				
			||||||
			*zpl_cast( u64* )( s + 24 ) = c64;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			n -= 32;
 | 
					 | 
				
			||||||
			s += 32;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return dest;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return a.Proc( a.Data, EAllocation_ALLOC, size, alignment, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* alloc( AllocatorInfo a, sw size )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return alloc_align( a, size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void free( AllocatorInfo a, void* ptr )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( ptr != nullptr )
 | 
					 | 
				
			||||||
		a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void free_all( AllocatorInfo a )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	a.Proc( a.Data, EAllocation_FREE_ALL, 0, 0, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* resize( AllocatorInfo a, void* ptr, sw old_size, sw new_size )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return resize_align( a, ptr, old_size, new_size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return a.Proc( a.Data, EAllocation_RESIZE, new_size, alignment, ptr, old_size, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void* default_resize_align( AllocatorInfo a, void* old_memory, sw old_size, sw new_size, sw alignment )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if ( ! old_memory )
 | 
					 | 
				
			||||||
		return alloc_align( a, new_size, alignment );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( new_size == 0 )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		free( a, old_memory );
 | 
					 | 
				
			||||||
		return nullptr;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( new_size < old_size )
 | 
					 | 
				
			||||||
		new_size = old_size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if ( old_size == new_size )
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return old_memory;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		void* new_memory = alloc_align( a, new_size, alignment );
 | 
					 | 
				
			||||||
		if ( ! new_memory )
 | 
					 | 
				
			||||||
			return nullptr;
 | 
					 | 
				
			||||||
		mem_move( new_memory, old_memory, min( new_size, old_size ) );
 | 
					 | 
				
			||||||
		free( a, old_memory );
 | 
					 | 
				
			||||||
		return new_memory;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GEN_IMPL_INLINE void zero_size( void* ptr, sw size )
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	mem_set( ptr, 0, size );
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct VirtualMemory
 | 
					struct VirtualMemory
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void*  data;
 | 
						void*  data;
 | 
				
			||||||
	sw size;
 | 
						ssize size;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Initialize virtual memory from existing data.
 | 
					//! Initialize virtual memory from existing data.
 | 
				
			||||||
VirtualMemory vm_from_memory( void* data, sw size );
 | 
					VirtualMemory vm_from_memory( void* data, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Allocate virtual memory at address with size.
 | 
					//! Allocate virtual memory at address with size.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it.
 | 
					//! @param addr The starting address of the region to reserve. If NULL, it lets operating system to decide where to allocate it.
 | 
				
			||||||
//! @param size The size to serve.
 | 
					//! @param size The size to serve.
 | 
				
			||||||
VirtualMemory vm_alloc( void* addr, sw size );
 | 
					VirtualMemory vm_alloc( void* addr, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Release the virtual memory.
 | 
					//! Release the virtual memory.
 | 
				
			||||||
b32 vm_free( VirtualMemory vm );
 | 
					b32 vm_free( VirtualMemory vm );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Trim virtual memory.
 | 
					//! Trim virtual memory.
 | 
				
			||||||
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size );
 | 
					VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Purge virtual memory.
 | 
					//! Purge virtual memory.
 | 
				
			||||||
b32 gen_vm_purge( VirtualMemory vm );
 | 
					b32 gen_vm_purge( VirtualMemory vm );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//! Retrieve VM's page size and alignment.
 | 
					//! Retrieve VM's page size and alignment.
 | 
				
			||||||
sw gen_virtual_memory_page_size( sw* alignment_out );
 | 
					ssize gen_virtual_memory_page_size( ssize* alignment_out );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Arena
 | 
					struct Arena
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
 | 
						void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Arena init_from_memory( void* start, sw size )
 | 
						Arena init_from_memory( void* start, ssize size )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -411,7 +189,7 @@ struct Arena
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Arena init_from_allocator( AllocatorInfo backing, sw size )
 | 
						Arena init_from_allocator( AllocatorInfo backing, ssize size )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Arena result =
 | 
							Arena result =
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -425,18 +203,18 @@ struct Arena
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Arena init_sub( Arena& parent, sw size )
 | 
						Arena init_sub( Arena& parent, ssize size )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return init_from_allocator( parent.Backing, size );
 | 
							return init_from_allocator( parent.Backing, size );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw alignment_of( sw alignment )
 | 
						ssize alignment_of( ssize alignment )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw alignment_offset, result_pointer, mask;
 | 
							ssize alignment_offset, result_pointer, mask;
 | 
				
			||||||
		GEN_ASSERT( is_power_of_two( alignment ) );
 | 
							GEN_ASSERT( is_power_of_two( alignment ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		alignment_offset = 0;
 | 
							alignment_offset = 0;
 | 
				
			||||||
		result_pointer   = (sw) PhysicalStart + TotalUsed;
 | 
							result_pointer   = (ssize) PhysicalStart + TotalUsed;
 | 
				
			||||||
		mask             = alignment - 1;
 | 
							mask             = alignment - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( result_pointer & mask )
 | 
							if ( result_pointer & mask )
 | 
				
			||||||
@@ -445,10 +223,14 @@ struct Arena
 | 
				
			|||||||
		return alignment_offset;
 | 
							return alignment_offset;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This id is defined by Unreal for asserts
 | 
				
			||||||
 | 
					#pragma push_macro("check")
 | 
				
			||||||
 | 
					#undef check
 | 
				
			||||||
	void check()
 | 
						void check()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		GEN_ASSERT( TempCount == 0 );
 | 
							GEN_ASSERT( TempCount == 0 );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#pragma pop_macro("check")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void free()
 | 
						void free()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -459,17 +241,17 @@ struct Arena
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw size_remaining( sw alignment )
 | 
						ssize size_remaining( ssize alignment )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw result = TotalSize - ( TotalUsed + alignment_of( alignment ) );
 | 
							ssize result = TotalSize - ( TotalUsed + alignment_of( alignment ) );
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AllocatorInfo Backing;
 | 
						AllocatorInfo Backing;
 | 
				
			||||||
	void*         PhysicalStart;
 | 
						void*         PhysicalStart;
 | 
				
			||||||
	sw            TotalSize;
 | 
						ssize            TotalSize;
 | 
				
			||||||
	sw            TotalUsed;
 | 
						ssize            TotalUsed;
 | 
				
			||||||
	sw            TempCount;
 | 
						ssize            TempCount;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	operator AllocatorInfo()
 | 
						operator AllocatorInfo()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -489,7 +271,7 @@ struct FixedArena
 | 
				
			|||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw size_remaining( sw alignment )
 | 
						ssize size_remaining( ssize alignment )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return arena.size_remaining( alignment );
 | 
							return arena.size_remaining( alignment );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -519,16 +301,16 @@ using Arena_4MB   = FixedArena< megabytes( 4 ) >;
 | 
				
			|||||||
struct Pool
 | 
					struct Pool
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
 | 
						void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Pool init( AllocatorInfo backing, sw num_blocks, sw block_size )
 | 
						Pool init( AllocatorInfo backing, ssize num_blocks, ssize block_size )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return init_align( backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
							return init_align( backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	Pool init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align );
 | 
						Pool init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void clear();
 | 
						void clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -543,10 +325,10 @@ struct Pool
 | 
				
			|||||||
	AllocatorInfo Backing;
 | 
						AllocatorInfo Backing;
 | 
				
			||||||
	void*         PhysicalStart;
 | 
						void*         PhysicalStart;
 | 
				
			||||||
	void*         FreeList;
 | 
						void*         FreeList;
 | 
				
			||||||
	sw            BlockSize;
 | 
						ssize         BlockSize;
 | 
				
			||||||
	sw            BlockAlign;
 | 
						ssize         BlockAlign;
 | 
				
			||||||
	sw            TotalSize;
 | 
						ssize         TotalSize;
 | 
				
			||||||
	sw            NumBlocks;
 | 
						ssize         NumBlocks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	operator AllocatorInfo()
 | 
						operator AllocatorInfo()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -554,4 +336,236 @@ struct Pool
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					b32 is_power_of_two( ssize x ) {
 | 
				
			||||||
 | 
						if ( x <= 0 )
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						return ! ( x & ( x - 1 ) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					mem_ptr align_forward( void* ptr, ssize alignment )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						GEN_ASSERT( is_power_of_two( alignment ) );
 | 
				
			||||||
 | 
						uptr p       = to_uptr(ptr);
 | 
				
			||||||
 | 
						uptr forward = (p + ( alignment - 1 ) ) & ~( alignment - 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return to_mem_ptr(forward);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline s64 align_forward_i64( s64 value, ssize alignment ) { return value + ( alignment - value % alignment ) % alignment; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void*       pointer_add      ( void*       ptr, ssize bytes ) { return rcast(void*,       rcast( u8*,        ptr) + bytes ); }
 | 
				
			||||||
 | 
					inline void const* pointer_add_const( void const* ptr, ssize bytes ) { return rcast(void const*, rcast( u8 const*,  ptr) + bytes ); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline sptr pointer_diff( mem_ptr_const begin, mem_ptr_const end ) {
 | 
				
			||||||
 | 
						return scast( ssize, rcast( u8 const*, end) - rcast(u8 const*, begin) );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* mem_move( void* destination, void const* source, ssize byte_count )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( destination == NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						u8*       dest_ptr = rcast( u8*, destination);
 | 
				
			||||||
 | 
						u8 const* src_ptr  = rcast( u8 const*, source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( dest_ptr == src_ptr )
 | 
				
			||||||
 | 
							return dest_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( src_ptr + byte_count <= dest_ptr || dest_ptr + byte_count <= src_ptr )    // NOTE: Non-overlapping
 | 
				
			||||||
 | 
							return mem_copy( dest_ptr, src_ptr, byte_count );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( dest_ptr < src_ptr )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( to_uptr(src_ptr) % size_of( ssize ) == to_uptr(dest_ptr) % size_of( ssize ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								while ( pcast( uptr, dest_ptr) % size_of( ssize ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ( ! byte_count-- )
 | 
				
			||||||
 | 
										return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									*dest_ptr++ = *src_ptr++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while ( byte_count >= size_of( ssize ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									* rcast(ssize*, dest_ptr)  = * rcast(ssize const*, src_ptr);
 | 
				
			||||||
 | 
									byte_count -= size_of( ssize );
 | 
				
			||||||
 | 
									dest_ptr   += size_of( ssize );
 | 
				
			||||||
 | 
									src_ptr    += size_of( ssize );
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for ( ; byte_count; byte_count-- )
 | 
				
			||||||
 | 
								*dest_ptr++ = *src_ptr++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if ( ( to_uptr(src_ptr) % size_of( ssize ) ) == ( to_uptr(dest_ptr) % size_of( ssize ) ) )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								while ( to_uptr( dest_ptr + byte_count ) % size_of( ssize ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if ( ! byte_count-- )
 | 
				
			||||||
 | 
										return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									dest_ptr[ byte_count ] = src_ptr[ byte_count ];
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								while ( byte_count >= size_of( ssize ) )
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									byte_count                              -= size_of( ssize );
 | 
				
			||||||
 | 
									* rcast(ssize*, dest_ptr + byte_count )  = * rcast( ssize const*, src_ptr + byte_count );
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							while ( byte_count )
 | 
				
			||||||
 | 
								byte_count--, dest_ptr[ byte_count ] = src_ptr[ byte_count ];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return destination;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* mem_set( void* destination, u8 fill_byte, ssize byte_count )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( destination == NULL )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ssize align_offset;
 | 
				
			||||||
 | 
						u8*   dest_ptr  = rcast( u8*, destination);
 | 
				
			||||||
 | 
						u32   fill_word = ( ( u32 )-1 ) / 255 * fill_byte;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( byte_count == 0 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dest_ptr[ 0 ] = dest_ptr[ byte_count - 1 ] = fill_byte;
 | 
				
			||||||
 | 
						if ( byte_count < 3 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dest_ptr[ 1 ] = dest_ptr[ byte_count - 2 ] = fill_byte;
 | 
				
			||||||
 | 
						dest_ptr[ 2 ] = dest_ptr[ byte_count - 3 ] = fill_byte;
 | 
				
			||||||
 | 
						if ( byte_count < 7 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dest_ptr[ 3 ] = dest_ptr[ byte_count - 4 ] = fill_byte;
 | 
				
			||||||
 | 
						if ( byte_count < 9 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						align_offset  = -to_sptr( dest_ptr ) & 3;
 | 
				
			||||||
 | 
						dest_ptr     += align_offset;
 | 
				
			||||||
 | 
						byte_count   -= align_offset;
 | 
				
			||||||
 | 
						byte_count   &= -4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* rcast( u32*, ( dest_ptr + 0              ) ) = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, ( dest_ptr + byte_count - 4 ) ) = fill_word;
 | 
				
			||||||
 | 
						if ( byte_count < 9 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 4 )               = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 8 )               = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 12 ) = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 8 )  = fill_word;
 | 
				
			||||||
 | 
						if ( byte_count < 25 )
 | 
				
			||||||
 | 
							return destination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 12 )              = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 16 )              = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 20 )              = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + 24 )              = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 28 ) = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 24 ) = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 20 ) = fill_word;
 | 
				
			||||||
 | 
						* rcast( u32*, dest_ptr + byte_count - 16 ) = fill_word;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						align_offset  = 24 + to_uptr( dest_ptr ) & 4;
 | 
				
			||||||
 | 
						dest_ptr     += align_offset;
 | 
				
			||||||
 | 
						byte_count   -= align_offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							u64 fill_doubleword = ( scast( u64, fill_word) << 32 ) | fill_word;
 | 
				
			||||||
 | 
							while ( byte_count > 31 )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								* rcast( u64*, dest_ptr + 0 )  = fill_doubleword;
 | 
				
			||||||
 | 
								* rcast( u64*, dest_ptr + 8 )  = fill_doubleword;
 | 
				
			||||||
 | 
								* rcast( u64*, dest_ptr + 16 ) = fill_doubleword;
 | 
				
			||||||
 | 
								* rcast( u64*, dest_ptr + 24 ) = fill_doubleword;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								byte_count -= 32;
 | 
				
			||||||
 | 
								dest_ptr += 32;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return destination;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* alloc_align( AllocatorInfo a, ssize size, ssize alignment ) {
 | 
				
			||||||
 | 
						return a.Proc( a.Data, EAllocation_ALLOC, size, alignment, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* alloc( AllocatorInfo a, ssize size ) {
 | 
				
			||||||
 | 
						return alloc_align( a, size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void free( AllocatorInfo a, void* ptr ) {
 | 
				
			||||||
 | 
						if ( ptr != nullptr )
 | 
				
			||||||
 | 
							a.Proc( a.Data, EAllocation_FREE, 0, 0, ptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void free_all( AllocatorInfo a ) {
 | 
				
			||||||
 | 
						a.Proc( a.Data, EAllocation_FREE_ALL, 0, 0, nullptr, 0, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* resize( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size ) {
 | 
				
			||||||
 | 
						return resize_align( a, ptr, old_size, new_size, GEN_DEFAULT_MEMORY_ALIGNMENT );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment ) {
 | 
				
			||||||
 | 
						return a.Proc( a.Data, EAllocation_RESIZE, new_size, alignment, ptr, old_size, GEN_DEFAULT_ALLOCATOR_FLAGS );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void* default_resize_align( AllocatorInfo a, void* old_memory, ssize old_size, ssize new_size, ssize alignment )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( ! old_memory )
 | 
				
			||||||
 | 
							return alloc_align( a, new_size, alignment );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( new_size == 0 )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							free( a, old_memory );
 | 
				
			||||||
 | 
							return nullptr;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( new_size < old_size )
 | 
				
			||||||
 | 
							new_size = old_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( old_size == new_size )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return old_memory;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							void*  new_memory = alloc_align( a, new_size, alignment );
 | 
				
			||||||
 | 
							if ( ! new_memory )
 | 
				
			||||||
 | 
								return nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mem_move( new_memory, old_memory, min( new_size, old_size ) );
 | 
				
			||||||
 | 
							free( a, old_memory );
 | 
				
			||||||
 | 
							return new_memory;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
 | 
					void zero_size( void* ptr, ssize size ) {
 | 
				
			||||||
 | 
						mem_set( ptr, 0, size );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion Memory
 | 
					#pragma endregion Memory
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,7 +36,7 @@ u8 adt_destroy_branch( ADT_Node* node )
 | 
				
			|||||||
	GEN_ASSERT_NOT_NULL( node );
 | 
						GEN_ASSERT_NOT_NULL( node );
 | 
				
			||||||
	if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
 | 
						if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw i = 0; i < node->nodes.num(); ++i )
 | 
							for ( ssize i = 0; i < scast(ssize, node->nodes.num()); ++i )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			adt_destroy_branch( node->nodes + i );
 | 
								adt_destroy_branch( node->nodes + i );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -66,7 +66,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
 | 
				
			|||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for ( sw i = 0; i < node->nodes.num(); i++ )
 | 
						for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( ! str_compare( node->nodes[ i ].name, name ) )
 | 
							if ( ! str_compare( node->nodes[ i ].name, name ) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -76,7 +76,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ( deep_search )
 | 
						if ( deep_search )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw i = 0; i < node->nodes.num(); i++ )
 | 
							for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
 | 
								ADT_Node* res = adt_find( node->nodes + i, name, deep_search );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -111,7 +111,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
 | 
				
			|||||||
				file_stream_open( &tmp, heap(), ( u8* )back, size_of( back ), EFileStream_WRITABLE );
 | 
									file_stream_open( &tmp, heap(), ( u8* )back, size_of( back ), EFileStream_WRITABLE );
 | 
				
			||||||
				adt_print_number( &tmp, node );
 | 
									adt_print_number( &tmp, node );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				sw  fsize = 0;
 | 
									ssize  fsize = 0;
 | 
				
			||||||
				u8* buf   = file_stream_buf( &tmp, &fsize );
 | 
									u8* buf   = file_stream_buf( &tmp, &fsize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( ! str_compare( ( char const* )buf, value ) )
 | 
									if ( ! str_compare( ( char const* )buf, value ) )
 | 
				
			||||||
@@ -132,7 +132,7 @@ internal ADT_Node* _adt_get_value( ADT_Node* node, char const* value )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
 | 
					internal ADT_Node* _adt_get_field( ADT_Node* node, char* name, char* value )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	for ( sw i = 0; i < node->nodes.num(); i++ )
 | 
						for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( ! str_compare( node->nodes[ i ].name, name ) )
 | 
							if ( ! str_compare( node->nodes[ i ].name, name ) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -207,7 +207,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
 | 
				
			|||||||
			/* run a value comparison against any child that is an object node */
 | 
								/* run a value comparison against any child that is an object node */
 | 
				
			||||||
			else if ( node->type == EADT_TYPE_ARRAY )
 | 
								else if ( node->type == EADT_TYPE_ARRAY )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				for ( sw i = 0; i < node->nodes.num(); i++ )
 | 
									for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					ADT_Node* child = &node->nodes[ i ];
 | 
										ADT_Node* child = &node->nodes[ i ];
 | 
				
			||||||
					if ( child->type != EADT_TYPE_OBJECT )
 | 
										if ( child->type != EADT_TYPE_OBJECT )
 | 
				
			||||||
@@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
 | 
				
			|||||||
		/* [value] */
 | 
							/* [value] */
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			for ( sw i = 0; i < node->nodes.num(); i++ )
 | 
								for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				ADT_Node* child = &node->nodes[ i ];
 | 
									ADT_Node* child = &node->nodes[ i ];
 | 
				
			||||||
				if ( _adt_get_value( child, l_b2 ) )
 | 
									if ( _adt_get_value( child, l_b2 ) )
 | 
				
			||||||
@@ -256,8 +256,8 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
 | 
				
			|||||||
	/* handle array index lookup */
 | 
						/* handle array index lookup */
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw idx = ( sw )str_to_i64( buf, NULL, 10 );
 | 
							ssize idx = ( ssize )str_to_i64( buf, NULL, 10 );
 | 
				
			||||||
		if ( idx >= 0 && idx < node->nodes.num() )
 | 
							if ( idx >= 0 && idx < scast(ssize, node->nodes.num()) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			found_node = &node->nodes[ idx ];
 | 
								found_node = &node->nodes[ idx ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -272,7 +272,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
 | 
				
			|||||||
	return found_node;
 | 
						return found_node;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
 | 
					ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( ! parent || ( parent->type != EADT_TYPE_OBJECT && parent->type != EADT_TYPE_ARRAY ) )
 | 
						if ( ! parent || ( parent->type != EADT_TYPE_OBJECT && parent->type != EADT_TYPE_ARRAY ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -282,7 +282,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
 | 
				
			|||||||
	if ( ! parent->nodes )
 | 
						if ( ! parent->nodes )
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( index < 0 || index > parent->nodes.num() )
 | 
						if ( index < 0 || index > scast(ssize, parent->nodes.num()) )
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ADT_Node o = { 0 };
 | 
						ADT_Node o = { 0 };
 | 
				
			||||||
@@ -337,7 +337,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value )
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index )
 | 
					ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( node );
 | 
						GEN_ASSERT_NOT_NULL( node );
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( new_parent );
 | 
						GEN_ASSERT_NOT_NULL( new_parent );
 | 
				
			||||||
@@ -366,8 +366,8 @@ void adt_swap_nodes( ADT_Node* node, ADT_Node* other_node )
 | 
				
			|||||||
	GEN_ASSERT_NOT_NULL( other_node );
 | 
						GEN_ASSERT_NOT_NULL( other_node );
 | 
				
			||||||
	ADT_Node* parent                     = node->parent;
 | 
						ADT_Node* parent                     = node->parent;
 | 
				
			||||||
	ADT_Node* other_parent               = other_node->parent;
 | 
						ADT_Node* other_parent               = other_node->parent;
 | 
				
			||||||
	sw        index                      = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
 | 
						ssize        index                      = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
 | 
				
			||||||
	sw        index2                     = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
 | 
						ssize        index2                     = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
 | 
				
			||||||
	ADT_Node  temp                       = parent->nodes[ index ];
 | 
						ADT_Node  temp                       = parent->nodes[ index ];
 | 
				
			||||||
	temp.parent                          = other_parent;
 | 
						temp.parent                          = other_parent;
 | 
				
			||||||
	other_parent->nodes[ index2 ].parent = parent;
 | 
						other_parent->nodes[ index2 ].parent = parent;
 | 
				
			||||||
@@ -380,7 +380,7 @@ void adt_remove_node( ADT_Node* node )
 | 
				
			|||||||
	GEN_ASSERT_NOT_NULL( node );
 | 
						GEN_ASSERT_NOT_NULL( node );
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( node->parent );
 | 
						GEN_ASSERT_NOT_NULL( node->parent );
 | 
				
			||||||
	ADT_Node* parent = node->parent;
 | 
						ADT_Node* parent = node->parent;
 | 
				
			||||||
	sw        index  = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
 | 
						ssize        index  = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
 | 
				
			||||||
	parent->nodes.remove_at( index );
 | 
						parent->nodes.remove_at( index );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -484,7 +484,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
 | 
				
			|||||||
	node_type = EADT_TYPE_INTEGER;
 | 
						node_type = EADT_TYPE_INTEGER;
 | 
				
			||||||
	neg_zero  = false;
 | 
						neg_zero  = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw   ib        = 0;
 | 
						ssize   ib        = 0;
 | 
				
			||||||
	char buf[ 48 ] = { 0 };
 | 
						char buf[ 48 ] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( *e == '+' )
 | 
						if ( *e == '+' )
 | 
				
			||||||
@@ -550,7 +550,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	f32  eb          = 10;
 | 
						f32  eb          = 10;
 | 
				
			||||||
	char expbuf[ 6 ] = { 0 };
 | 
						char expbuf[ 6 ] = { 0 };
 | 
				
			||||||
	sw   expi        = 0;
 | 
						ssize   expi        = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( *e && ! ! str_find( "eE", *e ) )
 | 
						if ( *e && ! ! str_find( "eE", *e ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -595,7 +595,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifndef GEN_PARSER_DISABLE_ANALYSIS
 | 
					#ifndef GEN_PARSER_DISABLE_ANALYSIS
 | 
				
			||||||
		char *q = buf, *base_string = q, *base_string2 = q;
 | 
							char *q = buf, *base_string = q, *base_string2 = q;
 | 
				
			||||||
		base_string           = zpl_cast( char* ) str_skip( base_string, '.' );
 | 
							base_string           = ccast( char*, str_skip( base_string, '.' ));
 | 
				
			||||||
		*base_string          = '\0';
 | 
							*base_string          = '\0';
 | 
				
			||||||
		base_string2          = base_string + 1;
 | 
							base_string2          = base_string + 1;
 | 
				
			||||||
		char* base_string_off = base_string2;
 | 
							char* base_string_off = base_string2;
 | 
				
			||||||
@@ -816,13 +816,13 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
	char* beginChar;
 | 
						char* beginChar;
 | 
				
			||||||
	char* endChar;
 | 
						char* endChar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw columnIndex       = 0;
 | 
						ssize columnIndex       = 0;
 | 
				
			||||||
	sw totalColumnIndex = 0;
 | 
						ssize totalColumnIndex = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	do
 | 
						do
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char delimiter = 0;
 | 
							char delimiter = 0;
 | 
				
			||||||
		currentChar = zpl_cast( char* ) str_trim( currentChar, false );
 | 
							currentChar = ccast( char*, str_trim( currentChar, false ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( *currentChar == 0 )
 | 
							if ( *currentChar == 0 )
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -846,7 +846,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
		#endif
 | 
							#endif
 | 
				
			||||||
			do
 | 
								do
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				endChar = zpl_cast( char* ) str_skip( endChar, '"' );
 | 
									endChar = ccast( char*, str_skip( endChar, '"' ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( *endChar && *( endChar + 1 ) == '"' )
 | 
									if ( *endChar && *( endChar + 1 ) == '"' )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
@@ -865,7 +865,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			*endChar    = 0;
 | 
								*endChar    = 0;
 | 
				
			||||||
			currentChar = zpl_cast( char* ) str_trim( endChar + 1, true );
 | 
								currentChar = ccast( char*, str_trim( endChar + 1, true ));
 | 
				
			||||||
			delimiter   = * currentChar;
 | 
								delimiter   = * currentChar;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* unescape escaped quotes (so that unescaped text escapes :) */
 | 
								/* unescape escaped quotes (so that unescaped text escapes :) */
 | 
				
			||||||
@@ -902,7 +902,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			if ( * endChar )
 | 
								if ( * endChar )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				currentChar = zpl_cast( char* ) str_trim( endChar, true );
 | 
									currentChar = ccast( char*, str_trim( endChar, true ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				while ( char_is_space( *( endChar - 1 ) ) )
 | 
									while ( char_is_space( *( endChar - 1 ) ) )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
@@ -946,7 +946,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( columnIndex >= root->nodes.num() )
 | 
							if ( columnIndex >= scast(ssize, root->nodes.num()) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			adt_append_arr( root, NULL );
 | 
								adt_append_arr( root, NULL );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -989,7 +989,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
 | 
				
			|||||||
	/* consider first row as a header. */
 | 
						/* consider first row as a header. */
 | 
				
			||||||
	if ( has_header )
 | 
						if ( has_header )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw i = 0; i < root->nodes.num(); i++ )
 | 
							for ( ssize i = 0; i < scast(ssize, root->nodes.num()); i++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			CSV_Object* col = root->nodes + i;
 | 
								CSV_Object* col = root->nodes + i;
 | 
				
			||||||
			CSV_Object* hdr = col->nodes;
 | 
								CSV_Object* hdr = col->nodes;
 | 
				
			||||||
@@ -1057,11 +1057,11 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
 | 
				
			|||||||
	GEN_ASSERT_NOT_NULL( file );
 | 
						GEN_ASSERT_NOT_NULL( file );
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( obj );
 | 
						GEN_ASSERT_NOT_NULL( obj );
 | 
				
			||||||
	GEN_ASSERT( obj->nodes );
 | 
						GEN_ASSERT( obj->nodes );
 | 
				
			||||||
	sw cols = obj->nodes.num();
 | 
						ssize cols = obj->nodes.num();
 | 
				
			||||||
	if ( cols == 0 )
 | 
						if ( cols == 0 )
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw rows = obj->nodes[ 0 ].nodes.num();
 | 
						ssize rows = obj->nodes[ 0 ].nodes.num();
 | 
				
			||||||
	if ( rows == 0 )
 | 
						if ( rows == 0 )
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1069,7 +1069,7 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if ( has_headers )
 | 
						if ( has_headers )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw i = 0; i < cols; i++ )
 | 
							for ( ssize i = 0; i < cols; i++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			_csv_write_header( file, &obj->nodes[ i ] );
 | 
								_csv_write_header( file, &obj->nodes[ i ] );
 | 
				
			||||||
			if ( i + 1 != cols )
 | 
								if ( i + 1 != cols )
 | 
				
			||||||
@@ -1080,9 +1080,9 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
 | 
				
			|||||||
		str_fmt_file( file, "\n" );
 | 
							str_fmt_file( file, "\n" );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for ( sw r = 0; r < rows; r++ )
 | 
						for ( ssize r = 0; r < rows; r++ )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		for ( sw i = 0; i < cols; i++ )
 | 
							for ( ssize i = 0; i < cols; i++ )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
 | 
								_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
 | 
				
			||||||
			if ( i + 1 != cols )
 | 
								if ( i + 1 != cols )
 | 
				
			||||||
@@ -1099,7 +1099,8 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
 | 
				
			|||||||
	FileInfo tmp;
 | 
						FileInfo tmp;
 | 
				
			||||||
	file_stream_new( &tmp, a );
 | 
						file_stream_new( &tmp, a );
 | 
				
			||||||
	csv_write_delimiter( &tmp, obj, delimiter );
 | 
						csv_write_delimiter( &tmp, obj, delimiter );
 | 
				
			||||||
	sw     fsize;
 | 
						
 | 
				
			||||||
 | 
						ssize  fsize;
 | 
				
			||||||
	u8*    buf    = file_stream_buf( &tmp, &fsize );
 | 
						u8*    buf    = file_stream_buf( &tmp, &fsize );
 | 
				
			||||||
	String output = String::make_length( a, ( char* )buf, fsize );
 | 
						String output = String::make_length( a, ( char* )buf, fsize );
 | 
				
			||||||
	file_close( &tmp );
 | 
						file_close( &tmp );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -178,7 +178,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
 | 
				
			|||||||
	* @param index
 | 
						* @param index
 | 
				
			||||||
	* @return zpl_adt_node * node
 | 
						* @return zpl_adt_node * node
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index );
 | 
					ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* @brief Allocate an unitialised node within a container.
 | 
						* @brief Allocate an unitialised node within a container.
 | 
				
			||||||
@@ -196,7 +196,7 @@ ADT_Node* adt_alloc( ADT_Node* parent );
 | 
				
			|||||||
	* @param index
 | 
						* @param index
 | 
				
			||||||
	* @return zpl_adt_node * node
 | 
						* @return zpl_adt_node * node
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index );
 | 
					ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
	* @brief Move an existing node to a new container.
 | 
						* @brief Move an existing node to a new container.
 | 
				
			||||||
@@ -400,31 +400,33 @@ enum CSV_Error : u32
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef ADT_Node CSV_Object;
 | 
					typedef ADT_Node CSV_Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
 | 
					u8   csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
 | 
				
			||||||
u8   csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
 | 
					u8   csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header, char delim );
 | 
				
			||||||
void csv_free( CSV_Object* obj );
 | 
					void csv_free( CSV_Object* obj );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE void   csv_write( FileInfo* file, CSV_Object* obj );
 | 
					void   csv_write( FileInfo* file, CSV_Object* obj );
 | 
				
			||||||
GEN_DEF_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj );
 | 
					String csv_write_string( AllocatorInfo a, CSV_Object* obj );
 | 
				
			||||||
void   csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
 | 
					void   csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
 | 
				
			||||||
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
 | 
					String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* inline */
 | 
					/* inline */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
 | 
					inline
 | 
				
			||||||
 | 
					u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return csv_parse_delimiter( root, text, allocator, has_header, ',' );
 | 
						return csv_parse_delimiter( root, text, allocator, has_header, ',' );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE void csv_write( FileInfo* file, CSV_Object* obj )
 | 
					inline
 | 
				
			||||||
 | 
					void csv_write( FileInfo* file, CSV_Object* obj )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	csv_write_delimiter( file, obj, ',' );
 | 
						csv_write_delimiter( file, obj, ',' );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj )
 | 
					inline
 | 
				
			||||||
 | 
					String csv_write_string( AllocatorInfo a, CSV_Object* obj )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return csv_write_string_delimiter( a, obj, ',' );
 | 
						return csv_write_string_delimiter( a, obj, ',' );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma endregion CSV
 | 
					#pragma endregion CSV
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,6 @@
 | 
				
			|||||||
 | 
					#ifdef GEN_INTELLISENSE_DIRECTIVES
 | 
				
			||||||
#	pragma once
 | 
					#	pragma once
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region Platform Detection
 | 
					#pragma region Platform Detection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,9 +101,6 @@
 | 
				
			|||||||
#  define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
 | 
					#  define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define GEN_DEF_INLINE  static
 | 
					 | 
				
			||||||
#define GEN_IMPL_INLINE static inline
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma endregion Platform Detection
 | 
					#pragma endregion Platform Detection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma region Mandatory Includes
 | 
					#pragma region Mandatory Includes
 | 
				
			||||||
@@ -41,10 +41,10 @@ struct _format_info
 | 
				
			|||||||
	s32 precision;
 | 
						s32 precision;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_string( char* text, sw max_len, _format_info* info, char const* str )
 | 
					internal ssize _print_string( char* text, ssize max_len, _format_info* info, char const* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw    res = 0, len = 0;
 | 
						ssize    res = 0, len = 0;
 | 
				
			||||||
	sw    remaining = max_len;
 | 
						ssize    remaining = max_len;
 | 
				
			||||||
	char* begin     = text;
 | 
						char* begin     = text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( str == NULL && max_len >= 6 )
 | 
						if ( str == NULL && max_len >= 6 )
 | 
				
			||||||
@@ -75,7 +75,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if ( info->width > res )
 | 
							if ( info->width > res )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sw padding = info->width - len;
 | 
								ssize padding = info->width - len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
 | 
								char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
 | 
				
			||||||
			while ( padding-- > 0 && remaining-- > 0 )
 | 
								while ( padding-- > 0 && remaining-- > 0 )
 | 
				
			||||||
@@ -86,7 +86,7 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		if ( info && ( info->width > res ) )
 | 
							if ( info && ( info->width > res ) )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sw   padding = info->width - len;
 | 
								ssize   padding = info->width - len;
 | 
				
			||||||
			char pad     = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
 | 
								char pad     = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
 | 
				
			||||||
			while ( padding-- > 0 && remaining-- > 0 )
 | 
								while ( padding-- > 0 && remaining-- > 0 )
 | 
				
			||||||
				*text++ = pad, res++;
 | 
									*text++ = pad, res++;
 | 
				
			||||||
@@ -108,16 +108,16 @@ internal sw _print_string( char* text, sw max_len, _format_info* info, char cons
 | 
				
			|||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_char( char* text, sw max_len, _format_info* info, char arg )
 | 
					internal ssize _print_char( char* text, ssize max_len, _format_info* info, char arg )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char str[ 2 ] = "";
 | 
						char str[ 2 ] = "";
 | 
				
			||||||
	str[ 0 ]      = arg;
 | 
						str[ 0 ]      = arg;
 | 
				
			||||||
	return _print_string( text, max_len, info, str );
 | 
						return _print_string( text, max_len, info, str );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, char arg )
 | 
					internal ssize _print_repeated_char( char* text, ssize max_len, _format_info* info, char arg )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw  res = 0;
 | 
						ssize  res = 0;
 | 
				
			||||||
	s32 rem = ( info ) ? ( info->width > 0 ) ? info->width : 1 : 1;
 | 
						s32 rem = ( info ) ? ( info->width > 0 ) ? info->width : 1 : 1;
 | 
				
			||||||
	res     = rem;
 | 
						res     = rem;
 | 
				
			||||||
	while ( rem-- > 0 )
 | 
						while ( rem-- > 0 )
 | 
				
			||||||
@@ -126,24 +126,24 @@ internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, ch
 | 
				
			|||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_i64( char* text, sw max_len, _format_info* info, s64 value )
 | 
					internal ssize _print_i64( char* text, ssize max_len, _format_info* info, s64 value )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char num[ 130 ];
 | 
						char num[ 130 ];
 | 
				
			||||||
	i64_to_str( value, num, info ? info->base : 10 );
 | 
						i64_to_str( value, num, info ? info->base : 10 );
 | 
				
			||||||
	return _print_string( text, max_len, info, num );
 | 
						return _print_string( text, max_len, info, num );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_u64( char* text, sw max_len, _format_info* info, u64 value )
 | 
					internal ssize _print_u64( char* text, ssize max_len, _format_info* info, u64 value )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char num[ 130 ];
 | 
						char num[ 130 ];
 | 
				
			||||||
	u64_to_str( value, num, info ? info->base : 10 );
 | 
						u64_to_str( value, num, info ? info->base : 10 );
 | 
				
			||||||
	return _print_string( text, max_len, info, num );
 | 
						return _print_string( text, max_len, info, num );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
 | 
					internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// TODO: Handle exponent notation
 | 
						// TODO: Handle exponent notation
 | 
				
			||||||
	sw    width, len, remaining = max_len;
 | 
						ssize    width, len, remaining = max_len;
 | 
				
			||||||
	char* text_begin = text;
 | 
						char* text_begin = text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( arg )
 | 
						if ( arg )
 | 
				
			||||||
@@ -163,7 +163,7 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
 | 
				
			|||||||
			text++;
 | 
								text++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		value  = zpl_cast( u64 ) arg;
 | 
							value  = scast( u64, arg);
 | 
				
			||||||
		len    = _print_u64( text, remaining, NULL, value );
 | 
							len    = _print_u64( text, remaining, NULL, value );
 | 
				
			||||||
		text  += len;
 | 
							text  += len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -184,14 +184,14 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
 | 
				
			|||||||
			text++;
 | 
								text++;
 | 
				
			||||||
			while ( info->precision-- > 0 )
 | 
								while ( info->precision-- > 0 )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				value  = zpl_cast( u64 )( arg * mult );
 | 
									value  = scast( u64, arg * mult );
 | 
				
			||||||
				len    = _print_u64( text, remaining, NULL, value );
 | 
									len    = _print_u64( text, remaining, NULL, value );
 | 
				
			||||||
				text  += len;
 | 
									text  += len;
 | 
				
			||||||
				if ( len >= remaining )
 | 
									if ( len >= remaining )
 | 
				
			||||||
					remaining = min( remaining, 1 );
 | 
										remaining = min( remaining, 1 );
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					remaining -= len;
 | 
										remaining -= len;
 | 
				
			||||||
				arg  -= zpl_cast( f64 ) value / mult;
 | 
									arg  -= scast( f64, value / mult);
 | 
				
			||||||
				mult *= 10;
 | 
									mult *= 10;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -239,15 +239,15 @@ internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexad
 | 
				
			|||||||
	return ( text - text_begin );
 | 
						return ( text - text_begin );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
					neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char const* text_begin = text;
 | 
						char const* text_begin = text;
 | 
				
			||||||
	sw          remaining  = max_len, res;
 | 
						ssize          remaining  = max_len, res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while ( *fmt )
 | 
						while ( *fmt )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		_format_info info = { 0 };
 | 
							_format_info info = { 0 };
 | 
				
			||||||
		sw           len  = 0;
 | 
							ssize           len  = 0;
 | 
				
			||||||
		info.precision    = -1;
 | 
							info.precision    = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while ( *fmt && *fmt != '%' && remaining )
 | 
							while ( *fmt && *fmt != '%' && remaining )
 | 
				
			||||||
@@ -311,7 +311,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			info.width = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
 | 
								info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
 | 
				
			||||||
			if ( info.width != 0 )
 | 
								if ( info.width != 0 )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				info.flags |= GEN_FMT_WIDTH;
 | 
									info.flags |= GEN_FMT_WIDTH;
 | 
				
			||||||
@@ -329,7 +329,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				info.precision = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
 | 
									info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			info.flags &= ~GEN_FMT_ZERO;
 | 
								info.flags &= ~GEN_FMT_ZERO;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -411,7 +411,7 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
				
			|||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case 'c' :
 | 
								case 'c' :
 | 
				
			||||||
				len = _print_char( text, remaining, &info, zpl_cast( char ) va_arg( va, int ) );
 | 
									len = _print_char( text, remaining, &info, scast( char, va_arg( va, int ) ));
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case 's' :
 | 
								case 's' :
 | 
				
			||||||
@@ -455,25 +455,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
				
			|||||||
				switch ( info.flags & GEN_FMT_INTS )
 | 
									switch ( info.flags & GEN_FMT_INTS )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					case GEN_FMT_CHAR :
 | 
										case GEN_FMT_CHAR :
 | 
				
			||||||
						value = zpl_cast( u64 ) zpl_cast( u8 ) va_arg( va, int );
 | 
											value = scast( u64, scast( u8, va_arg( va, int )));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_SHORT :
 | 
										case GEN_FMT_SHORT :
 | 
				
			||||||
						value = zpl_cast( u64 ) zpl_cast( u16 ) va_arg( va, int );
 | 
											value = scast( u64, scast( u16, va_arg( va, int )));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_LONG:
 | 
										case GEN_FMT_LONG:
 | 
				
			||||||
						value = zpl_cast( u64 ) va_arg( va, unsigned long );
 | 
											value = scast( u64, va_arg( va, unsigned long ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_LLONG :
 | 
										case GEN_FMT_LLONG :
 | 
				
			||||||
						value = zpl_cast( u64 ) va_arg( va, unsigned long long );
 | 
											value = scast( u64, va_arg( va, unsigned long long ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_SIZE :
 | 
										case GEN_FMT_SIZE :
 | 
				
			||||||
						value = zpl_cast( u64 ) va_arg( va, uw );
 | 
											value = scast( u64, va_arg( va, usize ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_INTPTR :
 | 
										case GEN_FMT_INTPTR :
 | 
				
			||||||
						value = zpl_cast( u64 ) va_arg( va, uptr );
 | 
											value = scast( u64, va_arg( va, uptr ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					default :
 | 
										default :
 | 
				
			||||||
						value = zpl_cast( u64 ) va_arg( va, unsigned int );
 | 
											value = scast( u64, va_arg( va, unsigned int ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -485,25 +485,25 @@ neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
 | 
				
			|||||||
				switch ( info.flags & GEN_FMT_INTS )
 | 
									switch ( info.flags & GEN_FMT_INTS )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					case GEN_FMT_CHAR :
 | 
										case GEN_FMT_CHAR :
 | 
				
			||||||
						value = zpl_cast( s64 ) zpl_cast( s8 ) va_arg( va, int );
 | 
											value = scast( s64, scast( s8, va_arg( va, int )));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_SHORT :
 | 
										case GEN_FMT_SHORT :
 | 
				
			||||||
						value = zpl_cast( s64 ) zpl_cast( s16 ) va_arg( va, int );
 | 
											value = scast( s64, scast( s16, va_arg( va, int )));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_LONG :
 | 
										case GEN_FMT_LONG :
 | 
				
			||||||
						value = zpl_cast( s64 ) va_arg( va, long );
 | 
											value = scast( s64, va_arg( va, long ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_LLONG :
 | 
										case GEN_FMT_LLONG :
 | 
				
			||||||
						value = zpl_cast( s64 ) va_arg( va, long long );
 | 
											value = scast( s64, va_arg( va, long long ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_SIZE :
 | 
										case GEN_FMT_SIZE :
 | 
				
			||||||
						value = zpl_cast( s64 ) va_arg( va, uw );
 | 
											value = scast( s64, va_arg( va, usize ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					case GEN_FMT_INTPTR :
 | 
										case GEN_FMT_INTPTR :
 | 
				
			||||||
						value = zpl_cast( s64 ) va_arg( va, uptr );
 | 
											value = scast( s64, va_arg( va, uptr ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
					default :
 | 
										default :
 | 
				
			||||||
						value = zpl_cast( s64 ) va_arg( va, int );
 | 
											value = scast( s64, va_arg( va, int ));
 | 
				
			||||||
						break;
 | 
											break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -540,17 +540,17 @@ char* str_fmt_buf( char const* fmt, ... )
 | 
				
			|||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
 | 
					ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
 | 
						local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
 | 
				
			||||||
	sw                              len = str_fmt_va( buf, size_of( buf ), fmt, va );
 | 
						ssize                              len = str_fmt_va( buf, size_of( buf ), fmt, va );
 | 
				
			||||||
	b32                             res = file_write( f, buf, len - 1 );    // NOTE: prevent extra whitespace
 | 
						b32                             res = file_write( f, buf, len - 1 );    // NOTE: prevent extra whitespace
 | 
				
			||||||
	return res ? len : -1;
 | 
						return res ? len : -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt_file( struct FileInfo* f, char const* fmt, ... )
 | 
					ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw      res;
 | 
						ssize      res;
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start( va, fmt );
 | 
						va_start( va, fmt );
 | 
				
			||||||
	res = str_fmt_file_va( f, fmt, va );
 | 
						res = str_fmt_file_va( f, fmt, va );
 | 
				
			||||||
@@ -558,9 +558,9 @@ sw str_fmt_file( struct FileInfo* f, char const* fmt, ... )
 | 
				
			|||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt( char* str, sw n, char const* fmt, ... )
 | 
					ssize str_fmt( char* str, ssize n, char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw      res;
 | 
						ssize      res;
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start( va, fmt );
 | 
						va_start( va, fmt );
 | 
				
			||||||
	res = str_fmt_va( str, n, fmt, va );
 | 
						res = str_fmt_va( str, n, fmt, va );
 | 
				
			||||||
@@ -568,19 +568,19 @@ sw str_fmt( char* str, sw n, char const* fmt, ... )
 | 
				
			|||||||
	return res;
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt_out_va( char const* fmt, va_list va )
 | 
					ssize str_fmt_out_va( char const* fmt, va_list va )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
 | 
						return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt_out_err_va( char const* fmt, va_list va )
 | 
					ssize str_fmt_out_err_va( char const* fmt, va_list va )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
 | 
						return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sw str_fmt_out_err( char const* fmt, ... )
 | 
					ssize str_fmt_out_err( char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw      res;
 | 
						ssize      res;
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start( va, fmt );
 | 
						va_start( va, fmt );
 | 
				
			||||||
	res = str_fmt_out_err_va( fmt, va );
 | 
						res = str_fmt_out_err_va( fmt, va );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,21 +14,21 @@ struct FileInfo;
 | 
				
			|||||||
// NOTE: A locally persisting buffer is used internally
 | 
					// NOTE: A locally persisting buffer is used internally
 | 
				
			||||||
char*  str_fmt_buf       ( char const* fmt, ... );
 | 
					char*  str_fmt_buf       ( char const* fmt, ... );
 | 
				
			||||||
char*  str_fmt_buf_va    ( char const* fmt, va_list va );
 | 
					char*  str_fmt_buf_va    ( char const* fmt, va_list va );
 | 
				
			||||||
sw    str_fmt           ( char* str, sw n, char const* fmt, ... );
 | 
					ssize  str_fmt           ( char* str, ssize n, char const* fmt, ... );
 | 
				
			||||||
sw    str_fmt_va        ( char* str, sw n, char const* fmt, va_list va );
 | 
					ssize  str_fmt_va        ( char* str, ssize n, char const* fmt, va_list va );
 | 
				
			||||||
sw    str_fmt_out_va    ( char const* fmt, va_list va );
 | 
					ssize  str_fmt_out_va    ( char const* fmt, va_list va );
 | 
				
			||||||
sw    str_fmt_out_err   ( char const* fmt, ... );
 | 
					ssize  str_fmt_out_err   ( char const* fmt, ... );
 | 
				
			||||||
sw    str_fmt_out_err_va( char const* fmt, va_list va );
 | 
					ssize  str_fmt_out_err_va( char const* fmt, va_list va );
 | 
				
			||||||
sw    str_fmt_file      ( FileInfo* f, char const* fmt, ... );
 | 
					ssize  str_fmt_file      ( FileInfo* f, char const* fmt, ... );
 | 
				
			||||||
sw    str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va );
 | 
					ssize  str_fmt_file_va   ( FileInfo* f, char const* fmt, va_list va );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr
 | 
					constexpr
 | 
				
			||||||
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
 | 
					char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline
 | 
					inline
 | 
				
			||||||
sw log_fmt(char const* fmt, ...)
 | 
					ssize log_fmt(char const* fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw res;
 | 
						ssize res;
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_start(va, fmt);
 | 
						va_start(va, fmt);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
#pragma region String Ops
 | 
					#pragma region String Ops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
internal
 | 
					internal
 | 
				
			||||||
sw _scan_zpl_i64( const char* text, s32 base, s64* value )
 | 
					ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char* text_begin = text;
 | 
						const char* text_begin = text;
 | 
				
			||||||
	s64         result     = 0;
 | 
						s64         result     = 0;
 | 
				
			||||||
@@ -56,7 +56,7 @@ global const char _num_to_char_table[] =
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
s64 str_to_i64( const char* str, char** end_ptr, s32 base )
 | 
					s64 str_to_i64( const char* str, char** end_ptr, s32 base )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw  len;
 | 
						ssize  len;
 | 
				
			||||||
	s64 value;
 | 
						s64 value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( ! base )
 | 
						if ( ! base )
 | 
				
			||||||
@@ -85,7 +85,7 @@ void i64_to_str( s64 value, char* string, s32 base )
 | 
				
			|||||||
		value    = -value;
 | 
							value    = -value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v = zpl_cast( u64 ) value;
 | 
						v = scast( u64, value);
 | 
				
			||||||
	if ( v != 0 )
 | 
						if ( v != 0 )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		while ( v > 0 )
 | 
							while ( v > 0 )
 | 
				
			||||||
@@ -207,7 +207,7 @@ f64 str_to_f64( const char* str, char** end_ptr )
 | 
				
			|||||||
	result = sign * ( frac ? ( value / scale ) : ( value * scale ) );
 | 
						result = sign * ( frac ? ( value / scale ) : ( value * scale ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if ( end_ptr )
 | 
						if ( end_ptr )
 | 
				
			||||||
		*end_ptr = zpl_cast( char* ) str;
 | 
							* end_ptr = rcast( char*, ccast(char*, str) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,41 +5,42 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region String Ops
 | 
					#pragma region String Ops
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE const char* char_first_occurence( const char* str, char c );
 | 
					const char* char_first_occurence( const char* str, char c );
 | 
				
			||||||
constexpr auto str_find = &char_first_occurence;
 | 
					constexpr auto str_find = &char_first_occurence;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE b32   char_is_alpha( char c );
 | 
					b32   char_is_alpha( char c );
 | 
				
			||||||
GEN_DEF_INLINE b32   char_is_alphanumeric( char c );
 | 
					b32   char_is_alphanumeric( char c );
 | 
				
			||||||
GEN_DEF_INLINE b32   char_is_digit( char c );
 | 
					b32   char_is_digit( char c );
 | 
				
			||||||
GEN_DEF_INLINE b32   char_is_hex_digit( char c );
 | 
					b32   char_is_hex_digit( char c );
 | 
				
			||||||
GEN_DEF_INLINE b32   char_is_space( char c );
 | 
					b32   char_is_space( char c );
 | 
				
			||||||
GEN_DEF_INLINE char  char_to_lower( char c );
 | 
					char  char_to_lower( char c );
 | 
				
			||||||
GEN_DEF_INLINE char  char_to_upper( char c );
 | 
					char  char_to_upper( char c );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE s32  digit_to_int( char c );
 | 
					s32  digit_to_int( char c );
 | 
				
			||||||
GEN_DEF_INLINE s32  hex_digit_to_int( char c );
 | 
					s32  hex_digit_to_int( char c );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_DEF_INLINE s32         str_compare( const char* s1, const char* s2 );
 | 
					s32         str_compare( const char* s1, const char* s2 );
 | 
				
			||||||
GEN_DEF_INLINE s32         str_compare( const char* s1, const char* s2, sw len );
 | 
					s32         str_compare( const char* s1, const char* s2, ssize len );
 | 
				
			||||||
GEN_DEF_INLINE char*       str_copy( char* dest, const char* source, sw len );
 | 
					char*       str_copy( char* dest, const char* source, ssize len );
 | 
				
			||||||
GEN_DEF_INLINE sw          str_copy_nulpad( char* dest, const char* source, sw len );
 | 
					ssize       str_copy_nulpad( char* dest, const char* source, ssize len );
 | 
				
			||||||
GEN_DEF_INLINE sw          str_len( const char* str );
 | 
					ssize       str_len( const char* str );
 | 
				
			||||||
GEN_DEF_INLINE sw          str_len( const char* str, sw max_len );
 | 
					ssize       str_len( const char* str, ssize max_len );
 | 
				
			||||||
GEN_DEF_INLINE char*       str_reverse( char* str );    // NOTE: ASCII only
 | 
					char*       str_reverse( char* str );    // NOTE: ASCII only
 | 
				
			||||||
GEN_DEF_INLINE char const* str_skip( char const* str, char c );
 | 
					char const* str_skip( char const* str, char c );
 | 
				
			||||||
GEN_DEF_INLINE char const* str_skip_any( char const* str, char const* char_list );
 | 
					char const* str_skip_any( char const* str, char const* char_list );
 | 
				
			||||||
GEN_DEF_INLINE char const* str_trim( char const* str, b32 catch_newline );
 | 
					char const* str_trim( char const* str, b32 catch_newline );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NOTE: ASCII only
 | 
					// NOTE: ASCII only
 | 
				
			||||||
GEN_DEF_INLINE void str_to_lower( char* str );
 | 
					void str_to_lower( char* str );
 | 
				
			||||||
GEN_DEF_INLINE void str_to_upper( char* str );
 | 
					void str_to_upper( char* str );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
s64  str_to_i64( const char* str, char** end_ptr, s32 base );
 | 
					s64  str_to_i64( const char* str, char** end_ptr, s32 base );
 | 
				
			||||||
void i64_to_str( s64 value, char* string, s32 base );
 | 
					void i64_to_str( s64 value, char* string, s32 base );
 | 
				
			||||||
void u64_to_str( u64 value, char* string, s32 base );
 | 
					void u64_to_str( u64 value, char* string, s32 base );
 | 
				
			||||||
f64  str_to_f64( const char* str, char** end_ptr );
 | 
					f64  str_to_f64( const char* str, char** end_ptr );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
 | 
					inline
 | 
				
			||||||
 | 
					const char* char_first_occurence( const char* s, char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char ch = c;
 | 
						char ch = c;
 | 
				
			||||||
	for ( ; *s != ch; s++ )
 | 
						for ( ; *s != ch; s++ )
 | 
				
			||||||
@@ -50,59 +51,67 @@ GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
 | 
				
			|||||||
	return s;
 | 
						return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 char_is_alpha( char c )
 | 
					inline
 | 
				
			||||||
 | 
					b32 char_is_alpha( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
 | 
						if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 char_is_alphanumeric( char c )
 | 
					inline
 | 
				
			||||||
 | 
					b32 char_is_alphanumeric( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return char_is_alpha( c ) || char_is_digit( c );
 | 
						return char_is_alpha( c ) || char_is_digit( c );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 char_is_digit( char c )
 | 
					inline
 | 
				
			||||||
 | 
					b32 char_is_digit( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( c >= '0' && c <= '9' )
 | 
						if ( c >= '0' && c <= '9' )
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 char_is_hex_digit( char c )
 | 
					inline
 | 
				
			||||||
 | 
					b32 char_is_hex_digit( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) )
 | 
						if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) )
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE b32 char_is_space( char c )
 | 
					inline
 | 
				
			||||||
 | 
					b32 char_is_space( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' )
 | 
						if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' )
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char char_to_lower( char c )
 | 
					inline
 | 
				
			||||||
 | 
					char char_to_lower( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( c >= 'A' && c <= 'Z' )
 | 
						if ( c >= 'A' && c <= 'Z' )
 | 
				
			||||||
		return 'a' + ( c - 'A' );
 | 
							return 'a' + ( c - 'A' );
 | 
				
			||||||
	return c;
 | 
						return c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char char_to_upper( char c )
 | 
					inline char char_to_upper( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( c >= 'a' && c <= 'z' )
 | 
						if ( c >= 'a' && c <= 'z' )
 | 
				
			||||||
		return 'A' + ( c - 'a' );
 | 
							return 'A' + ( c - 'a' );
 | 
				
			||||||
	return c;
 | 
						return c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE s32 digit_to_int( char c )
 | 
					inline
 | 
				
			||||||
 | 
					s32 digit_to_int( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return char_is_digit( c ) ? c - '0' : c - 'W';
 | 
						return char_is_digit( c ) ? c - '0' : c - 'W';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE s32 hex_digit_to_int( char c )
 | 
					inline
 | 
				
			||||||
 | 
					s32 hex_digit_to_int( char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( char_is_digit( c ) )
 | 
						if ( char_is_digit( c ) )
 | 
				
			||||||
		return digit_to_int( c );
 | 
							return digit_to_int( c );
 | 
				
			||||||
@@ -113,7 +122,8 @@ GEN_IMPL_INLINE s32 hex_digit_to_int( char c )
 | 
				
			|||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
 | 
					inline
 | 
				
			||||||
 | 
					s32 str_compare( const char* s1, const char* s2 )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while ( *s1 && ( *s1 == *s2 ) )
 | 
						while ( *s1 && ( *s1 == *s2 ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -122,7 +132,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
 | 
				
			|||||||
	return *( u8* )s1 - *( u8* )s2;
 | 
						return *( u8* )s1 - *( u8* )s2;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
 | 
					inline
 | 
				
			||||||
 | 
					s32 str_compare( const char* s1, const char* s2, ssize len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	for ( ; len > 0; s1++, s2++, len-- )
 | 
						for ( ; len > 0; s1++, s2++, len-- )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -134,7 +145,8 @@ GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
 | 
					inline
 | 
				
			||||||
 | 
					char* str_copy( char* dest, const char* source, ssize len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( dest );
 | 
						GEN_ASSERT_NOT_NULL( dest );
 | 
				
			||||||
	if ( source )
 | 
						if ( source )
 | 
				
			||||||
@@ -154,9 +166,10 @@ GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
 | 
				
			|||||||
	return dest;
 | 
						return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
 | 
					inline
 | 
				
			||||||
 | 
					ssize str_copy_nulpad( char* dest, const char* source, ssize len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw result = 0;
 | 
						ssize result = 0;
 | 
				
			||||||
	GEN_ASSERT_NOT_NULL( dest );
 | 
						GEN_ASSERT_NOT_NULL( dest );
 | 
				
			||||||
	if ( source )
 | 
						if ( source )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -178,7 +191,8 @@ GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
 | 
				
			|||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE sw str_len( const char* str )
 | 
					inline
 | 
				
			||||||
 | 
					ssize str_len( const char* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( str == NULL )
 | 
						if ( str == NULL )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -190,17 +204,19 @@ GEN_IMPL_INLINE sw str_len( const char* str )
 | 
				
			|||||||
	return str - p;
 | 
						return str - p;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE sw str_len( const char* str, sw max_len )
 | 
					inline
 | 
				
			||||||
 | 
					ssize str_len( const char* str, ssize max_len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char* end = zpl_cast( const char* ) mem_find( str, 0, max_len );
 | 
						const char* end = rcast(const char*, mem_find( str, 0, max_len ));
 | 
				
			||||||
	if ( end )
 | 
						if ( end )
 | 
				
			||||||
		return end - str;
 | 
							return end - str;
 | 
				
			||||||
	return max_len;
 | 
						return max_len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char* str_reverse( char* str )
 | 
					inline
 | 
				
			||||||
 | 
					char* str_reverse( char* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw    len  = str_len( str );
 | 
						ssize    len  = str_len( str );
 | 
				
			||||||
	char* a    = str + 0;
 | 
						char* a    = str + 0;
 | 
				
			||||||
	char* b    = str + len - 1;
 | 
						char* b    = str + len - 1;
 | 
				
			||||||
	len       /= 2;
 | 
						len       /= 2;
 | 
				
			||||||
@@ -212,7 +228,8 @@ GEN_IMPL_INLINE char* str_reverse( char* str )
 | 
				
			|||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char const* str_skip( char const* str, char c )
 | 
					inline
 | 
				
			||||||
 | 
					char const* str_skip( char const* str, char c )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while ( *str && *str != c )
 | 
						while ( *str && *str != c )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -221,11 +238,12 @@ GEN_IMPL_INLINE char const* str_skip( char const* str, char c )
 | 
				
			|||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list )
 | 
					inline
 | 
				
			||||||
 | 
					char const* str_skip_any( char const* str, char const* char_list )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char const* closest_ptr     = zpl_cast( char const* ) pointer_add( ( void* )str, str_len( str ) );
 | 
						char const* closest_ptr     = rcast( char const*, pointer_add_const( rcast(void const*, str), str_len( str ) ));
 | 
				
			||||||
	sw          char_list_count = str_len( char_list );
 | 
						ssize       char_list_count = str_len( char_list );
 | 
				
			||||||
	for ( sw i = 0; i < char_list_count; i++ )
 | 
						for ( ssize i = 0; i < char_list_count; i++ )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char const* p = str_skip( str, char_list[ i ] );
 | 
							char const* p = str_skip( str, char_list[ i ] );
 | 
				
			||||||
		closest_ptr   = min( closest_ptr, p );
 | 
							closest_ptr   = min( closest_ptr, p );
 | 
				
			||||||
@@ -233,7 +251,8 @@ GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list
 | 
				
			|||||||
	return closest_ptr;
 | 
						return closest_ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline )
 | 
					inline
 | 
				
			||||||
 | 
					char const* str_trim( char const* str, b32 catch_newline )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
 | 
						while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -242,7 +261,8 @@ GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline )
 | 
				
			|||||||
	return str;
 | 
						return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE void str_to_lower( char* str )
 | 
					inline
 | 
				
			||||||
 | 
					void str_to_lower( char* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( ! str )
 | 
						if ( ! str )
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
@@ -253,7 +273,8 @@ GEN_IMPL_INLINE void str_to_lower( char* str )
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_IMPL_INLINE void str_to_upper( char* str )
 | 
					inline
 | 
				
			||||||
 | 
					void str_to_upper( char* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ( ! str )
 | 
						if ( ! str )
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma region String
 | 
					#pragma region String
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... )
 | 
					String String::fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
	va_start( va, fmt );
 | 
						va_start( va, fmt );
 | 
				
			||||||
@@ -15,9 +15,9 @@ String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const*
 | 
				
			|||||||
	return make( allocator, buf );
 | 
						return make( allocator, buf );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String String::make_length( AllocatorInfo allocator, char const* str, sw length )
 | 
					String String::make_length( AllocatorInfo allocator, char const* str, ssize length )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	constexpr sw header_size = sizeof( Header );
 | 
						constexpr ssize header_size = sizeof( Header );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s32   alloc_size = header_size + length + 1;
 | 
						s32   alloc_size = header_size + length + 1;
 | 
				
			||||||
	void* allocation = alloc( allocator, alloc_size );
 | 
						void* allocation = alloc( allocator, alloc_size );
 | 
				
			||||||
@@ -41,9 +41,9 @@ String String::make_length( AllocatorInfo allocator, char const* str, sw length
 | 
				
			|||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
String String::make_reserve( AllocatorInfo allocator, sw capacity )
 | 
					String String::make_reserve( AllocatorInfo allocator, ssize capacity )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	constexpr sw header_size = sizeof( Header );
 | 
						constexpr ssize header_size = sizeof( Header );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s32   alloc_size = header_size + capacity + 1;
 | 
						s32   alloc_size = header_size + capacity + 1;
 | 
				
			||||||
	void* allocation = alloc( allocator, alloc_size );
 | 
						void* allocation = alloc( allocator, alloc_size );
 | 
				
			||||||
@@ -78,7 +78,7 @@ String String::fmt_buf( AllocatorInfo allocator, char const* fmt, ... )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
bool String::append_fmt( char const* fmt, ... )
 | 
					bool String::append_fmt( char const* fmt, ... )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw   res;
 | 
						ssize   res;
 | 
				
			||||||
	char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
 | 
						char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	va_list va;
 | 
						va_list va;
 | 
				
			||||||
@@ -89,9 +89,9 @@ bool String::append_fmt( char const* fmt, ... )
 | 
				
			|||||||
	return append( buf, res );
 | 
						return append( buf, res );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool String::make_space_for( char const* str, sw add_len )
 | 
					bool String::make_space_for( char const* str, ssize add_len )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw available = avail_space();
 | 
						ssize available = avail_space();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// NOTE: Return if there is enough space left
 | 
						// NOTE: Return if there is enough space left
 | 
				
			||||||
	if ( available >= add_len )
 | 
						if ( available >= add_len )
 | 
				
			||||||
@@ -100,7 +100,7 @@ bool String::make_space_for( char const* str, sw add_len )
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw new_len, old_size, new_size;
 | 
							ssize new_len, old_size, new_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void* ptr;
 | 
							void* ptr;
 | 
				
			||||||
		void* new_ptr;
 | 
							void* new_ptr;
 | 
				
			||||||
@@ -118,13 +118,13 @@ bool String::make_space_for( char const* str, sw add_len )
 | 
				
			|||||||
		if ( new_ptr == nullptr )
 | 
							if ( new_ptr == nullptr )
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header            = zpl_cast( Header* ) new_ptr;
 | 
							header            = rcast( Header*, new_ptr);
 | 
				
			||||||
		header->Allocator = allocator;
 | 
							header->Allocator = allocator;
 | 
				
			||||||
		header->Capacity  = new_len;
 | 
							header->Capacity  = new_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Data = rcast( char*, header + 1 );
 | 
							Data = rcast( char*, header + 1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return str;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#pragma endregion String
 | 
					#pragma endregion String
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,16 +8,17 @@
 | 
				
			|||||||
// Constant string with length.
 | 
					// Constant string with length.
 | 
				
			||||||
struct StrC
 | 
					struct StrC
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	sw          Len;
 | 
						ssize          Len;
 | 
				
			||||||
	char const* Ptr;
 | 
						char const* Ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	operator char const* ()               const { return Ptr; }
 | 
						operator char const* ()               const { return Ptr; }
 | 
				
			||||||
	char const& operator[]( sw index ) const { return Ptr[index]; }
 | 
						char const& operator[]( ssize index ) const { return Ptr[index]; }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
 | 
					#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
 | 
				
			||||||
#define txt( text )         StrC { sizeof( text ) - 1, ( text ) }
 | 
					#define txt( text )         StrC { sizeof( text ) - 1, ( text ) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline
 | 
				
			||||||
StrC to_str( char const* str )
 | 
					StrC to_str( char const* str )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return { str_len( str ), str };
 | 
						return { str_len( str ), str };
 | 
				
			||||||
@@ -32,12 +33,12 @@ struct String
 | 
				
			|||||||
	struct Header
 | 
						struct Header
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		AllocatorInfo Allocator;
 | 
							AllocatorInfo Allocator;
 | 
				
			||||||
		sw            Capacity;
 | 
							ssize            Capacity;
 | 
				
			||||||
		sw            Length;
 | 
							ssize            Length;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	uw grow_formula( uw value )
 | 
						usize grow_formula( usize value )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
 | 
							// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
 | 
				
			||||||
		return 4 * value + 8;
 | 
							return 4 * value + 8;
 | 
				
			||||||
@@ -46,7 +47,7 @@ struct String
 | 
				
			|||||||
	static
 | 
						static
 | 
				
			||||||
	String make( AllocatorInfo allocator, char const* str )
 | 
						String make( AllocatorInfo allocator, char const* str )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw length = str ? str_len( str ) : 0;
 | 
							ssize length = str ? str_len( str ) : 0;
 | 
				
			||||||
		return make_length( allocator, str, length );
 | 
							return make_length( allocator, str, length );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,23 +58,23 @@ struct String
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	String make_reserve( AllocatorInfo allocator, sw capacity );
 | 
						String make_reserve( AllocatorInfo allocator, ssize capacity );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	String make_length( AllocatorInfo allocator, char const* str, sw length );
 | 
						String make_length( AllocatorInfo allocator, char const* str, ssize length );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	String fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... );
 | 
						String fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	String fmt_buf( AllocatorInfo allocator, char const* fmt, ... );
 | 
						String fmt_buf( AllocatorInfo allocator, char const* fmt, ... );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static
 | 
						static
 | 
				
			||||||
	String join( AllocatorInfo allocator, char const** parts, sw num_parts, char const* glue )
 | 
						String join( AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		String result = make( allocator, "" );
 | 
							String result = make( allocator, "" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = 0; idx < num_parts; ++idx )
 | 
							for ( ssize idx = 0; idx < num_parts; ++idx )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			result.append( parts[ idx ] );
 | 
								result.append( parts[ idx ] );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -90,7 +91,7 @@ struct String
 | 
				
			|||||||
		if ( lhs.length() != rhs.length() )
 | 
							if ( lhs.length() != rhs.length() )
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = 0; idx < lhs.length(); ++idx )
 | 
							for ( ssize idx = 0; idx < lhs.length(); ++idx )
 | 
				
			||||||
			if ( lhs[ idx ] != rhs[ idx ] )
 | 
								if ( lhs[ idx ] != rhs[ idx ] )
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -103,14 +104,14 @@ struct String
 | 
				
			|||||||
		if ( lhs.length() != (rhs.Len) )
 | 
							if ( lhs.length() != (rhs.Len) )
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for ( sw idx = 0; idx < lhs.length(); ++idx )
 | 
							for ( ssize idx = 0; idx < lhs.length(); ++idx )
 | 
				
			||||||
			if ( lhs[idx] != rhs[idx] )
 | 
								if ( lhs[idx] != rhs[idx] )
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool make_space_for( char const* str, sw add_len );
 | 
						bool make_space_for( char const* str, ssize add_len );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append( char c )
 | 
						bool append( char c )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -122,11 +123,11 @@ struct String
 | 
				
			|||||||
		return append( str, str_len( str ) );
 | 
							return append( str, str_len( str ) );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append( char const* str, sw length )
 | 
						bool append( char const* str, ssize length )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if ( sptr(str) > 0 )
 | 
							if ( sptr(str) > 0 )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sw curr_len = this->length();
 | 
								ssize curr_len = this->length();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if ( ! make_space_for( str, length ) )
 | 
								if ( ! make_space_for( str, length ) )
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
@@ -139,7 +140,7 @@ struct String
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			header.Length = curr_len + length;
 | 
								header.Length = curr_len + length;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return str;
 | 
							return str != nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool append( StrC str)
 | 
						bool append( StrC str)
 | 
				
			||||||
@@ -154,7 +155,7 @@ struct String
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool append_fmt( char const* fmt, ... );
 | 
						bool append_fmt( char const* fmt, ... );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw avail_space() const
 | 
						ssize avail_space() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header const&
 | 
							Header const&
 | 
				
			||||||
		header = * rcast( Header const*, Data - sizeof( Header ));
 | 
							header = * rcast( Header const*, Data - sizeof( Header ));
 | 
				
			||||||
@@ -167,7 +168,7 @@ struct String
 | 
				
			|||||||
		return Data[ length() - 1 ];
 | 
							return Data[ length() - 1 ];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw capacity() const
 | 
						ssize capacity() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header const&
 | 
							Header const&
 | 
				
			||||||
		header = * rcast( Header const*, Data - sizeof( Header ));
 | 
							header = * rcast( Header const*, Data - sizeof( Header ));
 | 
				
			||||||
@@ -200,7 +201,7 @@ struct String
 | 
				
			|||||||
		return *(Header*)(Data - sizeof(Header));
 | 
							return *(Header*)(Data - sizeof(Header));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sw length() const
 | 
						ssize length() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		Header const&
 | 
							Header const&
 | 
				
			||||||
		header = * rcast( Header const*, Data - sizeof( Header ));
 | 
							header = * rcast( Header const*, Data - sizeof( Header ));
 | 
				
			||||||
@@ -272,7 +273,7 @@ struct String
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void trim( char const* cut_set )
 | 
						void trim( char const* cut_set )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		sw len = 0;
 | 
							ssize len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		char* start_pos = Data;
 | 
							char* start_pos = Data;
 | 
				
			||||||
		char* end_pos   = Data + length() - 1;
 | 
							char* end_pos   = Data + length() - 1;
 | 
				
			||||||
@@ -283,7 +284,7 @@ struct String
 | 
				
			|||||||
		while ( end_pos > start_pos && char_first_occurence( cut_set, *end_pos ) )
 | 
							while ( end_pos > start_pos && char_first_occurence( cut_set, *end_pos ) )
 | 
				
			||||||
			end_pos--;
 | 
								end_pos--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		len = scast( sw, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) );
 | 
							len = scast( ssize, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if ( Data != start_pos )
 | 
							if ( Data != start_pos )
 | 
				
			||||||
			mem_move( Data, start_pos, len );
 | 
								mem_move( Data, start_pos, len );
 | 
				
			||||||
@@ -353,7 +354,7 @@ struct String
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	operator bool()
 | 
						operator bool()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return Data;
 | 
							return Data != nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	operator char* ()
 | 
						operator char* ()
 | 
				
			||||||
@@ -378,19 +379,19 @@ struct String
 | 
				
			|||||||
		if ( this == & other )
 | 
							if ( this == & other )
 | 
				
			||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		String& this_ = ccast( String, *this );
 | 
							String*
 | 
				
			||||||
 | 
							this_ = ccast(String*, this);
 | 
				
			||||||
 | 
							this_->Data = other.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this_.Data = other.Data;
 | 
							return *this;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		return this_;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char& operator [] ( sw index )
 | 
						char& operator [] ( ssize index )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return Data[ index ];
 | 
							return Data[ index ];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char const& operator [] ( sw index ) const
 | 
						char const& operator [] ( ssize index ) const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return Data[ index ];
 | 
							return Data[ index ];
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		u32 hi, lo;
 | 
							u32 hi, lo;
 | 
				
			||||||
		__asm__ __volatile__( "rdtsc" : "=a"( lo ), "=d"( hi ) );
 | 
							__asm__ __volatile__( "rdtsc" : "=a"( lo ), "=d"( hi ) );
 | 
				
			||||||
		return ( zpl_cast( u64 ) lo ) | ( ( zpl_cast( u64 ) hi ) << 32 );
 | 
							return scast( u64, lo ) | ( scast( u64, hi ) << 32 );
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	#elif defined( __powerpc__ )
 | 
						#elif defined( __powerpc__ )
 | 
				
			||||||
	u64 read_cpu_time_stamp_counter( void )
 | 
						u64 read_cpu_time_stamp_counter( void )
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
 | 
					// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dependencies/header_start.hpp"
 | 
					#include "dependencies/platform.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
GEN_NS_BEGIN
 | 
					GEN_NS_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@ CodeBody gen_ecode( char const* path )
 | 
				
			|||||||
#pragma push_macro("local_persist")
 | 
					#pragma push_macro("local_persist")
 | 
				
			||||||
#undef local_persist
 | 
					#undef local_persist
 | 
				
			||||||
	CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
						CodeFn to_str = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		StrC to_str( Type type )
 | 
							StrC to_str( Type type )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -69,7 +70,7 @@ CodeBody gen_eoperator( char const* path )
 | 
				
			|||||||
	String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
						String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
				
			||||||
	String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
						String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (uw idx = 0; idx < enum_strs.num(); idx++)
 | 
						for (usize idx = 0; idx < enum_strs.num(); idx++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char const* enum_str     = enum_strs[idx].string;
 | 
							char const* enum_str     = enum_strs[idx].string;
 | 
				
			||||||
		char const* entry_to_str = str_strs [idx].string;
 | 
							char const* entry_to_str = str_strs [idx].string;
 | 
				
			||||||
@@ -89,6 +90,7 @@ CodeBody gen_eoperator( char const* path )
 | 
				
			|||||||
#pragma push_macro("local_persist")
 | 
					#pragma push_macro("local_persist")
 | 
				
			||||||
#undef local_persist
 | 
					#undef local_persist
 | 
				
			||||||
	CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
 | 
						CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		StrC to_str( Type op )
 | 
							StrC to_str( Type op )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -124,7 +126,7 @@ CodeBody gen_especifier( char const* path )
 | 
				
			|||||||
	String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
						String enum_entries   = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
				
			||||||
	String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
						String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (uw idx = 0; idx < enum_strs.num(); idx++)
 | 
						for (usize idx = 0; idx < enum_strs.num(); idx++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char const* enum_str     = enum_strs[idx].string;
 | 
							char const* enum_str     = enum_strs[idx].string;
 | 
				
			||||||
		char const* entry_to_str = str_strs [idx].string;
 | 
							char const* entry_to_str = str_strs [idx].string;
 | 
				
			||||||
@@ -142,6 +144,7 @@ CodeBody gen_especifier( char const* path )
 | 
				
			|||||||
	)));
 | 
						)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
 | 
						CodeFn is_trailing = parse_function(token_fmt("specifier", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		bool is_trailing( Type specifier )
 | 
							bool is_trailing( Type specifier )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return specifier > Virtual;
 | 
								return specifier > Virtual;
 | 
				
			||||||
@@ -159,6 +162,7 @@ CodeBody gen_especifier( char const* path )
 | 
				
			|||||||
#undef forceinline
 | 
					#undef forceinline
 | 
				
			||||||
#undef neverinline
 | 
					#undef neverinline
 | 
				
			||||||
	CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
 | 
						CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		StrC to_str( Type type )
 | 
							StrC to_str( Type type )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -171,6 +175,7 @@ CodeBody gen_especifier( char const* path )
 | 
				
			|||||||
	)));
 | 
						)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
						CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		Type to_type( StrC str )
 | 
							Type to_type( StrC str )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -236,7 +241,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
 | 
				
			|||||||
	String to_str_attributes        = String::make_reserve( GlobalAllocator, kilobytes(4) );
 | 
						String to_str_attributes        = String::make_reserve( GlobalAllocator, kilobytes(4) );
 | 
				
			||||||
	String attribute_define_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
 | 
						String attribute_define_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (uw idx = 0; idx < enum_strs.num(); idx++)
 | 
						for (usize idx = 0; idx < enum_strs.num(); idx++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char const* enum_str     = enum_strs[idx].string;
 | 
							char const* enum_str     = enum_strs[idx].string;
 | 
				
			||||||
		char const* entry_to_str = enum_str_strs [idx].string;
 | 
							char const* entry_to_str = enum_str_strs [idx].string;
 | 
				
			||||||
@@ -245,7 +250,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
 | 
				
			|||||||
		to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
 | 
							to_str_entries.append_fmt( "{ sizeof(\"%s\"), \"%s\" },\n", entry_to_str, entry_to_str);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for ( uw idx = 0; idx < attribute_strs.num(); idx++ )
 | 
						for ( usize idx = 0; idx < attribute_strs.num(); idx++ )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		char const* attribute_str = attribute_strs[idx].string;
 | 
							char const* attribute_str = attribute_strs[idx].string;
 | 
				
			||||||
		char const* entry_to_str  = attribute_str_strs [idx].string;
 | 
							char const* entry_to_str  = attribute_str_strs [idx].string;
 | 
				
			||||||
@@ -282,6 +287,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
 | 
				
			|||||||
#undef do_once_start
 | 
					#undef do_once_start
 | 
				
			||||||
#undef do_once_end
 | 
					#undef do_once_end
 | 
				
			||||||
	CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize(
 | 
						CodeFn to_str = parse_function(token_fmt("entries", (StrC)to_str_entries, "attribute_toks", (StrC)to_str_attributes, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		StrC to_str( Type type )
 | 
							StrC to_str( Type type )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -295,6 +301,7 @@ CodeBody gen_etoktype( char const* etok_path, char const* attr_path )
 | 
				
			|||||||
	)));
 | 
						)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
						CodeFn to_type = parse_function( token_fmt( "entries", (StrC)to_str_entries, stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		Type to_type( StrC str )
 | 
							Type to_type( StrC str )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			local_persist
 | 
								local_persist
 | 
				
			||||||
@@ -339,6 +346,7 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
#undef log_failure
 | 
					#undef log_failure
 | 
				
			||||||
	char const* code_impl_tmpl = stringize(
 | 
						char const* code_impl_tmpl = stringize(
 | 
				
			||||||
		\n
 | 
							\n
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		char const* <typename>::debug_str()
 | 
							char const* <typename>::debug_str()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast == nullptr )
 | 
								if ( ast == nullptr )
 | 
				
			||||||
@@ -346,6 +354,7 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return rcast(AST*, ast)->debug_str();
 | 
								return rcast(AST*, ast)->debug_str();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		Code <typename>::duplicate()
 | 
							Code <typename>::duplicate()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast == nullptr )
 | 
								if ( ast == nullptr )
 | 
				
			||||||
@@ -356,19 +365,23 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			return { rcast(AST*, ast)->duplicate() };
 | 
								return { rcast(AST*, ast)->duplicate() };
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		bool <typename>::is_equal( Code other )
 | 
							bool <typename>::is_equal( Code other )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast == nullptr || other.ast == nullptr )
 | 
								if ( ast == nullptr || other.ast == nullptr )
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// Just check if they're both null.
 | 
									// Just check if they're both null.
 | 
				
			||||||
				return rcast(AST*, ast) == other.ast;
 | 
									// log_failure( "Code::is_equal: Cannot compare code, AST is null!" );
 | 
				
			||||||
 | 
									return ast == nullptr && other.ast == nullptr;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return rcast(AST*, ast)->is_equal( other.ast );
 | 
								return rcast(AST*, ast)->is_equal( other.ast );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		bool <typename>::is_valid()
 | 
							bool <typename>::is_valid()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
 | 
								return (AST*) ast != nullptr && rcast( AST*, ast)->Type != CodeT::Invalid;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		void <typename>::set_global()
 | 
							void <typename>::set_global()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast == nullptr )
 | 
								if ( ast == nullptr )
 | 
				
			||||||
@@ -379,6 +392,7 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			rcast(AST*, ast)->Parent = Code::Global.ast;
 | 
								rcast(AST*, ast)->Parent = Code::Global.ast;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		<typename>& <typename>::operator =( Code other )
 | 
							<typename>& <typename>::operator =( Code other )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( other.ast && other->Parent )
 | 
								if ( other.ast && other->Parent )
 | 
				
			||||||
@@ -390,14 +404,17 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
			ast = rcast( decltype(ast), other.ast );
 | 
								ast = rcast( decltype(ast), other.ast );
 | 
				
			||||||
			return *this;
 | 
								return *this;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		bool <typename>::operator ==( Code other )
 | 
							bool <typename>::operator ==( Code other )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return (AST*) ast == other.ast;
 | 
								return (AST*) ast == other.ast;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		bool <typename>::operator !=( Code other )
 | 
							bool <typename>::operator !=( Code other )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return (AST*) ast != other.ast;
 | 
								return (AST*) ast != other.ast;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		<typename>::operator bool()
 | 
							<typename>::operator bool()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return ast != nullptr;
 | 
								return ast != nullptr;
 | 
				
			||||||
@@ -405,14 +422,17 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char const* codetype_impl_tmpl = stringize(
 | 
						char const* codetype_impl_tmpl = stringize(
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		AST* Code<typename>::raw()
 | 
							AST* Code<typename>::raw()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return rcast( AST*, ast );
 | 
								return rcast( AST*, ast );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		Code<typename>::operator Code()
 | 
							Code<typename>::operator Code()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return *rcast( Code*, this );
 | 
								return *rcast( Code*, this );
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline
 | 
				
			||||||
		AST_<typename>* Code<typename>::operator->()
 | 
							AST_<typename>* Code<typename>::operator->()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if ( ast == nullptr )
 | 
								if ( ast == nullptr )
 | 
				
			||||||
@@ -480,12 +500,11 @@ CodeBody gen_ast_inlines()
 | 
				
			|||||||
	impl_code_var.     append( parse_global_body( token_fmt( "typename", StrC name(Var),            codetype_impl_tmpl )));
 | 
						impl_code_var.     append( parse_global_body( token_fmt( "typename", StrC name(Var),            codetype_impl_tmpl )));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	char const* cast_tmpl = stringize(
 | 
						char const* cast_tmpl = stringize(
 | 
				
			||||||
		AST::operator Code<typename>()
 | 
							inline	AST::operator Code<typename>()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return { rcast( AST_<typename>*, this ) };
 | 
								return { rcast( AST_<typename>*, this ) };
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							inline Code::operator Code<typename>() const
 | 
				
			||||||
		Code::operator Code<typename>() const
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return { (AST_<typename>*) ast };
 | 
								return { (AST_<typename>*) ast };
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
#if __clang__
 | 
					#ifdef __clang__
 | 
				
			||||||
#	pragma clang diagnostic pop
 | 
					#	pragma clang diagnostic pop
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __GNUC__
 | 
					#ifdef __GNUC__
 | 
				
			||||||
#	pragma GCC diagnostic pop
 | 
					#	pragma GCC diagnostic pop
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
#if __clang__
 | 
					#ifdef __clang__
 | 
				
			||||||
#	pragma clang diagnostic push
 | 
					#	pragma clang diagnostic push
 | 
				
			||||||
#	pragma clang diagnostic ignored "-Wunused-const-variable"
 | 
					#	pragma clang diagnostic ignored "-Wunused-const-variable"
 | 
				
			||||||
#	pragma clang diagnostic ignored "-Wunused-but-set-variable"
 | 
					#	pragma clang diagnostic ignored "-Wunused-but-set-variable"
 | 
				
			||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
#	pragma clang diagnostic ignored "-Wunused-function"
 | 
					#	pragma clang diagnostic ignored "-Wunused-function"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if __GNUC__
 | 
					#ifdef __GNUC__
 | 
				
			||||||
#	pragma GCC diagnostic push
 | 
					#	pragma GCC diagnostic push
 | 
				
			||||||
#   pragma GCC diagnostic ignored "-Wunknown-pragmas"
 | 
					#   pragma GCC diagnostic ignored "-Wunknown-pragmas"
 | 
				
			||||||
#	pragma GCC diagnostic ignored "-Wcomment"
 | 
					#	pragma GCC diagnostic ignored "-Wcomment"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,6 @@
 | 
				
			|||||||
#undef forceinline
 | 
					#undef forceinline
 | 
				
			||||||
#undef neverinline
 | 
					#undef neverinline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#undef zpl_cast
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#undef global
 | 
					#undef global
 | 
				
			||||||
#undef internal
 | 
					#undef internal
 | 
				
			||||||
#undef local_persist
 | 
					#undef local_persist
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,36 @@
 | 
				
			|||||||
# It will most likely need a partial rewrite to segment the build process into separate script invocations based on the OS.
 | 
					# It will most likely need a partial rewrite to segment the build process into separate script invocations based on the OS.
 | 
				
			||||||
# That or just rewrite it in an sh script and call it a day.
 | 
					# That or just rewrite it in an sh script and call it a day.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Import-Module ./helpers/target_arch.psm1
 | 
					 | 
				
			||||||
$target_arch        = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
 | 
					$target_arch        = Join-Path $PSScriptRoot 'helpers/target_arch.psm1'
 | 
				
			||||||
$devshell           = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
 | 
					$devshell           = Join-Path $PSScriptRoot 'helpers/devshell.ps1'
 | 
				
			||||||
$format_cpp	        = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
 | 
					$format_cpp	        = Join-Path $PSScriptRoot 'helpers/format_cpp.psm1'
 | 
				
			||||||
 | 
					$refactor_unreal    = Join-Path $PSScriptRoot 'refactor_unreal.ps1'
 | 
				
			||||||
$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
 | 
					$incremental_checks = Join-Path $PSScriptRoot 'helpers/incremental_checks.ps1'
 | 
				
			||||||
$vendor_toolchain   = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
 | 
					$vendor_toolchain   = Join-Path $PSScriptRoot 'helpers/vendor_toolchain.ps1'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$path_root = git rev-parse --show-toplevel
 | 
					Import-Module $target_arch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Get-ScriptRepoRoot {
 | 
				
			||||||
 | 
					    $currentPath = $PSScriptRoot
 | 
				
			||||||
 | 
					    while ($currentPath -ne $null -and $currentPath -ne "")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					        if (Test-Path (Join-Path $currentPath ".git")) {
 | 
				
			||||||
 | 
					            return $currentPath
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        # Also check for .git file which indicates a submodule
 | 
				
			||||||
 | 
					        $gitFile = Join-Path $currentPath ".git"
 | 
				
			||||||
 | 
					        if (Test-Path $gitFile -PathType Leaf)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
					            $gitContent = Get-Content $gitFile
 | 
				
			||||||
 | 
					            if ($gitContent -match "gitdir: (.+)") {
 | 
				
			||||||
 | 
					                return $currentPath
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $currentPath = Split-Path $currentPath -Parent
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    throw "Unable to find repository root"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					$path_root = Get-ScriptRepoRoot
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Import-Module $target_arch
 | 
					Import-Module $target_arch
 | 
				
			||||||
Import-Module $format_cpp
 | 
					Import-Module $format_cpp
 | 
				
			||||||
@@ -22,6 +44,7 @@ Push-Location $path_root
 | 
				
			|||||||
	   $verbose      = $false
 | 
						   $verbose      = $false
 | 
				
			||||||
[bool] $bootstrap    = $false
 | 
					[bool] $bootstrap    = $false
 | 
				
			||||||
[bool] $singleheader = $false
 | 
					[bool] $singleheader = $false
 | 
				
			||||||
 | 
					[bool] $unreal       = $false
 | 
				
			||||||
[bool] $test         = $false
 | 
					[bool] $test         = $false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[array] $vendors = @( "clang", "msvc" )
 | 
					[array] $vendors = @( "clang", "msvc" )
 | 
				
			||||||
@@ -36,6 +59,7 @@ if ( $args ) { $args | ForEach-Object {
 | 
				
			|||||||
		"debug"               { $release      = $false }
 | 
							"debug"               { $release      = $false }
 | 
				
			||||||
		"bootstrap"           { $bootstrap    = $true }
 | 
							"bootstrap"           { $bootstrap    = $true }
 | 
				
			||||||
		"singleheader"        { $singleheader = $true }
 | 
							"singleheader"        { $singleheader = $true }
 | 
				
			||||||
 | 
							"unreal"              { $unreal       = $true }
 | 
				
			||||||
		"test"                { $test         = $true }
 | 
							"test"                { $test         = $true }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}}
 | 
					}}
 | 
				
			||||||
@@ -64,7 +88,7 @@ else {
 | 
				
			|||||||
	$optimize = $true
 | 
						$optimize = $true
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $bootstrap -eq $false -and $singleheader -eq $false -and $test -eq $false ) {
 | 
					if ( $bootstrap -eq $false -and $singleheader -eq $false -and $unreal -eq $false -and $test -eq $false ) {
 | 
				
			||||||
	throw "No build target specified. One must be specified, this script will not assume one"
 | 
						throw "No build target specified. One must be specified, this script will not assume one"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,6 +104,7 @@ $path_build        = Join-Path $path_root build
 | 
				
			|||||||
$path_project      = Join-Path $path_root project
 | 
					$path_project      = Join-Path $path_root project
 | 
				
			||||||
$path_scripts      = Join-Path $path_root scripts
 | 
					$path_scripts      = Join-Path $path_root scripts
 | 
				
			||||||
$path_singleheader = Join-Path $path_root singleheader
 | 
					$path_singleheader = Join-Path $path_root singleheader
 | 
				
			||||||
 | 
					$path_unreal       = Join-Path $path_root unreal_engine
 | 
				
			||||||
$path_test         = Join-Path $path_root test
 | 
					$path_test         = Join-Path $path_root test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $bootstrap )
 | 
					if ( $bootstrap )
 | 
				
			||||||
@@ -162,6 +187,46 @@ if ( $singleheader )
 | 
				
			|||||||
	Pop-Location
 | 
						Pop-Location
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ( $unreal )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						$path_build = join-path $path_unreal build
 | 
				
			||||||
 | 
						$path_gen   = join-path $path_unreal gen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if ( -not(Test-Path($path_build) )) {
 | 
				
			||||||
 | 
							New-Item -ItemType Directory -Path $path_build
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if ( -not(Test-Path($path_gen) )) {
 | 
				
			||||||
 | 
							New-Item -ItemType Directory -Path $path_gen
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$includes    = @( $path_project )
 | 
				
			||||||
 | 
						$unit       = join-path $path_unreal "unreal.cpp"
 | 
				
			||||||
 | 
						$executable = join-path $path_build  "unreal.exe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$compiler_args = @()
 | 
				
			||||||
 | 
						$compiler_args += ( $flag_define + 'GEN_TIME' )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						$linker_args   = @(
 | 
				
			||||||
 | 
							$flag_link_win_subsystem_console
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						build-simple $path_build $includes $compiler_args $linker_args $unit $executable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Push-Location $path_unreal
 | 
				
			||||||
 | 
							if ( Test-Path( $executable ) ) {
 | 
				
			||||||
 | 
								write-host "`nRunning unreal variant generator"
 | 
				
			||||||
 | 
								$time_taken = Measure-Command { & $executable
 | 
				
			||||||
 | 
										| ForEach-Object {
 | 
				
			||||||
 | 
											write-host `t $_ -ForegroundColor Green
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								write-host "`n Unreal variant generator completed in $($time_taken.TotalMilliseconds) ms"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						Pop-Location
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						. $refactor_unreal
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $test )
 | 
					if ( $test )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_gen          = join-path $path_test gen
 | 
						$path_gen          = join-path $path_test gen
 | 
				
			||||||
@@ -226,10 +291,9 @@ if ( $test )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#region Formatting
 | 
					#region Formatting
 | 
				
			||||||
push-location $path_scripts
 | 
					push-location $path_scripts
 | 
				
			||||||
if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
 | 
					if ( $true -and $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_gen      = join-path $path_project gen
 | 
						$path_gen      = join-path $path_project gen
 | 
				
			||||||
	$path_comp_gen = join-path $path_project components/gen
 | 
					 | 
				
			||||||
	$include  = @(
 | 
						$include  = @(
 | 
				
			||||||
		'gen.hpp', 'gen.cpp',
 | 
							'gen.hpp', 'gen.cpp',
 | 
				
			||||||
		'gen.dep.hpp', 'gen.dep.cpp',
 | 
							'gen.dep.hpp', 'gen.dep.cpp',
 | 
				
			||||||
@@ -237,12 +301,12 @@ if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
 | 
				
			|||||||
		'gen.scanner.hpp', 'gen.scanner.cpp'
 | 
							'gen.scanner.hpp', 'gen.scanner.cpp'
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	$exclude  = $null
 | 
						$exclude  = $null
 | 
				
			||||||
	format-cpp $path_gen $include $exclude
 | 
						# format-cpp $path_gen $include $exclude
 | 
				
			||||||
	format-cpp $path_comp_gen @( 'ast_inlines.hpp', 'ecode.hpp', 'especifier.hpp', 'eoperator.hpp', 'etoktype.cpp' ) $null
 | 
						format-cpp $path_comp_gen @( 'ast_inlines.hpp', 'ecode.hpp', 'especifier.hpp', 'eoperator.hpp', 'etoktype.cpp' ) $null
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) )
 | 
					if ( $false -and $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_gen = join-path $path_singleheader gen
 | 
						$path_gen = join-path $path_singleheader gen
 | 
				
			||||||
	$include  = @(
 | 
						$include  = @(
 | 
				
			||||||
@@ -252,6 +316,19 @@ if ( $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp"))
 | 
				
			|||||||
	format-cpp $path_gen $include $exclude
 | 
						format-cpp $path_gen $include $exclude
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ( $false -and $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						$path_gen = join-path $path_unreal gen
 | 
				
			||||||
 | 
						$include  = @(
 | 
				
			||||||
 | 
							'gen.hpp', 'gen.cpp',
 | 
				
			||||||
 | 
							'gen.dep.hpp', 'gen.dep.cpp',
 | 
				
			||||||
 | 
							'gen.builder.hpp', 'gen.builder.cpp'
 | 
				
			||||||
 | 
							'gen.scanner.hpp', 'gen.scanner.cpp'
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
						$exclude  = $null
 | 
				
			||||||
 | 
						format-cpp $path_gen $include $exclude
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $test -and $false )
 | 
					if ( $test -and $false )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	$path_gen = join-path $path_test gen
 | 
						$path_gen = join-path $path_test gen
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,9 +43,6 @@
 | 
				
			|||||||
// word GEN_COMPILER_MINGW, new_name
 | 
					// word GEN_COMPILER_MINGW, new_name
 | 
				
			||||||
// word GEN_COMPILER_MSVC,  new_name
 | 
					// word GEN_COMPILER_MSVC,  new_name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // General
 | 
					 | 
				
			||||||
// word zpl_cast, new_name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// word global,        new_name
 | 
					// word global,        new_name
 | 
				
			||||||
// word internal,      new_name
 | 
					// word internal,      new_name
 | 
				
			||||||
// word local_persist, new_name
 | 
					// word local_persist, new_name
 | 
				
			||||||
@@ -150,8 +147,8 @@
 | 
				
			|||||||
// word u16,  new_name
 | 
					// word u16,  new_name
 | 
				
			||||||
// word u32,  new_name
 | 
					// word u32,  new_name
 | 
				
			||||||
// word u64,  new_name
 | 
					// word u64,  new_name
 | 
				
			||||||
// word uw,   new_name
 | 
					// word usize,   new_name
 | 
				
			||||||
// word sw,   new_name
 | 
					// word ssize,   new_name
 | 
				
			||||||
// word sptr, new_name
 | 
					// word sptr, new_name
 | 
				
			||||||
// word uptr, new_name
 | 
					// word uptr, new_name
 | 
				
			||||||
// word f32,  new_name
 | 
					// word f32,  new_name
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,10 +3,10 @@ cls
 | 
				
			|||||||
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
 | 
					$build = Join-Path $PSScriptRoot 'build.ci.ps1'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( $IsWindows ) {
 | 
					if ( $IsWindows ) {
 | 
				
			||||||
	& $build release msvc bootstrap singleheader
 | 
						& $build release msvc bootstrap singleheader unreal msvc debug
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
else {
 | 
					else {
 | 
				
			||||||
	& $build release clang bootstrap singleheader
 | 
						& $build release clang bootstrap singleheader unreal msvc debug
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$path_root             = git rev-parse --show-toplevel
 | 
					$path_root             = git rev-parse --show-toplevel
 | 
				
			||||||
@@ -15,6 +15,8 @@ $path_project          = Join-Path $path_root project
 | 
				
			|||||||
$path_project_gen      = Join-Path $path_project      gen
 | 
					$path_project_gen      = Join-Path $path_project      gen
 | 
				
			||||||
$path_singleheader	   = Join-Path $path_root         singleheader
 | 
					$path_singleheader	   = Join-Path $path_root         singleheader
 | 
				
			||||||
$path_singleheader_gen = Join-Path $path_singleheader gen
 | 
					$path_singleheader_gen = Join-Path $path_singleheader gen
 | 
				
			||||||
 | 
					$path_unreal           = Join-Path $path_root         unreal_engine
 | 
				
			||||||
 | 
					$path_unreal_gen       = Join-Path $path_unreal       gen
 | 
				
			||||||
$path_release          = Join-Path $path_root         release
 | 
					$path_release          = Join-Path $path_root         release
 | 
				
			||||||
$path_release_content  = Join-Path $path_release      content
 | 
					$path_release_content  = Join-Path $path_release      content
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,9 +24,9 @@ if ( -not(Test-Path $path_release) ) {
 | 
				
			|||||||
	New-Item -ItemType Directory -Path $path_release
 | 
						New-Item -ItemType Directory -Path $path_release
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if ( -not(Test-Path $path_release_content) ) {
 | 
					function prep-ReleaseContent()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	New-Item -ItemType Directory -Path $path_release_content
 | 
						New-Item -ItemType Directory -Path $path_release_content
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	$license            = Join-Path $path_root LICENSE
 | 
						$license            = Join-Path $path_root LICENSE
 | 
				
			||||||
	$readme_root        = Join-Path $path_root Readme.md
 | 
						$readme_root        = Join-Path $path_root Readme.md
 | 
				
			||||||
@@ -41,14 +43,49 @@ Copy-Item $readme_ast_design  -Destination (Join-Path $path_release_content "AST
 | 
				
			|||||||
	Copy-Item $readme_ast_types   -Destination (Join-Path $path_release_content "AST_Types.md")
 | 
						Copy-Item $readme_ast_types   -Destination (Join-Path $path_release_content "AST_Types.md")
 | 
				
			||||||
	Copy-Item $readme_parsing     -Destination (Join-Path $path_release_content "Parsing.md")
 | 
						Copy-Item $readme_parsing     -Destination (Join-Path $path_release_content "Parsing.md")
 | 
				
			||||||
	Copy-Item $readme_parser_algo -Destination (Join-Path $path_release_content "Parser_Algo.md")
 | 
						Copy-Item $readme_parser_algo -Destination (Join-Path $path_release_content "Parser_Algo.md")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Singleheader
 | 
					# Singleheader
 | 
				
			||||||
 | 
					prep-ReleaseContent
 | 
				
			||||||
Copy-Item        -Path $path_singleheader_gen\gen.hpp -Destination $path_release_content\gen.hpp
 | 
					Copy-Item        -Path $path_singleheader_gen\gen.hpp -Destination $path_release_content\gen.hpp
 | 
				
			||||||
Compress-Archive -Path $path_release_content\*        -DestinationPath $path_release\gencpp_singleheader.zip -Force
 | 
					Compress-Archive -Path $path_release_content\*        -DestinationPath $path_release\gencpp_singleheader.zip -Force
 | 
				
			||||||
Remove-Item      -Path $path_release_content\gen.hpp
 | 
					Remove-Item -Path $path_release_content -Recurse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Segmented
 | 
					# Segmented
 | 
				
			||||||
 | 
					prep-ReleaseContent
 | 
				
			||||||
Copy-Item        -Path $path_project_gen\*     -Destination $path_release_content
 | 
					Copy-Item        -Path $path_project_gen\*     -Destination $path_release_content
 | 
				
			||||||
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_segmented.zip -Force
 | 
					Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_segmented.zip -Force
 | 
				
			||||||
 | 
					Remove-Item -Path $path_release_content -Recurse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Unreal
 | 
				
			||||||
 | 
					prep-ReleaseContent
 | 
				
			||||||
 | 
					Copy-Item        -Path $path_unreal_gen\*      -Destination $path_release_content
 | 
				
			||||||
 | 
					Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_unreal.zip -Force
 | 
				
			||||||
 | 
					Remove-Item -Path $path_release_content -Recurse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# As Is
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prep-ReleaseContent
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\gen.hpp               -Destination $path_release_content
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\gen.cpp               -Destination $path_release_content
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\gen.dep.hpp           -Destination $path_release_content
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\gen.dep.cpp           -Destination $path_release_content
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\auxillary\builder.hpp -Destination $path_release_content\auxillary
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\auxillary\builder.cpp -Destination $path_release_content\auxillary
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\auxillary\scanner.hpp -Destination $path_release_content\auxillary
 | 
				
			||||||
 | 
					Copy-Item        -Verbose -Path $path_project\auxillary\scanner.cpp -Destination $path_release_content\auxillary
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					New-Item -ItemType Directory -Force -Path "$path_release_content\components"
 | 
				
			||||||
 | 
					New-Item -ItemType Directory -Force -Path "$path_release_content\components\gen"
 | 
				
			||||||
 | 
					New-Item -ItemType Directory -Force -Path "$path_release_content\dependencies"
 | 
				
			||||||
 | 
					New-Item -ItemType Directory -Force -Path "$path_release_content\enums"
 | 
				
			||||||
 | 
					New-Item -ItemType Directory -Force -Path "$path_release_content\helpers"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Get-ChildItem -Verbose -Path "$path_project\components\*"     -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\components"
 | 
				
			||||||
 | 
					Get-ChildItem -Verbose -Path "$path_project\components\gen\*" -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\components\gen"
 | 
				
			||||||
 | 
					Get-ChildItem -Verbose -Path "$path_project\dependencies\*"   -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\dependencies"
 | 
				
			||||||
 | 
					Get-ChildItem -Verbose -Path "$path_project\enums\*"          -Include *.csv       | Copy-Item -Destination "$path_release_content\enums"
 | 
				
			||||||
 | 
					Get-ChildItem -Verbose -Path "$path_project\helpers\*"        -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\helpers"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Compress-Archive -Path $path_release_content\** -DestinationPath $path_release\gencpp_as_is.zip -Force
 | 
				
			||||||
Remove-Item -Path $path_release_content -Recurse
 | 
					Remove-Item -Path $path_release_content -Recurse
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										56
									
								
								scripts/refactor_unreal.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								scripts/refactor_unreal.ps1
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					[string] $format = $false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					foreach ( $arg in $args )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if ( $arg -eq "format" )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							$format = $true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[string[]] $include = 'gen.*.hpp', 'gen.*.cpp', 'gen.hpp', 'gen.cpp'
 | 
				
			||||||
 | 
					[string[]] $exclude
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$path_root               = git rev-parse --show-toplevel
 | 
				
			||||||
 | 
					$path_project            = Join-Path $path_root        project
 | 
				
			||||||
 | 
					$path_scripts            = Join-Path $path_root        scripts
 | 
				
			||||||
 | 
					$path_singlheader        = Join-Path $path_root        singleheader
 | 
				
			||||||
 | 
					$path_singleheader_comp  = Join-Path $path_singlheader components
 | 
				
			||||||
 | 
					$path_unreal             = Join-Path $path_root        unreal_engine
 | 
				
			||||||
 | 
					$path_unreal_gen         = Join-Path $path_unreal      gen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$file_spec = Join-Path $path_scripts unreal.refactor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Gather the files to be formatted.
 | 
				
			||||||
 | 
					$targetFiles = @()
 | 
				
			||||||
 | 
					$targetFiles += Get-ChildItem -Recurse -Path $path_unreal_gen        -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
 | 
				
			||||||
 | 
					# $targetFiles += Get-ChildItem -Recurse -Path $path_project           -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
 | 
				
			||||||
 | 
					# $targetFiles += Get-ChildItem -Recurse -Path $path_singleheader_comp -Include $include -Exclude $exclude | Select-Object -ExpandProperty FullName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Format the files.
 | 
				
			||||||
 | 
					$formatParams = @(
 | 
				
			||||||
 | 
					    '-i'                          # In-place
 | 
				
			||||||
 | 
					    '-style=file:./.clang-format' # Search for a .clang-format file in the parent directory of the source file.
 | 
				
			||||||
 | 
					    '-verbose'
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					write-host "Beginning refactor...`n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$refactorParams = @(
 | 
				
			||||||
 | 
					    # "-debug",
 | 
				
			||||||
 | 
					    "-num=$($targetFiles.Count)"
 | 
				
			||||||
 | 
					    "-src=$($targetFiles)",
 | 
				
			||||||
 | 
					    "-spec=$($file_spec)"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					& refactor $refactorParams
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Write-Host "`nRefactoring complete`n`n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ( $format -eq $true ) {
 | 
				
			||||||
 | 
						Write-Host "Beginning format...`n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						& clang-format $formatParams $targetFiles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Write-Host "`nFormatting complete"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								scripts/unreal.refactor
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								scripts/unreal.refactor
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					 __VERSION 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This is a example template to be used with the refactor program
 | 
				
			||||||
 | 
					// Use it to refactor the naming convention of this library to your own.
 | 
				
			||||||
 | 
					// Can be used as an aid to help use use your project's implementation if it fullfills the dependencies of this project.
 | 
				
			||||||
 | 
					// Example: Most likely have a memory and string library already, just rename the functions and make sure the args are the same.
 | 
				
			||||||
 | 
					// Program: https://github.com/Ed94/refactor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOTE: Due to the current limitations of the program, not every symbol in the library can be renamed.
 | 
				
			||||||
 | 
					// This is due to the program not actually parsing C/C++.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// not       : Ignore
 | 
				
			||||||
 | 
					// include   : #includes
 | 
				
			||||||
 | 
					// word      : Alphanumeric or underscore
 | 
				
			||||||
 | 
					// namespace : Prefix search and replace (c-namspaces).
 | 
				
			||||||
 | 
					// regex     : Unavailable in __VERSION 1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Precedence (highest to lowest):
 | 
				
			||||||
 | 
					// word, namespace, regex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Gen Macro namespace
 | 
				
			||||||
 | 
					// namespace GEN_, new_namespace_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					word forceinline,      FORCEINLINE
 | 
				
			||||||
 | 
					word spec_forceinline, spec_FORCEINLINE
 | 
				
			||||||
@@ -14,6 +14,8 @@ GEN_NS_END
 | 
				
			|||||||
#include "auxillary/builder.cpp"
 | 
					#include "auxillary/builder.cpp"
 | 
				
			||||||
#include "auxillary/scanner.hpp"
 | 
					#include "auxillary/scanner.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <cstdlib>   // for system()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using namespace gen;
 | 
					using namespace gen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr char const* generation_notice =
 | 
					constexpr char const* generation_notice =
 | 
				
			||||||
@@ -35,7 +37,6 @@ constexpr StrC roll_own_dependencies_guard_start = txt(R"(
 | 
				
			|||||||
//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
 | 
					//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
 | 
				
			||||||
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
 | 
					// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
 | 
				
			||||||
#ifndef GEN_ROLL_OWN_DEPENDENCIES
 | 
					#ifndef GEN_ROLL_OWN_DEPENDENCIES
 | 
				
			||||||
 | 
					 | 
				
			||||||
)");
 | 
					)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
 | 
					constexpr StrC roll_own_dependencies_guard_end = txt(R"(
 | 
				
			||||||
@@ -48,6 +49,42 @@ global bool generate_builder = true;
 | 
				
			|||||||
global bool generate_editor  = true;
 | 
					global bool generate_editor  = true;
 | 
				
			||||||
global bool generate_scanner = true;
 | 
					global bool generate_scanner = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void format_file( char const* path )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						String resolved_path = String::make(GlobalAllocator, to_str(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
 | 
				
			||||||
 | 
						style_arg.append("../scripts/.clang-format ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Need to execute clang format on the generated file to get it to match the original.
 | 
				
			||||||
 | 
						#define clang_format      "clang-format "
 | 
				
			||||||
 | 
						#define cf_format_inplace "-i "
 | 
				
			||||||
 | 
						#define cf_verbose        "-verbose "
 | 
				
			||||||
 | 
						String command = String::make( GlobalAllocator, clang_format );
 | 
				
			||||||
 | 
						command.append( cf_format_inplace );
 | 
				
			||||||
 | 
						command.append( cf_verbose );
 | 
				
			||||||
 | 
						command.append( style_arg );
 | 
				
			||||||
 | 
						command.append( resolved_path );
 | 
				
			||||||
 | 
							log_fmt("\tRunning clang-format on file:\n");
 | 
				
			||||||
 | 
							system( command );
 | 
				
			||||||
 | 
							log_fmt("\tclang-format finished reformatting.\n");
 | 
				
			||||||
 | 
						#undef cf_cmd
 | 
				
			||||||
 | 
						#undef cf_format_inplace
 | 
				
			||||||
 | 
						#undef cf_style
 | 
				
			||||||
 | 
						#undef cf_verbse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Code dump_to_scratch_and_retireve( Code code )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Builder ecode_file_temp = Builder::open("gen/scratch.hpp");
 | 
				
			||||||
 | 
						ecode_file_temp.print(code);
 | 
				
			||||||
 | 
						ecode_file_temp.write();
 | 
				
			||||||
 | 
						format_file("gen/scratch.hpp");
 | 
				
			||||||
 | 
						Code result = scan_file( "gen/scratch.hpp" );
 | 
				
			||||||
 | 
						remove("gen/scratch.hpp");
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gen_main()
 | 
					int gen_main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#define project_dir "../project/"
 | 
					#define project_dir "../project/"
 | 
				
			||||||
@@ -69,7 +106,7 @@ int gen_main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if ( generate_gen_dep )
 | 
							if ( generate_gen_dep )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Code header_start = scan_file( project_dir "dependencies/header_start.hpp" );
 | 
								Code platform     = scan_file( project_dir "dependencies/platform.hpp" );
 | 
				
			||||||
			Code macros       = scan_file( project_dir "dependencies/macros.hpp" );
 | 
								Code macros       = scan_file( project_dir "dependencies/macros.hpp" );
 | 
				
			||||||
			Code basic_types  = scan_file( project_dir "dependencies/basic_types.hpp" );
 | 
								Code basic_types  = scan_file( project_dir "dependencies/basic_types.hpp" );
 | 
				
			||||||
			Code debug        = scan_file( project_dir "dependencies/debug.hpp" );
 | 
								Code debug        = scan_file( project_dir "dependencies/debug.hpp" );
 | 
				
			||||||
@@ -83,7 +120,7 @@ int gen_main()
 | 
				
			|||||||
			Code timing       = scan_file( project_dir "dependencies/timing.hpp" );
 | 
								Code timing       = scan_file( project_dir "dependencies/timing.hpp" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			header.print_fmt( roll_own_dependencies_guard_start );
 | 
								header.print_fmt( roll_own_dependencies_guard_start );
 | 
				
			||||||
			header.print( header_start );
 | 
								header.print( platform );
 | 
				
			||||||
			header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
								header.print_fmt( "\nGEN_NS_BEGIN\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			header.print( macros );
 | 
								header.print( macros );
 | 
				
			||||||
@@ -127,9 +164,13 @@ int gen_main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		header.print_fmt("#pragma region Types\n");
 | 
							header.print_fmt("#pragma region Types\n");
 | 
				
			||||||
		header.print( types );
 | 
							header.print( types );
 | 
				
			||||||
		header.print( ecode );
 | 
							header.print( fmt_newline );
 | 
				
			||||||
		header.print( eoperator );
 | 
							header.print( dump_to_scratch_and_retireve( ecode ));
 | 
				
			||||||
		header.print( especifier );
 | 
							header.print( fmt_newline );
 | 
				
			||||||
 | 
							header.print( dump_to_scratch_and_retireve( eoperator ));
 | 
				
			||||||
 | 
							header.print( fmt_newline );
 | 
				
			||||||
 | 
							header.print( dump_to_scratch_and_retireve( especifier ));
 | 
				
			||||||
 | 
							header.print( fmt_newline );
 | 
				
			||||||
		header.print_fmt("#pragma endregion Types\n\n");
 | 
							header.print_fmt("#pragma endregion Types\n\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print_fmt("#pragma region AST\n");
 | 
							header.print_fmt("#pragma region AST\n");
 | 
				
			||||||
@@ -142,7 +183,8 @@ int gen_main()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		header.print_fmt( "\n#pragma region Inlines\n" );
 | 
							header.print_fmt( "\n#pragma region Inlines\n" );
 | 
				
			||||||
		header.print( inlines );
 | 
							header.print( inlines );
 | 
				
			||||||
		header.print( ast_inlines );
 | 
							header.print( dump_to_scratch_and_retireve( ast_inlines ));
 | 
				
			||||||
 | 
							header.print( fmt_newline );
 | 
				
			||||||
		header.print_fmt( "#pragma endregion Inlines\n" );
 | 
							header.print_fmt( "#pragma endregion Inlines\n" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print( header_end );
 | 
							header.print( header_end );
 | 
				
			||||||
@@ -209,7 +251,7 @@ int gen_main()
 | 
				
			|||||||
		Code untyped           = scan_file( project_dir "components/interface.untyped.cpp" );
 | 
							Code untyped           = scan_file( project_dir "components/interface.untyped.cpp" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		CodeBody etoktype      = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" );
 | 
							CodeBody etoktype      = gen_etoktype( project_dir "enums/ETokType.csv", project_dir "enums/AttributeTokens.csv" );
 | 
				
			||||||
		CodeNS   parser_nspace = def_namespace( name(Parser), def_namespace_body( args(etoktype)) );
 | 
							CodeNS   parser_nspace = def_namespace( name(parser), def_namespace_body( args(etoktype)) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		header.print_fmt( "\nGEN_NS_BEGIN\n");
 | 
							header.print_fmt( "\nGEN_NS_BEGIN\n");
 | 
				
			||||||
		header.print( static_data );
 | 
							header.print( static_data );
 | 
				
			||||||
@@ -224,7 +266,7 @@ int gen_main()
 | 
				
			|||||||
		header.print( interface );
 | 
							header.print( interface );
 | 
				
			||||||
		header.print( upfront );
 | 
							header.print( upfront );
 | 
				
			||||||
		header.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
							header.print_fmt( "\n#pragma region Parsing\n\n" );
 | 
				
			||||||
		header.print( parser_nspace );
 | 
							header.print( dump_to_scratch_and_retireve(parser_nspace) );
 | 
				
			||||||
		header.print( lexer );
 | 
							header.print( lexer );
 | 
				
			||||||
		header.print( parser );
 | 
							header.print( parser );
 | 
				
			||||||
		header.print( parsing_interface );
 | 
							header.print( parsing_interface );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,11 +15,11 @@ Code gen__array_base()
 | 
				
			|||||||
		struct ArrayHeader
 | 
							struct ArrayHeader
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			AllocatorInfo Allocator;
 | 
								AllocatorInfo Allocator;
 | 
				
			||||||
			uw            Capacity;
 | 
								usize            Capacity;
 | 
				
			||||||
			uw            Num;
 | 
								usize            Num;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline uw array_grow_formula( uw value )
 | 
							static inline usize array_grow_formula( usize value )
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return 2 * value * 8;
 | 
								return 2 * value * 8;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -52,7 +52,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				static
 | 
									static
 | 
				
			||||||
				<ArrayType> init_reserve( AllocatorInfo allocator, sw capacity )
 | 
									<ArrayType> init_reserve( AllocatorInfo allocator, ssize capacity )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) ));
 | 
										Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,14 +94,14 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					header.Num     = 0;
 | 
										header.Num     = 0;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bool fill( uw begin, uw end, Type value )
 | 
									bool fill( usize begin, usize end, Type value )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header = get_header();
 | 
										Header& header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ( begin < 0 || end >= header.Num )
 | 
										if ( begin < 0 || end >= header.Num )
 | 
				
			||||||
						return false;
 | 
											return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for ( sw idx = begin; idx < end; idx++ )
 | 
										for ( ssize idx = begin; idx < end; idx++ )
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						Data[ idx ] = value;
 | 
											Data[ idx ] = value;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -120,10 +120,10 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					return *( reinterpret_cast< Header* >( Data ) - 1 );
 | 
										return *( reinterpret_cast< Header* >( Data ) - 1 );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bool grow( uw min_capacity )
 | 
									bool grow( usize min_capacity )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header       = get_header();
 | 
										Header& header       = get_header();
 | 
				
			||||||
					uw      new_capacity = grow_formula( header.Capacity );
 | 
										usize      new_capacity = grow_formula( header.Capacity );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ( new_capacity < min_capacity )
 | 
										if ( new_capacity < min_capacity )
 | 
				
			||||||
						new_capacity = 8;
 | 
											new_capacity = 8;
 | 
				
			||||||
@@ -131,7 +131,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					return set_capacity( new_capacity );
 | 
										return set_capacity( new_capacity );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				uw num( void )
 | 
									usize num( void )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					return get_header().Num;
 | 
										return get_header().Num;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -144,7 +144,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					header.Num--;
 | 
										header.Num--;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				void remove_at( uw idx )
 | 
									void remove_at( usize idx )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header* header = &get_header();
 | 
										Header* header = &get_header();
 | 
				
			||||||
					GEN_ASSERT( idx < header->Num );
 | 
										GEN_ASSERT( idx < header->Num );
 | 
				
			||||||
@@ -153,7 +153,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					header->Num--;
 | 
										header->Num--;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bool reserve( uw new_capacity )
 | 
									bool reserve( usize new_capacity )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header = get_header();
 | 
										Header& header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -163,7 +163,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					return true;
 | 
										return true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bool resize( uw num )
 | 
									bool resize( usize num )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header = get_header();
 | 
										Header& header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,7 +177,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					return true;
 | 
										return true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bool set_capacity( uw new_capacity )
 | 
									bool set_capacity( usize new_capacity )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header = get_header();
 | 
										Header& header = get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -187,7 +187,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
					if ( new_capacity < header.Num )
 | 
										if ( new_capacity < header.Num )
 | 
				
			||||||
						header.Num = new_capacity;
 | 
											header.Num = new_capacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					sw      size       = sizeof( Header ) + sizeof( Type ) * new_capacity;
 | 
										ssize      size       = sizeof( Header ) + sizeof( Type ) * new_capacity;
 | 
				
			||||||
					Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
 | 
										Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ( new_header == nullptr )
 | 
										if ( new_header == nullptr )
 | 
				
			||||||
@@ -233,7 +233,7 @@ void gen__array_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenArrayRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenArrayRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,8 @@ Code gen__buffer_base()
 | 
				
			|||||||
		struct BufferHeader
 | 
							struct BufferHeader
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			AllocatorInfo Backing;
 | 
								AllocatorInfo Backing;
 | 
				
			||||||
			uw            Capacity;
 | 
								usize            Capacity;
 | 
				
			||||||
			uw            Num;
 | 
								usize            Num;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	));
 | 
						));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -38,7 +38,7 @@ Code gen__buffer( StrC type )
 | 
				
			|||||||
				using Header = BufferHeader;
 | 
									using Header = BufferHeader;
 | 
				
			||||||
				using Type   = <type>;
 | 
									using Type   = <type>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				static <BufferName> init( AllocatorInfo allocator, sw capacity )
 | 
									static <BufferName> init( AllocatorInfo allocator, ssize capacity )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + capacity * sizeof( Type ) ) );
 | 
										Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + capacity * sizeof( Type ) ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -76,7 +76,7 @@ Code gen__buffer( StrC type )
 | 
				
			|||||||
					header.Num++;
 | 
										header.Num++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				void append( Type* values, sw num )
 | 
									void append( Type* values, ssize num )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Header& header = get_header();
 | 
										Header& header = get_header();
 | 
				
			||||||
					GEN_ASSERT( header.Num + num <= header.Capacity);
 | 
										GEN_ASSERT( header.Num + num <= header.Capacity);
 | 
				
			||||||
@@ -108,7 +108,7 @@ Code gen__buffer( StrC type )
 | 
				
			|||||||
					return *( rcast( Header*, Data ) - 1 );
 | 
										return *( rcast( Header*, Data ) - 1 );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				sw num( void )
 | 
									ssize num( void )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					return get_header().Num;
 | 
										return get_header().Num;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -147,7 +147,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenBufferRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenBufferRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,9 +15,9 @@ Code gen__hashtable_base()
 | 
				
			|||||||
	return parse_global_body( code(
 | 
						return parse_global_body( code(
 | 
				
			||||||
		struct HashTable_FindResult
 | 
							struct HashTable_FindResult
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sw HashIndex;
 | 
								ssize HashIndex;
 | 
				
			||||||
			sw PrevIndex;
 | 
								ssize PrevIndex;
 | 
				
			||||||
			sw EntryIndex;
 | 
								ssize EntryIndex;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	));
 | 
						));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -37,7 +37,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
			struct <HashTableName>_Entry
 | 
								struct <HashTableName>_Entry
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				u64 Key;
 | 
									u64 Key;
 | 
				
			||||||
				sw  Next;
 | 
									ssize  Next;
 | 
				
			||||||
				<type> Value;
 | 
									<type> Value;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
@@ -86,7 +86,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				Type* get( u64 key )
 | 
									Type* get( u64 key )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw idx = find( key ).EntryIndex;
 | 
										ssize idx = find( key ).EntryIndex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ( idx > 0 )
 | 
										if ( idx > 0 )
 | 
				
			||||||
						return &Entries[ idx ].Value;
 | 
											return &Entries[ idx ].Value;
 | 
				
			||||||
@@ -96,7 +96,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				void grow( void )
 | 
									void grow( void )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw new_num = array_grow_formula( Entries.num() );
 | 
										ssize new_num = array_grow_formula( Entries.num() );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					rehash( new_num );
 | 
										rehash( new_num );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -105,7 +105,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					GEN_ASSERT_NOT_NULL( map_proc );
 | 
										GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
										for ( ssize idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
											map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -115,16 +115,16 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					GEN_ASSERT_NOT_NULL( map_proc );
 | 
										GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
										for ( ssize idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						map_proc( Entries[ idx ].Key, &Entries[ idx ].Value );
 | 
											map_proc( Entries[ idx ].Key, &Entries[ idx ].Value );
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				void rehash( sw new_num )
 | 
									void rehash( ssize new_num )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw            idx;
 | 
										ssize            idx;
 | 
				
			||||||
					sw            last_added_index;
 | 
										ssize            last_added_index;
 | 
				
			||||||
					HashTable_u32 new_ht = HashTable_u32::init( Hashes.get_header().Allocator );
 | 
										HashTable_u32 new_ht = HashTable_u32::init( Hashes.get_header().Allocator );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					new_ht.Hashes.resize( new_num );
 | 
										new_ht.Hashes.resize( new_num );
 | 
				
			||||||
@@ -163,7 +163,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				void rehash_fast( void )
 | 
									void rehash_fast( void )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw idx;
 | 
										ssize idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					for ( idx = 0; idx < Entries.num(); idx++ )
 | 
										for ( idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
						Entries[ idx ].Next = -1;
 | 
											Entries[ idx ].Next = -1;
 | 
				
			||||||
@@ -189,14 +189,14 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				void remove_entry( sw idx )
 | 
									void remove_entry( ssize idx )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Entries.remove_at( idx );
 | 
										Entries.remove_at( idx );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				void set( u64 key, Type value )
 | 
									void set( u64 key, Type value )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw         idx;
 | 
										ssize         idx;
 | 
				
			||||||
					FindResult find_result;
 | 
										FindResult find_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if ( Hashes.num() == 0 )
 | 
										if ( Hashes.num() == 0 )
 | 
				
			||||||
@@ -228,9 +228,9 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
						grow();
 | 
											grow();
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				sw slot( u64 key )
 | 
									ssize slot( u64 key )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					for ( sw idx = 0; idx < Hashes.num(); ++idx )
 | 
										for ( ssize idx = 0; idx < Hashes.num(); ++idx )
 | 
				
			||||||
						if ( Hashes[ idx ] == key )
 | 
											if ( Hashes[ idx ] == key )
 | 
				
			||||||
							return idx;
 | 
												return idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -242,9 +242,9 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
			protected:
 | 
								protected:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				sw add_entry( u64 key )
 | 
									ssize add_entry( u64 key )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					sw    idx;
 | 
										ssize    idx;
 | 
				
			||||||
					Entry entry = { key, -1 };
 | 
										Entry entry = { key, -1 };
 | 
				
			||||||
					idx         = Entries.num();
 | 
										idx         = Entries.num();
 | 
				
			||||||
					Entries.append( entry );
 | 
										Entries.append( entry );
 | 
				
			||||||
@@ -294,11 +294,11 @@ void gen__hashtable_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_start
 | 
						do_once_start
 | 
				
			||||||
		GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
 | 
							GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gen_array( sw );
 | 
							gen_array( ssize );
 | 
				
			||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenHashTableRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenHashTableRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ Code gen__ring( StrC type )
 | 
				
			|||||||
			{
 | 
								{
 | 
				
			||||||
				using Type = <type>;
 | 
									using Type = <type>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				static <RingName> init( AllocatorInfo allocator, uw max_size )
 | 
									static <RingName> init( AllocatorInfo allocator, usize max_size )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					<RingName> result = { 0 };
 | 
										<RingName> result = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,9 +52,9 @@ Code gen__ring( StrC type )
 | 
				
			|||||||
						Tail = ( Tail + 1 ) % Capacity;
 | 
											Tail = ( Tail + 1 ) % Capacity;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				inline void append( Type* values, sw num )
 | 
									inline void append( Type* values, ssize num )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					for ( sw idx = 0; idx < num; idx++ )
 | 
										for ( ssize idx = 0; idx < num; idx++ )
 | 
				
			||||||
						append( values[ idx ] );
 | 
											append( values[ idx ] );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -88,9 +88,9 @@ Code gen__ring( StrC type )
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				AllocatorInfo Backing;
 | 
									AllocatorInfo Backing;
 | 
				
			||||||
				uw            Capacity;
 | 
									usize            Capacity;
 | 
				
			||||||
				uw            Head;
 | 
									usize            Head;
 | 
				
			||||||
				uw            Tail;
 | 
									usize            Tail;
 | 
				
			||||||
				<BufferName>  Buffer;
 | 
									<BufferName>  Buffer;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
@@ -113,7 +113,7 @@ void gen__ring_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenRingRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenRingRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,14 +23,14 @@ int gen_main()
 | 
				
			|||||||
	gen_sanity();
 | 
						gen_sanity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_array( u8 );
 | 
						gen_array( u8 );
 | 
				
			||||||
	gen_array( sw );
 | 
						gen_array( ssize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_buffer( u8 );
 | 
						gen_buffer( u8 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_hashtable( u32 );
 | 
						gen_hashtable( u32 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_ring( s16 );
 | 
						gen_ring( s16 );
 | 
				
			||||||
	gen_ring( uw );
 | 
						gen_ring( usize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_array_file();
 | 
						gen_array_file();
 | 
				
			||||||
	gen_buffer_file();
 | 
						gen_buffer_file();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -142,7 +142,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
				if ( begin < 0 || end >= header.Num )
 | 
									if ( begin < 0 || end >= header.Num )
 | 
				
			||||||
					return false;
 | 
										return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				for ( sw idx = begin; idx < end; idx++ )
 | 
									for ( ssize idx = begin; idx < end; idx++ )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Data[ idx ] = value;
 | 
										Data[ idx ] = value;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -170,7 +170,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
			, def_execution( code(
 | 
								, def_execution( code(
 | 
				
			||||||
				Header& header = * get_header();
 | 
									Header& header = * get_header();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				uw new_capacity = grow_formula( header.Capacity );
 | 
									usize new_capacity = grow_formula( header.Capacity );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( new_capacity < min_capacity )
 | 
									if ( new_capacity < min_capacity )
 | 
				
			||||||
					new_capacity = 8;
 | 
										new_capacity = 8;
 | 
				
			||||||
@@ -243,7 +243,7 @@ Code gen__array( StrC type )
 | 
				
			|||||||
				if ( new_capacity < header.Num )
 | 
									if ( new_capacity < header.Num )
 | 
				
			||||||
					header.Num = new_capacity;
 | 
										header.Num = new_capacity;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				sw      size       = sizeof(Header) + sizeof(Type) * new_capacity;
 | 
									ssize      size       = sizeof(Header) + sizeof(Type) * new_capacity;
 | 
				
			||||||
				Header* new_header = rcast( Header*, alloc( header.Allocator, size ));
 | 
									Header* new_header = rcast( Header*, alloc( header.Allocator, size ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( new_header == nullptr )
 | 
									if ( new_header == nullptr )
 | 
				
			||||||
@@ -314,7 +314,7 @@ void gen__array_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenArrayRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenArrayRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ Code gen__buffer_base()
 | 
				
			|||||||
	return def_global_body( 1, header );
 | 
						return def_global_body( 1, header );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Code gen__buffer( StrC type, sw type_size )
 | 
					Code gen__buffer( StrC type, ssize type_size )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static CodeType t_allocator_info = def_type( name(AllocatorInfo));
 | 
						static CodeType t_allocator_info = def_type( name(AllocatorInfo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -206,7 +206,7 @@ struct GenBufferRequest
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	StrC Dependency;
 | 
						StrC Dependency;
 | 
				
			||||||
	StrC Type;
 | 
						StrC Type;
 | 
				
			||||||
	sw   TypeSize;
 | 
						ssize   TypeSize;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
Array<GenBufferRequest> GenBufferRequests;
 | 
					Array<GenBufferRequest> GenBufferRequests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,7 +217,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenBufferRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenBufferRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -128,7 +128,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		CodeFn get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr
 | 
							CodeFn get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr
 | 
				
			||||||
			, def_execution( code(
 | 
								, def_execution( code(
 | 
				
			||||||
				sw idx = find( key ).EntryIndex;
 | 
									ssize idx = find( key ).EntryIndex;
 | 
				
			||||||
				if ( idx >= 0 )
 | 
									if ( idx >= 0 )
 | 
				
			||||||
					return & Entries[ idx ].Value;
 | 
										return & Entries[ idx ].Value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -153,7 +153,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
			Code body = def_execution( code(
 | 
								Code body = def_execution( code(
 | 
				
			||||||
				GEN_ASSERT_NOT_NULL( map_proc );
 | 
									GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
									for ( ssize idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
										map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -179,7 +179,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
			Code body = def_execution( code(
 | 
								Code body = def_execution( code(
 | 
				
			||||||
				GEN_ASSERT_NOT_NULL( map_proc );
 | 
									GEN_ASSERT_NOT_NULL( map_proc );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				for ( sw idx = 0; idx < Entries.num(); idx++ )
 | 
									for ( ssize idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
 | 
										map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
@@ -190,7 +190,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		CodeFn grow = def_function( name(grow), __, t_void
 | 
							CodeFn grow = def_function( name(grow), __, t_void
 | 
				
			||||||
			, def_execution( code(
 | 
								, def_execution( code(
 | 
				
			||||||
				sw new_num = array_grow_formula( Entries.num() );
 | 
									ssize new_num = array_grow_formula( Entries.num() );
 | 
				
			||||||
				rehash( new_num );
 | 
									rehash( new_num );
 | 
				
			||||||
			))
 | 
								))
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
@@ -198,8 +198,8 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
		CodeFn rehash;
 | 
							CodeFn rehash;
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			char const* tmpl = stringize(
 | 
								char const* tmpl = stringize(
 | 
				
			||||||
				sw idx;
 | 
									ssize idx;
 | 
				
			||||||
				sw last_added_index;
 | 
									ssize last_added_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				<type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
 | 
									<type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -242,7 +242,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
		CodeFn rehash_fast;
 | 
							CodeFn rehash_fast;
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			char const* tmpl = stringize(
 | 
								char const* tmpl = stringize(
 | 
				
			||||||
				sw idx;
 | 
									ssize idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				for ( idx = 0; idx < Entries.num(); idx++ )
 | 
									for ( idx = 0; idx < Entries.num(); idx++ )
 | 
				
			||||||
					Entries[ idx ].Next = -1;
 | 
										Entries[ idx ].Next = -1;
 | 
				
			||||||
@@ -288,7 +288,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
			));
 | 
								));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Code body = def_execution( code(
 | 
								Code body = def_execution( code(
 | 
				
			||||||
				sw idx;
 | 
									ssize idx;
 | 
				
			||||||
				FindResult find_result;
 | 
									FindResult find_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ( Hashes.num() == 0 )
 | 
									if ( Hashes.num() == 0 )
 | 
				
			||||||
@@ -325,7 +325,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		CodeFn slot = def_function( name(slot), def_param( t_u64, name(key)), t_sw
 | 
							CodeFn slot = def_function( name(slot), def_param( t_u64, name(key)), t_sw
 | 
				
			||||||
			, def_execution( code(
 | 
								, def_execution( code(
 | 
				
			||||||
				for ( sw idx = 0; idx < Hashes.num(); ++idx )
 | 
									for ( ssize idx = 0; idx < Hashes.num(); ++idx )
 | 
				
			||||||
					if ( Hashes[ idx ] == key )
 | 
										if ( Hashes[ idx ] == key )
 | 
				
			||||||
						return idx;
 | 
											return idx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -335,7 +335,7 @@ Code gen__hashtable( StrC type )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		CodeFn add_entry = def_function( name(add_entry), def_param( t_u64, name(key)), t_sw
 | 
							CodeFn add_entry = def_function( name(add_entry), def_param( t_u64, name(key)), t_sw
 | 
				
			||||||
			, def_execution( code(
 | 
								, def_execution( code(
 | 
				
			||||||
				sw idx;
 | 
									ssize idx;
 | 
				
			||||||
				Entry entry = { key, -1 };
 | 
									Entry entry = { key, -1 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				idx = Entries.num();
 | 
									idx = Entries.num();
 | 
				
			||||||
@@ -421,11 +421,11 @@ void gen__hashtable_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_start
 | 
						do_once_start
 | 
				
			||||||
		GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
 | 
							GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		gen_array( sw );
 | 
							gen_array( ssize );
 | 
				
			||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenHashTableRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenHashTableRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,7 +87,7 @@ Code gen__ring( StrC type )
 | 
				
			|||||||
			);
 | 
								);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Code body = def_execution( code(
 | 
								Code body = def_execution( code(
 | 
				
			||||||
				for ( sw idx = 0; idx < num; idx++ )
 | 
									for ( ssize idx = 0; idx < num; idx++ )
 | 
				
			||||||
					append( values[ idx ] );
 | 
										append( values[ idx ] );
 | 
				
			||||||
			));
 | 
								));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -167,7 +167,7 @@ void gen__ring_request( StrC type, StrC dep = {} )
 | 
				
			|||||||
	do_once_end
 | 
						do_once_end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Make sure we don't already have a request for the type.
 | 
						// Make sure we don't already have a request for the type.
 | 
				
			||||||
	for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
 | 
						for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx )
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		StrC const reqest_type = GenRingRequests[ idx ].Type;
 | 
							StrC const reqest_type = GenRingRequests[ idx ].Type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,7 @@ int gen_main()
 | 
				
			|||||||
	gen_sanity_upfront();
 | 
						gen_sanity_upfront();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_array( u8 );
 | 
						gen_array( u8 );
 | 
				
			||||||
	gen_array( sw );
 | 
						gen_array( ssize );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	gen_buffer( u8 );
 | 
						gen_buffer( u8 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,21 +5,64 @@
 | 
				
			|||||||
#define GEN_BENCHMARK
 | 
					#define GEN_BENCHMARK
 | 
				
			||||||
#include "gen.cpp"
 | 
					#include "gen.cpp"
 | 
				
			||||||
#include "gen.builder.cpp"
 | 
					#include "gen.builder.cpp"
 | 
				
			||||||
 | 
					#include "gen.scanner.cpp"
 | 
				
			||||||
#include "sanity.cpp"
 | 
					#include "sanity.cpp"
 | 
				
			||||||
#include "SOA.cpp"
 | 
					#include "SOA.cpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef GEN_SYSTEM_WINDOWS
 | 
				
			||||||
 | 
						#include <process.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace gen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void format_file( char const* path )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						String resolved_path = String::make(GlobalAllocator, to_str(path));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						String style_arg = String::make(GlobalAllocator, txt("-style=file:"));
 | 
				
			||||||
 | 
						style_arg.append("../scripts/.clang-format ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Need to execute clang format on the generated file to get it to match the original.
 | 
				
			||||||
 | 
						#define clang_format      "clang-format "
 | 
				
			||||||
 | 
						#define cf_format_inplace "-i "
 | 
				
			||||||
 | 
						#define cf_verbose        "-verbose "
 | 
				
			||||||
 | 
						String command = String::make( GlobalAllocator, clang_format );
 | 
				
			||||||
 | 
						command.append( cf_format_inplace );
 | 
				
			||||||
 | 
						command.append( cf_verbose );
 | 
				
			||||||
 | 
						command.append( style_arg );
 | 
				
			||||||
 | 
						command.append( resolved_path );
 | 
				
			||||||
 | 
							log_fmt("\tRunning clang-format on file:\n");
 | 
				
			||||||
 | 
							system( command );
 | 
				
			||||||
 | 
							log_fmt("\tclang-format finished reformatting.\n");
 | 
				
			||||||
 | 
						#undef cf_cmd
 | 
				
			||||||
 | 
						#undef cf_format_inplace
 | 
				
			||||||
 | 
						#undef cf_style
 | 
				
			||||||
 | 
						#undef cf_verbse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Code dump_to_scratch_and_retireve( Code code )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Builder ecode_file_temp = Builder::open("gen/scratch.hpp");
 | 
				
			||||||
 | 
						ecode_file_temp.print(code);
 | 
				
			||||||
 | 
						ecode_file_temp.write();
 | 
				
			||||||
 | 
						format_file("gen/scratch.hpp");
 | 
				
			||||||
 | 
						Code result = scan_file( "gen/scratch.hpp" );
 | 
				
			||||||
 | 
						remove("gen/scratch.hpp");
 | 
				
			||||||
 | 
						return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "validate.original.cpp"
 | 
					#include "validate.original.cpp"
 | 
				
			||||||
#include "validate.singleheader.cpp"
 | 
					#include "validate.singleheader.cpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int gen_main()
 | 
					int gen_main()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	using namespace gen;
 | 
					 | 
				
			||||||
	log_fmt("\ngen_time:");
 | 
						log_fmt("\ngen_time:");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// check_sanity();
 | 
						// check_sanity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// check_SOA();
 | 
						// check_SOA();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	validate_original_files_ast();
 | 
						// validate_original_files_ast();
 | 
				
			||||||
	validate_singleheader_ast();
 | 
						validate_singleheader_ast();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,6 @@
 | 
				
			|||||||
#include "gen.scanner.hpp"
 | 
					#include "gen.scanner.hpp"
 | 
				
			||||||
using namespace gen;
 | 
					using namespace gen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GEN_SYSTEM_WINDOWS
 | 
					 | 
				
			||||||
	#include <process.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define path_root         "../"
 | 
					#define path_root         "../"
 | 
				
			||||||
#define path_project      path_root       "project/"
 | 
					#define path_project      path_root       "project/"
 | 
				
			||||||
#define path_scripts      path_root       "scripts/"
 | 
					#define path_scripts      path_root       "scripts/"
 | 
				
			||||||
@@ -26,13 +22,32 @@ void validate_file_ast( char const* path, char const* path_gen )
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	String path_temp = String::make_length( GlobalAllocator, path_gen, str_len( path_gen ) );
 | 
						String path_temp = String::make_length( GlobalAllocator, path_gen, str_len( path_gen ) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Sleep(100);
 | 
				
			||||||
	FileContents file  = file_read_contents( GlobalAllocator, true, path );
 | 
						FileContents file  = file_read_contents( GlobalAllocator, true, path );
 | 
				
			||||||
	// FileError    error = file_open_mode( & path_temp, EFileMode_WRITE, path );
 | 
					
 | 
				
			||||||
	// if ( error != EFileError_NONE )
 | 
						// Duplicate and format
 | 
				
			||||||
	// {
 | 
						{
 | 
				
			||||||
	// 	log_failure( "gen::File::open - Could not open file: %s", path);
 | 
							// Sleep(100);
 | 
				
			||||||
	// 	return;
 | 
							FileInfo  scratch;
 | 
				
			||||||
	// }
 | 
							FileError error = file_open_mode( & scratch, EFileMode_WRITE, "gen/scratch.cpp" );
 | 
				
			||||||
 | 
							if ( error != EFileError_NONE ) {
 | 
				
			||||||
 | 
								log_failure( "gen::File::open - Could not open file: %s", "gen/scratch.cpp");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
							b32 result = file_write( & scratch, file.data, file.size );
 | 
				
			||||||
 | 
							if ( result == false ) {
 | 
				
			||||||
 | 
								log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & scratch ) );
 | 
				
			||||||
 | 
								file_close( & scratch );
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							file_close( & scratch );
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
							format_file( "gen/scratch.cpp" );
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							file = file_read_contents( GlobalAllocator, true, "gen/scratch.cpp" );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u64          time_start = time_rel_ms();
 | 
						u64          time_start = time_rel_ms();
 | 
				
			||||||
	CodeBody     ast        = parse_global_body( { file.size, (char const*)file.data } );
 | 
						CodeBody     ast        = parse_global_body( { file.size, (char const*)file.data } );
 | 
				
			||||||
@@ -85,8 +100,11 @@ void validate_original_files_ast()
 | 
				
			|||||||
	gen::init();
 | 
						gen::init();
 | 
				
			||||||
	log_fmt("\nvalidate_original_files_ast:\n");
 | 
						log_fmt("\nvalidate_original_files_ast:\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PreprocessorDefines.append( get_cached_string( txt("GEN_DEF_INLINE")  ));
 | 
						PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_SEEK_PROC(")));
 | 
				
			||||||
	PreprocessorDefines.append( get_cached_string( txt("GEN_IMPL_INLINE") ));
 | 
						PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_READ_AT_PROC(")));
 | 
				
			||||||
 | 
						PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_WRITE_AT_PROC(")));
 | 
				
			||||||
 | 
						PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_CLOSE_PROC(")));
 | 
				
			||||||
 | 
						PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_OPEN_PROC(")));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Helpers
 | 
						// Helpers
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -99,7 +117,7 @@ void validate_original_files_ast()
 | 
				
			|||||||
	// Dependencies
 | 
						// Dependencies
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		#define validate( path ) validate_file_ast( path_dependencies path, "gen/original/dependencies/" path )
 | 
							#define validate( path ) validate_file_ast( path_dependencies path, "gen/original/dependencies/" path )
 | 
				
			||||||
		validate( "header_start.hpp" );
 | 
							validate( "platform.hpp"     );
 | 
				
			||||||
		validate( "macros.hpp"       );
 | 
							validate( "macros.hpp"       );
 | 
				
			||||||
		validate( "basic_types.hpp"  );
 | 
							validate( "basic_types.hpp"  );
 | 
				
			||||||
		validate( "debug.hpp"        );
 | 
							validate( "debug.hpp"        );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,17 +7,38 @@
 | 
				
			|||||||
#include "gen.scanner.hpp"
 | 
					#include "gen.scanner.hpp"
 | 
				
			||||||
using namespace gen;
 | 
					using namespace gen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef GEN_SYSTEM_WINDOWS
 | 
					 | 
				
			||||||
	#include <process.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void validate_singleheader_ast()
 | 
					void validate_singleheader_ast()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	#define root_dir "../"
 | 
						#define root_dir "../"
 | 
				
			||||||
	gen::init();
 | 
						gen::init();
 | 
				
			||||||
	log_fmt("\validate_singleheader_ast:\n");
 | 
						log_fmt("\nvalidate_singleheader_ast:\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FileContents file = file_read_contents( GlobalAllocator, true, root_dir "singleheader/gen/gen.hpp" );
 | 
						FileContents file = file_read_contents( GlobalAllocator, true, root_dir "singleheader/gen/gen.hpp" );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Duplicate and format
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
							FileInfo  scratch;
 | 
				
			||||||
 | 
							FileError error = file_open_mode( & scratch, EFileMode_WRITE, "gen/scratch.cpp" );
 | 
				
			||||||
 | 
							if ( error != EFileError_NONE ) {
 | 
				
			||||||
 | 
								log_failure( "gen::File::open - Could not open file: %s", "gen/scratch.cpp");
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
							b32 result = file_write( & scratch, file.data, file.size );
 | 
				
			||||||
 | 
							if ( result == false ) {
 | 
				
			||||||
 | 
								log_failure("gen::File::write - Failed to write to file: %s\n", file_name( & scratch ) );
 | 
				
			||||||
 | 
								file_close( & scratch );
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							file_close( & scratch );
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
							format_file( "gen/scratch.cpp" );
 | 
				
			||||||
 | 
							// Sleep(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							file = file_read_contents( GlobalAllocator, true, "gen/scratch.cpp" );
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u64          time_start = time_rel_ms();
 | 
						u64          time_start = time_rel_ms();
 | 
				
			||||||
	CodeBody     ast        = parse_global_body( { file.size, (char const*)file.data } );
 | 
						CodeBody     ast        = parse_global_body( { file.size, (char const*)file.data } );
 | 
				
			||||||
	log_fmt("\nAst generated. Time taken: %llu ms\n", time_rel_ms() - time_start);
 | 
						log_fmt("\nAst generated. Time taken: %llu ms\n", time_rel_ms() - time_start);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								unreal_engine/Readme.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								unreal_engine/Readme.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Unreal Engine Version Generator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This generates a variant of gencpp thats compatiable with use as a thirdparty module within a plugin or module of an Unreal Project or the Engine itself.
 | 
				
			||||||
							
								
								
									
										31
									
								
								unreal_engine/components/header_start.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								unreal_engine/components/header_start.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
						gencpp: An attempt at "simple" staged metaprogramming for c/c++.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						See Readme.md for more information from the project repository.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Public Address:
 | 
				
			||||||
 | 
						https://github.com/Ed94/gencpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						This is a variant intended for use with Unreal Engine 5
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
 | 
				
			||||||
 | 
					#	error Gen.hpp : GEN_TIME not defined
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//! If its desired to roll your own dependencies, define GEN_ROLL_OWN_DEPENDENCIES before including this file.
 | 
				
			||||||
 | 
					// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
 | 
				
			||||||
 | 
					#ifndef GEN_ROLL_OWN_DEPENDENCIES
 | 
				
			||||||
 | 
					#	include "gen.dep.hpp"
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef GEN_NS_BEGIN
 | 
				
			||||||
 | 
					#	ifdef GEN_DONT_USE_NAMESPACE
 | 
				
			||||||
 | 
					#		define GEN_NS
 | 
				
			||||||
 | 
					#		define GEN_NS_BEGIN
 | 
				
			||||||
 | 
					#		define GEN_NS_END
 | 
				
			||||||
 | 
					#	else
 | 
				
			||||||
 | 
					#		define GEN_NS       gen::
 | 
				
			||||||
 | 
					#		define GEN_NS_BEGIN namespace gen {
 | 
				
			||||||
 | 
					#		define GEN_NS_END   }
 | 
				
			||||||
 | 
					#	endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										5
									
								
								unreal_engine/components/src_start.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								unreal_engine/components/src_start.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					#if ! defined(GEN_DONT_ENFORCE_GEN_TIME_GUARD) && ! defined(GEN_TIME)
 | 
				
			||||||
 | 
					#	error Gen.hpp : GEN_TIME not defined
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "gen.hpp"
 | 
				
			||||||
							
								
								
									
										7
									
								
								unreal_engine/enums/AttributeTokens.csv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								unreal_engine/enums/AttributeTokens.csv
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					API_Export,            GEN_API_Export_Code
 | 
				
			||||||
 | 
					API_Import,            GEN_API_Import_Code
 | 
				
			||||||
 | 
					COREUOBJECT_API,       COREUOBJECT_API
 | 
				
			||||||
 | 
					ENGINE_API,            ENGINE_API
 | 
				
			||||||
 | 
					GAMEPLAYABILITIES_API, GAMEPLAYABILITIES_API
 | 
				
			||||||
 | 
					UMG_API,               UMG_API
 | 
				
			||||||
 | 
					UE_DEPRECATED,         UE_DEPRECATED
 | 
				
			||||||
		
		
			
  | 
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user