Compare commits

..

No commits in common. "81a0376c99e17e35b6a46bc939d2c4fbc88e35d3" and "00df336610d431545ee0c1aa35edbf65277535a2" have entirely different histories.

82 changed files with 13593 additions and 1406 deletions

2
.gitignore vendored
View File

@ -29,5 +29,3 @@ release/**
! **/Unreal/validate.unreal.cpp
project/auxillary/vis_ast/dependencies/temp
test/gen/original
singleheader/gen/scratch.hpp
test/gen/scratch.cpp

View File

@ -67,7 +67,7 @@ Example using each construction interface:
Validation and construction through a functional interface.
```cpp
Code t_uw = def_type( name(usize) );
Code t_uw = def_type( name(uw) );
Code t_allocator = def_type( name(allocator) );
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(
struct ArrayHeader
{
usize Num;
usize Capacity;
uw Num;
uw Capacity;
allocator Allocator;
};
));
@ -106,8 +106,8 @@ No validation, just glorified text injection.
Code header = code_str(
struct ArrayHeader
{
usize Num;
usize Capacity;
uw Num;
uw Capacity;
allocator Allocator;
};
);
@ -123,8 +123,8 @@ All three constrcuton interfaces will generate the following C code:
```cpp
struct ArrayHeader
{
usize Num;
usize Capacity;
uw Num;
uw Capacity;
allocator Allocator;
};
```

View File

@ -136,7 +136,7 @@ The width dictates how much the static array can hold before it must give way to
```cpp
constexpr static
usize ArrSpecs_Cap =
uw ArrSpecs_Cap =
(
AST_POD_Size
- sizeof(AST*) * 3
@ -158,7 +158,7 @@ Data Notes:
* Most of the work is just defining the allocation procedure:
```cpp
void* ( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
void* ( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
```
* ASTs are wrapped for the user in a Code struct which is a wrapper for a AST* type.

View File

@ -6,7 +6,6 @@
<SyncFiles>true</SyncFiles>
<Recursive>true</Recursive>
<ShowEmptyFolders>true</ShowEmptyFolders>
<IncludeFilesWithoutExt>false</IncludeFilesWithoutExt>
<IsVirtual>false</IsVirtual>
<IsFolder>false</IsFolder>
<BuildCommand>pwsh ./scripts/build.ps1 msvc debug bootstrap</BuildCommand>
@ -15,13 +14,12 @@
<CleanCommand>pwsh ./scripts/clean.ps1</CleanCommand>
<BuildWorkingDirectory></BuildWorkingDirectory>
<CancelBuild></CancelBuild>
<Exe>./test/gen/build/gencpp.exe</Exe>
<Args></Args>
<WorkingDirectory></WorkingDirectory>
<RunCommand>./test/gen/build/gencpp.exe</RunCommand>
<RunCommandWorkingDirectory></RunCommandWorkingDirectory>
<DebugCommand>pwsh ./scripts/build.ps1</DebugCommand>
<ExePathCommand>./test/gen/build/gencpp.exe</ExePathCommand>
<DebugSln></DebugSln>
<UseVisualStudioEnvBat>true</UseVisualStudioEnvBat>
<CaptureExeOutput>false</CaptureExeOutput>
<Configurations>
<Configuration>Debug</Configuration>
<Configuration>Release</Configuration>
@ -46,8 +44,6 @@
<Define>GEN_SYSTEM_WINDOWS</Define>
<Define>GEN_INTELLISENSE_DIRECTIVES</Define>
<Define>GEN_EXECUTION_EXPRESSION_SUPPORT</Define>
<Define>GEN_BENCHMARK</Define>
<Define>GEN_COMPILER_MSVC</Define>
</Defines>
<ConfigProperties>
<ConfigAndPlatform>

View File

@ -27,14 +27,14 @@ void Builder::pad_lines( s32 num )
void Builder::print( Code code )
{
String str = code->to_string();
// const ssize len = str.length();
// const sw len = str.length();
// log_fmt( "%s - print: %.*s\n", File.filename, len > 80 ? 80 : len, str.Data );
Buffer.append( str );
}
void Builder::print_fmt( char const* fmt, ... )
{
ssize res;
sw res;
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
va_list va;

View File

@ -17,7 +17,7 @@ Code scan_file( char const* path )
GEN_FATAL( "scan_file: Could not open: %s", path );
}
ssize fsize = file_size( & file );
sw fsize = file_size( & file );
if ( fsize <= 0 )
{
GEN_FATAL("scan_file: %s is empty", path );

View File

@ -0,0 +1,126 @@
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

View File

@ -0,0 +1,22 @@
$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
}

View File

@ -0,0 +1,25 @@
#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 ) )

View File

@ -0,0 +1,10 @@
// 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

View File

@ -0,0 +1,22 @@
// 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

View File

@ -0,0 +1,34 @@
#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

View File

@ -0,0 +1,22 @@
// 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

View File

@ -0,0 +1,45 @@
#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;
}

View File

@ -0,0 +1,3 @@
#pragma once
using HINSTANCE = void*;

View File

@ -0,0 +1,14 @@
#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"

View File

@ -0,0 +1,285 @@
/**********************************************************************************************
*
* 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

View File

@ -0,0 +1,562 @@
/*******************************************************************************************
*
* 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

View File

@ -0,0 +1,579 @@
/**********************************************************************************************
*
* 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(&currentTime);
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

View File

@ -0,0 +1,81 @@
/**********************************************************************************************
*
* 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

View File

@ -0,0 +1,8 @@
#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

View File

@ -0,0 +1,242 @@
// 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

View File

@ -0,0 +1,322 @@
#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;
}

View File

@ -0,0 +1,10 @@
# 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.

View File

View File

@ -0,0 +1,256 @@
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

View File

@ -20,44 +20,6 @@ constexpr char const* generation_notice =
"// This file was generated automatially by gencpp's bootstrap.cpp "
"(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()
{
gen::init();
@ -67,7 +29,7 @@ int gen_main()
// gen_dep.hpp
{
Code platform = scan_file( "dependencies/platform.hpp" );
Code header_start = scan_file( "dependencies/header_start.hpp" );
Code macros = scan_file( "dependencies/macros.hpp" );
Code basic_types = scan_file( "dependencies/basic_types.hpp" );
Code debug = scan_file( "dependencies/debug.hpp" );
@ -83,8 +45,8 @@ int gen_main()
Builder
header = Builder::open("gen/gen.dep.hpp");
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" );
header.print( platform );
header.print_fmt( "// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)\n\n" );
header.print( header_start );
header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( macros );
@ -118,7 +80,7 @@ int gen_main()
Builder
src = Builder::open( "gen/gen.dep.cpp" );
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" );
src.print_fmt( "// This file is intended to be included within gen.cpp (There is no pragma diagnostic ignores)\n\n" );
src.print( src_start );
src.print_fmt( "\nGEN_NS_BEGIN\n" );
@ -170,13 +132,9 @@ int gen_main()
header.print_fmt( "#pragma region Types\n" );
header.print( types );
header.print( fmt_newline);
header.print( dump_to_scratch_and_retireve(ecode) );
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( ecode );
header.print( eoperator );
header.print( especifier );
header.print_fmt( "#pragma endregion Types\n\n" );
header.print_fmt( "#pragma region AST\n" );
@ -190,8 +148,7 @@ int gen_main()
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
header.print( fmt_newline );
header.print( dump_to_scratch_and_retireve(ast_inlines) );
header.print( fmt_newline );
header.print( ast_inlines );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
@ -246,7 +203,7 @@ int gen_main()
src.print_fmt( generation_notice );
src.print( push_ignores );
src.print( src_start );
src.print_fmt( "\nGEN_NS_BEGIN\n");
src.print_fmt( "GEN_NS_BEGIN\n");
src.print( static_data );
@ -260,7 +217,7 @@ int gen_main()
src.print( interface );
src.print( upfront );
src.print_fmt( "\n#pragma region Parsing\n\n" );
src.print( dump_to_scratch_and_retireve(nspaced_etoktype) );
src.print( nspaced_etoktype );
src.print( lexer );
src.print( parser );
src.print( parsing_interface );
@ -321,11 +278,12 @@ int gen_main()
header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( parsing );
header.print( scanner );
header.print_fmt( "\nGEN_NS_END\n" );
header.print_fmt( "GEN_NS_END\n" );
header.write();
}
// gen_scanner.cpp
if (1)
{
Code parsing = scan_file( "dependencies/parsing.cpp" );
Code scanner = scan_file( "auxillary/scanner.cpp" );

View File

@ -211,7 +211,7 @@ struct AST_Expr
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -226,7 +226,7 @@ struct AST_Expr_Assign
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -241,7 +241,7 @@ struct AST_Expr_Alignof
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -256,7 +256,7 @@ struct AST_Expr_Binary
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -271,7 +271,7 @@ struct AST_Expr_CStyleCast
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -286,7 +286,7 @@ struct AST_Expr_FunctionalCast
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -301,7 +301,7 @@ struct AST_Expr_CppCast
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -316,7 +316,7 @@ struct AST_Expr_ProcCall
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -331,7 +331,7 @@ struct AST_Expr_Decltype
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -346,7 +346,7 @@ struct AST_Expr_Comma
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -361,7 +361,7 @@ struct AST_Expr_AMS
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -376,7 +376,7 @@ struct AST_Expr_Sizeof
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -391,7 +391,7 @@ struct AST_Expr_Subscript
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -406,7 +406,7 @@ struct AST_Expr_Ternary
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -421,7 +421,7 @@ struct AST_Expr_UnaryPrefix
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -436,7 +436,7 @@ struct AST_Expr_UnaryPostfix
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -451,7 +451,7 @@ struct AST_Expr_Element
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -711,7 +711,7 @@ struct AST_Stmt
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -726,7 +726,7 @@ struct AST_Stmt_Break
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -741,7 +741,7 @@ struct AST_Stmt_Case
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -756,7 +756,7 @@ struct AST_Stmt_Continue
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -771,7 +771,7 @@ struct AST_Stmt_Decl
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -786,7 +786,7 @@ struct AST_Stmt_Do
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -801,7 +801,7 @@ struct AST_Stmt_Expr
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -816,7 +816,7 @@ struct AST_Stmt_Else
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -831,7 +831,7 @@ struct AST_Stmt_If
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -846,7 +846,7 @@ struct AST_Stmt_For
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -861,7 +861,7 @@ struct AST_Stmt_Goto
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -876,7 +876,7 @@ struct AST_Stmt_Label
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -891,7 +891,7 @@ struct AST_Stmt_Switch
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;
@ -906,7 +906,7 @@ struct AST_Stmt_While
{
union {
char _PAD_[ sizeof(SpecifierT) * AST::ArrSpecs_Cap + sizeof(AST*) ];
};
}
CodeExpr Prev;
CodeExpr Next;
parser::Token* Tok;

View File

@ -42,7 +42,7 @@ constexpr s32 InitSize_DataArrays = 16;
// 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.
constexpr usize Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
constexpr uw Global_BucketSize = GEN_GLOBAL_BUCKET_SIZE;
constexpr s32 CodePool_NumBlocks = GEN_CODEPOOL_NUM_BLOCKS;
constexpr s32 SizePer_StringArena = GEN_SIZE_PER_STRING_ARENA;
@ -122,8 +122,8 @@ extern CodeType t_typename;
extern CodeType t_u32;
extern CodeType t_u64;
extern CodeType t_ssize;
extern CodeType t_usize;
extern CodeType t_sw;
extern CodeType t_uw;
extern CodeType t_f32;
extern CodeType t_f64;

View File

@ -193,7 +193,7 @@ CodeBody def_body( CodeT type )
}
inline
StrC token_fmt_impl( ssize num, ... )
StrC token_fmt_impl( sw num, ... )
{
local_persist thread_local
char buf[GEN_PRINTF_MAXLEN] = { 0 };
@ -201,7 +201,7 @@ StrC token_fmt_impl( ssize num, ... )
va_list va;
va_start(va, num );
ssize result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
sw result = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num, va);
va_end(va);
return { result, buf };

View File

@ -9,7 +9,7 @@ internal void deinit();
}
internal
void* Global_Allocator_Proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
void* Global_Allocator_Proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
{
Arena* last = & Global_AllocatorBuckets.back();
@ -169,8 +169,8 @@ void define_constants()
def_constant_code_type( u32 );
def_constant_code_type( u64 );
def_constant_code_type( ssize );
def_constant_code_type( usize );
def_constant_code_type( sw );
def_constant_code_type( uw );
def_constant_code_type( f32 );
def_constant_code_type( f64 );
@ -298,8 +298,8 @@ void init()
void deinit()
{
usize index = 0;
usize left = CodePools.num();
uw index = 0;
uw left = CodePools.num();
do
{
Pool* code_pool = & CodePools[index];
@ -372,9 +372,9 @@ AllocatorInfo get_string_allocator( s32 str_length )
{
Arena* last = & StringArenas.back();
usize size_req = str_length + sizeof(String::Header) + sizeof(char*);
uw size_req = str_length + sizeof(String::Header) + sizeof(char*);
if ( last->TotalUsed + ssize(size_req) > last->TotalSize )
if ( last->TotalUsed + sw(size_req) > last->TotalSize )
{
Arena new_arena = Arena::init_from_allocator( Allocator_StringArena, SizePer_StringArena );

View File

@ -166,7 +166,7 @@ namespace parser {
}
struct ParseInfo
{
Arena FileMem;
Arena TokMem;
Arena CodeMem;
@ -175,7 +175,7 @@ struct ParseInfo
Array<parser::Token> Tokens;
Array<parser::Error> Errors;
// Errors are allocated to a dedicated general arena.
};
;
CodeBody parse_file( StrC path );
#endif
@ -204,9 +204,9 @@ CodeVar parse_variable ( StrC var_def );
#pragma region Untyped text
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va );
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va );
//! Do not use directly. Use the token_fmt macro instead.
StrC token_fmt_impl( ssize, ... );
StrC token_fmt_impl( sw, ... );
Code untyped_str ( StrC content);
Code untyped_fmt ( char const* fmt, ... );

View File

@ -3,10 +3,10 @@
#include "interface.parsing.cpp"
#endif
ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
sw token_fmt_va( char* buf, uw buf_size, s32 num_tokens, va_list va )
{
char const* buf_begin = buf;
ssize remaining = buf_size;
sw remaining = buf_size;
local_persist
Arena tok_map_arena;
@ -37,7 +37,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
while ( current )
{
ssize len = 0;
sw len = 0;
while ( current && current != '<' && remaining )
{
@ -68,7 +68,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
if ( value )
{
ssize left = value->Len;
sw left = value->Len;
char const* str = value->Ptr;
while ( left-- )
@ -97,7 +97,7 @@ ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list va )
tok_map.clear();
tok_map_arena.free();
ssize result = buf_size - remaining;
sw result = buf_size - remaining;
return result;
}
@ -138,7 +138,7 @@ Code untyped_fmt( char const* fmt, ...)
va_list va;
va_start(va, fmt);
ssize length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
sw length = str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va);
va_end(va);
Code
@ -169,7 +169,7 @@ Code untyped_token_fmt( s32 num_tokens, ... )
va_list va;
va_start(va, num_tokens);
ssize length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
sw length = token_fmt_va(buf, GEN_PRINTF_MAXLEN, num_tokens, va);
va_end(va);
Code

View File

@ -169,12 +169,6 @@ if ( def.Ptr == nullptr ) \
# define eat( Type_ ) Context.Tokens.__eat( Type_ )
# 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( Type_ ) ( left && currtok.Type == Type_ )
@ -5363,7 +5357,3 @@ CodeVar parse_variable()
// namespace parser
}
#ifdef CHECK_WAS_DEFINED
#pragma pop_macro("check")
#endif

View File

@ -97,8 +97,8 @@ global CodeType t_u16;
global CodeType t_u32;
global CodeType t_u64;
global CodeType t_ssize;
global CodeType t_usize;
global CodeType t_sw;
global CodeType t_uw;
global CodeType t_f32;
global CodeType t_f64;

View File

@ -3,7 +3,7 @@
#include "header_start.hpp"
#endif
using LogFailType = ssize(*)(char const*, ...);
using LogFailType = sw(*)(char const*, ...);
// 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.

View File

@ -85,10 +85,10 @@ static_assert( sizeof( u16 ) == 2, "sizeof(u16) != 2" );
static_assert( sizeof( u32 ) == 4, "sizeof(u32) != 4" );
static_assert( sizeof( u64 ) == 8, "sizeof(u64) != 8" );
typedef size_t usize;
typedef ptrdiff_t ssize;
typedef size_t uw;
typedef ptrdiff_t sw;
static_assert( sizeof( usize ) == sizeof( ssize ), "sizeof(usize) != sizeof(ssize)" );
static_assert( sizeof( uw ) == sizeof( sw ), "sizeof(uw) != sizeof(sw)" );
// NOTE: (u)zpl_intptr is only here for semantic reasons really as this library will only support 32/64 bit OSes.
#if defined( _WIN64 )
@ -122,13 +122,4 @@ typedef s8 b8;
typedef s16 b16;
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

View File

@ -8,7 +8,7 @@
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, usize Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; };
template<class TType, uw Size> struct RemoveConst<const TType[Size]> { typedef TType Type[Size]; };
template<class TType>
using TRemoveConst = typename RemoveConst<TType>::Type;
@ -19,8 +19,8 @@ struct Array
struct Header
{
AllocatorInfo Allocator;
usize Capacity;
usize Num;
uw Capacity;
uw Num;
};
static
@ -30,7 +30,7 @@ struct Array
}
static
Array init_reserve( AllocatorInfo allocator, ssize capacity )
Array init_reserve( AllocatorInfo allocator, sw capacity )
{
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) * capacity ));
@ -45,7 +45,7 @@ struct Array
}
static
usize grow_formula( usize value )
uw grow_formula( uw value )
{
return 2 * value + 8;
}
@ -73,7 +73,7 @@ struct Array
return true;
}
bool append( Type* items, usize item_num )
bool append( Type* items, uw item_num )
{
Header* header = get_header();
@ -91,7 +91,7 @@ struct Array
return true;
}
bool append_at( Type item, usize idx )
bool append_at( Type item, uw idx )
{
Header* header = get_header();
@ -117,7 +117,7 @@ struct Array
return true;
}
bool append_at( Type* items, usize item_num, usize idx )
bool append_at( Type* items, uw item_num, uw idx )
{
Header* header = get_header();
@ -156,14 +156,14 @@ struct Array
header.Num = 0;
}
bool fill( usize begin, usize end, Type value )
bool fill( uw begin, uw end, Type value )
{
Header& header = * get_header();
if ( begin < 0 || end > header.Num )
return false;
for ( ssize idx = ssize(begin); idx < ssize(end); idx++ )
for ( sw idx = sw(begin); idx < sw(end); idx++ )
{
Data[ idx ] = value;
}
@ -184,10 +184,10 @@ struct Array
return rcast( Header*, const_cast<NonConstType*>(Data) ) - 1 ;
}
bool grow( usize min_capacity )
bool grow( uw min_capacity )
{
Header& header = * get_header();
usize new_capacity = grow_formula( header.Capacity );
uw new_capacity = grow_formula( header.Capacity );
if ( new_capacity < min_capacity )
new_capacity = min_capacity;
@ -195,7 +195,7 @@ struct Array
return set_capacity( new_capacity );
}
usize num( void )
uw num( void )
{
return get_header()->Num;
}
@ -208,7 +208,7 @@ struct Array
header.Num--;
}
void remove_at( usize idx )
void remove_at( uw idx )
{
Header* header = get_header();
GEN_ASSERT( idx < header->Num );
@ -217,7 +217,7 @@ struct Array
header->Num--;
}
bool reserve( usize new_capacity )
bool reserve( uw new_capacity )
{
Header& header = * get_header();
@ -227,7 +227,7 @@ struct Array
return true;
}
bool resize( usize num )
bool resize( uw num )
{
Header* header = get_header();
@ -243,7 +243,7 @@ struct Array
return true;
}
bool set_capacity( usize new_capacity )
bool set_capacity( uw new_capacity )
{
Header& header = * get_header();
@ -257,7 +257,7 @@ struct Array
return true;
}
ssize size = sizeof( Header ) + sizeof( Type ) * new_capacity;
sw size = sizeof( Header ) + sizeof( Type ) * new_capacity;
Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
if ( new_header == nullptr )
@ -305,15 +305,15 @@ struct HashTable
{
struct FindResult
{
ssize HashIndex;
ssize PrevIndex;
ssize EntryIndex;
sw HashIndex;
sw PrevIndex;
sw EntryIndex;
};
struct Entry
{
u64 Key;
ssize Next;
sw Next;
Type Value;
};
@ -327,11 +327,11 @@ struct HashTable
}
static
HashTable init_reserve( AllocatorInfo allocator, usize num )
HashTable init_reserve( AllocatorInfo allocator, uw num )
{
HashTable<Type> result = { { nullptr }, { nullptr } };
result.Hashes = Array<ssize>::init_reserve( allocator, num );
result.Hashes = Array<sw>::init_reserve( allocator, num );
result.Hashes.get_header()->Num = num;
result.Hashes.resize( num );
result.Hashes.fill( 0, num, -1);
@ -357,7 +357,7 @@ struct HashTable
Type* get( u64 key )
{
ssize idx = find( key ).EntryIndex;
sw idx = find( key ).EntryIndex;
if ( idx >= 0 )
return & Entries[ idx ].Value;
@ -370,7 +370,7 @@ struct HashTable
{
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
{
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
}
@ -382,7 +382,7 @@ struct HashTable
{
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
{
map_proc( Entries[ idx ].Key, & Entries[ idx ].Value );
}
@ -390,16 +390,16 @@ struct HashTable
void grow()
{
ssize new_num = Array<Entry>::grow_formula( Entries.num() );
sw new_num = Array<Entry>::grow_formula( Entries.num() );
rehash( new_num );
}
void rehash( ssize new_num )
void rehash( sw new_num )
{
ssize last_added_index;
sw last_added_index;
HashTable<Type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
for ( ssize idx = 0; idx < ssize(Entries.num()); ++idx )
for ( sw idx = 0; idx < sw(Entries.num()); ++idx )
{
FindResult find_result;
@ -422,15 +422,15 @@ struct HashTable
void rehash_fast()
{
ssize idx;
sw idx;
for ( idx = 0; idx < ssize(Entries.num()); idx++ )
for ( idx = 0; idx < sw(Entries.num()); idx++ )
Entries[ idx ].Next = -1;
for ( idx = 0; idx < ssize(Hashes.num()); idx++ )
for ( idx = 0; idx < sw(Hashes.num()); idx++ )
Hashes[ idx ] = -1;
for ( idx = 0; idx < ssize(Entries.num()); idx++ )
for ( idx = 0; idx < sw(Entries.num()); idx++ )
{
Entry* entry;
FindResult find_result;
@ -456,14 +456,14 @@ struct HashTable
}
}
void remove_entry( ssize idx )
void remove_entry( sw idx )
{
Entries.remove_at( idx );
}
void set( u64 key, Type value )
{
ssize idx;
sw idx;
FindResult find_result;
if ( full() )
@ -494,23 +494,23 @@ struct HashTable
grow();
}
ssize slot( u64 key )
sw slot( u64 key )
{
for ( ssize idx = 0; idx < ssize(Hashes.num()); ++idx )
for ( sw idx = 0; idx < sw(Hashes.num()); ++idx )
if ( Hashes[ idx ] == key )
return idx;
return -1;
}
Array< ssize> Hashes;
Array< sw> Hashes;
Array< Entry> Entries;
protected:
ssize add_entry( u64 key )
sw add_entry( u64 key )
{
ssize idx;
sw idx;
Entry entry = { key, -1 };
idx = Entries.num();
@ -542,7 +542,7 @@ protected:
b32 full()
{
usize critical_load = usize( CriticalLoadScale * f32(Hashes.num()) );
uw critical_load = uw( CriticalLoadScale * f32(Hashes.num()) );
b32 result = Entries.num() > critical_load;
return result;
}

View File

@ -24,7 +24,7 @@
{ \
if ( ! ( cond ) ) \
{ \
assert_handler( #cond, __FILE__, scast( s64, __LINE__ ), msg, ##__VA_ARGS__ ); \
assert_handler( #cond, __FILE__, zpl_cast( s64 ) __LINE__, msg, ##__VA_ARGS__ ); \
GEN_DEBUG_TRAP(); \
} \
} while ( 0 )
@ -34,6 +34,10 @@
// NOTE: Things that shouldn't happen with a message!
#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
#define GEN_FATAL( ... ) \
do \
@ -56,8 +60,4 @@
while (0)
#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

View File

@ -7,11 +7,10 @@
#if defined( GEN_SYSTEM_WINDOWS ) || defined( GEN_SYSTEM_CYGWIN )
internal
wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
internal wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, sw* w_len_ )
{
wchar_t* w_text = NULL;
ssize len = 0, w_len = 0, w_len1 = 0;
sw len = 0, w_len = 0, w_len1 = 0;
if ( text == NULL )
{
if ( w_len_ )
@ -25,7 +24,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
*w_len_ = w_len;
return NULL;
}
w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), NULL, 0 );
w_len = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, NULL, 0 );
if ( w_len == 0 )
{
if ( w_len_ )
@ -33,7 +32,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
return NULL;
}
w_text = alloc_array( a, wchar_t, w_len + 1 );
w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, scast( int, len), w_text, scast( int, w_len) );
w_len1 = MultiByteToWideChar( CP_UTF8, MB_ERR_INVALID_CHARS, text, zpl_cast( int ) len, w_text, zpl_cast( int ) w_len );
if ( w_len1 == 0 )
{
free( a, w_text );
@ -47,8 +46,7 @@ wchar_t* _alloc_utf8_to_ucs2( AllocatorInfo a, char const* text, ssize* w_len_ )
return w_text;
}
internal
GEN_FILE_SEEK_PROC( _win32_file_seek )
internal GEN_FILE_SEEK_PROC( _win32_file_seek )
{
LARGE_INTEGER li_offset;
li_offset.QuadPart = offset;
@ -62,13 +60,12 @@ GEN_FILE_SEEK_PROC( _win32_file_seek )
return true;
}
internal
GEN_FILE_READ_AT_PROC( _win32_file_read )
internal GEN_FILE_READ_AT_PROC( _win32_file_read )
{
// unused( stop_at_newline );
b32 result = false;
_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
DWORD bytes_read_;
if ( ReadFile( fd.p, buffer, size_, &bytes_read_, NULL ) )
{
@ -80,10 +77,9 @@ GEN_FILE_READ_AT_PROC( _win32_file_read )
return result;
}
internal
GEN_FILE_WRITE_AT_PROC( _win32_file_write )
internal GEN_FILE_WRITE_AT_PROC( _win32_file_write )
{
DWORD size_ = scast( DWORD, ( size > GEN_I32_MAX ? GEN_I32_MAX : size ));
DWORD size_ = zpl_cast( DWORD )( size > GEN_I32_MAX ? GEN_I32_MAX : size );
DWORD bytes_written_;
_win32_file_seek( fd, offset, ESeekWhence_BEGIN, NULL );
if ( WriteFile( fd.p, buffer, size_, &bytes_written_, NULL ) )
@ -95,16 +91,14 @@ GEN_FILE_WRITE_AT_PROC( _win32_file_write )
return false;
}
internal
GEN_FILE_CLOSE_PROC( _win32_file_close )
internal GEN_FILE_CLOSE_PROC( _win32_file_close )
{
CloseHandle( fd.p );
}
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 creation_disposition;
@ -182,8 +176,7 @@ GEN_FILE_OPEN_PROC( _win32_file_open )
#else // POSIX
# include <fcntl.h>
internal
GEN_FILE_SEEK_PROC( _posix_file_seek )
internal GEN_FILE_SEEK_PROC( _posix_file_seek )
{
# if defined( GEN_SYSTEM_OSX )
s64 res = lseek( fd.i, offset, whence );
@ -197,11 +190,10 @@ GEN_FILE_SEEK_PROC( _posix_file_seek )
return true;
}
internal
GEN_FILE_READ_AT_PROC( _posix_file_read )
internal GEN_FILE_READ_AT_PROC( _posix_file_read )
{
unused( stop_at_newline );
ssize res = pread( fd.i, buffer, size, offset );
sw res = pread( fd.i, buffer, size, offset );
if ( res < 0 )
return false;
if ( bytes_read )
@ -209,20 +201,19 @@ GEN_FILE_READ_AT_PROC( _posix_file_read )
return true;
}
internal
GEN_FILE_WRITE_AT_PROC( _posix_file_write )
internal GEN_FILE_WRITE_AT_PROC( _posix_file_write )
{
ssize res;
sw res;
s64 curr_offset = 0;
_posix_file_seek( fd, 0, ESeekWhence_CURRENT, &curr_offset );
if ( curr_offset == offset )
{
// NOTE: Writing to stdout et al. doesn't like pwrite for numerous reasons
res = write( scast( int, fd.i), buffer, size );
res = write( zpl_cast( int ) fd.i, buffer, size );
}
else
{
res = pwrite( scast( int, fd.i), buffer, size, offset );
res = pwrite( zpl_cast( int ) fd.i, buffer, size, offset );
}
if ( res < 0 )
return false;
@ -231,16 +222,14 @@ GEN_FILE_WRITE_AT_PROC( _posix_file_write )
return true;
}
internal
GEN_FILE_CLOSE_PROC( _posix_file_close )
internal GEN_FILE_CLOSE_PROC( _posix_file_close )
{
close( fd.i );
}
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;
switch ( mode & GEN_FILE_MODES )
@ -340,7 +329,7 @@ FileError file_close( FileInfo* f )
return EFileError_INVALID;
if ( f->filename )
free( heap(), ccast( char*, f->filename ));
free( heap(), zpl_cast( char* ) f->filename );
#if defined( GEN_SYSTEM_WINDOWS )
if ( f->fd.p == INVALID_HANDLE_VALUE )
@ -375,14 +364,14 @@ FileError file_close( FileInfo* f )
FileError file_new( FileInfo* f, FileDescriptor fd, FileOperations ops, char const* filename )
{
FileError err = EFileError_NONE;
ssize len = str_len( filename );
sw len = str_len( filename );
f->ops = ops;
f->fd = fd;
f->dir = nullptr;
f->last_write_time = 0;
f->filename = alloc_array( heap(), char, len + 1 );
mem_copy( ccast( char*, f->filename), ccast( char*, filename), len + 1 );
mem_copy( zpl_cast( char* ) f->filename, zpl_cast( char* ) filename, len + 1 );
return err;
}
@ -441,7 +430,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
if ( file_open( &file, filepath ) == EFileError_NONE )
{
ssize fsize = scast( ssize , file_size( &file ));
sw fsize = zpl_cast( sw ) file_size( &file );
if ( fsize > 0 )
{
result.data = alloc( a, zero_terminate ? fsize + 1 : fsize );
@ -449,7 +438,7 @@ FileContents file_read_contents( AllocatorInfo a, b32 zero_terminate, char const
file_read_at( &file, result.data, result.size, 0 );
if ( zero_terminate )
{
u8* str = rcast( u8*, result.data);
u8* str = zpl_cast( u8* ) result.data;
str[ fsize ] = '\0';
}
}
@ -463,28 +452,26 @@ struct _memory_fd
{
u8 magic;
u8* buf; //< zpl_array OR plain buffer if we can't write
ssize cursor;
sw cursor;
AllocatorInfo allocator;
FileStreamFlags flags;
ssize cap;
sw cap;
};
#define GEN__FILE_STREAM_FD_MAGIC 37
FileDescriptor _file_stream_fd_make( _memory_fd* d );
_memory_fd* _file_stream_from_fd( FileDescriptor fd );
GEN_DEF_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d );
GEN_DEF_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd );
inline
FileDescriptor _file_stream_fd_make( _memory_fd* d )
GEN_IMPL_INLINE FileDescriptor _file_stream_fd_make( _memory_fd* d )
{
FileDescriptor fd = { 0 };
fd.p = ( void* )d;
return fd;
}
inline
_memory_fd* _file_stream_from_fd( FileDescriptor fd )
GEN_IMPL_INLINE _memory_fd* _file_stream_from_fd( FileDescriptor fd )
{
_memory_fd* d = ( _memory_fd* )fd.p;
GEN_ASSERT( d->magic == GEN__FILE_STREAM_FD_MAGIC );
@ -519,7 +506,7 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator )
return true;
}
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags )
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags )
{
GEN_ASSERT_NOT_NULL( file );
_memory_fd* d = ( _memory_fd* )alloc( allocator, size_of( _memory_fd ) );
@ -556,7 +543,7 @@ b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize
return true;
}
u8* file_stream_buf( FileInfo* file, ssize* size )
u8* file_stream_buf( FileInfo* file, sw* size )
{
GEN_ASSERT_NOT_NULL( file );
_memory_fd* d = _file_stream_from_fd( file->fd );
@ -565,11 +552,10 @@ u8* file_stream_buf( FileInfo* file, ssize* size )
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 );
ssize buflen = d->cap;
sw buflen = d->cap;
if ( whence == ESeekWhence_BEGIN )
d->cursor = 0;
@ -582,8 +568,7 @@ GEN_FILE_SEEK_PROC( _memory_file_seek )
return true;
}
internal
GEN_FILE_READ_AT_PROC( _memory_file_read )
internal GEN_FILE_READ_AT_PROC( _memory_file_read )
{
// unused( stop_at_newline );
_memory_fd* d = _file_stream_from_fd( fd );
@ -593,24 +578,23 @@ GEN_FILE_READ_AT_PROC( _memory_file_read )
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 );
if ( ! ( d->flags & ( EFileStream_CLONE_WRITABLE | EFileStream_WRITABLE ) ) )
return false;
ssize buflen = d->cap;
ssize extralen = max( 0, size - ( buflen - offset ) );
ssize rwlen = size - extralen;
ssize new_cap = buflen + extralen;
sw buflen = d->cap;
sw extralen = max( 0, size - ( buflen - offset ) );
sw rwlen = size - extralen;
sw new_cap = buflen + extralen;
if ( d->flags & EFileStream_CLONE_WRITABLE )
{
Array<u8> arr = { d->buf };
if ( arr.get_header()->Capacity < usize(new_cap) )
if ( arr.get_header()->Capacity < uw(new_cap) )
{
if ( ! arr.grow( ( s64 )( new_cap ) ) )
return false;
@ -638,8 +622,7 @@ GEN_FILE_WRITE_AT_PROC( _memory_file_write )
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 );
AllocatorInfo allocator = d->allocator;

View File

@ -48,8 +48,8 @@ union FileDescriptor
typedef struct FileOperations FileOperations;
#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, 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, ssize size, s64 offset, ssize* bytes_written )
#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_WRITE_AT_PROC( name ) b32 name( FileDescriptor fd, void const* buffer, sw size, s64 offset, sw* bytes_written )
#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 )
@ -161,7 +161,7 @@ FileError file_open_mode( FileInfo* file, FileMode mode, char const* filename );
* @param buffer Buffer to read to
* @param size Size to read
*/
b32 file_read( FileInfo* file, void* buffer, ssize size );
GEN_DEF_INLINE b32 file_read( FileInfo* file, void* buffer, sw size );
/**
* Reads file at a specific offset
@ -171,7 +171,7 @@ b32 file_read( FileInfo* file, void* buffer, ssize size );
* @param offset Offset to read from
* @param bytes_read How much data we've actually read
*/
b32 file_read_at( FileInfo* file, void* buffer, ssize size, s64 offset );
GEN_DEF_INLINE b32 file_read_at( FileInfo* file, void* buffer, sw size, s64 offset );
/**
* Reads file safely
@ -181,13 +181,13 @@ b32 file_read_at( FileInfo* file, void* buffer, ssize size, s64 offset );
* @param offset Offset to read from
* @param bytes_read How much data we've actually read
*/
b32 file_read_at_check( FileInfo* file, void* buffer, ssize size, s64 offset, ssize* bytes_read );
GEN_DEF_INLINE b32 file_read_at_check( FileInfo* file, void* buffer, sw size, s64 offset, sw* bytes_read );
struct FileContents
{
AllocatorInfo allocator;
void* data;
ssize size;
sw size;
};
constexpr b32 zero_terminate = true;
@ -214,20 +214,20 @@ s64 file_size( FileInfo* file );
* @param file
* @param offset Offset to seek to
*/
s64 file_seek( FileInfo* file, s64 offset );
GEN_DEF_INLINE s64 file_seek( FileInfo* file, s64 offset );
/**
* Seeks the file cursor to the end of the file
* @param file
*/
s64 file_seek_to_end( FileInfo* file );
GEN_DEF_INLINE s64 file_seek_to_end( FileInfo* file );
/**
* Returns the length from the beginning of the file we've read so far
* @param file
* @return Our current position in file
*/
s64 file_tell( FileInfo* file );
GEN_DEF_INLINE s64 file_tell( FileInfo* file );
/**
* Writes to a file
@ -235,7 +235,7 @@ s64 file_tell( FileInfo* file );
* @param buffer Buffer to read from
* @param size Size to read
*/
b32 file_write( FileInfo* file, void const* buffer, ssize size );
GEN_DEF_INLINE b32 file_write( FileInfo* file, void const* buffer, sw size );
/**
* Writes to file at a specific offset
@ -245,7 +245,7 @@ b32 file_write( FileInfo* file, void const* buffer, ssize size );
* @param offset Offset to write to
* @param bytes_written How much data we've actually written
*/
b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
GEN_DEF_INLINE b32 file_write_at( FileInfo* file, void const* buffer, sw size, s64 offset );
/**
* Writes to file safely
@ -255,7 +255,86 @@ b32 file_write_at( FileInfo* file, void const* buffer, ssize size, s64 offset );
* @param offset Offset to write to
* @param bytes_written How much data we've actually written
*/
b32 file_write_at_check( FileInfo* file, void const* buffer, ssize size, s64 offset, ssize* bytes_written );
GEN_DEF_INLINE b32 file_write_at_check( FileInfo* file, void const* buffer, sw size, s64 offset, sw* 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
{
@ -282,103 +361,15 @@ b8 file_stream_new( FileInfo* file, AllocatorInfo allocator );
* @param size Buffer's size
* @param flags
*/
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, ssize size, FileStreamFlags flags );
b8 file_stream_open( FileInfo* file, AllocatorInfo allocator, u8* buffer, sw size, FileStreamFlags flags );
/**
* Retrieves the stream's underlying buffer and buffer size.
* @param file memory stream
* @param size (Optional) buffer size
*/
u8* file_stream_buf( FileInfo* file, ssize* size );
u8* file_stream_buf( FileInfo* file, sw* size );
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

View File

@ -27,11 +27,11 @@ global u32 const _crc32_table[ 256 ] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
u32 crc32( void const* data, ssize len )
u32 crc32( void const* data, sw len )
{
ssize remaining;
u32 result = ~( scast( u32, 0) );
u8 const* c = rcast( u8 const*, data);
sw remaining;
u32 result = ~( zpl_cast( u32 ) 0 );
u8 const* c = zpl_cast( u8 const* ) data;
for ( remaining = len; remaining--; c++ )
result = ( result >> 8 ) ^ ( _crc32_table[ ( result ^ *c ) & 0xff ] );
return ~result;
@ -77,11 +77,11 @@ global u64 const _crc64_table[ 256 ] = {
0xa6df411fbfb21ca3ull, 0xdc0731d78f8795daull, 0x536fa08fdfd90e51ull, 0x29b7d047efec8728ull,
};
u64 crc64( void const* data, ssize len )
u64 crc64( void const* data, sw len )
{
ssize remaining;
u64 result = ( scast( u64, 0) );
u8 const* c = rcast( u8 const*, data);
sw remaining;
u64 result = ( zpl_cast( u64 ) 0 );
u8 const* c = zpl_cast( u8 const* ) data;
for ( remaining = len; remaining--; c++ )
result = ( result >> 8 ) ^ ( _crc64_table[ ( result ^ *c ) & 0xff ] );
return result;

View File

@ -5,7 +5,7 @@
#pragma region Hashing
u32 crc32( void const* data, ssize len );
u64 crc64( void const* data, ssize len );
u32 crc32( void const* data, sw len );
u64 crc64( void const* data, sw len );
#pragma endregion Hashing

View File

@ -1,6 +1,4 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
#endif
#pragma once
#pragma region Platform Detection
@ -101,6 +99,9 @@
# define GEN_GCC_VERSION_CHECK(major,minor,patch) (0)
#endif
#define GEN_DEF_INLINE static
#define GEN_IMPL_INLINE static inline
#pragma endregion Platform Detection
#pragma region Mandatory Includes

View File

@ -1,77 +1,58 @@
#ifdef GEN_INTELLISENSE_DIRECTIVES
# pragma once
# include "header_start.hpp"
#endif
#pragma region Macros
#ifndef global
#define global static // Global variables
#endif
#ifndef internal
#define internal static // Internal linkage
#endif
#ifndef local_persist
#define local_persist static // Local Persisting variables
#endif
#define zpl_cast( Type ) ( Type )
#ifndef api_c
#define api_c extern "C"
// Keywords
#define global static // Global variables
#define internal static // Internal linkage
#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
#else
# define forceinline
# define neverinline
#endif
#pragma endregion ForceInline Definition
// Bits
#ifndef bit
#define bit( Value ) ( 1 << Value )
#define bitfield_is_equal( Type, Field, Mask ) ( (Type(Mask) & Type(Field)) == Type(Mask) )
#endif
// Casting
#ifndef ccast
#define ccast( type, value ) ( const_cast< type >( (value) ) )
#endif
#ifndef pcast
#define pcast( type, value ) ( * reinterpret_cast< type* >( & ( value ) ) )
#endif
#ifndef rcast
#define rcast( type, value ) reinterpret_cast< type >( value )
#endif
#ifndef scast
#define scast( type, value ) static_cast< type >( value )
#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 )
#endif
#ifndef stringize
#define stringize_va( ... ) #__VA_ARGS__
#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
// Num Arguments (Varadics)
// #if defined(__GNUC__) || defined(__clang__)
// Supports 0-50 arguments
#define num_args_impl( _0, \
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
@ -86,7 +67,7 @@
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(...) \
num_args_impl(_, ## __VA_ARGS__, \
100, 99, 98, 97, 96, 95, 94, 93, 92, 91, \
@ -101,69 +82,93 @@
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, \
0 \
)
#endif
#ifndef clamp
// #else
// 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 ) )
#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 count_of( x ) ( ( size_of( x ) / size_of( 0 [ x ] ) ) / ( ( sw )( ! ( size_of( x ) % size_of( 0 [ x ] ) ) ) ) )
#define is_between( x, lower, upper ) ( ( ( lower ) <= ( x ) ) && ( ( x ) <= ( upper ) ) )
#endif
#ifndef size_of
#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
#define max( a, b ) ( ( a ) > ( b ) ? ( a ) : ( b ) )
#define min( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) )
#define size_of( x ) ( sw )( sizeof( x ) )
#if defined( _MSC_VER ) || defined( GEN_COMPILER_TINYC )
# define offset_of( Type, element ) ( ( GEN_NS( ssize ) ) & ( ( ( Type* )0 )->element ) )
# define offset_of( Type, element ) ( ( GEN_NS( gen_sw ) ) & ( ( ( Type* )0 )->element ) )
#else
# define offset_of( Type, element ) __builtin_offsetof( Type, element )
#endif
#ifndef forceinline
# ifdef GEN_COMPILER_MSVC
# define forceinline __forceinline
# define neverinline __declspec( noinline )
# elif defined(GEN_COMPILER_GCC)
# define forceinline inline __attribute__((__always_inline__))
# define neverinline __attribute__( ( __noinline__ ) )
# elif defined(GEN_COMPILER_CLANG)
# if __has_attribute(__always_inline__)
# define forceinline inline __attribute__((__always_inline__))
# define neverinline __attribute__( ( __noinline__ ) )
# else
# define forceinline
# define neverinline
# endif
# else
# define forceinline
# define neverinline
# endif
#endif
#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
template< class Type >
void swap( Type& a, Type& b )
{
Type tmp = a;
a = b;
b = tmp;
}
#pragma endregion Macros

View File

@ -5,7 +5,7 @@
#pragma region Memory
void* mem_copy( void* dest, void const* source, ssize n )
void* mem_copy( void* dest, void const* source, sw n )
{
if ( dest == NULL )
{
@ -15,25 +15,25 @@ void* mem_copy( void* dest, void const* source, ssize n )
return memcpy( dest, source, n );
}
void const* mem_find( void const* data, u8 c, ssize n )
void const* mem_find( void const* data, u8 c, sw n )
{
u8 const* s = rcast( u8 const*, data);
while ( ( rcast( uptr, s) & ( sizeof( usize ) - 1 ) ) && n && *s != c )
u8 const* s = zpl_cast( u8 const* ) data;
while ( ( zpl_cast( uptr ) s & ( sizeof( uw ) - 1 ) ) && n && *s != c )
{
s++;
n--;
}
if ( n && *s != c )
{
ssize const* w;
ssize k = GEN__ONES * c;
w = rcast( ssize const*, s);
while ( n >= size_of( ssize ) && ! GEN__HAS_ZERO( *w ^ k ) )
sw const* w;
sw k = GEN__ONES * c;
w = zpl_cast( sw const* ) s;
while ( n >= size_of( sw ) && ! GEN__HAS_ZERO( *w ^ k ) )
{
w++;
n -= size_of( ssize );
n -= size_of( sw );
}
s = rcast( u8 const*, w);
s = zpl_cast( u8 const* ) w;
while ( n && *s != c )
{
s++;
@ -41,7 +41,7 @@ void const* mem_find( void const* data, u8 c, ssize n )
}
}
return n ? rcast( void const*, s ) : NULL;
return n ? zpl_cast( void const* ) s : NULL;
}
#define GEN_HEAP_STATS_MAGIC 0xDEADC0DE
@ -49,8 +49,8 @@ void const* mem_find( void const* data, u8 c, ssize n )
struct _heap_stats
{
u32 magic;
ssize used_memory;
ssize alloc_count;
sw used_memory;
sw alloc_count;
};
global _heap_stats _heap_stats_info;
@ -61,13 +61,13 @@ void heap_stats_init( void )
_heap_stats_info.magic = GEN_HEAP_STATS_MAGIC;
}
ssize heap_stats_used_memory( void )
sw 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!" );
return _heap_stats_info.used_memory;
}
ssize heap_stats_alloc_count( void )
sw 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!" );
return _heap_stats_info.alloc_count;
@ -82,11 +82,11 @@ void heap_stats_check( void )
struct _heap_alloc_info
{
ssize size;
sw size;
void* physical_start;
};
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
{
void* ptr = NULL;
// unused( allocator_data );
@ -95,16 +95,16 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssi
alignment = GEN_DEFAULT_MEMORY_ALIGNMENT;
#ifdef GEN_HEAP_ANALYSIS
ssize alloc_info_size = size_of( _heap_alloc_info );
ssize alloc_info_remainder = ( alloc_info_size % alignment );
ssize track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
sw alloc_info_size = size_of( _heap_alloc_info );
sw alloc_info_remainder = ( alloc_info_size % alignment );
sw track_size = max( alloc_info_size, alignment ) + alloc_info_remainder;
switch ( type )
{
case EAllocation_FREE :
{
if ( ! old_memory )
break;
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, old_memory) - 1;
_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* ) old_memory - 1;
_heap_stats_info.used_memory -= alloc_info->size;
_heap_stats_info.alloc_count--;
old_memory = alloc_info->physical_start;
@ -195,11 +195,11 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssi
#ifdef GEN_HEAP_ANALYSIS
if ( type == EAllocation_ALLOC )
{
_heap_alloc_info* alloc_info = rcast( _heap_alloc_info*, rcast( char*, ptr) + alloc_info_remainder );
_heap_alloc_info* alloc_info = zpl_cast( _heap_alloc_info* )( zpl_cast( char* ) ptr + alloc_info_remainder );
zero_item( alloc_info );
alloc_info->size = size - track_size;
alloc_info->physical_start = ptr;
ptr = rcast( void*, alloc_info + 1 );
ptr = zpl_cast( void* )( alloc_info + 1 );
_heap_stats_info.used_memory += alloc_info->size;
_heap_stats_info.alloc_count++;
}
@ -209,7 +209,7 @@ void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssi
}
#pragma region VirtualMemory
VirtualMemory vm_from_memory( void* data, ssize size )
VirtualMemory vm_from_memory( void* data, sw size )
{
VirtualMemory vm;
vm.data = data;
@ -218,7 +218,7 @@ VirtualMemory vm_from_memory( void* data, ssize size )
}
#if defined( GEN_SYSTEM_WINDOWS )
VirtualMemory vm_alloc( void* addr, ssize size )
VirtualMemory vm_alloc( void* addr, sw size )
{
VirtualMemory vm;
GEN_ASSERT( size > 0 );
@ -234,7 +234,7 @@ b32 vm_free( VirtualMemory vm )
{
if ( VirtualQuery( vm.data, &info, size_of( info ) ) == 0 )
return false;
if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > scast( usize, vm.size) )
if ( info.BaseAddress != vm.data || info.AllocationBase != vm.data || info.State != MEM_COMMIT || info.RegionSize > zpl_cast( uw ) vm.size )
{
return false;
}
@ -246,7 +246,7 @@ b32 vm_free( VirtualMemory vm )
return true;
}
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
{
VirtualMemory new_vm = { 0 };
void* ptr;
@ -270,7 +270,7 @@ b32 vm_purge( VirtualMemory vm )
return true;
}
ssize virtual_memory_page_size( ssize* alignment_out )
sw virtual_memory_page_size( sw* alignment_out )
{
SYSTEM_INFO info;
GetSystemInfo( &info );
@ -285,7 +285,7 @@ ssize virtual_memory_page_size( ssize* alignment_out )
# ifndef MAP_ANONYMOUS
# define MAP_ANONYMOUS MAP_ANON
# endif
VirtualMemory vm_alloc( void* addr, ssize size )
VirtualMemory vm_alloc( void* addr, sw size )
{
VirtualMemory vm;
GEN_ASSERT( size > 0 );
@ -300,10 +300,10 @@ b32 vm_free( VirtualMemory vm )
return true;
}
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size )
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size )
{
void* ptr;
ssize trail_size;
sw trail_size;
GEN_ASSERT( vm.size >= lead_size + size );
ptr = pointer_add( vm.data, lead_size );
@ -322,10 +322,10 @@ b32 vm_purge( VirtualMemory vm )
return err != 0;
}
ssize virtual_memory_page_size( ssize* alignment_out )
sw virtual_memory_page_size( sw* alignment_out )
{
// TODO: Is this always true?
ssize result = scast( ssize, sysconf( _SC_PAGE_SIZE ));
sw result = zpl_cast( sw ) sysconf( _SC_PAGE_SIZE );
if ( alignment_out )
*alignment_out = result;
return result;
@ -334,7 +334,7 @@ ssize virtual_memory_page_size( ssize* alignment_out )
#pragma endregion VirtualMemory
void* Arena::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
void* Arena::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
{
Arena* arena = rcast(Arena*, allocator_data);
void* ptr = NULL;
@ -346,10 +346,10 @@ void* Arena::allocator_proc( void* allocator_data, AllocType type, ssize size, s
case EAllocation_ALLOC :
{
void* end = pointer_add( arena->PhysicalStart, arena->TotalUsed );
ssize total_size = align_forward_i64( size, alignment );
sw total_size = align_forward_i64( size, alignment );
// NOTE: Out of memory
if ( arena->TotalUsed + total_size > (ssize) arena->TotalSize )
if ( arena->TotalUsed + total_size > (sw) arena->TotalSize )
{
// zpl__printf_err("%s", "Arena out of memory\n");
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, ssize size, s
return ptr;
}
void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags )
void* Pool::allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags )
{
Pool* pool = rcast( Pool*, allocator_data);
Pool* pool = zpl_cast( Pool* ) allocator_data;
void* ptr = NULL;
// unused( old_size );
@ -401,9 +401,9 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ss
GEN_ASSERT( alignment == pool->BlockAlign );
GEN_ASSERT( pool->FreeList != NULL );
next_free = * rcast( uptr*, pool->FreeList);
next_free = *zpl_cast( uptr* ) pool->FreeList;
ptr = pool->FreeList;
pool->FreeList = rcast( void*, next_free);
pool->FreeList = zpl_cast( void* ) next_free;
pool->TotalSize += pool->BlockSize;
if ( flags & ALLOCATOR_FLAG_CLEAR_TO_ZERO )
@ -417,8 +417,8 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ss
if ( old_memory == NULL )
return NULL;
next = rcast( uptr*, old_memory);
*next = rcast( uptr, pool->FreeList);
next = zpl_cast( uptr* ) old_memory;
*next = zpl_cast( uptr ) pool->FreeList;
pool->FreeList = old_memory;
pool->TotalSize -= pool->BlockSize;
}
@ -426,7 +426,7 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ss
case EAllocation_FREE_ALL :
{
ssize actual_block_size, block_index;
sw actual_block_size, block_index;
void* curr;
uptr* end;
@ -437,13 +437,13 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ss
curr = pool->PhysicalStart;
for ( block_index = 0; block_index < pool->NumBlocks - 1; block_index++ )
{
uptr* next = rcast( uptr*, curr);
* next = rcast( uptr, curr) + actual_block_size;
uptr* next = zpl_cast( uptr* ) curr;
*next = zpl_cast( uptr ) curr + actual_block_size;
curr = pointer_add( curr, actual_block_size );
}
end = rcast( uptr*, curr);
* end = scast( uptr, NULL);
end = zpl_cast( uptr* ) curr;
*end = zpl_cast( uptr ) NULL;
pool->FreeList = pool->PhysicalStart;
}
break;
@ -457,11 +457,11 @@ void* Pool::allocator_proc( void* allocator_data, AllocType type, ssize size, ss
return ptr;
}
Pool Pool::init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align )
Pool Pool::init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align )
{
Pool pool = {};
ssize actual_block_size, pool_size, block_index;
sw actual_block_size, pool_size, block_index;
void *data, *curr;
uptr* end;
@ -497,7 +497,7 @@ Pool Pool::init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size
void Pool::clear()
{
ssize actual_block_size, block_index;
sw actual_block_size, block_index;
void* curr;
uptr* end;

View File

@ -10,51 +10,43 @@
#define gigabytes( x ) ( megabytes( x ) * ( s64 )( 1024 ) )
#define terabytes( x ) ( gigabytes( x ) * ( s64 )( 1024 ) )
#define GEN__ONES ( scast( GEN_NS usize, - 1) / GEN_U8_MAX )
#define GEN__ONES ( zpl_cast( uw ) - 1 / GEN_U8_MAX )
#define GEN__HIGHS ( GEN__ONES * ( GEN_U8_MAX / 2 + 1 ) )
#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;
}
#define GEN__HAS_ZERO( x ) ( ( ( x )-GEN__ONES ) & ~( x )&GEN__HIGHS )
//! Checks if value is power of 2.
b32 is_power_of_two( ssize x );
GEN_DEF_INLINE b32 is_power_of_two( sw x );
//! Aligns address to specified alignment.
void* align_forward( void* ptr, ssize alignment );
GEN_DEF_INLINE void* align_forward( void* ptr, sw alignment );
//! Aligns value to a specified alignment.
s64 align_forward_i64( s64 value, ssize alignment );
GEN_DEF_INLINE s64 align_forward_i64( s64 value, sw alignment );
//! Moves pointer forward by bytes.
void* pointer_add( void* ptr, ssize bytes );
GEN_DEF_INLINE void* pointer_add( void* ptr, sw bytes );
//! Moves pointer forward by bytes.
void const* pointer_add_const( void const* ptr, ssize bytes );
GEN_DEF_INLINE void const* pointer_add_const( void const* ptr, sw bytes );
//! Calculates difference between two addresses.
ssize pointer_diff( void const* begin, void const* end );
GEN_DEF_INLINE sw pointer_diff( void const* begin, void const* end );
//! Copy non-overlapping memory from source to destination.
void* mem_copy( void* dest, void const* source, ssize size );
void* mem_copy( void* dest, void const* source, sw size );
//! Search for a constant value within the size limit at memory location.
void const* mem_find( void const* data, u8 byte_value, ssize size );
void const* mem_find( void const* data, u8 byte_value, sw size );
//! Copy memory from source to destination.
void* mem_move( void* dest, void const* source, ssize size );
GEN_DEF_INLINE void* mem_move( void* dest, void const* source, sw size );
//! Set constant value at memory location with specified size.
void* mem_set( void* data, u8 byte_value, ssize size );
GEN_DEF_INLINE void* mem_set( void* data, u8 byte_value, sw size );
//! @param ptr Memory location to clear up.
//! @param size The size to clear up with.
void zero_size( void* ptr, ssize size );
GEN_DEF_INLINE void zero_size( void* ptr, sw size );
//! Clears up an item.
#define zero_item( t ) zero_size( ( t ), size_of( *( t ) ) ) // NOTE: Pass pointer of struct
@ -71,8 +63,8 @@ enum AllocType : u8
};
using AllocatorProc = void* ( void* allocator_data, AllocType type
, ssize size, ssize alignment
, void* old_memory, ssize old_size
, sw size, sw alignment
, void* old_memory, sw old_size
, u64 flags );
struct AllocatorInfo
@ -95,22 +87,22 @@ enum AllocFlag
#endif
//! Allocate memory with default alignment.
void* alloc( AllocatorInfo a, ssize size );
GEN_DEF_INLINE void* alloc( AllocatorInfo a, sw size );
//! Allocate memory with specified alignment.
void* alloc_align( AllocatorInfo a, ssize size, ssize alignment );
GEN_DEF_INLINE void* alloc_align( AllocatorInfo a, sw size, sw alignment );
//! Free allocated memory.
void free( AllocatorInfo a, void* ptr );
GEN_DEF_INLINE void free( AllocatorInfo a, void* ptr );
//! Free all memory allocated by an allocator.
void free_all( AllocatorInfo a );
GEN_DEF_INLINE void free_all( AllocatorInfo a );
//! Resize an allocated memory.
void* resize( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size );
GEN_DEF_INLINE void* resize( AllocatorInfo a, void* ptr, sw old_size, sw new_size );
//! Resize an allocated memory with specified alignment.
void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
GEN_DEF_INLINE void* resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment );
//! Allocate memory for an item.
#define alloc_item( allocator_, Type ) ( Type* )alloc( allocator_, size_of( Type ) )
@ -123,16 +115,16 @@ void* resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size,
/* 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 */
void heap_stats_init( void );
ssize heap_stats_used_memory( void );
ssize heap_stats_alloc_count( void );
sw heap_stats_used_memory( void );
sw heap_stats_alloc_count( void );
void heap_stats_check( void );
//! Allocate/Resize memory using default options.
//! Use this if you don't need a "fancy" resize allocation
void* default_resize_align( AllocatorInfo a, void* ptr, ssize old_size, ssize new_size, ssize alignment );
GEN_DEF_INLINE void* default_resize_align( AllocatorInfo a, void* ptr, sw old_size, sw new_size, sw alignment );
void* heap_allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
void* heap_allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
//! The heap allocator backed by operating system's memory manager.
constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr }; }
@ -143,40 +135,270 @@ constexpr AllocatorInfo heap( void ) { return { heap_allocator_proc, nullptr };
//! Helper to free memory allocated by heap allocator.
#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
{
void* data;
ssize size;
sw size;
};
//! Initialize virtual memory from existing data.
VirtualMemory vm_from_memory( void* data, ssize size );
VirtualMemory vm_from_memory( void* data, sw 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 size The size to serve.
VirtualMemory vm_alloc( void* addr, ssize size );
VirtualMemory vm_alloc( void* addr, sw size );
//! Release the virtual memory.
b32 vm_free( VirtualMemory vm );
//! Trim virtual memory.
VirtualMemory vm_trim( VirtualMemory vm, ssize lead_size, ssize size );
VirtualMemory vm_trim( VirtualMemory vm, sw lead_size, sw size );
//! Purge virtual memory.
b32 gen_vm_purge( VirtualMemory vm );
//! Retrieve VM's page size and alignment.
ssize gen_virtual_memory_page_size( ssize* alignment_out );
sw gen_virtual_memory_page_size( sw* alignment_out );
struct Arena
{
static
void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
static
Arena init_from_memory( void* start, ssize size )
Arena init_from_memory( void* start, sw size )
{
return
{
@ -189,7 +411,7 @@ struct Arena
}
static
Arena init_from_allocator( AllocatorInfo backing, ssize size )
Arena init_from_allocator( AllocatorInfo backing, sw size )
{
Arena result =
{
@ -203,18 +425,18 @@ struct Arena
}
static
Arena init_sub( Arena& parent, ssize size )
Arena init_sub( Arena& parent, sw size )
{
return init_from_allocator( parent.Backing, size );
}
ssize alignment_of( ssize alignment )
sw alignment_of( sw alignment )
{
ssize alignment_offset, result_pointer, mask;
sw alignment_offset, result_pointer, mask;
GEN_ASSERT( is_power_of_two( alignment ) );
alignment_offset = 0;
result_pointer = (ssize) PhysicalStart + TotalUsed;
result_pointer = (sw) PhysicalStart + TotalUsed;
mask = alignment - 1;
if ( result_pointer & mask )
@ -241,17 +463,17 @@ struct Arena
}
}
ssize size_remaining( ssize alignment )
sw size_remaining( sw alignment )
{
ssize result = TotalSize - ( TotalUsed + alignment_of( alignment ) );
sw result = TotalSize - ( TotalUsed + alignment_of( alignment ) );
return result;
}
AllocatorInfo Backing;
void* PhysicalStart;
ssize TotalSize;
ssize TotalUsed;
ssize TempCount;
sw TotalSize;
sw TotalUsed;
sw TempCount;
operator AllocatorInfo()
{
@ -271,7 +493,7 @@ struct FixedArena
return result;
}
ssize size_remaining( ssize alignment )
sw size_remaining( sw alignment )
{
return arena.size_remaining( alignment );
}
@ -301,16 +523,16 @@ using Arena_4MB = FixedArena< megabytes( 4 ) >;
struct Pool
{
static
void* allocator_proc( void* allocator_data, AllocType type, ssize size, ssize alignment, void* old_memory, ssize old_size, u64 flags );
void* allocator_proc( void* allocator_data, AllocType type, sw size, sw alignment, void* old_memory, sw old_size, u64 flags );
static
Pool init( AllocatorInfo backing, ssize num_blocks, ssize block_size )
Pool init( AllocatorInfo backing, sw num_blocks, sw block_size )
{
return init_align( backing, num_blocks, block_size, GEN_DEFAULT_MEMORY_ALIGNMENT );
}
static
Pool init_align( AllocatorInfo backing, ssize num_blocks, ssize block_size, ssize block_align );
Pool init_align( AllocatorInfo backing, sw num_blocks, sw block_size, sw block_align );
void clear();
@ -325,10 +547,10 @@ struct Pool
AllocatorInfo Backing;
void* PhysicalStart;
void* FreeList;
ssize BlockSize;
ssize BlockAlign;
ssize TotalSize;
ssize NumBlocks;
sw BlockSize;
sw BlockAlign;
sw TotalSize;
sw NumBlocks;
operator AllocatorInfo()
{
@ -336,236 +558,4 @@ 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

View File

@ -36,7 +36,7 @@ u8 adt_destroy_branch( ADT_Node* node )
GEN_ASSERT_NOT_NULL( node );
if ( ( node->type == EADT_TYPE_OBJECT || node->type == EADT_TYPE_ARRAY ) && node->nodes )
{
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); ++i )
for ( sw i = 0; i < scast(sw, node->nodes.num()); ++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;
}
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
{
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 )
{
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
{
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 );
adt_print_number( &tmp, node );
ssize fsize = 0;
sw fsize = 0;
u8* buf = file_stream_buf( &tmp, &fsize );
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 )
{
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
{
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 */
else if ( node->type == EADT_TYPE_ARRAY )
{
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
{
ADT_Node* child = &node->nodes[ i ];
if ( child->type != EADT_TYPE_OBJECT )
@ -225,7 +225,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
/* [value] */
else
{
for ( ssize i = 0; i < scast(ssize, node->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, node->nodes.num()); i++ )
{
ADT_Node* child = &node->nodes[ i ];
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 */
else
{
ssize idx = ( ssize )str_to_i64( buf, NULL, 10 );
if ( idx >= 0 && idx < scast(ssize, node->nodes.num()) )
sw idx = ( sw )str_to_i64( buf, NULL, 10 );
if ( idx >= 0 && idx < scast(sw, node->nodes.num()) )
{
found_node = &node->nodes[ idx ];
@ -272,7 +272,7 @@ ADT_Node* adt_query( ADT_Node* node, char const* uri )
return found_node;
}
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index )
{
if ( ! parent || ( parent->type != EADT_TYPE_OBJECT && parent->type != EADT_TYPE_ARRAY ) )
{
@ -282,7 +282,7 @@ ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index )
if ( ! parent->nodes )
return NULL;
if ( index < 0 || index > scast(ssize, parent->nodes.num()) )
if ( index < 0 || index > scast(sw, parent->nodes.num()) )
return NULL;
ADT_Node o = { 0 };
@ -337,7 +337,7 @@ b8 adt_set_int( ADT_Node* obj, char const* name, s64 value )
return true;
}
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index )
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index )
{
GEN_ASSERT_NOT_NULL( node );
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 );
ADT_Node* parent = node->parent;
ADT_Node* other_parent = other_node->parent;
ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
ssize index2 = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
sw index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
sw index2 = ( pointer_diff( other_parent->nodes, other_node ) / size_of( ADT_Node ) );
ADT_Node temp = parent->nodes[ index ];
temp.parent = other_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->parent );
ADT_Node* parent = node->parent;
ssize index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
sw index = ( pointer_diff( parent->nodes, node ) / size_of( ADT_Node ) );
parent->nodes.remove_at( index );
}
@ -484,7 +484,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
node_type = EADT_TYPE_INTEGER;
neg_zero = false;
ssize ib = 0;
sw ib = 0;
char buf[ 48 ] = { 0 };
if ( *e == '+' )
@ -550,7 +550,7 @@ char* adt_parse_number( ADT_Node* node, char* base_str )
f32 eb = 10;
char expbuf[ 6 ] = { 0 };
ssize expi = 0;
sw expi = 0;
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
char *q = buf, *base_string = q, *base_string2 = q;
base_string = ccast( char*, str_skip( base_string, '.' ));
base_string = zpl_cast( char* ) str_skip( base_string, '.' );
*base_string = '\0';
base_string2 = base_string + 1;
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* endChar;
ssize columnIndex = 0;
ssize totalColumnIndex = 0;
sw columnIndex = 0;
sw totalColumnIndex = 0;
do
{
char delimiter = 0;
currentChar = ccast( char*, str_trim( currentChar, false ));
currentChar = zpl_cast( char* ) str_trim( currentChar, false );
if ( *currentChar == 0 )
break;
@ -846,7 +846,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
#endif
do
{
endChar = ccast( char*, str_skip( endChar, '"' ));
endChar = zpl_cast( char* ) str_skip( endChar, '"' );
if ( *endChar && *( endChar + 1 ) == '"' )
{
@ -865,7 +865,7 @@ u8 csv_parse_delimiter( CSV_Object* root, char* text, AllocatorInfo allocator, b
}
*endChar = 0;
currentChar = ccast( char*, str_trim( endChar + 1, true ));
currentChar = zpl_cast( char* ) str_trim( endChar + 1, true );
delimiter = * currentChar;
/* 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 )
{
currentChar = ccast( char*, str_trim( endChar, true ));
currentChar = zpl_cast( char* ) str_trim( endChar, true );
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(ssize, root->nodes.num()) )
if ( columnIndex >= scast(sw, root->nodes.num()) )
{
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. */
if ( has_header )
{
for ( ssize i = 0; i < scast(ssize, root->nodes.num()); i++ )
for ( sw i = 0; i < scast(sw, root->nodes.num()); i++ )
{
CSV_Object* col = root->nodes + i;
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( obj );
GEN_ASSERT( obj->nodes );
ssize cols = obj->nodes.num();
sw cols = obj->nodes.num();
if ( cols == 0 )
return;
ssize rows = obj->nodes[ 0 ].nodes.num();
sw rows = obj->nodes[ 0 ].nodes.num();
if ( rows == 0 )
return;
@ -1069,7 +1069,7 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
if ( has_headers )
{
for ( ssize i = 0; i < cols; i++ )
for ( sw i = 0; i < cols; i++ )
{
_csv_write_header( file, &obj->nodes[ i ] );
if ( i + 1 != cols )
@ -1080,9 +1080,9 @@ void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delimiter )
str_fmt_file( file, "\n" );
}
for ( ssize r = 0; r < rows; r++ )
for ( sw r = 0; r < rows; r++ )
{
for ( ssize i = 0; i < cols; i++ )
for ( sw i = 0; i < cols; i++ )
{
_csv_write_record( file, &obj->nodes[ i ].nodes[ r ] );
if ( i + 1 != cols )
@ -1099,8 +1099,7 @@ String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delimi
FileInfo tmp;
file_stream_new( &tmp, a );
csv_write_delimiter( &tmp, obj, delimiter );
ssize fsize;
sw fsize;
u8* buf = file_stream_buf( &tmp, &fsize );
String output = String::make_length( a, ( char* )buf, fsize );
file_close( &tmp );

View File

@ -178,7 +178,7 @@ ADT_Node* adt_find( ADT_Node* node, char const* name, b32 deep_search );
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_alloc_at( ADT_Node* parent, ssize index );
ADT_Node* adt_alloc_at( ADT_Node* parent, sw index );
/**
* @brief Allocate an unitialised node within a container.
@ -196,7 +196,7 @@ ADT_Node* adt_alloc( ADT_Node* parent );
* @param index
* @return zpl_adt_node * node
*/
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, ssize index );
ADT_Node* adt_move_node_at( ADT_Node* node, ADT_Node* new_parent, sw index );
/**
* @brief Move an existing node to a new container.
@ -400,33 +400,31 @@ enum CSV_Error : u32
typedef ADT_Node CSV_Object;
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header );
GEN_DEF_INLINE 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 );
void csv_free( CSV_Object* obj );
void csv_write( FileInfo* file, CSV_Object* obj );
String csv_write_string( AllocatorInfo a, CSV_Object* obj );
GEN_DEF_INLINE void csv_write( FileInfo* file, CSV_Object* obj );
GEN_DEF_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj );
void csv_write_delimiter( FileInfo* file, CSV_Object* obj, char delim );
String csv_write_string_delimiter( AllocatorInfo a, CSV_Object* obj, char delim );
/* inline */
inline
u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
GEN_IMPL_INLINE u8 csv_parse( CSV_Object* root, char* text, AllocatorInfo allocator, b32 has_header )
{
return csv_parse_delimiter( root, text, allocator, has_header, ',' );
}
inline
void csv_write( FileInfo* file, CSV_Object* obj )
GEN_IMPL_INLINE void csv_write( FileInfo* file, CSV_Object* obj )
{
csv_write_delimiter( file, obj, ',' );
}
inline
String csv_write_string( AllocatorInfo a, CSV_Object* obj )
GEN_IMPL_INLINE String csv_write_string( AllocatorInfo a, CSV_Object* obj )
{
return csv_write_string_delimiter( a, obj, ',' );
}
#pragma endregion CSV

View File

@ -41,10 +41,10 @@ struct _format_info
s32 precision;
};
internal ssize _print_string( char* text, ssize max_len, _format_info* info, char const* str )
internal sw _print_string( char* text, sw max_len, _format_info* info, char const* str )
{
ssize res = 0, len = 0;
ssize remaining = max_len;
sw res = 0, len = 0;
sw remaining = max_len;
char* begin = text;
if ( str == NULL && max_len >= 6 )
@ -75,7 +75,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
if ( info->width > res )
{
ssize padding = info->width - len;
sw padding = info->width - len;
char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
while ( padding-- > 0 && remaining-- > 0 )
@ -86,7 +86,7 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
{
if ( info && ( info->width > res ) )
{
ssize padding = info->width - len;
sw padding = info->width - len;
char pad = ( info->flags & GEN_FMT_ZERO ) ? '0' : ' ';
while ( padding-- > 0 && remaining-- > 0 )
*text++ = pad, res++;
@ -108,16 +108,16 @@ internal ssize _print_string( char* text, ssize max_len, _format_info* info, cha
return res;
}
internal ssize _print_char( char* text, ssize max_len, _format_info* info, char arg )
internal sw _print_char( char* text, sw max_len, _format_info* info, char arg )
{
char str[ 2 ] = "";
str[ 0 ] = arg;
return _print_string( text, max_len, info, str );
}
internal ssize _print_repeated_char( char* text, ssize max_len, _format_info* info, char arg )
internal sw _print_repeated_char( char* text, sw max_len, _format_info* info, char arg )
{
ssize res = 0;
sw res = 0;
s32 rem = ( info ) ? ( info->width > 0 ) ? info->width : 1 : 1;
res = rem;
while ( rem-- > 0 )
@ -126,24 +126,24 @@ internal ssize _print_repeated_char( char* text, ssize max_len, _format_info* in
return res;
}
internal ssize _print_i64( char* text, ssize max_len, _format_info* info, s64 value )
internal sw _print_i64( char* text, sw max_len, _format_info* info, s64 value )
{
char num[ 130 ];
i64_to_str( value, num, info ? info->base : 10 );
return _print_string( text, max_len, info, num );
}
internal ssize _print_u64( char* text, ssize max_len, _format_info* info, u64 value )
internal sw _print_u64( char* text, sw max_len, _format_info* info, u64 value )
{
char num[ 130 ];
u64_to_str( value, num, info ? info->base : 10 );
return _print_string( text, max_len, info, num );
}
internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
internal sw _print_f64( char* text, sw max_len, _format_info* info, b32 is_hexadecimal, f64 arg )
{
// TODO: Handle exponent notation
ssize width, len, remaining = max_len;
sw width, len, remaining = max_len;
char* text_begin = text;
if ( arg )
@ -163,7 +163,7 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is
text++;
}
value = scast( u64, arg);
value = zpl_cast( u64 ) arg;
len = _print_u64( text, remaining, NULL, value );
text += len;
@ -184,14 +184,14 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is
text++;
while ( info->precision-- > 0 )
{
value = scast( u64, arg * mult );
value = zpl_cast( u64 )( arg * mult );
len = _print_u64( text, remaining, NULL, value );
text += len;
if ( len >= remaining )
remaining = min( remaining, 1 );
else
remaining -= len;
arg -= scast( f64, value / mult);
arg -= zpl_cast( f64 ) value / mult;
mult *= 10;
}
}
@ -239,15 +239,15 @@ internal ssize _print_f64( char* text, ssize max_len, _format_info* info, b32 is
return ( text - text_begin );
}
neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_list va )
neverinline sw str_fmt_va( char* text, sw max_len, char const* fmt, va_list va )
{
char const* text_begin = text;
ssize remaining = max_len, res;
sw remaining = max_len, res;
while ( *fmt )
{
_format_info info = { 0 };
ssize len = 0;
sw len = 0;
info.precision = -1;
while ( *fmt && *fmt != '%' && remaining )
@ -311,7 +311,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
}
else
{
info.width = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
info.width = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
if ( info.width != 0 )
{
info.flags |= GEN_FMT_WIDTH;
@ -329,7 +329,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
}
else
{
info.precision = scast( s32, str_to_i64( fmt, ccast( char**, & fmt), 10 ));
info.precision = zpl_cast( s32 ) str_to_i64( fmt, zpl_cast( char** ) & fmt, 10 );
}
info.flags &= ~GEN_FMT_ZERO;
}
@ -411,7 +411,7 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
break;
case 'c' :
len = _print_char( text, remaining, &info, scast( char, va_arg( va, int ) ));
len = _print_char( text, remaining, &info, zpl_cast( char ) va_arg( va, int ) );
break;
case 's' :
@ -455,25 +455,25 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
switch ( info.flags & GEN_FMT_INTS )
{
case GEN_FMT_CHAR :
value = scast( u64, scast( u8, va_arg( va, int )));
value = zpl_cast( u64 ) zpl_cast( u8 ) va_arg( va, int );
break;
case GEN_FMT_SHORT :
value = scast( u64, scast( u16, va_arg( va, int )));
value = zpl_cast( u64 ) zpl_cast( u16 ) va_arg( va, int );
break;
case GEN_FMT_LONG:
value = scast( u64, va_arg( va, unsigned long ));
case GEN_FMT_LONG :
value = zpl_cast( u64 ) va_arg( va, unsigned long );
break;
case GEN_FMT_LLONG :
value = scast( u64, va_arg( va, unsigned long long ));
value = zpl_cast( u64 ) va_arg( va, unsigned long long );
break;
case GEN_FMT_SIZE :
value = scast( u64, va_arg( va, usize ));
value = zpl_cast( u64 ) va_arg( va, uw );
break;
case GEN_FMT_INTPTR :
value = scast( u64, va_arg( va, uptr ));
value = zpl_cast( u64 ) va_arg( va, uptr );
break;
default :
value = scast( u64, va_arg( va, unsigned int ));
value = zpl_cast( u64 ) va_arg( va, unsigned int );
break;
}
@ -485,25 +485,25 @@ neverinline ssize str_fmt_va( char* text, ssize max_len, char const* fmt, va_lis
switch ( info.flags & GEN_FMT_INTS )
{
case GEN_FMT_CHAR :
value = scast( s64, scast( s8, va_arg( va, int )));
value = zpl_cast( s64 ) zpl_cast( s8 ) va_arg( va, int );
break;
case GEN_FMT_SHORT :
value = scast( s64, scast( s16, va_arg( va, int )));
value = zpl_cast( s64 ) zpl_cast( s16 ) va_arg( va, int );
break;
case GEN_FMT_LONG :
value = scast( s64, va_arg( va, long ));
value = zpl_cast( s64 ) va_arg( va, long );
break;
case GEN_FMT_LLONG :
value = scast( s64, va_arg( va, long long ));
value = zpl_cast( s64 ) va_arg( va, long long );
break;
case GEN_FMT_SIZE :
value = scast( s64, va_arg( va, usize ));
value = zpl_cast( s64 ) va_arg( va, uw );
break;
case GEN_FMT_INTPTR :
value = scast( s64, va_arg( va, uptr ));
value = zpl_cast( s64 ) va_arg( va, uptr );
break;
default :
value = scast( s64, va_arg( va, int ));
value = zpl_cast( s64 ) va_arg( va, int );
break;
}
@ -540,17 +540,17 @@ char* str_fmt_buf( char const* fmt, ... )
return str;
}
ssize str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
sw str_fmt_file_va( struct FileInfo* f, char const* fmt, va_list va )
{
local_persist thread_local char buf[ GEN_PRINTF_MAXLEN ];
ssize len = str_fmt_va( buf, size_of( buf ), fmt, va );
sw len = str_fmt_va( buf, size_of( buf ), fmt, va );
b32 res = file_write( f, buf, len - 1 ); // NOTE: prevent extra whitespace
return res ? len : -1;
}
ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... )
sw str_fmt_file( struct FileInfo* f, char const* fmt, ... )
{
ssize res;
sw res;
va_list va;
va_start( va, fmt );
res = str_fmt_file_va( f, fmt, va );
@ -558,9 +558,9 @@ ssize str_fmt_file( struct FileInfo* f, char const* fmt, ... )
return res;
}
ssize str_fmt( char* str, ssize n, char const* fmt, ... )
sw str_fmt( char* str, sw n, char const* fmt, ... )
{
ssize res;
sw res;
va_list va;
va_start( va, fmt );
res = str_fmt_va( str, n, fmt, va );
@ -568,19 +568,19 @@ ssize str_fmt( char* str, ssize n, char const* fmt, ... )
return res;
}
ssize str_fmt_out_va( char const* fmt, va_list va )
sw str_fmt_out_va( char const* fmt, va_list va )
{
return str_fmt_file_va( file_get_standard( EFileStandard_OUTPUT ), fmt, va );
}
ssize str_fmt_out_err_va( char const* fmt, va_list va )
sw str_fmt_out_err_va( char const* fmt, va_list va )
{
return str_fmt_file_va( file_get_standard( EFileStandard_ERROR ), fmt, va );
}
ssize str_fmt_out_err( char const* fmt, ... )
sw str_fmt_out_err( char const* fmt, ... )
{
ssize res;
sw res;
va_list va;
va_start( va, fmt );
res = str_fmt_out_err_va( fmt, va );

View File

@ -14,21 +14,21 @@ struct FileInfo;
// NOTE: A locally persisting buffer is used internally
char* str_fmt_buf ( char const* fmt, ... );
char* str_fmt_buf_va ( char const* fmt, va_list va );
ssize str_fmt ( char* str, ssize n, char const* fmt, ... );
ssize str_fmt_va ( char* str, ssize n, char const* fmt, va_list va );
ssize str_fmt_out_va ( char const* fmt, va_list va );
ssize str_fmt_out_err ( char const* fmt, ... );
ssize str_fmt_out_err_va( char const* fmt, va_list va );
ssize str_fmt_file ( FileInfo* f, char const* fmt, ... );
ssize str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
sw str_fmt ( char* str, sw n, char const* fmt, ... );
sw str_fmt_va ( char* str, sw n, char const* fmt, va_list va );
sw str_fmt_out_va ( char const* fmt, va_list va );
sw str_fmt_out_err ( char const* fmt, ... );
sw str_fmt_out_err_va( char const* fmt, va_list va );
sw str_fmt_file ( FileInfo* f, char const* fmt, ... );
sw str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
inline
ssize log_fmt(char const* fmt, ...)
sw log_fmt(char const* fmt, ...)
{
ssize res;
sw res;
va_list va;
va_start(va, fmt);

View File

@ -7,7 +7,7 @@
#pragma region String Ops
internal
ssize _scan_zpl_i64( const char* text, s32 base, s64* value )
sw _scan_zpl_i64( const char* text, s32 base, s64* value )
{
const char* text_begin = text;
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 )
{
ssize len;
sw len;
s64 value;
if ( ! base )
@ -85,7 +85,7 @@ void i64_to_str( s64 value, char* string, s32 base )
value = -value;
}
v = scast( u64, value);
v = zpl_cast( u64 ) value;
if ( 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 ) );
if ( end_ptr )
* end_ptr = rcast( char*, ccast(char*, str) );
*end_ptr = zpl_cast( char* ) str;
return result;
}

View File

@ -5,42 +5,41 @@
#pragma region String Ops
const char* char_first_occurence( const char* str, char c );
GEN_DEF_INLINE const char* char_first_occurence( const char* str, char c );
constexpr auto str_find = &char_first_occurence;
b32 char_is_alpha( char c );
b32 char_is_alphanumeric( char c );
b32 char_is_digit( char c );
b32 char_is_hex_digit( char c );
b32 char_is_space( char c );
char char_to_lower( char c );
char char_to_upper( char c );
GEN_DEF_INLINE b32 char_is_alpha( char c );
GEN_DEF_INLINE b32 char_is_alphanumeric( char c );
GEN_DEF_INLINE b32 char_is_digit( char c );
GEN_DEF_INLINE b32 char_is_hex_digit( char c );
GEN_DEF_INLINE b32 char_is_space( char c );
GEN_DEF_INLINE char char_to_lower( char c );
GEN_DEF_INLINE char char_to_upper( char c );
s32 digit_to_int( char c );
s32 hex_digit_to_int( char c );
GEN_DEF_INLINE s32 digit_to_int( char c );
GEN_DEF_INLINE s32 hex_digit_to_int( char c );
s32 str_compare( const char* s1, const char* s2 );
s32 str_compare( const char* s1, const char* s2, ssize len );
char* str_copy( char* dest, const char* source, ssize len );
ssize str_copy_nulpad( char* dest, const char* source, ssize len );
ssize str_len( const char* str );
ssize str_len( const char* str, ssize max_len );
char* str_reverse( char* str ); // NOTE: ASCII only
char const* str_skip( char const* str, char c );
char const* str_skip_any( char const* str, char const* char_list );
char const* str_trim( char const* str, b32 catch_newline );
GEN_DEF_INLINE s32 str_compare( const char* s1, const char* s2 );
GEN_DEF_INLINE s32 str_compare( const char* s1, const char* s2, sw len );
GEN_DEF_INLINE char* str_copy( char* dest, const char* source, sw len );
GEN_DEF_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len );
GEN_DEF_INLINE sw str_len( const char* str );
GEN_DEF_INLINE sw str_len( const char* str, sw max_len );
GEN_DEF_INLINE char* str_reverse( char* str ); // NOTE: ASCII only
GEN_DEF_INLINE char const* str_skip( char const* str, char c );
GEN_DEF_INLINE 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 );
// NOTE: ASCII only
void str_to_lower( char* str );
void str_to_upper( char* str );
GEN_DEF_INLINE void str_to_lower( char* str );
GEN_DEF_INLINE void str_to_upper( char* str );
s64 str_to_i64( const char* str, char** end_ptr, s32 base );
void i64_to_str( s64 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 );
inline
const char* char_first_occurence( const char* s, char c )
GEN_IMPL_INLINE const char* char_first_occurence( const char* s, char c )
{
char ch = c;
for ( ; *s != ch; s++ )
@ -51,67 +50,59 @@ const char* char_first_occurence( const char* s, char c )
return s;
}
inline
b32 char_is_alpha( char c )
GEN_IMPL_INLINE b32 char_is_alpha( char c )
{
if ( ( c >= 'A' && c <= 'Z' ) || ( c >= 'a' && c <= 'z' ) )
return true;
return false;
}
inline
b32 char_is_alphanumeric( char c )
GEN_IMPL_INLINE b32 char_is_alphanumeric( char c )
{
return char_is_alpha( c ) || char_is_digit( c );
}
inline
b32 char_is_digit( char c )
GEN_IMPL_INLINE b32 char_is_digit( char c )
{
if ( c >= '0' && c <= '9' )
return true;
return false;
}
inline
b32 char_is_hex_digit( char c )
GEN_IMPL_INLINE b32 char_is_hex_digit( char c )
{
if ( char_is_digit( c ) || ( c >= 'a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) )
return true;
return false;
}
inline
b32 char_is_space( char c )
GEN_IMPL_INLINE b32 char_is_space( char c )
{
if ( c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' )
return true;
return false;
}
inline
char char_to_lower( char c )
GEN_IMPL_INLINE char char_to_lower( char c )
{
if ( c >= 'A' && c <= 'Z' )
return 'a' + ( c - 'A' );
return c;
}
inline char char_to_upper( char c )
GEN_IMPL_INLINE char char_to_upper( char c )
{
if ( c >= 'a' && c <= 'z' )
return 'A' + ( c - 'a' );
return c;
}
inline
s32 digit_to_int( char c )
GEN_IMPL_INLINE s32 digit_to_int( char c )
{
return char_is_digit( c ) ? c - '0' : c - 'W';
}
inline
s32 hex_digit_to_int( char c )
GEN_IMPL_INLINE s32 hex_digit_to_int( char c )
{
if ( char_is_digit( c ) )
return digit_to_int( c );
@ -122,8 +113,7 @@ s32 hex_digit_to_int( char c )
return -1;
}
inline
s32 str_compare( const char* s1, const char* s2 )
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2 )
{
while ( *s1 && ( *s1 == *s2 ) )
{
@ -132,8 +122,7 @@ s32 str_compare( const char* s1, const char* s2 )
return *( u8* )s1 - *( u8* )s2;
}
inline
s32 str_compare( const char* s1, const char* s2, ssize len )
GEN_IMPL_INLINE s32 str_compare( const char* s1, const char* s2, sw len )
{
for ( ; len > 0; s1++, s2++, len-- )
{
@ -145,8 +134,7 @@ s32 str_compare( const char* s1, const char* s2, ssize len )
return 0;
}
inline
char* str_copy( char* dest, const char* source, ssize len )
GEN_IMPL_INLINE char* str_copy( char* dest, const char* source, sw len )
{
GEN_ASSERT_NOT_NULL( dest );
if ( source )
@ -166,10 +154,9 @@ char* str_copy( char* dest, const char* source, ssize len )
return dest;
}
inline
ssize str_copy_nulpad( char* dest, const char* source, ssize len )
GEN_IMPL_INLINE sw str_copy_nulpad( char* dest, const char* source, sw len )
{
ssize result = 0;
sw result = 0;
GEN_ASSERT_NOT_NULL( dest );
if ( source )
{
@ -191,8 +178,7 @@ ssize str_copy_nulpad( char* dest, const char* source, ssize len )
return result;
}
inline
ssize str_len( const char* str )
GEN_IMPL_INLINE sw str_len( const char* str )
{
if ( str == NULL )
{
@ -204,19 +190,17 @@ ssize str_len( const char* str )
return str - p;
}
inline
ssize str_len( const char* str, ssize max_len )
GEN_IMPL_INLINE sw str_len( const char* str, sw max_len )
{
const char* end = rcast(const char*, mem_find( str, 0, max_len ));
const char* end = zpl_cast( const char* ) mem_find( str, 0, max_len );
if ( end )
return end - str;
return max_len;
}
inline
char* str_reverse( char* str )
GEN_IMPL_INLINE char* str_reverse( char* str )
{
ssize len = str_len( str );
sw len = str_len( str );
char* a = str + 0;
char* b = str + len - 1;
len /= 2;
@ -228,8 +212,7 @@ char* str_reverse( char* str )
return str;
}
inline
char const* str_skip( char const* str, char c )
GEN_IMPL_INLINE char const* str_skip( char const* str, char c )
{
while ( *str && *str != c )
{
@ -238,12 +221,11 @@ char const* str_skip( char const* str, char c )
return str;
}
inline
char const* str_skip_any( char const* str, char const* char_list )
GEN_IMPL_INLINE char const* str_skip_any( char const* str, char const* char_list )
{
char const* closest_ptr = rcast( char const*, pointer_add_const( rcast(void const*, str), str_len( str ) ));
ssize char_list_count = str_len( char_list );
for ( ssize i = 0; i < char_list_count; i++ )
char const* closest_ptr = zpl_cast( char const* ) pointer_add( ( void* )str, str_len( str ) );
sw char_list_count = str_len( char_list );
for ( sw i = 0; i < char_list_count; i++ )
{
char const* p = str_skip( str, char_list[ i ] );
closest_ptr = min( closest_ptr, p );
@ -251,8 +233,7 @@ char const* str_skip_any( char const* str, char const* char_list )
return closest_ptr;
}
inline
char const* str_trim( char const* str, b32 catch_newline )
GEN_IMPL_INLINE char const* str_trim( char const* str, b32 catch_newline )
{
while ( *str && char_is_space( *str ) && ( ! catch_newline || ( catch_newline && *str != '\n' ) ) )
{
@ -261,8 +242,7 @@ char const* str_trim( char const* str, b32 catch_newline )
return str;
}
inline
void str_to_lower( char* str )
GEN_IMPL_INLINE void str_to_lower( char* str )
{
if ( ! str )
return;
@ -273,8 +253,7 @@ void str_to_lower( char* str )
}
}
inline
void str_to_upper( char* str )
GEN_IMPL_INLINE void str_to_upper( char* str )
{
if ( ! str )
return;

View File

@ -5,7 +5,7 @@
#pragma region String
String String::fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... )
String String::fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... )
{
va_list va;
va_start( va, fmt );
@ -15,9 +15,9 @@ String String::fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char con
return make( allocator, buf );
}
String String::make_length( AllocatorInfo allocator, char const* str, ssize length )
String String::make_length( AllocatorInfo allocator, char const* str, sw length )
{
constexpr ssize header_size = sizeof( Header );
constexpr sw header_size = sizeof( Header );
s32 alloc_size = header_size + length + 1;
void* allocation = alloc( allocator, alloc_size );
@ -41,9 +41,9 @@ String String::make_length( AllocatorInfo allocator, char const* str, ssize leng
return result;
}
String String::make_reserve( AllocatorInfo allocator, ssize capacity )
String String::make_reserve( AllocatorInfo allocator, sw capacity )
{
constexpr ssize header_size = sizeof( Header );
constexpr sw header_size = sizeof( Header );
s32 alloc_size = header_size + capacity + 1;
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, ... )
{
ssize res;
sw res;
char buf[ GEN_PRINTF_MAXLEN ] = { 0 };
va_list va;
@ -89,9 +89,9 @@ bool String::append_fmt( char const* fmt, ... )
return append( buf, res );
}
bool String::make_space_for( char const* str, ssize add_len )
bool String::make_space_for( char const* str, sw add_len )
{
ssize available = avail_space();
sw available = avail_space();
// NOTE: Return if there is enough space left
if ( available >= add_len )
@ -100,7 +100,7 @@ bool String::make_space_for( char const* str, ssize add_len )
}
else
{
ssize new_len, old_size, new_size;
sw new_len, old_size, new_size;
void* ptr;
void* new_ptr;
@ -118,7 +118,7 @@ bool String::make_space_for( char const* str, ssize add_len )
if ( new_ptr == nullptr )
return false;
header = rcast( Header*, new_ptr);
header = zpl_cast( Header* ) new_ptr;
header->Allocator = allocator;
header->Capacity = new_len;

View File

@ -8,14 +8,14 @@
// Constant string with length.
struct StrC
{
ssize Len;
sw Len;
char const* Ptr;
operator char const* () const { return Ptr; }
char const& operator[]( ssize index ) const { return Ptr[index]; }
char const& operator[]( sw index ) const { return Ptr[index]; }
};
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(ssize) )
#define cast_to_strc( str ) * rcast( StrC*, (str) - sizeof(sw) )
#define txt( text ) StrC { sizeof( text ) - 1, ( text ) }
inline
@ -33,12 +33,12 @@ struct String
struct Header
{
AllocatorInfo Allocator;
ssize Capacity;
ssize Length;
sw Capacity;
sw Length;
};
static
usize grow_formula( usize value )
uw grow_formula( uw value )
{
// Using a very aggressive growth formula to reduce time mem_copying with recursive calls to append in this library.
return 4 * value + 8;
@ -47,7 +47,7 @@ struct String
static
String make( AllocatorInfo allocator, char const* str )
{
ssize length = str ? str_len( str ) : 0;
sw length = str ? str_len( str ) : 0;
return make_length( allocator, str, length );
}
@ -58,23 +58,23 @@ struct String
}
static
String make_reserve( AllocatorInfo allocator, ssize capacity );
String make_reserve( AllocatorInfo allocator, sw capacity );
static
String make_length( AllocatorInfo allocator, char const* str, ssize length );
String make_length( AllocatorInfo allocator, char const* str, sw length );
static
String fmt( AllocatorInfo allocator, char* buf, ssize buf_size, char const* fmt, ... );
String fmt( AllocatorInfo allocator, char* buf, sw buf_size, char const* fmt, ... );
static
String fmt_buf( AllocatorInfo allocator, char const* fmt, ... );
static
String join( AllocatorInfo allocator, char const** parts, ssize num_parts, char const* glue )
String join( AllocatorInfo allocator, char const** parts, sw num_parts, char const* glue )
{
String result = make( allocator, "" );
for ( ssize idx = 0; idx < num_parts; ++idx )
for ( sw idx = 0; idx < num_parts; ++idx )
{
result.append( parts[ idx ] );
@ -91,7 +91,7 @@ struct String
if ( lhs.length() != rhs.length() )
return false;
for ( ssize idx = 0; idx < lhs.length(); ++idx )
for ( sw idx = 0; idx < lhs.length(); ++idx )
if ( lhs[ idx ] != rhs[ idx ] )
return false;
@ -104,14 +104,14 @@ struct String
if ( lhs.length() != (rhs.Len) )
return false;
for ( ssize idx = 0; idx < lhs.length(); ++idx )
for ( sw idx = 0; idx < lhs.length(); ++idx )
if ( lhs[idx] != rhs[idx] )
return false;
return true;
}
bool make_space_for( char const* str, ssize add_len );
bool make_space_for( char const* str, sw add_len );
bool append( char c )
{
@ -123,11 +123,11 @@ struct String
return append( str, str_len( str ) );
}
bool append( char const* str, ssize length )
bool append( char const* str, sw length )
{
if ( sptr(str) > 0 )
{
ssize curr_len = this->length();
sw curr_len = this->length();
if ( ! make_space_for( str, length ) )
return false;
@ -155,7 +155,7 @@ struct String
bool append_fmt( char const* fmt, ... );
ssize avail_space() const
sw avail_space() const
{
Header const&
header = * rcast( Header const*, Data - sizeof( Header ));
@ -168,7 +168,7 @@ struct String
return Data[ length() - 1 ];
}
ssize capacity() const
sw capacity() const
{
Header const&
header = * rcast( Header const*, Data - sizeof( Header ));
@ -201,7 +201,7 @@ struct String
return *(Header*)(Data - sizeof(Header));
}
ssize length() const
sw length() const
{
Header const&
header = * rcast( Header const*, Data - sizeof( Header ));
@ -273,7 +273,7 @@ struct String
void trim( char const* cut_set )
{
ssize len = 0;
sw len = 0;
char* start_pos = Data;
char* end_pos = Data + length() - 1;
@ -284,7 +284,7 @@ struct String
while ( end_pos > start_pos && char_first_occurence( cut_set, *end_pos ) )
end_pos--;
len = scast( ssize, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) );
len = scast( sw, ( start_pos > end_pos ) ? 0 : ( ( end_pos - start_pos ) + 1 ) );
if ( Data != start_pos )
mem_move( Data, start_pos, len );
@ -379,19 +379,19 @@ struct String
if ( this == & other )
return *this;
String*
this_ = ccast(String*, this);
this_->Data = other.Data;
String& this_ = ccast( String, *this );
return *this;
this_.Data = other.Data;
return this_;
}
char& operator [] ( ssize index )
char& operator [] ( sw index )
{
return Data[ index ];
}
char const& operator [] ( ssize index ) const
char const& operator [] ( sw index ) const
{
return Data[ index ];
}

View File

@ -23,7 +23,7 @@
{
u32 hi, lo;
__asm__ __volatile__( "rdtsc" : "=a"( lo ), "=d"( hi ) );
return scast( u64, lo ) | ( scast( u64, hi ) << 32 );
return ( zpl_cast( u64 ) lo ) | ( ( zpl_cast( u64 ) hi ) << 32 );
}
#elif defined( __powerpc__ )
u64 read_cpu_time_stamp_counter( void )

View File

@ -1,7 +1,7 @@
// This file is intended to be included within gen.hpp (There is no pragma diagnostic ignores)
#pragma once
#include "dependencies/platform.hpp"
#include "dependencies/header_start.hpp"
GEN_NS_BEGIN

View File

@ -70,7 +70,7 @@ CodeBody gen_eoperator( char const* path )
String enum_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
String to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for (usize idx = 0; idx < enum_strs.num(); idx++)
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_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 to_str_entries = String::make_reserve( GlobalAllocator, kilobytes(1) );
for (usize idx = 0; idx < enum_strs.num(); idx++)
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_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 attribute_define_entries = String::make_reserve( GlobalAllocator, kilobytes(4) );
for (usize idx = 0; idx < enum_strs.num(); idx++)
for (uw idx = 0; idx < enum_strs.num(); idx++)
{
char const* enum_str = enum_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);
}
for ( usize idx = 0; idx < attribute_strs.num(); idx++ )
for ( uw idx = 0; idx < attribute_strs.num(); idx++ )
{
char const* attribute_str = attribute_strs[idx].string;
char const* entry_to_str = attribute_str_strs [idx].string;

View File

@ -24,6 +24,8 @@
#undef forceinline
#undef neverinline
#undef zpl_cast
#undef global
#undef internal
#undef local_persist

View File

@ -291,7 +291,7 @@ if ( $test )
#region Formatting
push-location $path_scripts
if ( $true -and $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
if ( $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp")) )
{
$path_gen = join-path $path_project gen
$include = @(
@ -301,12 +301,12 @@ if ( $true -and $bootstrap -and (Test-Path (Join-Path $path_project "gen/gen.hpp
'gen.scanner.hpp', 'gen.scanner.cpp'
)
$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
}
if ( $false -and $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) )
if ( $singleheader -and (Test-Path (Join-Path $path_singleheader "gen/gen.hpp")) )
{
$path_gen = join-path $path_singleheader gen
$include = @(
@ -316,7 +316,7 @@ if ( $false -and $singleheader -and (Test-Path (Join-Path $path_singleheader "ge
format-cpp $path_gen $include $exclude
}
if ( $false -and $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
if ( $unreal -and (Test-Path( Join-Path $path_unreal "gen/gen.hpp")) )
{
$path_gen = join-path $path_unreal gen
$include = @(

View File

@ -43,6 +43,9 @@
// word GEN_COMPILER_MINGW, new_name
// word GEN_COMPILER_MSVC, new_name
// General
// word zpl_cast, new_name
// word global, new_name
// word internal, new_name
// word local_persist, new_name
@ -147,8 +150,8 @@
// word u16, new_name
// word u32, new_name
// word u64, new_name
// word usize, new_name
// word ssize, new_name
// word uw, new_name
// word sw, new_name
// word sptr, new_name
// word uptr, new_name
// word f32, new_name

View File

@ -3,10 +3,10 @@ cls
$build = Join-Path $PSScriptRoot 'build.ci.ps1'
if ( $IsWindows ) {
& $build release msvc bootstrap singleheader unreal msvc debug
& $build release msvc bootstrap singleheader unreal
}
else {
& $build release clang bootstrap singleheader unreal msvc debug
& $build release clang bootstrap singleheader unreal
}
$path_root = git rev-parse --show-toplevel
@ -24,68 +24,45 @@ if ( -not(Test-Path $path_release) ) {
New-Item -ItemType Directory -Path $path_release
}
function prep-ReleaseContent()
{
if ( -not(Test-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
prep-ReleaseContent
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
Remove-Item -Path $path_release_content -Recurse
Remove-Item -Path $path_release_content\gen.hpp
# Segmented
prep-ReleaseContent
Copy-Item -Path $path_project_gen\* -Destination $path_release_content
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_segmented.zip -Force
Remove-Item -Path $path_release_content -Recurse
Remove-Item -Path $path_release_content\gen.dep.hpp
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
prep-ReleaseContent
Copy-Item -Path $path_unreal_gen\* -Destination $path_release_content
Compress-Archive -Path $path_release_content\* -DestinationPath $path_release\gencpp_unreal.zip -Force
Remove-Item -Path $path_release_content -Recurse
# As Is
prep-ReleaseContent
Copy-Item -Verbose -Path $path_project\gen.hpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_project\gen.cpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_project\gen.dep.hpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_project\gen.dep.cpp -Destination $path_release_content
Copy-Item -Verbose -Path $path_project\auxillary\builder.hpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_project\auxillary\builder.cpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_project\auxillary\scanner.hpp -Destination $path_release_content\auxillary
Copy-Item -Verbose -Path $path_project\auxillary\scanner.cpp -Destination $path_release_content\auxillary
New-Item -ItemType Directory -Force -Path "$path_release_content\components"
New-Item -ItemType Directory -Force -Path "$path_release_content\components\gen"
New-Item -ItemType Directory -Force -Path "$path_release_content\dependencies"
New-Item -ItemType Directory -Force -Path "$path_release_content\enums"
New-Item -ItemType Directory -Force -Path "$path_release_content\helpers"
Get-ChildItem -Verbose -Path "$path_project\components\*" -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\components"
Get-ChildItem -Verbose -Path "$path_project\components\gen\*" -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\components\gen"
Get-ChildItem -Verbose -Path "$path_project\dependencies\*" -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\dependencies"
Get-ChildItem -Verbose -Path "$path_project\enums\*" -Include *.csv | Copy-Item -Destination "$path_release_content\enums"
Get-ChildItem -Verbose -Path "$path_project\helpers\*" -Include *.cpp,*.hpp | Copy-Item -Destination "$path_release_content\helpers"
Compress-Archive -Path $path_release_content\** -DestinationPath $path_release\gencpp_as_is.zip -Force
Remove-Item -Path $path_release_content -Recurse

View File

@ -14,8 +14,6 @@ GEN_NS_END
#include "auxillary/builder.cpp"
#include "auxillary/scanner.hpp"
#include <cstdlib> // for system()
using namespace gen;
constexpr char const* generation_notice =
@ -37,6 +35,7 @@ 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.
// Dependencies are derived from the c-zpl library: https://github.com/zpl-c/zpl
#ifndef GEN_ROLL_OWN_DEPENDENCIES
)");
constexpr StrC roll_own_dependencies_guard_end = txt(R"(
@ -49,42 +48,6 @@ global bool generate_builder = true;
global bool generate_editor = 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()
{
#define project_dir "../project/"
@ -106,7 +69,7 @@ int gen_main()
if ( generate_gen_dep )
{
Code platform = scan_file( project_dir "dependencies/platform.hpp" );
Code header_start = scan_file( project_dir "dependencies/header_start.hpp" );
Code macros = scan_file( project_dir "dependencies/macros.hpp" );
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
@ -120,7 +83,7 @@ int gen_main()
Code timing = scan_file( project_dir "dependencies/timing.hpp" );
header.print_fmt( roll_own_dependencies_guard_start );
header.print( platform );
header.print( header_start );
header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( macros );
@ -164,13 +127,9 @@ int gen_main()
header.print_fmt("#pragma region Types\n");
header.print( types );
header.print( fmt_newline );
header.print( dump_to_scratch_and_retireve( ecode ));
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( ecode );
header.print( eoperator );
header.print( especifier );
header.print_fmt("#pragma endregion Types\n\n");
header.print_fmt("#pragma region AST\n");
@ -183,8 +142,7 @@ int gen_main()
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
header.print( dump_to_scratch_and_retireve( ast_inlines ));
header.print( fmt_newline );
header.print( ast_inlines );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
@ -266,7 +224,7 @@ int gen_main()
header.print( interface );
header.print( upfront );
header.print_fmt( "\n#pragma region Parsing\n\n" );
header.print( dump_to_scratch_and_retireve(parser_nspace) );
header.print( parser_nspace );
header.print( lexer );
header.print( parser );
header.print( parsing_interface );

View File

@ -15,11 +15,11 @@ Code gen__array_base()
struct ArrayHeader
{
AllocatorInfo Allocator;
usize Capacity;
usize Num;
uw Capacity;
uw Num;
};
static inline usize array_grow_formula( usize value )
static inline uw array_grow_formula( uw value )
{
return 2 * value * 8;
}
@ -52,7 +52,7 @@ Code gen__array( StrC type )
}
static
<ArrayType> init_reserve( AllocatorInfo allocator, ssize capacity )
<ArrayType> init_reserve( AllocatorInfo allocator, sw capacity )
{
Header* header = rcast( Header*, alloc( allocator, sizeof(Header) + sizeof(Type) ));
@ -94,14 +94,14 @@ Code gen__array( StrC type )
header.Num = 0;
}
bool fill( usize begin, usize end, Type value )
bool fill( uw begin, uw end, Type value )
{
Header& header = get_header();
if ( begin < 0 || end >= header.Num )
return false;
for ( ssize idx = begin; idx < end; idx++ )
for ( sw idx = begin; idx < end; idx++ )
{
Data[ idx ] = value;
}
@ -120,10 +120,10 @@ Code gen__array( StrC type )
return *( reinterpret_cast< Header* >( Data ) - 1 );
}
bool grow( usize min_capacity )
bool grow( uw min_capacity )
{
Header& header = get_header();
usize new_capacity = grow_formula( header.Capacity );
uw new_capacity = grow_formula( header.Capacity );
if ( new_capacity < min_capacity )
new_capacity = 8;
@ -131,7 +131,7 @@ Code gen__array( StrC type )
return set_capacity( new_capacity );
}
usize num( void )
uw num( void )
{
return get_header().Num;
}
@ -144,7 +144,7 @@ Code gen__array( StrC type )
header.Num--;
}
void remove_at( usize idx )
void remove_at( uw idx )
{
Header* header = &get_header();
GEN_ASSERT( idx < header->Num );
@ -153,7 +153,7 @@ Code gen__array( StrC type )
header->Num--;
}
bool reserve( usize new_capacity )
bool reserve( uw new_capacity )
{
Header& header = get_header();
@ -163,7 +163,7 @@ Code gen__array( StrC type )
return true;
}
bool resize( usize num )
bool resize( uw num )
{
Header& header = get_header();
@ -177,7 +177,7 @@ Code gen__array( StrC type )
return true;
}
bool set_capacity( usize new_capacity )
bool set_capacity( uw new_capacity )
{
Header& header = get_header();
@ -187,7 +187,7 @@ Code gen__array( StrC type )
if ( new_capacity < header.Num )
header.Num = new_capacity;
ssize size = sizeof( Header ) + sizeof( Type ) * new_capacity;
sw size = sizeof( Header ) + sizeof( Type ) * new_capacity;
Header* new_header = rcast( Header*, alloc( header.Allocator, size ) );
if ( new_header == nullptr )
@ -233,7 +233,7 @@ void gen__array_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx )
for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
{
StrC const reqest_type = GenArrayRequests[ idx ].Type;

View File

@ -15,8 +15,8 @@ Code gen__buffer_base()
struct BufferHeader
{
AllocatorInfo Backing;
usize Capacity;
usize Num;
uw Capacity;
uw Num;
};
));
}
@ -38,7 +38,7 @@ Code gen__buffer( StrC type )
using Header = BufferHeader;
using Type = <type>;
static <BufferName> init( AllocatorInfo allocator, ssize capacity )
static <BufferName> init( AllocatorInfo allocator, sw capacity )
{
Header* header = rcast( Header*, alloc( allocator, sizeof( Header ) + capacity * sizeof( Type ) ) );
@ -76,7 +76,7 @@ Code gen__buffer( StrC type )
header.Num++;
}
void append( Type* values, ssize num )
void append( Type* values, sw num )
{
Header& header = get_header();
GEN_ASSERT( header.Num + num <= header.Capacity);
@ -108,7 +108,7 @@ Code gen__buffer( StrC type )
return *( rcast( Header*, Data ) - 1 );
}
ssize num( void )
sw num( void )
{
return get_header().Num;
}
@ -147,7 +147,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx )
for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
{
StrC const reqest_type = GenBufferRequests[ idx ].Type;

View File

@ -15,9 +15,9 @@ Code gen__hashtable_base()
return parse_global_body( code(
struct HashTable_FindResult
{
ssize HashIndex;
ssize PrevIndex;
ssize EntryIndex;
sw HashIndex;
sw PrevIndex;
sw EntryIndex;
};
));
}
@ -37,7 +37,7 @@ Code gen__hashtable( StrC type )
struct <HashTableName>_Entry
{
u64 Key;
ssize Next;
sw Next;
<type> Value;
};
)
@ -86,7 +86,7 @@ Code gen__hashtable( StrC type )
Type* get( u64 key )
{
ssize idx = find( key ).EntryIndex;
sw idx = find( key ).EntryIndex;
if ( idx > 0 )
return &Entries[ idx ].Value;
@ -96,7 +96,7 @@ Code gen__hashtable( StrC type )
void grow( void )
{
ssize new_num = array_grow_formula( Entries.num() );
sw new_num = array_grow_formula( Entries.num() );
rehash( new_num );
}
@ -105,7 +105,7 @@ Code gen__hashtable( StrC type )
{
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < Entries.num(); idx++ )
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
}
@ -115,16 +115,16 @@ Code gen__hashtable( StrC type )
{
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < Entries.num(); idx++ )
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
map_proc( Entries[ idx ].Key, &Entries[ idx ].Value );
}
}
void rehash( ssize new_num )
void rehash( sw new_num )
{
ssize idx;
ssize last_added_index;
sw idx;
sw last_added_index;
HashTable_u32 new_ht = HashTable_u32::init( Hashes.get_header().Allocator );
new_ht.Hashes.resize( new_num );
@ -163,7 +163,7 @@ Code gen__hashtable( StrC type )
void rehash_fast( void )
{
ssize idx;
sw idx;
for ( idx = 0; idx < Entries.num(); idx++ )
Entries[ idx ].Next = -1;
@ -189,14 +189,14 @@ Code gen__hashtable( StrC type )
}
}
void remove_entry( ssize idx )
void remove_entry( sw idx )
{
Entries.remove_at( idx );
}
void set( u64 key, Type value )
{
ssize idx;
sw idx;
FindResult find_result;
if ( Hashes.num() == 0 )
@ -228,9 +228,9 @@ Code gen__hashtable( StrC type )
grow();
}
ssize slot( u64 key )
sw slot( u64 key )
{
for ( ssize idx = 0; idx < Hashes.num(); ++idx )
for ( sw idx = 0; idx < Hashes.num(); ++idx )
if ( Hashes[ idx ] == key )
return idx;
@ -242,9 +242,9 @@ Code gen__hashtable( StrC type )
protected:
ssize add_entry( u64 key )
sw add_entry( u64 key )
{
ssize idx;
sw idx;
Entry entry = { key, -1 };
idx = Entries.num();
Entries.append( entry );
@ -294,11 +294,11 @@ void gen__hashtable_request( StrC type, StrC dep = {} )
do_once_start
GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
gen_array( ssize );
gen_array( sw );
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx )
for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
{
StrC const reqest_type = GenHashTableRequests[ idx ].Type;

View File

@ -30,7 +30,7 @@ Code gen__ring( StrC type )
{
using Type = <type>;
static <RingName> init( AllocatorInfo allocator, usize max_size )
static <RingName> init( AllocatorInfo allocator, uw max_size )
{
<RingName> result = { 0 };
@ -52,9 +52,9 @@ Code gen__ring( StrC type )
Tail = ( Tail + 1 ) % Capacity;
}
inline void append( Type* values, ssize num )
inline void append( Type* values, sw num )
{
for ( ssize idx = 0; idx < num; idx++ )
for ( sw idx = 0; idx < num; idx++ )
append( values[ idx ] );
}
@ -88,9 +88,9 @@ Code gen__ring( StrC type )
}
AllocatorInfo Backing;
usize Capacity;
usize Head;
usize Tail;
uw Capacity;
uw Head;
uw Tail;
<BufferName> Buffer;
};
)
@ -113,7 +113,7 @@ void gen__ring_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx )
for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
{
StrC const reqest_type = GenRingRequests[ idx ].Type;

View File

@ -23,14 +23,14 @@ int gen_main()
gen_sanity();
gen_array( u8 );
gen_array( ssize );
gen_array( sw );
gen_buffer( u8 );
gen_hashtable( u32 );
gen_ring( s16 );
gen_ring( usize );
gen_ring( uw );
gen_array_file();
gen_buffer_file();

View File

@ -142,7 +142,7 @@ Code gen__array( StrC type )
if ( begin < 0 || end >= header.Num )
return false;
for ( ssize idx = begin; idx < end; idx++ )
for ( sw idx = begin; idx < end; idx++ )
{
Data[ idx ] = value;
}
@ -170,7 +170,7 @@ Code gen__array( StrC type )
, def_execution( code(
Header& header = * get_header();
usize new_capacity = grow_formula( header.Capacity );
uw new_capacity = grow_formula( header.Capacity );
if ( new_capacity < min_capacity )
new_capacity = 8;
@ -243,7 +243,7 @@ Code gen__array( StrC type )
if ( new_capacity < header.Num )
header.Num = new_capacity;
ssize size = sizeof(Header) + sizeof(Type) * new_capacity;
sw size = sizeof(Header) + sizeof(Type) * new_capacity;
Header* new_header = rcast( Header*, alloc( header.Allocator, size ));
if ( new_header == nullptr )
@ -314,7 +314,7 @@ void gen__array_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenArrayRequests.num(); ++idx )
for ( sw idx = 0; idx < GenArrayRequests.num(); ++idx )
{
StrC const reqest_type = GenArrayRequests[ idx ].Type;

View File

@ -19,7 +19,7 @@ Code gen__buffer_base()
return def_global_body( 1, header );
}
Code gen__buffer( StrC type, ssize type_size )
Code gen__buffer( StrC type, sw type_size )
{
static CodeType t_allocator_info = def_type( name(AllocatorInfo));
@ -206,7 +206,7 @@ struct GenBufferRequest
{
StrC Dependency;
StrC Type;
ssize TypeSize;
sw TypeSize;
};
Array<GenBufferRequest> GenBufferRequests;
@ -217,7 +217,7 @@ void gen__buffer_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenBufferRequests.num(); ++idx )
for ( sw idx = 0; idx < GenBufferRequests.num(); ++idx )
{
StrC const reqest_type = GenBufferRequests[ idx ].Type;

View File

@ -128,7 +128,7 @@ Code gen__hashtable( StrC type )
CodeFn get = def_function( name(get), def_param( t_u64, name(key)), t_type_ptr
, def_execution( code(
ssize idx = find( key ).EntryIndex;
sw idx = find( key ).EntryIndex;
if ( idx >= 0 )
return & Entries[ idx ].Value;
@ -153,7 +153,7 @@ Code gen__hashtable( StrC type )
Code body = def_execution( code(
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < Entries.num(); idx++ )
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
map_proc( Entries[ idx ].Key, Entries[ idx ].Value );
}
@ -179,7 +179,7 @@ Code gen__hashtable( StrC type )
Code body = def_execution( code(
GEN_ASSERT_NOT_NULL( map_proc );
for ( ssize idx = 0; idx < Entries.num(); idx++ )
for ( sw idx = 0; idx < Entries.num(); idx++ )
{
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
, def_execution( code(
ssize new_num = array_grow_formula( Entries.num() );
sw new_num = array_grow_formula( Entries.num() );
rehash( new_num );
))
);
@ -198,8 +198,8 @@ Code gen__hashtable( StrC type )
CodeFn rehash;
{
char const* tmpl = stringize(
ssize idx;
ssize last_added_index;
sw idx;
sw last_added_index;
<type> new_ht = init_reserve( Hashes.get_header()->Allocator, new_num );
@ -242,7 +242,7 @@ Code gen__hashtable( StrC type )
CodeFn rehash_fast;
{
char const* tmpl = stringize(
ssize idx;
sw idx;
for ( idx = 0; idx < Entries.num(); idx++ )
Entries[ idx ].Next = -1;
@ -288,7 +288,7 @@ Code gen__hashtable( StrC type )
));
Code body = def_execution( code(
ssize idx;
sw idx;
FindResult find_result;
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
, def_execution( code(
for ( ssize idx = 0; idx < Hashes.num(); ++idx )
for ( sw idx = 0; idx < Hashes.num(); ++idx )
if ( Hashes[ idx ] == key )
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
, def_execution( code(
ssize idx;
sw idx;
Entry entry = { key, -1 };
idx = Entries.num();
@ -421,11 +421,11 @@ void gen__hashtable_request( StrC type, StrC dep = {} )
do_once_start
GenHashTableRequests = Array<GenHashTableRequest>::init( GlobalAllocator );
gen_array( ssize );
gen_array( sw );
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenHashTableRequests.num(); ++idx )
for ( sw idx = 0; idx < GenHashTableRequests.num(); ++idx )
{
StrC const reqest_type = GenHashTableRequests[ idx ].Type;

View File

@ -87,7 +87,7 @@ Code gen__ring( StrC type )
);
Code body = def_execution( code(
for ( ssize idx = 0; idx < num; idx++ )
for ( sw idx = 0; idx < num; idx++ )
append( values[ idx ] );
));
@ -167,7 +167,7 @@ void gen__ring_request( StrC type, StrC dep = {} )
do_once_end
// Make sure we don't already have a request for the type.
for ( ssize idx = 0; idx < GenRingRequests.num(); ++idx )
for ( sw idx = 0; idx < GenRingRequests.num(); ++idx )
{
StrC const reqest_type = GenRingRequests[ idx ].Type;

View File

@ -22,7 +22,7 @@ int gen_main()
gen_sanity_upfront();
gen_array( u8 );
gen_array( ssize );
gen_array( sw );
gen_buffer( u8 );

View File

@ -5,64 +5,21 @@
#define GEN_BENCHMARK
#include "gen.cpp"
#include "gen.builder.cpp"
#include "gen.scanner.cpp"
#include "sanity.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.singleheader.cpp"
int gen_main()
{
using namespace gen;
log_fmt("\ngen_time:");
// check_sanity();
// check_SOA();
// validate_original_files_ast();
validate_original_files_ast();
validate_singleheader_ast();
return 0;

View File

@ -8,6 +8,10 @@
#include "gen.scanner.hpp"
using namespace gen;
#ifdef GEN_SYSTEM_WINDOWS
#include <process.h>
#endif
#define path_root "../"
#define path_project path_root "project/"
#define path_scripts path_root "scripts/"
@ -22,32 +26,13 @@ void validate_file_ast( char const* path, char const* 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 );
// 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" );
}
// FileError error = file_open_mode( & path_temp, EFileMode_WRITE, path );
// if ( error != EFileError_NONE )
// {
// log_failure( "gen::File::open - Could not open file: %s", path);
// return;
// }
u64 time_start = time_rel_ms();
CodeBody ast = parse_global_body( { file.size, (char const*)file.data } );
@ -100,11 +85,8 @@ void validate_original_files_ast()
gen::init();
log_fmt("\nvalidate_original_files_ast:\n");
PreprocessorDefines.append( get_cached_string( txt("GEN_FILE_SEEK_PROC(")));
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(")));
PreprocessorDefines.append( get_cached_string( txt("GEN_DEF_INLINE") ));
PreprocessorDefines.append( get_cached_string( txt("GEN_IMPL_INLINE") ));
// Helpers
{
@ -117,7 +99,7 @@ void validate_original_files_ast()
// Dependencies
{
#define validate( path ) validate_file_ast( path_dependencies path, "gen/original/dependencies/" path )
validate( "platform.hpp" );
validate( "header_start.hpp" );
validate( "macros.hpp" );
validate( "basic_types.hpp" );
validate( "debug.hpp" );

View File

@ -7,38 +7,17 @@
#include "gen.scanner.hpp"
using namespace gen;
#ifdef GEN_SYSTEM_WINDOWS
#include <process.h>
#endif
void validate_singleheader_ast()
{
#define root_dir "../"
gen::init();
log_fmt("\nvalidate_singleheader_ast:\n");
log_fmt("\validate_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" );
}
u64 time_start = time_rel_ms();
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);

View File

@ -14,8 +14,6 @@ GEN_NS_END
#include "auxillary/builder.cpp"
#include "auxillary/scanner.hpp"
#include <cstdlib> // for system()
using namespace gen;
constexpr char const* generation_notice =
@ -50,42 +48,6 @@ global bool generate_builder = true;
global bool generate_editor = 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()
{
#define project_dir "../project/"
@ -99,6 +61,24 @@ int gen_main()
// 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 );
{
FileContents content = file_read_contents( GlobalAllocator, true, project_dir "dependencies/macros.hpp" );
@ -131,7 +111,6 @@ int gen_main()
}
}
Code platform = scan_file( project_dir "dependencies/platform.hpp" );
Code basic_types = scan_file( project_dir "dependencies/basic_types.hpp" );
Code debug = scan_file( project_dir "dependencies/debug.hpp" );
Code memory = scan_file( project_dir "dependencies/memory.hpp" );
@ -146,13 +125,10 @@ int gen_main()
Builder
header = Builder::open("gen/gen.dep.hpp");
header.print_fmt( generation_notice );
header.print( pragma_once );
header.print( push_ignores );
header.print( platform );
header.print( header_start );
header.print_fmt( "\nGEN_NS_BEGIN\n" );
header.print( fmt_newline);
header.print( dump_to_scratch_and_retireve(macros) );
header.print( macros );
header.print( basic_types );
header.print( debug );
header.print( memory );
@ -233,13 +209,9 @@ int gen_main()
header.print_fmt( "#pragma region Types\n" );
header.print( types );
header.print( fmt_newline );
header.print( dump_to_scratch_and_retireve(ecode) );
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( ecode );
header.print( eoperator );
header.print( especifier );
header.print_fmt( "#pragma endregion Types\n\n" );
header.print_fmt( "#pragma region AST\n" );
@ -253,8 +225,7 @@ int gen_main()
header.print_fmt( "\n#pragma region Inlines\n" );
header.print( inlines );
header.print( fmt_newline );
header.print( dump_to_scratch_and_retireve(ast_inlines) );
header.print( fmt_newline );
header.print( ast_inlines );
header.print_fmt( "#pragma endregion Inlines\n" );
header.print( header_end );
@ -304,7 +275,7 @@ int gen_main()
src.print( interface );
src.print( upfront );
src.print_fmt( "\n#pragma region Parsing\n\n" );
src.print( dump_to_scratch_and_retireve(nspaced_etoktype) );
src.print( nspaced_etoktype );
src.print( lexer );
src.print( parser );
src.print( parsing_interface );