diff --git a/.gitignore b/.gitignore
index 6e5b49f..cab1d1a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,9 +5,8 @@ obj/
# user files
.old*/
.vs/
-.vscode/
.vshistory/
.editorconfig
*.user
*.vcxproj.filters
-.config
+current.config
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..dd060e8
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "cbuild"]
+ path = cbuild
+ url = https://github.com/Timerix22/cbuild.git
diff --git a/.vscode/.gitignore b/.vscode/.gitignore
new file mode 100644
index 0000000..c3d3a20
--- /dev/null
+++ b/.vscode/.gitignore
@@ -0,0 +1 @@
+settings.json
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..421e47a
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,34 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "(gdb) Debug",
+ "type": "cppdbg",
+ "request": "launch",
+ "preLaunchTask": "build_exec_dbg",
+ "program": "${workspaceFolder}/bin/kerep.com",
+ "stopAtEntry": false,
+ "cwd": "${workspaceFolder}",
+ "externalConsole": true,
+ "internalConsoleOptions": "openOnSessionStart",
+ "miDebuggerPath": "/usr/bin/gdb",
+ "MIMode": "gdb",
+ "pipeTransport": {
+ "debuggerPath": "gdb",
+ "pipeProgram": "bash",
+ "pipeArgs": ["-c"],
+ "pipeCwd": "${workspaceFolder}"
+ }
+ },
+ {
+ "name": "(msvc) Debug",
+ "type": "cppvsdbg",
+ "request": "launch",
+ "preLaunchTask": "build_dbg",
+ "cwd": "${workspaceFolder}\\bin",
+ "program": "${workspaceFolder}\\bin\\kerep.com",
+ "stopAtEntry": false,
+ "console": "integratedTerminal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..7fb803b
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,57 @@
+
+{
+
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "build_exec",
+ "detail": "build project",
+ "type": "cppbuild",
+ "command": "make",
+ "args": [
+ "build_exec"
+ ],
+ "options": {
+ "cwd": "${workspaceFolder}"
+ },
+ "problemMatcher": ["$gcc"],
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": true,
+ "panel": "shared",
+ "showReuseMessage": false,
+ "clear": true
+ }
+ },
+
+ {
+ "label": "build_exec_dbg",
+ "detail": "build project with debug symbols",
+ "type": "cppbuild",
+ "command": "make",
+ "args": [
+ "build_exec_dbg"
+ ],
+ "options": {
+ "cwd": "${workspaceFolder}"
+ },
+ "problemMatcher": ["$gcc"],
+ "group": {
+ "kind": "build"
+ },
+ "presentation": {
+ "echo": true,
+ "reveal": "always",
+ "focus": true,
+ "panel": "shared",
+ "showReuseMessage": false,
+ "clear": true
+ }
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 49eea86..c61ed41 100644
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,24 @@
-###### Building tasks #######
-build_test:
- @build_scripts/build_configurations/build_test.sh
-
-build_test_dbg:
- @build_scripts/build_configurations/build_test_dbg.sh
+###### Build cbuild/default_tasks #######
+build_exec:
+ @cbuild/call_task.sh build_exec
+build_exec_dbg:
+ @cbuild/call_task.sh build_exec_dbg
build_shared_lib:
- @build_scripts/build_configurations/build_shared_lib.sh
+ @cbuild/call_task.sh build_shared_lib
+build_shared_lib_dbg:
+ @cbuild/call_task.sh build_shared_lib_dbg
build_static_lib:
- @build_scripts/build_configurations/build_static_lib.sh
-
+ @cbuild/call_task.sh build_static_lib
build_static_lib_dbg:
- @build_scripts/build_configurations/build_static_lib_dbg.sh
+ @cbuild/call_task.sh build_static_lib_dbg
-###### Testing tasks #######
-test: build_test
- @build_scripts/build_configurations/test.sh
+###### Launch cbuild/default_tasks #######
+exec: build_exec
+ @cbuild/call_task.sh exec
-test_valgrind: build_test_dbg
- @build_scripts/build_configurations/test_valgrind.sh
+valgrind: build_exec_dbg
+ @cbuild/call_task.sh valgrind
-all: build_test
+all: build_exec
diff --git a/build_scripts/build_configurations/build_shared_lib.sh b/build_scripts/build_configurations/build_shared_lib.sh
deleted file mode 100644
index dbe33c9..0000000
--- a/build_scripts/build_configurations/build_shared_lib.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}==========[build_shared_lib]==========\n"
-clear_dir "$OUTDIR"
-clear_dir "$OBJDIR"
-compile_c "$BUILD_SHARED_LIB_C_ARGS" "$SRC_C tests/test_marshalling.c"
-compile_cpp "$BUILD_SHARED_LIB_CPP_ARGS" "$SRC_CPP"
-link "$BUILD_SHARED_LIB_CPP_ARGS $BUILD_SHARED_LIB_LINKER_ARGS" "$SHARED_LIB_FILE"
diff --git a/build_scripts/build_configurations/build_static_lib.sh b/build_scripts/build_configurations/build_static_lib.sh
deleted file mode 100644
index 692155e..0000000
--- a/build_scripts/build_configurations/build_static_lib.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}==========[build_static_lib]==========\n"
-clear_dir "$OUTDIR"
-clear_dir "$OBJDIR"
-compile_c "$BUILD_STATIC_LIB_C_ARGS" "$SRC_C tests/test_marshalling.c"
-compile_cpp "$BUILD_STATIC_LIB_CPP_ARGS" "$SRC_CPP"
-pack_static_lib "$STATIC_LIB_FILE"
diff --git a/build_scripts/build_configurations/build_static_lib_dbg.sh b/build_scripts/build_configurations/build_static_lib_dbg.sh
deleted file mode 100644
index ef8aa3d..0000000
--- a/build_scripts/build_configurations/build_static_lib_dbg.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}==========[build_static_lib_dbg]==========\n"
-clear_dir "$OUTDIR"
-clear_dir "$OBJDIR"
-compile_c "$BUILD_STATIC_LIB_DBG_C_ARGS" "$SRC_C tests/test_marshalling.c"
-compile_cpp "$BUILD_STATIC_LIB_DBG_CPP_ARGS" "$SRC_CPP"
-pack_static_lib "$STATIC_LIB_DBG_FILE"
diff --git a/build_scripts/build_configurations/build_test.sh b/build_scripts/build_configurations/build_test.sh
deleted file mode 100644
index 570de5a..0000000
--- a/build_scripts/build_configurations/build_test.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}=============[build_test]=============\n"
-clear_dir "$OUTDIR"
-clear_dir "$OBJDIR"
-compile_c "$BUILD_TEST_C_ARGS" "$SRC_C $TESTS_C"
-compile_cpp "$BUILD_TEST_CPP_ARGS" "$SRC_CPP $TESTS_CPP"
-link "$BUILD_TEST_CPP_ARGS $BUILD_TEST_LINKER_ARGS" $TEST_FILE
diff --git a/build_scripts/build_configurations/build_test_dbg.sh b/build_scripts/build_configurations/build_test_dbg.sh
deleted file mode 100644
index ff56aa0..0000000
--- a/build_scripts/build_configurations/build_test_dbg.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}===========[build_test_dbg]===========\n"
-clear_dir "$OUTDIR"
-clear_dir "$OBJDIR"
-compile_c "$BUILD_TEST_DBG_C_ARGS" "$SRC_C $TESTS_C"
-compile_cpp "$BUILD_TEST_DBG_CPP_ARGS" "$SRC_CPP $TESTS_CPP"
-link "$BUILD_TEST_DBG_CPP_ARGS $BUILD_TEST_DBG_LINKER_ARGS" $TEST_DBG_FILE
diff --git a/build_scripts/build_configurations/test.sh b/build_scripts/build_configurations/test.sh
deleted file mode 100644
index 45ac85c..0000000
--- a/build_scripts/build_configurations/test.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}================[test]================\n"
-cd $OUTDIR
-./$TEST_FILE
-cd ..
diff --git a/build_scripts/build_configurations/test_valgrind.sh b/build_scripts/build_configurations/test_valgrind.sh
deleted file mode 100644
index a92df20..0000000
--- a/build_scripts/build_configurations/test_valgrind.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-source build_scripts/init.sh
-
-print "${CYAN}===========[test_valgrind]============\n"
-cd $OUTDIR
-valgrind $VALGRIND_ARGS ./$TEST_DBG_FILE
-cat "valgrind.log"
-cd ..
diff --git a/build_scripts/colors.sh b/build_scripts/colors.sh
deleted file mode 100644
index e3e8363..0000000
--- a/build_scripts/colors.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-BLACK='\033[0;30m'
-GRAY='\033[0;37m'
-WHITE='\033[0;97m'
-RED='\033[0;91m'
-GREEN='\033[0;92m'
-YELLOW='\033[0;93m'
-BLUE='\033[0;94m'
-PURPLE='\033[0;95m'
-CYAN='\033[0;96m'
diff --git a/build_scripts/default.config.sh b/build_scripts/default.config.sh
deleted file mode 100644
index fa3755e..0000000
--- a/build_scripts/default.config.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/bash
-
-OUTDIR=bin
-OBJDIR=obj
-CMP_C=gcc
-CMP_CPP=g++
-STD_C=c11
-STD_CPP=c++17
-WARN_C="-Wall -Wno-discarded-qualifiers" #-Wextra
-WARN_CPP="-Wall -Wno-unused-variable -Wno-return-type" #-Wextra
-SRC_C="$( find src -name '*.c')"
-SRC_CPP="$( find src -name '*.cpp')"
-TESTS_C="$( find tests -name '*.c')"
-TESTS_CPP="$(find tests -name '*.cpp')"
-VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=kerep/ --leak-check=full --show-leak-kinds=all"
-
-# build_test
-TEST_FILE=kerep.com
-BUILD_TEST_C_ARGS="-O2"
-BUILD_TEST_CPP_ARGS="$BUILD_TEST_C_ARGS"
-BUILD_TEST_LINKER_ARGS=""
-
-# build_test_dbg
-TEST_DBG_FILE=$TEST_FILE
-BUILD_TEST_DBG_C_ARGS="-O0 -g"
-BUILD_TEST_DBG_CPP_ARGS="$BUILD_TEST_DBG_C_ARGS"
-BUILD_TEST_DBG_LINKER_ARGS=""
-
-# build_shared_lib
-SHARED_LIB_FILE=kerep.so
-BUILD_SHARED_LIB_C_ARGS="-O2 -fpic -flto -shared"
-BUILD_SHARED_LIB_CPP_ARGS="$BUILD_SHARED_LIB_C_ARGS"
-BUILD_SHARED_LIB_LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
-
-# build_static_lib
-STATIC_LIB_FILE=kerep.a
-BUILD_STATIC_LIB_C_ARGS="-O2 -fpic"
-BUILD_STATIC_LIB_CPP_ARGS="$BUILD_STATIC_LIB_C_ARGS"
-
-# build_static_lib_dbg
-STATIC_LIB_DBG_FILE="$STATIC_LIB_FILE"
-BUILD_STATIC_LIB_DBG_C_ARGS="-O0 -g"
-BUILD_STATIC_LIB_DBG_CPP_ARGS="$BUILD_STATIC_LIB_DBG_C_ARGS"
diff --git a/build_scripts/functions.sh b/build_scripts/functions.sh
deleted file mode 100644
index a2486e0..0000000
--- a/build_scripts/functions.sh
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/bin/bash
-
-function print {
- printf "$1$GRAY"
-}
-
-function clear_dir {
- print "${BLUE}clearing $1\n"
- rm -rf $1
- mkdir $1
-}
-
-function compile {
- local cmp=$1
- print "${BLUE}compiler: ${GRAY}$cmp\n"
- local std=$2
- print "${BLUE}standard: ${GRAY}$std\n"
- local warn=$3
- print "${BLUE}warnings: ${GRAY}$warn\n"
- local args=$4
- print "${BLUE}args: ${GRAY}$args\n"
- local sources=$5
- print "${BLUE}sources: ${GRAY}$sources\n"
- local compilation_error=0
-
- for srcfile in $sources
- do (
- local object="$OBJDIR/$(basename $srcfile).o"
- if ! $($cmp -std=$std $warn $args -c -o $object $srcfile)
- then
- print "${RED}some error happened\n"
- compilation_error=1
- fi
- ) & done
- wait
-
- if [ $compilation_error != 0 ]
- then
- exit 1
- fi
-}
-
-# (args, sources)
-function compile_c {
- print "${CYAN}-------------[compile_c]--------------\n"
- compile $CMP_C $STD_C "$WARN_C" "$1" "$2"
-}
-
-# (args, sources)
-function compile_cpp {
- print "${CYAN}------------[compile_cpp]-------------\n"
- compile $CMP_CPP $STD_CPP "$WARN_CPP" "$1" "$2"
-}
-
-# (args, outfile)
-function link {
- print "${CYAN}----------------[link]----------------\n"
- local args=$1
- print "${BLUE}args: ${GRAY}$args\n"
- local outfile=$OUTDIR/$2
- print "${BLUE}outfile: ${GRAY}$outfile\n"
- local objects="$(find $OBJDIR -name *.o)"
- print "${BLUE}objects: ${GRAY}$objects\n"
- if $CMP_CPP $args -o $outfile $(echo $objects | tr '\n' ' ')
- then
- print "${GREEN}file $CYAN$outfile ${GREEN}created\n"
- rm -rf $OBJDIR
- else
- print "${RED}some error happened\n"
- exit 1
- fi
-}
-
-# (outfile)
-function pack_static_lib {
- print "${CYAN}----------------[link]----------------\n"
- local outfile=$OUTDIR/$1
- print "${BLUE}outfile: ${GRAY}$outfile\n"
- local objects="$(find $OBJDIR -name *.o)"
- print "${BLUE}objects: ${GRAY}$objects\n"
- if ar rcs $outfile $(echo $objects | tr '\n' ' ')
- then
- print "${GREEN}file $CYAN$outfile ${GREEN}created\n"
- rm -rf $OBJDIR
- else
- print "${RED}some error happened\n"
- exit 1
- fi
-}
\ No newline at end of file
diff --git a/build_scripts/init.sh b/build_scripts/init.sh
deleted file mode 100644
index 868baf5..0000000
--- a/build_scripts/init.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-
-tabs 4
-
-source build_scripts/colors.sh
-source build_scripts/functions.sh
-
-if [ ! -f ".config" ]; then
- print "${YELLOW}./.config doesn't exists\n"
- cp build_scripts/default.config.sh .config
- print "${YELLOW}default config created\n"
- while true; do
- print "${WHITE}continue? (y/n) "
- read answ
- case $answ in
- [Yy] ) break;;
- [Nn] ) exit;;
- * ) print "${RED}incorrect answer\n";;
- esac
- done
-fi
-source .config
diff --git a/default.config b/default.config
new file mode 100644
index 0000000..37c5883
--- /dev/null
+++ b/default.config
@@ -0,0 +1,77 @@
+#!/bin/bash
+CONFIG_VERSION=3
+CBUILD_VERSION=2
+
+PROJECT=kerep
+CMP_C=gcc
+CMP_CPP=g++
+STD_C=c11
+STD_CPP=c++17
+WARN_C="-Wall -Wno-discarded-qualifiers -Wno-int-conversion"
+WARN_CPP="-Wall"
+SRC_C="$( find src -name '*.c')"
+SRC_CPP="$( find src -name '*.cpp')"
+TESTS_C="$( find tests -name '*.c')"
+TESTS_CPP="$(find tests -name '*.cpp')"
+
+OUTDIR=bin
+OBJDIR=obj
+EXEC_FILE=$PROJECT.com
+SHARED_LIB_FILE=$PROJECT.so
+STATIC_LIB_FILE=$PROJECT.a
+
+case $TASK in
+ build_exec)
+ C_ARGS="-O2"
+ CPP_ARGS="$C_ARGS"
+ LINKER_ARGS=""
+ TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ build_exec_dbg)
+ C_ARGS="-O0 -g"
+ CPP_ARGS="$C_ARGS"
+ LINKER_ARGS=""
+ TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ build_shared_lib)
+ C_ARGS="-O2 -fpic -flto -shared"
+ CPP_ARGS="$C_ARGS"
+ LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
+ TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ build_shared_lib_dbg)
+ C_ARGS="-O0 -g -fpic -shared"
+ CPP_ARGS="$C_ARGS"
+ LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
+ TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ build_static_lib)
+ C_ARGS="-O2 -fpic"
+ CPP_ARGS="$C_ARGS"
+ TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ build_static_lib_dbg)
+ C_ARGS="-O0 -g"
+ CPP_ARGS="$C_ARGS"
+ TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
+ PRE_TASK_SCRIPT=tasks/pre_build.sh
+ POST_TASK_SCRIPT=
+ ;;
+ exec)
+ TASK_SCRIPT=cbuild/default_tasks/exec.sh
+ ;;
+ valgrind)
+ VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
+ TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
+ ;;
+esac
diff --git a/kerep.vcxproj b/kerep.vcxproj
index 159f0fe..33807a4 100644
--- a/kerep.vcxproj
+++ b/kerep.vcxproj
@@ -32,9 +32,6 @@
-
-
-
@@ -44,7 +41,6 @@
-
@@ -63,11 +59,6 @@
-
-
-
-
-
@@ -261,4 +252,4 @@
-
\ No newline at end of file
+
diff --git a/src/Array/Array.h b/src/Array/Array.h
new file mode 100644
index 0000000..ac9dabc
--- /dev/null
+++ b/src/Array/Array.h
@@ -0,0 +1,40 @@
+#include "Array_declare.h"
+
+Array_declare(char)
+Array_declare(bool)
+Array_declare(float32)
+Array_declare(float64)
+Array_declare(int8)
+Array_declare(uint8)
+Array_declare(int16)
+Array_declare(uint16)
+Array_declare(int32)
+Array_declare(uint32)
+Array_declare(int64)
+Array_declare(uint64)
+
+ktId_declare(ArrayChar);
+ktId_declare(ArrayBool);
+ktId_declare(ArrayFloat32);
+ktId_declare(ArrayFloat64);
+ktId_declare(ArrayInt8);
+ktId_declare(ArrayUInt8);
+ktId_declare(ArrayInt16);
+ktId_declare(ArrayUInt16);
+ktId_declare(ArrayInt32);
+ktId_declare(ArrayUInt32);
+ktId_declare(ArrayInt64);
+ktId_declare(ArrayUInt64);
+
+ktId_declare(ArrayCharPtr);
+ktId_declare(ArrayBoolPtr);
+ktId_declare(ArrayFloat32Ptr);
+ktId_declare(ArrayFloat64Ptr);
+ktId_declare(ArrayInt8Ptr);
+ktId_declare(ArrayUInt8Ptr);
+ktId_declare(ArrayInt16Ptr);
+ktId_declare(ArrayUInt16Ptr);
+ktId_declare(ArrayInt32Ptr);
+ktId_declare(ArrayUInt32Ptr);
+ktId_declare(ArrayInt64Ptr);
+ktId_declare(ArrayUInt64Ptr);
diff --git a/src/Array/Array_declare.h b/src/Array/Array_declare.h
new file mode 100644
index 0000000..6d12ead
--- /dev/null
+++ b/src/Array/Array_declare.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../base/base.h"
+
+#define Array_declare(type)\
+typedef struct Array_##type{\
+ type* values;\
+ uint32 length;\
+ bool allocatedOnHeap;\
+} Array_##type;\
+\
+\
+static inline Array_##type Array_##type##_allocValues(uint32 length){\
+ return (Array_##type) {\
+ .values=(type##*)malloc(sizeof(type)*length),\
+ .length=length,\
+ .allocatedOnHeap=true\
+ };\
+}\
+\
+static inline Array_##type Array_##type##_fromBuffer(type##* buffer, uint32 bufferLength, bool allocatedOnHeap){\
+ return (Array_##type) {\
+ .values=buffer,\
+ .length=bufferLength,\
+ .allocatedOnHeap=allocatedOnHeap\
+ };\
+}\
+\
+static inline void Array_##type##_freeValues(Array_##type* array){\
+ if(array->allocatedOnHeap)\
+ free(array->values);\
+}
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/Array/README.md b/src/Array/README.md
new file mode 100644
index 0000000..931ff09
--- /dev/null
+++ b/src/Array/README.md
@@ -0,0 +1,2 @@
+# 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`. It uses `static inline` functions, so all definitions will be generated in header.
diff --git a/src/Autoarr/Autoarr.c b/src/Autoarr/Autoarr.c
index 48d595a..c72a299 100644
--- a/src/Autoarr/Autoarr.c
+++ b/src/Autoarr/Autoarr.c
@@ -1,19 +1,51 @@
#include "Autoarr.h"
-Autoarr_define(uint8);
-Autoarr_define(int8);
-Autoarr_define(uint16);
-Autoarr_define(int16);
-Autoarr_define(uint32);
-Autoarr_define(int32);
-Autoarr_define(uint64);
-Autoarr_define(int64);
-Autoarr_define(float);
-Autoarr_define(double);
-Autoarr_define(Unitype);
+Autoarr_define(char)
+Autoarr_define(bool)
+Autoarr_define(float32)
+Autoarr_define(float64)
+Autoarr_define(uint8)
+Autoarr_define(int8)
+Autoarr_define(uint16)
+Autoarr_define(int16)
+Autoarr_define(uint32)
+Autoarr_define(int32)
+Autoarr_define(uint64)
+Autoarr_define(int64)
+
+ktId_define(AutoarrChar);
+ktId_define(AutoarrBool);
+ktId_define(AutoarrFloat32);
+ktId_define(AutoarrFloat64);
+ktId_define(AutoarrInt8);
+ktId_define(AutoarrUInt8);
+ktId_define(AutoarrInt16);
+ktId_define(AutoarrUInt16);
+ktId_define(AutoarrInt32);
+ktId_define(AutoarrUInt32);
+ktId_define(AutoarrInt64);
+ktId_define(AutoarrUInt64);
+
+ktId_define(AutoarrCharPtr);
+ktId_define(AutoarrBoolPtr);
+ktId_define(AutoarrFloat32Ptr);
+ktId_define(AutoarrFloat64Ptr);
+ktId_define(AutoarrInt8Ptr);
+ktId_define(AutoarrUInt8Ptr);
+ktId_define(AutoarrInt16Ptr);
+ktId_define(AutoarrUInt16Ptr);
+ktId_define(AutoarrInt32Ptr);
+ktId_define(AutoarrUInt32Ptr);
+ktId_define(AutoarrInt64Ptr);
+ktId_define(AutoarrUInt64Ptr);
+
+Autoarr_define(Unitype)
+ktId_define(AutoarrUnitype);
+ktId_define(AutoarrUnitypePtr);
// right func to clear array of unitype values
-void Autoarr_free_Unitype(Autoarr(Unitype)* ar){
+void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr){
Autoarr_foreach(ar, u,Unitype_free(u));
- Autoarr_free(ar);
+ __Autoarr_free_Unitype(ar, freePtr);
}
+void ____Autoarr_free_Unitype_(void* ar) { __Autoarr_free_Unitype_((Autoarr(Unitype)*)ar, false); }
\ No newline at end of file
diff --git a/src/Autoarr/Autoarr.h b/src/Autoarr/Autoarr.h
index 89440a4..3a953c0 100644
--- a/src/Autoarr/Autoarr.h
+++ b/src/Autoarr/Autoarr.h
@@ -7,20 +7,52 @@ extern "C" {
#include "Autoarr_declare.h"
#include "Autoarr_define.h"
-Autoarr_declare(uint8)
+Autoarr_declare(char)
+Autoarr_declare(bool)
+Autoarr_declare(float32)
+Autoarr_declare(float64)
Autoarr_declare(int8)
-Autoarr_declare(uint16)
+Autoarr_declare(uint8)
Autoarr_declare(int16)
-Autoarr_declare(uint32)
+Autoarr_declare(uint16)
Autoarr_declare(int32)
-Autoarr_declare(uint64)
+Autoarr_declare(uint32)
Autoarr_declare(int64)
-Autoarr_declare(float)
-Autoarr_declare(double)
-Autoarr_declare(Unitype)
+Autoarr_declare(uint64)
-// right func to clear array of unitype values
-void Autoarr_free_Unitype(Autoarr(Unitype)* ar);
+ktId_declare(AutoarrChar);
+ktId_declare(AutoarrBool);
+ktId_declare(AutoarrFloat32);
+ktId_declare(AutoarrFloat64);
+ktId_declare(AutoarrInt8);
+ktId_declare(AutoarrUInt8);
+ktId_declare(AutoarrInt16);
+ktId_declare(AutoarrUInt16);
+ktId_declare(AutoarrInt32);
+ktId_declare(AutoarrUInt32);
+ktId_declare(AutoarrInt64);
+ktId_declare(AutoarrUInt64);
+
+ktId_declare(AutoarrCharPtr);
+ktId_declare(AutoarrBoolPtr);
+ktId_declare(AutoarrFloat32Ptr);
+ktId_declare(AutoarrFloat64Ptr);
+ktId_declare(AutoarrInt8Ptr);
+ktId_declare(AutoarrUInt8Ptr);
+ktId_declare(AutoarrInt16Ptr);
+ktId_declare(AutoarrUInt16Ptr);
+ktId_declare(AutoarrInt32Ptr);
+ktId_declare(AutoarrUInt32Ptr);
+ktId_declare(AutoarrInt64Ptr);
+ktId_declare(AutoarrUInt64Ptr);
+
+Autoarr_declare(Unitype)
+ktId_declare(AutoarrUnitype);
+ktId_declare(AutoarrUnitypePtr);
+
+// this function is injected in kerep_init()
+void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr);
+void ____Autoarr_free_Unitype_(void* ar);
#define Autoarr_foreach(ar,elem,codeblock)({\
if(ar->blocks_count>0) {\
diff --git a/src/Autoarr/Autoarr_KVPair_exported.c b/src/Autoarr/Autoarr_KVPair_exported.c
index 18fa4aa..8bfbd56 100644
--- a/src/Autoarr/Autoarr_KVPair_exported.c
+++ b/src/Autoarr/Autoarr_KVPair_exported.c
@@ -10,7 +10,7 @@ EXPORT void CALL kerep_Autoarr_KVPair_create(uint16 max_blocks_count, uint16 max
}
EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
- Autoarr_free_KVPair(ar);
+ Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, uint32 index, KVPair* output){
diff --git a/src/Autoarr/Autoarr_Unitype_exported.c b/src/Autoarr/Autoarr_Unitype_exported.c
index 8ad5efd..2aded2e 100644
--- a/src/Autoarr/Autoarr_Unitype_exported.c
+++ b/src/Autoarr/Autoarr_Unitype_exported.c
@@ -9,7 +9,7 @@ EXPORT void CALL kerep_Autoarr_Unitype_create(uint16 max_blocks_count, uint16 ma
}
EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
- Autoarr_free_Unitype(ar);
+ Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, uint32 index, Unitype* output){
diff --git a/src/Autoarr/Autoarr_declare.h b/src/Autoarr/Autoarr_declare.h
index 80169bd..404a361 100644
--- a/src/Autoarr/Autoarr_declare.h
+++ b/src/Autoarr/Autoarr_declare.h
@@ -15,7 +15,8 @@ typedef struct {\
type (*get)(struct Autoarr_##type* ar, uint32 index);\
type* (*getptr)(struct Autoarr_##type* ar, uint32 index);\
void (*set)(struct Autoarr_##type* ar, uint32 index, type element);\
- void (*_free)(struct Autoarr_##type* ar);\
+ void (*freear)(struct Autoarr_##type* ar, bool freePtr);\
+ type* (*toArray)(struct Autoarr_##type* ar);\
} __functions_list_t_##type;\
\
typedef struct Autoarr_##type{\
@@ -27,15 +28,14 @@ typedef struct Autoarr_##type{\
__functions_list_t_##type* functions;\
} Autoarr_##type;\
\
-void __Autoarr_add_##type(Autoarr_##type* ar, type element);\
-type __Autoarr_get_##type(Autoarr_##type* ar, uint32 index);\
-type* __Autoarr_getptr_##type(Autoarr_##type* ar, uint32 index);\
-void __Autoarr_set_##type(Autoarr_##type* ar, uint32 index, type element);\
-void __Autoarr_free_##type(Autoarr_##type* ar);\
-Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length);
+Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length);\
+void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr);\
+void ____Autoarr_free_##type(void* ar);
#define Autoarr(type) Autoarr_##type
+#define Autoarr_create(type, max_blocks_count, max_block_length)\
+ __Autoarr_create_##type(max_blocks_count, max_block_length)
#define Autoarr_add(autoarr, element)\
autoarr->functions->add(autoarr, element)
#define Autoarr_get(autoarr, index)\
@@ -44,10 +44,10 @@ Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_bloc
autoarr->functions->getptr(autoarr,index)
#define Autoarr_set(autoarr, index, element)\
autoarr->functions->set(autoarr, index, element)
-#define Autoarr_free(autoarr)\
- autoarr->functions->_free(autoarr)
-#define Autoarr_create(type, max_blocks_count, max_block_length)\
- __Autoarr_create_##type(max_blocks_count, max_block_length)
+#define Autoarr_free(autoarr, freePtr)\
+ autoarr->functions->freear(autoarr, freePtr)
+#define Autoarr_toArray(autoarr)\
+ autoarr->functions->toArray(autoarr)
#define Autoarr_length(autoarr) \
(uint32)(!autoarr->blocks_count ? 0 : \
diff --git a/src/Autoarr/Autoarr_define.h b/src/Autoarr/Autoarr_define.h
index 441c9b6..b70ad86 100644
--- a/src/Autoarr/Autoarr_define.h
+++ b/src/Autoarr/Autoarr_define.h
@@ -39,11 +39,22 @@ void __Autoarr_set_##type(Autoarr_##type* ar, uint32 index, type element){\
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element;\
}\
\
-void __Autoarr_free_##type(Autoarr_##type* ar){\
+void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr){\
for(uint16 i=0; iblocks_count;i++)\
free(ar->values[i]); \
free(ar->values);\
- free(ar);\
+ if(freePtr) free(ar);\
+}\
+void ____Autoarr_free_##type(void* ar){\
+ __Autoarr_free_##type((Autoarr_##type*)ar, false);\
+}\
+\
+type* __Autoarr_toArray_##type(Autoarr_##type* ar){\
+ uint32 length=Autoarr_length(ar);\
+ type* array=malloc(length * sizeof(type));\
+ for(uint32 i=0; i0) safethrow(ERR_ENDOFSTR,;);
- return SUCCESS(UniPtr(CharPtr,NULL));
+ return SUCCESS(UniHeap(ktId_CharPtr,NULL));
}
#define ReadName() __ReadName(shared)
@@ -137,7 +137,7 @@ Maybe __ReadString(DeserializeSharedData* shared){
}
else {
char* str=StringBuilder_build(b).ptr;
- return SUCCESS(UniPtr(CharPtr,str));
+ return SUCCESS(UniHeap(ktId_CharPtr,str));
}
}
else {
@@ -154,16 +154,16 @@ Maybe __ReadList(DeserializeSharedData* shared){
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
bool readingList=true;
while (true){
- try(ReadValue((&readingList)), val, Autoarr_free_Unitype(list))
+ try(ReadValue((&readingList)), val, Autoarr_free(list, true))
Autoarr_add(list,val.value);
if (!readingList){
- if(val.value.type==Null)
+ if(val.value.typeId==ktId_Null)
Autoarr_pop(list);
break;
}
}
- return SUCCESS(UniPtr(AutoarrUnitypePtr,list));
+ return SUCCESS(UniHeap(ktId_AutoarrUnitypePtr,list));
};
#define ReadList() __ReadList(shared)
@@ -182,7 +182,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
// Float64
case 'f': {
char* _c=string_extract(str);
- Unitype rez=Uni(Float64,strtod(_c,NULL));
+ Unitype rez=UniFloat64(strtod(_c,NULL));
free(_c);
return SUCCESS(rez);
}
@@ -199,7 +199,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
safethrow(err,free(_c));
}
free(_c);
- return SUCCESS(Uni(UInt64,lu));
+ return SUCCESS(UniUInt64(lu));
}
// Int64
case '0': case '1': case '2': case '3': case '4':
@@ -215,7 +215,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
safethrow(err,free(_c));
}
free(_c);
- return SUCCESS(Uni(Int64,li));
+ return SUCCESS(UniInt64(li));
}
// wrong type
default:
@@ -275,7 +275,7 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
case ';':
case ',':
if(valueStr.length!=0){
- if(value.type!=Null)
+ if(value.typeId!=ktId_Null)
safethrow_wrongchar(c,Unitype_free(value));
try(ParseValue(valueStr),maybeParsed,;)
value=maybeParsed.value;
@@ -321,7 +321,7 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
}
else{
list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
- Hashtable_add(dict,nameCPtr,UniPtr(AutoarrUnitypePtr,list));
+ Hashtable_add(dict,nameCPtr,UniHeap(ktId_AutoarrUnitypePtr,list));
}
Autoarr_add(list,val.value);
}
@@ -331,7 +331,7 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
END:
*_text=text;
- return SUCCESS(UniPtr(HashtablePtr,dict));
+ return SUCCESS(UniHeap(ktId_HashtablePtr,dict));
}
Maybe DtsodV24_deserialize(char* _text) {
diff --git a/src/DtsodParser/DtsodV24_serialize.c b/src/DtsodParser/DtsodV24_serialize.c
index 4618104..cf48d34 100644
--- a/src/DtsodParser/DtsodV24_serialize.c
+++ b/src/DtsodParser/DtsodV24_serialize.c
@@ -23,70 +23,65 @@ void __AppendTabs(SerializeSharedData* shared) {
Maybe __AppendValue(SerializeSharedData* shared, Unitype u);
#define AppendValue(UNI) __AppendValue(shared, UNI)
Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
- switch(u.type){
- case Int64:
- StringBuilder_append_int64(b,u.Int64);
- break;
- case UInt64:
- StringBuilder_append_uint64(b,u.UInt64);
- addc('u');
- break;
- case Float64:
- StringBuilder_append_float64(b,u.Float64);
- addc('f');
- break;
- case CharPtr:
- addc('"');
- char c;
- while((c=*(char*)(u.VoidPtr++))){
- if(c=='\"') addc('\\');
- addc(c);
- }
- addc('"');
- break;
- case Bool:
- StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
- break;
- case Null:
- safethrow("Null isn't supported in DtsodV24",;);
- case AutoarrUnitypePtr:
- if(Autoarr_length(((Autoarr_Unitype*)(u.VoidPtr)))){
+ if(u.typeId==ktId_Int64){
+ StringBuilder_append_int64(b,u.Int64);
+ }
+ else if(u.typeId==ktId_UInt64){
+ StringBuilder_append_uint64(b,u.UInt64);
+ addc('u');
+ }
+ else if(u.typeId==ktId_Float64){
+ StringBuilder_append_float64(b,u.Float64);
+ addc('f');
+ }
+ else if(u.typeId==ktId_CharPtr){
+ addc('"');
+ char c;
+ while((c=*(char*)(u.VoidPtr++))){
+ if(c=='\"') addc('\\');
+ addc(c);
+ }
+ addc('"');
+ }
+ else if(u.typeId==ktId_Bool){
+ StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
+ }
+ else if(u.typeId==ktId_Null){
+ safethrow("Null isn't supported in DtsodV24",;);
+ }
+ else if(u.typeId==ktId_AutoarrUnitypePtr){
+ if(Autoarr_length(((Autoarr_Unitype*)(u.VoidPtr)))){
+ addc('\n');
+ AppendTabs();
+ addc('[');
+ tabs++;
+ Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({
addc('\n');
AppendTabs();
- addc('[');
- tabs++;
- Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({
- addc('\n');
- AppendTabs();
- try(AppendValue(e),__,;);
- addc(',');
- }));
- StringBuilder_rmchar(b);
- addc('\n');
- tabs--;
- AppendTabs();
- addc(']');
- }
- else {
- addc('[');
- addc(']');
- }
- break;
- case HashtablePtr:
- // check hashtable is blank
- Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({
- goto hashtableNotBlank;
- if(__.key); // weird way to disable warning
+ try(AppendValue(e),__,;);
+ addc(',');
}));
-
-
- // blank hashtable
- addc('{');
- addc('}');
+ StringBuilder_rmchar(b);
+ addc('\n');
+ tabs--;
+ AppendTabs();
+ addc(']');
+ }
+ else {
+ addc('[');
+ addc(']');
+ }
+ }
+ else if(u.typeId==ktId_HashtablePtr){
+ // check hashtable is blank
+ bool hashtableNotBlank=false;
+ Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({
+ hashtableNotBlank=true;
+ if(__.key); // weird way to disable warning
break;
-
- // not blank hashtable
- hashtableNotBlank:
+ }));
+
+ if(hashtableNotBlank){
addc('\n');
AppendTabs();
addc('{');
@@ -94,10 +89,16 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
try(__serialize(b,tabs+1,u.VoidPtr),___,;);
AppendTabs();
addc('}');
- break;
- default: dbg((u.type)); safethrow(ERR_WRONGTYPE,;);
+ }
+ else {
+ addc('{');
+ addc('}');
+ }
+ }
+ else {
+ dbg((u.typeId));
+ safethrow(ERR_WRONGTYPE,;);
}
-
return MaybeNull;
};
@@ -125,5 +126,5 @@ Maybe DtsodV24_serialize(Hashtable* dtsod){
StringBuilder* sb=StringBuilder_create();
try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb));
char* str=StringBuilder_build(sb).ptr;
- return SUCCESS(UniPtr(CharPtr, str));
+ return SUCCESS(UniHeap(ktId_CharPtr, str));
}
diff --git a/src/Filesystem/filesystem.c b/src/Filesystem/filesystem.c
new file mode 100644
index 0000000..fe535da
--- /dev/null
+++ b/src/Filesystem/filesystem.c
@@ -0,0 +1,38 @@
+#include "filesystem.h"
+
+char* __path_concat(uint16 n, char* prev_part, ...){
+ char** parts=(char**)malloc(n*sizeof(char*));
+ uint32* lengths=malloc(n*sizeof(uint32));
+ uint32 totalLength=0;
+
+ // reading args from va_list
+ va_list vl;
+ va_start(vl, prev_part);
+ for(uint16 i=0; ihein];i++)
- Autoarr_free_KVPair(ht->rows[i]);
+ Autoarr_free(ht->rows[i], true);
free(ht->rows);
+}
+void Hashtable_free(Hashtable* ht){
+ __Hashtable_free(ht);
free(ht);
}
@@ -43,7 +50,8 @@ void Hashtable_expand(Hashtable* ht){
Autoarr(KVPair)* newar=newrows[newrown];
Autoarr_add(newar,p);
}
- Autoarr_free(ar);
+ // there is no need to free array values, because they are copied into new array
+ __Autoarr_free_KVPair(ar, true);
}
free(ht->rows);
@@ -88,7 +96,7 @@ Unitype Hashtable_get(Hashtable* ht, char* key){
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output){
Unitype u=Hashtable_get(ht,key);
*output=u;
- return u.type!=Null;
+ return u.typeId!=ktId_Null;
}
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u){
diff --git a/src/Hashtable/Hashtable.h b/src/Hashtable/Hashtable.h
index 3500199..520c2e4 100644
--- a/src/Hashtable/Hashtable.h
+++ b/src/Hashtable/Hashtable.h
@@ -11,9 +11,12 @@ typedef struct Hashtable{
uint8 hein; // height=HT_HEIGHTS[hein]
Autoarr(KVPair)** rows; // Autoarr[height]
} Hashtable;
+ktId_declare(Hashtable);
+ktId_declare(HashtablePtr);
Hashtable* Hashtable_create();
void Hashtable_free(Hashtable* ht);
+void __Hashtable_free(void* ht);
// amount of rows
uint16 Hashtable_height(Hashtable* ht);
diff --git a/src/Hashtable/KeyValuePair.c b/src/Hashtable/KeyValuePair.c
index cbe22dd..667487e 100644
--- a/src/Hashtable/KeyValuePair.c
+++ b/src/Hashtable/KeyValuePair.c
@@ -1,22 +1,30 @@
#include "KeyValuePair.h"
-Autoarr_define(KVPair)
+ktId_define(KVPair);
+ktId_define(KVPairPtr);
+Autoarr_define(KVPair)
+ktId_define(AutoarrKVPair);
+ktId_define(AutoarrKVPairPtr);
// proper way to clear a KVP
void KVPair_free(KVPair p){
free(p.key);
Unitype_free(p.value);
}
+void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
// func for KVP array clearing
-void Autoarr_free_KVPair(Autoarr_KVPair* ar){
+void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr){
Autoarr_foreach(ar,k,KVPair_free(k));
- Autoarr_free(ar);
+ __Autoarr_free_KVPair(ar, freePtr);
+}
+void ____Autoarr_free_KVPair_(void* ar){
+ __Autoarr_free_KVPair_((Autoarr_KVPair*)ar, false);
}
void printkvp(KVPair p){
- printf("{\"%s\", ",p.key);
+ kprintf("{\"%s\", ",p.key);
printuni(p.value);
- printf("}");
+ kprintf("}");
}
diff --git a/src/Hashtable/KeyValuePair.h b/src/Hashtable/KeyValuePair.h
index 19cc277..ef6a32b 100644
--- a/src/Hashtable/KeyValuePair.h
+++ b/src/Hashtable/KeyValuePair.h
@@ -11,14 +11,20 @@ typedef struct KVPair{
char* key;
Unitype value;
} KVPair;
+ktId_declare(KVPair);
+ktId_declare(KVPairPtr);
Autoarr_declare(KVPair)
+ktId_declare(AutoarrKVPair);
+ktId_declare(AutoarrKVPairPtr);
// proper way to clear a KVP
void KVPair_free(KVPair p);
+void __KVPair_free(void* p);
// func to clear KVP array
-void Autoarr_free_KVPair(Autoarr_KVPair* ar);
+void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr);
+void ____Autoarr_free_KVPair_(void* ar);
void printkvp(KVPair p);
diff --git a/src/SearchTree/SearchTree.c b/src/SearchTree/SearchTree.c
index e7cfac6..29e772d 100644
--- a/src/SearchTree/SearchTree.c
+++ b/src/SearchTree/SearchTree.c
@@ -1,14 +1,18 @@
#include "SearchTree.h"
+ktId_define(STNode);
+ktId_define(STNodePtr);
+
STNode* STNode_create(){
STNode* node=malloc(sizeof(STNode));
node->branches=NULL;
- node->value.type=Null;
+ node->value.typeId=ktId_Null;
node->value.UInt64=0;
return node;
}
-void STNode_free(STNode* node){
+void __STNode_free(void* _node){
+ STNode* node=_node;
if (!node) throw(ERR_NULLPTR);
if(node->branches){
for(uint8 n32 = 0;n32<8;n32++){
@@ -32,6 +36,9 @@ void STNode_free(STNode* node){
}
if(node->value.VoidPtr)
Unitype_free(node->value);
+}
+void STNode_free(STNode* node){
+ __STNode_free(node);
free(node);
}
diff --git a/src/SearchTree/SearchTree.h b/src/SearchTree/SearchTree.h
index fc4eb8c..a11de86 100644
--- a/src/SearchTree/SearchTree.h
+++ b/src/SearchTree/SearchTree.h
@@ -11,9 +11,12 @@ typedef struct SearchTreeNode{
struct SearchTreeNode**** branches; // *STNode[8][8][4]
Unitype value;
} STNode;
+ktId_declare(STNode);
+ktId_declare(STNodePtr);
STNode* STNode_create();
void STNode_free(STNode* node);
+void __STNode_free(void* node);
void ST_push(STNode* node, char* key, Unitype value);
void ST_pushString(STNode* node, string key, Unitype value);
diff --git a/src/String/StringBuilder.c b/src/String/StringBuilder.c
index c0b46a9..8f7cff5 100644
--- a/src/String/StringBuilder.c
+++ b/src/String/StringBuilder.c
@@ -1,6 +1,11 @@
#include "StringBuilder.h"
Autoarr_define(string)
+ktId_define(AutoarrString);
+ktId_define(AutoarrStringPtr);
+
+ktId_define(StringBuilder);
+ktId_define(StringBuilderPtr);
#define BL_C 32
#define BL_L 1024
@@ -17,7 +22,7 @@ void complete_buf(StringBuilder* b){
str.ptr[i++]=c;
}));
Autoarr_add(b->compl_bufs,str);
- Autoarr_free(b->curr_buf);
+ Autoarr_free(b->curr_buf, true);
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
}
@@ -34,9 +39,13 @@ StringBuilder* StringBuilder_create(){
return b;
}
+void __StringBuilder_free(void* _b){
+ StringBuilder* b=_b;
+ if(b->compl_bufs) Autoarr_free(b->compl_bufs, true);
+ Autoarr_free(b->curr_buf, true);
+}
void StringBuilder_free(StringBuilder* b){
- if(b->compl_bufs) Autoarr_free(b->compl_bufs);
- Autoarr_free(b->curr_buf);
+ __StringBuilder_free(b);
free(b);
}
diff --git a/src/String/StringBuilder.h b/src/String/StringBuilder.h
index 8e19420..a5f13ef 100644
--- a/src/String/StringBuilder.h
+++ b/src/String/StringBuilder.h
@@ -8,14 +8,19 @@ extern "C" {
#include "string.h"
Autoarr_declare(string)
+ktId_declare(AutoarrString);
+ktId_declare(AutoarrStringPtr);
typedef struct StringBuilder{
Autoarr(string)* compl_bufs;
Autoarr(int8)* curr_buf;
} StringBuilder;
+ktId_declare(StringBuilder);
+ktId_declare(StringBuilderPtr);
StringBuilder* StringBuilder_create(void);
void StringBuilder_free(StringBuilder* b);
+void __StringBuilder_free(void* b);
// Joins all strings from compl_bufs.
// Returns zero-terminated string.
// No need to call string_extract()!
diff --git a/src/String/string.c b/src/String/string.c
index 2926359..93c0ed9 100644
--- a/src/String/string.c
+++ b/src/String/string.c
@@ -1,5 +1,8 @@
#include "string.h"
+ktId_define(string);
+ktId_define(stringPtr);
+
// copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(string str){
if(str.length==0) return NULL;
diff --git a/src/String/string.h b/src/String/string.h
index e2076ee..caf5e73 100644
--- a/src/String/string.h
+++ b/src/String/string.h
@@ -12,6 +12,8 @@ typedef struct string{
char* ptr; // char pointer
uint32 length; // amount of chars in ptr value
} string;
+ktId_declare(string);
+ktId_declare(stringPtr);
static const string stringNull={NULL,0};
diff --git a/src/base/base.h b/src/base/base.h
index d49b6d7..7263d4b 100644
--- a/src/base/base.h
+++ b/src/base/base.h
@@ -5,10 +5,11 @@ extern "C" {
#endif
#include "std.h"
-#include "types.h"
#include "errors.h"
#include "cptr.h"
#include "optime.h"
+#include "type_system/type_system.h"
+#include "../kprint/kprintf.h"
#if __cplusplus
}
diff --git a/src/base/cptr.c b/src/base/cptr.c
index 22a6b36..0086edd 100644
--- a/src/base/cptr.c
+++ b/src/base/cptr.c
@@ -34,3 +34,56 @@ char* char_multiply(char c, uint32 n){
rez[n]=c;
return rez;
}
+
+bool cptr_startsWith(char* ptr, char* fragment){
+ for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
+ if(cs!=cf) return false;
+ return true;
+}
+
+bool cptr_endsWith(char* ptr, char* fragment){
+ ptr+=cptr_length(ptr)-cptr_length(fragment);
+ for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
+ if(cs!=cf) return false;
+ return true;
+}
+
+void memcopy(void* from, void* to, uint32 size){
+ if(from==NULL || to==NULL)
+ throw(ERR_NULLPTR);
+ for(uint32 i=0; i
#include
#include
+#include
#include
#include
#include
+typedef int8_t int8;
+typedef uint8_t uint8;
+typedef int16_t int16;
+typedef uint16_t uint16;
+typedef int32_t int32;
+typedef uint32_t uint32;
+typedef int64_t int64;
+typedef uint64_t uint64;
+typedef float float32;
+typedef double float64;
-#define dbg(N) printf("\e[95m%d\n",N)
-
+#define dbg(N) kprintf("\e[95m%d\n",N)
#ifdef _MSC_VER
#pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK
@@ -29,13 +39,12 @@ extern "C" {
#define CALL
#endif
#ifndef typeof
- #define typeof __typeof__
+ #define typeof(X) __typeof__(X)
#endif
#else
#pragma GCC error "unknown compiler"
#endif
-
#ifdef _MSC_VER
#define IFWIN(YES, NO) YES
#define IFMSC(YES, NO) YES
@@ -49,6 +58,23 @@ extern "C" {
#pragma GCC error "unknown compiler"
#endif
+#ifndef sprintf_s
+ #define sprintf_s(BUF, BUFSIZE, FORMAT, ...) sprintf(BUF, FORMAT, ## __VA_ARGS__)
+#endif
+
+
+#define __count_args(\
+ a0, a1, a2, a3, a4, a5, a6, a7,\
+ a8, a9, a10,a11,a12,a13,a14,a15,\
+ a16,a17,a18,a19,a20,a21,a22,a23,\
+ a24,a25,a26,a27,a28,a29,a30,a31,\
+ a32,...) a32
+#define count_args(ARGS...) __count_args(\
+ ARGS,\
+ 32,31,30,29,28,27,26,25,\
+ 24,23,22,21,20,19,18,17,\
+ 16,15,14,13,12,11,10,9,\
+ 8, 7, 6, 5, 4, 3, 2, 1, 0)
#if __cplusplus
}
diff --git a/src/base/type_system/README.md b/src/base/type_system/README.md
new file mode 100644
index 0000000..356cd5d
--- /dev/null
+++ b/src/base/type_system/README.md
@@ -0,0 +1,32 @@
+# kerep type system
+
+For using some kerep capabilities, such as generic structs, unitype, and kprint, types should be *registered*.
+
+## type id
+
+Every registered type has its own id (`ktId`), which should be declared in header file and defined in source file.
+Example:
+```c
+//someStruct.h
+typedef struct { } someStruct;
+ktId_declare(someStruct);
+ktId_declare(someStructPtr); // pointer to type is another type
+```
+```c
+//someStruct.c
+ktId_define(someStruct);
+ktId_define(someStructPtr);
+```
+
+## 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`).
+
+## type registration
+
+To finally register a type, you should call macro `kt_register()` between `ktDescriptors_beginInit()` and `ktDescriptors_endInit()`. Better do it at the start of your program. To register all types from kerep, call `ktDescriptors_initKerepTypes()`.
+
+You can free internal ktDescriptors storage by calling `ktDescriptors_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
+Examples:
++ [ktDescriptors_initKerepTypes()](src/base/type_system/init.c)
++ [kerep types registration](tests/main.cpp)
diff --git a/src/base/type_system/base_toString.c b/src/base/type_system/base_toString.c
new file mode 100644
index 0000000..02be90f
--- /dev/null
+++ b/src/base/type_system/base_toString.c
@@ -0,0 +1,186 @@
+#include "base_toString.h"
+#include "../base.h"
+#include "../../kprint/kprint_format.h"
+
+char* __toString_char(void* c, uint32 fmt) {
+ char* cc=malloc(2);
+ cc[0]=*(char*)c;
+ cc[1]=0;
+ return cc;
+}
+
+char* __toString_charPtr(void* c, uint32 fmt){
+ return cptr_copy(*(char**)c);
+}
+
+char* __toString_bool(void* c, uint32 fmt) {
+ static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
+ uint8 strind=*(bool*)c==1 + kprint_format_uppercase(fmt)*2;
+ char* rez=malloc(6);
+ rez[0]=_strbool[strind][0];
+ rez[1]=_strbool[strind][1];
+ rez[2]=_strbool[strind][2];
+ rez[3]=_strbool[strind][3];
+ rez[4]=_strbool[strind][4];
+ rez[5]=0;
+ return rez;
+}
+
+char* toString_int(int64 n){
+ int64 d=n;
+ char str[32];
+ uint8 i=sizeof(str);
+ str[--i]=0;
+ while(d!=0){
+ str[--i]='0' + d%10;
+ d/=10;
+ }
+ if(n>>63)
+ str[--i]='-';
+ return cptr_copy((char*)str+i);
+}
+
+char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
+ uint64 d=n;
+ char str[32];
+ uint8 i=sizeof(str);
+ str[--i]=0;
+ if(withPostfix)
+ str[--i]= uppercase ? 'U' : 'u';
+ while(d!=0){
+ str[--i]='0' + d%10;
+ d/=10;
+ }
+ return cptr_copy((char*)str+i);
+}
+
+char* toString_float(float64 n, bool withPostfix, bool uppercase){
+ // int64 d=n;
+ // float64 r=n-d;
+ // char* strint=toString_int(d);
+ // char strfract[32];
+ // uint8 i=0;
+ // strfract[i++]='.';
+ // while(r!=0){
+ // r*=10.0;
+ // char fc=r;
+ // strfract[i++]=fc;
+ // r-=fc;
+ // }
+ // if(withPostfix)
+ // strfract[i++]= uppercase ? 'F' : 'f';
+ // strfract[i]=0;
+ // char* str==cptr_concat(strint, strfract);
+ // free(strint);
+ // return str;
+ return cptr_copy("");
+}
+
+char* toString_bin(void* _bytes, uint32 size, bool withPrefix){
+ char* bytes=_bytes;
+ char* str=malloc(size*8 + (withPrefix?2:0) +1);
+ uint32 cn=0;
+ if(withPrefix){
+ str[cn++]='0';
+ str[cn++]='b';
+ }
+ for(uint32 bn=0; bn>i);
+ }
+ str[cn]=0;
+ return str;
+}
+
+char _4bitsHex(uint8 u, bool uppercase){
+ switch(u){
+ case 0: case 1: case 2: case 3: case 4:
+ case 5: case 6: case 7: case 8: case 9:
+ return '0'+u;
+ case 0xA: case 0xB: case 0xC:
+ case 0xD: case 0xE: case 0xF:
+ return (uppercase ? 'A' : 'a') + u -10;
+ default:
+ dbg(u);
+ throw("incorrect number");
+ return 219;
+ }
+}
+
+char* toString_hex(void* _bytes, uint32 size, bool withPrefix, bool uppercase){
+ char* bytes=_bytes;
+ char* str=malloc(size*2 + (withPrefix?2:0) + 1);
+ uint32 cn=0;
+ if(withPrefix){
+ str[cn++]='0';
+ str[cn++]='x';
+ }
+ for(uint32 bn=0; bnfunctions->freear=__Autoarr_free_Unitype_;
+ Autoarr_free(_uar, true);
+
+ // SearchTreeNode
+ kt_register(STNode, ktId_STNode, __STNode_free, NULL);
+ kt_register(STNode*, ktId_STNodePtr, __STNode_free, NULL);
+
+ // KeyValuePair
+ kt_register(KVPair, ktId_KVPair, __KVPair_free, NULL);
+ kt_register(KVPair*, ktId_KVPairPtr, __KVPair_free, NULL);
+ kt_register(Autoarr_KVPair, ktId_AutoarrKVPair, ____Autoarr_free_KVPair_, NULL);
+ kt_register(Autoarr_KVPair*, ktId_AutoarrKVPairPtr, ____Autoarr_free_KVPair_, NULL);
+ // replacing autogenerated freear() function to custom
+ Autoarr_KVPair* _kvpar=Autoarr_create(KVPair, 1, 1);
+ _kvpar->functions->freear=__Autoarr_free_KVPair_;
+ Autoarr_free(_kvpar, true);
+
+ // Hashtable
+ kt_register(Hashtable, ktId_Hashtable, __Hashtable_free, NULL);
+ kt_register(Hashtable*, ktId_HashtablePtr, __Hashtable_free, NULL);
+
+ // string
+ kt_register(string, ktId_string, NULL, NULL);
+ kt_register(string*, ktId_stringPtr, NULL, NULL);
+ kt_register(string, ktId_AutoarrString, ____Autoarr_free_string, NULL);
+ kt_register(string*, ktId_AutoarrStringPtr, ____Autoarr_free_string, NULL);
+ // StringBuilder
+ kt_register(StringBuilder, ktId_StringBuilder, __StringBuilder_free, NULL);
+ kt_register(StringBuilder*, ktId_StringBuilderPtr, __StringBuilder_free, NULL);
+}
diff --git a/src/base/type_system/init.h b/src/base/type_system/init.h
new file mode 100644
index 0000000..d08ef9d
--- /dev/null
+++ b/src/base/type_system/init.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+// call this between ktDescriptors_beginInit() and ktDescriptors_endInit()
+void ktDescriptors_initKerepTypes();
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/base/type_system/ktDescriptor.h b/src/base/type_system/ktDescriptor.h
new file mode 100644
index 0000000..a12facb
--- /dev/null
+++ b/src/base/type_system/ktDescriptor.h
@@ -0,0 +1,20 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../std.h"
+#include "ktId.h"
+
+typedef struct ktDescriptor{
+ char* name;
+ ktId id;
+ uint16 size;
+ void (*freeMembers)(void*); // NULL or function which frees all struct members
+ char* (*toString)(void* obj, uint32 fmt); // NULL or function which generates string representaion of object
+} ktDescriptor;
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/base/type_system/ktId.h b/src/base/type_system/ktId.h
new file mode 100644
index 0000000..63f7847
--- /dev/null
+++ b/src/base/type_system/ktId.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../std.h"
+typedef uint16 ktId;
+
+#define ktId_declare(TYPE_NAME)\
+ extern ktId ktId_##TYPE_NAME
+#define ktId_define(TYPE_NAME)\
+ ktId ktId_##TYPE_NAME=-1
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/base/type_system/kt_functions.c b/src/base/type_system/kt_functions.c
new file mode 100644
index 0000000..fa4a26d
--- /dev/null
+++ b/src/base/type_system/kt_functions.c
@@ -0,0 +1,82 @@
+#include "../../Autoarr/Autoarr.h"
+
+Autoarr_declare(ktDescriptor)
+Autoarr_define(ktDescriptor)
+
+ktId_define(Null);
+
+ktId_define(Char);
+ktId_define(Bool);
+ktId_define(Float32);
+ktId_define(Float64);
+ktId_define(Int8);
+ktId_define(UInt8);
+ktId_define(Int16);
+ktId_define(UInt16);
+ktId_define(Int32);
+ktId_define(UInt32);
+ktId_define(Int64);
+ktId_define(UInt64);
+
+ktId_define(CharPtr);
+ktId_define(BoolPtr);
+ktId_define(Float32Ptr);
+ktId_define(Float64Ptr);
+ktId_define(Int8Ptr);
+ktId_define(UInt8Ptr);
+ktId_define(Int16Ptr);
+ktId_define(UInt16Ptr);
+ktId_define(Int32Ptr);
+ktId_define(UInt32Ptr);
+ktId_define(Int64Ptr);
+ktId_define(UInt64Ptr);
+
+ktId_define(ktDescriptor);
+ktId_define(ktDescriptorPtr);
+
+// type descriptors are stored here during initialization
+Autoarr(ktDescriptor)* __ktDescriptors=NULL;
+// here type descriptors are stored when initialization is complited
+ktDescriptor* typeDescriptors=NULL;
+ktId ktId_last=-1;
+
+typedef enum{
+ NotInitialized, Initializing, Initialized
+} ktDescriptorsState;
+ktDescriptorsState initState=NotInitialized;
+
+void ktDescriptors_beginInit(){
+ kprintf("\e[94mtype descriptors initializing...\n");
+ __ktDescriptors=Autoarr_create(ktDescriptor, 256, 256);
+ if(__ktDescriptors==NULL) throw(ERR_NULLPTR);
+}
+
+void ktDescriptors_endInit(){
+ typeDescriptors=Autoarr_toArray(__ktDescriptors);
+ Autoarr_free(__ktDescriptors,true);
+ if(typeDescriptors==NULL) throw(ERR_NULLPTR);
+ kprintf("\e[92minitialized %u type descriptors\n", ktId_last);
+}
+
+void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32)){
+ ktDescriptor typeDesc={
+ .name=name,
+ .size=size,
+ .id=++ktId_last,
+ .freeMembers=freeMembers,
+ .toString=toString
+ };
+ Autoarr_add(__ktDescriptors, typeDesc);
+}
+
+ktDescriptor ktDescriptor_get(ktId id){
+ if(id>ktId_last) {
+ kprintf("\ntype id: %u\n",id);
+ throw("invalid type id");
+ }
+ return typeDescriptors[id];
+}
+
+void ktDescriptors_free(){
+ free(typeDescriptors);
+}
diff --git a/src/base/type_system/kt_functions.h b/src/base/type_system/kt_functions.h
new file mode 100644
index 0000000..cf27d3e
--- /dev/null
+++ b/src/base/type_system/kt_functions.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../std.h"
+#include "ktId.h"
+#include "ktDescriptor.h"
+
+extern ktId ktId_last;
+void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32));
+
+#define kt_register(TYPE, ID_VAR_NAME, FREE_MEMBERS_FUNC, TO_STRING_FUNC)\
+ __kt_register(#ID_VAR_NAME, sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
+ ID_VAR_NAME=ktId_last;
+
+void ktDescriptors_beginInit();
+void ktDescriptors_endInit();
+
+/// @param id id of registered type
+ktDescriptor ktDescriptor_get(ktId id);
+
+// call it to free heap-allocated ktDescriptors array
+void ktDescriptors_free();
+
+ktId_declare(Null);
+
+ktId_declare(Char);
+ktId_declare(Bool);
+ktId_declare(Float32);
+ktId_declare(Float64);
+ktId_declare(Int8);
+ktId_declare(UInt8);
+ktId_declare(Int16);
+ktId_declare(UInt16);
+ktId_declare(Int32);
+ktId_declare(UInt32);
+ktId_declare(Int64);
+ktId_declare(UInt64);
+
+ktId_declare(CharPtr);
+ktId_declare(BoolPtr);
+ktId_declare(Float32Ptr);
+ktId_declare(Float64Ptr);
+ktId_declare(Int8Ptr);
+ktId_declare(UInt8Ptr);
+ktId_declare(Int16Ptr);
+ktId_declare(UInt16Ptr);
+ktId_declare(Int32Ptr);
+ktId_declare(UInt32Ptr);
+ktId_declare(Int64Ptr);
+ktId_declare(UInt64Ptr);
+
+ktId_declare(ktDescriptor);
+ktId_declare(ktDescriptorPtr);
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/base/type_system/type_system.h b/src/base/type_system/type_system.h
new file mode 100644
index 0000000..2c20ac0
--- /dev/null
+++ b/src/base/type_system/type_system.h
@@ -0,0 +1,5 @@
+#include "init.h"
+#include "ktId.h"
+#include "ktDescriptor.h"
+#include "kt_functions.h"
+#include "unitype.h"
diff --git a/src/base/type_system/unitype.c b/src/base/type_system/unitype.c
new file mode 100644
index 0000000..59892fb
--- /dev/null
+++ b/src/base/type_system/unitype.c
@@ -0,0 +1,53 @@
+#include "../base.h"
+
+ktId_define(Unitype);
+ktId_define(UnitypePtr);
+
+void Unitype_free(Unitype u){
+ ktDescriptor type=ktDescriptor_get(u.typeId);
+ if(type.freeMembers)
+ type.freeMembers(u.VoidPtr);
+ if(u.allocatedInHeap)
+ free(u.VoidPtr);
+}
+void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
+
+char* toString_Unitype(void* _u, uint32 fmt){
+ Unitype* u=_u;
+ ktDescriptor type=ktDescriptor_get(u->typeId);
+ char* valuestr=type.toString(_u, fmt);
+ char* rezult=cptr_concat("{ type: ", type.name,
+ ", allocated on heap: ", (u->allocatedInHeap ? "true" : "false"),
+ ", value:", valuestr, " }");
+ free(valuestr);
+ return rezult;
+}
+
+
+
+#define BUFSIZE 64
+char* sprintuni(Unitype v){
+ char* buf=malloc(BUFSIZE);
+ ktDescriptor type=ktDescriptor_get(v.typeId);
+ if(v.typeId==ktId_Null)
+ sprintf_s(buf, BUFSIZE, "{Null}");
+ else if(v.typeId==ktId_Float64)
+ sprintf_s(buf, BUFSIZE, "{%s : %lf}", type.name,v.Float64);
+ else if(v.typeId==ktId_Bool || v.typeId==ktId_UInt64)
+ sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%llu", "%lu") "}", type.name,v.UInt64);
+ else if(v.typeId==ktId_Int64)
+ sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%lld", "%ld") "}", type.name,v.Int64);
+ else if(v.typeId==ktId_CharPtr){
+ size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2;
+ buf=realloc(buf, newBUFSIZE);
+ sprintf_s(buf, BUFSIZE, "{%s : \"%s\"}", type.name,(char*)v.VoidPtr);
+ }
+ else sprintf_s(buf, BUFSIZE, "{%s : %p}", type.name,v.VoidPtr);
+ return buf;
+}
+
+void printuni(Unitype v){
+ char* s=sprintuni(v);
+ fputs(s, stdout);
+ free(s);
+}
\ No newline at end of file
diff --git a/src/base/type_system/unitype.h b/src/base/type_system/unitype.h
new file mode 100644
index 0000000..666ee3e
--- /dev/null
+++ b/src/base/type_system/unitype.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "ktId.h"
+
+typedef struct Unitype{
+ union {
+ int64 Int64;
+ uint64 UInt64;
+ double Float64;
+ bool Bool;
+ void* VoidPtr;
+ char Bytes[8];
+ };
+ ktId typeId;
+ bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
+} Unitype;
+ktId_declare(Unitype);
+ktId_declare(UnitypePtr);
+
+
+#define __UniDef(TYPE, VAL) (Unitype){\
+ .TYPE=VAL, .typeId=ktId_##TYPE, .allocatedInHeap=false}
+
+#define UniInt64(VAL) __UniDef(Int64, VAL)
+#define UniUInt64(VAL) __UniDef(UInt64, VAL)
+#define UniFloat64(VAL) __UniDef(Float64, VAL)
+#define UniBool(VAL) __UniDef(Bool, VAL)
+
+#define UniStack(ID_VAR_NAME, VAL) (Unitype){\
+ .VoidPtr=VAL, .typeId=ID_VAR_NAME, .allocatedInHeap=false}
+#define UniHeap(ID_VAR_NAME, VAL) (Unitype){\
+ .VoidPtr=VAL, .typeId=ID_VAR_NAME, .allocatedInHeap=true}
+
+#define UniNull UniStack(ktId_Null, NULL)
+#define UniTrue UniBool(true)
+#define UniFalse UniBool(false)
+
+// frees VoidPtr value or does nothing if type isn't pointer
+void Unitype_free(Unitype u);
+void __UnitypePtr_free(void* u);
+void printuni(Unitype v);
+char* sprintuni(Unitype v);
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/base/types.c b/src/base/types.c
deleted file mode 100644
index fed1f0b..0000000
--- a/src/base/types.c
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "types.h"
-#include "errors.h"
-#include "../Autoarr/Autoarr.h"
-#include "../Hashtable/Hashtable.h"
-#include "../SearchTree/SearchTree.h"
-
-const char* my_type_name(my_type t){
- switch (t) {
- case Null: return "Null";
- case Float64: return "Float64";
- case Float32: return "Float32";
- case Bool: return "Bool";
- case Char: return "Char";
- case Int8: return "Int8";
- case UInt8: return "UInt8";
- case Int16: return "Int16";
- case UInt16: return "UInt16";
- case Int32: return "Int32";
- case UInt32: return "UInt32";
- case Int64: return "Int64";
- case UInt64: return "UInt64";
- case Int8Ptr: return "Int8Ptr";
- case UInt8Ptr: return "UInt8Ptr";
- case Int16Ptr: return "Int16Ptr";
- case UInt16Ptr: return "UInt16Ptr";
- case Int32Ptr: return "Int32Ptr";
- case UInt32Ptr: return "UInt32Ptr";
- case Int64Ptr: return "Int64Ptr";
- case UInt64Ptr: return "UInt64Ptr";
- case CharPtr: return "CharPtr";
- case STNodePtr: return "STNodePtr";
- case HashtablePtr: return "HashtablePtr";
- case UniversalType: return "Unitype";
- case AutoarrInt8Ptr: return "AutoarrInt8Ptr";
- case AutoarrUInt8Ptr: return "AutoarrUInt8Ptr";
- case AutoarrInt16Ptr: return "AutoarrInt16Ptr";
- case AutoarrUInt16Ptr: return "AutoarrUInt16Ptr";
- case AutoarrInt32Ptr: return "AutoarrInt32Ptr";
- case AutoarrUInt32Ptr: return "AutoarrUInt32Ptr";
- case AutoarrInt64Ptr: return "AutoarrInt64Ptr";
- case AutoarrUInt64Ptr: return "AutoarrUInt64Ptr";
- case AutoarrUnitypePtr: return "AutoarrUnitypePtr";
- case AutoarrKVPairPtr: return "AutoarrKVPairPtr";
- default: throw(ERR_WRONGTYPE);
- }
-}
-
-// frees VoidPtr value or does nothing if type isn't pointer
-void Unitype_free(Unitype u){
- switch (u.type) {
- case Null:
- case Float32:
- case Float64:
- case Char:
- case Bool:
- case Int8:
- case UInt8:
- case Int16:
- case UInt16:
- case Int32:
- case UInt32:
- case Int64:
- case UInt64:
- break;
- case Int8Ptr:
- case UInt8Ptr:
- case Int16Ptr:
- case UInt16Ptr:
- case Int32Ptr:
- case UInt32Ptr:
- case Int64Ptr:
- case UInt64Ptr:
- case CharPtr:
- free(u.VoidPtr);
- break;
- case HashtablePtr:
- Hashtable_free(u.VoidPtr);
- break;
- case STNodePtr:
- STNode_free(u.VoidPtr);
- break;
- case AutoarrInt8Ptr:
- __Autoarr_free_int8(u.VoidPtr);
- break;
- case AutoarrUInt8Ptr:
- __Autoarr_free_uint8(u.VoidPtr);
- break;
- case AutoarrInt16Ptr:
- __Autoarr_free_int16(u.VoidPtr);
- break;
- case AutoarrUInt16Ptr:
- __Autoarr_free_uint16(u.VoidPtr);
- break;
- case AutoarrInt32Ptr:
- __Autoarr_free_int32(u.VoidPtr);
- break;
- case AutoarrUInt32Ptr:
- __Autoarr_free_uint32(u.VoidPtr);
- break;
- case AutoarrInt64Ptr:
- __Autoarr_free_int64(u.VoidPtr);
- break;
- case AutoarrUInt64Ptr:
- __Autoarr_free_uint64(u.VoidPtr);
- break;
- case AutoarrUnitypePtr:
- Autoarr_free_Unitype(u.VoidPtr);
- break;
- case AutoarrKVPairPtr:
- Autoarr_free_KVPair(u.VoidPtr);
- break;
- default: throw(ERR_WRONGTYPE);
- }
-}
-
-#define BUFSIZE 64
-char* sprintuni(Unitype v){
- char* buf=malloc(BUFSIZE);
- IFMSC(
- switch (v.type) {
- case Null: sprintf_s(buf, BUFSIZE, "{Null}");break;
- case Float64: sprintf_s(buf, BUFSIZE, "{%s : %lf}", my_type_name(v.type),v.Float64);break;
- case Bool:
- case UInt64: sprintf_s(buf, BUFSIZE, "{%s : %lu}", my_type_name(v.type),v.UInt64);break;
- case Int64: sprintf_s(buf, BUFSIZE, "{%s : %ld}", my_type_name(v.type),v.Int64);break;
- case CharPtr: ;
- size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2;
- buf=realloc(buf, newBUFSIZE);
- sprintf_s(buf, newBUFSIZE, "{%s : \"%s\"}", my_type_name(v.type),(char*)v.VoidPtr);
- break;
- default: sprintf_s(buf, BUFSIZE, "{%s : %p}", my_type_name(v.type),v.VoidPtr);break;
- },
- switch (v.type) {
- case Null: sprintf(buf, "{Null}"); break;
- case Float64: sprintf(buf, "{%s : %lf}", my_type_name(v.type),v.Float64); break;
- case Bool:
- case UInt64: sprintf(buf, "{%s : " IFWIN("%llu", "%lu") "}", my_type_name(v.type),v.UInt64); break;
- case Int64: sprintf(buf, "{%s : " IFWIN("%lld", "%ld") "}", my_type_name(v.type),v.Int64); break;
- case CharPtr: ;
- size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2;
- buf=realloc(buf, newBUFSIZE);
- sprintf(buf, "{%s : \"%s\"}", my_type_name(v.type),(char*)v.VoidPtr);
- break;
- default: sprintf(buf, "{%s : %p}", my_type_name(v.type),v.VoidPtr);break;
- }
- );
- return buf;
-}
-
-void printuni(Unitype v){
- char* s=sprintuni(v);
- fputs(s, stdout);
- free(s);
-}
\ No newline at end of file
diff --git a/src/base/types.h b/src/base/types.h
deleted file mode 100644
index e34d95f..0000000
--- a/src/base/types.h
+++ /dev/null
@@ -1,58 +0,0 @@
-#pragma once
-
-#if __cplusplus
-extern "C" {
-#endif
-
-#include "std.h"
-
-typedef int8_t int8;
-typedef uint8_t uint8;
-typedef int16_t int16;
-typedef uint16_t uint16;
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
-typedef float float32;
-typedef double float64;
-typedef enum __attribute__((__packed__)) my_type {
- Null, Float32, Float64, Char, Bool,
- UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
- UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
- CharPtr, STNodePtr, HashtablePtr,
- UniversalType,
- AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
- AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
- AutoarrUnitypePtr, AutoarrKVPairPtr, knSocketPtr
-} my_type;
-#define my_type_last knSocketPtr
-
-const char* my_type_name(my_type t);
-
-typedef struct Unitype{
- union {
- int64 Int64;
- uint64 UInt64;
- double Float64;
- bool Bool;
- void* VoidPtr;
- };
- my_type type;
-} Unitype;
-
-static const Unitype UniNull={.VoidPtr=NULL,.type=Null};
-static const Unitype UniTrue={.Bool=true,.type=Bool};
-static const Unitype UniFalse={.Bool=false,.type=Bool};
-
-#define Uni(TYPE,VAL) (Unitype){.type=TYPE,.TYPE=VAL}
-#define UniPtr(TYPE,VAL) (Unitype){.type=TYPE,.VoidPtr=VAL}
-
-// frees VoidPtr value or does nothing if type isn't pointer
-void Unitype_free(Unitype u);
-void printuni(Unitype v);
-char* sprintuni(Unitype v);
-
-#if __cplusplus
-}
-#endif
\ No newline at end of file
diff --git a/src/kprint/README.md b/src/kprint/README.md
new file mode 100644
index 0000000..c59a66e
--- /dev/null
+++ b/src/kprint/README.md
@@ -0,0 +1,36 @@
+# kprintf
+It is just my variant of printf.
+
+# kprint
+I don't really like printf function (and its variants), so i made safer and more convinient replacement.
+
+| function | returns | arguments |
+|----------|---------|-----------|
+| kprint | void/throw | kprint_format, void*, kprint_format, void*... |
+| ksprint | Maybe | kprint_format, void*, kprint_format, void*... |
+| kfprint | Maybe | FILE*, kprint_format, void*, kprint_format, void*... |
+
+## how to use it:
++ **format construction:**
+ ```
+ kprint_format fmt= kprint_fgColor | kprint_bgColor | kprint_fdataFmt | flags | ktId;
+ ```
+ [more about `kprint_format`](kprint_format.md)
+ + fgColor and bgColor can be set to change console output color
+ + you should set dataFormat for `int`/`uint`/`float`/`char*` arguments and ktId for other types
+ + flags can be set to modify TypeDescriptor.toString() behavior
+ + don't forget to set TypeDescriptor.toString when registering type, or kprint will crash
+
++ **using base type arguments:**
+ you can just put them into a function
+ ```
+ kprint(kprint_fmtHex | kprint_fmtUppercase | kprint_fmtWithPrefix, 255);
+ ```
+ output: 0xFF
++ **using other registered types:**
+ should be sent as pointers
+ ```
+ Maybe m=MaybeNull;
+ kprint(kprint_fgBlue | kprint_fmtString, "Maybe: ", kprint_fgGreen | ktId_MaybePtr, &m);
+ ```
+ output: Maybe: {value={0, ktId_Null}}
\ No newline at end of file
diff --git a/src/kprint/kprint.c b/src/kprint/kprint.c
new file mode 100644
index 0000000..97186fb
--- /dev/null
+++ b/src/kprint/kprint.c
@@ -0,0 +1,168 @@
+#include "../String/StringBuilder.h"
+#include "kprint.h"
+
+ktId __typeFromFormat(kprint_format f){
+ ktId typeId=kprint_format_ktId(f);
+ if(typeId)
+ return typeId;
+ switch(kprint_format_dataFormat(f)){
+ case kprint_fmtInt:
+ case kprint_fmtHex:
+ case kprint_fmtBin:
+ return ktId_Int64;
+ case kprint_fmtUInt:
+ return ktId_UInt64;
+ case kprint_fmtFloat:
+ return ktId_Float64;
+ case kprint_fmtChar:
+ return ktId_Char;
+ case kprint_fmtString:
+ return ktId_CharPtr;
+ default:
+ return -1;
+ }
+}
+
+Maybe __next_toString(kprint_format f, __kprint_value_union* object){
+ // detecting type
+ ktId typeId=__typeFromFormat(f);
+ if(typeId==-1)
+ safethrow("typeId is not set, can't autodetect type",;);
+ ktDescriptor typeDesc=ktDescriptor_get(typeId);
+ if(!typeDesc.toString)
+ safethrow("type descriptor doesnt have toString() func",;);
+ return SUCCESS(UniHeap(ktId_CharPtr, typeDesc.toString(object, f)));
+}
+
+Maybe __ksprint(uint8 n, kprint_format* formats, __kprint_value_union* objects){
+ n/=2;
+ StringBuilder* strb=StringBuilder_create();
+ for(uint8 i=0; i
+#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
+
+DWORD kprint_fgColor_toWin(kprint_fgColor f){
+ //kprintf("fg: %x\n", f);
+ switch(f){
+ case kprint_fgBlack: return 0;
+ case kprint_fgDarkRed: return FOREGROUND_RED;
+ case kprint_fgDarkGreen: return FOREGROUND_GREEN;
+ case kprint_fgDarkYellow: return FOREGROUND_GREEN | FOREGROUND_RED;
+ case kprint_fgDarkBlue: return FOREGROUND_BLUE;
+ case kprint_fgDarkMagenta: return FOREGROUND_RED | FOREGROUND_BLUE;
+ case kprint_fgDarkCyan: return FOREGROUND_BLUE | FOREGROUND_GREEN;
+ case kprint_fgGray: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
+ case kprint_fgDarkGray: return FOREGROUND_INTENSITY;
+ case kprint_fgRed: return FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case kprint_fgGreen: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ case kprint_fgYellow: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case kprint_fgBlue: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
+ case kprint_fgMagenta: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case kprint_fgCyan: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ case kprint_fgWhite: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ default: throw(ERR_FORMAT);
+ }
+}
+
+DWORD kprint_bgColor_toWin(kprint_bgColor f){
+ //kprintf("bg: %x\n", f);
+ switch(f){
+ case kprint_bgBlack: return 0;
+ case kprint_bgDarkRed: return BACKGROUND_RED;
+ case kprint_bgDarkGreen: return BACKGROUND_GREEN;
+ case kprint_bgDarkYellow: return BACKGROUND_GREEN | BACKGROUND_RED;
+ case kprint_bgDarkBlue: return BACKGROUND_BLUE;
+ case kprint_bgDarkMagenta: return BACKGROUND_RED | BACKGROUND_BLUE;
+ case kprint_bgDarkCyan: return BACKGROUND_BLUE | BACKGROUND_GREEN;
+ case kprint_bgGray: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
+ case kprint_bgDarkGray: return BACKGROUND_INTENSITY;
+ case kprint_bgRed: return BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case kprint_bgGreen: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ case kprint_bgYellow: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case kprint_bgBlue: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
+ case kprint_bgMagenta: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case kprint_bgCyan: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ case kprint_bgWhite: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ default: throw(ERR_FORMAT);
+ }
+}
+
+void kprint_setColor(kprint_format f){
+ DWORD color=0;
+ if(!kprint_format_fgColorChanged(f) & !kprint_format_bgColorChanged(f))
+ return;
+ if(kprint_format_fgColorChanged(f))
+ color+=kprint_fgColor_toWin(kprint_format_fgColor(f));
+ if(kprint_format_bgColorChanged(f))
+ color+=kprint_bgColor_toWin(kprint_format_bgColor(f));
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ SetConsoleTextAttribute(hConsole, color);
+}
+#else
+void kprint_setColor(kprint_format f){
+ if(kprint_format_fgColorChanged(f)){
+ uint8 fg=(f&0x0f000000)>>24;
+ if(fg<8) fg+=30;
+ else fg+=90-8;
+ printf("\e[%um", fg);
+ }
+ if(kprint_format_bgColorChanged(f)){
+ uint8 bg=(f&0x00f00000)>>20;
+ if(bg<8) bg+=40;
+ else bg+=100-8;
+ printf("\e[%um", bg);
+ }
+}
+#endif
+
+/* Maybe ksprint_ar(uint32 count, kprint_format format, ktId typeId, void* array){
+ ktDescriptor typeDesc=ktDescriptor_get(format.typeId);
+ if(!typeDesc.toString)
+ safethrow("type descriptor doesnt have toString() func",;);
+ StringBuilder* strb=StringBuilder_create();
+ StringBuilder_append_char(strb, '[');
+ for (uint16 e=1; e
+
+WORD unixColorToWin(uint8 c){
+ switch(c){
+ //foreground
+ case 30: return 0;
+ case 31: return FOREGROUND_RED;
+ case 32: return FOREGROUND_GREEN;
+ case 33: return FOREGROUND_GREEN | FOREGROUND_RED;
+ case 34: return FOREGROUND_BLUE;
+ case 35: return FOREGROUND_RED | FOREGROUND_BLUE;
+ case 36: return FOREGROUND_BLUE | FOREGROUND_GREEN;
+ case 37: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
+ case 90: return FOREGROUND_INTENSITY;
+ case 91: return FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case 92: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ case 93: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case 94: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
+ case 95: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
+ case 96: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ case 97: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
+ //background
+ case 40: return 0;
+ case 41: return BACKGROUND_RED;
+ case 42: return BACKGROUND_GREEN;
+ case 43: return BACKGROUND_GREEN | BACKGROUND_RED;
+ case 44: return BACKGROUND_BLUE;
+ case 45: return BACKGROUND_RED | BACKGROUND_BLUE;
+ case 46: return BACKGROUND_BLUE | BACKGROUND_GREEN;
+ case 47: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
+ case 100: return BACKGROUND_INTENSITY;
+ case 101: return BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case 102: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ case 103: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case 104: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
+ case 105: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
+ case 106: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ case 107: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
+ default: return 0;
+ }
+}
+#endif
+
+void kprintf(const char* format, ...){
+ va_list vl;
+ va_start(vl, format);
+ uint32 i=0;
+ for(char c=format[i++]; c!=0; c=format[i++]){
+ if(c=='%'){
+ char* argstr=NULL;
+ c=format[i++];
+ format_escape_seq:
+ switch (c) {
+ case 'u':
+ argstr=toString_uint(va_arg(vl, uint64),0,0);
+ break;
+ case 'i': case 'd':
+ argstr=toString_int(va_arg(vl, uint64));
+ break;
+ case 'f':
+ argstr=toString_float(va_arg(vl, float64),0,0);
+ break;
+ case 'l':
+ if((c=format[i++]))
+ goto format_escape_seq;
+ break;
+ // switch (c) {
+ // case 'u':
+ // argstr=toString_uint(va_arg(vl, uint64),0,0);
+ // break;
+ // case 'i':
+ // argstr=toString_int(va_arg(vl, uint64));
+ // break;
+ // case 'f':
+ // argstr=toString_float(va_arg(vl, float64),0,0);
+ // break;
+ // default:
+ // throw(ERR_FORMAT);
+ // }
+ // break;
+ case 'p':
+ case 'x':
+ uint64 px=va_arg(vl, uint64);
+ argstr=toString_hex(&px,sizeof(px),1,0);
+ break;
+ case 's':
+ char* cptr=va_arg(vl,char*);
+ if(!cptr)
+ cptr="";
+ if(*cptr)
+ fputs(cptr, stdout);
+ break;
+ case 'c':
+ argstr=malloc(2);
+ argstr[0]=(char)va_arg(vl,int);
+ argstr[1]=0;
+ break;
+ default:
+ putc('\n',stdout);
+ putc('<',stdout);
+ putc(c,stdout);
+ putc('>',stdout);
+ throw(ERR_FORMAT);
+ }
+ if(argstr){
+ fputs(argstr, stdout);
+ free(argstr);
+ }
+ } else if(c=='\e'){
+ IFWIN(
+ ({
+ if((c=format[i++])=='['){
+ uint8 colorUnix=0;
+ for(int8 n=0; n<6 && c!=0; n++){
+ c=format[i++];
+ switch (c){
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ colorUnix=colorUnix*10+c-'0';
+ break;
+ case 'm':
+ WORD colorWin=unixColorToWin(colorUnix);
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ SetConsoleTextAttribute(hConsole, colorWin);
+ goto end_iteration;
+ default:
+ goto end_iteration;
+ }
+ }
+ }
+ }),
+ putc(c,stdout);
+ );
+ } else {
+ putc(c,stdout);
+ }
+ #if defined(_WIN64) || defined(_WIN32)
+ end_iteration:
+ #endif
+ }
+ va_end(vl);
+}
diff --git a/src/kprint/kprintf.h b/src/kprint/kprintf.h
new file mode 100644
index 0000000..0ca5a68
--- /dev/null
+++ b/src/kprint/kprintf.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+// cross-platform kprintf analog
+void kprintf(const char* format, ...);
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/random/krandom.h b/src/random/krandom.h
new file mode 100644
index 0000000..d78b7d6
--- /dev/null
+++ b/src/random/krandom.h
@@ -0,0 +1,72 @@
+#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(uint32 seed);
+ uint32 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 int8 krand_next8 (krand_statePtr state, int8 from, int8 to) __krand_next_definition(32)
+static inline int16 krand_next16(krand_statePtr state, int16 from, int16 to) __krand_next_definition(32)
+static inline int32 krand_next32(krand_statePtr state, int32 from, int32 to) __krand_next_definition(32)
+static inline int64 krand_next64(krand_statePtr state, int64 from, int64 to) __krand_next_definition(64)
+
+// divides random number by 2^64 to return a value between 0 and 1
+static inline float32 krand_nextFloat32(krand_statePtr state) {return (uint32)KRAND_ALG32_next(state)/0xffffffff; }
+static inline float64 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){
+ int limit=1/chance + 0.01f;
+ return KRAND_ALG32_next(state)%limit == 0;
+}
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/random/splitmix64/splitmix64.c b/src/random/splitmix64/splitmix64.c
new file mode 100644
index 0000000..591167c
--- /dev/null
+++ b/src/random/splitmix64/splitmix64.c
@@ -0,0 +1,34 @@
+#include "splitmix64.h"
+
+/*
+This is a fixed-increment version of Java 8's SplittableRandom generator
+See http://dx.doi.org/10.1145/2714064.2660195 and
+http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
+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
+rather suggest to use a xoroshiro128+ (for moderately parallel
+computations) or xorshift1024* (for massively parallel computations)
+generator.
+*/
+
+// The state can be seeded with any (upto) 64 bit integer value.
+
+void* splitmix64_init(uint64 seed){
+ splitmix64_state* state=malloc(sizeof(splitmix64_state));
+ *state=seed;
+ return state;
+}
+
+uint64 splitmix64_next(void* _state) {
+ splitmix64_state* state=_state;
+ // increment the state variable
+ *state += 0x9e3779b97f4a7c15;
+ // copy the state to a working variable
+ uint64 z = *state;
+ // xor the variable with the variable right bit shifted 30 then multiply by a constant
+ z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
+ // xor the variable with the variable right bit shifted 27 then multiply by a constant
+ z = (z ^ (z>>27)) * 0x94d049bb133111eb;
+ // return the variable xored with itself right bit shifted 31
+ return z ^ (z>>31);
+}
diff --git a/src/random/splitmix64/splitmix64.h b/src/random/splitmix64/splitmix64.h
new file mode 100644
index 0000000..8cf8104
--- /dev/null
+++ b/src/random/splitmix64/splitmix64.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../../base/base.h"
+
+typedef uint64 splitmix64_state;
+typedef void* splitmix64_statePtr;
+
+splitmix64_statePtr splitmix64_init(uint64 seed);
+static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
+
+uint64 splitmix64_next(splitmix64_statePtr);
+static inline void splitmix64_free(splitmix64_statePtr state) {
+ free(state);
+}
+
+#if __cplusplus
+}
+#endif
\ No newline at end of file
diff --git a/src/random/xoroshiro/32bitValue/xoroshiro64.h b/src/random/xoroshiro/32bitValue/xoroshiro64.h
new file mode 100644
index 0000000..6377bba
--- /dev/null
+++ b/src/random/xoroshiro/32bitValue/xoroshiro64.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../../../base/std.h"
+#include "../../splitmix64/splitmix64.h"
+
+typedef union {
+ uint64 merged;
+ uint32 s[2];
+} xoroshiro64_state;
+typedef void* xoroshiro64_statePtr;
+
+xoroshiro64_statePtr xoroshiro64_init(uint64 seed);
+#define xoroshiro64star_init xoroshiro64_init
+#define xoroshiro64starstar_init xoroshiro64_init
+
+static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoroshiro64_init(time(NULL)); }
+#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
+#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
+
+uint32 xoroshiro64star_next(xoroshiro64_statePtr);
+uint32 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
+}
+#endif
\ No newline at end of file
diff --git a/src/random/xoroshiro/32bitValue/xoroshiro64star.c b/src/random/xoroshiro/32bitValue/xoroshiro64star.c
new file mode 100644
index 0000000..7c2fd3c
--- /dev/null
+++ b/src/random/xoroshiro/32bitValue/xoroshiro64star.c
@@ -0,0 +1,49 @@
+/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoroshiro64.h"
+
+/*
+This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
+generator for 32-bit floating-point numbers. We suggest to use its
+upper bits for floating-point generation, as it is slightly faster than
+xoroshiro64**. It passes all tests we are aware of except for linearity
+tests, as the lowest six bits have low linear complexity, so if low
+linear complexity is not considered an issue (as it is usually the
+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
+right shifts to extract subsets of bits.
+
+The state must be seeded so that it is not everywhere zero.
+*/
+
+static inline uint32 rotl(const uint32 x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+uint32 xoroshiro64star_next(void* _state) {
+ xoroshiro64_state* state=_state;
+ const uint32 s0 = state->s[0];
+ uint32 s1 = state->s[1];
+ const uint32 result = s0 * 0x9E3779BB;
+
+ s1 ^= s0;
+ state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
+ state->s[1] = rotl(s1, 13); // c
+
+ return result;
+}
+
+void* xoroshiro64_init(uint64 seed){
+ xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
+ splitmix64_state* splitmix=splitmix64_init(seed);
+ state->merged=splitmix64_next(splitmix);
+ splitmix64_free(splitmix);
+ return state;
+}
diff --git a/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c b/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
new file mode 100644
index 0000000..df4432e
--- /dev/null
+++ b/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
@@ -0,0 +1,37 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoroshiro64.h"
+
+/* This is xoroshiro64** 1.0, our 32-bit all-purpose, rock-solid,
+ small-state generator. It is extremely fast and it passes all tests we
+ are aware of, but its state space is not large enough for any parallel
+ application.
+
+ For generating just single-precision (i.e., 32-bit) floating-point
+ numbers, xoroshiro64* is even faster.
+
+ The state must be seeded so that it is not everywhere zero. */
+
+
+static inline uint32 rotl(const uint32 x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+uint32 xoroshiro64starstar_next(void* _state) {
+ xoroshiro64_state* state=_state;
+ const uint32 s0 = state->s[0];
+ uint32 s1 = state->s[1];
+ const uint32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
+
+ s1 ^= s0;
+ state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
+ state->s[1] = rotl(s1, 13); // c
+
+ return result;
+}
diff --git a/src/random/xoroshiro/64bitValue/xoroshiro128.h b/src/random/xoroshiro/64bitValue/xoroshiro128.h
new file mode 100644
index 0000000..63ed537
--- /dev/null
+++ b/src/random/xoroshiro/64bitValue/xoroshiro128.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../../../base/std.h"
+#include "../../splitmix64/splitmix64.h"
+
+
+typedef union {
+ uint32 s[2];
+} xoroshiro128_state;
+typedef void* xoroshiro128_statePtr;
+
+xoroshiro128_statePtr xoroshiro128_init(uint64 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)); }
+#define xoroshiro128plus_initFromTime xoroshiro128_initFromTime
+#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
+#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
+
+uint64 xoroshiro128plus_next(xoroshiro128_statePtr);
+uint64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
+uint64 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
+}
+#endif
\ No newline at end of file
diff --git a/src/random/xoroshiro/64bitValue/xoroshiro128plus.c b/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
new file mode 100644
index 0000000..e01e0b5
--- /dev/null
+++ b/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
@@ -0,0 +1,59 @@
+/* Written in 2016-2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoroshiro128.h"
+
+/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
+ for floating-point numbers, but its state space is large enough only
+ for mild parallelism. We suggest to use its upper bits for
+ floating-point generation, as it is slightly faster than
+ xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
+ except for the four lower bits, which might fail linearity tests (and
+ just those), so if low linear complexity is not considered an issue (as
+ it is usually the case) it can be used to generate 64-bit outputs, too;
+ moreover, this generator has a very mild Hamming-weight dependency
+ making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
+ output; we believe this slight bias cannot affect any application. If
+ you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
+
+ We suggest to use a sign test to extract a random Boolean value, and
+ right shifts to extract subsets of bits.
+
+ 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
+ output to fill s.
+
+ 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).
+*/
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64 xoroshiro128plus_next(void* _state){
+ xoroshiro128_state* state=_state;
+ const uint64 s0 = state->s[0];
+ uint64 s1 = state->s[1];
+ const uint64 result = s0 + s1;
+
+ s1 ^= s0;
+ state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
+ state->s[1] = rotl(s1, 37); // c
+
+ return result;
+}
+
+void* xoroshiro128_init(uint64 seed){
+ xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
+ splitmix64_state* splitmix=splitmix64_init(seed);
+ state->s[0]=splitmix64_next(splitmix);
+ state->s[1]=splitmix64_next(splitmix);
+ splitmix64_free(splitmix);
+ return state;
+}
diff --git a/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c b/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
new file mode 100644
index 0000000..c01fb30
--- /dev/null
+++ b/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
@@ -0,0 +1,39 @@
+/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoroshiro128.h"
+
+/* This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
+ small-state generators. It is extremely (sub-ns) fast and it passes all
+ tests we are aware of, but its state space is large enough only for
+ mild parallelism.
+
+ For generating just floating-point numbers, xoroshiro128+ is even
+ faster (but it has a very mild bias, see notes in the comments).
+
+ 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
+ output to fill s. */
+
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64 xoroshiro128plusplus_next(void* _state){
+ xoroshiro128_state* state=_state;
+ const uint64 s0 = state->s[0];
+ uint64 s1 = state->s[1];
+ const uint64 result = rotl(s0 + s1, 17) + s0;
+
+ s1 ^= s0;
+ state->s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
+ state->s[1] = rotl(s1, 28); // c
+
+ return result;
+}
diff --git a/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c b/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
new file mode 100644
index 0000000..3e9ac72
--- /dev/null
+++ b/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
@@ -0,0 +1,39 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoroshiro128.h"
+
+/* This is xoroshiro128** 1.0, one of our all-purpose, rock-solid,
+ small-state generators. It is extremely (sub-ns) fast and it passes all
+ tests we are aware of, but its state space is large enough only for
+ mild parallelism.
+
+ For generating just floating-point numbers, xoroshiro128+ is even
+ faster (but it has a very mild bias, see notes in the comments).
+
+ 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
+ output to fill s. */
+
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64 xoroshiro128starstar_next(void* _state){
+ xoroshiro128_state* state=_state;
+ const uint64 s0 = state->s[0];
+ uint64 s1 = state->s[1];
+ const uint64 result = rotl(s0 * 5, 7) * 9;
+
+ s1 ^= s0;
+ state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
+ state->s[1] = rotl(s1, 37); // c
+
+ return result;
+}
diff --git a/src/random/xoroshiro/xoroshiro.h b/src/random/xoroshiro/xoroshiro.h
new file mode 100644
index 0000000..127c937
--- /dev/null
+++ b/src/random/xoroshiro/xoroshiro.h
@@ -0,0 +1,2 @@
+#include "32bitValue/xoroshiro64.h"
+#include "64bitValue/xoroshiro128.h"
diff --git a/src/random/xoshiro-xoroshiro.md b/src/random/xoshiro-xoroshiro.md
new file mode 100644
index 0000000..269477c
--- /dev/null
+++ b/src/random/xoshiro-xoroshiro.md
@@ -0,0 +1,24 @@
+# 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
+├── 32bitValue
+| ├── xoroshiro64star.c
+| └── xoroshiro64starstar.c
+└── 64bitValue
+ ├── xoroshiro128plus.c
+ ├── xoroshiro128plusplus.c
+ └── xoroshiro128starstar.c
+
+xoshiro
+├── 32bitValue
+│ ├── xoshiro128plus.c
+│ ├── xoshiro128plusplus.c
+│ └── xoshiro128starstar.c
+└── 64bitValue
+ ├── xoshiro256plus.c
+ ├── xoshiro256plusplus.c
+ └── xoshiro256starstar.c
+```
diff --git a/src/random/xoshiro/32bitValue/xoshiro128.h b/src/random/xoshiro/32bitValue/xoshiro128.h
new file mode 100644
index 0000000..02d52e8
--- /dev/null
+++ b/src/random/xoshiro/32bitValue/xoshiro128.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../../../base/std.h"
+#include "../../splitmix64/splitmix64.h"
+
+
+typedef union {
+ uint64 merged[2];
+ uint32 s[4];
+} xoshiro128_state;
+typedef void* xoshiro128_statePtr;
+
+xoshiro128_statePtr xoshiro128_init(uint64 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)); }
+#define xoshiro128plus_initFromTime xoshiro128_initFromTime
+#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
+#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
+
+uint32 xoshiro128plus_next(xoshiro128_statePtr);
+uint32 xoshiro128plusplus_next(xoshiro128_statePtr);
+uint32 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
+}
+#endif
\ No newline at end of file
diff --git a/src/random/xoshiro/32bitValue/xoshiro128plus.c b/src/random/xoshiro/32bitValue/xoshiro128plus.c
new file mode 100644
index 0000000..8cafc8b
--- /dev/null
+++ b/src/random/xoshiro/32bitValue/xoshiro128plus.c
@@ -0,0 +1,54 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro128.h"
+
+/* This is xoshiro128+ 1.0, our best and fastest 32-bit generator for 32-bit
+ floating-point numbers. We suggest to use its upper bits for
+ floating-point generation, as it is slightly faster than xoshiro128**.
+ It passes all tests we are aware of except for
+ linearity tests, as the lowest four bits have low linear complexity, so
+ if low linear complexity is not considered an issue (as it is usually
+ the 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
+ right shifts to extract subsets of bits.
+
+ The state must be seeded so that it is not everywhere zero. */
+
+
+static inline uint32 rotl(const uint32 x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+uint32 xoshiro128plus_next(void* _state){
+ xoshiro128_state* state=_state;
+ const uint32 result = state->s[0] + state->s[3];
+
+ const uint32 t = state->s[1] << 9;
+
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+
+ state->s[2] ^= t;
+
+ state->s[3] = rotl(state->s[3], 11);
+
+ return result;
+}
+
+void* xoshiro128_init(uint64 seed){
+ xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
+ splitmix64_state* splitmix=splitmix64_init(seed);
+ state->merged[0]=splitmix64_next(splitmix);
+ state->merged[1]=splitmix64_next(splitmix);
+ splitmix64_free(splitmix);
+ return state;
+}
diff --git a/src/random/xoshiro/32bitValue/xoshiro128plusplus.c b/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
new file mode 100644
index 0000000..e9be19d
--- /dev/null
+++ b/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
@@ -0,0 +1,42 @@
+/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro128.h"
+
+/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
+ generators. It has excellent speed, a state size (128 bits) that is
+ large enough for mild parallelism, and it passes all tests we are aware
+ of.
+
+ For generating just single-precision (i.e., 32-bit) floating-point
+ numbers, xoshiro128+ is even faster.
+
+ The state must be seeded so that it is not everywhere zero. */
+
+
+static inline uint32 rotl(const uint32 x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+uint32 xoshiro128plusplus_next(void* _state){
+ xoshiro128_state* state=_state;
+ const uint32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
+
+ const uint32 t = state->s[1] << 9;
+
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+
+ state->s[2] ^= t;
+
+ state->s[3] = rotl(state->s[3], 11);
+
+ return result;
+}
diff --git a/src/random/xoshiro/32bitValue/xoshiro128starstar.c b/src/random/xoshiro/32bitValue/xoshiro128starstar.c
new file mode 100644
index 0000000..40a53d2
--- /dev/null
+++ b/src/random/xoshiro/32bitValue/xoshiro128starstar.c
@@ -0,0 +1,45 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro128.h"
+
+/* This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
+ generators. It has excellent speed, a state size (128 bits) that is
+ large enough for mild parallelism, and it passes all tests we are aware
+ of.
+
+ Note that version 1.0 had mistakenly state->s[0] instead of state->s[1] as state
+ word passed to the scrambler.
+
+ For generating just single-precision (i.e., 32-bit) floating-point
+ numbers, xoshiro128+ is even faster.
+
+ The state must be seeded so that it is not everywhere zero. */
+
+
+static inline uint32 rotl(const uint32 x, int k) {
+ return (x << k) | (x >> (32 - k));
+}
+
+uint32 xoshiro128starstar_next(void* _state){
+ xoshiro128_state* state=_state;
+ const uint32 result = rotl(state->s[1] * 5, 7) * 9;
+
+ const uint32 t = state->s[1] << 9;
+
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+
+ state->s[2] ^= t;
+
+ state->s[3] = rotl(state->s[3], 11);
+
+ return result;
+}
diff --git a/src/random/xoshiro/64bitValue/xoshiro256.h b/src/random/xoshiro/64bitValue/xoshiro256.h
new file mode 100644
index 0000000..479c6aa
--- /dev/null
+++ b/src/random/xoshiro/64bitValue/xoshiro256.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#if __cplusplus
+extern "C" {
+#endif
+
+#include "../../../base/std.h"
+#include "../../splitmix64/splitmix64.h"
+
+
+typedef union {
+ uint64 s[4];
+} xoshiro256_state;
+typedef void* xoshiro256_statePtr;
+
+xoshiro256_statePtr xoshiro256_init(uint64 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)); }
+#define xoshiro256plus_initFromTime xoshiro256_initFromTime
+#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
+#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
+
+uint64 xoshiro256plus_next(xoshiro256_statePtr);
+uint64 xoshiro256plusplus_next(xoshiro256_statePtr);
+uint64 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
+}
+#endif
\ No newline at end of file
diff --git a/src/random/xoshiro/64bitValue/xoshiro256plus.c b/src/random/xoshiro/64bitValue/xoshiro256plus.c
new file mode 100644
index 0000000..066ef8a
--- /dev/null
+++ b/src/random/xoshiro/64bitValue/xoshiro256plus.c
@@ -0,0 +1,58 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro256.h"
+
+/* This is xoshiro256+ 1.0, our best and fastest generator for floating-point
+ numbers. We suggest to use its upper bits for floating-point
+ generation, as it is slightly faster than xoshiro256++/xoshiro256**. It
+ passes all tests we are aware of except for the lowest three bits,
+ which might fail linearity tests (and just those), so if low linear
+ complexity is not considered an issue (as it is usually the case) it
+ can be used to generate 64-bit outputs, too.
+
+ We suggest to use a sign test to extract a random Boolean value, and
+ right shifts to extract subsets of bits.
+
+ 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
+ output to fill s. */
+
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64 xoshiro256plus_next(void* _state){
+ xoshiro256_state* state=_state;
+ const uint64 result = state->s[0] + state->s[3];
+
+ const uint64 t = state->s[1] << 17;
+
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+
+ state->s[2] ^= t;
+
+ state->s[3] = rotl(state->s[3], 45);
+
+ return result;
+}
+
+void* xoshiro256_init(uint64 seed){
+ xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
+ splitmix64_state* splitmix=splitmix64_init(seed);
+ state->s[0]=splitmix64_next(splitmix);
+ state->s[1]=splitmix64_next(splitmix);
+ state->s[2]=splitmix64_next(splitmix);
+ state->s[3]=splitmix64_next(splitmix);
+ splitmix64_free(splitmix);
+ return state;
+}
diff --git a/src/random/xoshiro/64bitValue/xoshiro256plusplus.c b/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
new file mode 100644
index 0000000..77ca943
--- /dev/null
+++ b/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
@@ -0,0 +1,37 @@
+/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro256.h"
+
+/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
+ It has excellent (sub-ns) speed, a state (256 bits) that is large
+ enough for any parallel application, and it passes all tests we are
+ aware of.
+
+ For generating just floating-point numbers, xoshiro256+ is even faster.
+
+ 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
+ output to fill s. */
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x>>(64 - k));
+}
+
+uint64 xoshiro256plusplus_next(void* _state) {
+ xoshiro256_state* state=_state;
+ const uint64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0];
+ const uint64 t=state->s[1] << 17;
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+ state->s[2] ^= t;
+ state->s[3]=rotl(state->s[3], 45);
+ return result;
+}
diff --git a/src/random/xoshiro/64bitValue/xoshiro256starstar.c b/src/random/xoshiro/64bitValue/xoshiro256starstar.c
new file mode 100644
index 0000000..7829096
--- /dev/null
+++ b/src/random/xoshiro/64bitValue/xoshiro256starstar.c
@@ -0,0 +1,42 @@
+/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
+
+To the extent possible under law, the author has dedicated all copyright
+and related and neighboring rights to this software to the public domain
+worldwide. This software is distributed without any warranty.
+
+See . */
+
+#include "xoshiro256.h"
+
+/* This is xoshiro256** 1.0, one of our all-purpose, rock-solid
+ generators. It has excellent (sub-ns) speed, a state (256 bits) that is
+ large enough for any parallel application, and it passes all tests we
+ are aware of.
+
+ For generating just floating-point numbers, xoshiro256+ is even faster.
+
+ 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
+ output to fill s. */
+
+static inline uint64 rotl(const uint64 x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64 xoshiro256starstar_next(void* _state){
+ xoshiro256_state* state=_state;
+ const uint64 result = rotl(state->s[1] * 5, 7) * 9;
+
+ const uint64 t = state->s[1] << 17;
+
+ state->s[2] ^= state->s[0];
+ state->s[3] ^= state->s[1];
+ state->s[1] ^= state->s[2];
+ state->s[0] ^= state->s[3];
+
+ state->s[2] ^= t;
+
+ state->s[3] = rotl(state->s[3], 45);
+
+ return result;
+}
diff --git a/src/random/xoshiro/xoshiro.h b/src/random/xoshiro/xoshiro.h
new file mode 100644
index 0000000..121ed3a
--- /dev/null
+++ b/src/random/xoshiro/xoshiro.h
@@ -0,0 +1,2 @@
+#include "32bitValue/xoshiro128.h"
+#include "64bitValue/xoshiro256.h"
diff --git a/tests/main.cpp b/tests/main.cpp
index b68a42d..6338d3b 100644
--- a/tests/main.cpp
+++ b/tests/main.cpp
@@ -5,17 +5,24 @@ void test_all(){
test_safethrow();
test_searchtree();
test_autoarr();
+ test_autoarrVsVector();
test_hash_functions();
test_hashtable();
test_dtsod();
- test_network();
- printf("\e[96m--------------------------------------\e[0m\n");
+ test_rng_algorithms();
+ test_kprint_colors();
+ kprintf("\e[96m--------------------------------------\e[0m\n");
}
-
int main(){
- setlocale(LC_ALL, "en-US.Unicode");
- printf("\e[92mkerep tests are starting!\e[97m\n");
- optime("test_all",1,test_all());
- printf("\e[0m\n");
+ if(!setlocale(LC_ALL, "C.UTF8"))
+ kprintf("\e[93msetlocale failed\n");
+ ktDescriptors_beginInit();
+ ktDescriptors_initKerepTypes();
+ ktDescriptors_endInit();
+ kprintf("\e[97mkerep tests are starting!\n");
+ //optime("test_all",1,test_all());
+ ktDescriptors_free();
+ kprintf("ъъъъ");
+ kprintf("\e[0m\n");
return 0;
}
diff --git a/tests/test_autoarr-vs-vector.cpp b/tests/test_autoarr-vs-vector.cpp
new file mode 100644
index 0000000..f349435
--- /dev/null
+++ b/tests/test_autoarr-vs-vector.cpp
@@ -0,0 +1,40 @@
+#include "tests.h"
+#include "../src/Autoarr/Autoarr.h"
+#include
+
+int64 _autoarrVsVector(uint16 blockCount, uint16 blockLength){
+ uint32 count=blockLength*blockCount;
+ kprintf("\e[94mblock count: %u block length: %u count: " IFWIN("%llu", "%lu") "\n", blockCount, blockLength, (uint64)count);
+ Autoarr_int64* ar=Autoarr_create(int64, blockCount, blockLength);
+ std::vector vec=std::vector();
+ optime("Autoarr_add", 1, ({
+ for(uint32 i=0; i< count; i++)
+ Autoarr_add(ar, i);
+ }));
+ optime("vector_push_back", 1, ({
+ for(uint32 i=0; i< count; i++)
+ vec.push_back(i);
+ }));
+ int64 t=0;
+ optime("Autoarr_get", 1, ({
+ for(uint32 i=0; i< count; i++)
+ t=Autoarr_get(ar, i);
+ }));
+ optime("vector_get", 1, ({
+ for(uint32 i=0; i< count; i++)
+ t=vec[i];
+ }));
+ Autoarr_free(ar, true);
+ return t;
+}
+
+void test_autoarrVsVector(){
+ kprintf("\e[96m-------[test_autoarr_vs_vector]-------\n");
+ _autoarrVsVector(4, 16);
+ _autoarrVsVector(16, 64);
+ _autoarrVsVector(32, 32);
+ _autoarrVsVector(64, 64);
+ _autoarrVsVector(32, 1024);
+ _autoarrVsVector(256, 256);
+ _autoarrVsVector(1024, 1024);
+}
diff --git a/tests/test_autoarr.c b/tests/test_autoarr.c
index 11b818d..2b3d24d 100644
--- a/tests/test_autoarr.c
+++ b/tests/test_autoarr.c
@@ -2,7 +2,7 @@
#include "../src/Autoarr/Autoarr.h"
static void printautoarr(Autoarr(uint16)* ar){
- printf("\e[94mAutoarr(uint16): "
+ kprintf("\e[94mAutoarr(uint16): "
IFWIN("%llu", "%lu")
"\n max_blocks_count: %u\n"
" blocks_count: %u\n"
@@ -29,25 +29,25 @@ static void resetar(Autoarr(uint16)* ar){
}
static void printallval(Autoarr(uint16)* ar){
- printf("\e[90m");
+ kprintf("\e[90m");
for (uint16 i=0;i=100?0:(i>=10?1:2));
char* str1=char_multiply(' ',lgs[i]>=100?0:(lgs[i]>=10?1:2));
char* str2=char_multiply('#',lgs[i]/100);
- printf("\e[94m length: \e[96m%u %s \e[94mfrequency: \e[96m%u %s \e[90m%s\n",i,str0,lgs[i],str1,str2);
+ kprintf("\e[94m length: \e[96m%u %s \e[94mfrequency: \e[96m%u %s \e[90m%s\n",i,str0,lgs[i],str1,str2);
free(str0);
free(str1);
free(str2);
@@ -47,7 +47,7 @@ char* genkey(uint32 i){
void fill(Hashtable* ht){
for(uint32 i=0;i<100000;i++)
- Hashtable_add(ht,genkey(i),Uni(UInt64,i));
+ Hashtable_add(ht,genkey(i),UniUInt64(i));
}
Unitype gett(Hashtable* ht){
@@ -63,15 +63,15 @@ Unitype gett(Hashtable* ht){
void test_hashtable(){
optime("test_hashtable",1,({
- printf("\e[96m-----------[test_hashtable]-----------\n");
+ kprintf("\e[96m-----------[test_hashtable]-----------\n");
Hashtable* ht=Hashtable_create();
- printf("\e[92mhashtable created\n");
+ kprintf("\e[92mhashtable created\n");
print_hashtable(ht);
optime("fill",1,fill(ht));
optime("get",1,gett(ht));
printrowgraph(ht);
print_hashtable(ht);
Hashtable_free(ht);
- printf("\e[92mhashtable freed\n");
+ kprintf("\e[92mhashtable freed\n");
}));
}
diff --git a/tests/test_kprint_colors.c b/tests/test_kprint_colors.c
new file mode 100644
index 0000000..afe3640
--- /dev/null
+++ b/tests/test_kprint_colors.c
@@ -0,0 +1,50 @@
+#include "tests.h"
+#include "../src/kprint/kprint.h"
+#if defined(_WIN32)|| defined(_WIN64)
+ #include
+#endif
+
+#define testColor(COLOR) \
+ kprint_setColor(kprint_bgBlack | kprint_fg##COLOR);\
+ kprintf(#COLOR " ");\
+ kprint_setColor(kprint_bg##COLOR | kprint_fgGray);\
+ kprintf(#COLOR);\
+ kprint_setColor(kprint_bgBlack | kprint_fgBlack);\
+ kprintf("\n");
+
+void test_kprint_colors(){
+ /* IFWIN(
+ ({
+ HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+ for(uint8 col=0; col<255; col++){
+ SetConsoleTextAttribute(hConsole, col);
+ kprintf("%u ",col);
+ }
+ }),
+ ({
+ for(uint8 col=0; col<255; col++)
+ kprintf("\e[%um%u ", col, col);
+ })
+ );
+ kprintf("\n"); */
+
+ testColor(Black);
+ testColor(DarkRed);
+ testColor(DarkGreen);
+ testColor(DarkYellow);
+ testColor(DarkBlue);
+ testColor(DarkMagenta);
+ testColor(DarkCyan);
+ testColor(Gray);
+ testColor(DarkGray);
+ testColor(Red);
+ testColor(Green);
+ testColor(Yellow);
+ testColor(Blue);
+ testColor(Magenta);
+ testColor(Cyan);
+ testColor(White);
+ kprint_setColor(kprint_bgBlack | kprint_fgGray);
+
+ kprint(kprint_fmtInt | kprint_fgCyan, 8888, kprint_fmtString | kprint_fgYellow, " ooo ", kprint_fmtFloat | kprint_bgDarkGreen | kprint_fgRed, 4.01, kprint_fmtString | kprint_fgWhite, "\ngg\n");
+}
\ No newline at end of file
diff --git a/tests/test_marshalling.c b/tests/test_marshalling.c
index 3dde3c0..a3646e6 100644
--- a/tests/test_marshalling.c
+++ b/tests/test_marshalling.c
@@ -4,11 +4,11 @@ EXPORT void CALL test_marshalling(char* text, KVPair** kptr){
KVPair* k=malloc(sizeof(KVPair));
k->key="message";
char* tc=cptr_copy(text);
- Unitype u={.VoidPtr=tc, .type=CharPtr};
+ Unitype u=UniHeap(ktId_CharPtr,tc);
k->value=u;
*kptr=k;
}
EXPORT void CALL pinvoke_print(char* msg) {
- printf("printed from unmanaged code: %s\n", msg);
+ kprintf("printed from unmanaged code: %s\n", msg);
}
diff --git a/tests/test_rng_algorithms.c b/tests/test_rng_algorithms.c
new file mode 100644
index 0000000..1af5ef5
--- /dev/null
+++ b/tests/test_rng_algorithms.c
@@ -0,0 +1,45 @@
+#include "tests.h"
+#include "../src/random/krandom.h"
+
+
+#define test_alg(ALG, VALUE_SIZE, EXPECTED_FROM_ZERO){\
+ kprintf("\e[94mrng algorithm: \e[96m" #ALG "\n");\
+ void* s= ALG##_init(0);\
+ uint##VALUE_SIZE r=ALG##_next(s);\
+ kprintf("\e[97m next from zero seed:");\
+ if(r!=EXPECTED_FROM_ZERO){\
+ kprintf("\e[91m " IFWIN("%llu\n","%lu\n"), (uint64)r);\
+ throw(ERR_UNEXPECTEDVAL);\
+ }\
+ kprintf("\e[92m " IFWIN("%llu\n","%lu\n"), (uint64)r);\
+ ALG##_free(s);\
+ s= ALG##_initFromTime();\
+ r=ALG##_next(s);\
+ ALG##_free(s);\
+ kprintf("\e[97m next from time seed:\e[92m " IFWIN("%llu\n","%lu\n"), (uint64)r);\
+}
+
+void test_rng_algorithms(){
+ optime("test_rng_algorithms",1,({
+ kprintf("\e[96m--------[test_rng_algorithms]---------\n");
+ // for ALG32
+ // xoroshiro64
+ test_alg(xoroshiro64star, 32, 932574677ULL)
+ test_alg(xoroshiro64starstar, 32, 3183060286ULL)
+ // xoshiro128
+ test_alg(xoshiro128plus, 32, 3918949401ULL)
+ test_alg(xoshiro128plusplus, 32, 1179900579ULL)
+ test_alg(xoshiro128starstar, 32, 3737715805ULL)
+ // for ALG64
+ // xoroshiro128
+ test_alg(xoroshiro128plus, 64, 4778832803ULL)
+ test_alg(xoroshiro128plusplus, 64, 626373238705583ULL)
+ test_alg(xoroshiro128starstar, 64, 11897572417920ULL)
+ // xoshiro256
+ test_alg(xoshiro256plus, 64, 15757075719729598363ULL)
+ test_alg(xoshiro256plusplus, 64, 5987356902031041503ULL)
+ test_alg(xoshiro256starstar, 64, 11091344671253066420ULL)
+ // splitmix64
+ test_alg(splitmix64, 64, 16294208416658607535ULL)
+ }));
+}
\ No newline at end of file
diff --git a/tests/test_safethrow.c b/tests/test_safethrow.c
index 4ccd4dc..14e4e1e 100644
--- a/tests/test_safethrow.c
+++ b/tests/test_safethrow.c
@@ -1,7 +1,7 @@
#include "tests.h"
Maybe dont_throw(){
- return SUCCESS(Uni(UInt64, 9/2));
+ return SUCCESS(UniUInt64(9/2));
}
Maybe throw_error(){
@@ -14,10 +14,10 @@ Maybe throw_errcode(){
}
Maybe test_maybe(){
- printf("\e[94mdont_throw returns \e[92m");
+ kprintf("\e[94mdont_throw returns \e[92m");
tryLast(dont_throw(),rez0)
printMaybe(rez0);
- printf("\n");
+ kprintf("\n");
try(throw_error(),rez1,;)
printMaybe(rez1);
throw("test_maybe failed");
@@ -29,13 +29,13 @@ Maybe b(){ try(c(),_,;) return MaybeNull; }
Maybe a(){ try(b(),_,;) return MaybeNull; }
void test_safethrow(){
- printf("\e[96m-----------[test_safethrow]-----------\n");
+ kprintf("\e[96m-----------[test_safethrow]-----------\n");
optime("test_safethrow", 1, ({
Maybe e=test_maybe();
- printf("\e[94mthrow_error:\n\e[92m");
+ kprintf("\e[94mthrow_error:\n\e[92m");
printMaybe(e);
Maybe_free(e);
- printf("\e[94mthrow_errcode:\n\e[92m");
+ kprintf("\e[94mthrow_errcode:\n\e[92m");
e=a();
printMaybe(e);
Maybe_free(e);
diff --git a/tests/test_searchtree.c b/tests/test_searchtree.c
index cff22a5..c7312e8 100644
--- a/tests/test_searchtree.c
+++ b/tests/test_searchtree.c
@@ -2,20 +2,21 @@
#include "../src/SearchTree/SearchTree.h"
void printstnode(STNode* node){
- printf("\e[94mSTNode: "
+ kprintf("\e[94mSTNode: "
IFWIN("%llu", "%lu")
"\n address: %p\n value: ",sizeof(STNode),node);
printuni(node->value);
+ kprintf("\n");
// prints pointers to all existing branches
- /* printf("\n branches: %p\n", node->branches);
+ /* kprintf(" branches: %p\n", node->branches);
if(node->branches) for(uint8 i=0;i<8;i++){
- printf(" \e[90m[%u]=%p\n",i,node->branches[i]);
+ kprintf(" \e[90m[%u]=%p\n",i,node->branches[i]);
if(node->branches[i])
for (uint8 ii = 0; ii < 8; ii++){
- printf(" \e[90m[%u]=%p\n",ii,node->branches[i][ii]);
+ kprintf(" \e[90m[%u]=%p\n",ii,node->branches[i][ii]);
if(node->branches[i][ii])
for (uint8 iii = 0; iii < 4; iii++)
- printf(" \e[90m[%u]=%p\n",iii,node->branches[i][ii][iii]);
+ kprintf(" \e[90m[%u]=%p\n",iii,node->branches[i][ii][iii]);
}
} */
@@ -23,51 +24,51 @@ void printstnode(STNode* node){
void test_searchtree(){
optime("test_searchtree",1,({
- printf("\e[96m-----------[test_searchtree]----------\n");
+ kprintf("\e[96m-----------[test_searchtree]----------\n");
STNode* node=STNode_create();
- printf("\e[92mnode created\n");
- printf("push:\e[94m\n ");
- Unitype u={.type=Int64,.Int64=-3};
+ kprintf("\e[92mnode created\n");
+ kprintf("push:\e[94m\n ");
+ Unitype u=UniInt64(-3);
printuni(u);
ST_push(node,"type", u);
- printf(" -> type\n ");
- u=(Unitype){.type=Int64,.Int64=25};
+ kprintf(" -> type\n ");
+ u=UniInt64(25);
printuni(u);
ST_push(node,"time", u);
- printf(" -> time\n ");
- u=(Unitype){.type=Float64,.Float64=-542.00600};
+ kprintf(" -> time\n ");
+ u=UniFloat64(-542.00600);
printuni(u);
ST_push(node,"author_id", u);
- printf(" -> author_id\n ");
- u=(Unitype){.type=Int64,.Int64=-31255};
+ kprintf(" -> author_id\n ");
+ u=UniInt64(-31255);
printuni(u);
ST_push(node,"channel_id", u);
- printf(" -> channel_id\n ");
- u=(Unitype){.type=Float64,.Float64=32.2004};
+ kprintf(" -> channel_id\n ");
+ u=UniHeap(ktId_CharPtr, cptr_copy("32.2004"));
printuni(u);
ST_push(node,"message_id", u);
- printf(" -> message_id\n ");
- u=(Unitype){.type=CharPtr,.VoidPtr=cptr_copy("some text UwU")};
+ kprintf(" -> message_id\n ");
+ u=UniStack(ktId_CharPtr,"some text UwU");
printuni(u);
ST_push(node,"text", u);
- printf(" -> text\n");
- printf("\e[92mpull:\e[94m");
- printf("\n type -> ");
+ kprintf(" -> text\n");
+ kprintf("\e[92mpull:\e[94m");
+ kprintf("\n type -> ");
printuni(ST_pull(node,"type"));
- printf("\n time -> ");
+ kprintf("\n time -> ");
printuni(ST_pull(node,"time"));
- printf("\n author_id -> ");
+ kprintf("\n author_id -> ");
printuni(ST_pull(node,"author_id"));
- printf("\n channel_id -> ");
+ kprintf("\n channel_id -> ");
printuni(ST_pull(node,"channel_id"));
- printf("\n message_id -> ");
+ kprintf("\n message_id -> ");
printuni(ST_pull(node,"message_id"));
- printf("\n text -> ");
+ kprintf("\n text -> ");
printuni(ST_pull(node,"text"));
- printf("\n");
- printf("\e[92mfirst node: ");
+ kprintf("\n");
+ kprintf("\e[92mfirst node: ");
printstnode(node);
STNode_free(node);
- printf("\e[92mnode deleted\n");
+ kprintf("\e[92mnode deleted\n");
}));
}
diff --git a/tests/test_string.c b/tests/test_string.c
index 9a6aac2..ff861f9 100644
--- a/tests/test_string.c
+++ b/tests/test_string.c
@@ -3,12 +3,12 @@
void test_string(){
optime(__func__,1,({
- printf("\e[96m-------------[test_string]------------\n");
+ kprintf("\e[96m-------------[test_string]------------\n");
char c[]="0123456789abcdef";
string s={.ptr=c, .length=cptr_length(c)};
if(s.length!=sizeof(c)-1) throw("string created with incorrect length");
char* p=string_extract(s);
- printf("\e[94mstring_extract() -> \e[92m\"%s\"\n",p);
+ kprintf("\e[94mstring_extract() -> \e[92m\"%s\"\n",p);
free(p);
}));
}
\ No newline at end of file
diff --git a/tests/tests.h b/tests/tests.h
index eb66a8f..8941c61 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -13,10 +13,12 @@ void test_autoarr();
void test_hash_functions();
void test_hashtable();
void test_dtsod();
-void test_network();
+void test_kprint_colors();
+void test_autoarrVsVector();
+void test_rng_algorithms();
-#define PRINT_SIZEOF(T) printf("\e[94m" #T " size: \e[96m" IFWIN("%llu", "%lu") "\n", sizeof(T))
+#define PRINT_SIZEOF(T) kprintf("\e[94m" #T " size: \e[96m" IFWIN("%llu", "%lu") "\n", sizeof(T))
#if __cplusplus
}
-#endif
\ No newline at end of file
+#endif