mirror of
https://github.com/Ed94/gencpp.git
synced 2024-12-22 07:44:45 -08:00
Compare commits
9 Commits
00df336610
...
81a0376c99
Author | SHA1 | Date | |
---|---|---|---|
81a0376c99 | |||
1417a68757 | |||
1e4d5ce630 | |||
0f2763a115 | |||
420f452d35 | |||
908c385de5 | |||
c1878265c8 | |||
23742868c4 | |||
2e5e31ed3b |
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
|
||||||
|
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;
|
||||||
|
@ -17,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,12 +321,11 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
// gen_scanner.cpp
|
// gen_scanner.cpp
|
||||||
if (1)
|
|
||||||
{
|
{
|
||||||
Code parsing = scan_file( "dependencies/parsing.cpp" );
|
Code parsing = scan_file( "dependencies/parsing.cpp" );
|
||||||
Code scanner = scan_file( "auxillary/scanner.cpp" );
|
Code scanner = scan_file( "auxillary/scanner.cpp" );
|
||||||
|
@ -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;
|
||||||
@ -711,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;
|
||||||
@ -726,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;
|
||||||
@ -741,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;
|
||||||
@ -756,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;
|
||||||
@ -771,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;
|
||||||
@ -786,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;
|
||||||
@ -801,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;
|
||||||
@ -816,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;
|
||||||
@ -831,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;
|
||||||
@ -846,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;
|
||||||
@ -861,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;
|
||||||
@ -876,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;
|
||||||
@ -891,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;
|
||||||
@ -906,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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -122,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;
|
||||||
|
@ -193,7 +193,7 @@ CodeBody def_body( CodeT type )
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
StrC token_fmt_impl( sw num, ... )
|
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 };
|
||||||
@ -201,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 + sw(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
|
||||||
|
@ -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_ )
|
||||||
|
|
||||||
@ -5357,3 +5363,7 @@ CodeVar parse_variable()
|
|||||||
|
|
||||||
// namespace parser
|
// namespace parser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CHECK_WAS_DEFINED
|
||||||
|
#pragma pop_macro("check")
|
||||||
|
#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.
|
||||||
|
@ -47,21 +47,21 @@
|
|||||||
#if defined( GEN_COMPILER_MSVC )
|
#if defined( GEN_COMPILER_MSVC )
|
||||||
# if _MSC_VER < 1300
|
# if _MSC_VER < 1300
|
||||||
typedef unsigned char u8;
|
typedef unsigned char u8;
|
||||||
typedef signed char s8;
|
typedef signed char s8;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short u16;
|
||||||
typedef signed short s16;
|
typedef signed short s16;
|
||||||
typedef unsigned int u32;
|
typedef unsigned int u32;
|
||||||
typedef signed int s32;
|
typedef signed int s32;
|
||||||
# else
|
# else
|
||||||
typedef unsigned __int8 u8;
|
typedef unsigned __int8 u8;
|
||||||
typedef signed __int8 s8;
|
typedef signed __int8 s8;
|
||||||
typedef unsigned __int16 u16;
|
typedef unsigned __int16 u16;
|
||||||
typedef signed __int16 s16;
|
typedef signed __int16 s16;
|
||||||
typedef unsigned __int32 u32;
|
typedef unsigned __int32 u32;
|
||||||
typedef signed __int32 s32;
|
typedef signed __int32 s32;
|
||||||
# endif
|
# endif
|
||||||
typedef unsigned __int64 u64;
|
typedef unsigned __int64 u64;
|
||||||
typedef signed __int64 s64;
|
typedef signed __int64 s64;
|
||||||
#else
|
#else
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
|
||||||
@ -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
|
||||||
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
#pragma region Containers
|
#pragma region Containers
|
||||||
|
|
||||||
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,7 +45,7 @@ struct Array
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
uw grow_formula( uw value )
|
usize grow_formula( usize value )
|
||||||
{
|
{
|
||||||
return 2 * value + 8;
|
return 2 * value + 8;
|
||||||
}
|
}
|
||||||
@ -73,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();
|
||||||
|
|
||||||
@ -91,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();
|
||||||
|
|
||||||
@ -117,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();
|
||||||
|
|
||||||
@ -156,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 = sw(begin); idx < sw(end); idx++ )
|
for ( ssize idx = ssize(begin); idx < ssize(end); idx++ )
|
||||||
{
|
{
|
||||||
Data[ idx ] = value;
|
Data[ idx ] = value;
|
||||||
}
|
}
|
||||||
@ -184,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;
|
||||||
@ -195,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;
|
||||||
}
|
}
|
||||||
@ -208,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 );
|
||||||
@ -217,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();
|
||||||
|
|
||||||
@ -227,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();
|
||||||
|
|
||||||
@ -243,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();
|
||||||
|
|
||||||
@ -257,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 )
|
||||||
@ -305,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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -327,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);
|
||||||
@ -357,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;
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ struct HashTable
|
|||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL( map_proc );
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
for ( sw idx = 0; idx < sw(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 );
|
||||||
}
|
}
|
||||||
@ -382,7 +382,7 @@ struct HashTable
|
|||||||
{
|
{
|
||||||
GEN_ASSERT_NOT_NULL( map_proc );
|
GEN_ASSERT_NOT_NULL( map_proc );
|
||||||
|
|
||||||
for ( sw idx = 0; idx < sw(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 );
|
||||||
}
|
}
|
||||||
@ -390,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 < sw(Entries.num()); ++idx )
|
for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
|
||||||
{
|
{
|
||||||
FindResult find_result;
|
FindResult find_result;
|
||||||
|
|
||||||
@ -422,15 +422,15 @@ struct HashTable
|
|||||||
|
|
||||||
void rehash_fast()
|
void rehash_fast()
|
||||||
{
|
{
|
||||||
sw idx;
|
ssize idx;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Entries.num()); idx++ )
|
for ( idx = 0; idx < ssize(Entries.num()); idx++ )
|
||||||
Entries[ idx ].Next = -1;
|
Entries[ idx ].Next = -1;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Hashes.num()); idx++ )
|
for ( idx = 0; idx < ssize(Hashes.num()); idx++ )
|
||||||
Hashes[ idx ] = -1;
|
Hashes[ idx ] = -1;
|
||||||
|
|
||||||
for ( idx = 0; idx < sw(Entries.num()); idx++ )
|
for ( idx = 0; idx < ssize(Entries.num()); idx++ )
|
||||||
{
|
{
|
||||||
Entry* entry;
|
Entry* entry;
|
||||||
FindResult find_result;
|
FindResult find_result;
|
||||||
@ -456,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() )
|
||||||
@ -494,23 +494,23 @@ struct HashTable
|
|||||||
grow();
|
grow();
|
||||||
}
|
}
|
||||||
|
|
||||||
sw slot( u64 key )
|
ssize slot( u64 key )
|
||||||
{
|
{
|
||||||
for ( sw idx = 0; idx < sw(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();
|
||||||
@ -542,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 < uw(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,58 +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
|
||||||
|
|
||||||
#pragma region ForceInline Definition
|
|
||||||
#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
|
#endif
|
||||||
#else
|
|
||||||
# define forceinline
|
|
||||||
# define neverinline
|
|
||||||
#endif
|
|
||||||
#pragma endregion ForceInline Definition
|
|
||||||
|
|
||||||
// Bits
|
#ifndef api_c
|
||||||
|
#define api_c extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef bit
|
#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
|
#endif
|
||||||
|
|
||||||
// Casting
|
|
||||||
|
|
||||||
#ifndef ccast
|
#ifndef ccast
|
||||||
#define ccast( Type, Value ) ( * const_cast< Type* >( & (Value) ) )
|
#define ccast( type, value ) ( const_cast< type >( (value) ) )
|
||||||
#define pcast( Type, Value ) ( * reinterpret_cast< Type* >( & ( Value ) ) )
|
#endif
|
||||||
#define rcast( Type, Value ) reinterpret_cast< Type >( Value )
|
#ifndef pcast
|
||||||
#define scast( Type, Value ) static_cast< Type >( Value )
|
#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
|
#endif
|
||||||
|
|
||||||
// Num Arguments (Varadics)
|
#ifndef stringize
|
||||||
// #if defined(__GNUC__) || defined(__clang__)
|
#define stringize_va( ... ) #__VA_ARGS__
|
||||||
// Supports 0-50 arguments
|
#define stringize( ... ) stringize_va( __VA_ARGS__ )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef do_once
|
||||||
|
#define do_once( statement ) for ( local_persist b32 once = true; once; once = false, (statement) )
|
||||||
|
|
||||||
|
#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, \
|
||||||
@ -67,7 +86,7 @@
|
|||||||
N, ... \
|
N, ... \
|
||||||
) N
|
) N
|
||||||
|
|
||||||
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
// ## deletes preceding comma if _VA_ARGS__ is empty (GCC, Clang)
|
||||||
#define num_args(...) \
|
#define num_args(...) \
|
||||||
num_args_impl(_, ## __VA_ARGS__, \
|
num_args_impl(_, ## __VA_ARGS__, \
|
||||||
100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
|
100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
|
||||||
@ -82,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 ) )
|
||||||
@ -114,17 +122,17 @@ GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw n
|
|||||||
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
/* define GEN_HEAP_ANALYSIS to enable this feature */
|
||||||
/* 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 )
|
||||||
@ -463,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()
|
||||||
{
|
{
|
||||||
@ -493,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 );
|
||||||
}
|
}
|
||||||
@ -523,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();
|
||||||
|
|
||||||
@ -547,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()
|
||||||
{
|
{
|
||||||
@ -558,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 < scast(sw, 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 < scast(sw, 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 < scast(sw, 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 < scast(sw, 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 < scast(sw, 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 < scast(sw, 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 < scast(sw, 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 > scast(sw, 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 >= scast(sw, 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 < scast(sw, 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 @@
|
|||||||
#pragma once
|
#ifdef GEN_INTELLISENSE_DIRECTIVES
|
||||||
|
# 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 );
|
||||||
|
@ -12,23 +12,23 @@ struct FileInfo;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 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,7 +118,7 @@ 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;
|
||||||
|
|
||||||
|
@ -8,15 +8,15 @@
|
|||||||
// 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
|
inline
|
||||||
StrC to_str( char const* str )
|
StrC to_str( char const* str )
|
||||||
@ -33,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;
|
||||||
@ -47,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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,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 ] );
|
||||||
|
|
||||||
@ -91,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;
|
||||||
|
|
||||||
@ -104,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 )
|
||||||
{
|
{
|
||||||
@ -123,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;
|
||||||
@ -155,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 ));
|
||||||
@ -168,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 ));
|
||||||
@ -201,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 ));
|
||||||
@ -273,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;
|
||||||
@ -284,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 );
|
||||||
@ -379,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
|
||||||
|
|
||||||
|
@ -70,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;
|
||||||
@ -126,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;
|
||||||
@ -241,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;
|
||||||
@ -250,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;
|
||||||
|
@ -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
|
||||||
|
@ -291,7 +291,7 @@ 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
|
||||||
$include = @(
|
$include = @(
|
||||||
@ -301,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 = @(
|
||||||
@ -316,7 +316,7 @@ 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 ( $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
|
if ( $false -and $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
|
||||||
{
|
{
|
||||||
$path_gen = join-path $path_unreal gen
|
$path_gen = join-path $path_unreal gen
|
||||||
$include = @(
|
$include = @(
|
||||||
|
@ -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 unreal
|
& $build release msvc bootstrap singleheader unreal msvc debug
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
& $build release clang bootstrap singleheader unreal
|
& $build release clang bootstrap singleheader unreal msvc debug
|
||||||
}
|
}
|
||||||
|
|
||||||
$path_root = git rev-parse --show-toplevel
|
$path_root = git rev-parse --show-toplevel
|
||||||
@ -24,45 +24,68 @@ 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
|
||||||
|
$readme_root = Join-Path $path_root Readme.md
|
||||||
|
$readme_docs = Join-Path $path_docs Readme.md
|
||||||
|
$readme_ast_design = Join-Path $path_docs AST_Design.md
|
||||||
|
$readme_ast_types = Join-Path $path_docs AST_Types.md
|
||||||
|
$readme_parsing = Join-Path $path_docs Parsing.md
|
||||||
|
$readme_parser_algo = Join-Path $path_docs Parser_Algo.md
|
||||||
|
|
||||||
|
Copy-Item $license -Destination (Join-Path $path_release_content "LICENSE")
|
||||||
|
Copy-Item $readme_root -Destination (Join-Path $path_release_content "Readme.md")
|
||||||
|
Copy-Item $readme_docs -Destination (Join-Path $path_release_content "Readme_Docs.md")
|
||||||
|
Copy-Item $readme_ast_design -Destination (Join-Path $path_release_content "AST_Design.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_parser_algo -Destination (Join-Path $path_release_content "Parser_Algo.md")
|
||||||
}
|
}
|
||||||
|
|
||||||
$license = Join-Path $path_root LICENSE
|
|
||||||
$readme_root = Join-Path $path_root Readme.md
|
|
||||||
$readme_docs = Join-Path $path_docs Readme.md
|
|
||||||
$readme_ast_design = Join-Path $path_docs AST_Design.md
|
|
||||||
$readme_ast_types = Join-Path $path_docs AST_Types.md
|
|
||||||
$readme_parsing = Join-Path $path_docs Parsing.md
|
|
||||||
$readme_parser_algo = Join-Path $path_docs Parser_Algo.md
|
|
||||||
|
|
||||||
Copy-Item $license -Destination (Join-Path $path_release_content "LICENSE")
|
|
||||||
Copy-Item $readme_root -Destination (Join-Path $path_release_content "Readme.md")
|
|
||||||
Copy-Item $readme_docs -Destination (Join-Path $path_release_content "Readme_Docs.md")
|
|
||||||
Copy-Item $readme_ast_design -Destination (Join-Path $path_release_content "AST_Design.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_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\gen.dep.hpp
|
Remove-Item -Path $path_release_content -Recurse
|
||||||
Remove-Item -Path $path_release_content\gen.dep.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.builder.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.builder.cpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.scanner.hpp
|
|
||||||
Remove-Item -Path $path_release_content\gen.scanner.cpp
|
|
||||||
|
|
||||||
# Unreal
|
# Unreal
|
||||||
|
prep-ReleaseContent
|
||||||
Copy-Item -Path $path_unreal_gen\* -Destination $path_release_content
|
Copy-Item -Path $path_unreal_gen\* -Destination $path_release_content
|
||||||
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_unreal.zip -Force
|
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
|
||||||
|
@ -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 );
|
||||||
@ -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" );
|
||||||
|
|
||||||
|
// 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" );
|
||||||
|
}
|
||||||
|
|
||||||
FileContents file = file_read_contents( GlobalAllocator, true, root_dir "singleheader/gen/gen.hpp" );
|
|
||||||
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);
|
||||||
|
@ -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 =
|
||||||
@ -48,6 +50,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/"
|
||||||
@ -61,24 +99,6 @@ int gen_main()
|
|||||||
|
|
||||||
// gen_dep.hpp
|
// gen_dep.hpp
|
||||||
{
|
{
|
||||||
CodeBody header_start = def_body( CodeT::Global_Body );
|
|
||||||
{
|
|
||||||
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/header_start.hpp" );
|
|
||||||
CodeBody ori_header_start = parse_global_body( StrC { content.size, (char const*)content.data });
|
|
||||||
|
|
||||||
for (Code code = ori_header_start.begin();
|
|
||||||
code != ori_header_start.end();
|
|
||||||
++ code )
|
|
||||||
{
|
|
||||||
header_start.append(code);
|
|
||||||
if (code->Type == CodeT::Preprocess_Pragma && code->Content.starts_with(txt("once")))
|
|
||||||
{
|
|
||||||
header_start.append( fmt_newline );
|
|
||||||
header_start.append( push_ignores );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CodeBody macros = def_body( CodeT::Global_Body );
|
CodeBody macros = def_body( CodeT::Global_Body );
|
||||||
{
|
{
|
||||||
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/macros.hpp" );
|
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/macros.hpp" );
|
||||||
@ -111,6 +131,7 @@ int gen_main()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Code platform = scan_file( project_dir "dependencies/platform.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" );
|
||||||
Code memory = scan_file( project_dir "dependencies/memory.hpp" );
|
Code memory = scan_file( project_dir "dependencies/memory.hpp" );
|
||||||
@ -125,10 +146,13 @@ 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( header_start );
|
header.print( pragma_once );
|
||||||
|
header.print( push_ignores );
|
||||||
|
header.print( platform );
|
||||||
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
header.print_fmt( "\nGEN_NS_BEGIN\n" );
|
||||||
|
|
||||||
header.print( macros );
|
header.print( fmt_newline);
|
||||||
|
header.print( dump_to_scratch_and_retireve(macros) );
|
||||||
header.print( basic_types );
|
header.print( basic_types );
|
||||||
header.print( debug );
|
header.print( debug );
|
||||||
header.print( memory );
|
header.print( memory );
|
||||||
@ -209,9 +233,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" );
|
||||||
@ -225,7 +253,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 );
|
||||||
@ -275,7 +304,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 );
|
||||||
|
Loading…
Reference in New Issue
Block a user