Compare commits

13 Commits

Author SHA1 Message Date
885ef7fea6 Hashtable 2023-10-27 14:21:29 +06:00
b6088845d9 removed elements freeing in autoarr 2023-10-27 14:21:10 +06:00
5ddc96e1b4 StringBuilder 2023-10-27 13:37:18 +06:00
e7280038fb typeof 2023-10-12 14:01:39 +06:00
14630e509d Autuarr 2023-07-10 18:31:16 +06:00
28169450cf LinearAllocator improved 2023-06-08 21:29:47 +06:00
8d36fd8042 string and StringBuilder 2023-06-08 18:41:05 +06:00
32ce7d3a70 some fixes 2023-06-08 15:59:52 +06:00
080bbb28fd random 2023-06-08 15:15:50 +06:00
c5585bbb0c refactoring 2023-06-08 15:15:38 +06:00
a983df1ac6 memory allocators 2023-06-05 14:10:00 +06:00
490d450a82 changed Autoarr field names 2023-06-05 13:56:14 +06:00
61da9ad161 memcpy 2023-06-05 13:55:00 +06:00
117 changed files with 1735 additions and 1773 deletions

4
.gitignore vendored
View File

@@ -4,6 +4,10 @@ obj/
# user files # user files
.old*/ .old*/
[Tt]mp/
[Tt]emp/
.[Tt]mp/
.[Tt]emp/
.vs/ .vs/
.vshistory/ .vshistory/
.editorconfig .editorconfig

10
.vscode/launch.json vendored
View File

@@ -42,16 +42,6 @@
"pipeArgs": ["-c"], "pipeArgs": ["-c"],
"pipeCwd": "${workspaceFolder}" "pipeCwd": "${workspaceFolder}"
} }
},
{
"name": "(msvc) Debug",
"type": "cppvsdbg",
"request": "launch",
"preLaunchTask": "build_dbg",
"program": "${workspaceFolder}\\bin\\kerep",
"cwd": "${workspaceFolder}\\bin",
"stopAtEntry": false,
"console": "integratedTerminal"
} }
] ]
} }

3
.vscode/tasks.json vendored
View File

@@ -23,8 +23,7 @@
"reveal": "always", "reveal": "always",
"focus": true, "focus": true,
"panel": "shared", "panel": "shared",
"showReuseMessage": false, "showReuseMessage": false
"clean": true
} }
} }
] ]

29
TODO.md Normal file
View File

@@ -0,0 +1,29 @@
## Allocators
- replace all malloc() and free() with allocator_alloc() and allocator_free()
- replace allocating constructors with Type_construct(var_ptr, ...)
- replace Struct_free functions with Struct_destruct which will not call free() on the struct ptr
- store in resizable structs their buffer allocators and free them with Struct_destruct()
- check allocator_free call order
- deal with StackingAllocator_free not freing memory sometimes
- replace LinearAllocator with StackingAllocator when possible (in DtsodV24_deserialize)
- use LinkedList instead of complicated LinearAllocator logic
- configurable LinearAllocator chunk size (static/growing)
## Autoarr
- store length and max_length inside the struct instead of calculating them by macro
- keep Autoarr_length() and Autoarr_maxLength() to old code compatibility
- toString()
## Hashtable
- store hash in KVPair
- don't use Autoarr in Hashtable
- make Hashtable generic struct
## Unitype
- replace UniPtrHeap with UniPtrStack
- do something with VoidPtr ownership
## String
- add `bool zero_terminated`
- rewrite all code to use `string` instead of `char*`
- rewrite `StringBuilder`

2
cbuild

Submodule cbuild updated: ef6a3f82c4...60fa8c11c2

View File

@@ -1,31 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32317.152 VisualStudioVersion = 17.2.32317.152
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kerep", "kerep.vcxproj", "{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kerep", "kerep.vcxproj", "{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
Debug|x86 = Debug|x86 Debug|x86 = Debug|x86
Release|x64 = Release|x64 Release|x64 = Release|x64
Release|x86 = Release|x86 Release|x86 = Release|x86
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.ActiveCfg = Debug|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.ActiveCfg = Debug|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.Build.0 = Debug|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x64.Build.0 = Debug|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.ActiveCfg = Debug|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.ActiveCfg = Debug|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.Build.0 = Debug|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Debug|x86.Build.0 = Debug|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.ActiveCfg = Release|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.ActiveCfg = Release|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.Build.0 = Release|x64 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x64.Build.0 = Release|x64
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.ActiveCfg = Release|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.ActiveCfg = Release|Win32
{52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.Build.0 = Release|Win32 {52F0BD29-A3CB-47CE-B25D-CEAF5DFB2D73}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {22F8C351-9A96-4F37-94E6-37E6AB5BA058} SolutionGuid = {22F8C351-9A96-4F37-94E6-37E6AB5BA058}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@@ -1,297 +1,297 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32"> <ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Win32</Platform> <Platform>Win32</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64"> <ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration> <Configuration>Debug</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
<ProjectConfiguration Include="Release|x64"> <ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>x64</Platform> <Platform>x64</Platform>
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\Array\Array.c" /> <ClCompile Include="src\Array\Array.c" />
<ClCompile Include="src\Autoarr\Autoarr.c" /> <ClCompile Include="src\Autoarr\Autoarr.c" />
<ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" /> <ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" />
<ClCompile Include="src\Autoarr\Autoarr_Unitype.c" /> <ClCompile Include="src\Autoarr\Autoarr_Unitype.c" />
<ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" /> <ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" />
<ClCompile Include="src\base\cptr.c" /> <ClCompile Include="src\base\cptr.c" />
<ClCompile Include="src\base\endian.c" /> <ClCompile Include="src\base\endian.c" />
<ClCompile Include="src\base\errors.c" /> <ClCompile Include="src\base\errors.c" />
<ClCompile Include="src\base\type_system\base_toString.c" /> <ClCompile Include="src\base\type_system\base_toString.c" />
<ClCompile Include="src\base\type_system\init.c" /> <ClCompile Include="src\base\type_system\init.c" />
<ClCompile Include="src\base\type_system\kt_functions.c" /> <ClCompile Include="src\base\type_system\kt_functions.c" />
<ClCompile Include="src\base\type_system\unitype.c" /> <ClCompile Include="src\base\type_system\unitype.c" />
<ClCompile Include="src\DtsodParser\DtsodV24.c" /> <ClCompile Include="src\DtsodParser\DtsodV24.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_exported.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_exported.c" />
<ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" /> <ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" />
<ClCompile Include="src\Filesystem\dir.c" /> <ClCompile Include="src\Filesystem\dir.c" />
<ClCompile Include="src\Filesystem\file.c" /> <ClCompile Include="src\Filesystem\file.c" />
<ClCompile Include="src\Filesystem\path.c" /> <ClCompile Include="src\Filesystem\path.c" />
<ClCompile Include="src\HashFunctions\hash.c" /> <ClCompile Include="src\HashFunctions\hash.c" />
<ClCompile Include="src\Hashtable\Hashtable.c" /> <ClCompile Include="src\Hashtable\Hashtable.c" />
<ClCompile Include="src\Hashtable\KeyValuePair.c" /> <ClCompile Include="src\Hashtable\KeyValuePair.c" />
<ClCompile Include="src\kprint\kprint.c" /> <ClCompile Include="src\kprint\kprint.c" />
<ClCompile Include="src\kprint\kprintf.c" /> <ClCompile Include="src\kprint\kprintf.c" />
<ClCompile Include="src\random\splitmix64\splitmix64.c" /> <ClCompile Include="src\random\splitmix64\splitmix64.c" />
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64star.c" /> <ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64star.c" />
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64starstar.c" /> <ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64starstar.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plus.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plus.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plusplus.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plusplus.c" />
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128starstar.c" /> <ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128starstar.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plus.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plus.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plusplus.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plusplus.c" />
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128starstar.c" /> <ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128starstar.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plus.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plus.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plusplus.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plusplus.c" />
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256starstar.c" /> <ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256starstar.c" />
<ClCompile Include="src\SearchTree\SearchTree.c" /> <ClCompile Include="src\SearchTree\SearchTree.c" />
<ClCompile Include="src\String\string.c" /> <ClCompile Include="src\String\string.c" />
<ClCompile Include="src\String\StringBuilder.c" /> <ClCompile Include="src\String\StringBuilder.c" />
<ClCompile Include="tests\test_marshalling.c" /> <ClCompile Include="tests\test_marshalling.c" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\Array\Array.h" /> <ClInclude Include="src\Array\Array.h" />
<ClInclude Include="src\Array\Array_declare.h" /> <ClInclude Include="src\Array\Array_declare.h" />
<ClInclude Include="src\Array\Array_define.h" /> <ClInclude Include="src\Array\Array_define.h" />
<ClInclude Include="src\Autoarr\Autoarr.h" /> <ClInclude Include="src\Autoarr\Autoarr.h" />
<ClInclude Include="src\Autoarr\Autoarr_declare.h" /> <ClInclude Include="src\Autoarr\Autoarr_declare.h" />
<ClInclude Include="src\Autoarr\Autoarr_define.h" /> <ClInclude Include="src\Autoarr\Autoarr_define.h" />
<ClInclude Include="src\Autoarr\Autoarr_Unitype.h" /> <ClInclude Include="src\Autoarr\Autoarr_Unitype.h" />
<ClInclude Include="src\base\base.h" /> <ClInclude Include="src\base\base.h" />
<ClInclude Include="src\base\cptr.h" /> <ClInclude Include="src\base\cptr.h" />
<ClInclude Include="src\base\endian.h" /> <ClInclude Include="src\base\endian.h" />
<ClInclude Include="src\base\errors.h" /> <ClInclude Include="src\base\errors.h" />
<ClInclude Include="src\base\optime.h" /> <ClInclude Include="src\base\optime.h" />
<ClInclude Include="src\base\std.h" /> <ClInclude Include="src\base\std.h" />
<ClInclude Include="src\base\type_system\base_toString.h" /> <ClInclude Include="src\base\type_system\base_toString.h" />
<ClInclude Include="src\base\type_system\init.h" /> <ClInclude Include="src\base\type_system\init.h" />
<ClInclude Include="src\base\type_system\ktDescriptor.h" /> <ClInclude Include="src\base\type_system\ktDescriptor.h" />
<ClInclude Include="src\base\type_system\ktid.h" /> <ClInclude Include="src\base\type_system\ktid.h" />
<ClInclude Include="src\base\type_system\kt_functions.h" /> <ClInclude Include="src\base\type_system\kt_functions.h" />
<ClInclude Include="src\base\type_system\type_system.h" /> <ClInclude Include="src\base\type_system\type_system.h" />
<ClInclude Include="src\base\type_system\unitype.h" /> <ClInclude Include="src\base\type_system\unitype.h" />
<ClInclude Include="src\DtsodParser\DtsodV24.h" /> <ClInclude Include="src\DtsodParser\DtsodV24.h" />
<ClInclude Include="src\Filesystem\dir.h" /> <ClInclude Include="src\Filesystem\dir.h" />
<ClInclude Include="src\Filesystem\file.h" /> <ClInclude Include="src\Filesystem\file.h" />
<ClInclude Include="src\Filesystem\filesystem.h" /> <ClInclude Include="src\Filesystem\filesystem.h" />
<ClInclude Include="src\Filesystem\path.h" /> <ClInclude Include="src\Filesystem\path.h" />
<ClInclude Include="src\HashFunctions\hash.h" /> <ClInclude Include="src\HashFunctions\hash.h" />
<ClInclude Include="src\Hashtable\Hashtable.h" /> <ClInclude Include="src\Hashtable\Hashtable.h" />
<ClInclude Include="src\Hashtable\KeyValuePair.h" /> <ClInclude Include="src\Hashtable\KeyValuePair.h" />
<ClInclude Include="src\kprint\kprint.h" /> <ClInclude Include="src\kprint\kprint.h" />
<ClInclude Include="src\kprint\kprintf.h" /> <ClInclude Include="src\kprint\kprintf.h" />
<ClInclude Include="src\kprint\kprint_colors.h" /> <ClInclude Include="src\kprint\kprint_colors.h" />
<ClInclude Include="src\kprint\kprint_format.h" /> <ClInclude Include="src\kprint\kprint_format.h" />
<ClInclude Include="src\random\krandom.h" /> <ClInclude Include="src\random\krandom.h" />
<ClInclude Include="src\random\splitmix64\splitmix64.h" /> <ClInclude Include="src\random\splitmix64\splitmix64.h" />
<ClInclude Include="src\random\xoroshiro\32bitValue\xoroshiro64.h" /> <ClInclude Include="src\random\xoroshiro\32bitValue\xoroshiro64.h" />
<ClInclude Include="src\random\xoroshiro\64bitValue\xoroshiro128.h" /> <ClInclude Include="src\random\xoroshiro\64bitValue\xoroshiro128.h" />
<ClInclude Include="src\random\xoroshiro\xoroshiro.h" /> <ClInclude Include="src\random\xoroshiro\xoroshiro.h" />
<ClInclude Include="src\random\xoshiro\32bitValue\xoshiro128.h" /> <ClInclude Include="src\random\xoshiro\32bitValue\xoshiro128.h" />
<ClInclude Include="src\random\xoshiro\64bitValue\xoshiro256.h" /> <ClInclude Include="src\random\xoshiro\64bitValue\xoshiro256.h" />
<ClInclude Include="src\random\xoshiro\xoshiro.h" /> <ClInclude Include="src\random\xoshiro\xoshiro.h" />
<ClInclude Include="src\SearchTree\SearchTree.h" /> <ClInclude Include="src\SearchTree\SearchTree.h" />
<ClInclude Include="src\String\string.h" /> <ClInclude Include="src\String\string.h" />
<ClInclude Include="src\String\StringBuilder.h" /> <ClInclude Include="src\String\StringBuilder.h" />
<ClInclude Include="tests\tests.h" /> <ClInclude Include="tests\tests.h" />
</ItemGroup> </ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion> <VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword> <Keyword>Win32Proj</Keyword>
<ProjectGuid>{52f0bd29-a3cb-47ce-b25d-ceaf5dfb2d73}</ProjectGuid> <ProjectGuid>{52f0bd29-a3cb-47ce-b25d-ceaf5dfb2d73}</ProjectGuid>
<RootNamespace>kerep</RootNamespace> <RootNamespace>kerep</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType> <ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>ClangCL</PlatformToolset> <PlatformToolset>ClangCL</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet> <CharacterSet>MultiByte</CharacterSet>
<CLRSupport>false</CLRSupport> <CLRSupport>false</CLRSupport>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings"> <ImportGroup Label="ExtensionSettings">
</ImportGroup> </ImportGroup>
<ImportGroup Label="Shared"> <ImportGroup Label="Shared">
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>bin\$(Configuration)-$(Platform)\</OutDir> <OutDir>bin\$(Configuration)-$(Platform)\</OutDir>
<IntDir>obj\$(Configuration)-$(Platform)\</IntDir> <IntDir>obj\$(Configuration)-$(Platform)\</IntDir>
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>bin\x86\</OutDir> <OutDir>bin\x86\</OutDir>
<IntDir>obj\x86\</IntDir> <IntDir>obj\x86\</IntDir>
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<OutDir>bin\$(Configuration)-$(Platform)\</OutDir> <OutDir>bin\$(Configuration)-$(Platform)\</OutDir>
<IntDir>obj\$(Configuration)-$(Platform)\</IntDir> <IntDir>obj\$(Configuration)-$(Platform)\</IntDir>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<RunCodeAnalysis>true</RunCodeAnalysis> <RunCodeAnalysis>true</RunCodeAnalysis>
<OutDir>bin\x64\</OutDir> <OutDir>bin\x64\</OutDir>
<IntDir>obj\x64\</IntDir> <IntDir>obj\x64\</IntDir>
<ManagedAssembly>false</ManagedAssembly> <ManagedAssembly>false</ManagedAssembly>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal> <TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
<DisableAnalyzeExternal>true</DisableAnalyzeExternal> <DisableAnalyzeExternal>true</DisableAnalyzeExternal>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
<WarningLevel>TurnOffAllWarnings</WarningLevel> <WarningLevel>TurnOffAllWarnings</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;KEREP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader> <PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile> <PrecompiledHeaderFile>
</PrecompiledHeaderFile> </PrecompiledHeaderFile>
<LanguageStandard_C>stdc17</LanguageStandard_C> <LanguageStandard_C>stdc17</LanguageStandard_C>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<PrecompiledHeaderOutputFile /> <PrecompiledHeaderOutputFile />
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<CompileAs>Default</CompileAs> <CompileAs>Default</CompileAs>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
<DebugInformationFormat>None</DebugInformationFormat> <DebugInformationFormat>None</DebugInformationFormat>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC> <EnableUAC>false</EnableUAC>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@@ -1,27 +0,0 @@
#include "Array.h"
Array_define(char)
Array_define(bool)
Array_define(f32)
Array_define(f64)
Array_define(i8)
Array_define(u8)
Array_define(i16)
Array_define(u16)
Array_define(i32)
Array_define(u32)
Array_define(i64)
Array_define(u64)
Array_define(Pointer)
Array_define(Unitype)
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers){
if(freeMembers) for (u32 i=0; i<array->length; i++)
Unitype_free(array->values[i]);
if(array->allocatedOnHeap)
free(array->values);
}
void __Array_Unitype_free_(void* ar)
{ Array_Unitype_free_(ar, true); }

View File

@@ -1,32 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "Array_declare.h"
#include "Array_define.h"
Array_declare(char)
Array_declare(bool)
Array_declare(f32)
Array_declare(f64)
Array_declare(i8)
Array_declare(u8)
Array_declare(i16)
Array_declare(u16)
Array_declare(i32)
Array_declare(u32)
Array_declare(i64)
Array_declare(u64)
Array_declare(Pointer)
Array_declare(Unitype)
/// use this function instead of auto generated
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers);
void __Array_Unitype_free_(void* ar);
#if __cplusplus
}
#endif

View File

@@ -1,39 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Array_declare(type) \
STRUCT(Array_##type, \
type* values; \
u32 length; \
bool allocatedOnHeap; \
) \
\
static inline Array_##type Array_##type##_allocValues(u32 length){ \
return (Array_##type) { \
.values=(type*)malloc(sizeof(type)*length), \
.length=length, \
.allocatedOnHeap=true \
}; \
} \
\
static inline Array_##type Array_##type##_fromBuffer(type* buffer, u32 bufferLength, bool allocatedOnHeap){ \
return (Array_##type) { \
.values=buffer, \
.length=bufferLength, \
.allocatedOnHeap=allocatedOnHeap \
}; \
} \
\
static inline void Array_##type##_free(Array_##type* array){ \
if(array->allocatedOnHeap) \
free(array->values); \
}
#if __cplusplus
}
#endif

View File

@@ -1,14 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Array_define(type) \
kt_define(Array_##type, (freeMembers_t)Array_##type##_free, NULL);
#if __cplusplus
}
#endif

View File

@@ -1,2 +0,0 @@
# Array struct
This struct stores array pointer and length. If you want to use `Array` of some type, it should be declared in header file by macro `Array_declare` and defined in source file by `Array_define`.

View File

@@ -1,17 +1,17 @@
#include "Autoarr.h" #include "Autoarr.h"
Autoarr_define(Pointer, true) Autoarr_define(Pointer)
Autoarr_define(char, false) Autoarr_define(char)
Autoarr_define(bool, false) Autoarr_define(bool)
Autoarr_define(f32, false) Autoarr_define(f32)
Autoarr_define(f64, false) Autoarr_define(f64)
Autoarr_define(u8, false) Autoarr_define(u8)
Autoarr_define(i8, false) Autoarr_define(i8)
Autoarr_define(u16, false) Autoarr_define(u16)
Autoarr_define(i16, false) Autoarr_define(i16)
Autoarr_define(u32, false) Autoarr_define(u32)
Autoarr_define(i32, false) Autoarr_define(i32)
Autoarr_define(u64, false) Autoarr_define(u64)
Autoarr_define(i64, false) Autoarr_define(i64)
Autoarr_define(Unitype, false) Autoarr_define(Unitype)

View File

@@ -23,21 +23,6 @@ Autoarr_declare(u64)
Autoarr_declare(Unitype) Autoarr_declare(Unitype)
#define Autoarr_foreach(ar, elem, codeblock...) { \
if(ar->blocks_count>0) { \
typeof(**ar->values) elem; \
for(u16 blockI=0;blockI<ar->blocks_count-1;blockI++) \
for(u32 elemI=0;elemI<ar->max_block_length;elemI++){ \
elem=ar->values[blockI][elemI]; \
{ codeblock; } \
} \
for(u16 elemI=0;elemI<ar->block_length;elemI++){ \
elem=ar->values[ar->blocks_count-1][elemI]; \
{ codeblock; } \
} \
} \
}
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,38 +0,0 @@
#if __cplusplus
extern "C" {
#endif
#include "Autoarr.h"
#include "../Hashtable/KeyValuePair.h"
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_blocks_count, u16 max_block_length, Autoarr_KVPair** output){
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
}
EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, u32 index, KVPair* output){
*output=Autoarr_get(ar, index);
}
EXPORT void CALL kerep_Autoarr_KVPair_add(Autoarr_KVPair* ar, KVPair element){
Autoarr_add(ar, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, u32 index, KVPair element){
Autoarr_set(ar, index, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_length(ar);
}
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_max_length(ar);
}
#if __cplusplus
}
#endif

View File

@@ -4,12 +4,12 @@ extern "C" {
#include "Autoarr.h" #include "Autoarr.h"
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_blocks_count, u16 max_block_length, Autoarr_Unitype** output){ EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_chunks_count, u16 max_chunk_length, Autoarr_Unitype** output){
*output=Autoarr_create(Unitype, max_blocks_count, max_block_length); *output=Autoarr_construct(Unitype, max_chunks_count, max_chunk_length);
} }
EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){ EXPORT void CALL kerep_Autoarr_Unitype_destruct(Autoarr_Unitype* ar){
Autoarr_free(ar, true); Autoarr_destruct(ar, true);
} }
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){ EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){
@@ -34,4 +34,4 @@ EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, u32* outp
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -6,69 +6,62 @@ extern "C" {
#include "../base/base.h" #include "../base/base.h"
#define Autoarr_declare(type) \ #define Autoarr_declare(TYPE) \
\ \
struct Autoarr_##type; \ typedef struct Autoarr_##TYPE Autoarr_##TYPE; \
\ \
typedef struct __Autoarr_##type##_functions_list_t { \ typedef struct __Autoarr_##TYPE##_functions_list_t { \
void (*add)(struct Autoarr_##type* ar, type element); \ void (*add)(Autoarr_##TYPE* ar, TYPE element); \
type (*get)(struct Autoarr_##type* ar, u32 index); \ TYPE (*get)(Autoarr_##TYPE* ar, u32 index); \
type* (*getPtr)(struct Autoarr_##type* ar, u32 index); \ TYPE* (*getPtr)(Autoarr_##TYPE* ar, u32 index); \
void (*set)(struct Autoarr_##type* ar, u32 index, type element); \ void (*set)(Autoarr_##TYPE* ar, u32 index, TYPE element); \
void (*freeWithMembers)(struct Autoarr_##type* ar, bool freePtr); \ TYPE* (*toArray)(Autoarr_##TYPE* ar, allocator_ptr array_holder); \
void (*freeWithoutMembers)(struct Autoarr_##type* ar, bool freePtr); \ } __Autoarr_##TYPE##_functions_list_t; \
type* (*toArray)(struct Autoarr_##type* ar); \
} __Autoarr_##type##_functions_list_t; \
\ \
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \ STRUCT(Autoarr_##TYPE, \
\ InternalAllocator_declare(LinearAllocator); \
STRUCT(Autoarr_##type, \ __Autoarr_##TYPE##_functions_list_t* functions; \
u16 blocks_count; \ ktDescriptor* type; \
u16 max_blocks_count; \ u32 length; \
u16 block_length; \ TYPE* _typeof_target; \
u16 max_block_length; \
type** values; \
__Autoarr_##type##_functions_list_t* functions; \
) \ ) \
\ \
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \ void __Autoarr_##TYPE##_construct(Autoarr_##TYPE* ar, alloc_size_t starting_size, allocator_ptr external_al); \
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \ void __Autoarr_##TYPE##_destruct(Autoarr_##TYPE* ar); \
void ____Autoarr_##type##_freeWithMembers(void* ar);
#define Autoarr(type) Autoarr_##type #define Autoarr(TYPE) Autoarr_##TYPE
#define Autoarr_create(type, max_blocks_count, max_block_length) \ #define Autoarr_construct(ptr, TYPE, starting_size, data_allocator) \
__Autoarr_##type##_create(max_blocks_count, max_block_length) __Autoarr_##TYPE##_construct(ptr, starting_size, data_allocator)
#define Autoarr_add(autoarr, element) \ #define Autoarr_destruct(autoarr) (autoarr)->type->destruct(autoarr)
autoarr->functions->add(autoarr, element) #define Autoarr_add(autoarr, element) (autoarr)->functions->add(autoarr, element)
#define Autoarr_get(autoarr, index) \ #define Autoarr_get(autoarr, index) (autoarr)->functions->get(autoarr,index)
autoarr->functions->get(autoarr,index) #define Autoarr_getPtr(autoarr, index) (autoarr)->functions->getPtr(autoarr,index)
#define Autoarr_getPtr(autoarr, index) \ #define Autoarr_set(autoarr, index, element) (autoarr)->functions->set(autoarr, index, element)
autoarr->functions->getPtr(autoarr,index) #define Autoarr_toArray(autoarr, array_alloctr) (autoarr)->functions->toArray(autoarr, array_alloctr)
#define Autoarr_set(autoarr, index, element) \ #define Autoarr_length(autoarr) (autoarr)->length
autoarr->functions->set(autoarr, index, element) #define Autoarr_pop(autoarr) { \
#define Autoarr_free(autoarr, freePtr) \ u32 new_len=(autoarr)->length-1; \
autoarr->functions->freeWithMembers(autoarr, freePtr) allocator_free(InternalAllocator_getPtr((autoarr)), Autoarr_getPtr((autoarr), new_len)); \
#define Autoarr_freeWithoutMembers(autoarr, freePtr) \ (autoarr)->length=new_len; \
autoarr->functions->freeWithoutMembers(autoarr, freePtr) }
#define Autoarr_toArray(autoarr) \
autoarr->functions->toArray(autoarr)
#define Autoarr_length(autoarr) \ #define Autoarr_foreach(ar, elem, codeblock...) { \
(u32)(!autoarr->blocks_count ? 0 : \ if((ar)->length > 0) { \
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length) typeof(*((ar)->_typeof_target)) elem; \
#define Autoarr_max_length(autoarr) \ LinearAllocator* al=(LinearAllocator*)InternalAllocator_getPtr(ar); \
(u32)(autoarr->max_block_length*autoarr->max_blocks_count) for(u16 chunk_i=0; chunk_i <= al->curr_chunk_i; chunk_i++) { \
MemoryChunk chunk = al->chunks[chunk_i]; \
#define Autoarr_pop(AR){ \ alloc_size_t chunk_elem_count = chunk.occupied_size/sizeof(elem); \
if(AR->block_length==1){ \ typeof((ar)->_typeof_target) chunk_data = (void*)chunk.data; \
AR->blocks_count--; \ for(u32 elem##_i=0; elem##_i < chunk_elem_count; elem##_i++) { \
AR->block_length=AR->max_block_length; \ elem = chunk_data[elem##_i]; \
free(AR->values[AR->blocks_count]); \ { codeblock; } \
} \
} \
} \ } \
else AR->block_length--; \
} }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -6,95 +6,73 @@ extern "C" {
#include "../base/base.h" #include "../base/base.h"
#define Autoarr_define(type, TYPE_IS_PTR) \ #define Autoarr_define(TYPE) \
\ \
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \ void __Autoarr_##TYPE##_add(Autoarr_##TYPE* ar, TYPE element){ \
TYPE* ptr = allocator_alloc(InternalAllocator_getPtr(ar), sizeof(element)); \
*ptr=element; \
ar->length++; \
} \
\ \
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \ TYPE* __Autoarr_##TYPE##_getPtr(Autoarr_##TYPE* ar, u32 index){ \
if(!ar->values){ \ if(index >= Autoarr_length(ar)) \
ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \ throw(ERR_WRONGINDEX); \
goto create_block; \ u32 elem_count_sum=0; \
LinearAllocator* al=(LinearAllocator*)InternalAllocator_getPtr(ar); \
for(u16 chunk_i=0; chunk_i <= al->curr_chunk_i; chunk_i++) { \
MemoryChunk chunk = al->chunks[chunk_i]; \
alloc_size_t chunk_elem_count = chunk.occupied_size/sizeof(TYPE); \
alloc_size_t chunk_elem_i = index - elem_count_sum; \
if(chunk_elem_i < chunk_elem_count){ \
return chunk.data + chunk_elem_i*sizeof(TYPE); \
} \
elem_count_sum += chunk_elem_count; \
} \ } \
if(ar->block_length==ar->max_block_length){ \ return NULL; \
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH); \
ar->block_length=0; \
create_block: \
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type)); \
ar->blocks_count++; \
} \
ar->values[ar->blocks_count-1][ar->block_length]=element; \
ar->block_length++; \
} \ } \
\ \
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \ TYPE __Autoarr_##TYPE##_get(Autoarr_##TYPE* ar, u32 index){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \ TYPE* ptr=__Autoarr_##TYPE##_getPtr(ar, index); \
return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \ return *ptr; \
} \ } \
\ \
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \ void __Autoarr_##TYPE##_set(Autoarr_##TYPE* ar, u32 index, TYPE value){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \ TYPE* ptr=__Autoarr_##TYPE##_getPtr(ar, index); \
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \ *ptr=value; \
} \ } \
\ \
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \ void __Autoarr_##TYPE##_destruct(Autoarr_##TYPE* ar){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \ InternalAllocator_destructIfInternal(LinearAllocator, ar); \
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element; \
} \ } \
\ \
void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \ TYPE* __Autoarr_##TYPE##_toArray(Autoarr_##TYPE* ar, allocator_ptr array_alloctr){ \
for(u16 i=0; i<ar->blocks_count;i++) \
free(ar->values[i]); \
free(ar->values); \
if(freePtr) free(ar); \
} \
\
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr){ \
if(ktDescriptor_##type.freeMembers!=NULL) { \
Autoarr_foreach(ar, el, \
void* members_ptr=&el; \
if(TYPE_IS_PTR) members_ptr=*(type**)members_ptr; \
ktDescriptor_##type.freeMembers(members_ptr); \
); \
} \
__Autoarr_##type##_freeWithoutMembers(ar, freePtr);\
} \
void ____Autoarr_##type##_freeWithMembers(void* ar){ \
__Autoarr_##type##_freeWithMembers((Autoarr_##type*)ar, false); \
} \
\
type* __Autoarr_##type##_toArray(Autoarr_##type* ar){ \
u32 length=Autoarr_length(ar); \ u32 length=Autoarr_length(ar); \
if(length==0) \ if(length==0) \
return NULL; \ return NULL; \
type* array=malloc(length * sizeof(type)); \ TYPE* array=allocator_alloc(array_alloctr, length); \
for(u32 i=0; i<length; i++) \ Autoarr_foreach(ar, el, { \
array[i]=__Autoarr_##type##_get(ar, i); \ array[el_i]=el; \
}); \
return array; \ return array; \
} \ } \
\ \
__Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \ __Autoarr_##TYPE##_functions_list_t __Autoarr_##TYPE##_functions_list={ \
&__Autoarr_##type##_add, \ &__Autoarr_##TYPE##_add, \
&__Autoarr_##type##_get, \ &__Autoarr_##TYPE##_get, \
&__Autoarr_##type##_getPtr, \ &__Autoarr_##TYPE##_getPtr, \
&__Autoarr_##type##_set, \ &__Autoarr_##TYPE##_set, \
&__Autoarr_##type##_freeWithMembers, \ &__Autoarr_##TYPE##_toArray \
&__Autoarr_##type##_freeWithoutMembers, \
&__Autoarr_##type##_toArray \
}; \ }; \
\ \
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length){ \ void __Autoarr_##TYPE##_construct(Autoarr_##TYPE* ar, alloc_size_t starting_size, allocator_ptr data_allocator){ \
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \ InternalAllocator_setExternalOrConstruct(ar, data_allocator, LinearAllocator, starting_size); \
*ar=(Autoarr_##type){ \ ar->functions=&__Autoarr_##TYPE##_functions_list; \
.max_blocks_count=max_blocks_count, \ ar->type = &ktDescriptor_name(TYPE); \
.blocks_count=0, \ ar->length=0; \
.max_block_length=max_block_length, \ } \
.block_length=0, \ \
.values=NULL, \ kt_define(Autoarr_##TYPE, (destruct_t)__Autoarr_##TYPE##_destruct, NULL);
.functions=&__Autoarr_##type##_functions_list \
}; \
return ar; \
}
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -25,6 +25,6 @@ bool DtsodV24_remove(Hashtable* dtsod, char* key){
} }
// frees memory including memory of elements (hashtables, autoarrs, etc.) // frees memory including memory of elements (hashtables, autoarrs, etc.)
void DtsodV24_free(Hashtable* dtsod){ void DtsodV24_destruct(Hashtable* dtsod){
Hashtable_free(dtsod); Hashtable_destruct(dtsod);
} }

View File

@@ -25,8 +25,8 @@ bool DtsodV24_contains(Hashtable* dtsod, char* key);
bool DtsodV24_remove(Hashtable* dtsod, char* key); bool DtsodV24_remove(Hashtable* dtsod, char* key);
// frees memory including memory of elements (hashtables, autoarrs, etc.) // frees memory including memory of elements (hashtables, autoarrs, etc.)
void DtsodV24_free(Hashtable* dtsod); void DtsodV24_destruct(Hashtable* dtsod);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,8 +1,7 @@
#include "DtsodV24.h" #include "DtsodV24.h"
#include "../String/StringBuilder.h" #include "../String/StringBuilder.h"
#define ARR_BC 64 #define ARR_SZ_START 64
#define ARR_BL 1024
typedef struct DeserializeSharedData{ typedef struct DeserializeSharedData{
@@ -10,11 +9,13 @@ typedef struct DeserializeSharedData{
char* sh_text; char* sh_text;
bool sh_partOfDollarList; bool sh_partOfDollarList;
bool sh_calledRecursively; bool sh_calledRecursively;
allocator_ptr sh_tmp_al;
} DeserializeSharedData; } DeserializeSharedData;
#define text shared->sh_text #define text shared->sh_text
#define partOfDollarList shared->sh_partOfDollarList #define partOfDollarList shared->sh_partOfDollarList
#define calledRecursively shared->sh_calledRecursively #define calledRecursively shared->sh_calledRecursively
#define tmp_al shared->sh_tmp_al
// special func for throwing error messages about wrong characters in deserializing text // special func for throwing error messages about wrong characters in deserializing text
@@ -44,16 +45,10 @@ Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* s
if(!_c) break; if(!_c) break;
} }
char errmsg[1024]; char errmsg[1024];
IFMSC( sprintf_s(errmsg, sizeof(errmsg), "unexpected <%c> at:\n"
sprintf_s(errmsg,1024, "unexpected <%c> at:\n" " \"%s\"\n"
" \"%s\"\n" "\\___[%s:%d] %s()",
"\\___[%s:%d] %s()", c,errBuf, srcfile,line,funcname);
c,errBuf, srcfile,line,funcname),
sprintf(errmsg, "unexpected <%c> at:\n"
" \"%s\"\n"
" \\___[%s:%d] %s()",
c,errBuf, srcfile,line,funcname)
);
safethrow(errmsg,;); safethrow(errmsg,;);
} }
#define safethrow_wrongchar(C, freeMem) { freeMem; return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__); } #define safethrow_wrongchar(C, freeMem) { freeMem; return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__); }
@@ -96,11 +91,11 @@ Maybe __ReadName(DeserializeSharedData* shared){
nameStr.ptr=text+1; // skips '\n' nameStr.ptr=text+1; // skips '\n'
break; break;
case '}': case '}':
if(!calledRecursively || nameStr.length!=0) if(!calledRecursively || nameStr.length!=0)
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
return SUCCESS(UniHeapPtr(char,NULL)); return SUCCESS(UniHeapPtr(char,NULL));
case ':': case ':':
return SUCCESS(UniHeapPtr(char,string_extract(nameStr))); return SUCCESS(UniHeapPtr(char,string_extract(tmp_al, nameStr)));
case '$': case '$':
if(nameStr.length!=0) if(nameStr.length!=0)
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
@@ -117,7 +112,7 @@ Maybe __ReadName(DeserializeSharedData* shared){
} }
#define ReadName() __ReadName(shared) #define ReadName() __ReadName(shared)
Maybe __deserialize(char** _text, bool _calledRecursively); Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al);
Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList); Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList);
#define ReadValue(rL) __ReadValue(shared, rL) #define ReadValue(rL) __ReadValue(shared, rL)
@@ -125,13 +120,15 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList);
Maybe __ReadString(DeserializeSharedData* shared){ Maybe __ReadString(DeserializeSharedData* shared){
char c; char c;
bool prevIsBackslash=false; bool prevIsBackslash=false;
StringBuilder* b=StringBuilder_create(); StringBuilder _sb;
StringBuilder* b=&_sb;
StringBuilder_construct(b, tmp_al);
while ((c=*++text)){ while ((c=*++text)){
if(c=='"') { if(c=='"') {
if(prevIsBackslash) { if(prevIsBackslash) {
// replacing <\"> with <"> // replacing <\"> with <">
StringBuilder_rmchar(b); StringBuilder_rmchar(b);
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
prevIsBackslash=false; prevIsBackslash=false;
} }
@@ -139,31 +136,32 @@ Maybe __ReadString(DeserializeSharedData* shared){
char* str=StringBuilder_build(b).ptr; char* str=StringBuilder_build(b).ptr;
return SUCCESS(UniHeapPtr(char,str)); return SUCCESS(UniHeapPtr(char,str));
} }
} }
else { else {
prevIsBackslash= c=='\\' && !prevIsBackslash; prevIsBackslash= c=='\\' && !prevIsBackslash;
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
} }
} }
safethrow(ERR_ENDOFSTR, StringBuilder_free(b)); safethrow(ERR_ENDOFSTR, StringBuilder_destruct(b));
} }
#define ReadString() __ReadString(shared) #define ReadString() __ReadString(shared)
Maybe __ReadList(DeserializeSharedData* shared){ Maybe __ReadList(DeserializeSharedData* shared){
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL); Autoarr(Unitype) list;
Autoarr_construct(&list, Unitype, ARR_SZ_START, NULL);
bool readingList=true; bool readingList=true;
while (true){ while (true){
try(ReadValue((&readingList)), m_val, Autoarr_free(list, true)) try(ReadValue((&readingList)), m_val, Autoarr_destruct(&list))
Autoarr_add(list,m_val.value); Autoarr_add(&list, m_val.value);
if (!readingList){ if (!readingList){
if(Unitype_isUniNull(m_val.value)) if(Unitype_isUniNull(m_val.value))
Autoarr_pop(list); Autoarr_pop(&list);
break; break;
} }
} }
return SUCCESS(UniHeapPtr(Autoarr_Unitype,list)); return SUCCESS(UniHeapPtr(Autoarr_Unitype, &list));
}; };
#define ReadList() __ReadList(shared) #define ReadList() __ReadList(shared)
@@ -181,40 +179,34 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
else safethrow_wrongchar(*str.ptr,;); else safethrow_wrongchar(*str.ptr,;);
// Float64 // Float64
case 'f': { case 'f': {
char* _c=string_extract(str); char* _c=string_extract(tmp_al, str);
Unitype rez=UniFloat64(strtod(_c,NULL)); Unitype rez=UniFloat64(strtod(_c,NULL));
free(_c); // allocator_free(tmp_al,_c);
return SUCCESS(rez); return SUCCESS(rez);
} }
// UInt64 // UInt64
case 'u': { case 'u': {
u64 lu=0; u64 lu=0;
char* _c=string_extract(str); char* _c=string_extract(tmp_al, str);
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){ if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
char err[64]; char err[64];
IFMSC( sprintf_s(err, sizeof(err), "can't parse to int: <%s>", _c);
sprintf_s(err,64,"can't parse to int: <%s>",_c), safethrow(err, /*allocator_free(tmp_al, _c)*/);
sprintf(err,"can't parse to int: <%s>",_c)
);
safethrow(err,free(_c));
} }
free(_c); // allocator_free(tmp_al, _c);
return SUCCESS(UniUInt64(lu)); return SUCCESS(UniUInt64(lu));
} }
// Int64 // Int64
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
i64 li=0; i64 li=0;
char* _c=string_extract(str); char* _c=string_extract(tmp_al, str);
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){ if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
char err[64]; char err[64];
IFMSC( sprintf_s(err, sizeof(err),"can't parse to int: <%s>",_c);
sprintf_s(err,64,"can't parse to int: <%s>",_c), // safethrow(err,allocator_free(tmp_al, _c));
sprintf(err,"can't parse to int: <%s>",_c)
);
safethrow(err,free(_c));
} }
free(_c); // allocator_free(tmp_al, _c);
return SUCCESS(UniInt64(li)); return SUCCESS(UniInt64(li));
} }
// wrong type // wrong type
@@ -239,53 +231,53 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
spaceAfterVal=true; spaceAfterVal=true;
else valueStr.ptr++; else valueStr.ptr++;
break; break;
case '=': case ':': case '=': case ':':
case '}': case '$': case '}': case '$':
case '\'': case '\'':
safethrow_wrongchar(c,Unitype_free(value)); safethrow_wrongchar(c,Unitype_destruct(&value));
case '#':; case '#':;
char _c=c; char _c=c;
char* _text=text; char* _text=text;
try(SkipComment(),_,;); try(SkipComment(),_,;);
if(valueStr.length!=0){ if(valueStr.length!=0){
text=_text; text=_text;
safethrow_wrongchar(_c,Unitype_free(value)); safethrow_wrongchar(_c,Unitype_destruct(&value));
} }
valueStr.ptr=text+1; // skips '\n' valueStr.ptr=text+1; // skips '\n'
break; break;
case '"': case '"':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value));
try(ReadString(),maybeString,;) try(ReadString(),maybeString,;)
value=maybeString.value; value=maybeString.value;
break; break;
case '{': case '{':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value));
++text; // skips '{' ++text; // skips '{'
try(__deserialize(&text,true), val,Unitype_free(value)) try(__deserialize(&text,true,tmp_al), val, Unitype_destruct(&value))
value=val.value; value=val.value;
break; break;
case '[': case '[':
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value)); if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_destruct(&value));
try(ReadList(),maybeList,Unitype_free(value)) try(ReadList(),maybeList,Unitype_destruct(&value))
value=maybeList.value; value=maybeList.value;
break; break;
case ']': case ']':
if(!readingList) safethrow_wrongchar(c,Unitype_free(value)); if(!readingList) safethrow_wrongchar(c,Unitype_destruct(&value));
*readingList=false; *readingList=false;
goto return_value; goto return_value;
case ';': case ';':
case ',': case ',':
return_value: return_value:
if(valueStr.length!=0){ if(valueStr.length!=0){
if(!Unitype_isUniNull(value)) if(!Unitype_isUniNull(value))
safethrow_wrongchar(c,Unitype_free(value)); safethrow_wrongchar(c,Unitype_destruct(&value));
try(ParseValue(valueStr),maybeParsed,;) try(ParseValue(valueStr),maybeParsed,;)
value=maybeParsed.value; value=maybeParsed.value;
} }
return SUCCESS(value); return SUCCESS(value);
default: default:
if(spaceAfterVal) if(spaceAfterVal)
safethrow_wrongchar(c,Unitype_free(value)); safethrow_wrongchar(c,Unitype_destruct(&value));
valueStr.length++; valueStr.length++;
break; break;
} }
@@ -294,25 +286,29 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
} }
Maybe __deserialize(char** _text, bool _calledRecursively) { Maybe __deserialize(char** _text, bool _calledRecursively, allocator_ptr _tmp_al) {
DeserializeSharedData _shared={ DeserializeSharedData _shared={
.sh_text_first=*_text, .sh_text_first=*_text,
.sh_text=*_text, .sh_text=*_text,
.sh_partOfDollarList=false, .sh_partOfDollarList=false,
.sh_calledRecursively=_calledRecursively .sh_calledRecursively=_calledRecursively,
.sh_tmp_al=_tmp_al
}; };
DeserializeSharedData* shared=&_shared; DeserializeSharedData* shared=&_shared;
Hashtable* dict=Hashtable_create(); Hashtable _dict;
Hashtable* dict = &_dict;
Hashtable_construct(dict, _tmp_al);
text--; text--;
while(true){ while(true){
try(ReadName(), maybeName, Hashtable_free(dict)) try(ReadName(), maybeName, Hashtable_destruct(dict))
if(!maybeName.value.VoidPtr) // end of file or '}' in recursive call if(!maybeName.value.VoidPtr) // end of file or '}' in recursive call
goto END; goto END;
char* nameCPtr=maybeName.value.VoidPtr; char* nameCPtr=maybeName.value.VoidPtr;
try(ReadValue(NULL), val, { try(ReadValue(NULL), val, {
Hashtable_free(dict); Hashtable_destruct(dict);
free(nameCPtr); // do not use, free call order is incorrect
// allocator_free(tmp_al, nameCPtr);
}) { }) {
if(partOfDollarList){ if(partOfDollarList){
partOfDollarList=false; partOfDollarList=false;
@@ -322,10 +318,12 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
list=(Autoarr(Unitype)*)lu.VoidPtr; list=(Autoarr(Unitype)*)lu.VoidPtr;
// Key is not used in that case, because it is already added // Key is not used in that case, because it is already added
// to the table with the first dollar list item. // to the table with the first dollar list item.
free(nameCPtr); // do not use, free call order is incorrect
// allocator_free(tmp_al, nameCPtr);
} }
else{ else{
list=Autoarr_create(Unitype,ARR_BC,ARR_BL); list=allocator_alloc(tmp_al, sizeof(*list));
Autoarr_construct(list, Unitype, ARR_SZ_START, NULL);
Hashtable_add(dict,nameCPtr,UniHeapPtr(Autoarr_Unitype,list)); Hashtable_add(dict,nameCPtr,UniHeapPtr(Autoarr_Unitype,list));
} }
Autoarr_add(list,val.value); Autoarr_add(list,val.value);
@@ -340,5 +338,9 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
} }
Maybe DtsodV24_deserialize(char* _text) { Maybe DtsodV24_deserialize(char* _text) {
return __deserialize(&_text, false); LinearAllocator _tmp_al;
LinearAllocator_construct(&_tmp_al, 1024);
Maybe m=__deserialize(&_text, false, (allocator_ptr)&_tmp_al);
LinearAllocator_destruct(&_tmp_al);
return m;
} }

View File

@@ -1,62 +0,0 @@
//
// I planned to export functions from DtsodV24.h,
// but C# P/Invoke can't get returned values for some reason.
// Following functions return values by pointer, which looks in C# like out parameter
//
#if __cplusplus
extern "C" {
#endif
#include "DtsodV24.h"
// parses text to binary values
EXPORT void CALL kerep_DtsodV24_deserialize(char* text, Hashtable** output, char** errmsg){
Maybe r=DtsodV24_deserialize(text);
*errmsg=r.errmsg;
*output=r.value.VoidPtr;
}
// creates text representation of dtsod
EXPORT void CALL kerep_DtsodV24_serialize(Hashtable* dtsod, char** output, char** errmsg){
Maybe r=DtsodV24_serialize(dtsod);
*errmsg=r.errmsg;
*output=r.value.VoidPtr;
}
// returns value or UniNull if key not found
EXPORT void CALL kerep_DtsodV24_get(Hashtable* dtsod, char* key, Unitype* output){
*output=DtsodV24_get(dtsod, key);
}
// adds or sets the value
EXPORT void CALL kerep_DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){
DtsodV24_addOrSet(dtsod, key, value);
}
// checks for dtsod contains value or dont
EXPORT void CALL kerep_DtsodV24_contains(Hashtable* dtsod, char* key, bool* output){
*output=DtsodV24_contains(dtsod, key);
}
// replaces value with UniNull if key exists in dtsod
EXPORT void CALL kerep_DtsodV24_remove(Hashtable* dtsod, char* key, bool* output){
*output=DtsodV24_remove(dtsod, key);
}
// replaces value with UniNull if key exists in dtsod
EXPORT void CALL kerep_DtsodV24_free(Hashtable* dtsod){
DtsodV24_free(dtsod);
}
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, u16* heigth){
*heigth=Hashtable_height(dtsod);
}
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, u16 h, Autoarr_KVPair** row){
*row=dtsod->rows[h];
}
#if __cplusplus
}
#endif

View File

@@ -3,7 +3,7 @@
STRUCT(SerializeSharedData, STRUCT(SerializeSharedData,
StringBuilder* sh_builder; StringBuilder* sh_builder;
u8 sh_tabs; u8 sh_tabs;
) )
#define b shared->sh_builder #define b shared->sh_builder
@@ -55,7 +55,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
AppendTabs(); AppendTabs();
addc('['); addc('[');
tabs++; tabs++;
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e,
addc('\n'); addc('\n');
AppendTabs(); AppendTabs();
try(AppendValue(e),__,;); try(AppendValue(e),__,;);
@@ -75,7 +75,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
else if(u.typeId==ktid_ptrName(Hashtable)){ else if(u.typeId==ktid_ptrName(Hashtable)){
// check hashtable is blank // check hashtable is blank
bool hashtableNotBlank=false; bool hashtableNotBlank=false;
Hashtable_foreach(((Hashtable*)u.VoidPtr), __, Hashtable_foreach(((Hashtable*)u.VoidPtr), __,
hashtableNotBlank=true; hashtableNotBlank=true;
if(__.key) {} // weird way to disable warning if(__.key) {} // weird way to disable warning
break; break;
@@ -96,7 +96,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
} }
} }
else { else {
dbg((u.typeId)); dbg((u.typeId));
safethrow(ERR_WRONGTYPE,;); safethrow(ERR_WRONGTYPE,;);
} }
return MaybeNull; return MaybeNull;
@@ -109,7 +109,7 @@ Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
}; };
SerializeSharedData* shared=&_shared; SerializeSharedData* shared=&_shared;
Hashtable_foreach(dtsod, p, Hashtable_foreach(dtsod, p,
AppendTabs(); AppendTabs();
StringBuilder_append_cptr(b,p.key); StringBuilder_append_cptr(b,p.key);
addc(':'); addc(':');
@@ -123,8 +123,13 @@ Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
} }
Maybe DtsodV24_serialize(Hashtable* dtsod){ Maybe DtsodV24_serialize(Hashtable* dtsod){
StringBuilder* sb=StringBuilder_create(); LinearAllocator _al; allocator_ptr al=(allocator_ptr)&_al;
try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb)); LinearAllocator_construct(&_al, 512);
StringBuilder _sb;
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
try(__serialize(sb,0,dtsod),__, StringBuilder_destruct(sb); LinearAllocator_destruct(&_al););
char* str=StringBuilder_build(sb).ptr; char* str=StringBuilder_build(sb).ptr;
LinearAllocator_destruct(&_al);
return SUCCESS(UniHeapPtr(char, str)); return SUCCESS(UniHeapPtr(char, str));
} }

View File

@@ -4,7 +4,7 @@
bool dir_exists(const char* path){ bool dir_exists(const char* path){
if(path[0]=='.'){ if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[1]==0)) if(path[1]==0 || (path[1]==path_sep && path[1]==0))
return true; // dir . or ./ always exists return true; // dir . or ./ always exists
// else if(path[1]=='.' && path[2]==path_sep) // else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern //TODO path_resolve because windows doesnt recognize .\ pattern
@@ -26,9 +26,10 @@ bool dir_exists(const char* path){
Maybe dir_create(const char* path){ Maybe dir_create(const char* path){
if (dir_exists(path)) if (dir_exists(path))
return MaybeNull; return MaybeNull;
char* parentDir=path_parentDir(path); LinearAllocator _al; LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
char* parentDir=path_parentDir(al, path);
dir_create(parentDir); dir_create(parentDir);
free(parentDir);
#if KFS_USE_WINDOWS_H #if KFS_USE_WINDOWS_H
if(!CreateDirectory(path, NULL)) if(!CreateDirectory(path, NULL))
#else #else
@@ -36,12 +37,10 @@ Maybe dir_create(const char* path){
#endif #endif
{ {
char err[512]; char err[512];
IFWIN( sprintf_s(err, sizeof(err), "can't create dicectory <%s>", path);
sprintf_s(err, 512, "can't create dicectory <%s>", path), safethrow(err, LinearAllocator_destruct(&_al));
sprintf(err, "can't create dicectory <%s>", path));
safethrow(err,;);
} }
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }

View File

@@ -25,4 +25,4 @@ Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -2,9 +2,9 @@
#include "../String/StringBuilder.h" #include "../String/StringBuilder.h"
#include "io_includes.h" #include "io_includes.h"
void __file_freeMembers(void* _f){ fclose((FileHandle)_f); } void __file_destructMembers(void* _f){ fclose((FileHandle)_f); }
kt_define(FileHandle, __file_freeMembers, NULL) kt_define(FileHandle, __file_destructMembers, NULL)
bool file_exists(const char* path){ bool file_exists(const char* path){
if(path[0]=='.'){ if(path[0]=='.'){
@@ -50,8 +50,11 @@ char* FileOpenMode_toStr(FileOpenMode m){
Maybe file_open(const char* path, FileOpenMode mode){ Maybe file_open(const char* path, FileOpenMode mode){
FileHandle file=fopen(path, FileOpenMode_toStr(mode)); FileHandle file=fopen(path, FileOpenMode_toStr(mode));
LinearAllocator _al; LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
if(!file) if(!file)
safethrow(cptr_concat("can't open file ", (char*)path),;); safethrow(cptr_concat(al, "can't open file ", (char*)path), LinearAllocator_destruct(&_al));
LinearAllocator_destruct(&_al);
return SUCCESS(UniHeapPtr(FileHandle,file)); return SUCCESS(UniHeapPtr(FileHandle,file));
} }
@@ -112,13 +115,15 @@ Maybe file_readAll(FileHandle file, char** allBytes){
i32 rezult=0; i32 rezult=0;
char buffer[256]; char buffer[256];
string bufStr={.ptr=buffer, .length=sizeof(buffer)}; string bufStr={.ptr=buffer, .length=sizeof(buffer)};
StringBuilder* sb=StringBuilder_create(); StringBuilder _sb;
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, NULL);
u64 i=0; u64 i=0;
while(true){ while(true){
rezult=fgetc(file); rezult=fgetc(file);
if(rezult==EOF){ if(rezult==EOF){
if(ferror(file)) if(ferror(file))
safethrow(ERR_IO, StringBuilder_free(sb)); safethrow(ERR_IO, StringBuilder_destruct(sb));
break; break;
} }
buffer[i%sizeof(buffer)]=(char)rezult; buffer[i%sizeof(buffer)]=(char)rezult;
@@ -132,7 +137,7 @@ Maybe file_readAll(FileHandle file, char** allBytes){
string str=StringBuilder_build(sb); string str=StringBuilder_build(sb);
*allBytes=str.ptr; *allBytes=str.ptr;
// i dont know how can it happen, but if it will have, it will be very dangerous // i dont know how can it happen, but if it will have, it will be very dangerous
if(i!=str.length) if(i!=str.length)
throw(ERR_UNEXPECTEDVAL); throw(ERR_UNEXPECTEDVAL);
return SUCCESS(UniUInt64(i)); return SUCCESS(UniUInt64(i));
} }

View File

@@ -5,7 +5,6 @@ extern "C" {
#endif #endif
#include "../base/base.h" #include "../base/base.h"
#include "../Array/Array.h"
#include "../String/string.h" #include "../String/string.h"
typedef FILE* FileHandle; typedef FILE* FileHandle;
@@ -17,15 +16,15 @@ bool file_exists(const char* path);
Maybe file_delete(const char* path, bool recursive); Maybe file_delete(const char* path, bool recursive);
PACKED_ENUM(FileOpenMode, PACKED_ENUM(FileOpenMode,
// open a file for reading // open a file for reading
FileOpenMode_Read=1, FileOpenMode_Read=1,
// (re)create a file for writing // (re)create a file for writing
FileOpenMode_Write=2, FileOpenMode_Write=2,
// opens file for writing additional data to the end / creates new file // opens file for writing additional data to the end / creates new file
FileOpenMode_Append=4, FileOpenMode_Append=4,
// (re)creates file for reading/writing // (re)creates file for reading/writing
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write, FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
// opens file for readng/writing additional data to the end / creates new file // opens file for readng/writing additional data to the end / creates new file
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
) )
@@ -67,10 +66,10 @@ Maybe file_readChar(FileHandle file);
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length); Maybe file_readBuffer(FileHandle file, char* buffer, u64 length);
/// @brief reads all bytes from file /// @brief reads all bytes from file
/// @param allBytes ptr to the file's content will be pushed there /// @param allBytes ptr to the file's content will be pushed there
/// @return Maybe<u64> total number of successfully read bytes /// @return Maybe<u64> total number of successfully read bytes
Maybe file_readAll(FileHandle file, char** allBytes); Maybe file_readAll(FileHandle file, char** allBytes);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -2,7 +2,7 @@
#if defined(_WIN64) || defined(_WIN32) #if defined(_WIN64) || defined(_WIN32)
#define KFS_USE_WINDOWS_H 1 #define KFS_USE_WINDOWS_H 1
#else #else
#define KFS_USE_WINDOWS_H 0 #define KFS_USE_WINDOWS_H 0
#endif #endif

View File

@@ -1,8 +1,8 @@
#include "filesystem.h" #include "filesystem.h"
char* __path_concat(u32 n, ...){ char* __path_concat(allocator_ptr al, u32 n, ...){
char** parts=(char**)malloc(n*sizeof(char*)); char** parts=(char**)allocator_alloc(al, n*sizeof(char*));
u32* lengths=malloc(n*sizeof(u32)); u32* lengths=allocator_alloc(al, n*sizeof(u32));
u32 totalLength=0; u32 totalLength=0;
// reading args from va_list // reading args from va_list
@@ -18,27 +18,27 @@ char* __path_concat(u32 n, ...){
va_end(vl); va_end(vl);
// allocating memory for output value // allocating memory for output value
char* totality=malloc(totalLength+1); char* totality=allocator_alloc(al, totalLength+1);
const char* output=totality; const char* output=totality;
totality[totalLength]=0; totality[totalLength]=0;
// copying content of all strings to rezult // copying content of all strings to rezult
u16 k=0; u16 k=0;
for(; k<n-1; k++){ for(; k<n-1; k++){
memcopy(parts[k], totality, lengths[k]); memcpy(totality, parts[k], lengths[k]);
totality+=lengths[k]; totality+=lengths[k];
*totality=path_sep; *totality=path_sep;
totality++; totality++;
} }
memcopy(parts[k], totality, lengths[k]); memcpy(totality, parts[k], lengths[k]);
free(parts); allocator_free(al, lengths);
free(lengths); allocator_free(al, parts);
return output; return output;
} }
char* path_fixSeparators(const char* path){ char* path_fixSeparators(allocator_ptr al, const char* path){
char* pathCopy=cptr_copy(path); char* pathCopy=cptr_copy(al, path);
char c; char c;
while((c=*pathCopy)){ while((c=*pathCopy)){
if(c==path_notSep) if(c==path_notSep)
@@ -49,13 +49,17 @@ char* path_fixSeparators(const char* path){
} }
Maybe path_throwIfEscapes(const char* path){ Maybe path_throwIfEscapes(const char* path){
LinearAllocator _al; LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
if(cptr_contains(path,"..")) if(cptr_contains(path,".."))
safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),); safethrow(cptr_concat(al, "path <",path,"> uses <..>, that's not allowed"),
LinearAllocator_destruct(&_al));
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }
char* path_parentDir(char* dir){ char* path_parentDir(allocator_ptr al, char* dir){
char* copy=cptr_copy(dir); char* copy=cptr_copy(al, dir);
i32 length=cptr_length(copy); i32 length=cptr_length(copy);
i32 i=cptr_lastIndexOfChar(copy,path_sep); i32 i=cptr_lastIndexOfChar(copy,path_sep);
if(i!=-1 && i==length-1){ if(i!=-1 && i==length-1){
@@ -63,8 +67,8 @@ char* path_parentDir(char* dir){
i=cptr_lastIndexOfChar(copy,path_sep); i=cptr_lastIndexOfChar(copy,path_sep);
} }
if(i==-1){ if(i==-1){
free(copy); allocator_free(al, copy);
copy=malloc(2); copy=allocator_alloc(al, 2);
copy[0]='.'; copy[0]='.';
copy[1]=0; copy[1]=0;
} }
@@ -72,7 +76,7 @@ char* path_parentDir(char* dir){
} }
char* path_basename(char* path, bool with_extension){ char* path_basename(allocator_ptr al, char* path, bool with_extension){
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1; i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
string rezult=string_fromCptr(path+nameIndex); string rezult=string_fromCptr(path+nameIndex);
if(!with_extension){ if(!with_extension){
@@ -80,5 +84,5 @@ char* path_basename(char* path, bool with_extension){
if(extIndex!=0 && extIndex!=-1) if(extIndex!=0 && extIndex!=-1)
rezult.length=extIndex; rezult.length=extIndex;
} }
return string_extract(rezult); return string_extract(al, rezult);
} }

View File

@@ -14,17 +14,17 @@ static const char path_sep='/';
static const char path_notSep='\\'; static const char path_notSep='\\';
#endif #endif
char* __path_concat(u32 n, ...); char* __path_concat(allocator_ptr al, u32 n, ...);
/// @brief merges path parts together and puts <path_sep> between them /// @brief merges path parts together and puts <path_sep> between them
/// @return new cstr /// @return new cstr
#define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS) #define path_concat(ALLOCATOR, PATH_PARTS...) __path_concat(ALLOCATOR, count_args(PATH_PARTS), PATH_PARTS)
/// @brief fixes path separators /// @brief fixes path separators
/// @param cstr where can be <path_notSep> /// @param cstr where can be <path_notSep>
/// @return new cstr with correct separators /// @return new cstr with correct separators
char* path_fixSeparators(const char* path); char* path_fixSeparators(allocator_ptr al, const char* path);
#define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS)) #define path_resolve(ALLOCATOR, PATH_PARTS...) path_fixSeparators(ALLOCATOR, path_concat(ALLOCATOR, PATH_PARTS))
/// @brief calls safethrow() if finds escape sequense in path /// @brief calls safethrow() if finds escape sequense in path
/// @param path cstr where can be <..> /// @param path cstr where can be <..>
@@ -32,11 +32,11 @@ char* path_fixSeparators(const char* path);
Maybe path_throwIfEscapes(const char* path); Maybe path_throwIfEscapes(const char* path);
///@return path of parent dir ///@return path of parent dir
char* path_parentDir(char* path); char* path_parentDir(allocator_ptr al, char* path);
///@return file name ///@return file name
char* path_basename(char* path, bool with_extension); char* path_basename(allocator_ptr al, char* path, bool with_extension);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -9,68 +9,68 @@ u32 hash_sdbm32(u32 oldhash, void* buf, u32 len){
} }
static const u32 crc_32_tab[]={ static const u32 crc_32_tab[]={
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}; };

View File

@@ -14,4 +14,4 @@ u32 hash_crc32(u32 oldhash, void* buf, u32 len);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,74 +1,70 @@
#include "Hashtable.h" #include "Hashtable.h"
kt_define(Hashtable, __Hashtable_free, NULL); kt_define(Hashtable, __Hashtable_destruct, NULL);
// amount of rows // amount of rows
static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
#define HT_HEIN_MIN 0 #define HT_HEIN_MIN 0
#define HT_HEIN_MAX 6 #define HT_HEIN_MAX 6
#define ARR_BC 2 #define ARR_SIZE_MAX 16
#define ARR_BL 8
Hashtable* Hashtable_create(){ void Hashtable_construct(Hashtable* ht, allocator_ptr external_al){
Hashtable* ht=malloc(sizeof(Hashtable)); InternalAllocator_setExternalOrConstruct(ht, external_al, LinearAllocator, 1024);
ht->hein=HT_HEIN_MIN; ht->hein=HT_HEIN_MIN;
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*)); ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*));
for(u16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++) allocator_ptr internal_al = InternalAllocator_getPtr(ht);
ht->rows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL); for(u16 i=0; i<HT_HEIGHTS[HT_HEIN_MIN]; i++)
return ht; Autoarr_construct(&ht->rows[i], KVPair, 16, internal_al);
} }
void __Hashtable_free(void* _ht){ u16 __Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
void __Hashtable_destruct(void* _ht){
Hashtable* ht=_ht; Hashtable* ht=_ht;
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++) for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
Autoarr_free(ht->rows[i], true); Autoarr_destruct(&ht->rows[i]);
free(ht->rows); allocator_free(InternalAllocator_getPtr(ht), ht->rows);
InternalAllocator_destructIfInternal(LinearAllocator, ht);
} }
void Hashtable_free(Hashtable* ht){ void Hashtable_destruct(Hashtable* ht){
__Hashtable_free(ht); __Hashtable_destruct(ht);
free(ht);
} }
u16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
void Hashtable_expand(Hashtable* ht){ void Hashtable_expand(Hashtable* ht){
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH); if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*)); Autoarr(KVPair)* newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*));
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++) for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL); Autoarr_construct(&newrows[i], KVPair, ARR_SIZE_MAX, InternalAllocator_getPtr(ht));
for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){ for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
Autoarr(KVPair)* ar=ht->rows[i]; Autoarr(KVPair)* ar=&ht->rows[i];
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 k=0;k<arlen;k++){ for(u32 k=0;k<arlen;k++){
KVPair p=Autoarr_get(ar,k); KVPair p=Autoarr_get(ar,k);
u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein]; u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
Autoarr(KVPair)* newar=newrows[newrown]; Autoarr(KVPair)* newar=&newrows[newrown];
Autoarr_add(newar,p); Autoarr_add(newar,p);
} }
// there is no need to free array values, because they are copied into new array Autoarr_destruct(ar);
// so dont replace this incorrect auto-generated function
Autoarr_freeWithoutMembers(ar, true);
} }
free(ht->rows); free(ht->rows);
ht->rows=newrows; ht->rows = newrows;
} }
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){ Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
u32 hash=hashs(hash_sdbm32, key); u32 hash=hashs(hash_sdbm32, key);
Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]]; Autoarr(KVPair)* ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]];
if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar)) if(can_expand && Autoarr_length(ar) == ARR_SIZE_MAX)
Hashtable_expand(ht); Hashtable_expand(ht);
ar=ht->rows[hash%HT_HEIGHTS[ht->hein]]; ar=&ht->rows[hash%HT_HEIGHTS[ht->hein]];
return ar; return ar;
} }
/// @param key must be heap allocated /// @param key must be heap allocated
/// Hashtable_free will free this pointer /// Hashtable_destruct will free this pointer
void Hashtable_add(Hashtable* ht, char* key, Unitype u){ void Hashtable_add(Hashtable* ht, char* key, Unitype u){
KVPair p={ .key=key, .value=u }; KVPair p={ .key=key, .value=u };
Autoarr_add(getrow(ht,key,true),p); Autoarr_add(getrow(ht,key,true),p);
@@ -86,7 +82,8 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key){
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){ for(u32 i=0;i<arlen;i++){
KVPair* p=Autoarr_getPtr(ar,i); KVPair* p=Autoarr_getPtr(ar,i);
if(cptr_equals(key,p->key)) return &p->value; if(cptr_equals(key,p->key))
return &p->value;
} }
return NULL; return NULL;
} }
@@ -96,7 +93,8 @@ Unitype Hashtable_get(Hashtable* ht, char* key){
u32 arlen=Autoarr_length(ar); u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){ for(u32 i=0;i<arlen;i++){
KVPair p=Autoarr_get(ar,i); KVPair p=Autoarr_get(ar,i);
if(cptr_equals(key,p.key)) return p.value; if(cptr_equals(key,p.key))
return p.value;
} }
return UniNull; return UniNull;
} }

View File

@@ -9,16 +9,14 @@ extern "C" {
#include "KeyValuePair.h" #include "KeyValuePair.h"
STRUCT(Hashtable, STRUCT(Hashtable,
u8 hein; // height=HT_HEIGHTS[hein] InternalAllocator_declare(LinearAllocator);
Autoarr(KVPair)** rows; // Autoarr[height] u8 hein; // height=HT_HEIGHTS[hein]
Autoarr(KVPair)* rows; // Autoarr[height]
) )
Hashtable* Hashtable_create(); void Hashtable_construct(Hashtable* ht, allocator_ptr external_al);
void Hashtable_free(Hashtable* ht); void Hashtable_destruct(Hashtable* ht);
void __Hashtable_free(void* ht); void __Hashtable_destruct(void* ht);
// amount of rows
u16 Hashtable_height(Hashtable* ht);
// don't add pairs with the same keys, // don't add pairs with the same keys,
// or something weird will happen // or something weird will happen
@@ -36,14 +34,16 @@ Unitype* Hashtable_getPtr(Hashtable* ht, char* key);
Unitype Hashtable_get(Hashtable* ht, char* key); Unitype Hashtable_get(Hashtable* ht, char* key);
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output); bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
u16 __Hashtable_height(Hashtable* ht);
#define Hashtable_foreach(HT, EL, codeblock...) { \ #define Hashtable_foreach(HT, EL, codeblock...) { \
u16 hmax=Hashtable_height(HT); \ u16 hmax=__Hashtable_height(HT); \
for(u16 h=0; h<hmax; h++){ \ for(u16 h=0; h<hmax; h++){ \
Autoarr(KVPair)* AR=HT->rows[h]; \ Autoarr(KVPair)* row=&HT->rows[h]; \
Autoarr_foreach(AR, EL, codeblock); \ Autoarr_foreach(row, EL, codeblock); \
} \ } \
} }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,15 +1,8 @@
#include "KeyValuePair.h" #include "KeyValuePair.h"
kt_define(KVPair, __KVPair_free, NULL); kt_define(KVPair, NULL, NULL);
Autoarr_define(KVPair, false) Autoarr_define(KVPair)
// proper way to clean a KVP
void KVPair_free(KVPair p){
free(p.key);
Unitype_free(p.value);
}
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
void printkvp(KVPair p){ void printkvp(KVPair p){
kprintf("{\"%s\", ",p.key); kprintf("{\"%s\", ",p.key);

View File

@@ -14,12 +14,10 @@ STRUCT(KVPair,
Autoarr_declare(KVPair) Autoarr_declare(KVPair)
// proper way to clean a KVP void __KVPair_destruct(void* p);
void KVPair_free(KVPair p);
void __KVPair_free(void* p);
void printkvp(KVPair p); void printkvp(KVPair p);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -34,7 +34,7 @@ void LinkedList_addToEnd(void* _llist, void* _new_node) {
llist->last_node=new_node; llist->last_node=new_node;
} }
static inline void _insertNode(LinkedList(Pointer)* llist, static inline void _insertNode(LinkedList(Pointer)* llist,
LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){ LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){
if(prev_node==NULL){ if(prev_node==NULL){
if(next_node==llist->first_node) if(next_node==llist->first_node)

View File

@@ -16,7 +16,7 @@ extern "C" {
#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE) #define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE)
#define LinkedList_create(TYPE) LinkedList_##TYPE##_create() #define LinkedList_create(TYPE) LinkedList_##TYPE##_create()
#define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); }) #define LinkedList_destruct(LLIST) ({ LLIST->_functions->destruct(LLIST); free(LLIST); })
void LinkedList_addToBeginning(void* _llist, void* _new_node); void LinkedList_addToBeginning(void* _llist, void* _new_node);

View File

@@ -12,7 +12,7 @@ STRUCT(LLNode(TYPE), \
) \ ) \
\ \
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value); void LLNode_##TYPE##_destruct(LLNode(TYPE)* node, bool free_value);
#define LinkedList_declare(TYPE)\ #define LinkedList_declare(TYPE)\
@@ -27,7 +27,7 @@ STRUCT(LinkedList(TYPE), \
) \ ) \
\ \
typedef struct LinkedList_##TYPE##_functions_t { \ typedef struct LinkedList_##TYPE##_functions_t { \
freeMembers_t freeMembers; \ destruct_t destruct; \
void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \ void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \
void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \ void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \
} LinkedList_##TYPE##_functions_t; \ } LinkedList_##TYPE##_functions_t; \

View File

@@ -14,19 +14,19 @@ LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value){ \
return node; \ return node; \
} \ } \
\ \
void LLNode_##TYPE##_freeMembers(void* _node){ \ void LLNode_##TYPE##_destructMembers(void* _node){ \
LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \ LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \
void* value_ptr=&node->value; \ void* value_ptr=&node->value; \
if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \ if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \
ktDescriptor_##TYPE.freeMembers(value_ptr); \ ktDescriptor_##TYPE.destruct(value_ptr); \
} \ } \
\ \
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \ void LLNode_##TYPE##_destruct(LLNode(TYPE)* node, bool free_value){ \
if(free_value) LLNode_##TYPE##_freeMembers(node); \ if(free_value) LLNode_##TYPE##_destructMembers(node); \
free(node); \ free(node); \
} \ } \
\ \
kt_define(LLNode_##TYPE, LLNode_##TYPE##_freeMembers, NULL) kt_define(LLNode_##TYPE, LLNode_##TYPE##_destructMembers, NULL)
#define LinkedList_define(TYPE, VALUE_IS_PTR)\ #define LinkedList_define(TYPE, VALUE_IS_PTR)\
@@ -41,10 +41,10 @@ LinkedList(TYPE)* LinkedList_##TYPE##_create(){ \
return l; \ return l; \
} \ } \
\ \
void LinkedList_##TYPE##_freeMembers(void* _l){ \ void LinkedList_##TYPE##_destructMembers(void* _l){ \
LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \ LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \
if(l->first_node!=NULL) \ if(l->first_node!=NULL) \
LinkedList_foreach(l, node, LLNode_##TYPE##_free(node, true)); \ LinkedList_foreach(l, node, LLNode_##TYPE##_destruct(node, true)); \
l->first_node=NULL; l->last_node=NULL; l->count=0; \ l->first_node=NULL; l->last_node=NULL; l->count=0; \
} \ } \
\ \
@@ -55,7 +55,7 @@ void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextN
nextNode->prev=prevNode; \ nextNode->prev=prevNode; \
prevNode->next=nextNode; \ prevNode->next=nextNode; \
if(freeRemoved) \ if(freeRemoved) \
LLNode_##TYPE##_free(removedNode, true); \ LLNode_##TYPE##_destruct(removedNode, true); \
} \ } \
\ \
void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \ void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \
@@ -65,16 +65,16 @@ void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevN
prevNode->next=nextNode; \ prevNode->next=nextNode; \
nextNode->prev=prevNode; \ nextNode->prev=prevNode; \
if(freeRemoved) \ if(freeRemoved) \
LLNode_##TYPE##_free(removedNode, true); \ LLNode_##TYPE##_destruct(removedNode, true); \
} \ } \
\ \
LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \ LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \
.freeMembers=LinkedList_##TYPE##_freeMembers, \ .destruct=LinkedList_##TYPE##_destructMembers, \
.removePrev=LinkedList_##TYPE##_removePrev, \ .removePrev=LinkedList_##TYPE##_removePrev, \
.removeNext=LinkedList_##TYPE##_removeNext \ .removeNext=LinkedList_##TYPE##_removeNext \
}; \ }; \
\ \
kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_freeMembers, NULL) kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_destructMembers, NULL)
#if __cplusplus #if __cplusplus

View File

@@ -1,6 +1,6 @@
#include "SearchTree.h" #include "SearchTree.h"
kt_define(STNode, __STNode_free, NULL); kt_define(STNode, __STNode_destruct, NULL);
STNode* STNode_create(){ STNode* STNode_create(){
STNode* node=malloc(sizeof(STNode)); STNode* node=malloc(sizeof(STNode));
@@ -9,20 +9,20 @@ STNode* STNode_create(){
return node; return node;
} }
void __STNode_free(void* _node){ void __STNode_destruct(void* _node){
STNode* node=_node; STNode* node=_node;
if (!node) throw(ERR_NULLPTR); if (!node) throw(ERR_NULLPTR);
if(node->branches){ if(node->branches){
for(u8 n32 = 0;n32<8;n32++){ for(u8 n32 = 0;n32<8;n32++){
STNode*** ptrn32=(STNode***)node->branches[n32]; STNode*** ptrn32=(STNode***)node->branches[n32];
if(ptrn32){ if(ptrn32){
for(u8 n4 = 0;n4<8;n4++){ for(u8 n4 = 0;n4<8;n4++){
STNode** ptrn4=ptrn32[n4]; STNode** ptrn4=ptrn32[n4];
if (ptrn4){ if (ptrn4){
for(u8 rem=0;rem<4;rem++){ for(u8 rem=0;rem<4;rem++){
STNode* ptrrem=ptrn4[rem]; STNode* ptrrem=ptrn4[rem];
if(ptrrem) if(ptrrem)
STNode_free(ptrrem); STNode_destruct(ptrrem);
} }
free(ptrn4); free(ptrn4);
} }
@@ -32,11 +32,11 @@ void __STNode_free(void* _node){
} }
free(node->branches); free(node->branches);
} }
if(node->value.VoidPtr) if(node->value.VoidPtr)
Unitype_free(node->value); Unitype_destruct(&node->value);
} }
void STNode_free(STNode* node){ void STNode_destruct(STNode* node){
__STNode_free(node); __STNode_destruct(node);
free(node); free(node);
} }

View File

@@ -13,8 +13,8 @@ STRUCT(STNode,
) )
STNode* STNode_create(); STNode* STNode_create();
void STNode_free(STNode* node); void STNode_destruct(STNode* node);
void __STNode_free(void* node); void __STNode_destruct(void* node);
void ST_push(STNode* node, char* key, Unitype value); void ST_push(STNode* node, char* key, Unitype value);
void ST_pushString(STNode* node, string key, Unitype value); void ST_pushString(STNode* node, string key, Unitype value);
@@ -23,4 +23,4 @@ Unitype ST_pullString(STNode* node, string key);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -22,4 +22,4 @@ STNode.branches byte
┗━[7]━┳━[0] 252 ┗━[7]━┳━[0] 252
┣━... ┣━...
┗━[3] 255 ┗━[3] 255
``` ```

View File

@@ -1,147 +1,90 @@
#include "StringBuilder.h" #include "StringBuilder.h"
kt_define(StringBuilder, __StringBuilder_free, NULL); kt_define(StringBuilder, (destruct_t)StringBuilder_destruct, NULL);
#define BL_C 32 #define BL_C 32
#define BL_L 1024 #define BL_L 1024
#define createBuffer() (MemoryChunk){.data = allocator_alloc(InternalAllocator_getPtr(b), 512), .size=512, .occupied_size=0}
void complete_buf(StringBuilder* b){ void complete_buf(StringBuilder* b){
if(!b->compl_bufs) if(b->curr_buf.occupied_size == 0)
b->compl_bufs=Autoarr_create(string,BL_C,BL_L); return;
u32 len=Autoarr_length(b->curr_buf); string str={ .length=b->curr_buf.occupied_size, .ptr= b->curr_buf.data };
if(!len) return; Autoarr_add(&b->compl_bufs,str);
string str={.length=len, .ptr=malloc(len)}; b->curr_buf = createBuffer();
u32 i=0;
Autoarr_foreach(b->curr_buf, c,
str.ptr[i++]=c;
);
Autoarr_add(b->compl_bufs,str);
Autoarr_free(b->curr_buf, true);
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
}
void try_complete_buf(StringBuilder* b){
if(b->curr_buf->blocks_count==BL_C)
complete_buf(b);
} }
StringBuilder* StringBuilder_create(){ void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al){
StringBuilder* b=malloc(sizeof(StringBuilder)); InternalAllocator_setExternalOrConstruct(b, external_al, LinearAllocator, 1024);
b->compl_bufs=NULL; Autoarr_construct(&b->compl_bufs, string, 0, InternalAllocator_getPtr(b));
b->curr_buf=Autoarr_create(i8,BL_C,BL_L); b->curr_buf = createBuffer();
return b; b->total_length = 0;
} }
void __StringBuilder_free(void* _b){ void StringBuilder_destruct(StringBuilder* b){
StringBuilder* b=_b; Autoarr_destruct(&b->compl_bufs);
if(b->compl_bufs) Autoarr_free(b->compl_bufs, true); allocator_free(InternalAllocator_getPtr(b), b->curr_buf.data);
Autoarr_free(b->curr_buf, true); InternalAllocator_destructIfInternal(LinearAllocator, b);
}
void StringBuilder_free(StringBuilder* b){
__StringBuilder_free(b);
free(b);
} }
string StringBuilder_build(StringBuilder* b){ string StringBuilder_build(StringBuilder* b){
complete_buf(b); complete_buf(b);
u32 len=0; string str= {
Autoarr_foreach(b->compl_bufs, cs, .length = b->total_length,
len+=cs.length; .ptr = allocator_alloc(InternalAllocator_getPtr(b), b->total_length+1)
};
str.ptr[b->total_length]='\0';
char* free_space_ptr = str.ptr;
Autoarr_foreach(&b->compl_bufs, buf,
memcpy(free_space_ptr, buf.ptr, buf.length);
free_space_ptr += buf.length;
); );
string str= { .length=len, .ptr=malloc(len+1) }; StringBuilder_destruct(b);
str.ptr[len]='\0';
u32 i=0;
Autoarr_foreach(b->compl_bufs, cs,
for(u32 n=0;n<cs.length;n++)
str.ptr[i++]=cs.ptr[n];
free(cs.ptr);
);
StringBuilder_free(b);
return str; return str;
} }
void StringBuilder_rmchar(StringBuilder* b){ void StringBuilder_rmchar(StringBuilder* b){
if(b->curr_buf->block_length!=0) if(b->curr_buf.occupied_size != 0)
Autoarr_pop(b->curr_buf) b->curr_buf.occupied_size--;
else { else {
if(!b->compl_bufs) throw(ERR_NULLPTR); for(u32 buf_i = Autoarr_length(&b->compl_bufs) - 1; buf_i != (u32)-1; buf_i--){
string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1)); string* lastcb = Autoarr_getPtr(&b->compl_bufs, buf_i);
lastcb->length--; if(lastcb->length != 0){
lastcb->length--;
break;
}
}
} }
} }
void StringBuilder_append_char(StringBuilder* b, char c){ void StringBuilder_append_char(StringBuilder* b, char c){
try_complete_buf(b); if(b->curr_buf.occupied_size==b->curr_buf.size)
Autoarr_add(b->curr_buf,c); complete_buf(b);
((char*)b->curr_buf.data)[b->curr_buf.occupied_size] = c;
} }
void StringBuilder_append_string(StringBuilder* b, string s){ void StringBuilder_append_string(StringBuilder* b, string s){
complete_buf(b); complete_buf(b);
Autoarr_add(b->compl_bufs, string_copy(s)); Autoarr_add(&b->compl_bufs, s);
} }
void StringBuilder_append_cptr(StringBuilder* b, char* s){ void StringBuilder_append_cptr(StringBuilder* b, char* s){
string str={ string str={ .ptr=s, .length=cptr_length(s) };
.ptr=s, StringBuilder_append_string(b, str);
.length=cptr_length(s)
};
StringBuilder_append_string(b,str);
}
void curr_buf_add_string(StringBuilder* b, string s){
for(u32 i=0; i<s.length; i++)
Autoarr_add(b->curr_buf,s.ptr[i]);
} }
void StringBuilder_append_i64(StringBuilder* b, i64 a){ void StringBuilder_append_i64(StringBuilder* b, i64 a){
try_complete_buf(b); StringBuilder_append_cptr(b, toString_i64(InternalAllocator_getPtr(b), a));
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
}
else if(a<0){
Autoarr_add(b->curr_buf,'-');
a=-a;
}
char buf[24];
while(a!=0){
buf[i++]='0'+a%10;
a/=10;
}
string rev=string_reverse((string){buf,i});
curr_buf_add_string(b,rev);
free(rev.ptr);
} }
void StringBuilder_append_u64(StringBuilder* b, u64 a){ void StringBuilder_append_u64(StringBuilder* b, u64 a){
try_complete_buf(b); StringBuilder_append_cptr(b, toString_u64(InternalAllocator_getPtr(b), a, 0, 0));
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
}
char buf[24];
while(a!=0){
buf[i++]='0'+a%10;
a/=10;
}
string rev=string_reverse((string){buf,i});
curr_buf_add_string(b,rev);
free(rev.ptr);
} }
void StringBuilder_append_f64(StringBuilder* b, f64 a){ void StringBuilder_append_f64(StringBuilder* b, f64 a){
try_complete_buf(b); StringBuilder_append_cptr(b, toString_f64(InternalAllocator_getPtr(b), a, toString_f64_max_precision, 0, 0));
char buf[32];
IFMSC(
sprintf_s(buf,32,"%lf",a),
sprintf(buf,"%lf",a)
);
curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
} }

View File

@@ -8,20 +8,25 @@ extern "C" {
#include "string.h" #include "string.h"
STRUCT(StringBuilder, STRUCT(StringBuilder,
Autoarr(string)* compl_bufs; InternalAllocator_declare(LinearAllocator);
Autoarr(i8)* curr_buf; Autoarr(string) compl_bufs;
MemoryChunk curr_buf;
u64 total_length;
) )
StringBuilder* StringBuilder_create(void); ///@param external_al if null, creates internal allocator
void StringBuilder_free(StringBuilder* b); void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al);
void __StringBuilder_free(void* b); void StringBuilder_destruct(StringBuilder* b);
// Joins all strings from compl_bufs. // Joins all strings from compl_bufs.
// Returns zero-terminated string. // Returns zero-terminated string.
// No need to call string_extract()! // No need to call string_extract!
// Frees StringBuilder. // Destructs StringBuilder.
string StringBuilder_build(StringBuilder* b); string StringBuilder_build(StringBuilder* b);
// removes last char
/// OBSOLETE! Will be removed later
void StringBuilder_rmchar(StringBuilder* b); void StringBuilder_rmchar(StringBuilder* b);
void StringBuilder_append_char(StringBuilder* b, char c); void StringBuilder_append_char(StringBuilder* b, char c);
void StringBuilder_append_cptr(StringBuilder* b, char* s); void StringBuilder_append_cptr(StringBuilder* b, char* s);
void StringBuilder_append_string(StringBuilder* b, string s); void StringBuilder_append_string(StringBuilder* b, string s);
@@ -31,4 +36,4 @@ void StringBuilder_append_f64(StringBuilder* b, f64 a);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,47 +1,49 @@
#include "string.h" #include "string.h"
kt_define(string, NULL, NULL); kt_define(string, NULL, NULL);
Array_define(string) Autoarr_define(string);
Autoarr_define(string, false)
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(string str){ char* string_extract(allocator_ptr al, string str){
if(str.length==0) return NULL; if(str.length==0) return NULL;
char* cptr=malloc(str.length*sizeof(char)+1); char* cptr=allocator_alloc(al, str.length+1);
memcpy(cptr, str.ptr, str.length);
cptr[str.length]=0; cptr[str.length]=0;
while(str.length-->0)
cptr[str.length]=str.ptr[str.length];
return cptr; return cptr;
} }
// copies src.ptr content to new string and adds \0 at the end // copies src.ptr content to new string and adds \0 at the end
string string_copy(string src){ string string_copy(allocator_ptr al, string src){
if(!src.ptr) if(!src.ptr)
return src; throw(ERR_NULLPTR);
string nstr; string nstr;
nstr.length=src.length; nstr.length=src.length;
nstr.ptr=malloc(nstr.length+1); nstr.ptr=allocator_alloc(al, nstr.length+1);
for(u32 i=0;i<nstr.length;i++) memcpy(nstr.ptr, src.ptr, nstr.length);
nstr.ptr[i]=src.ptr[i];
nstr.ptr[nstr.length]='\0'; nstr.ptr[nstr.length]='\0';
return nstr; return nstr;
} }
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1){ bool string_compare(string str0, string str1){
if(str0.length!=str1.length) return false; if(str0.length!=str1.length)
if(!str0.ptr) return str1.ptr ? false : true; return false;
if(!str0.ptr)
return str1.ptr ? false : true;
else if(!str1.ptr) return false; else if(!str1.ptr) return false;
while(str0.length-->0) while(str0.length-->0)
if(*str0.ptr++ != *str1.ptr++) if(*str0.ptr++ != *str1.ptr++)
return false; return false;
return true; return true;
} }
// creates new string which is reversed variant of <s> // creates new string which is reversed variant of <s>
string string_reverse(string s){ string string_reverse(allocator_ptr al, string s){
if(s.length==0) return s; if(s.length==0)
string r={malloc(s.length), s.length}; return s;
string r;
r.ptr=allocator_alloc(al, s.length);
r.length=s.length;
for(u32 i=0; i<s.length; i++) for(u32 i=0; i<s.length; i++)
r.ptr[i]=s.ptr[s.length-i-1]; r.ptr[i]=s.ptr[s.length-i-1];
return r; return r;

View File

@@ -5,7 +5,6 @@ extern "C" {
#endif #endif
#include "../base/base.h" #include "../base/base.h"
#include "../Array/Array.h"
#include "../Autoarr/Autoarr.h" #include "../Autoarr/Autoarr.h"
// my fixed length string struct // my fixed length string struct
@@ -15,7 +14,6 @@ STRUCT(string,
u64 length; // amount of chars in ptr value u64 length; // amount of chars in ptr value
) )
Array_declare(string)
Autoarr_declare(string) Autoarr_declare(string)
static const string stringNull={NULL,0}; static const string stringNull={NULL,0};
@@ -24,17 +22,17 @@ static const string stringNull={NULL,0};
#define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) } #define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) }
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(string str); char* string_extract(allocator_ptr al, string str);
// copies src.ptr content to new string and adds \0 at the end // copies src.ptr content to new string and adds \0 at the end
string string_copy(string src); string string_copy(allocator_ptr al, string src);
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1); bool string_compare(string str0, string str1);
// creates new string which is reversed variant of <s> // creates new string which is reversed variant of <s>
string string_reverse(string s); string string_reverse(allocator_ptr al, string s);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -11,7 +11,8 @@ extern "C" {
#include "type_system/type_system.h" #include "type_system/type_system.h"
#include "../kprint/kprintf.h" #include "../kprint/kprintf.h"
#include "endian.h" #include "endian.h"
#include "memory/memory.h"
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -11,17 +11,16 @@ u32 cptr_length(const char* str){
} }
// allocates new char[] and copies src there // allocates new char[] and copies src there
char* cptr_copy(const char* src){ char* cptr_copy(allocator_ptr al, const char* src){
u32 len=cptr_length(src)+1; u32 len=cptr_length(src)+1;
char* dst=malloc(len); char* dst=allocator_alloc(al, len);
while(len--!=0) memcpy(dst, src, len);
dst[len]=src[len];
return dst; return dst;
} }
// multiplies char n times // multiplies char n times
char* char_multiply(char c, u32 n){ char* char_multiply(allocator_ptr al, char c, u32 n){
char* rez=malloc(n+1); char* rez=allocator_alloc(al, n+1);
rez[n]=0; rez[n]=0;
while(n--!=0) while(n--!=0)
rez[n]=c; rez[n]=c;
@@ -131,16 +130,9 @@ i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 see
return -1; return -1;
} }
void memcopy(void* from, void* to, u32 size){ char* __cptr_concat(allocator_ptr al, u32 n, ...){
if(from==NULL || to==NULL) char** strs=(char**)allocator_alloc(al, n*sizeof(char*));
throw(ERR_NULLPTR); u32* lengths=allocator_alloc(al, n*sizeof(u32));
for(u32 i=0; i<size; i++)
((char*)to)[i]=((char*)from)[i];
}
char* __cptr_concat(u32 n, ...){
char** strs=(char**)malloc(n*sizeof(char*));
u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0; u32 totalLength=0;
// reading args from va_list // reading args from va_list
@@ -156,41 +148,41 @@ char* __cptr_concat(u32 n, ...){
va_end(vl); va_end(vl);
// allocating memory for output value // allocating memory for output value
char* totality=malloc(totalLength+1); char* totality=allocator_alloc(al, totalLength+1);
char* output=totality; char* output=totality;
totality[totalLength]=0; totality[totalLength]=0;
// copying content of all strings to rezult // copying content of all strings to rezult
for(u16 k=0; k<n; k++){ for(u16 k=0; k<n; k++){
memcopy(strs[k], totality, lengths[k]); memcpy(totality, strs[k], lengths[k]);
totality+=lengths[k]; totality+=lengths[k];
} }
free(strs); allocator_free(al, lengths);
free(lengths); allocator_free(al, strs);
return output; return output;
} }
char* cptr_toLower(const char* src) { char* cptr_toLower(allocator_ptr al, const char* src) {
u32 length=cptr_length(src); u32 length=cptr_length(src);
char *p=malloc(length+1); char *p=allocator_alloc(al, length+1);
p[length]=0; p[length]=0;
for(u32 i=0; i<length; i++) for(u32 i=0; i<length; i++)
p[i]=tolower(src[i]); p[i]=tolower(src[i]);
return p; return p;
} }
char* cptr_toUpper(const char* src) { char* cptr_toUpper(allocator_ptr al, const char* src) {
u32 length=cptr_length(src); u32 length=cptr_length(src);
char *p=malloc(length+1); char *p=allocator_alloc(al, length+1);
p[length]=0; p[length]=0;
for(u32 i=0; i<length; i++) for(u32 i=0; i<length; i++)
p[i]=toupper(src[i]); p[i]=toupper(src[i]);
return p; return p;
} }
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){ char* cptr_replaceCharIn(allocator_ptr al, const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){
char* rzlt=cptr_copy(src); char* rzlt=cptr_copy(al, src);
for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){ for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){
if(src[i]==c_old) if(src[i]==c_old)
rzlt[i]=c_new; rzlt[i]=c_new;
@@ -198,8 +190,10 @@ char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex
return rzlt; return rzlt;
} }
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){ char* cptr_replaceIn(allocator_ptr al, const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){
StringBuilder* sb=StringBuilder_create(); StringBuilder _sb;
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
const u32 str_old_len=cptr_length(str_old); const u32 str_old_len=cptr_length(str_old);
const u32 str_new_len=cptr_length(str_new); const u32 str_new_len=cptr_length(str_new);
i32 i=startIndex; i32 i=startIndex;

View File

@@ -5,12 +5,13 @@ extern "C" {
#endif #endif
#include "std.h" #include "std.h"
#include "memory/allocator_base.h"
// returns length of char buffer (without \0) // returns length of char buffer (without \0)
u32 cptr_length(const char* str); u32 cptr_length(const char* str);
// allocates new char[] and copies src there // allocates new char[] and copies src there
char* cptr_copy(const char* src); char* cptr_copy(allocator_ptr al, const char* src);
bool cptr_equals(const char* key0, const char* key1); bool cptr_equals(const char* key0, const char* key1);
@@ -19,9 +20,9 @@ bool cptr_startsWith(const char* src, const char* fragment);
bool cptr_endsWith(const char* src, const char* fragment); bool cptr_endsWith(const char* src, const char* fragment);
// multiplies char n times // multiplies char n times
char* char_multiply(char c, u32 n); char* char_multiply(allocator_ptr al, char c, u32 n);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found /// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength); i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
@@ -66,29 +67,27 @@ static inline bool cptr_contains(const char* src, const char* fragment){
return cptr_seek(src, fragment, 0, -1) +1; return cptr_seek(src, fragment, 0, -1) +1;
} }
void memcopy(void* from, void* to, u32 size); char* __cptr_concat(allocator_ptr al, u32 n, ...);
#define cptr_concat(ALLOCATOR, STR...) __cptr_concat(ALLOCATOR, count_args(STR), STR)
char* __cptr_concat(u32 n, ...); char* cptr_toLower(allocator_ptr al, const char* src);
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR) char* cptr_toUpper(allocator_ptr al, const char* src);
char* cptr_toLower(const char* src);
char* cptr_toUpper(const char* src);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found /// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength); char* cptr_replaceIn(allocator_ptr al, const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength);
/// @param startIndex 0 ... src length /// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1 /// @param seekLength 0 ... -1
/// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found /// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength); char* cptr_replaceCharIn(allocator_ptr al, const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength);
static inline char* cptr_replace(const char* src, const char* str_old, const char* str_new) static inline char* cptr_replace(allocator_ptr al, const char* src, const char* str_old, const char* str_new)
{ return cptr_replaceIn(src, str_old, str_new, 0, -1); } { return cptr_replaceIn(al, src, str_old, str_new, 0, -1); }
static inline char* cptr_replaceChar(const char* src, char c_old, char c_new) static inline char* cptr_replaceChar(allocator_ptr al, const char* src, char c_old, char c_new)
{ return cptr_replaceCharIn(src, c_old, c_new, 0, -1); } { return cptr_replaceCharIn(al, src, c_old, c_new, 0, -1); }
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -26,27 +26,21 @@ char* errname(ErrorId err){
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){ char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=ERRMSG_MAXLENGTH; size_t bufsize=ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize); char* rezult=malloc(bufsize);
IFMSC( sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg);
sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg),
sprintf(rezult,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg)
);
return rezult; return rezult;
} }
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){ char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH; size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize); char* rezult=malloc(bufsize);
IFMSC( sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname);
sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname),
sprintf(rezult,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname)
);
free(errmsg); free(errmsg);
return rezult; return rezult;
} }
void Maybe_free(Maybe e){ void Maybe_destruct(Maybe e){
free(e.errmsg); free(e.errmsg);
Unitype_free(e.value); Unitype_destruct(&e.value);
} }
void printMaybe(Maybe e){ void printMaybe(Maybe e){

View File

@@ -29,7 +29,7 @@ STRUCT(Maybe,
// .value .errmsg // .value .errmsg
#define MaybeNull (Maybe){UniNull, NULL} #define MaybeNull (Maybe){UniNull, NULL}
void Maybe_free(Maybe e); void Maybe_destruct(Maybe e);
void printMaybe(Maybe e); void printMaybe(Maybe e);
@@ -87,4 +87,4 @@ char* __unknownErr( );
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -0,0 +1,15 @@
#include "allocators_internal.h"
void* CstdAllocator_alloc(allocator_ptr self, alloc_size_t size){
// assert(size>0);
return malloc(size);
}
void CstdAllocator_free(allocator_ptr self, void* ptr){
// assert(ptr!=NULL);
free(ptr);
}
kt_define(CstdAllocator, NULL, NULL);
CstdAllocator CstdAllocator_instance=(CstdAllocator){.base.alloc_f=CstdAllocator_alloc, .base.free_f=CstdAllocator_free};

View File

@@ -0,0 +1,102 @@
#include "allocators_internal.h"
#include <stdio.h>
#define default_chunks_per_allocation 16
// growing chunk array size
#define new_max_chunks_count ( default_chunks_per_allocation*(self->chunks_count/16 == 0) + \
default_chunks_per_allocation*add_padding(self->chunks_count/2)/4 )
#define default_chunk_size 1024
// growing chunk size
#define new_chunk_size ( default_chunk_size*(self->chunks_count/16 == 0) + \
default_chunk_size*add_padding(self->chunks_count/8) )
#define chunk_alloc(SZ, OCCUPIED) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=OCCUPIED }
#define curr_chunk (self->chunks+self->curr_chunk_i)
__attribute__ ((noinline)) void* ___alloc_realloc_chunk(LinearAllocator* self, alloc_size_t alloc_size){
free(curr_chunk->data);
*curr_chunk=chunk_alloc(alloc_size, alloc_size);
return curr_chunk->data;
}
__attribute__ ((noinline)) void* __alloc_new_chunk(LinearAllocator* self, alloc_size_t alloc_size){
self->curr_chunk_i++;
// next chunk has been already allocated
if(self->curr_chunk_i < self->chunks_count)
return curr_chunk->data;
// self->chunks array is full
if(self->chunks_count == self->max_chunks_count){
self->max_chunks_count = new_max_chunks_count;
self->chunks = realloc(self->chunks, sizeof(MemoryChunk) * self->max_chunks_count);
}
// new chunk allocation
self->chunks_count++;
alloc_size_t _new_chunk_size= alloc_size > new_chunk_size ? alloc_size : new_chunk_size;
*curr_chunk=chunk_alloc(_new_chunk_size, alloc_size);
return curr_chunk->data;
}
void* LinearAllocator_alloc(allocator_ptr _self, alloc_size_t alloc_size){
// assert(_self!=NULL);
// assert(alloc_size>0);
LinearAllocator* self = (LinearAllocator*)_self;
alloc_size=add_padding(alloc_size);
// aligned alloc_size can fit into the current chunk
if(curr_chunk->occupied_size + alloc_size <= curr_chunk->size){
void* data_ptr=curr_chunk->data + curr_chunk->occupied_size;
curr_chunk->occupied_size += alloc_size;
return data_ptr;
}
// reallocation of current chunk because it is clean
if(curr_chunk->occupied_size == 0){
// It is very unefficient operation.
// If it happens not only in the first chunk, code have to be refactored
assert(self->curr_chunk_i==0);
return ___alloc_realloc_chunk(self, alloc_size);
}
// creation of a new chunk
else {
return __alloc_new_chunk(self, alloc_size);
}
}
void LinearAllocator_free(allocator_ptr _self, void* ptr){
// LinearAllocator can't free pointers
}
void LinearAllocator_destruct(LinearAllocator* self){
// assert(_self!=NULL);
u32 size=0;
u32 oc_size=0;
for(u32 chunk_i=0; chunk_i < self->chunks_count; chunk_i++){
free(self->chunks[chunk_i].data);
size+=self->chunks[chunk_i].size;
oc_size+=self->chunks[chunk_i].occupied_size;
}
printf("\e[35m%u/%u\n",oc_size,size);
free(self->chunks);
self->chunks=NULL;
self->chunks_count=0;
self->curr_chunk_i=0;
self->max_chunks_count=0;
}
void LinearAllocator_construct(LinearAllocator* self, alloc_size_t starting_size){
assert(self!=NULL);
assert(starting_size>0);
self->base.alloc_f=LinearAllocator_alloc;
self->base.free_f=LinearAllocator_free;
self->curr_chunk_i=0;
self->chunks_count=1;
self->max_chunks_count=new_max_chunks_count;
self->chunks=malloc(sizeof(MemoryChunk) * new_max_chunks_count);
self->chunks[0]=chunk_alloc(starting_size, 0);
}
kt_define(LinearAllocator, (destruct_t)LinearAllocator_destruct, NULL)

View File

@@ -0,0 +1,58 @@
#include "allocators_internal.h"
#define chunk_alloc(SZ) (MemoryChunk){ .data=malloc(SZ), .size=SZ, .occupied_size=0 }
#define linear self->base
#define curr_chunk (linear.chunks+linear.curr_chunk_i)
typedef struct {
alloc_size_t data_size;
} AllocationHeader;
void* StackingAllocator_alloc(allocator_ptr _self, alloc_size_t size){
assert(_self!=NULL);
assert(size>0);
StackingAllocator* self = (StackingAllocator*)_self;
size=add_padding(size);
// allocates memory with header struct before data
AllocationHeader* header_ptr=LinearAllocator_alloc(_self, sizeof(AllocationHeader) + size);
void* data_ptr = (void*)header_ptr + sizeof(AllocationHeader);
header_ptr->data_size = size;
self->allocations_count++;
return data_ptr;
}
void StackingAllocator_free(allocator_ptr _self, void* data_ptr){
assert(_self!=NULL);
assert(data_ptr!=NULL);
StackingAllocator* self = (StackingAllocator*)_self;
AllocationHeader* header_ptr = data_ptr - sizeof(AllocationHeader);
// TODO check is data_ptr pointer to the last allocation
// chunk is empty
if(curr_chunk->occupied_size==0){
// isn't the first chunk
assert(linear.curr_chunk_i>0);
linear.curr_chunk_i--;
}
alloc_size_t allocation_size=header_ptr->data_size+sizeof(*header_ptr);
// data must fit in chunk
assert(allocation_size <= curr_chunk->occupied_size);
curr_chunk->occupied_size -= allocation_size;
}
void StackingAllocator_destruct(StackingAllocator* self){
LinearAllocator_destruct(&self->base);
}
void StackingAllocator_construct(StackingAllocator* self, alloc_size_t starting_size){
assert(self!=NULL);
assert(starting_size>0);
LinearAllocator_construct(&linear, starting_size);
linear.base.alloc_f=StackingAllocator_alloc;
linear.base.free_f=StackingAllocator_free;
self->allocations_count=0;
}
kt_define(StackingAllocator, (destruct_t)StackingAllocator_destruct, NULL)

View File

@@ -0,0 +1,36 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include "../std.h"
///////////////////////////////////////////
// MemoryAllocator interface //
///////////////////////////////////////////
typedef u32 alloc_size_t;
typedef struct MemoryAllocator MemoryAllocator;
typedef MemoryAllocator* allocator_ptr;
typedef void* (*alloc_t)(allocator_ptr, alloc_size_t size);
typedef void (*free_t)(allocator_ptr, void* ptr);
typedef struct MemoryAllocator {
alloc_t alloc_f;
free_t free_f;
} MemoryAllocator;
#define allocator_alloc(ALLOCATOR, SIZE) \
((allocator_ptr)ALLOCATOR)->alloc_f(ALLOCATOR, SIZE)
#define allocator_free(ALLOCATOR, PTR) \
((allocator_ptr)ALLOCATOR)->free_f(ALLOCATOR, PTR)
#define allocator_destruct(ALLOCATOR) \
((allocator_ptr)ALLOCATOR)->destruct_f(ALLOCATOR)
void* allocator_transfer(allocator_ptr src, allocator_ptr dest, void* data, alloc_size_t data_size);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,9 @@
#include "memory.h"
void* allocator_transfer(allocator_ptr src, allocator_ptr dest, void* data, alloc_size_t data_size)
{
void* transfered=allocator_alloc(dest, data_size);
memcpy(transfered, data, data_size);
allocator_free(src, data);
return transfered;
}

View File

@@ -0,0 +1,69 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../std.h"
#include "../type_system/ktDescriptor.h"
#include "allocator_base.h"
///////////////////////////////////////////
// CstdAllocator //
///////////////////////////////////////////
// Just wrapper for malloc() and free() //
///////////////////////////////////////////
STRUCT(CstdAllocator,
MemoryAllocator base;
);
extern CstdAllocator CstdAllocator_instance;
#define CstdAllocator_instPtr (allocator_ptr)(&CstdAllocator_instance)
///////////////////////////////////////////
// LinearAllocator //
///////////////////////////////////////////
// Can't free allocated memory. //
// Allocates new memory chunk when the //
// current is full. //
///////////////////////////////////////////
typedef struct MemoryChunk {
void* data;
alloc_size_t size;
alloc_size_t occupied_size; /* free memory position in the current chunk. */
} MemoryChunk;
STRUCT(LinearAllocator,
MemoryAllocator base;
MemoryChunk* chunks; /* MemoryChunk[max_chunks_count] */
u32 chunks_count; /* allocated chunks */
u32 max_chunks_count; /* chunks that can be allocated without reallocating .chunks */
u32 curr_chunk_i; /* index of current chunk in .chunks, can be < .chunks_count */
);
void LinearAllocator_construct(LinearAllocator* self, alloc_size_t starting_size);
void LinearAllocator_destruct(LinearAllocator* self);
///////////////////////////////////////////
// StackingAllocator //
///////////////////////////////////////////
// The same as Linear, but can free //
// allocations in reverse order //
///////////////////////////////////////////
STRUCT(StackingAllocator,
LinearAllocator base;
u32 allocations_count;
);
void StackingAllocator_construct(StackingAllocator* self, alloc_size_t starting_size);
void StackingAllocator_destruct(StackingAllocator* self);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,4 @@
#include <assert.h>
#include "memory.h"
void* LinearAllocator_alloc(allocator_ptr _self, alloc_size_t size);

44
src/base/memory/memory.h Normal file
View File

@@ -0,0 +1,44 @@
#include "allocators.h"
// addresses must be aligned to this value
#define memory_align sizeof(void*)
// adds padding if memory_align if N isn't a multiple of memory_aligh
#define add_padding(N) (N + (N%memory_align != 0)*(memory_align - N%memory_align))
///////////////////////////////////////////
// NOT AN ALLOCATOR //
///////////////////////////////////////////
// Macros to embed internal allocator //
// into some collection struct. //
///////////////////////////////////////////
/// call this macro inside struct declaration
#define InternalAllocator_declare(AL_TYPE) \
AL_TYPE _internal_al; \
allocator_ptr _internal_al_ptr;
/// get pointer to allocator
#define InternalAllocator_getPtr(STRUCT_PTR) ((STRUCT_PTR)->_internal_al_ptr)
/// true if allocator is stored inside the struct, otherwise false
#define InternalAllocator_isInternal(STRUCT_PTR) (bool)((STRUCT_PTR)->_internal_al_ptr == (allocator_ptr)&(STRUCT_PTR)->_internal_al)
/// set ptr to external allocator
#define InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) ((STRUCT_PTR)->_internal_al_ptr = EXT_AL_PTR);
/// create internal allocator and set ptr to it
#define InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS...) { \
TYPE##_construct(&(STRUCT_PTR)->_internal_al, CTOR_ARGS); \
(STRUCT_PTR)->_internal_al_ptr = (allocator_ptr)&(STRUCT_PTR)->_internal_al; \
}
/// if EXT_AL_PTR isn't null, set external allocator, otherwise create new
#define InternalAllocator_setExternalOrConstruct(STRUCT_PTR, EXT_AL_PTR, TYPE, CTOR_ARGS...) \
if(EXT_AL_PTR!=NULL) InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) \
else InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS)
#define InternalAllocator_destructIfInternal(TYPE, STRUCT_PTR) {\
if(InternalAllocator_isInternal(STRUCT_PTR)) \
TYPE##_destruct((TYPE*)InternalAllocator_getPtr(STRUCT_PTR)); \
}

View File

@@ -13,9 +13,10 @@
tni=1; \ tni=1; \
} else tni=2; \ } else tni=2; \
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \ kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \
opname, t, tnames[tni]); opname, t, tnames[tni]); \
fflush(stdout);
#ifdef CLOCK_REALTIME #ifdef CLOCK_REALTIME
/// executes codeblock and prints execution time /// executes codeblock and prints execution time
/// u64 op_i is counter of the internal loop /// u64 op_i is counter of the internal loop
/// uses non-standard high-precision clock /// uses non-standard high-precision clock
@@ -28,7 +29,7 @@
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \ f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \
__optime_print(opname,t); \ __optime_print(opname,t); \
} }
#else #else
/// uses standard low precision clock /// uses standard low precision clock
#define optime(opname, repeats, codeblock...) { \ #define optime(opname, repeats, codeblock...) { \
clock_t start=clock(); \ clock_t start=clock(); \

View File

@@ -25,10 +25,10 @@ typedef int64_t i64;
typedef uint64_t u64; typedef uint64_t u64;
typedef float f32; typedef float f32;
typedef double f64; typedef double f64;
/// anonymous pointer without specified freeMembers() func /// anonymous pointer without specified destruct() func
typedef void* Pointer; typedef void* Pointer;
// Usually bool from stdbool.h is defined as macro, // Usually bool from stdbool.h is defined as macro,
// so in other macros like ktid_##TYPE it will be replaced by _Bool. // so in other macros like ktid_##TYPE it will be replaced by _Bool.
// ktid__Bool will be created instead of ktid_bool // ktid__Bool will be created instead of ktid_bool
// In C++ bool is a keyword, so there is no need to redefine it. // In C++ bool is a keyword, so there is no need to redefine it.
@@ -38,6 +38,14 @@ typedef u8 bool;
#define false 0 #define false 0
#endif #endif
#ifndef memcpy
extern void* memcpy(void *dest, const void * src, size_t n);
#endif
#ifndef typeof
#define typeof __typeof__
#endif
#define dbg(N) kprintf("\e[95m%d\n",N) #define dbg(N) kprintf("\e[95m%d\n",N)
#define nameof(V) #V #define nameof(V) #V
@@ -132,4 +140,4 @@ You can even embed it into macro in header (see kprint.h)
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -22,7 +22,7 @@ and register it.
## type descriptors ## type descriptors
Every registered type should have it's own descriptor (`ktDescriptor`). It's a struct, which contains some information about type and pointers to some specific functions for this type (`toString`, `freeMembers`). Every registered type should have it's own descriptor (`ktDescriptor`). It's a struct, which contains some information about type and pointers to some specific functions for this type (`toString`, `destruct`).
## type registration ## type registration

View File

@@ -5,14 +5,14 @@
// accepts char* (ptr to char) and char* (ptr to string) // accepts char* (ptr to char) and char* (ptr to string)
// uses format kp_s and kp_c to determine what type is <c> argument // uses format kp_s and kp_c to determine what type is <c> argument
char* __toString_char(void* c, u32 fmt) { char* __toString_char(allocator_ptr al, void* c, u32 fmt) {
// *c=char* // *c=char*
if(kp_fmt_dataFormat(fmt)==kp_s){ if(kp_fmt_dataFormat(fmt)==kp_s){
return cptr_copy((char*)c); // to avoid segmentation fault on free() when *c allocalet on stack return cptr_copy(al, (char*)c); // to avoid segmentation fault on free() when *c allocalet on stack
} }
// *c=char // *c=char
if(kp_fmt_dataFormat(fmt)==kp_c){ if(kp_fmt_dataFormat(fmt)==kp_c){
char* cc=malloc(2); char* cc=allocator_alloc(al, 2);
cc[0]=*(char*)c; cc[0]=*(char*)c;
cc[1]=0; cc[1]=0;
return cc; return cc;
@@ -20,10 +20,10 @@ char* __toString_char(void* c, u32 fmt) {
else throw(ERR_FORMAT); else throw(ERR_FORMAT);
} }
char* __toString_bool(void* c, u32 fmt) { char* __toString_bool(allocator_ptr al, void* c, u32 fmt) {
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" }; static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2; u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
char* rez=malloc(6); char* rez=allocator_alloc(al, 6);
rez[0]=_strbool[strind][0]; rez[0]=_strbool[strind][0];
rez[1]=_strbool[strind][1]; rez[1]=_strbool[strind][1];
rez[2]=_strbool[strind][2]; rez[2]=_strbool[strind][2];
@@ -33,7 +33,7 @@ char* __toString_bool(void* c, u32 fmt) {
return rez; return rez;
} }
char* toString_i64(i64 n){ char* toString_i64(allocator_ptr al, i64 n){
i64 d=n<0 ? -1*n : n; i64 d=n<0 ? -1*n : n;
char str[32]; char str[32];
u8 i=sizeof(str); u8 i=sizeof(str);
@@ -46,10 +46,10 @@ char* toString_i64(i64 n){
} }
if(n<0) if(n<0)
str[--i]='-'; str[--i]='-';
return cptr_copy((char*)str+i); return cptr_copy(al, (char*)str+i);
} }
char* toString_u64(u64 n, bool withPostfix, bool uppercase){ char* toString_u64(allocator_ptr al, u64 n, bool withPostfix, bool uppercase){
char str[32]; char str[32];
u8 i=sizeof(str); u8 i=sizeof(str);
str[--i]=0; str[--i]=0;
@@ -61,33 +61,30 @@ char* toString_u64(u64 n, bool withPostfix, bool uppercase){
str[--i]='0' + n%10; str[--i]='0' + n%10;
n/=10; n/=10;
} }
return cptr_copy((char*)str+i); return cptr_copy(al, (char*)str+i);
} }
#define _toString_float_impl(bufsize, maxPrecision) { \ #define _toString_float_impl(al, bufsize, maxPrecision) { \
char str[bufsize]; \ char str[bufsize]; \
if(precision>maxPrecision) \ if(precision>maxPrecision) \
throw("too big precision"); \ throw("too big precision"); \
if(precision==0) \ if(precision==0) \
precision=toString_float_default_precision; \ precision=toString_float_default_precision; \
i32 cn=IFMSC( \ i32 cn=sprintf_s(str, bufsize, "%.*f", precision, n); \
sprintf_s(str, bufsize, "%.*f", precision, n), \
sprintf(str, "%.*f", precision, n) \
); \
/* remove trailing zeroes except .0*/ \ /* remove trailing zeroes except .0*/ \
while(str[cn-1]=='0' && str[cn-2]!='.') \ while(str[cn-1]=='0' && str[cn-2]!='.') \
cn--; \ cn--; \
if(withPostfix) \ if(withPostfix) \
str[cn++]= uppercase ? 'F' : 'f'; \ str[cn++]= uppercase ? 'F' : 'f'; \
str[cn]='\0'; \ str[cn]='\0'; \
return cptr_copy(str); \ return cptr_copy(al, str); \
} }
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase) char* toString_f32(allocator_ptr al, f32 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(48, toString_f32_max_precision) _toString_float_impl(al, 48, toString_f32_max_precision)
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase) char* toString_f64(allocator_ptr al, f64 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(512, toString_f64_max_precision) _toString_float_impl(al, 512, toString_f64_max_precision)
#define byte_to_bits(byte) { \ #define byte_to_bits(byte) { \
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \ str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \
@@ -100,9 +97,9 @@ char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase)
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \ str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \
} }
char* toString_bin(void* _bytes, u32 size, bool inverse, bool withPrefix){ char* toString_bin(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool withPrefix){
char* bytes=_bytes; char* bytes=_bytes;
char* str=malloc(size*8 + (withPrefix?2:0) +1); char* str=allocator_alloc(al, size*8 + (withPrefix?2:0) +1);
u32 cn=0; // char number u32 cn=0; // char number
if(withPrefix){ if(withPrefix){
str[cn++]='0'; str[cn++]='0';
@@ -126,19 +123,19 @@ char _4bitsHex(u8 u, bool uppercase){
case 0: case 1: case 2: case 3: case 4: case 0: case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8: case 9: case 5: case 6: case 7: case 8: case 9:
return '0'+u; return '0'+u;
case 0xA: case 0xB: case 0xC: case 0xA: case 0xB: case 0xC:
case 0xD: case 0xE: case 0xF: case 0xD: case 0xE: case 0xF:
return (uppercase ? 'A' : 'a') + u -10; return (uppercase ? 'A' : 'a') + u -10;
default: default:
dbg(u); dbg(u);
throw("incorrect number"); throw("incorrect number");
return 219; return (char)219;
} }
} }
char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){ char* toString_hex(allocator_ptr al, void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){
char* bytes=_bytes; char* bytes=_bytes;
char* str=malloc(size*2 + (withPrefix?2:0) + 1); char* str=allocator_alloc(al, size*2 + (withPrefix?2:0) + 1);
u32 cn=0; // char number u32 cn=0; // char number
if(withPrefix){ if(withPrefix){
str[cn++]='0'; str[cn++]='0';
@@ -147,7 +144,7 @@ char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool u
// left to right // left to right
if(inverse){ if(inverse){
// byte number // byte number
for(i32 bn=size-1; bn>=0; bn--){ for(i32 bn=size-1; bn>=0; bn--){
unsigned char byte=bytes[bn]; unsigned char byte=bytes[bn];
str[cn++]=_4bitsHex(byte/16, uppercase); str[cn++]=_4bitsHex(byte/16, uppercase);
str[cn++]=_4bitsHex(byte%16, uppercase); str[cn++]=_4bitsHex(byte%16, uppercase);
@@ -166,67 +163,58 @@ char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool u
} }
#define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){ \ #define __toString_i_def(BITS) char* __toString_i##BITS(allocator_ptr al, void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_i: ; \ case kp_i: ; \
i##BITS n=*(i##BITS*)_n; \ i##BITS n=*(i##BITS*)_n; \
return toString_i64(n); \ return toString_i64(al,n); \
case kp_b: \ case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
return NULL; \ return NULL; \
} \ } \
} }
__toString_i32_def(8)
__toString_i32_def(16)
__toString_i32_def(32)
__toString_i32_def(64)
#define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){ \ __toString_i_def(8)
__toString_i_def(16)
__toString_i_def(32)
__toString_i_def(64)
#define __toString_u_def(BITS) char* __toString_u##BITS(allocator_ptr al, void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_u: ; \ case kp_u: ; \
u##BITS n=*(u##BITS*)_n; \ u##BITS n=*(u##BITS*)_n; \
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \ return toString_u64(al, n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \ case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
return NULL; \ return NULL; \
} \ } \
} }
__toString_u_def(8) __toString_u_def(8)
__toString_u_def(16) __toString_u_def(16)
__toString_u_def(32) __toString_u_def(32)
// __toString_u_def(64) __toString_u_def(64)
char* __toString_u64(void* _n, u32 f){
switch(kp_fmt_dataFormat(f)){
case kp_u: ;
u64 n=*(u64*)_n;
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));
case kp_b:
return toString_bin(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));
case kp_h:
return toString_hex(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));
default:
kprintf("\n%u\n", kp_fmt_dataFormat(f)); throw(ERR_FORMAT); return NULL; }
}
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){ \
#define __toString_f_def(BITS) char* __toString_f##BITS(allocator_ptr al, void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \ switch(kp_fmt_dataFormat(f)){ \
case kp_f: ; \ case kp_f: ; \
f##BITS n=*(f##BITS*)_n; \ f##BITS n=*(f##BITS*)_n; \
return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \ return toString_f64(al, n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \ case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \ return toString_bin(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \ case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \ return toString_hex(al, _n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \ default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \ kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \ throw(ERR_FORMAT); \
@@ -234,5 +222,5 @@ char* __toString_u64(void* _n, u32 f){
} \ } \
} }
__toString_float_def(32) __toString_f_def(32)
__toString_float_def(64) __toString_f_def(64)

View File

@@ -5,43 +5,44 @@ extern "C" {
#endif #endif
#include "../errors.h" #include "../errors.h"
#include "../memory/allocator_base.h"
// accepts char* (ptr to char) and char* (ptr to string) // accepts char* (ptr to char) and char* (ptr to string)
// uses format kp_s and kp_c to determine what type is <c> argument // uses format kp_s and kp_c to determine what type is <c> argument
char* __toString_char(void* c, u32 fmt); char* __toString_char(allocator_ptr al, void* c, u32 fmt);
// bool // bool
char* __toString_bool(void* c, u32 fmt); char* __toString_bool(allocator_ptr al, void* c, u32 fmt);
// signed int // signed int
char* toString_i64(i64 n); char* toString_i64(allocator_ptr al, i64 n);
char* __toString_i8(void* n, u32 fmt); char* __toString_i8(allocator_ptr al, void* n, u32 fmt);
char* __toString_i16(void* n, u32 fmt); char* __toString_i16(allocator_ptr al, void* n, u32 fmt);
char* __toString_i32(void* n, u32 fmt); char* __toString_i32(allocator_ptr al, void* n, u32 fmt);
char* __toString_i64(void* n, u32 fmt); char* __toString_i64(allocator_ptr al, void* n, u32 fmt);
// unsigned int // unsigned int
char* toString_u64(u64 n, bool withPostfix, bool uppercase); char* toString_u64(allocator_ptr al, u64 n, bool withPostfix, bool uppercase);
char* __toString_u8(void* n, u32 fmt); char* __toString_u8(allocator_ptr al, void* n, u32 fmt);
char* __toString_u16(void* n, u32 fmt); char* __toString_u16(allocator_ptr al, void* n, u32 fmt);
char* __toString_u32(void* n, u32 fmt); char* __toString_u32(allocator_ptr al, void* n, u32 fmt);
char* __toString_u64(void* n, u32 fmt); char* __toString_u64(allocator_ptr al, void* n, u32 fmt);
// float // float
#define toString_f32_max_precision 6 #define toString_f32_max_precision 6
#define toString_f64_max_precision 15 #define toString_f64_max_precision 15
#define toString_float_default_precision 6 #define toString_float_default_precision 6
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf char* toString_f32(allocator_ptr al, f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf char* toString_f64(allocator_ptr al, f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* __toString_f32(void* n, u32 fmt); char* __toString_f32(allocator_ptr al, void* n, u32 fmt);
char* __toString_f64(void* n, u32 fmt); char* __toString_f64(allocator_ptr al, void* n, u32 fmt);
///@param inverse set to true for little endian numbers (their bytes are in reverse order) ///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_bin(void* bytes, u32 size, bool inverse, bool withPrefix); char* toString_bin(allocator_ptr al, void* bytes, u32 size, bool inverse, bool withPrefix);
///@param inverse set to true for little endian numbers (their bytes are in reverse order) ///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_hex(void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase); char* toString_hex(allocator_ptr al, void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,5 +1,4 @@
#include "../base.h" #include "../base.h"
#include "../../Array/Array.h"
#include "../../Autoarr/Autoarr.h" #include "../../Autoarr/Autoarr.h"
#include "../../SearchTree/SearchTree.h" #include "../../SearchTree/SearchTree.h"
#include "../../Hashtable/Hashtable.h" #include "../../Hashtable/Hashtable.h"
@@ -29,21 +28,6 @@ void kt_initKerepTypes(){
// ktDescriptor // ktDescriptor
kt_register(ktDescriptor); kt_register(ktDescriptor);
// base type arrays
kt_register(Array_char);
kt_register(Array_bool);
kt_register(Array_f32);
kt_register(Array_f64);
kt_register(Array_i8);
kt_register(Array_u8);
kt_register(Array_i16);
kt_register(Array_u16);
kt_register(Array_i32);
kt_register(Array_u32);
kt_register(Array_i64);
kt_register(Array_u64);
kt_register(Array_Pointer);
// base type autoarrs // base type autoarrs
kt_register(Autoarr_Pointer); kt_register(Autoarr_Pointer);
kt_register(Autoarr_char); kt_register(Autoarr_char);
@@ -61,7 +45,6 @@ void kt_initKerepTypes(){
// Unitype // Unitype
kt_register(Unitype); kt_register(Unitype);
kt_register(Array_Unitype);
kt_register(Autoarr_Unitype); kt_register(Autoarr_Unitype);
// STNode // STNode
@@ -76,12 +59,16 @@ void kt_initKerepTypes(){
// string // string
kt_register(string); kt_register(string);
kt_register(Array_string);
kt_register(Autoarr_string); kt_register(Autoarr_string);
// StringBuilder // StringBuilder
kt_register(StringBuilder); kt_register(StringBuilder);
//File // File
kt_register(FileHandle); kt_register(FileHandle);
// Allocators
kt_register(CstdAllocator);
kt_register(LinearAllocator);
kt_register(StackingAllocator);
} }

View File

@@ -9,4 +9,4 @@ void kt_initKerepTypes();
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -7,6 +7,7 @@ extern "C" {
#include "../std.h" #include "../std.h"
#include "ktid.h" #include "ktid.h"
#include "typedef_macros.h" #include "typedef_macros.h"
#include "../memory/allocator_base.h"
#define kt_declare(TYPE)\ #define kt_declare(TYPE)\
ktid_declare(TYPE);\ ktid_declare(TYPE);\
@@ -19,25 +20,25 @@ extern "C" {
.name=#TYPE, \ .name=#TYPE, \
.id=ktid_undefined, \ .id=ktid_undefined, \
.size=sizeof(TYPE), \ .size=sizeof(TYPE), \
.freeMembers=FREE_MEMBERS_F, \ .destruct=FREE_MEMBERS_F, \
.toString=TOSTRING_F \ .toString=TOSTRING_F \
}; \ }; \
ktDescriptor ktDescriptor_##TYPE##_Ptr={\ ktDescriptor ktDescriptor_##TYPE##_Ptr={\
.name=#TYPE "_Ptr", \ .name=#TYPE "_Ptr", \
.id=ktid_undefined, \ .id=ktid_undefined, \
.size=sizeof(TYPE), \ .size=sizeof(TYPE), \
.freeMembers=FREE_MEMBERS_F, \ .destruct=FREE_MEMBERS_F, \
.toString=TOSTRING_F \ .toString=TOSTRING_F \
}; };
typedef void (*freeMembers_t)(void*); typedef void (*destruct_t)(void*);
typedef char* (*toString_t)(void* obj, u32 fmt); typedef char* (*toString_t)(allocator_ptr al, void* obj, u32 fmt);
STRUCT(ktDescriptor, STRUCT(ktDescriptor,
char* name; char* name;
ktid id; ktid id;
u16 size; u16 size;
freeMembers_t freeMembers; // NULL or function which frees all struct members destruct_t destruct; // NULL or function which frees all struct members
toString_t toString; // NULL or function which generates string representaion of object toString_t toString; // NULL or function which generates string representaion of object
) )
@@ -48,4 +49,4 @@ STRUCT(ktDescriptor,
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -17,33 +17,33 @@ kt_define(i64, NULL, __toString_i64);
kt_define(u64, NULL, __toString_u64); kt_define(u64, NULL, __toString_u64);
char* ktDescriptor_toString(ktDescriptor* d){ char* ktDescriptor_toString(allocator_ptr al, ktDescriptor* d){
const char* n="null"; const char* n="null";
char *s0 = toString_u64(d->id, 0,0); char *s0 = toString_u64(al, d->id, 0,0);
char *s1 = toString_u64(d->size, 0,0); char *s1 = toString_u64(al, d->size, 0,0);
char *s2 = d->toString ? toString_hex(d->toString, sizeof(void*), 0,1,0) : n; char *s2 = d->toString ? toString_hex(al, d->toString, sizeof(void*), 0,1,0) : n;
char *s3 = d->freeMembers ? toString_hex(d->freeMembers, sizeof(void*), 0,1,0) : n; char *s3 = d->destruct ? toString_hex(al, d->destruct, sizeof(void*), 0,1,0) : n;
char *rez=cptr_concat("ktDescriptor {" char *rez=cptr_concat(al, "ktDescriptor {"
" name:", d->name, " name:", d->name,
" id:",s0, " id:",s0,
" size:",s1, " size:",s1,
" toString:",s2, " toString:",s2,
" freeMembers:",s3, " destruct:",s3,
" }"); " }");
free(s0); if(s3!=n) allocator_free(al, s3);
free(s1); if(s2!=n) allocator_free(al, s2);
if(s2!=n) free(s2); allocator_free(al, s1);
if(s3!=n) free(s3); allocator_free(al, s0);
return rez; return rez;
} }
char* _ktDescriptor_toString(void* _d, u32 fmt) { return ktDescriptor_toString(_d); } char* _ktDescriptor_toString(allocator_ptr al, void* _d, u32 fmt) { return ktDescriptor_toString(al, _d); }
kt_define(ktDescriptor, NULL, _ktDescriptor_toString); kt_define(ktDescriptor, NULL, _ktDescriptor_toString);
typedef ktDescriptor* ktDescriptor_Ptr; typedef ktDescriptor* ktDescriptor_Ptr;
// type descriptors are stored here during initialization // type descriptors are stored here during initialization
Autoarr(Pointer)* __descriptorPointers=NULL; Autoarr(Pointer)* __descriptorPointers=NULL;
// here type descriptors are stored when initialization is complited // here type descriptors are stored when initialization is complited
ktDescriptor** typeDescriptors=NULL; ktDescriptor** typeDescriptors=NULL;
@@ -56,15 +56,16 @@ ktDescriptorsState initState=NotInitialized;
void kt_beginInit(){ void kt_beginInit(){
kprintf("\e[94mtype descriptors initializing...\n"); kprintf("\e[94mtype descriptors initializing...\n");
__descriptorPointers=Autoarr_create(Pointer, 256, 256); Autoarr_construct(__descriptorPointers, Pointer, 256, NULL);
} }
void kt_endInit(){ void kt_endInit(){
if(__descriptorPointers==NULL) if(__descriptorPointers==NULL)
throw(ERR_NULLPTR); throw(ERR_NULLPTR);
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers); typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers, CstdAllocator_instPtr);
Autoarr_free(__descriptorPointers,true); Autoarr_destruct(__descriptorPointers);
if(typeDescriptors==NULL) throw(ERR_NULLPTR); if(typeDescriptors==NULL)
throw(ERR_NULLPTR);
kprintf("\e[92minitialized %u type descriptors\n", ktid_last); kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
} }
@@ -81,6 +82,6 @@ ktDescriptor* ktDescriptor_get(ktid id){
return typeDescriptors[id]; return typeDescriptors[id];
} }
void kt_free(){ void kt_deinit(){
free(typeDescriptors); free(typeDescriptors);
} }

View File

@@ -23,10 +23,10 @@ void kt_endInit();
/// @param id id of registered type /// @param id id of registered type
ktDescriptor* ktDescriptor_get(ktid id); ktDescriptor* ktDescriptor_get(ktid id);
char* ktDescriptor_toString(ktDescriptor* d); char* ktDescriptor_toString(allocator_ptr al, ktDescriptor* d);
// call it to free heap-allocated ktDescriptors array // call it to free heap-allocated ktDescriptors array
void kt_free(); void kt_deinit();
kt_declare(Pointer); kt_declare(Pointer);
kt_declare(char); kt_declare(char);
@@ -46,4 +46,4 @@ kt_declare(ktDescriptor);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -25,4 +25,4 @@ static const ktid ktid_undefined=-1;
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -8,6 +8,10 @@
ENUM_MEMBERS \ ENUM_MEMBERS \
} __attribute__((__packed__)) ENUM_NAME; } __attribute__((__packed__)) ENUM_NAME;
#define PACKED_STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME { \
STRUCT_MEMBERS \
} __attribute__((__packed__)) STRUCT_NAME;
#define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \ #define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \
typedef struct STRUCT_NAME { \ typedef struct STRUCT_NAME { \
STRUCT_MEMBERS \ STRUCT_MEMBERS \

View File

@@ -1,40 +1,36 @@
#include "../../kprint/kprint_format.h" #include "../../kprint/kprint_format.h"
#include "../base.h" #include "../base.h"
char *__Unitype_toString(void *_u, u32 fmt) char *__Unitype_toString(allocator_ptr al, void *_u, u32 fmt)
{ {
return Unitype_toString(*(Unitype *)_u, fmt); return Unitype_toString(al, *(Unitype *)_u, fmt);
} }
kt_define(Unitype, __UnitypePtr_free, __Unitype_toString); kt_define(Unitype, (destruct_t)Unitype_destruct, __Unitype_toString);
void Unitype_free(Unitype u) void Unitype_destruct(Unitype* u)
{ {
if (u.typeId == ktid_undefined) if (u->typeId == ktid_undefined)
{ {
if (u.VoidPtr != NULL) if (u->VoidPtr != NULL)
throw("unitype with undefined typeId has value"); throw("unitype with undefined typeId has value");
return; return;
} }
ktDescriptor *type = ktDescriptor_get(u.typeId); ktDescriptor *type = ktDescriptor_get(u->typeId);
if (type->freeMembers) if (type->destruct)
type->freeMembers(u.VoidPtr); type->destruct(u->VoidPtr);
if (u.allocatedInHeap) if (u->allocatedInHeap)
free(u.VoidPtr); free(u->VoidPtr);
}
void __UnitypePtr_free(void *u)
{
Unitype_free(*(Unitype *)u);
} }
char *Unitype_toString(Unitype u, u32 fmt) char *Unitype_toString(allocator_ptr al, Unitype u, u32 fmt)
{ {
if (u.typeId == ktid_undefined) if (u.typeId == ktid_undefined)
{ {
if (u.VoidPtr != NULL) if (u.VoidPtr != NULL)
throw("unitype with undefined typeId has value"); throw("unitype with undefined typeId has value");
return cptr_copy("{ERROR_TYPE}"); return cptr_copy(al, "{ERROR_TYPE}");
} }
if (fmt == 0) if (fmt == 0)
@@ -74,7 +70,7 @@ char *Unitype_toString(Unitype u, u32 fmt)
else if (u.typeId == ktid_name(Pointer)) else if (u.typeId == ktid_name(Pointer))
{ {
if (u.VoidPtr == NULL) if (u.VoidPtr == NULL)
return cptr_copy("{ UniNull }"); return cptr_copy(al, "{ UniNull }");
fmt = kp_h; fmt = kp_h;
} }
} }
@@ -82,19 +78,22 @@ char *Unitype_toString(Unitype u, u32 fmt)
ktDescriptor *type = ktDescriptor_get(u.typeId); ktDescriptor *type = ktDescriptor_get(u.typeId);
char *valuestr; char *valuestr;
if (type->toString) if (type->toString)
valuestr = type->toString(u.VoidPtr, fmt); valuestr = type->toString(al, u.VoidPtr, fmt);
else else
valuestr = "ERR_NO_TOSTRING_FUNC"; valuestr = "ERR_NO_TOSTRING_FUNC";
char *rezult = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"), char *rezult = cptr_concat(al, "{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
", value:", valuestr, " }"); ", value:", valuestr, " }");
if (type->toString) if (type->toString)
free(valuestr); allocator_free(al, valuestr);
return rezult; return rezult;
} }
void printuni(Unitype v) void printuni(Unitype v)
{ {
char *s = Unitype_toString(v, 0); LinearAllocator _al;
LinearAllocator_construct(&_al, 128);
allocator_ptr al=&_al.base;
char *s = Unitype_toString(al, v, 0);
fputs(s, stdout); fputs(s, stdout);
free(s); LinearAllocator_destruct(&_al);
} }

View File

@@ -17,7 +17,7 @@ STRUCT(Unitype,
char Bytes[8]; char Bytes[8];
}; };
ktid typeId; ktid typeId;
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr* bool allocatedInHeap; // should Unitype_destruct call free() to VoidPtr*
) )
@@ -45,11 +45,10 @@ STRUCT(Unitype,
#define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE)) #define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE))
// frees VoidPtr value or does nothing if type isn't pointer // frees VoidPtr value or does nothing if type isn't pointer
void Unitype_free(Unitype u); void Unitype_destruct(Unitype* u);
void __UnitypePtr_free(void* u); char* Unitype_toString(allocator_ptr al, Unitype v, u32 fmt);
char* Unitype_toString(Unitype v, u32 fmt);
void printuni(Unitype v); void printuni(Unitype v);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -3,27 +3,27 @@
ktid __typeFromFormat(kp_fmt f){ ktid __typeFromFormat(kp_fmt f){
ktid typeId=kp_fmt_ktid(f); ktid typeId=kp_fmt_ktid(f);
if(typeId) if(typeId)
return typeId; return typeId;
switch(kp_fmt_dataFormat(f)){ switch(kp_fmt_dataFormat(f)){
case kp_i: case kp_i:
case kp_h: case kp_h:
case kp_b: case kp_b:
return ktid_name(i64); return ktid_name(i64);
case kp_u: case kp_u:
return ktid_name(u64); return ktid_name(u64);
case kp_f: case kp_f:
return ktid_name(f64); return ktid_name(f64);
case kp_c: case kp_c:
return ktid_name(char); return ktid_name(char);
case kp_s: case kp_s:
return ktid_ptrName(char); return ktid_ptrName(char);
default: default:
return ktid_undefined; return ktid_undefined;
} }
} }
Maybe __next_toString(kp_fmt f, void* object){ Maybe __next_toString(allocator_ptr al, kp_fmt f, void* object){
// detecting type // detecting type
ktid typeId=__typeFromFormat(f); ktid typeId=__typeFromFormat(f);
if(typeId==ktid_undefined) if(typeId==ktid_undefined)
@@ -35,7 +35,7 @@ Maybe __next_toString(kp_fmt f, void* object){
ktDescriptor* type=ktDescriptor_get(typeId); ktDescriptor* type=ktDescriptor_get(typeId);
if(!type->toString) if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;); safethrow("type descriptor doesnt have toString() func",;);
return SUCCESS(UniHeapPtr(char, type->toString(object, f))); return SUCCESS(UniHeapPtr(char, type->toString(al, object, f)));
} }
Maybe check_argsN(u8 n){ Maybe check_argsN(u8 n){
@@ -44,52 +44,60 @@ Maybe check_argsN(u8 n){
return MaybeNull; return MaybeNull;
} }
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){ Maybe __ksprint(allocator_ptr al, u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;); try(check_argsN(n), _,;);
n/=2; n/=2;
StringBuilder* strb=StringBuilder_create(); StringBuilder _sb;
StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),mStr,;); try(__next_toString(al, formats[i], &objects[i]),mStr,;);
StringBuilder_append_cptr(strb, mStr.value.VoidPtr); StringBuilder_append_cptr(sb, mStr.value.VoidPtr);
Unitype_free(mStr.value); allocator_free(al, mStr.value.VoidPtr);
} }
char* rezult=StringBuilder_build(strb).ptr; char* rezult=StringBuilder_build(sb).ptr;
return SUCCESS(UniHeapPtr(char, rezult)); return SUCCESS(UniHeapPtr(char, rezult));
} }
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){ Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;); try(check_argsN(n), _,;);
n/=2; n/=2;
LinearAllocator _al;
LinearAllocator_construct(&_al, 256);
allocator_ptr al=&_al.base;
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),maybeStr,;); try(__next_toString(al, formats[i], &objects[i]),maybeStr, LinearAllocator_destruct(&_al));
if(fputs(maybeStr.value.VoidPtr, file)==EOF) if(fputs(maybeStr.value.VoidPtr, file)==EOF)
safethrow("can't write string to file", Unitype_free(maybeStr.value)); safethrow("can't write string to file", LinearAllocator_destruct(&_al));
Unitype_free(maybeStr.value);
} }
fflush(file); fflush(file);
LinearAllocator_destruct(&_al);
return MaybeNull; return MaybeNull;
} }
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
tryLast(check_argsN(n), _,;); tryLast(check_argsN(n), _,;);
n/=2; n/=2;
LinearAllocator _al;
LinearAllocator_construct(&_al, 256);
allocator_ptr al=&_al.base;
for(u8 i=0; i<n; i++){ for(u8 i=0; i<n; i++){
kp_fmt fmt=formats[i]; kp_fmt fmt=formats[i];
kprint_setColor(fmt); kprint_setColor(fmt);
tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray)); tryLast(__next_toString(al, fmt, &objects[i]), maybeStr,
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \ kprint_setColor(kp_bgBlack|kp_fgGray););
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF)
throw("can't write string to stdout"); throw("can't write string to stdout");
//, Unitype_free(maybeStr.value)
Unitype_free(maybeStr.value);
} }
fflush(stdout); fflush(stdout);
LinearAllocator_destruct(&_al);
} }
#if defined(_WIN32)|| defined(_WIN64) #if defined(_WIN32)|| defined(_WIN64)
#include <windows.h> #include <windows.h>
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED #define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
DWORD kp_fgColor_toWin(kp_fgColor f){ DWORD kp_fgColor_toWin(kp_fgColor f){
//kprintf("fg: %x\n", f); //kprintf("fg: %x\n", f);
switch(f){ switch(f){
case kp_fgBlack: return 0; case kp_fgBlack: return 0;
@@ -112,7 +120,7 @@ DWORD kp_fgColor_toWin(kp_fgColor f){
} }
} }
DWORD kp_bgColor_toWin(kp_bgColor f){ DWORD kp_bgColor_toWin(kp_bgColor f){
//kprintf("bg: %x\n", f); //kprintf("bg: %x\n", f);
switch(f){ switch(f){
case kp_bgBlack: return 0; case kp_bgBlack: return 0;
@@ -167,17 +175,19 @@ void kprint_setColor(kp_fmt f){
ktDescriptor* type=ktDescriptor_get(format.typeId); ktDescriptor* type=ktDescriptor_get(format.typeId);
if(!type->toString) if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;); safethrow("type descriptor doesnt have toString() func",;);
StringBuilder* strb=StringBuilder_create(); StringBuilder _sb;
StringBuilder_append_char(strb, '['); StringBuilder* sb=&_sb;
StringBuilder_construct(sb, al);
StringBuilder_append_char(sb, '[');
for (u16 e=1; e<count; e++){ for (u16 e=1; e<count; e++){
StringBuilder_append_char(strb, ' '); StringBuilder_append_char(sb, ' ');
char* elStr=type->toString(array+type->size*e, &format); char* elStr=type->toString(array+type->size*e, &format);
StringBuilder_append_cptr(strb, elStr); StringBuilder_append_cptr(sb, elStr);
StringBuilder_append_char(strb, ','); StringBuilder_append_char(sb, ',');
} }
StringBuilder_rmchar(strb); StringBuilder_rmchar(sb);
StringBuilder_append_char(strb, ' '); StringBuilder_append_char(sb, ' ');
StringBuilder_append_char(strb, ']'); StringBuilder_append_char(sb, ']');
} */ } */
static const char* _kp_colorNames[16]={ static const char* _kp_colorNames[16]={
@@ -199,12 +209,12 @@ static const char* _kp_colorNames[16]={
"white" "white"
}; };
char* kp_bgColor_toString(kp_fmt c){ char* kp_bgColor_toString(allocator_ptr al, kp_bgColor c){
u32 color_index=(c&0x00f00000)>>20; u32 color_index=(c&0x00f00000)>>20;
if(color_index>15) throw(ERR_WRONGINDEX); if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index]; return _kp_colorNames[color_index];
} }
char* kp_fgColor_toString(kp_fmt c){ char* kp_fgColor_toString(allocator_ptr al, kp_fgColor c){
u32 color_index=(c&0x00f00000)>>24; u32 color_index=(c&0x00f00000)>>24;
if(color_index>15) throw(ERR_WRONGINDEX); if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index]; return _kp_colorNames[color_index];

View File

@@ -9,7 +9,7 @@ extern "C" {
/* /*
This file looks like a mess, but all cotnent here just solves the problem of putting variadic arguments to array of formats and array of objects. This file looks like a mess, but all cotnent here just solves the problem of putting variadic arguments to array of formats and array of objects.
*/ */
@@ -18,11 +18,11 @@ typedef union {
u64 u64; u64 u64;
f64 f64; f64 f64;
void* ptr; void* ptr;
} __kp_value_union; } __kp_value_union;
static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; } static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; }
static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; } static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; }
#define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V) #define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V)
@@ -70,18 +70,18 @@ static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64
__kp_argsToObjs32(ARGS)) __kp_argsToObjs32(ARGS))
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects); Maybe __ksprint(allocator_ptr al, u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param ARGS kp_fmt, value, kp_fmt, value... /// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<char*> ///@returns Maybe<char*>
#define ksprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \ #define ksprint(ALLOCATOR, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__ksprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \ __ksprint(ALLOCATOR, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
) )
/*-Wint-conversion warning was produced during value to __kp_value_union conversion*/ /*-Wint-conversion warning was produced during value to __kp_value_union conversion*/
Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects); Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param FD FILE* /// @param FD FILE*
/// @param ARGS kp_fmt, value, kp_fmt, value... /// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<void> ///@returns Maybe<void>
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \ #define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
@@ -99,4 +99,4 @@ void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -4,10 +4,12 @@
extern "C" { extern "C" {
#endif #endif
#include "../base/memory/allocator_base.h"
// 10000000 00000000 00000000 00000000 // 10000000 00000000 00000000 00000000
// ^ ^^^^ // ^ ^^^^
// | color num // | color num
// fgColorSet flag // fgColorSet flag
PACKED_ENUM(kp_fgColor, PACKED_ENUM(kp_fgColor,
/// black foreground /// black foreground
kp_fgBlack = 0x80000000, kp_fgBlack = 0x80000000,
@@ -40,7 +42,7 @@ PACKED_ENUM(kp_fgColor,
/// cyan foreground /// cyan foreground
kp_fgCyan = 0x8e000000, kp_fgCyan = 0x8e000000,
/// white foreground /// white foreground
kp_fgWhite = 0x8f000000 kp_fgWhite = 0x8f000000
) )
// 01000000 00000000 00000000 00000000 // 01000000 00000000 00000000 00000000
@@ -81,9 +83,9 @@ PACKED_ENUM(kp_bgColor,
kp_bgWhite = 0x40f00000 kp_bgWhite = 0x40f00000
) )
char* kp_bgColor_toString(kp_bgColor c); char* kp_bgColor_toString(allocator_ptr al, kp_bgColor c);
char* kp_fgColor_toString(kp_fgColor c); char* kp_fgColor_toString(allocator_ptr al, kp_fgColor c);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -45,9 +45,9 @@ PACKED_ENUM(kp_dataFmt,
#define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000) #define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000)
#define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff) #define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff)
///@param f bgColor | fgColor ///@param f bgColor | fgColor
void kprint_setColor(kp_fmt f); void kprint_setColor(kp_fmt f);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -49,6 +49,9 @@ void kprintf(const char* format, ...){
va_list vl; va_list vl;
va_start(vl, format); va_start(vl, format);
u32 i=0; u32 i=0;
LinearAllocator _al;
LinearAllocator_construct(&_al, 128);
allocator_ptr al=(allocator_ptr)&_al;
for(char c=format[i++]; c!=0; c=format[i++]){ for(char c=format[i++]; c!=0; c=format[i++]){
// value format specifiers // value format specifiers
if(c=='%'){ if(c=='%'){
@@ -58,18 +61,18 @@ void kprintf(const char* format, ...){
format_escape_seq: format_escape_seq:
switch (c) { switch (c) {
case 'u': case 'u':
argstr=toString_u64( argstr=toString_u64(al,
l ? va_arg(vl, u64) : va_arg(vl, u32) l ? va_arg(vl, u64) : va_arg(vl, u32)
,0,0); ,0,0);
break; break;
case 'i': case 'd': case 'i': case 'd':
argstr=toString_i64( argstr=toString_i64(al,
l ? va_arg(vl, i64) : va_arg(vl, i32) l ? va_arg(vl, i64) : va_arg(vl, i32)
); );
break; break;
case 'f': case 'f':
// f32 is promoted to f64 when passed through '...' // f32 is promoted to f64 when passed through '...'
argstr=toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0); argstr=toString_f64(al, va_arg(vl, f64), toString_float_default_precision,0,0);
break; break;
case 'l': case 'l':
l=true; l=true;
@@ -78,16 +81,16 @@ void kprintf(const char* format, ...){
break; break;
case 'p': ; case 'p': ;
void* phex=va_arg(vl, void*); void* phex=va_arg(vl, void*);
argstr=toString_hex(&phex,getEndian()==LittleEndian,sizeof(phex),1,0); argstr=toString_hex(al, &phex,getEndian()==LittleEndian,sizeof(phex),1,0);
break; break;
case 'x': ; case 'x': ;
if(l){ if(l){
u64 xhex=va_arg(vl, u64); u64 xhex=va_arg(vl, u64);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1); argstr=toString_hex(al, &xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
} }
else { else {
u32 xhex=va_arg(vl, u32); u32 xhex=va_arg(vl, u32);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1); argstr=toString_hex(al, &xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
} }
break; break;
case 's': ; case 's': ;
@@ -98,7 +101,7 @@ void kprintf(const char* format, ...){
fputs(cptr, stdout); fputs(cptr, stdout);
break; break;
case 'c': case 'c':
argstr=malloc(2); argstr=allocator_alloc(al, 2);
argstr[0]=(char)va_arg(vl,int); argstr[0]=(char)va_arg(vl,int);
argstr[1]=0; argstr[1]=0;
break; break;
@@ -111,10 +114,9 @@ void kprintf(const char* format, ...){
} }
if(argstr){ if(argstr){
fputs(argstr, stdout); fputs(argstr, stdout);
free(argstr);
} }
} }
// escape sequences // escape sequences
else if(c=='\e'){ else if(c=='\e'){
IFWIN( IFWIN(
/* WINDOWS */ /* WINDOWS */
@@ -143,7 +145,7 @@ void kprintf(const char* format, ...){
putc(c,stdout); putc(c,stdout);
); );
} }
// common characters // common characters
else { else {
putc(c,stdout); putc(c,stdout);
} }
@@ -152,4 +154,5 @@ void kprintf(const char* format, ...){
#endif #endif
} }
va_end(vl); va_end(vl);
LinearAllocator_destruct(&_al);
} }

View File

@@ -11,4 +11,4 @@ void kprintf(const char* format, ...);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -1,7 +1,10 @@
# Xoshiro/Xoroshiro RNG algorithms # Random
There are a bunch of versions of xoshiro/xoroshiro algorithms, which are created by [David Blackman and Sebastiano Vigna](https://prng.di.unimi.it/) This directory contains some popular random functions. I recommend you using `splitmix64` initialized with `random_seedFromTime` for fast rng, hoshiro128plus for more accurate 32-bit rng and hoshiro256plus for 64-bit.
## Xoshiro/Xoroshiro RNG algorithms
There are a bunch of versions of xoshiro/xoroshiro algorithms, which are created by [David Blackman and Sebastiano Vigna](https://prng.di.unimi.it/)
``` ```
xoroshiro xoroshiro
├── 32bitValue ├── 32bitValue

View File

@@ -1,72 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/std.h"
#include "splitmix64/splitmix64.h"
#include "xoroshiro/xoroshiro.h"
#include "xoshiro/xoshiro.h"
/*
You can choose any algorithm that has required functions:
some_alg32_statePtr some_alg32_init(u32 seed);
u32 some_alg32_next(some_alg32_statePtr);
void some_alg32_free(some_alg32_statePtr);
#define KRAND_ALG32_init some_alg32_init
#define KRAND_ALG32_next some_alg32_next
#define KRAND_ALG32_free some_alg32_free
#include "kerep/random/krandom.h"
The same way it works for 64-bit RNGs
*/
// default rng_next function
#ifndef KRAND_ALG32_next
#define KRAND_ALG32_next xoshiro128plus##_next
#endif
#ifndef KRAND_ALG32_init
#define KRAND_ALG32_init xoshiro128plus##_init
#endif
#ifndef KRAND_ALG32_free
#define KRAND_ALG32_free xoshiro128plus##_free
#endif
#ifndef KRAND_ALG64_next
#define KRAND_ALG64_next xoshiro256plus##_next
#endif
#ifndef KRAND_ALG64_init
#define KRAND_ALG64_init xoshiro256plus##_init
#endif
#ifndef KRAND_ALG64_free
#define KRAND_ALG64_free xoshiro256plus##_free
#endif
typedef void* krand_statePtr;
#define KRAND_ALG32_initFromTime xoshiro128plus##_initFromTime
#define KRAND_ALG64_initFromTime xoshiro256plus##_initFromTime
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
// ready-to-use functions
static inline i8 krand_next8 (krand_statePtr state, i8 from, i8 to) __krand_next_definition(32)
static inline i16 krand_next16(krand_statePtr state, i16 from, i16 to) __krand_next_definition(32)
static inline i32 krand_next32(krand_statePtr state, i32 from, i32 to) __krand_next_definition(32)
static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64)
// divides random number by 2^64 to return a value between 0 and 1
static inline f32 krand_nextFloat32(krand_statePtr state) {return (u32)KRAND_ALG32_next(state)/0xffffffff; }
static inline f64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
///@param chance (0-1.0) is probability of success
static inline bool fate(krand_statePtr state,float chance){
i32 limit=1/chance + 0.01f;
return KRAND_ALG32_next(state)%limit == 0;
}
#if __cplusplus
}
#endif

33
src/random/random.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/std.h"
#include "splitmix64/splitmix64.h"
#include "xoroshiro/32bitValue/xoroshiro64.h"
#include "xoroshiro/64bitValue/xoroshiro128.h"
#include "xoshiro/32bitValue/xoshiro128.h"
#include "xoshiro/64bitValue/xoshiro256.h"
#define random_seedFromTime() time(NULL)
/// divides random number by 2^32
/// @return value between 0 and 1
static inline f32 random_toFloat32(u32 random_value) { return (f32)random_value / (f32)0xffff; }
/// divides random number by 2^64
/// @return value between 0 and 1
static inline f64 random_nextFloat64(u64 random_value) { return (f64)random_value / (f64)0xffffffff; }
///@param probability (0-1.0) probability of success
///@return is action sucsessfull or not
static inline bool random_probability(u32 random_value, float probability){
i32 limit=1.0f/probability + 0.0002f;
return random_value%limit == 0;
}
#if __cplusplus
}
#endif

View File

@@ -1,6 +1,6 @@
#include "splitmix64.h" #include "splitmix64.h"
/* /*
This is a fixed-increment version of Java 8's SplittableRandom generator This is a fixed-increment version of Java 8's SplittableRandom generator
See http://dx.doi.org/10.1145/2714064.2660195 and See http://dx.doi.org/10.1145/2714064.2660195 and
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
@@ -8,23 +8,14 @@ It is a very fast generator passing BigCrush, and it can be useful if
for some reason you absolutely want 64 bits of state; otherwise, we for some reason you absolutely want 64 bits of state; otherwise, we
rather suggest to use a xoroshiro128+ (for moderately parallel rather suggest to use a xoroshiro128+ (for moderately parallel
computations) or xorshift1024* (for massively parallel computations) computations) or xorshift1024* (for massively parallel computations)
generator. generator.
*/ */
// The state can be seeded with any (upto) 64 bit integer value. u64 splitmix64_next(splitmix64_state* state_ptr) {
void* splitmix64_init(u64 seed){
splitmix64_state* state=malloc(sizeof(splitmix64_state));
*state=seed;
return state;
}
u64 splitmix64_next(void* _state) {
splitmix64_state* state=_state;
// increment the state variable // increment the state variable
*state += 0x9e3779b97f4a7c15; *state_ptr += 0x9e3779b97f4a7c15;
// copy the state to a working variable // copy the state to a working variable
u64 z = *state; u64 z = *state_ptr;
// xor the variable with the variable right bit shifted 30 then multiply by a constant // xor the variable with the variable right bit shifted 30 then multiply by a constant
z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9; z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
// xor the variable with the variable right bit shifted 27 then multiply by a constant // xor the variable with the variable right bit shifted 27 then multiply by a constant

View File

@@ -7,16 +7,13 @@ extern "C" {
#include "../../base/base.h" #include "../../base/base.h"
typedef u64 splitmix64_state; typedef u64 splitmix64_state;
typedef void* splitmix64_statePtr;
splitmix64_statePtr splitmix64_init(u64 seed); static inline void splitmix64_construct(splitmix64_state* state, u64 seed){
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); } *state=seed;
u64 splitmix64_next(splitmix64_statePtr);
static inline void splitmix64_free(splitmix64_statePtr state) {
free(state);
} }
u64 splitmix64_next(splitmix64_state* state_ptr);
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -4,32 +4,18 @@
extern "C" { extern "C" {
#endif #endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h" #include "../../splitmix64/splitmix64.h"
typedef union { typedef union {
u64 merged; u64 merged;
u32 s[2]; u32 s[2];
} xoroshiro64_state; } xoroshiro64_state;
typedef void* xoroshiro64_statePtr;
xoroshiro64_statePtr xoroshiro64_init(u64 seed); void xoroshiro64_construct(xoroshiro64_state* state_ptr, u64 seed);
#define xoroshiro64star_init xoroshiro64_init
#define xoroshiro64starstar_init xoroshiro64_init
static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoroshiro64_init(time(NULL)); } u32 xoroshiro64star_next(xoroshiro64_state*);
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime u32 xoroshiro64starstar_next(xoroshiro64_state*);
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
u32 xoroshiro64star_next(xoroshiro64_statePtr);
u32 xoroshiro64starstar_next(xoroshiro64_statePtr);
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
free(state);
}
#define xoroshiro64star_free xoroshiro64_free
#define xoroshiro64starstar_free xoroshiro64_free
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -8,7 +8,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
#include "xoroshiro64.h" #include "xoroshiro64.h"
/* /*
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
generator for 32-bit floating-poi32 numbers. We suggest to use its generator for 32-bit floating-poi32 numbers. We suggest to use its
upper bits for floating-poi32 generation, as it is slightly faster than upper bits for floating-poi32 generation, as it is slightly faster than
@@ -20,15 +20,14 @@ case) it can be used to generate 32-bit outputs, too.
We suggest to use a sign test to extract a random Boolean value, and We suggest to use a sign test to extract a random Boolean value, and
right shifts to extract subsets of bits. right shifts to extract subsets of bits.
The state must be seeded so that it is not everywhere zero. The state must be seeded so that it is not everywhere zero.
*/ */
static inline u32 rotl(const u32 x, i32 k) { static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k)); return (x << k) | (x >> (32 - k));
} }
u32 xoroshiro64star_next(void* _state) { u32 xoroshiro64star_next(xoroshiro64_state* state) {
xoroshiro64_state* state=_state;
const u32 s0 = state->s[0]; const u32 s0 = state->s[0];
u32 s1 = state->s[1]; u32 s1 = state->s[1];
const u32 result = s0 * 0x9E3779BB; const u32 result = s0 * 0x9E3779BB;
@@ -40,10 +39,8 @@ u32 xoroshiro64star_next(void* _state) {
return result; return result;
} }
void* xoroshiro64_init(u64 seed){ void xoroshiro64_construct(xoroshiro64_state* state, u64 seed){
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state)); splitmix64_state sm_state;
splitmix64_state* splitmix=splitmix64_init(seed); splitmix64_construct(&sm_state, seed);
state->merged=splitmix64_next(splitmix); state->merged=splitmix64_next(&sm_state);
splitmix64_free(splitmix);
return state;
} }

View File

@@ -23,8 +23,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k)); return (x << k) | (x >> (32 - k));
} }
u32 xoroshiro64starstar_next(void* _state) { u32 xoroshiro64starstar_next(xoroshiro64_state* state) {
xoroshiro64_state* state=_state;
const u32 s0 = state->s[0]; const u32 s0 = state->s[0];
u32 s1 = state->s[1]; u32 s1 = state->s[1];
const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5; const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5;

View File

@@ -4,36 +4,18 @@
extern "C" { extern "C" {
#endif #endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h" #include "../../splitmix64/splitmix64.h"
typedef union { typedef union {
u32 s[2]; u32 s[2];
} xoroshiro128_state; } xoroshiro128_state;
typedef void* xoroshiro128_statePtr;
xoroshiro128_statePtr xoroshiro128_init(u64 seed); void xoroshiro128_construct(xoroshiro128_state* state, u64 seed);
#define xoroshiro128plus_init xoroshiro128_init
#define xoroshiro128plusplus_init xoroshiro128_init
#define xoroshiro128starstar_init xoroshiro128_init
static inline xoroshiro128_statePtr xoroshiro128_initFromTime(void) { return xoroshiro128_init(time(NULL)); } u64 xoroshiro128plus_next(xoroshiro128_state*);
#define xoroshiro128plus_initFromTime xoroshiro128_initFromTime u64 xoroshiro128plusplus_next(xoroshiro128_state*);
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime u64 xoroshiro128starstar_next(xoroshiro128_state*);
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
u64 xoroshiro128plus_next(xoroshiro128_statePtr);
u64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
u64 xoroshiro128starstar_next(xoroshiro128_statePtr);
static inline void xoroshiro128_free(xoroshiro128_statePtr state) {
free(state);
}
#define xoroshiro128plus_free xoroshiro128_free
#define xoroshiro128plusplus_free xoroshiro128_free
#define xoroshiro128starstar_free xoroshiro128_free
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -26,7 +26,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
The state must be seeded so that it is not everywhere zero. If you have The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. output to fill s.
NOTE: the parameters (a=24, b=16, b=37) of this version give slightly NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
better results in our test than the 2016 version (a=55, b=14, c=36). better results in our test than the 2016 version (a=55, b=14, c=36).
@@ -36,8 +36,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k)); return (x << k) | (x >> (64 - k));
} }
u64 xoroshiro128plus_next(void* _state){ u64 xoroshiro128plus_next(xoroshiro128_state* state){
xoroshiro128_state* state=_state;
const u64 s0 = state->s[0]; const u64 s0 = state->s[0];
u64 s1 = state->s[1]; u64 s1 = state->s[1];
const u64 result = s0 + s1; const u64 result = s0 + s1;
@@ -49,11 +48,9 @@ u64 xoroshiro128plus_next(void* _state){
return result; return result;
} }
void* xoroshiro128_init(u64 seed){ void xoroshiro128_construct(xoroshiro128_state* state, u64 seed){
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state)); splitmix64_state sm_state;
splitmix64_state* splitmix=splitmix64_init(seed); splitmix64_construct(&sm_state, seed);
state->s[0]=splitmix64_next(splitmix); state->s[0]=splitmix64_next(&sm_state);
state->s[1]=splitmix64_next(splitmix); state->s[1]=splitmix64_next(&sm_state);
splitmix64_free(splitmix);
return state;
} }

View File

@@ -25,8 +25,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k)); return (x << k) | (x >> (64 - k));
} }
u64 xoroshiro128plusplus_next(void* _state){ u64 xoroshiro128plusplus_next(xoroshiro128_state* state){
xoroshiro128_state* state=_state;
const u64 s0 = state->s[0]; const u64 s0 = state->s[0];
u64 s1 = state->s[1]; u64 s1 = state->s[1];
const u64 result = rotl(s0 + s1, 17) + s0; const u64 result = rotl(s0 + s1, 17) + s0;

View File

@@ -25,8 +25,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k)); return (x << k) | (x >> (64 - k));
} }
u64 xoroshiro128starstar_next(void* _state){ u64 xoroshiro128starstar_next(xoroshiro128_state* state){
xoroshiro128_state* state=_state;
const u64 s0 = state->s[0]; const u64 s0 = state->s[0];
u64 s1 = state->s[1]; u64 s1 = state->s[1];
const u64 result = rotl(s0 * 5, 7) * 9; const u64 result = rotl(s0 * 5, 7) * 9;

View File

@@ -1,2 +0,0 @@
#include "32bitValue/xoroshiro64.h"
#include "64bitValue/xoroshiro128.h"

View File

@@ -4,37 +4,19 @@
extern "C" { extern "C" {
#endif #endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h" #include "../../splitmix64/splitmix64.h"
typedef union { typedef union {
u64 merged[2]; u64 merged[2];
u32 s[4]; u32 s[4];
} xoshiro128_state; } xoshiro128_state;
typedef void* xoshiro128_statePtr;
xoshiro128_statePtr xoshiro128_init(u64 seed); void xoshiro128_construct(xoshiro128_state* state, u64 seed);
#define xoshiro128plus_init xoshiro128_init
#define xoshiro128plusplus_init xoshiro128_init
#define xoshiro128starstar_init xoshiro128_init
static inline xoshiro128_statePtr xoshiro128_initFromTime(void) { return xoshiro128_init(time(NULL)); } u32 xoshiro128plus_next(xoshiro128_state*);
#define xoshiro128plus_initFromTime xoshiro128_initFromTime u32 xoshiro128plusplus_next(xoshiro128_state*);
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime u32 xoshiro128starstar_next(xoshiro128_state*);
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
u32 xoshiro128plus_next(xoshiro128_statePtr);
u32 xoshiro128plusplus_next(xoshiro128_statePtr);
u32 xoshiro128starstar_next(xoshiro128_statePtr);
static inline void xoshiro128_free(xoshiro128_statePtr state) {
free(state);
}
#define xoshiro128plus_free xoshiro128_free
#define xoshiro128plusplus_free xoshiro128_free
#define xoshiro128starstar_free xoshiro128_free
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -26,8 +26,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k)); return (x << k) | (x >> (32 - k));
} }
u32 xoshiro128plus_next(void* _state){ u32 xoshiro128plus_next(xoshiro128_state* state){
xoshiro128_state* state=_state;
const u32 result = state->s[0] + state->s[3]; const u32 result = state->s[0] + state->s[3];
const u32 t = state->s[1] << 9; const u32 t = state->s[1] << 9;
@@ -44,11 +43,9 @@ u32 xoshiro128plus_next(void* _state){
return result; return result;
} }
void* xoshiro128_init(u64 seed){ void xoshiro128_construct(xoshiro128_state* state, u64 seed){
xoshiro128_state* state=malloc(sizeof(xoshiro128_state)); splitmix64_state sm_state;
splitmix64_state* splitmix=splitmix64_init(seed); splitmix64_construct(&sm_state, seed);
state->merged[0]=splitmix64_next(splitmix); state->merged[0]=splitmix64_next(&sm_state);
state->merged[1]=splitmix64_next(splitmix); state->merged[1]=splitmix64_next(&sm_state);
splitmix64_free(splitmix);
return state;
} }

View File

@@ -23,8 +23,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k)); return (x << k) | (x >> (32 - k));
} }
u32 xoshiro128plusplus_next(void* _state){ u32 xoshiro128plusplus_next(xoshiro128_state* state){
xoshiro128_state* state=_state;
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0]; const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
const u32 t = state->s[1] << 9; const u32 t = state->s[1] << 9;

View File

@@ -26,8 +26,7 @@ static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k)); return (x << k) | (x >> (32 - k));
} }
u32 xoshiro128starstar_next(void* _state){ u32 xoshiro128starstar_next(xoshiro128_state* state){
xoshiro128_state* state=_state;
const u32 result = rotl(state->s[1] * 5, 7) * 9; const u32 result = rotl(state->s[1] * 5, 7) * 9;
const u32 t = state->s[1] << 9; const u32 t = state->s[1] << 9;

View File

@@ -4,36 +4,18 @@
extern "C" { extern "C" {
#endif #endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h" #include "../../splitmix64/splitmix64.h"
typedef union { typedef union {
u64 s[4]; u64 s[4];
} xoshiro256_state; } xoshiro256_state;
typedef void* xoshiro256_statePtr;
xoshiro256_statePtr xoshiro256_init(u64 seed); void xoshiro256_construct(xoshiro256_state* state, u64 seed);
#define xoshiro256plus_init xoshiro256_init
#define xoshiro256plusplus_init xoshiro256_init
#define xoshiro256starstar_init xoshiro256_init
static inline xoshiro256_statePtr xoshiro256_initFromTime(void) { return xoshiro256_init(time(NULL)); } u64 xoshiro256plus_next(xoshiro256_state*);
#define xoshiro256plus_initFromTime xoshiro256_initFromTime u64 xoshiro256plusplus_next(xoshiro256_state*);
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime u64 xoshiro256starstar_next(xoshiro256_state*);
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
u64 xoshiro256plus_next(xoshiro256_statePtr);
u64 xoshiro256plusplus_next(xoshiro256_statePtr);
u64 xoshiro256starstar_next(xoshiro256_statePtr);
static inline void xoshiro256_free(xoshiro256_statePtr state) {
free(state);
}
#define xoshiro256plus_free xoshiro256_free
#define xoshiro256plusplus_free xoshiro256_free
#define xoshiro256starstar_free xoshiro256_free
#if __cplusplus #if __cplusplus
} }
#endif #endif

View File

@@ -28,8 +28,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k)); return (x << k) | (x >> (64 - k));
} }
u64 xoshiro256plus_next(void* _state){ u64 xoshiro256plus_next(xoshiro256_state* state){
xoshiro256_state* state=_state;
const u64 result = state->s[0] + state->s[3]; const u64 result = state->s[0] + state->s[3];
const u64 t = state->s[1] << 17; const u64 t = state->s[1] << 17;
@@ -46,13 +45,11 @@ u64 xoshiro256plus_next(void* _state){
return result; return result;
} }
void* xoshiro256_init(u64 seed){ void xoshiro256_construct(xoshiro256_state* state, u64 seed){
xoshiro256_state* state=malloc(sizeof(xoshiro256_state)); splitmix64_state sm_state;
splitmix64_state* splitmix=splitmix64_init(seed); splitmix64_construct(&sm_state, seed);
state->s[0]=splitmix64_next(splitmix); state->s[0]=splitmix64_next(&sm_state);
state->s[1]=splitmix64_next(splitmix); state->s[1]=splitmix64_next(&sm_state);
state->s[2]=splitmix64_next(splitmix); state->s[2]=splitmix64_next(&sm_state);
state->s[3]=splitmix64_next(splitmix); state->s[3]=splitmix64_next(&sm_state);
splitmix64_free(splitmix);
return state;
} }

View File

@@ -23,8 +23,7 @@ static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x>>(64 - k)); return (x << k) | (x>>(64 - k));
} }
u64 xoshiro256plusplus_next(void* _state) { u64 xoshiro256plusplus_next(xoshiro256_state* state) {
xoshiro256_state* state=_state;
const u64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0]; const u64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0];
const u64 t=state->s[1] << 17; const u64 t=state->s[1] << 17;
state->s[2] ^= state->s[0]; state->s[2] ^= state->s[0];

Some files were not shown because too many files have changed in this diff Show More