Merge branch 'main' into 'network'
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -6,7 +6,12 @@ obj/
|
|||||||
.old*/
|
.old*/
|
||||||
.vs/
|
.vs/
|
||||||
.vshistory/
|
.vshistory/
|
||||||
|
tmp/
|
||||||
|
temp/
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
.editorconfig
|
.editorconfig
|
||||||
*.user
|
*.user
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
|
*.log
|
||||||
current.config
|
current.config
|
||||||
|
|||||||
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,3 +1,4 @@
|
|||||||
[submodule "cbuild"]
|
[submodule "cbuild"]
|
||||||
path = cbuild
|
path = cbuild
|
||||||
url = https://github.com/Timerix22/cbuild.git
|
url = https://github.com/Timerix22/cbuild.git
|
||||||
|
branch = main
|
||||||
|
|||||||
10
.vscode/launch.json
vendored
10
.vscode/launch.json
vendored
@@ -5,10 +5,10 @@
|
|||||||
"name": "(gdb) Debug",
|
"name": "(gdb) Debug",
|
||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceFolder}/bin/kerep.com",
|
"program": "${workspaceFolder}/bin/kerep",
|
||||||
|
"cwd": "${workspaceFolder}/bin",
|
||||||
"preLaunchTask": "build_exec_dbg",
|
"preLaunchTask": "build_exec_dbg",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${fileDirname}",
|
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
"miDebuggerPath": "gdb"
|
"miDebuggerPath": "gdb"
|
||||||
@@ -18,9 +18,9 @@
|
|||||||
"type": "cppdbg",
|
"type": "cppdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build_exec_dbg",
|
"preLaunchTask": "build_exec_dbg",
|
||||||
"program": "${workspaceFolder}/bin/kerep.com",
|
"program": "${workspaceFolder}/bin/kerep",
|
||||||
|
"cwd": "${workspaceFolder}/bin",
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"cwd": "${workspaceFolder}",
|
|
||||||
"externalConsole": false,
|
"externalConsole": false,
|
||||||
"miDebuggerPath": "/usr/bin/gdb",
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
"MIMode": "gdb",
|
"MIMode": "gdb",
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
"type": "cppvsdbg",
|
"type": "cppvsdbg",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"preLaunchTask": "build_dbg",
|
"preLaunchTask": "build_dbg",
|
||||||
|
"program": "${workspaceFolder}\\bin\\kerep",
|
||||||
"cwd": "${workspaceFolder}\\bin",
|
"cwd": "${workspaceFolder}\\bin",
|
||||||
"program": "${workspaceFolder}\\bin\\kerep.com",
|
|
||||||
"stopAtEntry": false,
|
"stopAtEntry": false,
|
||||||
"console": "integratedTerminal"
|
"console": "integratedTerminal"
|
||||||
}
|
}
|
||||||
|
|||||||
28
.vscode/tasks.json
vendored
28
.vscode/tasks.json
vendored
@@ -3,32 +3,6 @@
|
|||||||
|
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [
|
"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",
|
"label": "build_exec_dbg",
|
||||||
"detail": "build project with debug symbols",
|
"detail": "build project with debug symbols",
|
||||||
@@ -50,7 +24,7 @@
|
|||||||
"focus": true,
|
"focus": true,
|
||||||
"panel": "shared",
|
"panel": "shared",
|
||||||
"showReuseMessage": false,
|
"showReuseMessage": false,
|
||||||
"clear": true
|
"clean": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
84
Makefile
84
Makefile
@@ -1,25 +1,85 @@
|
|||||||
###### Build cbuild/default_tasks #######
|
######################################
|
||||||
all: build_exec
|
###### Build tasks #######
|
||||||
|
######################################
|
||||||
|
|
||||||
build_exec:
|
all: build_exec_dbg
|
||||||
@cbuild/call_task.sh build_exec
|
|
||||||
|
# creates executable using profiling info generated by profile
|
||||||
|
build_exec: profile
|
||||||
|
@cbuild/call_task.sh build_exec 2>&1 | tee -a make_raw.log
|
||||||
|
|
||||||
|
# creates executable with debug info and no optimizations
|
||||||
build_exec_dbg:
|
build_exec_dbg:
|
||||||
@cbuild/call_task.sh build_exec_dbg
|
@cbuild/call_task.sh build_exec_dbg 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# creates shared library
|
||||||
build_shared_lib:
|
build_shared_lib:
|
||||||
@cbuild/call_task.sh build_shared_lib
|
@cbuild/call_task.sh build_shared_lib 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# creates shared library with debug symbols and no optimizations
|
||||||
build_shared_lib_dbg:
|
build_shared_lib_dbg:
|
||||||
@cbuild/call_task.sh build_shared_lib_dbg
|
@cbuild/call_task.sh build_shared_lib_dbg 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# creates static library
|
||||||
build_static_lib:
|
build_static_lib:
|
||||||
@cbuild/call_task.sh build_static_lib
|
@cbuild/call_task.sh build_static_lib 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# creates static library with debug symbols and no optimizations
|
||||||
build_static_lib_dbg:
|
build_static_lib_dbg:
|
||||||
@cbuild/call_task.sh build_static_lib_dbg
|
@cbuild/call_task.sh build_static_lib_dbg 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
###### Launch cbuild/default_tasks #######
|
######################################
|
||||||
|
###### Launch tasks #######
|
||||||
|
######################################
|
||||||
|
|
||||||
|
# executes $EXEC_FILE
|
||||||
exec: build_exec
|
exec: build_exec
|
||||||
@cbuild/call_task.sh exec
|
@cbuild/call_task.sh exec 2>&1 | tee -a make_raw.log
|
||||||
|
|
||||||
|
# executes $EXEC_FILE
|
||||||
|
exec_dbg: build_exec_dbg
|
||||||
|
@cbuild/call_task.sh exec 2>&1 | tee -a make_raw.log
|
||||||
|
|
||||||
|
# executes $EXEC_FILE with valgrind memory checker
|
||||||
valgrind: build_exec_dbg
|
valgrind: build_exec_dbg
|
||||||
@cbuild/call_task.sh valgrind
|
@cbuild/call_task.sh valgrind 2>&1 | tee -a make_raw.log
|
||||||
|
|
||||||
|
# generates profiling info
|
||||||
|
profile:
|
||||||
|
@cbuild/call_task.sh profile 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# compiles program with -pg and runs it with gprof
|
||||||
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
|
gprof:
|
||||||
|
@cbuild/call_task.sh gprof 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# compiles program and runs it with callgrind (part of valgrind)
|
||||||
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
|
# P.S. detailed rezults can be viewed in KCacheGrind
|
||||||
|
callgrind:
|
||||||
|
@cbuild/call_task.sh callgrind 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# compiles executable with sanitizers and executes it to find errors and warnings
|
||||||
|
sanitize:
|
||||||
|
@cbuild/call_task.sh sanitize 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
######################################
|
||||||
|
###### Other tasks #######
|
||||||
|
######################################
|
||||||
|
|
||||||
|
# deletes generated files
|
||||||
|
clean:
|
||||||
|
@cbuild/call_task.sh clean 2>&1 | tee make_raw.log
|
||||||
|
|
||||||
|
# removes all unreadable characters copied from stdio
|
||||||
|
fix_log:
|
||||||
|
sed 's/[^[:blank:][:print:]]//g' make_raw.log \
|
||||||
|
| sed 's/\[0;[0-9][0-9]m//g' \
|
||||||
|
| sed 's/\[0;[0-9]m//g' \
|
||||||
|
| sed 's/\[[0-9][0-9]m//g' \
|
||||||
|
| sed 's/\[[0-9]m//g' \
|
||||||
|
| sed 's/ H //g' \
|
||||||
|
| sed 's/\[3gH //g' \
|
||||||
|
> make_fixed.log
|
||||||
|
|||||||
2
cbuild
2
cbuild
Submodule cbuild updated: 15a9661c46...60fa8c11c2
165
default.config
165
default.config
@@ -1,81 +1,184 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
CBUILD_VERSION=4
|
CBUILD_VERSION=7
|
||||||
CONFIG_VERSION=5
|
CONFIG_VERSION=7
|
||||||
|
|
||||||
PROJECT=kerep
|
PROJECT="kerep"
|
||||||
CMP_C=gcc
|
CMP_C="gcc"
|
||||||
CMP_CPP=g++
|
CMP_CPP="g++"
|
||||||
STD_C=c11
|
STD_C="c11"
|
||||||
STD_CPP=c++17
|
STD_CPP="c++11"
|
||||||
WARN_C="-Wall -Wno-discarded-qualifiers"
|
WARN_C="-Wall -Wno-discarded-qualifiers -Wextra -Wno-unused-parameter"
|
||||||
WARN_CPP="-Wall"
|
WARN_CPP="-Wall -Wextra -Wno-unused-parameter"
|
||||||
SRC_C="$( find src -name '*.c')"
|
SRC_C="$( find src -name '*.c')"
|
||||||
SRC_CPP="$( find src -name '*.cpp')"
|
SRC_CPP="$( find src -name '*.cpp')"
|
||||||
TESTS_C="$( find tests -name '*.c')"
|
TESTS_C="$( find tests -name '*.c')"
|
||||||
TESTS_CPP="$(find tests -name '*.cpp')"
|
TESTS_CPP="$(find tests -name '*.cpp')"
|
||||||
|
|
||||||
OUTDIR=bin
|
# dir with dependeicy dirs
|
||||||
OBJDIR=obj
|
DEPS_BASEDIR="."
|
||||||
EXEC_FILE=$PROJECT.com
|
# EXAMPLE: "dependency_dir='build_task out_dir lib_file'
|
||||||
SHARED_LIB_FILE=$PROJECT.so
|
# other_depndency_dir=..."
|
||||||
STATIC_LIB_FILE=$PROJECT.a
|
# Dependencies must be declared on separate lines
|
||||||
|
# Values can be override by resetting one of dependencies:
|
||||||
|
# DEPS="$DEPS
|
||||||
|
# dependency_dir='...'"
|
||||||
|
DEPS=""
|
||||||
|
|
||||||
#can be used in tasks
|
# OBJDIR structure:
|
||||||
#PRE_TASK_SCRIPT=
|
# ├── objects/ - dir where compiled *.o files are stored. cleans every call of build task
|
||||||
#POST_TASK_SCRIPT=
|
# ├── profile/ - dir where gcc *.gcda profiling info files stored
|
||||||
|
# └── libs/ - there you can put static libs and linker will find them
|
||||||
|
OBJDIR="obj"
|
||||||
|
OUTDIR="bin"
|
||||||
|
STATIC_LIB_FILE="lib$PROJECT.a"
|
||||||
|
|
||||||
case $TASK in
|
# TASKS
|
||||||
|
case "$TASK" in
|
||||||
|
# creates executable using profiling info if it exists
|
||||||
build_exec)
|
build_exec)
|
||||||
C_ARGS="-O2"
|
# -flto applies more optimizations across object files
|
||||||
|
# -flto=auto is needed to multithreaded copilation
|
||||||
|
# -fuse-linker-plugin is required to use static libs with lto
|
||||||
|
# -fprofile-use enables compiler to use profiling info files to optimize executable
|
||||||
|
# -fprofile-prefix-path sets path where profiling info about objects are be saved
|
||||||
|
# -fdata-sections -ffunction-sections -Wl,--gc-sections removes unused code
|
||||||
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects -fdata-sections -ffunction-sections -Wl,--gc-sections"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS=""
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# creates executable with debug info and no optimizations
|
||||||
build_exec_dbg)
|
build_exec_dbg)
|
||||||
C_ARGS="-O0 -g"
|
C_ARGS="-O0 -g3"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS=""
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# creates shared library
|
||||||
build_shared_lib)
|
build_shared_lib)
|
||||||
C_ARGS="-O2 -fpic -flto -shared"
|
C_ARGS="-O2 -fpic -flto -shared"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
|
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# creates shared library with debug symbols and no optimizations
|
||||||
build_shared_lib_dbg)
|
build_shared_lib_dbg)
|
||||||
C_ARGS="-O0 -g -fpic -shared"
|
C_ARGS="-O0 -g3 -fpic -shared"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
|
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# creates static library
|
||||||
build_static_lib)
|
build_static_lib)
|
||||||
C_ARGS="-O2 -fpic"
|
C_ARGS="-O2 -fpic -fdata-sections -ffunction-sections"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# creates static library with debug symbols and no optimizations
|
||||||
build_static_lib_dbg)
|
build_static_lib_dbg)
|
||||||
C_ARGS="-O0 -g"
|
C_ARGS="-O0 -g3"
|
||||||
CPP_ARGS="$C_ARGS"
|
CPP_ARGS="$C_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=
|
||||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
;;
|
;;
|
||||||
|
# executes $EXEC_FILE
|
||||||
exec)
|
exec)
|
||||||
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
||||||
;;
|
;;
|
||||||
|
# executes $EXEC_FILE with valgrind memory checker
|
||||||
valgrind)
|
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"
|
VALGRIND_ARGS="-s --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
|
||||||
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
|
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
|
||||||
;;
|
;;
|
||||||
|
# generates profiling info
|
||||||
|
profile)
|
||||||
|
OUTDIR="$OUTDIR/profile"
|
||||||
|
# -flto applies more optimizations across object files
|
||||||
|
# -flto=auto is needed to multithreaded copilation
|
||||||
|
# -fuse-linker-plugin is required to use static libs with lto
|
||||||
|
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||||
|
# -fprofile-generate generates executable with profiling code
|
||||||
|
# -fprofile-prefix-path sets path where profiling info about objects will be saved
|
||||||
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
|
||||||
|
CPP_ARGS="$C_ARGS"
|
||||||
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
TASK_SCRIPT=cbuild/default_tasks/profile.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
|
;;
|
||||||
|
# compiles program with -pg and runs it with gprof
|
||||||
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
|
gprof)
|
||||||
|
OUTDIR="$OUTDIR/gprof"
|
||||||
|
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||||
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
|
||||||
|
CPP_ARGS="$C_ARGS"
|
||||||
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
TASK_SCRIPT=cbuild/default_tasks/gprof.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
|
;;
|
||||||
|
# compiles program and runs it with callgrind (part of valgrind)
|
||||||
|
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
|
||||||
|
# requires graphviz (https://www.graphviz.org/download/source/)
|
||||||
|
# P.S. detailed rezults can be viewed in KCacheGrind
|
||||||
|
callgrind)
|
||||||
|
OUTDIR="$OUTDIR/callgrind"
|
||||||
|
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||||
|
C_ARGS="-O2 -flto=auto -fuse-linker-plugin"
|
||||||
|
CPP_ARGS="$C_ARGS"
|
||||||
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=tasks/pre_build.sh
|
||||||
|
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
POST_TASK_SCRIPT=cbuild/default_tasks/callgrind.sh
|
||||||
|
;;
|
||||||
|
# compiles executable with sanitizers and executes it to find errors and warnings
|
||||||
|
sanitize)
|
||||||
|
OUTDIR="$OUTDIR/sanitize"
|
||||||
|
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
|
||||||
|
CPP_ARGS="$C_ARGS"
|
||||||
|
LINKER_ARGS="$CPP_ARGS"
|
||||||
|
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||||
|
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
||||||
|
POST_TASK_SCRIPT=
|
||||||
|
;;
|
||||||
|
# deletes generated files
|
||||||
|
clean)
|
||||||
|
TASK_SCRIPT=cbuild/default_tasks/clean.sh
|
||||||
|
;;
|
||||||
|
# nothing to do
|
||||||
|
no_task)
|
||||||
|
;;
|
||||||
|
# unknown task
|
||||||
|
*)
|
||||||
|
error "task <$TASK> not found"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case $OS in
|
# OS-specific options
|
||||||
|
case "$OS" in
|
||||||
WINDOWS)
|
WINDOWS)
|
||||||
|
EXEC_FILE="$PROJECT.exe"
|
||||||
|
SHARED_LIB_FILE="$PROJECT.dll"
|
||||||
LINKER_ARGS="$LINKER_ARGS -lws2_32"
|
LINKER_ARGS="$LINKER_ARGS -lws2_32"
|
||||||
;;
|
;;
|
||||||
LINUX)
|
LINUX)
|
||||||
|
EXEC_FILE="$PROJECT"
|
||||||
|
SHARED_LIB_FILE="$PROJECT.so"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
printf "${RED}operating system $OS has no configuration variants\n"
|
error "operating system $OS has no configuration variants"
|
||||||
exit 1
|
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -19,46 +19,88 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="src\Array\Array.c" />
|
||||||
<ClCompile Include="src\Autoarr\Autoarr.c" />
|
<ClCompile Include="src\Autoarr\Autoarr.c" />
|
||||||
<ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" />
|
<ClCompile Include="src\Autoarr\Autoarr_KVPair_exported.c" />
|
||||||
|
<ClCompile Include="src\Autoarr\Autoarr_Unitype.c" />
|
||||||
<ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" />
|
<ClCompile Include="src\Autoarr\Autoarr_Unitype_exported.c" />
|
||||||
<ClCompile Include="src\base\cptr.c" />
|
<ClCompile Include="src\base\cptr.c" />
|
||||||
|
<ClCompile Include="src\base\endian.c" />
|
||||||
<ClCompile Include="src\base\errors.c" />
|
<ClCompile Include="src\base\errors.c" />
|
||||||
<ClCompile Include="src\base\types.c" />
|
<ClCompile Include="src\base\type_system\base_toString.c" />
|
||||||
|
<ClCompile Include="src\base\type_system\init.c" />
|
||||||
|
<ClCompile Include="src\base\type_system\kt_functions.c" />
|
||||||
|
<ClCompile Include="src\base\type_system\unitype.c" />
|
||||||
<ClCompile Include="src\DtsodParser\DtsodV24.c" />
|
<ClCompile Include="src\DtsodParser\DtsodV24.c" />
|
||||||
<ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" />
|
<ClCompile Include="src\DtsodParser\DtsodV24_deserialize.c" />
|
||||||
<ClCompile Include="src\DtsodParser\DtsodV24_exported.c" />
|
<ClCompile Include="src\DtsodParser\DtsodV24_exported.c" />
|
||||||
<ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" />
|
<ClCompile Include="src\DtsodParser\DtsodV24_serialize.c" />
|
||||||
|
<ClCompile Include="src\Filesystem\dir.c" />
|
||||||
|
<ClCompile Include="src\Filesystem\file.c" />
|
||||||
|
<ClCompile Include="src\Filesystem\path.c" />
|
||||||
<ClCompile Include="src\HashFunctions\hash.c" />
|
<ClCompile Include="src\HashFunctions\hash.c" />
|
||||||
<ClCompile Include="src\Hashtable\Hashtable.c" />
|
<ClCompile Include="src\Hashtable\Hashtable.c" />
|
||||||
<ClCompile Include="src\Hashtable\KeyValuePair.c" />
|
<ClCompile Include="src\Hashtable\KeyValuePair.c" />
|
||||||
|
<ClCompile Include="src\kprint\kprint.c" />
|
||||||
|
<ClCompile Include="src\kprint\kprintf.c" />
|
||||||
|
<ClCompile Include="src\random\splitmix64\splitmix64.c" />
|
||||||
|
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64star.c" />
|
||||||
|
<ClCompile Include="src\random\xoroshiro\32bitValue\xoroshiro64starstar.c" />
|
||||||
|
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plus.c" />
|
||||||
|
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128plusplus.c" />
|
||||||
|
<ClCompile Include="src\random\xoroshiro\64bitValue\xoroshiro128starstar.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plus.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128plusplus.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\32bitValue\xoshiro128starstar.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plus.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256plusplus.c" />
|
||||||
|
<ClCompile Include="src\random\xoshiro\64bitValue\xoshiro256starstar.c" />
|
||||||
<ClCompile Include="src\SearchTree\SearchTree.c" />
|
<ClCompile Include="src\SearchTree\SearchTree.c" />
|
||||||
<ClCompile Include="src\String\string.c" />
|
<ClCompile Include="src\String\string.c" />
|
||||||
<ClCompile Include="src\String\StringBuilder.c" />
|
<ClCompile Include="src\String\StringBuilder.c" />
|
||||||
<ClCompile Include="tests\main.cpp" />
|
|
||||||
<ClCompile Include="tests\test_autoarr.c" />
|
|
||||||
<ClCompile Include="tests\test_dtsod.c" />
|
|
||||||
<ClCompile Include="tests\test_hashtable.c" />
|
|
||||||
<ClCompile Include="tests\test_hash_functions.c" />
|
|
||||||
<ClCompile Include="tests\test_marshalling.c" />
|
<ClCompile Include="tests\test_marshalling.c" />
|
||||||
<ClCompile Include="tests\test_safethrow.c" />
|
|
||||||
<ClCompile Include="tests\test_searchtree.c" />
|
|
||||||
<ClCompile Include="tests\test_string.c" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\Array\Array.h" />
|
||||||
|
<ClInclude Include="src\Array\Array_declare.h" />
|
||||||
|
<ClInclude Include="src\Array\Array_define.h" />
|
||||||
<ClInclude Include="src\Autoarr\Autoarr.h" />
|
<ClInclude Include="src\Autoarr\Autoarr.h" />
|
||||||
<ClInclude Include="src\Autoarr\Autoarr_declare.h" />
|
<ClInclude Include="src\Autoarr\Autoarr_declare.h" />
|
||||||
<ClInclude Include="src\Autoarr\Autoarr_define.h" />
|
<ClInclude Include="src\Autoarr\Autoarr_define.h" />
|
||||||
|
<ClInclude Include="src\Autoarr\Autoarr_Unitype.h" />
|
||||||
<ClInclude Include="src\base\base.h" />
|
<ClInclude Include="src\base\base.h" />
|
||||||
<ClInclude Include="src\base\cptr.h" />
|
<ClInclude Include="src\base\cptr.h" />
|
||||||
|
<ClInclude Include="src\base\endian.h" />
|
||||||
<ClInclude Include="src\base\errors.h" />
|
<ClInclude Include="src\base\errors.h" />
|
||||||
<ClInclude Include="src\base\optime.h" />
|
<ClInclude Include="src\base\optime.h" />
|
||||||
<ClInclude Include="src\base\std.h" />
|
<ClInclude Include="src\base\std.h" />
|
||||||
<ClInclude Include="src\base\types.h" />
|
<ClInclude Include="src\base\type_system\base_toString.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\init.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\ktDescriptor.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\ktid.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\kt_functions.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\type_system.h" />
|
||||||
|
<ClInclude Include="src\base\type_system\unitype.h" />
|
||||||
<ClInclude Include="src\DtsodParser\DtsodV24.h" />
|
<ClInclude Include="src\DtsodParser\DtsodV24.h" />
|
||||||
|
<ClInclude Include="src\Filesystem\dir.h" />
|
||||||
|
<ClInclude Include="src\Filesystem\file.h" />
|
||||||
|
<ClInclude Include="src\Filesystem\filesystem.h" />
|
||||||
|
<ClInclude Include="src\Filesystem\path.h" />
|
||||||
<ClInclude Include="src\HashFunctions\hash.h" />
|
<ClInclude Include="src\HashFunctions\hash.h" />
|
||||||
<ClInclude Include="src\Hashtable\Hashtable.h" />
|
<ClInclude Include="src\Hashtable\Hashtable.h" />
|
||||||
<ClInclude Include="src\Hashtable\KeyValuePair.h" />
|
<ClInclude Include="src\Hashtable\KeyValuePair.h" />
|
||||||
|
<ClInclude Include="src\kprint\kprint.h" />
|
||||||
|
<ClInclude Include="src\kprint\kprintf.h" />
|
||||||
|
<ClInclude Include="src\kprint\kprint_colors.h" />
|
||||||
|
<ClInclude Include="src\kprint\kprint_format.h" />
|
||||||
|
<ClInclude Include="src\random\krandom.h" />
|
||||||
|
<ClInclude Include="src\random\splitmix64\splitmix64.h" />
|
||||||
|
<ClInclude Include="src\random\xoroshiro\32bitValue\xoroshiro64.h" />
|
||||||
|
<ClInclude Include="src\random\xoroshiro\64bitValue\xoroshiro128.h" />
|
||||||
|
<ClInclude Include="src\random\xoroshiro\xoroshiro.h" />
|
||||||
|
<ClInclude Include="src\random\xoshiro\32bitValue\xoshiro128.h" />
|
||||||
|
<ClInclude Include="src\random\xoshiro\64bitValue\xoshiro256.h" />
|
||||||
|
<ClInclude Include="src\random\xoshiro\xoshiro.h" />
|
||||||
<ClInclude Include="src\SearchTree\SearchTree.h" />
|
<ClInclude Include="src\SearchTree\SearchTree.h" />
|
||||||
<ClInclude Include="src\String\string.h" />
|
<ClInclude Include="src\String\string.h" />
|
||||||
<ClInclude Include="src\String\StringBuilder.h" />
|
<ClInclude Include="src\String\StringBuilder.h" />
|
||||||
@@ -156,7 +198,7 @@
|
|||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<PrecompiledHeaderOutputFile />
|
<PrecompiledHeaderOutputFile />
|
||||||
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
<DebugInformationFormat>None</DebugInformationFormat>
|
||||||
@@ -182,7 +224,7 @@
|
|||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<PrecompiledHeaderOutputFile />
|
<PrecompiledHeaderOutputFile />
|
||||||
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
@@ -208,7 +250,7 @@
|
|||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<PrecompiledHeaderOutputFile />
|
<PrecompiledHeaderOutputFile />
|
||||||
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
<DebugInformationFormat>None</DebugInformationFormat>
|
||||||
@@ -235,7 +277,7 @@
|
|||||||
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
<LanguageStandard_C>stdc17</LanguageStandard_C>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<PrecompiledHeaderOutputFile />
|
<PrecompiledHeaderOutputFile />
|
||||||
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:twoPhase- /MP -fms-compatibility-version=14 -Wno-clang-analyzer-valist.Uninitialized %(AdditionalOptions)</AdditionalOptions>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
|||||||
@@ -2,15 +2,26 @@
|
|||||||
|
|
||||||
Array_define(char)
|
Array_define(char)
|
||||||
Array_define(bool)
|
Array_define(bool)
|
||||||
Array_define(float32)
|
Array_define(f32)
|
||||||
Array_define(float64)
|
Array_define(f64)
|
||||||
Array_define(int8)
|
Array_define(i8)
|
||||||
Array_define(uint8)
|
Array_define(u8)
|
||||||
Array_define(int16)
|
Array_define(i16)
|
||||||
Array_define(uint16)
|
Array_define(u16)
|
||||||
Array_define(int32)
|
Array_define(i32)
|
||||||
Array_define(uint32)
|
Array_define(u32)
|
||||||
Array_define(int64)
|
Array_define(i64)
|
||||||
Array_define(uint64)
|
Array_define(u64)
|
||||||
|
Array_define(Pointer)
|
||||||
|
|
||||||
Array_define(Unitype)
|
Array_define(Unitype)
|
||||||
|
|
||||||
|
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers){
|
||||||
|
if(freeMembers) for (u32 i=0; i<array->length; i++)
|
||||||
|
Unitype_free(array->values[i]);
|
||||||
|
if(array->allocatedOnHeap)
|
||||||
|
free(array->values);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __Array_Unitype_free_(void* ar)
|
||||||
|
{ Array_Unitype_free_(ar, true); }
|
||||||
|
|||||||
@@ -9,19 +9,24 @@ extern "C" {
|
|||||||
|
|
||||||
Array_declare(char)
|
Array_declare(char)
|
||||||
Array_declare(bool)
|
Array_declare(bool)
|
||||||
Array_declare(float32)
|
Array_declare(f32)
|
||||||
Array_declare(float64)
|
Array_declare(f64)
|
||||||
Array_declare(int8)
|
Array_declare(i8)
|
||||||
Array_declare(uint8)
|
Array_declare(u8)
|
||||||
Array_declare(int16)
|
Array_declare(i16)
|
||||||
Array_declare(uint16)
|
Array_declare(u16)
|
||||||
Array_declare(int32)
|
Array_declare(i32)
|
||||||
Array_declare(uint32)
|
Array_declare(u32)
|
||||||
Array_declare(int64)
|
Array_declare(i64)
|
||||||
Array_declare(uint64)
|
Array_declare(u64)
|
||||||
|
Array_declare(Pointer)
|
||||||
|
|
||||||
Array_declare(Unitype)
|
Array_declare(Unitype)
|
||||||
|
|
||||||
|
/// use this function instead of auto generated
|
||||||
|
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers);
|
||||||
|
void __Array_Unitype_free_(void* ar);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -6,34 +6,32 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
|
||||||
#define Array_declare(type)\
|
#define Array_declare(type) \
|
||||||
typedef struct Array_##type{\
|
STRUCT(Array_##type, \
|
||||||
type* values;\
|
type* values; \
|
||||||
uint32 length;\
|
u32 length; \
|
||||||
bool allocatedOnHeap;\
|
bool allocatedOnHeap; \
|
||||||
} Array_##type;\
|
) \
|
||||||
\
|
\
|
||||||
ktid_declare(Array_##type);\
|
static inline Array_##type Array_##type##_allocValues(u32 length){ \
|
||||||
|
return (Array_##type) { \
|
||||||
|
.values=(type*)malloc(sizeof(type)*length), \
|
||||||
|
.length=length, \
|
||||||
|
.allocatedOnHeap=true \
|
||||||
|
}; \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
static inline Array_##type Array_##type##_allocValues(uint32 length){\
|
static inline Array_##type Array_##type##_fromBuffer(type* buffer, u32 bufferLength, bool allocatedOnHeap){ \
|
||||||
return (Array_##type) {\
|
return (Array_##type) { \
|
||||||
.values=(type*)malloc(sizeof(type)*length),\
|
.values=buffer, \
|
||||||
.length=length,\
|
.length=bufferLength, \
|
||||||
.allocatedOnHeap=true\
|
.allocatedOnHeap=allocatedOnHeap \
|
||||||
};\
|
}; \
|
||||||
}\
|
} \
|
||||||
\
|
\
|
||||||
static inline Array_##type Array_##type##_fromBuffer(type* buffer, uint32 bufferLength, bool allocatedOnHeap){\
|
static inline void Array_##type##_free(Array_##type* array){ \
|
||||||
return (Array_##type) {\
|
if(array->allocatedOnHeap) \
|
||||||
.values=buffer,\
|
free(array->values); \
|
||||||
.length=bufferLength,\
|
|
||||||
.allocatedOnHeap=allocatedOnHeap\
|
|
||||||
};\
|
|
||||||
}\
|
|
||||||
\
|
|
||||||
static inline void Array_##type##_freeValues(Array_##type* array){\
|
|
||||||
if(array->allocatedOnHeap)\
|
|
||||||
free(array->values);\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
|
||||||
#define Array_define(type)\
|
#define Array_define(type) \
|
||||||
ktid_define(Array_##type);
|
kt_define(Array_##type, (freeMembers_t)Array_##type##_free, NULL);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,17 @@
|
|||||||
#include "Autoarr.h"
|
#include "Autoarr.h"
|
||||||
|
|
||||||
Autoarr_define(char)
|
Autoarr_define(Pointer, true)
|
||||||
Autoarr_define(bool)
|
Autoarr_define(char, false)
|
||||||
Autoarr_define(float32)
|
Autoarr_define(bool, false)
|
||||||
Autoarr_define(float64)
|
Autoarr_define(f32, false)
|
||||||
Autoarr_define(uint8)
|
Autoarr_define(f64, false)
|
||||||
Autoarr_define(int8)
|
Autoarr_define(u8, false)
|
||||||
Autoarr_define(uint16)
|
Autoarr_define(i8, false)
|
||||||
Autoarr_define(int16)
|
Autoarr_define(u16, false)
|
||||||
Autoarr_define(uint32)
|
Autoarr_define(i16, false)
|
||||||
Autoarr_define(int32)
|
Autoarr_define(u32, false)
|
||||||
Autoarr_define(uint64)
|
Autoarr_define(i32, false)
|
||||||
Autoarr_define(int64)
|
Autoarr_define(u64, false)
|
||||||
|
Autoarr_define(i64, false)
|
||||||
|
|
||||||
|
Autoarr_define(Unitype, false)
|
||||||
|
|||||||
@@ -6,21 +6,37 @@ extern "C" {
|
|||||||
|
|
||||||
#include "Autoarr_declare.h"
|
#include "Autoarr_declare.h"
|
||||||
#include "Autoarr_define.h"
|
#include "Autoarr_define.h"
|
||||||
#include "Autoarr_Unitype.h"
|
|
||||||
|
|
||||||
|
Autoarr_declare(Pointer)
|
||||||
Autoarr_declare(char)
|
Autoarr_declare(char)
|
||||||
Autoarr_declare(bool)
|
Autoarr_declare(bool)
|
||||||
Autoarr_declare(float32)
|
Autoarr_declare(f32)
|
||||||
Autoarr_declare(float64)
|
Autoarr_declare(f64)
|
||||||
Autoarr_declare(int8)
|
Autoarr_declare(i8)
|
||||||
Autoarr_declare(uint8)
|
Autoarr_declare(u8)
|
||||||
Autoarr_declare(int16)
|
Autoarr_declare(i16)
|
||||||
Autoarr_declare(uint16)
|
Autoarr_declare(u16)
|
||||||
Autoarr_declare(int32)
|
Autoarr_declare(i32)
|
||||||
Autoarr_declare(uint32)
|
Autoarr_declare(u32)
|
||||||
Autoarr_declare(int64)
|
Autoarr_declare(i64)
|
||||||
Autoarr_declare(uint64)
|
Autoarr_declare(u64)
|
||||||
|
|
||||||
|
Autoarr_declare(Unitype)
|
||||||
|
|
||||||
|
#define Autoarr_foreach(ar, elem, codeblock...) { \
|
||||||
|
if(ar->blocks_count>0) { \
|
||||||
|
typeof(**ar->values) elem; \
|
||||||
|
for(u16 blockI=0;blockI<ar->blocks_count-1;blockI++) \
|
||||||
|
for(u32 elemI=0;elemI<ar->max_block_length;elemI++){ \
|
||||||
|
elem=ar->values[blockI][elemI]; \
|
||||||
|
{ codeblock; } \
|
||||||
|
} \
|
||||||
|
for(u16 elemI=0;elemI<ar->block_length;elemI++){ \
|
||||||
|
elem=ar->values[ar->blocks_count-1][elemI]; \
|
||||||
|
{ codeblock; } \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ extern "C" {
|
|||||||
#include "Autoarr.h"
|
#include "Autoarr.h"
|
||||||
#include "../Hashtable/KeyValuePair.h"
|
#include "../Hashtable/KeyValuePair.h"
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_create(uint16 max_blocks_count, uint16 max_block_length, Autoarr_KVPair** output){
|
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_blocks_count, u16 max_block_length, Autoarr_KVPair** output){
|
||||||
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
|
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
|
|||||||
Autoarr_free(ar, true);
|
Autoarr_free(ar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, uint32 index, KVPair* output){
|
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, u32 index, KVPair* output){
|
||||||
*output=Autoarr_get(ar, index);
|
*output=Autoarr_get(ar, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,15 +21,15 @@ EXPORT void CALL kerep_Autoarr_KVPair_add(Autoarr_KVPair* ar, KVPair element){
|
|||||||
Autoarr_add(ar, element);
|
Autoarr_add(ar, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, uint32 index, KVPair element){
|
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, u32 index, KVPair element){
|
||||||
Autoarr_set(ar, index, element);
|
Autoarr_set(ar, index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, uint32* output){
|
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, u32* output){
|
||||||
*output=Autoarr_length(ar);
|
*output=Autoarr_length(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, uint32* output){
|
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, u32* output){
|
||||||
*output=Autoarr_max_length(ar);
|
*output=Autoarr_max_length(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
#include "Autoarr.h"
|
|
||||||
|
|
||||||
Autoarr_define(Unitype);
|
|
||||||
|
|
||||||
// right func to clear array of unitype values
|
|
||||||
void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr){
|
|
||||||
Autoarr_foreach(ar, u,Unitype_free(u));
|
|
||||||
__Autoarr_free_Unitype(ar, freePtr);
|
|
||||||
}
|
|
||||||
void ____Autoarr_free_Unitype_(void* ar) {
|
|
||||||
__Autoarr_free_Unitype_((Autoarr(Unitype)*)ar, false);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#if __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "Autoarr_declare.h"
|
|
||||||
#include "Autoarr_define.h"
|
|
||||||
|
|
||||||
Autoarr_declare(Unitype)
|
|
||||||
|
|
||||||
// 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) {\
|
|
||||||
typeof(**ar->values) elem;\
|
|
||||||
for(uint32 blockI=0;blockI<ar->blocks_count-1;blockI++)\
|
|
||||||
for(uint32 elemI=0;elemI<ar->max_block_length;elemI++){\
|
|
||||||
elem=ar->values[blockI][elemI];\
|
|
||||||
(codeblock);\
|
|
||||||
}\
|
|
||||||
for(uint32 elemI=0;elemI<ar->block_length;elemI++){\
|
|
||||||
elem=ar->values[ar->blocks_count-1][elemI];\
|
|
||||||
(codeblock);\
|
|
||||||
}\
|
|
||||||
}\
|
|
||||||
})
|
|
||||||
|
|
||||||
#if __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -4,7 +4,7 @@ extern "C" {
|
|||||||
|
|
||||||
#include "Autoarr.h"
|
#include "Autoarr.h"
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_create(uint16 max_blocks_count, uint16 max_block_length, Autoarr_Unitype** output){
|
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_blocks_count, u16 max_block_length, Autoarr_Unitype** output){
|
||||||
*output=Autoarr_create(Unitype, max_blocks_count, max_block_length);
|
*output=Autoarr_create(Unitype, max_blocks_count, max_block_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
|
|||||||
Autoarr_free(ar, true);
|
Autoarr_free(ar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, uint32 index, Unitype* output){
|
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){
|
||||||
*output=Autoarr_get(ar, index);
|
*output=Autoarr_get(ar, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,15 +20,15 @@ EXPORT void CALL kerep_Autoarr_Unitype_add(Autoarr_Unitype* ar, Unitype element)
|
|||||||
Autoarr_add(ar, element);
|
Autoarr_add(ar, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_set(Autoarr_Unitype* ar, uint32 index, Unitype element){
|
EXPORT void CALL kerep_Autoarr_Unitype_set(Autoarr_Unitype* ar, u32 index, Unitype element){
|
||||||
Autoarr_set(ar, index, element);
|
Autoarr_set(ar, index, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_length(Autoarr_Unitype* ar, uint32* output){
|
EXPORT void CALL kerep_Autoarr_Unitype_length(Autoarr_Unitype* ar, u32* output){
|
||||||
*output=Autoarr_length(ar);
|
*output=Autoarr_length(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, uint32* output){
|
EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, u32* output){
|
||||||
*output=Autoarr_max_length(ar);
|
*output=Autoarr_max_length(ar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,64 +6,67 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
|
||||||
#define Autoarr_declare(type)\
|
#define Autoarr_declare(type) \
|
||||||
\
|
\
|
||||||
struct Autoarr_##type;\
|
struct Autoarr_##type; \
|
||||||
\
|
\
|
||||||
typedef struct {\
|
typedef struct __Autoarr_##type##_functions_list_t { \
|
||||||
void (*add)(struct Autoarr_##type* ar, type element);\
|
void (*add)(struct Autoarr_##type* ar, type element); \
|
||||||
type (*get)(struct Autoarr_##type* ar, uint32 index);\
|
type (*get)(struct Autoarr_##type* ar, u32 index); \
|
||||||
type* (*getptr)(struct Autoarr_##type* ar, uint32 index);\
|
type* (*getPtr)(struct Autoarr_##type* ar, u32 index); \
|
||||||
void (*set)(struct Autoarr_##type* ar, uint32 index, type element);\
|
void (*set)(struct Autoarr_##type* ar, u32 index, type element); \
|
||||||
void (*freear)(struct Autoarr_##type* ar, bool freePtr);\
|
void (*freeWithMembers)(struct Autoarr_##type* ar, bool freePtr); \
|
||||||
type* (*toArray)(struct Autoarr_##type* ar);\
|
void (*freeWithoutMembers)(struct Autoarr_##type* ar, bool freePtr); \
|
||||||
} __functions_list_t_##type;\
|
type* (*toArray)(struct Autoarr_##type* ar); \
|
||||||
|
} __Autoarr_##type##_functions_list_t; \
|
||||||
\
|
\
|
||||||
typedef struct Autoarr_##type{\
|
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
|
||||||
uint16 blocks_count;\
|
|
||||||
uint16 max_blocks_count;\
|
|
||||||
uint16 block_length;\
|
|
||||||
uint16 max_block_length;\
|
|
||||||
type** values;\
|
|
||||||
__functions_list_t_##type* functions;\
|
|
||||||
} Autoarr_##type;\
|
|
||||||
\
|
\
|
||||||
ktid_declare(Autoarr_##type);\
|
STRUCT(Autoarr_##type, \
|
||||||
|
u16 blocks_count; \
|
||||||
|
u16 max_blocks_count; \
|
||||||
|
u16 block_length; \
|
||||||
|
u16 max_block_length; \
|
||||||
|
type** values; \
|
||||||
|
__Autoarr_##type##_functions_list_t* functions; \
|
||||||
|
) \
|
||||||
\
|
\
|
||||||
Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length);\
|
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \
|
||||||
void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr);\
|
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \
|
||||||
void ____Autoarr_free_##type(void* ar);
|
void ____Autoarr_##type##_freeWithMembers(void* ar);
|
||||||
|
|
||||||
#define Autoarr(type) Autoarr_##type
|
#define Autoarr(type) Autoarr_##type
|
||||||
|
|
||||||
#define Autoarr_create(type, max_blocks_count, max_block_length)\
|
#define Autoarr_create(type, max_blocks_count, max_block_length) \
|
||||||
__Autoarr_create_##type(max_blocks_count, max_block_length)
|
__Autoarr_##type##_create(max_blocks_count, max_block_length)
|
||||||
#define Autoarr_add(autoarr, element)\
|
#define Autoarr_add(autoarr, element) \
|
||||||
autoarr->functions->add(autoarr, element)
|
autoarr->functions->add(autoarr, element)
|
||||||
#define Autoarr_get(autoarr, index)\
|
#define Autoarr_get(autoarr, index) \
|
||||||
autoarr->functions->get(autoarr,index)
|
autoarr->functions->get(autoarr,index)
|
||||||
#define Autoarr_getptr(autoarr, index)\
|
#define Autoarr_getPtr(autoarr, index) \
|
||||||
autoarr->functions->getptr(autoarr,index)
|
autoarr->functions->getPtr(autoarr,index)
|
||||||
#define Autoarr_set(autoarr, index, element)\
|
#define Autoarr_set(autoarr, index, element) \
|
||||||
autoarr->functions->set(autoarr, index, element)
|
autoarr->functions->set(autoarr, index, element)
|
||||||
#define Autoarr_free(autoarr, freePtr)\
|
#define Autoarr_free(autoarr, freePtr) \
|
||||||
autoarr->functions->freear(autoarr, freePtr)
|
autoarr->functions->freeWithMembers(autoarr, freePtr)
|
||||||
#define Autoarr_toArray(autoarr)\
|
#define Autoarr_freeWithoutMembers(autoarr, freePtr) \
|
||||||
|
autoarr->functions->freeWithoutMembers(autoarr, freePtr)
|
||||||
|
#define Autoarr_toArray(autoarr) \
|
||||||
autoarr->functions->toArray(autoarr)
|
autoarr->functions->toArray(autoarr)
|
||||||
|
|
||||||
#define Autoarr_length(autoarr) \
|
#define Autoarr_length(autoarr) \
|
||||||
(uint32)(!autoarr->blocks_count ? 0 : \
|
(u32)(!autoarr->blocks_count ? 0 : \
|
||||||
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
|
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
|
||||||
#define Autoarr_max_length(autoarr)\
|
#define Autoarr_max_length(autoarr) \
|
||||||
(uint32)(autoarr->max_block_length*autoarr->max_blocks_count)
|
(u32)(autoarr->max_block_length*autoarr->max_blocks_count)
|
||||||
|
|
||||||
#define Autoarr_pop(AR){\
|
#define Autoarr_pop(AR){ \
|
||||||
if(AR->block_length==1){\
|
if(AR->block_length==1){ \
|
||||||
AR->blocks_count--;\
|
AR->blocks_count--; \
|
||||||
AR->block_length=AR->max_block_length;\
|
AR->block_length=AR->max_block_length; \
|
||||||
free(AR->values[AR->blocks_count]);\
|
free(AR->values[AR->blocks_count]); \
|
||||||
}\
|
} \
|
||||||
else AR->block_length--;\
|
else AR->block_length--; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -6,79 +6,93 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
|
||||||
#define Autoarr_define(type)\
|
#define Autoarr_define(type, TYPE_IS_PTR) \
|
||||||
\
|
\
|
||||||
ktid_define(Autoarr_##type);\
|
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
|
||||||
\
|
\
|
||||||
void __Autoarr_add_##type(Autoarr_##type* ar, type element){\
|
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
|
||||||
if(!ar->values){\
|
if(!ar->values){ \
|
||||||
ar->values=malloc(ar->max_blocks_count*sizeof(type*));\
|
ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \
|
||||||
goto create_block;\
|
goto create_block; \
|
||||||
}\
|
} \
|
||||||
if(ar->block_length==ar->max_block_length){\
|
if(ar->block_length==ar->max_block_length){ \
|
||||||
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH);\
|
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH); \
|
||||||
ar->block_length=0;\
|
ar->block_length=0; \
|
||||||
create_block:\
|
create_block: \
|
||||||
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type));\
|
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type)); \
|
||||||
ar->blocks_count++;\
|
ar->blocks_count++; \
|
||||||
}\
|
} \
|
||||||
ar->values[ar->blocks_count-1][ar->block_length]=element;\
|
ar->values[ar->blocks_count-1][ar->block_length]=element; \
|
||||||
ar->block_length++;\
|
ar->block_length++; \
|
||||||
}\
|
} \
|
||||||
\
|
\
|
||||||
type __Autoarr_get_##type(Autoarr_##type* ar, uint32 index){\
|
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX);\
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
return ar->values[index/ar->max_block_length][index%ar->max_block_length];\
|
return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \
|
||||||
}\
|
} \
|
||||||
\
|
\
|
||||||
type* __Autoarr_getptr_##type(Autoarr_##type* ar, uint32 index){\
|
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX);\
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length);\
|
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \
|
||||||
}\
|
} \
|
||||||
\
|
\
|
||||||
void __Autoarr_set_##type(Autoarr_##type* ar, uint32 index, type element){\
|
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
|
||||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX);\
|
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||||
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element;\
|
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element; \
|
||||||
}\
|
} \
|
||||||
\
|
\
|
||||||
void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr){\
|
void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \
|
||||||
for(uint16 i=0; i<ar->blocks_count;i++)\
|
for(u16 i=0; i<ar->blocks_count;i++) \
|
||||||
free(ar->values[i]); \
|
free(ar->values[i]); \
|
||||||
free(ar->values);\
|
free(ar->values); \
|
||||||
if(freePtr) 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){\
|
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr){ \
|
||||||
uint32 length=Autoarr_length(ar);\
|
if(ktDescriptor_##type.freeMembers!=NULL) { \
|
||||||
type* array=malloc(length * sizeof(type));\
|
Autoarr_foreach(ar, el, \
|
||||||
for(uint32 i=0; i<length; i++)\
|
void* members_ptr=⪙ \
|
||||||
array[i]=__Autoarr_get_##type(ar, i);\
|
if(TYPE_IS_PTR) members_ptr=*(type**)members_ptr; \
|
||||||
return array;\
|
ktDescriptor_##type.freeMembers(members_ptr); \
|
||||||
}\
|
); \
|
||||||
|
} \
|
||||||
|
__Autoarr_##type##_freeWithoutMembers(ar, freePtr);\
|
||||||
|
} \
|
||||||
|
void ____Autoarr_##type##_freeWithMembers(void* ar){ \
|
||||||
|
__Autoarr_##type##_freeWithMembers((Autoarr_##type*)ar, false); \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
__functions_list_t_##type __functions_list_##type={\
|
type* __Autoarr_##type##_toArray(Autoarr_##type* ar){ \
|
||||||
&__Autoarr_add_##type,\
|
u32 length=Autoarr_length(ar); \
|
||||||
&__Autoarr_get_##type,\
|
if(length==0) \
|
||||||
&__Autoarr_getptr_##type,\
|
return NULL; \
|
||||||
&__Autoarr_set_##type,\
|
type* array=malloc(length * sizeof(type)); \
|
||||||
&__Autoarr_free_##type,\
|
for(u32 i=0; i<length; i++) \
|
||||||
&__Autoarr_toArray_##type\
|
array[i]=__Autoarr_##type##_get(ar, i); \
|
||||||
};\
|
return array; \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length){\
|
__Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \
|
||||||
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type));\
|
&__Autoarr_##type##_add, \
|
||||||
*ar=(Autoarr_##type){\
|
&__Autoarr_##type##_get, \
|
||||||
.max_blocks_count=max_blocks_count,\
|
&__Autoarr_##type##_getPtr, \
|
||||||
.blocks_count=0,\
|
&__Autoarr_##type##_set, \
|
||||||
.max_block_length=max_block_length,\
|
&__Autoarr_##type##_freeWithMembers, \
|
||||||
.block_length=0,\
|
&__Autoarr_##type##_freeWithoutMembers, \
|
||||||
.values=NULL,\
|
&__Autoarr_##type##_toArray \
|
||||||
.functions=&__functions_list_##type\
|
}; \
|
||||||
};\
|
\
|
||||||
return ar;\
|
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length){ \
|
||||||
|
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \
|
||||||
|
*ar=(Autoarr_##type){ \
|
||||||
|
.max_blocks_count=max_blocks_count, \
|
||||||
|
.blocks_count=0, \
|
||||||
|
.max_block_length=max_block_length, \
|
||||||
|
.block_length=0, \
|
||||||
|
.values=NULL, \
|
||||||
|
.functions=&__Autoarr_##type##_functions_list \
|
||||||
|
}; \
|
||||||
|
return ar; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ void DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){
|
|||||||
|
|
||||||
// checks for dtsod contains value or dont
|
// checks for dtsod contains value or dont
|
||||||
bool DtsodV24_contains(Hashtable* dtsod, char* key){
|
bool DtsodV24_contains(Hashtable* dtsod, char* key){
|
||||||
Unitype* val=Hashtable_getptr(dtsod, key);
|
Unitype* val=Hashtable_getPtr(dtsod, key);
|
||||||
return val!=NULL;
|
return val!=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaces value with UniNull if key exists in dtsod
|
// replaces value with UniNull if key exists in dtsod
|
||||||
bool DtsodV24_remove(Hashtable* dtsod, char* key){
|
bool DtsodV24_remove(Hashtable* dtsod, char* key){
|
||||||
Unitype* val=Hashtable_getptr(dtsod, key);
|
Unitype* val=Hashtable_getPtr(dtsod, key);
|
||||||
if (!val) return false;
|
if (!val) return false;
|
||||||
*val=UniNull;
|
*val=UniNull;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -18,17 +18,17 @@ typedef struct DeserializeSharedData{
|
|||||||
|
|
||||||
|
|
||||||
// special func for throwing error messages about wrong characters in deserializing text
|
// special func for throwing error messages about wrong characters in deserializing text
|
||||||
Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* srcfile, int line, const char* funcname){
|
Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* srcfile, i32 line, const char* funcname){
|
||||||
char errBuf[68];
|
char errBuf[68];
|
||||||
for(uint8 n=0; n<sizeof(errBuf);n++)
|
for(u8 n=0; n<sizeof(errBuf);n++)
|
||||||
errBuf[n]='\0';
|
errBuf[n]='\0';
|
||||||
char* errText=_text-32;
|
char* errText=_text-32;
|
||||||
uint8 cplace=32;
|
u8 cplace=32;
|
||||||
if(errText<text_first) {
|
if(errText<text_first) {
|
||||||
cplace=_text-text_first;
|
cplace=_text-text_first;
|
||||||
errText=text_first;
|
errText=text_first;
|
||||||
}
|
}
|
||||||
uint8 i=0;
|
u8 i=0;
|
||||||
for(; i<cplace; i++){
|
for(; i<cplace; i++){
|
||||||
// writes 32 chars before the wrongchar
|
// writes 32 chars before the wrongchar
|
||||||
errBuf[i]=errText[i];
|
errBuf[i]=errText[i];
|
||||||
@@ -154,10 +154,10 @@ Maybe __ReadList(DeserializeSharedData* shared){
|
|||||||
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
|
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
|
||||||
bool readingList=true;
|
bool readingList=true;
|
||||||
while (true){
|
while (true){
|
||||||
try(ReadValue((&readingList)), val, Autoarr_free(list, true))
|
try(ReadValue((&readingList)), m_val, Autoarr_free(list, true))
|
||||||
Autoarr_add(list,val.value);
|
Autoarr_add(list,m_val.value);
|
||||||
if (!readingList){
|
if (!readingList){
|
||||||
if(val.value.typeId==ktid_Null)
|
if(Unitype_isUniNull(m_val.value))
|
||||||
Autoarr_pop(list);
|
Autoarr_pop(list);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
|
|||||||
}
|
}
|
||||||
// UInt64
|
// UInt64
|
||||||
case 'u': {
|
case 'u': {
|
||||||
uint64 lu=0;
|
u64 lu=0;
|
||||||
char* _c=string_extract(str);
|
char* _c=string_extract(str);
|
||||||
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
|
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
|
||||||
char err[64];
|
char err[64];
|
||||||
@@ -204,7 +204,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
|
|||||||
// Int64
|
// Int64
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9': {
|
case '5': case '6': case '7': case '8': case '9': {
|
||||||
int64 li=0;
|
i64 li=0;
|
||||||
char* _c=string_extract(str);
|
char* _c=string_extract(str);
|
||||||
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
|
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
|
||||||
char err[64];
|
char err[64];
|
||||||
@@ -272,10 +272,12 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
|
|||||||
case ']':
|
case ']':
|
||||||
if(!readingList) safethrow_wrongchar(c,Unitype_free(value));
|
if(!readingList) safethrow_wrongchar(c,Unitype_free(value));
|
||||||
*readingList=false;
|
*readingList=false;
|
||||||
|
goto return_value;
|
||||||
case ';':
|
case ';':
|
||||||
case ',':
|
case ',':
|
||||||
|
return_value:
|
||||||
if(valueStr.length!=0){
|
if(valueStr.length!=0){
|
||||||
if(value.typeId!=ktid_Null)
|
if(!Unitype_isUniNull(value))
|
||||||
safethrow_wrongchar(c,Unitype_free(value));
|
safethrow_wrongchar(c,Unitype_free(value));
|
||||||
try(ParseValue(valueStr),maybeParsed,;)
|
try(ParseValue(valueStr),maybeParsed,;)
|
||||||
value=maybeParsed.value;
|
value=maybeParsed.value;
|
||||||
@@ -316,8 +318,11 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
|
|||||||
partOfDollarList=false;
|
partOfDollarList=false;
|
||||||
Autoarr(Unitype)* list;
|
Autoarr(Unitype)* list;
|
||||||
Unitype lu;
|
Unitype lu;
|
||||||
if(Hashtable_try_get(dict,nameCPtr, &lu)){
|
if(Hashtable_tryGet(dict,nameCPtr, &lu)){
|
||||||
list=(Autoarr(Unitype)*)lu.VoidPtr;
|
list=(Autoarr(Unitype)*)lu.VoidPtr;
|
||||||
|
// Key is not used in that case, because it is already added
|
||||||
|
// to the table with the first dollar list item.
|
||||||
|
free(nameCPtr);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
|
list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
|
||||||
|
|||||||
@@ -49,11 +49,11 @@ EXPORT void CALL kerep_DtsodV24_free(Hashtable* dtsod){
|
|||||||
DtsodV24_free(dtsod);
|
DtsodV24_free(dtsod);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, uint16* heigth){
|
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, u16* heigth){
|
||||||
*heigth=Hashtable_height(dtsod);
|
*heigth=Hashtable_height(dtsod);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, uint16 h, Autoarr_KVPair** row){
|
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, u16 h, Autoarr_KVPair** row){
|
||||||
*row=dtsod->rows[h];
|
*row=dtsod->rows[h];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
#include "../String/StringBuilder.h"
|
#include "../String/StringBuilder.h"
|
||||||
|
|
||||||
|
|
||||||
typedef struct SerializeSharedData{
|
STRUCT(SerializeSharedData,
|
||||||
StringBuilder* sh_builder;
|
StringBuilder* sh_builder;
|
||||||
uint8 sh_tabs;
|
u8 sh_tabs;
|
||||||
} SerializeSharedData;
|
)
|
||||||
#define b shared->sh_builder
|
#define b shared->sh_builder
|
||||||
#define tabs shared->sh_tabs
|
#define tabs shared->sh_tabs
|
||||||
|
|
||||||
Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod);
|
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod);
|
||||||
|
|
||||||
#define addc(C) StringBuilder_append_char(b,C)
|
#define addc(C) StringBuilder_append_char(b,C)
|
||||||
|
|
||||||
|
|
||||||
void __AppendTabs(SerializeSharedData* shared) {
|
void __AppendTabs(SerializeSharedData* shared) {
|
||||||
for (uint8 t = 0; t < tabs; t++)
|
for (u8 t = 0; t < tabs; t++)
|
||||||
addc( '\t');
|
addc( '\t');
|
||||||
};
|
};
|
||||||
#define AppendTabs() __AppendTabs(shared)
|
#define AppendTabs() __AppendTabs(shared)
|
||||||
@@ -23,15 +23,15 @@ void __AppendTabs(SerializeSharedData* shared) {
|
|||||||
Maybe __AppendValue(SerializeSharedData* shared, Unitype u);
|
Maybe __AppendValue(SerializeSharedData* shared, Unitype u);
|
||||||
#define AppendValue(UNI) __AppendValue(shared, UNI)
|
#define AppendValue(UNI) __AppendValue(shared, UNI)
|
||||||
Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
||||||
if(u.typeId==ktid_name(int64)){
|
if(u.typeId==ktid_name(i64)){
|
||||||
StringBuilder_append_int64(b,u.Int64);
|
StringBuilder_append_i64(b,u.Int64);
|
||||||
}
|
}
|
||||||
else if(u.typeId==ktid_name(uint64)){
|
else if(u.typeId==ktid_name(u64)){
|
||||||
StringBuilder_append_uint64(b,u.UInt64);
|
StringBuilder_append_u64(b,u.UInt64);
|
||||||
addc('u');
|
addc('u');
|
||||||
}
|
}
|
||||||
else if(u.typeId==ktid_name(float64)){
|
else if(u.typeId==ktid_name(f64)){
|
||||||
StringBuilder_append_float64(b,u.Float64);
|
StringBuilder_append_f64(b,u.Float64);
|
||||||
addc('f');
|
addc('f');
|
||||||
}
|
}
|
||||||
else if(u.typeId==ktid_ptrName(char)){
|
else if(u.typeId==ktid_ptrName(char)){
|
||||||
@@ -46,7 +46,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
|||||||
else if(u.typeId==ktid_name(bool)){
|
else if(u.typeId==ktid_name(bool)){
|
||||||
StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
|
StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
|
||||||
}
|
}
|
||||||
else if(u.typeId==ktid_Null){
|
else if(Unitype_isUniNull(u)){
|
||||||
safethrow("Null isn't supported in DtsodV24",;);
|
safethrow("Null isn't supported in DtsodV24",;);
|
||||||
}
|
}
|
||||||
else if(u.typeId==ktid_ptrName(Autoarr_Unitype)){
|
else if(u.typeId==ktid_ptrName(Autoarr_Unitype)){
|
||||||
@@ -55,12 +55,12 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
|||||||
AppendTabs();
|
AppendTabs();
|
||||||
addc('[');
|
addc('[');
|
||||||
tabs++;
|
tabs++;
|
||||||
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({
|
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e,
|
||||||
addc('\n');
|
addc('\n');
|
||||||
AppendTabs();
|
AppendTabs();
|
||||||
try(AppendValue(e),__,;);
|
try(AppendValue(e),__,;);
|
||||||
addc(',');
|
addc(',');
|
||||||
}));
|
);
|
||||||
StringBuilder_rmchar(b);
|
StringBuilder_rmchar(b);
|
||||||
addc('\n');
|
addc('\n');
|
||||||
tabs--;
|
tabs--;
|
||||||
@@ -75,11 +75,11 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
|||||||
else if(u.typeId==ktid_ptrName(Hashtable)){
|
else if(u.typeId==ktid_ptrName(Hashtable)){
|
||||||
// check hashtable is blank
|
// check hashtable is blank
|
||||||
bool hashtableNotBlank=false;
|
bool hashtableNotBlank=false;
|
||||||
Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({
|
Hashtable_foreach(((Hashtable*)u.VoidPtr), __,
|
||||||
hashtableNotBlank=true;
|
hashtableNotBlank=true;
|
||||||
if(__.key); // weird way to disable warning
|
if(__.key) {} // weird way to disable warning
|
||||||
break;
|
break;
|
||||||
}));
|
);
|
||||||
|
|
||||||
if(hashtableNotBlank){
|
if(hashtableNotBlank){
|
||||||
addc('\n');
|
addc('\n');
|
||||||
@@ -102,14 +102,14 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
|||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
|
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
|
||||||
SerializeSharedData _shared={
|
SerializeSharedData _shared={
|
||||||
.sh_builder=_b,
|
.sh_builder=_b,
|
||||||
.sh_tabs=_tabs
|
.sh_tabs=_tabs
|
||||||
};
|
};
|
||||||
SerializeSharedData* shared=&_shared;
|
SerializeSharedData* shared=&_shared;
|
||||||
|
|
||||||
Hashtable_foreach(dtsod, p, ({
|
Hashtable_foreach(dtsod, p,
|
||||||
AppendTabs();
|
AppendTabs();
|
||||||
StringBuilder_append_cptr(b,p.key);
|
StringBuilder_append_cptr(b,p.key);
|
||||||
addc(':');
|
addc(':');
|
||||||
@@ -117,7 +117,7 @@ Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
|
|||||||
try(AppendValue(p.value),__,;);
|
try(AppendValue(p.value),__,;);
|
||||||
addc(';');
|
addc(';');
|
||||||
addc('\n');
|
addc('\n');
|
||||||
}));
|
);
|
||||||
|
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,69 @@
|
|||||||
#include "dir.h"
|
#include "filesystem.h"
|
||||||
|
#include "io_includes.h"
|
||||||
|
#include "../kprint/kprint.h"
|
||||||
|
|
||||||
|
bool dir_exists(const char* path){
|
||||||
|
if(path[0]=='.'){
|
||||||
|
if(path[1]==0 || (path[1]==path_sep && path[1]==0))
|
||||||
|
return true; // dir . or ./ always exists
|
||||||
|
// else if(path[1]=='.' && path[2]==path_sep)
|
||||||
|
//TODO path_resolve because windows doesnt recognize .\ pattern
|
||||||
|
}
|
||||||
|
#if KFS_USE_WINDOWS_H
|
||||||
|
DWORD dwAttrib = GetFileAttributes(path);
|
||||||
|
return (bool)(
|
||||||
|
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
|
||||||
|
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is a directory
|
||||||
|
#else
|
||||||
|
struct stat stats;
|
||||||
|
i32 rez=stat(path, &stats);
|
||||||
|
return (bool)(
|
||||||
|
(rez!=-1) && // file exists
|
||||||
|
(S_ISDIR(stats.st_mode))); // file is a directory
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe dir_create(const char* path){
|
||||||
|
if (dir_exists(path))
|
||||||
|
return MaybeNull;
|
||||||
|
char* parentDir=path_parentDir(path);
|
||||||
|
dir_create(parentDir);
|
||||||
|
free(parentDir);
|
||||||
|
#if KFS_USE_WINDOWS_H
|
||||||
|
if(!CreateDirectory(path, NULL))
|
||||||
|
#else
|
||||||
|
if(mkdir(path, 0777) == -1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
char err[512];
|
||||||
|
IFWIN(
|
||||||
|
sprintf_s(err, 512, "can't create dicectory <%s>", path),
|
||||||
|
sprintf(err, "can't create dicectory <%s>", path));
|
||||||
|
safethrow(err,;);
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe dir_delete(const char* path){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe dir_getFiles(const char* path, bool recursive){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
Maybe dir_getDirs(const char* path, bool recursive){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,11 +7,21 @@ extern "C" {
|
|||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
|
||||||
typedef char* DirPath;
|
bool dir_exists(const char* path);
|
||||||
Array_declare(DirPath);
|
///@return Maybe<void>
|
||||||
|
Maybe dir_create(const char* path);
|
||||||
|
///@return Maybe<void>
|
||||||
|
Maybe dir_delete(const char* path);
|
||||||
|
|
||||||
Array_FilePath dir_getFiles(DirPath path);
|
///@return Maybe<Array_string>
|
||||||
Array_FilePath dir_findFiles(DirPath path, FilePath searchPattern);
|
Maybe dir_getFiles(const char* path, bool recursive);
|
||||||
|
///@return Maybe<Array_string>
|
||||||
|
Maybe dir_getDirs(const char* path, bool recursive);
|
||||||
|
|
||||||
|
///@return Maybe<Array_string>
|
||||||
|
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive);
|
||||||
|
///@return Maybe<Array_string>
|
||||||
|
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,37 @@
|
|||||||
#include "file.h"
|
#include "filesystem.h"
|
||||||
#include "../String/StringBuilder.h"
|
#include "../String/StringBuilder.h"
|
||||||
|
#include "io_includes.h"
|
||||||
|
|
||||||
ktid_define(File);
|
void __file_freeMembers(void* _f){ fclose((FileHandle)_f); }
|
||||||
|
|
||||||
|
kt_define(FileHandle, __file_freeMembers, NULL)
|
||||||
|
|
||||||
|
bool file_exists(const char* path){
|
||||||
|
if(path[0]=='.'){
|
||||||
|
if(path[1]==0 || (path[1]==path_sep && path[2]==0))
|
||||||
|
return false; // . or ./ is not a file
|
||||||
|
// else if(path[1]=='.' && path[2]==path_sep)
|
||||||
|
//TODO path_resolve because windows doesnt recognize .\ pattern
|
||||||
|
}
|
||||||
|
|
||||||
|
#if KFS_USE_WINDOWS_H
|
||||||
|
DWORD dwAttrib = GetFileAttributes(path);
|
||||||
|
return (bool)(
|
||||||
|
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
|
||||||
|
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is not directory
|
||||||
|
#else
|
||||||
|
struct stat stats;
|
||||||
|
i32 rez=stat(path, &stats);
|
||||||
|
return (bool)(
|
||||||
|
(rez!=-1) && // file exists
|
||||||
|
!(S_ISDIR(stats.st_mode))); // file is not directory
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe file_delete(const char* path, bool recursive){
|
||||||
|
throw(ERR_NOTIMPLEMENTED);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
char* FileOpenMode_toStr(FileOpenMode m){
|
char* FileOpenMode_toStr(FileOpenMode m){
|
||||||
char* p;
|
char* p;
|
||||||
@@ -18,14 +48,14 @@ char* FileOpenMode_toStr(FileOpenMode m){
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_open(FilePath path, FileOpenMode mode){
|
Maybe file_open(const char* path, FileOpenMode mode){
|
||||||
File* file=fopen(path, FileOpenMode_toStr(mode));
|
FileHandle file=fopen(path, FileOpenMode_toStr(mode));
|
||||||
if(!file)
|
if(!file)
|
||||||
safethrow(cptr_concat("can't open file ", (char*)path),;);
|
safethrow(cptr_concat("can't open file ", (char*)path),;);
|
||||||
return SUCCESS(UniHeapPtr(File,file));
|
return SUCCESS(UniHeapPtr(FileHandle,file));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_close(File* file){
|
Maybe file_close(FileHandle file){
|
||||||
if(!file)
|
if(!file)
|
||||||
safethrow(ERR_NULLPTR,;);
|
safethrow(ERR_NULLPTR,;);
|
||||||
if(fclose(file))
|
if(fclose(file))
|
||||||
@@ -33,43 +63,43 @@ Maybe file_close(File* file){
|
|||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ioWriteCheck()\
|
#define ioWriteCheck() \
|
||||||
if(rezult==EOF)\
|
if(rezult==EOF) \
|
||||||
safethrow(ERR_IO_EOF,;);\
|
safethrow(ERR_IO_EOF,;); \
|
||||||
if(rezult!=0)\
|
if(rezult!=0) \
|
||||||
safethrow(ERR_IO,;);
|
safethrow(ERR_IO,;);
|
||||||
|
|
||||||
Maybe file_writeChar(File* file, char byte){
|
Maybe file_writeChar(FileHandle file, char byte){
|
||||||
int rezult=fputc(byte, file);
|
i32 rezult=fputc(byte, file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_writeBuffer(File* file, char* buffer, uint64 length){
|
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
|
||||||
int rezult=0;
|
i32 rezult=0;
|
||||||
for(uint64 i=0; i<length && !rezult; i++)
|
for(u64 i=0; i<length && !rezult; i++)
|
||||||
rezult=fputc(buffer[i], file);
|
rezult=fputc(buffer[i], file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_writeCptr(File* file, char* cptr){
|
Maybe file_writeCptr(FileHandle file, char* cptr){
|
||||||
int rezult=fputs(cptr, file);
|
i32 rezult=fputs(cptr, file);
|
||||||
ioWriteCheck();
|
ioWriteCheck();
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Maybe file_readChar(File* file){
|
Maybe file_readChar(FileHandle file){
|
||||||
int rezult=fgetc(file);
|
i32 rezult=fgetc(file);
|
||||||
if(feof(file)) safethrow(ERR_IO_EOF,;);
|
if(feof(file)) safethrow(ERR_IO_EOF,;);
|
||||||
if(ferror(file)) safethrow(ERR_IO,;);
|
if(ferror(file)) safethrow(ERR_IO,;);
|
||||||
return SUCCESS(UniUInt64(rezult));
|
return SUCCESS(UniUInt64(rezult));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_readBuffer(File* file, char* buffer, uint64 length){
|
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
|
||||||
int rezult=0;
|
i32 rezult=0;
|
||||||
uint64 i=0;
|
u64 i=0;
|
||||||
for(; i<length && rezult!=EOF; i++){
|
for(; i<length && rezult!=EOF; i++){
|
||||||
rezult=fgetc(file);
|
rezult=fgetc(file);
|
||||||
buffer[i]=(char)rezult;
|
buffer[i]=(char)rezult;
|
||||||
@@ -78,20 +108,20 @@ Maybe file_readBuffer(File* file, char* buffer, uint64 length){
|
|||||||
return SUCCESS(UniUInt64(i));
|
return SUCCESS(UniUInt64(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe file_readAll(File* file, char** allBytes){
|
Maybe file_readAll(FileHandle file, char** allBytes){
|
||||||
int rezult=0;
|
i32 rezult=0;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
|
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
|
||||||
StringBuilder* sb=StringBuilder_create();
|
StringBuilder* sb=StringBuilder_create();
|
||||||
uint64 i=0;
|
u64 i=0;
|
||||||
while(true){
|
while(true){
|
||||||
rezult=fgetc(file);
|
rezult=fgetc(file);
|
||||||
if(rezult!=EOF){
|
if(rezult==EOF){
|
||||||
if(ferror(file))
|
if(ferror(file))
|
||||||
safethrow(ERR_IO,; StringBuilder_free(sb));
|
safethrow(ERR_IO, StringBuilder_free(sb));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buffer[i]=(char)rezult;
|
buffer[i%sizeof(buffer)]=(char)rezult;
|
||||||
i++;
|
i++;
|
||||||
if(!(i%sizeof(buffer)))
|
if(!(i%sizeof(buffer)))
|
||||||
StringBuilder_append_string(sb,bufStr);
|
StringBuilder_append_string(sb,bufStr);
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ extern "C" {
|
|||||||
#include "../Array/Array.h"
|
#include "../Array/Array.h"
|
||||||
#include "../String/string.h"
|
#include "../String/string.h"
|
||||||
|
|
||||||
typedef char* FilePath;
|
typedef FILE* FileHandle;
|
||||||
Array_declare(FilePath);
|
kt_declare(FileHandle);
|
||||||
typedef FILE File;
|
|
||||||
ktid_declare(File);
|
|
||||||
|
|
||||||
PACK_ENUM(FileOpenMode,
|
bool file_exists(const char* path);
|
||||||
|
|
||||||
|
///@return Maybe<void>
|
||||||
|
Maybe file_delete(const char* path, bool recursive);
|
||||||
|
|
||||||
|
PACKED_ENUM(FileOpenMode,
|
||||||
// open a file for reading
|
// open a file for reading
|
||||||
FileOpenMode_Read=1,
|
FileOpenMode_Read=1,
|
||||||
// (re)create a file for writing
|
// (re)create a file for writing
|
||||||
@@ -24,50 +27,49 @@ PACK_ENUM(FileOpenMode,
|
|||||||
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
|
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
|
||||||
// opens file for readng/writing additional data to the end / creates new file
|
// opens file for readng/writing additional data to the end / creates new file
|
||||||
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
|
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/// @brief opens file
|
/// @brief opens file
|
||||||
/// @param path path to file
|
/// @param path path to file
|
||||||
/// @param mode Read/Write/Append/ReadWrite/ReadAppend
|
/// @param mode Read/Write/Append/ReadWrite/ReadAppend
|
||||||
/// @return Maybe<File*>
|
/// @return Maybe<FileHandle>
|
||||||
Maybe file_open(FilePath path, FileOpenMode mode);
|
Maybe file_open(const char* path, FileOpenMode mode);
|
||||||
|
|
||||||
/// @brief closes file descriptor
|
/// @brief closes file descriptor
|
||||||
/// @return Maybe<void>
|
/// @return Maybe<void>
|
||||||
Maybe file_close(File* file);
|
Maybe file_close(FileHandle file);
|
||||||
|
|
||||||
/// @brief closes file descriptor
|
/// @brief closes file descriptor
|
||||||
/// @param byte byte to write
|
/// @param byte byte to write
|
||||||
/// @return Maybe<void>
|
/// @return Maybe<void>
|
||||||
Maybe file_writeChar(File* file, char byte);
|
Maybe file_writeChar(FileHandle file, char byte);
|
||||||
|
|
||||||
/// @brief closes file descriptor
|
/// @brief closes file descriptor
|
||||||
/// @param buffer bytes to write
|
/// @param buffer bytes to write
|
||||||
/// @param length buffer length
|
/// @param length buffer length
|
||||||
/// @return Maybe<void>
|
/// @return Maybe<void>
|
||||||
Maybe file_writeBuffer(File* file, char* buffer, uint64 length);
|
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length);
|
||||||
|
|
||||||
/// @brief writes all cstring array content to file
|
/// @brief writes all cstring array content to file
|
||||||
/// @param cptr zero-terminated cstring
|
/// @param cptr zero-terminated cstring
|
||||||
/// @return Maybe<void>
|
/// @return Maybe<void>
|
||||||
Maybe file_writeCptr(File* file, char* cptr);
|
Maybe file_writeCptr(FileHandle file, char* cptr);
|
||||||
|
|
||||||
|
|
||||||
/// @brief reads single byte from file
|
/// @brief reads single byte from file
|
||||||
/// @return Maybe<char>
|
/// @return Maybe<char>
|
||||||
Maybe file_readChar(File* file);
|
Maybe file_readChar(FileHandle file);
|
||||||
|
|
||||||
/// @brief reads byte array of specofied length
|
/// @brief reads byte array of specofied length
|
||||||
/// @param buffer buffer that will be filled with file bytes
|
/// @param buffer buffer that will be filled with file bytes
|
||||||
/// @param length buffer length
|
/// @param length buffer length
|
||||||
/// @return Maybe<uint64> total number of successfully read bytes (<=length)
|
/// @return Maybe<u64> total number of successfully read bytes (<=length)
|
||||||
Maybe file_readBuffer(File* file, char* buffer, uint64 length);
|
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length);
|
||||||
|
|
||||||
/// @brief reads all bytes from file
|
/// @brief reads all bytes from file
|
||||||
/// @param allBytes ptr to the file's content will be pushed there
|
/// @param allBytes ptr to the file's content will be pushed there
|
||||||
/// @return Maybe<uint64> total number of successfully read bytes
|
/// @return Maybe<u64> total number of successfully read bytes
|
||||||
Maybe file_readAll(File* file, char** allBytes);
|
Maybe file_readAll(FileHandle file, char** allBytes);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/Filesystem/io_includes.h
Normal file
15
src/Filesystem/io_includes.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include "../base/std.h"
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
#define KFS_USE_WINDOWS_H 1
|
||||||
|
#else
|
||||||
|
#define KFS_USE_WINDOWS_H 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KFS_USE_WINDOWS_H
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
#include "filesystem.h"
|
#include "filesystem.h"
|
||||||
|
|
||||||
char* __path_concat(uint16 n, ...){
|
char* __path_concat(u32 n, ...){
|
||||||
char** parts=(char**)malloc(n*sizeof(char*));
|
char** parts=(char**)malloc(n*sizeof(char*));
|
||||||
uint32* lengths=malloc(n*sizeof(uint32));
|
u32* lengths=malloc(n*sizeof(u32));
|
||||||
uint32 totalLength=0;
|
u32 totalLength=0;
|
||||||
|
|
||||||
// reading args from va_list
|
// reading args from va_list
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, n);
|
va_start(vl, n);
|
||||||
for(uint16 i=0; i<n; i++){
|
for(u16 i=0; i<n; i++){
|
||||||
char* part=va_arg(vl,char*);
|
char* part=va_arg(vl,char*);
|
||||||
int16 length=cptr_length(part);
|
i16 length=cptr_length(part);
|
||||||
parts[i]=part;
|
parts[i]=part;
|
||||||
lengths[i]=length;
|
lengths[i]=length;
|
||||||
totalLength+=length;
|
totalLength+=length;
|
||||||
@@ -23,7 +23,7 @@ char* __path_concat(uint16 n, ...){
|
|||||||
totality[totalLength]=0;
|
totality[totalLength]=0;
|
||||||
|
|
||||||
// copying content of all strings to rezult
|
// copying content of all strings to rezult
|
||||||
uint16 k=0;
|
u16 k=0;
|
||||||
for(; k<n-1; k++){
|
for(; k<n-1; k++){
|
||||||
memcopy(parts[k], totality, lengths[k]);
|
memcopy(parts[k], totality, lengths[k]);
|
||||||
totality+=lengths[k];
|
totality+=lengths[k];
|
||||||
@@ -37,7 +37,7 @@ char* __path_concat(uint16 n, ...){
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* path_fixSeparators(char* path){
|
char* path_fixSeparators(const char* path){
|
||||||
char* pathCopy=cptr_copy(path);
|
char* pathCopy=cptr_copy(path);
|
||||||
char c;
|
char c;
|
||||||
while((c=*pathCopy)){
|
while((c=*pathCopy)){
|
||||||
@@ -48,8 +48,37 @@ char* path_fixSeparators(char* path){
|
|||||||
return pathCopy;
|
return pathCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe path_throwIfEscapes(char* path){
|
Maybe path_throwIfEscapes(const char* path){
|
||||||
if(cptr_contains(path,".."))
|
if(cptr_contains(path,".."))
|
||||||
safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),);
|
safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),);
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* path_parentDir(char* dir){
|
||||||
|
char* copy=cptr_copy(dir);
|
||||||
|
i32 length=cptr_length(copy);
|
||||||
|
i32 i=cptr_lastIndexOfChar(copy,path_sep);
|
||||||
|
if(i!=-1 && i==length-1){
|
||||||
|
copy[length-1]=0;
|
||||||
|
i=cptr_lastIndexOfChar(copy,path_sep);
|
||||||
|
}
|
||||||
|
if(i==-1){
|
||||||
|
free(copy);
|
||||||
|
copy=malloc(2);
|
||||||
|
copy[0]='.';
|
||||||
|
copy[1]=0;
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* path_basename(char* path, bool with_extension){
|
||||||
|
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
|
||||||
|
string rezult=string_fromCptr(path+nameIndex);
|
||||||
|
if(!with_extension){
|
||||||
|
i32 extIndex=cptr_lastIndexOfChar(rezult.ptr, '.');
|
||||||
|
if(extIndex!=0 && extIndex!=-1)
|
||||||
|
rezult.length=extIndex;
|
||||||
|
}
|
||||||
|
return string_extract(rezult);
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,22 +14,28 @@ static const char path_sep='/';
|
|||||||
static const char path_notSep='\\';
|
static const char path_notSep='\\';
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char* __path_concat(uint16 n, ...);
|
char* __path_concat(u32 n, ...);
|
||||||
/// @brief merges path parts together and places <path_sep> between them
|
/// @brief merges path parts together and puts <path_sep> between them
|
||||||
/// @return new cstr
|
/// @return new cstr
|
||||||
#define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS)
|
#define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS)
|
||||||
|
|
||||||
/// @brief fixes path separators
|
/// @brief fixes path separators
|
||||||
/// @param cstr where can be <path_notSep>
|
/// @param cstr where can be <path_notSep>
|
||||||
/// @return new cstr with correct separators
|
/// @return new cstr with correct separators
|
||||||
char* path_fixSeparators(char* path);
|
char* path_fixSeparators(const char* path);
|
||||||
|
|
||||||
#define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS))
|
#define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS))
|
||||||
|
|
||||||
/// @brief calls safethrow() if finds escape sequense in path
|
/// @brief calls safethrow() if finds escape sequense in path
|
||||||
/// @param path cstr where can be <..>
|
/// @param path cstr where can be <..>
|
||||||
/// @return Maybe<void>
|
/// @return Maybe<void>
|
||||||
Maybe path_throwIfEscapes(char* path);
|
Maybe path_throwIfEscapes(const char* path);
|
||||||
|
|
||||||
|
///@return path of parent dir
|
||||||
|
char* path_parentDir(char* path);
|
||||||
|
|
||||||
|
///@return file name
|
||||||
|
char* path_basename(char* path, bool with_extension);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
uint32 hash_sdbm32(uint32 oldhash, void* buf, uint32 len){
|
u32 hash_sdbm32(u32 oldhash, void* buf, u32 len){
|
||||||
uint8* ubuf=(uint8*)buf;
|
u8* ubuf=(u8*)buf;
|
||||||
register uint32 hash=oldhash;
|
register u32 hash=oldhash;
|
||||||
for (; len ; len--, ubuf++)
|
for (; len ; len--, ubuf++)
|
||||||
hash=(hash<<6)+(hash<<16)-hash+*ubuf;
|
hash=(hash<<6)+(hash<<16)-hash+*ubuf;
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32 crc_32_tab[]={
|
static const u32 crc_32_tab[]={
|
||||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
@@ -75,19 +75,19 @@ static const uint32 crc_32_tab[]={
|
|||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32 hash_crc32(uint32 oldhash, void* buf, uint32 len){
|
u32 hash_crc32(u32 oldhash, void* buf, u32 len){
|
||||||
uint8* ubuf=(uint8*)buf;
|
u8* ubuf=(u8*)buf;
|
||||||
register uint32 crc=oldhash;
|
register u32 crc=oldhash;
|
||||||
for (; len; --len, ++ubuf)
|
for (; len; --len, ++ubuf)
|
||||||
crc=crc_32_tab[(crc^(*ubuf)) & 0xff] ^ (crc>>8);
|
crc=crc_32_tab[(crc^(*ubuf)) & 0xff] ^ (crc>>8);
|
||||||
return ~crc;
|
return ~crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// bool hashf_crc32c(char *name, uint32 *crc, long *charcnt) {
|
// bool hashf_crc32c(char *name, u32 *crc, long *charcnt) {
|
||||||
// register FILE *fin;
|
// register FILE *fin;
|
||||||
// register uint32 oldcrc32;
|
// register u32 oldcrc32;
|
||||||
// register int c;
|
// register i32 c;
|
||||||
|
|
||||||
// oldcrc32 = 0xFFFFFFFF; *charcnt = 0;
|
// oldcrc32 = 0xFFFFFFFF; *charcnt = 0;
|
||||||
// if ((fin=fopen(name, "r"))==NULL) {
|
// if ((fin=fopen(name, "r"))==NULL) {
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ extern "C" {
|
|||||||
#define hashb(FUNC, BUF, LEN) FUNC(0xFFFFFFFF, BUF, LEN)
|
#define hashb(FUNC, BUF, LEN) FUNC(0xFFFFFFFF, BUF, LEN)
|
||||||
#define hashs(FUNC, STR) FUNC(0xFFFFFFFF, STR, cptr_length(STR))
|
#define hashs(FUNC, STR) FUNC(0xFFFFFFFF, STR, cptr_length(STR))
|
||||||
|
|
||||||
uint32 hash_sdbm32(uint32 oldhash, void* buf, uint32 len);
|
u32 hash_sdbm32(u32 oldhash, void* buf, u32 len);
|
||||||
uint32 hash_crc32(uint32 oldhash, void* buf, uint32 len);
|
u32 hash_crc32(u32 oldhash, void* buf, u32 len);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "Hashtable.h"
|
#include "Hashtable.h"
|
||||||
|
|
||||||
ktid_define(Hashtable);
|
kt_define(Hashtable, __Hashtable_free, NULL);
|
||||||
|
|
||||||
// amount of rows
|
// amount of rows
|
||||||
static const uint16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
|
static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
|
||||||
#define HT_HEIN_MIN 0
|
#define HT_HEIN_MIN 0
|
||||||
#define HT_HEIN_MAX 6
|
#define HT_HEIN_MAX 6
|
||||||
|
|
||||||
@@ -14,14 +14,14 @@ Hashtable* Hashtable_create(){
|
|||||||
Hashtable* ht=malloc(sizeof(Hashtable));
|
Hashtable* ht=malloc(sizeof(Hashtable));
|
||||||
ht->hein=HT_HEIN_MIN;
|
ht->hein=HT_HEIN_MIN;
|
||||||
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*));
|
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*));
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
|
for(u16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
|
||||||
ht->rows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
|
ht->rows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __Hashtable_free(void* _ht){
|
void __Hashtable_free(void* _ht){
|
||||||
Hashtable* ht=_ht;
|
Hashtable* ht=_ht;
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||||
Autoarr_free(ht->rows[i], true);
|
Autoarr_free(ht->rows[i], true);
|
||||||
free(ht->rows);
|
free(ht->rows);
|
||||||
}
|
}
|
||||||
@@ -30,27 +30,28 @@ void Hashtable_free(Hashtable* ht){
|
|||||||
free(ht);
|
free(ht);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
|
u16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
|
||||||
|
|
||||||
|
|
||||||
void Hashtable_expand(Hashtable* ht){
|
void Hashtable_expand(Hashtable* ht){
|
||||||
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
|
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
|
||||||
|
|
||||||
Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*));
|
Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*));
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||||
newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
|
newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
|
||||||
|
|
||||||
for(uint16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
|
for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
|
||||||
Autoarr(KVPair)* ar=ht->rows[i];
|
Autoarr(KVPair)* ar=ht->rows[i];
|
||||||
uint32 arlen=Autoarr_length(ar);
|
u32 arlen=Autoarr_length(ar);
|
||||||
for(uint32 k=0;k<arlen;k++){
|
for(u32 k=0;k<arlen;k++){
|
||||||
KVPair p=Autoarr_get(ar,k);
|
KVPair p=Autoarr_get(ar,k);
|
||||||
uint16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
|
u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
|
||||||
Autoarr(KVPair)* newar=newrows[newrown];
|
Autoarr(KVPair)* newar=newrows[newrown];
|
||||||
Autoarr_add(newar,p);
|
Autoarr_add(newar,p);
|
||||||
}
|
}
|
||||||
// there is no need to free array values, because they are copied into new array
|
// there is no need to free array values, because they are copied into new array
|
||||||
__Autoarr_free_KVPair(ar, true);
|
// so dont replace this incorrect auto-generated function
|
||||||
|
Autoarr_freeWithoutMembers(ar, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(ht->rows);
|
free(ht->rows);
|
||||||
@@ -58,7 +59,7 @@ void Hashtable_expand(Hashtable* ht){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
||||||
uint32 hash=hashs(hash_sdbm32, key);
|
u32 hash=hashs(hash_sdbm32, key);
|
||||||
Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
|
Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
|
||||||
if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar))
|
if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar))
|
||||||
Hashtable_expand(ht);
|
Hashtable_expand(ht);
|
||||||
@@ -66,40 +67,67 @@ Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
|||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @param key must be heap allocated
|
||||||
|
/// Hashtable_free will free this pointer
|
||||||
void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
||||||
KVPair p={ .key=key, .value=u };
|
KVPair p={ .key=key, .value=u };
|
||||||
Autoarr_add(getrow(ht,key,true),p);
|
Autoarr_add(getrow(ht,key,true),p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Hashtable_addMany(Hashtable* ht, KVPair* pair_array, u32 count){
|
||||||
|
for(u32 i=0; i<count; i++){
|
||||||
|
Hashtable_add(ht, pair_array[i].key, pair_array[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns null or pointer to value in hashtable
|
// returns null or pointer to value in hashtable
|
||||||
Unitype* Hashtable_getptr(Hashtable* ht, char* key){
|
Unitype* Hashtable_getPtr(Hashtable* ht, char* key){
|
||||||
Autoarr(KVPair)* ar=getrow(ht,key,false);
|
Autoarr(KVPair)* ar=getrow(ht,key,false);
|
||||||
uint32 arlen=Autoarr_length(ar);
|
u32 arlen=Autoarr_length(ar);
|
||||||
for(uint32 i=0;i<arlen;i++){
|
for(u32 i=0;i<arlen;i++){
|
||||||
KVPair* p=Autoarr_getptr(ar,i);
|
KVPair* p=Autoarr_getPtr(ar,i);
|
||||||
if(cptr_compare(key,p->key)) return &p->value;
|
if(cptr_equals(key,p->key)) return &p->value;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unitype Hashtable_get(Hashtable* ht, char* key){
|
Unitype Hashtable_get(Hashtable* ht, char* key){
|
||||||
Autoarr(KVPair)* ar=getrow(ht,key,false);
|
Autoarr(KVPair)* ar=getrow(ht,key,false);
|
||||||
uint32 arlen=Autoarr_length(ar);
|
u32 arlen=Autoarr_length(ar);
|
||||||
for(uint32 i=0;i<arlen;i++){
|
for(u32 i=0;i<arlen;i++){
|
||||||
KVPair p=Autoarr_get(ar,i);
|
KVPair p=Autoarr_get(ar,i);
|
||||||
if(cptr_compare(key,p.key)) return p.value;
|
if(cptr_equals(key,p.key)) return p.value;
|
||||||
}
|
}
|
||||||
return UniNull;
|
return UniNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output){
|
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output){
|
||||||
Unitype u=Hashtable_get(ht,key);
|
Unitype u=Hashtable_get(ht,key);
|
||||||
*output=u;
|
*output=u;
|
||||||
return u.typeId!=ktid_Null;
|
return !Unitype_isUniNull(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Hashtable_trySet(Hashtable* ht, char* key, Unitype u){
|
||||||
|
Unitype* val=Hashtable_getPtr(ht,key);
|
||||||
|
if(val==NULL)
|
||||||
|
return false;
|
||||||
|
*val=u;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Hashtable_tryAdd(Hashtable* ht, char* key, Unitype u){
|
||||||
|
Unitype* val=Hashtable_getPtr(ht,key);
|
||||||
|
if(val==NULL){
|
||||||
|
Hashtable_add(ht, key, u);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u){
|
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u){
|
||||||
Unitype* val=Hashtable_getptr(ht, key);
|
Unitype* val=Hashtable_getPtr(ht, key);
|
||||||
if(val) *val=u;
|
if(val==NULL)
|
||||||
else Hashtable_add(ht, key, u);
|
Hashtable_add(ht, key, u); // add
|
||||||
|
else *val=u; // set
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,21 +4,21 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../base/base.h"
|
||||||
#include "../HashFunctions/hash.h"
|
#include "../HashFunctions/hash.h"
|
||||||
#include "KeyValuePair.h"
|
#include "KeyValuePair.h"
|
||||||
|
|
||||||
typedef struct Hashtable{
|
STRUCT(Hashtable,
|
||||||
uint8 hein; // height=HT_HEIGHTS[hein]
|
u8 hein; // height=HT_HEIGHTS[hein]
|
||||||
Autoarr(KVPair)** rows; // Autoarr[height]
|
Autoarr(KVPair)** rows; // Autoarr[height]
|
||||||
} Hashtable;
|
)
|
||||||
ktid_declare(Hashtable);
|
|
||||||
|
|
||||||
Hashtable* Hashtable_create();
|
Hashtable* Hashtable_create();
|
||||||
void Hashtable_free(Hashtable* ht);
|
void Hashtable_free(Hashtable* ht);
|
||||||
void __Hashtable_free(void* ht);
|
void __Hashtable_free(void* ht);
|
||||||
|
|
||||||
// amount of rows
|
// amount of rows
|
||||||
uint16 Hashtable_height(Hashtable* ht);
|
u16 Hashtable_height(Hashtable* ht);
|
||||||
|
|
||||||
// don't add pairs with the same keys,
|
// don't add pairs with the same keys,
|
||||||
// or something weird will happen
|
// or something weird will happen
|
||||||
@@ -26,20 +26,23 @@ uint16 Hashtable_height(Hashtable* ht);
|
|||||||
void Hashtable_add(Hashtable* ht, char* key, Unitype u);
|
void Hashtable_add(Hashtable* ht, char* key, Unitype u);
|
||||||
|
|
||||||
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u);
|
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u);
|
||||||
|
void Hashtable_addMany(Hashtable* ht, KVPair* pair_array, u32 count);
|
||||||
|
bool Hashtable_tryAdd(Hashtable* ht, char* key, Unitype u);
|
||||||
|
bool Hashtable_trySet(Hashtable* ht, char* key, Unitype u);
|
||||||
|
|
||||||
// returns null or pointer to value in hashtable
|
// returns null or pointer to value in hashtable
|
||||||
Unitype* Hashtable_getptr(Hashtable* ht, char* key);
|
Unitype* Hashtable_getPtr(Hashtable* ht, char* key);
|
||||||
|
|
||||||
Unitype Hashtable_get(Hashtable* ht, char* key);
|
Unitype Hashtable_get(Hashtable* ht, char* key);
|
||||||
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output);
|
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
|
||||||
|
|
||||||
#define Hashtable_foreach(HT, EL, codeblock)({\
|
#define Hashtable_foreach(HT, EL, codeblock...) { \
|
||||||
uint16 hmax=Hashtable_height(HT);\
|
u16 hmax=Hashtable_height(HT); \
|
||||||
for(uint16 h=0; h<hmax; h++){\
|
for(u16 h=0; h<hmax; h++){ \
|
||||||
Autoarr(KVPair)* AR=HT->rows[h];\
|
Autoarr(KVPair)* AR=HT->rows[h]; \
|
||||||
Autoarr_foreach(AR, EL, codeblock);\
|
Autoarr_foreach(AR, EL, codeblock); \
|
||||||
}\
|
} \
|
||||||
})
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,16 @@
|
|||||||
#include "KeyValuePair.h"
|
#include "KeyValuePair.h"
|
||||||
|
|
||||||
ktid_define(KVPair);
|
kt_define(KVPair, __KVPair_free, NULL);
|
||||||
|
|
||||||
Autoarr_define(KVPair)
|
Autoarr_define(KVPair, false)
|
||||||
|
|
||||||
// proper way to clear a KVP
|
// proper way to clean a KVP
|
||||||
void KVPair_free(KVPair p){
|
void KVPair_free(KVPair p){
|
||||||
free(p.key);
|
free(p.key);
|
||||||
Unitype_free(p.value);
|
Unitype_free(p.value);
|
||||||
}
|
}
|
||||||
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
|
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
|
||||||
|
|
||||||
// func for KVP array clearing
|
|
||||||
void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr){
|
|
||||||
Autoarr_foreach(ar,k,KVPair_free(k));
|
|
||||||
__Autoarr_free_KVPair(ar, freePtr);
|
|
||||||
}
|
|
||||||
void ____Autoarr_free_KVPair_(void* ar){
|
|
||||||
__Autoarr_free_KVPair_((Autoarr_KVPair*)ar, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void printkvp(KVPair p){
|
void printkvp(KVPair p){
|
||||||
kprintf("{\"%s\", ",p.key);
|
kprintf("{\"%s\", ",p.key);
|
||||||
printuni(p.value);
|
printuni(p.value);
|
||||||
|
|||||||
@@ -7,22 +7,17 @@ extern "C" {
|
|||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
#include "../Autoarr/Autoarr.h"
|
#include "../Autoarr/Autoarr.h"
|
||||||
|
|
||||||
typedef struct KVPair{
|
STRUCT(KVPair,
|
||||||
char* key;
|
char* key;
|
||||||
Unitype value;
|
Unitype value;
|
||||||
} KVPair;
|
)
|
||||||
ktid_declare(KVPair);
|
|
||||||
|
|
||||||
Autoarr_declare(KVPair)
|
Autoarr_declare(KVPair)
|
||||||
|
|
||||||
// proper way to clear a KVP
|
// proper way to clean a KVP
|
||||||
void KVPair_free(KVPair p);
|
void KVPair_free(KVPair p);
|
||||||
void __KVPair_free(void* p);
|
void __KVPair_free(void* p);
|
||||||
|
|
||||||
// func to clear KVP array
|
|
||||||
void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr);
|
|
||||||
void ____Autoarr_free_KVPair_(void* ar);
|
|
||||||
|
|
||||||
void printkvp(KVPair p);
|
void printkvp(KVPair p);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
68
src/LinkedList/LinkedList.c
Normal file
68
src/LinkedList/LinkedList.c
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#include "LinkedList.h"
|
||||||
|
|
||||||
|
LinkedList_define(Pointer, true)
|
||||||
|
|
||||||
|
void LinkedList_addToBeginning(void* _llist, void* _new_node) {
|
||||||
|
LinkedList(Pointer)* llist=_llist;
|
||||||
|
LLNode(Pointer)* new_node=_new_node;
|
||||||
|
llist->count++;
|
||||||
|
if(llist->last_node==NULL){
|
||||||
|
if(llist->first_node!=NULL)
|
||||||
|
throw(ERR_NULLPTR); // last_node can't be null if first_node != null
|
||||||
|
llist->last_node=new_node;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
llist->first_node->prev=new_node;
|
||||||
|
new_node->next=llist->first_node;
|
||||||
|
}
|
||||||
|
llist->first_node=new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkedList_addToEnd(void* _llist, void* _new_node) {
|
||||||
|
LinkedList(Pointer)* llist=_llist;
|
||||||
|
LLNode(Pointer)* new_node=_new_node;
|
||||||
|
llist->count++;
|
||||||
|
if(llist->first_node==NULL) {
|
||||||
|
if(llist->last_node!=NULL)
|
||||||
|
throw(ERR_NULLPTR); // first_node can't be null if last_node != null
|
||||||
|
llist->first_node=new_node;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
llist->last_node->next=new_node;
|
||||||
|
new_node->prev=llist->last_node;
|
||||||
|
}
|
||||||
|
llist->last_node=new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void _insertNode(LinkedList(Pointer)* llist,
|
||||||
|
LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){
|
||||||
|
if(prev_node==NULL){
|
||||||
|
if(next_node==llist->first_node)
|
||||||
|
LinkedList_addToBeginning(llist, new_node);
|
||||||
|
else throw(ERR_NULLPTR); // prev_node is null, but it isn't insertion before first_node
|
||||||
|
}
|
||||||
|
else if(next_node==NULL){
|
||||||
|
if(prev_node==llist->last_node)
|
||||||
|
LinkedList_addToEnd(llist, new_node);
|
||||||
|
else throw(ERR_NULLPTR); // next_node is null, but it isn't insertion after last_node
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prev_node->next=new_node;
|
||||||
|
new_node->prev=prev_node;
|
||||||
|
new_node->next=next_node;
|
||||||
|
next_node->prev=new_node;
|
||||||
|
llist->count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node){
|
||||||
|
LLNode(Pointer)* next_node=_next_node;
|
||||||
|
LLNode(Pointer)* prev_node=next_node->prev;
|
||||||
|
_insertNode(_llist, prev_node, _new_node, next_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node){
|
||||||
|
LLNode(Pointer)* prev_node=_prev_node;
|
||||||
|
LLNode(Pointer)* next_node=prev_node->next;
|
||||||
|
_insertNode(_llist, prev_node, _new_node, next_node);
|
||||||
|
}
|
||||||
83
src/LinkedList/LinkedList.h
Normal file
83
src/LinkedList/LinkedList.h
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../base/base.h"
|
||||||
|
#include "LinkedList_declare.h"
|
||||||
|
#include "LinkedList_define.h"
|
||||||
|
|
||||||
|
// LinkedListNode
|
||||||
|
|
||||||
|
#define LLNode(TYPE) LLNode_##TYPE
|
||||||
|
#define LinkedList(TYPE) LinkedList_##TYPE
|
||||||
|
|
||||||
|
#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE)
|
||||||
|
|
||||||
|
#define LinkedList_create(TYPE) LinkedList_##TYPE##_create()
|
||||||
|
#define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); })
|
||||||
|
|
||||||
|
|
||||||
|
void LinkedList_addToBeginning(void* _llist, void* _new_node);
|
||||||
|
void LinkedList_addToEnd(void* _llist, void* _new_node);
|
||||||
|
|
||||||
|
/// inserts NEW_NODE before NEXT_NODE in LLIST
|
||||||
|
void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node);
|
||||||
|
|
||||||
|
/// inserts NEW_NODE after PREV_NODE in LLIST
|
||||||
|
void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node);
|
||||||
|
|
||||||
|
/// removes node before NEXT_NODE in LLIST
|
||||||
|
/// if FREE_REMOVED then frees removed node
|
||||||
|
#define LinkedList_removePrev(LLIST, NEXT_NODE, FREE_REMOVED) LLIST->_functions->removePrev(LLIST, NEXT_NODE, FREE_REMOVED)
|
||||||
|
|
||||||
|
/// removes node after PREV_NODE in LLIST
|
||||||
|
/// if FREE_REMOVED then frees removed node
|
||||||
|
#define LinkedList_removeNext(LLIST, PREV_NODE, FREE_REMOVED) LLIST->_functions->removeNext(LLIST, PREV_NODE, FREE_REMOVED)
|
||||||
|
|
||||||
|
///@param FIRST_N first node in enumeration
|
||||||
|
///@param CURR_N name of iteration variable
|
||||||
|
///@param CODE code todo in every iteration
|
||||||
|
#define LLNode_foreach(FIRST_N, CURR_N, CODE...) { \
|
||||||
|
typeof(FIRST_N) CURR_N=FIRST_N; \
|
||||||
|
typeof(FIRST_N) NEXT_N=FIRST_N; \
|
||||||
|
while(CURR_N!=NULL) { \
|
||||||
|
NEXT_N=CURR_N->next; \
|
||||||
|
CODE; \
|
||||||
|
CURR_N=NEXT_N; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
///@param FIRST_N first node in enumeration
|
||||||
|
///@param CURR_N name of iteration variable
|
||||||
|
///@param CODE code todo in every iteration
|
||||||
|
#define LLNode_foreachReverse(FIRST_N, CURR_N, CODE...) { \
|
||||||
|
typeof(FIRST_N) CURR_N=FIRST_N; \
|
||||||
|
typeof(FIRST_N) PREV_N=FIRST_N; \
|
||||||
|
while(CURR_N!=NULL) { \
|
||||||
|
PREV_N=CURR_N->prev; \
|
||||||
|
CODE; \
|
||||||
|
CURR_N=PREV_N; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
///@param LLIST LinkedList
|
||||||
|
///@param CURR_N name of iteration variable
|
||||||
|
///@param CODE code todo in every iteration
|
||||||
|
#define LinkedList_foreach(LLIST, CURR_N, CODE...) \
|
||||||
|
LLNode_foreach(LLIST->first_node, CURR_N, CODE)
|
||||||
|
|
||||||
|
///@param LLIST LinkedList
|
||||||
|
///@param CURR_N name of iteration variable
|
||||||
|
///@param CODE code todo in every iteration
|
||||||
|
#define LinkedList_foreachReverse(LLIST, CURR_N, CODE...) \
|
||||||
|
LLNode_foreachReverse(LLIST->last_node, CURR_N, CODE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LinkedList_declare(Pointer)
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
42
src/LinkedList/LinkedList_declare.h
Normal file
42
src/LinkedList/LinkedList_declare.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LLNode_declare(TYPE)\
|
||||||
|
STRUCT(LLNode(TYPE), \
|
||||||
|
LLNode(TYPE)* prev; \
|
||||||
|
LLNode(TYPE)* next; \
|
||||||
|
TYPE value; \
|
||||||
|
) \
|
||||||
|
\
|
||||||
|
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \
|
||||||
|
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value);
|
||||||
|
|
||||||
|
|
||||||
|
#define LinkedList_declare(TYPE)\
|
||||||
|
LLNode_declare(TYPE) \
|
||||||
|
typedef struct LinkedList_##TYPE##_functions_t LinkedList_##TYPE##_functions_t; \
|
||||||
|
\
|
||||||
|
STRUCT(LinkedList(TYPE), \
|
||||||
|
LinkedList_##TYPE##_functions_t* _functions; \
|
||||||
|
LLNode(TYPE)* first_node; \
|
||||||
|
LLNode(TYPE)* last_node; \
|
||||||
|
u32 count; \
|
||||||
|
) \
|
||||||
|
\
|
||||||
|
typedef struct LinkedList_##TYPE##_functions_t { \
|
||||||
|
freeMembers_t freeMembers; \
|
||||||
|
void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \
|
||||||
|
void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \
|
||||||
|
} LinkedList_##TYPE##_functions_t; \
|
||||||
|
\
|
||||||
|
extern LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions; \
|
||||||
|
\
|
||||||
|
LinkedList(TYPE)* LinkedList_##TYPE##_create(); \
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
82
src/LinkedList/LinkedList_define.h
Normal file
82
src/LinkedList/LinkedList_define.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LLNode_define(TYPE, TYPE_IS_PTR)\
|
||||||
|
\
|
||||||
|
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value){ \
|
||||||
|
LLNode(TYPE)* node= (LLNode(TYPE)*)malloc(sizeof(*node)); \
|
||||||
|
node->prev=NULL; \
|
||||||
|
node->next=NULL; \
|
||||||
|
node->value=value; \
|
||||||
|
return node; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void LLNode_##TYPE##_freeMembers(void* _node){ \
|
||||||
|
LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \
|
||||||
|
void* value_ptr=&node->value; \
|
||||||
|
if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \
|
||||||
|
ktDescriptor_##TYPE.freeMembers(value_ptr); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \
|
||||||
|
if(free_value) LLNode_##TYPE##_freeMembers(node); \
|
||||||
|
free(node); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
kt_define(LLNode_##TYPE, LLNode_##TYPE##_freeMembers, NULL)
|
||||||
|
|
||||||
|
|
||||||
|
#define LinkedList_define(TYPE, VALUE_IS_PTR)\
|
||||||
|
LLNode_define(TYPE, VALUE_IS_PTR) \
|
||||||
|
\
|
||||||
|
LinkedList(TYPE)* LinkedList_##TYPE##_create(){ \
|
||||||
|
LinkedList(TYPE)* l=malloc(sizeof(*l)); \
|
||||||
|
l->_functions=&_LinkedList_##TYPE##_functions; \
|
||||||
|
l->first_node=NULL; \
|
||||||
|
l->last_node=NULL; \
|
||||||
|
l->count=0; \
|
||||||
|
return l; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void LinkedList_##TYPE##_freeMembers(void* _l){ \
|
||||||
|
LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \
|
||||||
|
if(l->first_node!=NULL) \
|
||||||
|
LinkedList_foreach(l, node, LLNode_##TYPE##_free(node, true)); \
|
||||||
|
l->first_node=NULL; l->last_node=NULL; l->count=0; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved){ \
|
||||||
|
llist->count--; \
|
||||||
|
LLNode(TYPE)* removedNode=nextNode->prev; \
|
||||||
|
LLNode(TYPE)* prevNode=removedNode->prev; \
|
||||||
|
nextNode->prev=prevNode; \
|
||||||
|
prevNode->next=nextNode; \
|
||||||
|
if(freeRemoved) \
|
||||||
|
LLNode_##TYPE##_free(removedNode, true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \
|
||||||
|
llist->count--; \
|
||||||
|
LLNode(TYPE)* removedNode=prevNode->next; \
|
||||||
|
LLNode(TYPE)* nextNode=removedNode->next; \
|
||||||
|
prevNode->next=nextNode; \
|
||||||
|
nextNode->prev=prevNode; \
|
||||||
|
if(freeRemoved) \
|
||||||
|
LLNode_##TYPE##_free(removedNode, true); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \
|
||||||
|
.freeMembers=LinkedList_##TYPE##_freeMembers, \
|
||||||
|
.removePrev=LinkedList_##TYPE##_removePrev, \
|
||||||
|
.removeNext=LinkedList_##TYPE##_removeNext \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_freeMembers, NULL)
|
||||||
|
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -6,11 +6,11 @@ ktid_define(knIPV4Endpoint);
|
|||||||
Maybe knIPV4Address_fromStr(char* addrStr){
|
Maybe knIPV4Address_fromStr(char* addrStr){
|
||||||
char* addrStr_src=addrStr;
|
char* addrStr_src=addrStr;
|
||||||
char* errmsg_extra="wrong char";
|
char* errmsg_extra="wrong char";
|
||||||
uint8 c;
|
u8 c;
|
||||||
knIPV4Address addr;
|
knIPV4Address addr;
|
||||||
addr.u32=0;
|
addr.u32=0;
|
||||||
uint16 n=0;
|
u16 n=0;
|
||||||
for(uint8 i=0; i<4; ){
|
for(u8 i=0; i<4; ){
|
||||||
c=*addrStr++;
|
c=*addrStr++;
|
||||||
switch (c){
|
switch (c){
|
||||||
case '\0':
|
case '\0':
|
||||||
@@ -18,6 +18,10 @@ Maybe knIPV4Address_fromStr(char* addrStr){
|
|||||||
errmsg_extra="end of string";
|
errmsg_extra="end of string";
|
||||||
goto default_case;
|
goto default_case;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addr.bytes[i++]=n;
|
||||||
|
n=0;
|
||||||
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
addr.bytes[i++]=n;
|
addr.bytes[i++]=n;
|
||||||
n=0;
|
n=0;
|
||||||
@@ -32,7 +36,7 @@ Maybe knIPV4Address_fromStr(char* addrStr){
|
|||||||
break;
|
break;
|
||||||
default_case:
|
default_case:
|
||||||
default:
|
default:
|
||||||
uint32 errmsgL=cptr_length(addrStr) + 80;
|
u32 errmsgL=cptr_length(addrStr) + 80;
|
||||||
char* errmsg=malloc(errmsgL);
|
char* errmsg=malloc(errmsgL);
|
||||||
IFMSC(sprintf_s(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra),
|
IFMSC(sprintf_s(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra),
|
||||||
sprintf( errmsg, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra));
|
sprintf( errmsg, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra));
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ extern "C" {
|
|||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
|
||||||
|
|
||||||
typedef uint16 knPort;
|
typedef u16 knPort;
|
||||||
|
|
||||||
typedef union knIPV4Address {
|
typedef union knIPV4Address {
|
||||||
uint32 u32;
|
u32 u32;
|
||||||
char bytes[4];
|
char bytes[4];
|
||||||
} knIPV4Address;
|
} knIPV4Address;
|
||||||
ktid_declare(knIPV4Address);
|
ktid_declare(knIPV4Address);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ knChannel* __createChannel(){
|
|||||||
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
|
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
|
||||||
if(socket->channelsAmount == 65535)
|
if(socket->channelsAmount == 65535)
|
||||||
safethrow("max amount of channels",;);
|
safethrow("max amount of channels",;);
|
||||||
uint16 channelsAmountPrev=socket->channelsAmount;
|
u16 channelsAmountPrev=socket->channelsAmount;
|
||||||
socket->channelsAmount++;
|
socket->channelsAmount++;
|
||||||
if(channelsAmountPrev==0)
|
if(channelsAmountPrev==0)
|
||||||
socket->channels=malloc(sizeof(knChannel*));
|
socket->channels=malloc(sizeof(knChannel*));
|
||||||
@@ -54,6 +54,6 @@ Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remote
|
|||||||
|
|
||||||
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
||||||
|
|
||||||
Maybe knSocketChanneled_send(knSocketChanneled* socket, uint16 destinationIndex, uint8* data, uint32 dataLength);
|
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||||
|
|
||||||
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength);
|
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
|
||||||
@@ -7,7 +7,7 @@ extern "C" {
|
|||||||
#include "../../base/base.h"
|
#include "../../base/base.h"
|
||||||
#include "../knAddress.h"
|
#include "../knAddress.h"
|
||||||
|
|
||||||
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(uint8*))
|
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(u8*))
|
||||||
|
|
||||||
|
|
||||||
typedef enum __attribute__((__packed__)) knPacVersion {
|
typedef enum __attribute__((__packed__)) knPacVersion {
|
||||||
@@ -19,11 +19,11 @@ static const char knPacHeader[5]={'k','n','p','a','c'};
|
|||||||
typedef struct knPackage {
|
typedef struct knPackage {
|
||||||
char header[5]; // knpac
|
char header[5]; // knpac
|
||||||
knPacVersion version; // protocol version
|
knPacVersion version; // protocol version
|
||||||
uint16 data_size; // size of data block in bytes (1-KNPAC_MAX_DATA_SIZE)
|
u16 data_size; // size of data block in bytes (1-KNPAC_MAX_DATA_SIZE)
|
||||||
uint32 channel_id; // id of knChannel in socket
|
u32 channel_id; // id of knChannel in socket
|
||||||
uint32 package_num; // number in sequence of sent packages
|
u32 package_num; // number in sequence of sent packages
|
||||||
uint64 data_hash; // hash64 of data
|
u64 data_hash; // hash64 of data
|
||||||
uint8* data; // ptr to data
|
u8* data; // ptr to data
|
||||||
} knPackage;
|
} knPackage;
|
||||||
ktid_declare(knPackage);
|
ktid_declare(knPackage);
|
||||||
|
|
||||||
@@ -41,10 +41,10 @@ typedef struct knChannel {
|
|||||||
ktid_declare(knChannel);
|
ktid_declare(knChannel);
|
||||||
|
|
||||||
typedef struct knSocketChanneled{
|
typedef struct knSocketChanneled{
|
||||||
int64 socketfd;
|
i64 socketfd;
|
||||||
knIPV4Endpoint localEndpoint;
|
knIPV4Endpoint localEndpoint;
|
||||||
knIPV4Endpoint remoteEndpoint;
|
knIPV4Endpoint remoteEndpoint;
|
||||||
uint16 channelsAmount;
|
u16 channelsAmount;
|
||||||
knChannel** channels;
|
knChannel** channels;
|
||||||
} knSocketChanneled;
|
} knSocketChanneled;
|
||||||
ktid_declare(knSocketChanneled);
|
ktid_declare(knSocketChanneled);
|
||||||
@@ -56,7 +56,7 @@ Maybe knSocketChanneled_open();
|
|||||||
///@return Maybe<void> error or nothing
|
///@return Maybe<void> error or nothing
|
||||||
Maybe knSocketChanneled_close(knSocketChanneled* socket);
|
Maybe knSocketChanneled_close(knSocketChanneled* socket);
|
||||||
|
|
||||||
///@return Maybe<uint64> channel index
|
///@return Maybe<u64> channel index
|
||||||
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket);
|
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket);
|
||||||
|
|
||||||
///start listening at local endpoint
|
///start listening at local endpoint
|
||||||
@@ -72,12 +72,12 @@ Maybe knSocketChanneled_accept(knSocketChanneled* socket);
|
|||||||
|
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketChanneled_send(knSocketChanneled* socket, uint16 destinationIndex, uint8* data, uint32 dataLength);
|
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
|
||||||
|
|
||||||
///@param buffer buffer for recieving data
|
///@param buffer buffer for recieving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<uint64> recieved bytes amount
|
///@return Maybe<u64> recieved bytes amount
|
||||||
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength);
|
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
|
|||||||
|
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength);
|
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
|
||||||
|
|
||||||
///@param buffer buffer for recieving data
|
///@param buffer buffer for recieving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<uint64> recieved bytes amount
|
///@return Maybe<u64> recieved bytes amount
|
||||||
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength);
|
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ extern "C" {
|
|||||||
#include "../knAddress.h"
|
#include "../knAddress.h"
|
||||||
|
|
||||||
typedef struct knSocketTCP {
|
typedef struct knSocketTCP {
|
||||||
int64 socketfd;
|
i64 socketfd;
|
||||||
knIPV4Endpoint localEndpoint;
|
knIPV4Endpoint localEndpoint;
|
||||||
knIPV4Endpoint remoteEndpoint;
|
knIPV4Endpoint remoteEndpoint;
|
||||||
} knSocketTCP;
|
} knSocketTCP;
|
||||||
@@ -33,12 +33,12 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
|
|||||||
|
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength);
|
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
|
||||||
|
|
||||||
///@param buffer buffer for recieving data
|
///@param buffer buffer for recieving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<uint64> recieved bytes amount
|
///@return Maybe<u64> recieved bytes amount
|
||||||
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength);
|
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, u32 bufferLength);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ Maybe knSocketUDP_accept(knSocketUDP* socket);
|
|||||||
|
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination);
|
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||||
|
|
||||||
///@param buffer buffer for recieving data
|
///@param buffer buffer for recieving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<uint64> recieved bytes amount
|
///@return Maybe<u64> recieved bytes amount
|
||||||
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength);
|
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ extern "C" {
|
|||||||
#include "knSocketUDP.h"
|
#include "knSocketUDP.h"
|
||||||
|
|
||||||
typedef struct knSocketUDP {
|
typedef struct knSocketUDP {
|
||||||
int64 socketfd;
|
i64 socketfd;
|
||||||
knIPV4Endpoint localEndpoint;
|
knIPV4Endpoint localEndpoint;
|
||||||
} knSocketUDP;
|
} knSocketUDP;
|
||||||
ktid_declare(knSocketUDP);
|
ktid_declare(knSocketUDP);
|
||||||
@@ -27,12 +27,12 @@ Maybe knSocketUDP_accept(knSocketUDP* socket);
|
|||||||
|
|
||||||
///@param dataLength 0-4294967295
|
///@param dataLength 0-4294967295
|
||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination);
|
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
|
||||||
|
|
||||||
///@param buffer buffer for recieving data
|
///@param buffer buffer for recieving data
|
||||||
///@param bufferLength 0-4294967295
|
///@param bufferLength 0-4294967295
|
||||||
///@return Maybe<uint64> recieved bytes amount
|
///@return Maybe<u64> recieved bytes amount
|
||||||
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength);
|
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, u32 bufferLength);
|
||||||
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
#include "SearchTree.h"
|
#include "SearchTree.h"
|
||||||
|
|
||||||
ktid_define(STNode);
|
kt_define(STNode, __STNode_free, NULL);
|
||||||
|
|
||||||
STNode* STNode_create(){
|
STNode* STNode_create(){
|
||||||
STNode* node=malloc(sizeof(STNode));
|
STNode* node=malloc(sizeof(STNode));
|
||||||
node->branches=NULL;
|
node->branches=NULL;
|
||||||
node->value.typeId=ktid_Null;
|
node->value=UniNull;
|
||||||
node->value.UInt64=0;
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14,13 +13,13 @@ void __STNode_free(void* _node){
|
|||||||
STNode* node=_node;
|
STNode* node=_node;
|
||||||
if (!node) throw(ERR_NULLPTR);
|
if (!node) throw(ERR_NULLPTR);
|
||||||
if(node->branches){
|
if(node->branches){
|
||||||
for(uint8 n32 = 0;n32<8;n32++){
|
for(u8 n32 = 0;n32<8;n32++){
|
||||||
STNode*** ptrn32=(STNode***)node->branches[n32];
|
STNode*** ptrn32=(STNode***)node->branches[n32];
|
||||||
if(ptrn32){
|
if(ptrn32){
|
||||||
for(uint8 n4 = 0;n4<8;n4++){
|
for(u8 n4 = 0;n4<8;n4++){
|
||||||
STNode** ptrn4=ptrn32[n4];
|
STNode** ptrn4=ptrn32[n4];
|
||||||
if (ptrn4){
|
if (ptrn4){
|
||||||
for(uint8 rem=0;rem<4;rem++){
|
for(u8 rem=0;rem<4;rem++){
|
||||||
STNode* ptrrem=ptrn4[rem];
|
STNode* ptrrem=ptrn4[rem];
|
||||||
if(ptrrem)
|
if(ptrrem)
|
||||||
STNode_free(ptrrem);
|
STNode_free(ptrrem);
|
||||||
@@ -41,9 +40,9 @@ void STNode_free(STNode* node){
|
|||||||
free(node);
|
free(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {uint8 n32, n4, rem;} indexes3;
|
typedef struct {u8 n32, n4, rem;} indexes3;
|
||||||
|
|
||||||
indexes3 splitindex(uint8 i){
|
indexes3 splitindex(u8 i){
|
||||||
return (indexes3){
|
return (indexes3){
|
||||||
.n32=i/32,
|
.n32=i/32,
|
||||||
.n4=i%32/4,
|
.n4=i%32/4,
|
||||||
@@ -60,20 +59,20 @@ void ST_pushString(STNode* node_first, string key, Unitype value){
|
|||||||
if (!node_first) throw(ERR_NULLPTR);
|
if (!node_first) throw(ERR_NULLPTR);
|
||||||
STNode* node_last=node_first;
|
STNode* node_last=node_first;
|
||||||
while(key.length--){
|
while(key.length--){
|
||||||
indexes3 i3=splitindex((uint8)*key.ptr);
|
indexes3 i3=splitindex((u8)*key.ptr);
|
||||||
if(!node_last->branches){
|
if(!node_last->branches){
|
||||||
node_last->branches=(STNode****)malloc(8*sizeof(STNode***));
|
node_last->branches=(STNode****)malloc(8*sizeof(STNode***));
|
||||||
for(uint8 i=0;i<8;i++)
|
for(u8 i=0;i<8;i++)
|
||||||
node_last->branches[i]=(STNode***)NULL;
|
node_last->branches[i]=(STNode***)NULL;
|
||||||
}
|
}
|
||||||
if(!node_last->branches[i3.n32]){
|
if(!node_last->branches[i3.n32]){
|
||||||
node_last->branches[i3.n32]=(STNode***)malloc(8*sizeof(STNode**));
|
node_last->branches[i3.n32]=(STNode***)malloc(8*sizeof(STNode**));
|
||||||
for(uint8 i=0;i<8;i++)
|
for(u8 i=0;i<8;i++)
|
||||||
node_last->branches[i3.n32][i]=(STNode**)NULL;
|
node_last->branches[i3.n32][i]=(STNode**)NULL;
|
||||||
}
|
}
|
||||||
if(!node_last->branches[i3.n32][i3.n4]){
|
if(!node_last->branches[i3.n32][i3.n4]){
|
||||||
node_last->branches[i3.n32][i3.n4]=(STNode**)malloc(4*sizeof(STNode*));
|
node_last->branches[i3.n32][i3.n4]=(STNode**)malloc(4*sizeof(STNode*));
|
||||||
for(uint8 i=0;i<4;i++)
|
for(u8 i=0;i<4;i++)
|
||||||
node_last->branches[i3.n32][i3.n4][i]=(STNode*)NULL;
|
node_last->branches[i3.n32][i3.n4][i]=(STNode*)NULL;
|
||||||
}
|
}
|
||||||
if(!node_last->branches[i3.n32][i3.n4][i3.rem])
|
if(!node_last->branches[i3.n32][i3.n4][i3.rem])
|
||||||
@@ -93,7 +92,7 @@ Unitype ST_pullString(STNode* node_first, string key){
|
|||||||
if (!node_first) throw(ERR_NULLPTR);
|
if (!node_first) throw(ERR_NULLPTR);
|
||||||
STNode* node_last=node_first;
|
STNode* node_last=node_first;
|
||||||
while (key.length--){
|
while (key.length--){
|
||||||
indexes3 i3=splitindex((uint8)*key.ptr);
|
indexes3 i3=splitindex((u8)*key.ptr);
|
||||||
if(!node_last->branches) return UniNull;
|
if(!node_last->branches) return UniNull;
|
||||||
STNode*** ptrn32=(STNode***)node_last->branches[i3.n32];
|
STNode*** ptrn32=(STNode***)node_last->branches[i3.n32];
|
||||||
if(!ptrn32) return UniNull;
|
if(!ptrn32) return UniNull;
|
||||||
|
|||||||
@@ -7,11 +7,10 @@ extern "C" {
|
|||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
#include "../String/string.h"
|
#include "../String/string.h"
|
||||||
|
|
||||||
typedef struct SearchTreeNode{
|
STRUCT(STNode,
|
||||||
struct SearchTreeNode**** branches; // *STNode[8][8][4]
|
struct STNode**** branches; // *STNode[8][8][4]
|
||||||
Unitype value;
|
Unitype value;
|
||||||
} STNode;
|
)
|
||||||
ktid_declare(STNode);
|
|
||||||
|
|
||||||
STNode* STNode_create();
|
STNode* STNode_create();
|
||||||
void STNode_free(STNode* node);
|
void STNode_free(STNode* node);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "StringBuilder.h"
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
Autoarr_define(string)
|
kt_define(StringBuilder, __StringBuilder_free, NULL);
|
||||||
|
|
||||||
ktid_define(StringBuilder);
|
|
||||||
|
|
||||||
#define BL_C 32
|
#define BL_C 32
|
||||||
#define BL_L 1024
|
#define BL_L 1024
|
||||||
@@ -11,16 +9,16 @@ ktid_define(StringBuilder);
|
|||||||
void complete_buf(StringBuilder* b){
|
void complete_buf(StringBuilder* b){
|
||||||
if(!b->compl_bufs)
|
if(!b->compl_bufs)
|
||||||
b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
|
b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
|
||||||
uint32 len=Autoarr_length(b->curr_buf);
|
u32 len=Autoarr_length(b->curr_buf);
|
||||||
if(!len) return;
|
if(!len) return;
|
||||||
string str={.length=len, .ptr=malloc(len)};
|
string str={.length=len, .ptr=malloc(len)};
|
||||||
uint32 i=0;
|
u32 i=0;
|
||||||
Autoarr_foreach(b->curr_buf, c, ({
|
Autoarr_foreach(b->curr_buf, c,
|
||||||
str.ptr[i++]=c;
|
str.ptr[i++]=c;
|
||||||
}));
|
);
|
||||||
Autoarr_add(b->compl_bufs,str);
|
Autoarr_add(b->compl_bufs,str);
|
||||||
Autoarr_free(b->curr_buf, true);
|
Autoarr_free(b->curr_buf, true);
|
||||||
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
|
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void try_complete_buf(StringBuilder* b){
|
void try_complete_buf(StringBuilder* b){
|
||||||
@@ -32,7 +30,7 @@ void try_complete_buf(StringBuilder* b){
|
|||||||
StringBuilder* StringBuilder_create(){
|
StringBuilder* StringBuilder_create(){
|
||||||
StringBuilder* b=malloc(sizeof(StringBuilder));
|
StringBuilder* b=malloc(sizeof(StringBuilder));
|
||||||
b->compl_bufs=NULL;
|
b->compl_bufs=NULL;
|
||||||
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
|
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,18 +46,18 @@ void StringBuilder_free(StringBuilder* b){
|
|||||||
|
|
||||||
string StringBuilder_build(StringBuilder* b){
|
string StringBuilder_build(StringBuilder* b){
|
||||||
complete_buf(b);
|
complete_buf(b);
|
||||||
uint32 len=0;
|
u32 len=0;
|
||||||
Autoarr_foreach(b->compl_bufs, cs, ({
|
Autoarr_foreach(b->compl_bufs, cs,
|
||||||
len+=cs.length;
|
len+=cs.length;
|
||||||
}));
|
);
|
||||||
string str= { .length=len, .ptr=malloc(len+1) };
|
string str= { .length=len, .ptr=malloc(len+1) };
|
||||||
str.ptr[len]='\0';
|
str.ptr[len]='\0';
|
||||||
uint32 i=0;
|
u32 i=0;
|
||||||
Autoarr_foreach(b->compl_bufs, cs, ({
|
Autoarr_foreach(b->compl_bufs, cs,
|
||||||
for(uint32 n=0;n<cs.length;n++)
|
for(u32 n=0;n<cs.length;n++)
|
||||||
str.ptr[i++]=cs.ptr[n];
|
str.ptr[i++]=cs.ptr[n];
|
||||||
free(cs.ptr);
|
free(cs.ptr);
|
||||||
}));
|
);
|
||||||
StringBuilder_free(b);
|
StringBuilder_free(b);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
@@ -70,7 +68,7 @@ void StringBuilder_rmchar(StringBuilder* b){
|
|||||||
Autoarr_pop(b->curr_buf)
|
Autoarr_pop(b->curr_buf)
|
||||||
else {
|
else {
|
||||||
if(!b->compl_bufs) throw(ERR_NULLPTR);
|
if(!b->compl_bufs) throw(ERR_NULLPTR);
|
||||||
string* lastcb=Autoarr_getptr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
|
string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
|
||||||
lastcb->length--;
|
lastcb->length--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,13 +94,13 @@ void StringBuilder_append_cptr(StringBuilder* b, char* s){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void curr_buf_add_string(StringBuilder* b, string s){
|
void curr_buf_add_string(StringBuilder* b, string s){
|
||||||
for(uint32 i=0; i<s.length; i++)
|
for(u32 i=0; i<s.length; i++)
|
||||||
Autoarr_add(b->curr_buf,s.ptr[i]);
|
Autoarr_add(b->curr_buf,s.ptr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringBuilder_append_int64(StringBuilder* b, int64 a){
|
void StringBuilder_append_i64(StringBuilder* b, i64 a){
|
||||||
try_complete_buf(b);
|
try_complete_buf(b);
|
||||||
uint8 i=0;
|
u8 i=0;
|
||||||
if(a==0){
|
if(a==0){
|
||||||
Autoarr_add(b->curr_buf,'0');
|
Autoarr_add(b->curr_buf,'0');
|
||||||
return;
|
return;
|
||||||
@@ -121,9 +119,9 @@ void StringBuilder_append_int64(StringBuilder* b, int64 a){
|
|||||||
free(rev.ptr);
|
free(rev.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
|
void StringBuilder_append_u64(StringBuilder* b, u64 a){
|
||||||
try_complete_buf(b);
|
try_complete_buf(b);
|
||||||
uint8 i=0;
|
u8 i=0;
|
||||||
if(a==0){
|
if(a==0){
|
||||||
Autoarr_add(b->curr_buf,'0');
|
Autoarr_add(b->curr_buf,'0');
|
||||||
return;
|
return;
|
||||||
@@ -138,7 +136,7 @@ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
|
|||||||
free(rev.ptr);
|
free(rev.ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StringBuilder_append_float64(StringBuilder* b, double a){
|
void StringBuilder_append_f64(StringBuilder* b, f64 a){
|
||||||
try_complete_buf(b);
|
try_complete_buf(b);
|
||||||
char buf[32];
|
char buf[32];
|
||||||
IFMSC(
|
IFMSC(
|
||||||
|
|||||||
@@ -7,13 +7,10 @@ extern "C" {
|
|||||||
#include "../Autoarr/Autoarr.h"
|
#include "../Autoarr/Autoarr.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
Autoarr_declare(string)
|
STRUCT(StringBuilder,
|
||||||
|
|
||||||
typedef struct StringBuilder{
|
|
||||||
Autoarr(string)* compl_bufs;
|
Autoarr(string)* compl_bufs;
|
||||||
Autoarr(int8)* curr_buf;
|
Autoarr(i8)* curr_buf;
|
||||||
} StringBuilder;
|
)
|
||||||
ktid_declare(StringBuilder);
|
|
||||||
|
|
||||||
StringBuilder* StringBuilder_create(void);
|
StringBuilder* StringBuilder_create(void);
|
||||||
void StringBuilder_free(StringBuilder* b);
|
void StringBuilder_free(StringBuilder* b);
|
||||||
@@ -28,9 +25,9 @@ void StringBuilder_rmchar(StringBuilder* b);
|
|||||||
void StringBuilder_append_char(StringBuilder* b, char c);
|
void StringBuilder_append_char(StringBuilder* b, char c);
|
||||||
void StringBuilder_append_cptr(StringBuilder* b, char* s);
|
void StringBuilder_append_cptr(StringBuilder* b, char* s);
|
||||||
void StringBuilder_append_string(StringBuilder* b, string s);
|
void StringBuilder_append_string(StringBuilder* b, string s);
|
||||||
void StringBuilder_append_int64(StringBuilder* b, int64 a);
|
void StringBuilder_append_i64(StringBuilder* b, i64 a);
|
||||||
void StringBuilder_append_uint64(StringBuilder* b, uint64 a);
|
void StringBuilder_append_u64(StringBuilder* b, u64 a);
|
||||||
void StringBuilder_append_float64(StringBuilder* b, double a);
|
void StringBuilder_append_f64(StringBuilder* b, f64 a);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
ktid_define(string);
|
kt_define(string, NULL, NULL);
|
||||||
|
Array_define(string)
|
||||||
|
Autoarr_define(string, false)
|
||||||
|
|
||||||
// copies str content to new char pointer value (adding '\0' at the end)
|
// copies str content to new char pointer value (adding '\0' at the end)
|
||||||
char* string_extract(string str){
|
char* string_extract(string str){
|
||||||
@@ -12,14 +14,16 @@ char* string_extract(string str){
|
|||||||
return cptr;
|
return cptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// copies src.ptr content to new string
|
// copies src.ptr content to new string and adds \0 at the end
|
||||||
string string_copy(string src){
|
string string_copy(string src){
|
||||||
if(!src.ptr) return src;
|
if(!src.ptr)
|
||||||
|
return src;
|
||||||
string nstr;
|
string nstr;
|
||||||
nstr.length=src.length;
|
nstr.length=src.length;
|
||||||
nstr.ptr=malloc(nstr.length);
|
nstr.ptr=malloc(nstr.length+1);
|
||||||
for(uint32 i=0;i<nstr.length;i++)
|
for(u32 i=0;i<nstr.length;i++)
|
||||||
nstr.ptr[i]=src.ptr[i];
|
nstr.ptr[i]=src.ptr[i];
|
||||||
|
nstr.ptr[nstr.length]='\0';
|
||||||
return nstr;
|
return nstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +42,7 @@ bool string_compare(string str0, string str1){
|
|||||||
string string_reverse(string s){
|
string string_reverse(string s){
|
||||||
if(s.length==0) return s;
|
if(s.length==0) return s;
|
||||||
string r={malloc(s.length), s.length};
|
string r={malloc(s.length), s.length};
|
||||||
for(uint32 i=0; i<s.length; i++)
|
for(u32 i=0; i<s.length; i++)
|
||||||
r.ptr[i]=s.ptr[s.length-i-1];
|
r.ptr[i]=s.ptr[s.length-i-1];
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,28 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
|
#include "../Array/Array.h"
|
||||||
|
#include "../Autoarr/Autoarr.h"
|
||||||
|
|
||||||
// my fixed length string struct
|
// my fixed length string struct
|
||||||
// doesn't store '\0' at the end
|
// doesn't store '\0' at the end
|
||||||
typedef struct string{
|
STRUCT(string,
|
||||||
char* ptr; // char pointer
|
char* ptr; // char pointer
|
||||||
uint64 length; // amount of chars in ptr value
|
u64 length; // amount of chars in ptr value
|
||||||
} string;
|
)
|
||||||
ktid_declare(string);
|
|
||||||
|
Array_declare(string)
|
||||||
|
Autoarr_declare(string)
|
||||||
|
|
||||||
static const string stringNull={NULL,0};
|
static const string stringNull={NULL,0};
|
||||||
|
|
||||||
|
/// wraps pointer without copy
|
||||||
|
#define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) }
|
||||||
|
|
||||||
// copies str content to new char pointer value (adding '\0' at the end)
|
// copies str content to new char pointer value (adding '\0' at the end)
|
||||||
char* string_extract(string str);
|
char* string_extract(string str);
|
||||||
|
|
||||||
// copies src.ptr content to new string
|
// copies src.ptr content to new string and adds \0 at the end
|
||||||
string string_copy(string src);
|
string string_copy(string src);
|
||||||
|
|
||||||
// compares two strings, NullPtr-friendly
|
// compares two strings, NullPtr-friendly
|
||||||
|
|||||||
201
src/base/cptr.c
201
src/base/cptr.c
@@ -1,33 +1,26 @@
|
|||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
// returns length of char buffer (without \0)
|
// returns length of char buffer (without \0)
|
||||||
uint32 cptr_length(char* str){
|
u32 cptr_length(const char* str){
|
||||||
uint32 len=0;
|
const char *const str_first=str;
|
||||||
while(*(str++)) len++;
|
while(*str)
|
||||||
return len;
|
str++;
|
||||||
|
return str-str_first;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocates new char[] and copies src there
|
// allocates new char[] and copies src there
|
||||||
char* cptr_copy(char* src){
|
char* cptr_copy(const char* src){
|
||||||
uint32 len=cptr_length(src)+1;
|
u32 len=cptr_length(src)+1;
|
||||||
char* dst=malloc(len);
|
char* dst=malloc(len);
|
||||||
while(len--!=0)
|
while(len--!=0)
|
||||||
dst[len]=src[len];
|
dst[len]=src[len];
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compares two char buffers, NullPtr-friendly
|
|
||||||
bool cptr_compare(char* key0, char* key1){
|
|
||||||
if(!key0) return key1 ? false : true;
|
|
||||||
if(!key1) return false;
|
|
||||||
while(*key0&&*key1)
|
|
||||||
if(*key0++ != *key1++)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// multiplies char n times
|
// multiplies char n times
|
||||||
char* char_multiply(char c, uint32 n){
|
char* char_multiply(char c, u32 n){
|
||||||
char* rez=malloc(n+1);
|
char* rez=malloc(n+1);
|
||||||
rez[n]=0;
|
rez[n]=0;
|
||||||
while(n--!=0)
|
while(n--!=0)
|
||||||
@@ -35,50 +28,127 @@ char* char_multiply(char c, uint32 n){
|
|||||||
return rez;
|
return rez;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cptr_startsWith(char* ptr, char* fragment){
|
bool cptr_equals(const char* key0, const char* key1){
|
||||||
for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
|
char c0=*key0;
|
||||||
if(cs!=cf) return false;
|
char c1=*key1;
|
||||||
return true;
|
bool eq=c0==c1;
|
||||||
|
while(c0 && c1 && eq) {
|
||||||
|
c0=*++key0;
|
||||||
|
c1=*++key1;
|
||||||
|
eq=c0==c1;
|
||||||
|
}
|
||||||
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cptr_endsWith(char* ptr, char* fragment){
|
bool cptr_startsWith(const char* src, const char* fragment){
|
||||||
ptr+=cptr_length(ptr)-cptr_length(fragment);
|
char c0=*src;
|
||||||
for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
|
char c1=*fragment;
|
||||||
if(cs!=cf) return false;
|
bool eq=c0==c1 && c0 !=0 && c1!=0;
|
||||||
return true;
|
while(c0 && c1 && eq) {
|
||||||
|
c0=*++src;
|
||||||
|
c1=*++fragment;
|
||||||
|
eq=c0==c1;
|
||||||
|
if(c1==0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return eq;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 cptr_indexOf(char* ptr, char* fragment){
|
bool cptr_endsWith(const char* src, const char* fragment){
|
||||||
char sc=*ptr;
|
u32 src_len=cptr_length(src);
|
||||||
for(int si=0, fi=0; sc!=0; si++){
|
u32 fr_len=cptr_length(fragment);
|
||||||
sc=ptr[si];
|
if(src_len<fr_len || src_len==0 || fr_len==0)
|
||||||
if(sc==fragment[fi]){
|
return false;
|
||||||
fi++;
|
src+=src_len-fr_len;
|
||||||
if(fragment[fi]==0)
|
return cptr_equals(src, fragment);
|
||||||
return si-fi+1;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength){
|
||||||
|
char sc=*src, fc=*fragment;
|
||||||
|
if(sc==0 || fc==0)
|
||||||
|
return -1;
|
||||||
|
u32 fr_start=startIndex;
|
||||||
|
for(u32 si=startIndex; si-startIndex<seekLength && sc!=0; si++){
|
||||||
|
sc=src[si];
|
||||||
|
fc=fragment[si-fr_start];
|
||||||
|
if(fc==0)
|
||||||
|
return fr_start;
|
||||||
|
if(sc!=fc)
|
||||||
|
fr_start++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 cptr_seekReverse(const char* src, const char* fragment, u32 startIndex, u32 seekLength){
|
||||||
|
char sc=*src, fc=*fragment;
|
||||||
|
if(sc==0 || fc==0)
|
||||||
|
return -1;
|
||||||
|
i32 len=cptr_length(src);
|
||||||
|
if(startIndex==(u32)-1)
|
||||||
|
startIndex=len-1;
|
||||||
|
u32 fr_len=cptr_length(fragment);
|
||||||
|
for(u32 si=startIndex; si<(u32)-1 && si!=len-1-seekLength; si--){
|
||||||
|
if(si+1<fr_len)
|
||||||
|
return -1;
|
||||||
|
sc=src[si];
|
||||||
|
fc=fragment[0];
|
||||||
|
u32 fr_start=si;
|
||||||
|
for(u32 fi=0; fc==sc ; fi++){
|
||||||
|
if(fi==fr_len)
|
||||||
|
return fr_start;
|
||||||
|
fc=fragment[fi];
|
||||||
|
sc=src[si--];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memcopy(void* from, void* to, uint32 size){
|
i32 cptr_seekChar(const char* src, char fragment, u32 startIndex, u32 seekLength){
|
||||||
|
char sc=*src;
|
||||||
|
if(sc==0 || fragment==0)
|
||||||
|
return -1;
|
||||||
|
for(u32 si=startIndex; si-startIndex<seekLength && sc!=0; si++){
|
||||||
|
sc=src[si];
|
||||||
|
if(sc==fragment)
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength){
|
||||||
|
char sc=*src;
|
||||||
|
if(sc==0 || fragment==0)
|
||||||
|
return -1;
|
||||||
|
i32 len=cptr_length(src);
|
||||||
|
if(startIndex==(u32)-1)
|
||||||
|
startIndex=len-1;
|
||||||
|
for(u32 si=startIndex; si<(u32)-1 && si!=len-1-seekLength; si--){
|
||||||
|
sc=src[si];
|
||||||
|
if(sc==fragment)
|
||||||
|
return si;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void memcopy(void* from, void* to, u32 size){
|
||||||
if(from==NULL || to==NULL)
|
if(from==NULL || to==NULL)
|
||||||
throw(ERR_NULLPTR);
|
throw(ERR_NULLPTR);
|
||||||
for(uint32 i=0; i<size; i++)
|
for(u32 i=0; i<size; i++)
|
||||||
((char*)to)[i]=((char*)from)[i];
|
((char*)to)[i]=((char*)from)[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
char* __cptr_concat(uint16 n, ...){
|
char* __cptr_concat(u32 n, ...){
|
||||||
char** strs=(char**)malloc(n*sizeof(char*));
|
char** strs=(char**)malloc(n*sizeof(char*));
|
||||||
uint32* lengths=malloc(n*sizeof(uint32));
|
u32* lengths=malloc(n*sizeof(u32));
|
||||||
uint32 totalLength=0;
|
u32 totalLength=0;
|
||||||
|
|
||||||
// reading args from va_list
|
// reading args from va_list
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, n);
|
va_start(vl, n);
|
||||||
for(uint16 i=0; i<n; i++){
|
for(u16 i=0; i<n; i++){
|
||||||
char* str=va_arg(vl,char*);
|
char* str=va_arg(vl,char*);
|
||||||
int16 length=cptr_length(str);
|
i16 length=cptr_length(str);
|
||||||
strs[i]=str;
|
strs[i]=str;
|
||||||
lengths[i]=length;
|
lengths[i]=length;
|
||||||
totalLength+=length;
|
totalLength+=length;
|
||||||
@@ -87,11 +157,11 @@ char* __cptr_concat(uint16 n, ...){
|
|||||||
|
|
||||||
// allocating memory for output value
|
// allocating memory for output value
|
||||||
char* totality=malloc(totalLength+1);
|
char* totality=malloc(totalLength+1);
|
||||||
const char* output=totality;
|
char* output=totality;
|
||||||
totality[totalLength]=0;
|
totality[totalLength]=0;
|
||||||
|
|
||||||
// copying content of all strings to rezult
|
// copying content of all strings to rezult
|
||||||
for(uint16 k=0; k<n; k++){
|
for(u16 k=0; k<n; k++){
|
||||||
memcopy(strs[k], totality, lengths[k]);
|
memcopy(strs[k], totality, lengths[k]);
|
||||||
totality+=lengths[k];
|
totality+=lengths[k];
|
||||||
}
|
}
|
||||||
@@ -100,3 +170,48 @@ char* __cptr_concat(uint16 n, ...){
|
|||||||
free(lengths);
|
free(lengths);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* cptr_toLower(const char* src) {
|
||||||
|
u32 length=cptr_length(src);
|
||||||
|
char *p=malloc(length+1);
|
||||||
|
p[length]=0;
|
||||||
|
for(u32 i=0; i<length; i++)
|
||||||
|
p[i]=tolower(src[i]);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cptr_toUpper(const char* src) {
|
||||||
|
u32 length=cptr_length(src);
|
||||||
|
char *p=malloc(length+1);
|
||||||
|
p[length]=0;
|
||||||
|
for(u32 i=0; i<length; i++)
|
||||||
|
p[i]=toupper(src[i]);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){
|
||||||
|
char* rzlt=cptr_copy(src);
|
||||||
|
for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){
|
||||||
|
if(src[i]==c_old)
|
||||||
|
rzlt[i]=c_new;
|
||||||
|
}
|
||||||
|
return rzlt;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){
|
||||||
|
StringBuilder* sb=StringBuilder_create();
|
||||||
|
const u32 str_old_len=cptr_length(str_old);
|
||||||
|
const u32 str_new_len=cptr_length(str_new);
|
||||||
|
i32 i=startIndex;
|
||||||
|
while( (i=cptr_seek(src, str_old, startIndex, seekLength)) !=-1 ){
|
||||||
|
if(i!=0)
|
||||||
|
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=i});
|
||||||
|
StringBuilder_append_string(sb, (string){.ptr=str_new, .length=str_new_len});
|
||||||
|
src+=i+str_old_len;
|
||||||
|
}
|
||||||
|
u32 src_remains_len=cptr_length(src);
|
||||||
|
if(src_remains_len>0)
|
||||||
|
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len});
|
||||||
|
string rezult=StringBuilder_build(sb);
|
||||||
|
return rezult.ptr;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,37 +7,88 @@ extern "C" {
|
|||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
// returns length of char buffer (without \0)
|
// returns length of char buffer (without \0)
|
||||||
uint32 cptr_length(char* str);
|
u32 cptr_length(const char* str);
|
||||||
|
|
||||||
// allocates new char[] and copies src there
|
// allocates new char[] and copies src there
|
||||||
char* cptr_copy(char* src);
|
char* cptr_copy(const char* src);
|
||||||
|
|
||||||
// compares two char buffers, NullPtr-friendly
|
bool cptr_equals(const char* key0, const char* key1);
|
||||||
bool cptr_compare(char* key0, char* key1);
|
|
||||||
|
bool cptr_startsWith(const char* src, const char* fragment);
|
||||||
|
|
||||||
|
bool cptr_endsWith(const char* src, const char* fragment);
|
||||||
|
|
||||||
// multiplies char n times
|
// multiplies char n times
|
||||||
char* char_multiply(char c, uint32 n);
|
char* char_multiply(char c, u32 n);
|
||||||
|
|
||||||
bool cptr_startsWith(char* ptr, char* fragment);
|
/// @param startIndex 0 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
|
||||||
|
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
|
||||||
|
|
||||||
bool cptr_endsWith(char* ptr, char* fragment);
|
/// @param startIndex -1 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
|
||||||
|
i32 cptr_seekReverse(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
|
||||||
|
|
||||||
|
/// @param startIndex 0 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
|
||||||
|
i32 cptr_seekChar(const char* src, char fragment, u32 startIndex, u32 seekLength);
|
||||||
|
|
||||||
|
/// @param startIndex -1 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
|
||||||
|
i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength);
|
||||||
|
|
||||||
/// @brief search for <fragment> in <ptr>
|
/// @brief search for <fragment> in <ptr>
|
||||||
/// @return index of first <fragment> inclusion or -1 if not found
|
/// @return index of first <fragment> inclusion or -1 if not found
|
||||||
uint32 cptr_indexOf(char* ptr, char* fragment);
|
static inline i32 cptr_indexOf(const char* src, const char* fragment)
|
||||||
|
{ return cptr_seek(src, fragment, 0, -1); }
|
||||||
|
|
||||||
static inline bool cptr_contains(char* ptr, char* fragment){
|
/// @brief search for <fragment> in <ptr>
|
||||||
// if(cptr_indexOf(ptr, fragment)==-1)
|
/// @return index of first <fragment> inclusion or -1 if not found
|
||||||
// return false;
|
static inline i32 cptr_indexOfChar(const char* src, char fragment)
|
||||||
// return true;
|
{ return cptr_seekChar(src, fragment, 0, -1); }
|
||||||
return cptr_indexOf(ptr, fragment) +1;
|
|
||||||
|
/// @brief search for <fragment> in <ptr>
|
||||||
|
/// @return index of last <fragment> inclusion or -1 if not found
|
||||||
|
static inline i32 cptr_lastIndexOf(const char* src, const char* fragment)
|
||||||
|
{ return cptr_seekReverse(src, fragment, -1, -1); }
|
||||||
|
|
||||||
|
/// @brief search for <fragment> in <ptr>
|
||||||
|
/// @return index of last <fragment> inclusion or -1 if not found
|
||||||
|
static inline i32 cptr_lastIndexOfChar(const char* src, char fragment)
|
||||||
|
{ return cptr_seekCharReverse(src, fragment, -1, -1); }
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool cptr_contains(const char* src, const char* fragment){
|
||||||
|
return cptr_seek(src, fragment, 0, -1) +1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void memcopy(void* from, void* to, uint32 size);
|
void memcopy(void* from, void* to, u32 size);
|
||||||
|
|
||||||
char* __cptr_concat(uint16 n, ...);
|
char* __cptr_concat(u32 n, ...);
|
||||||
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
|
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
|
||||||
|
|
||||||
|
char* cptr_toLower(const char* src);
|
||||||
|
char* cptr_toUpper(const char* src);
|
||||||
|
|
||||||
|
/// @param startIndex 0 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found
|
||||||
|
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength);
|
||||||
|
/// @param startIndex 0 ... src length
|
||||||
|
/// @param seekLength 0 ... -1
|
||||||
|
/// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found
|
||||||
|
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength);
|
||||||
|
|
||||||
|
static inline char* cptr_replace(const char* src, const char* str_old, const char* str_new)
|
||||||
|
{ return cptr_replaceIn(src, str_old, str_new, 0, -1); }
|
||||||
|
|
||||||
|
static inline char* cptr_replaceChar(const char* src, char c_old, char c_new)
|
||||||
|
{ return cptr_replaceCharIn(src, c_old, c_new, 0, -1); }
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
static const union
|
static const union
|
||||||
{
|
{
|
||||||
uint16 number;
|
u16 number;
|
||||||
Endian bytes[2];
|
Endian bytes[2];
|
||||||
} _endian_union={ .number=0x0102 };
|
} _endian_union={ .number=0x0102 };
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,20 @@
|
|||||||
#include "std.h"
|
#pragma once
|
||||||
|
|
||||||
PACK_ENUM(Endian,
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "std.h"
|
||||||
|
#include "type_system/typedef_macros.h"
|
||||||
|
|
||||||
|
PACKED_ENUM(Endian,
|
||||||
UnknownEndian=0,
|
UnknownEndian=0,
|
||||||
LittleEndian=1,
|
LittleEndian=1,
|
||||||
BigEndian=2
|
BigEndian=2
|
||||||
);
|
)
|
||||||
|
|
||||||
Endian getEndian();
|
Endian getEndian();
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -5,25 +5,25 @@
|
|||||||
|
|
||||||
char* errname(ErrorId err){
|
char* errname(ErrorId err){
|
||||||
switch(err){
|
switch(err){
|
||||||
case SUCCESS: return "SUCCESS";
|
case SUCCESS: return nameof(SUCCESS);
|
||||||
case ERR_MAXLENGTH: return "ERR_MAXLENGTH";
|
case ERR_MAXLENGTH: return nameof(ERR_MAXLENGTH);
|
||||||
case ERR_WRONGTYPE: return "ERR_WRONGTYPE";
|
case ERR_WRONGTYPE: return nameof(ERR_WRONGTYPE);
|
||||||
case ERR_WRONGINDEX: return "ERR_WRONGINDEX";
|
case ERR_WRONGINDEX: return nameof(ERR_WRONGINDEX);
|
||||||
case ERR_NOTIMPLEMENTED: return "ERR_NOTIMPLEMENTED";
|
case ERR_NOTIMPLEMENTED: return nameof(ERR_NOTIMPLEMENTED);
|
||||||
case ERR_NULLPTR: return "ERR_NULLPTR";
|
case ERR_NULLPTR: return nameof(ERR_NULLPTR);
|
||||||
case ERR_ENDOFSTR: return "ERR_ENDOFSTR";
|
case ERR_ENDOFSTR: return nameof(ERR_ENDOFSTR);
|
||||||
case ERR_KEYNOTFOUND: return "ERR_KEYNOTFOUND";
|
case ERR_KEYNOTFOUND: return nameof(ERR_KEYNOTFOUND);
|
||||||
case ERR_FORMAT: return "ERR_FORMAT";
|
case ERR_FORMAT: return nameof(ERR_FORMAT);
|
||||||
case ERR_UNEXPECTEDVAL: return "ERR_UNEXPECTEDVAL";
|
case ERR_UNEXPECTEDVAL: return nameof(ERR_UNEXPECTEDVAL);
|
||||||
case ERR_IO: return "ERR_IO";
|
case ERR_IO: return nameof(ERR_IO);
|
||||||
case ERR_IO_EOF: return "ERR_IO_EOF";
|
case ERR_IO_EOF: return nameof(ERR_IO_EOF);
|
||||||
default: return "UNKNOWN_ERROR";
|
default: return "UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ERRMSG_MAXLENGTH 1024
|
#define ERRMSG_MAXLENGTH 1024
|
||||||
|
|
||||||
char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname){
|
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
||||||
size_t bufsize=ERRMSG_MAXLENGTH;
|
size_t bufsize=ERRMSG_MAXLENGTH;
|
||||||
char* rezult=malloc(bufsize);
|
char* rezult=malloc(bufsize);
|
||||||
IFMSC(
|
IFMSC(
|
||||||
@@ -33,7 +33,7 @@ char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char*
|
|||||||
return rezult;
|
return rezult;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* __extendErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname){
|
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
|
||||||
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
|
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
|
||||||
char* rezult=malloc(bufsize);
|
char* rezult=malloc(bufsize);
|
||||||
IFMSC(
|
IFMSC(
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
#include "type_system/unitype.h"
|
#include "type_system/type_system.h"
|
||||||
|
|
||||||
PACK_ENUM(ErrorId,
|
PACKED_ENUM(ErrorId,
|
||||||
SUCCESS, // not an error
|
SUCCESS, // not an error
|
||||||
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
|
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
|
||||||
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
|
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
|
||||||
@@ -17,13 +17,13 @@ PACK_ENUM(ErrorId,
|
|||||||
|
|
||||||
char* errname(ErrorId err);
|
char* errname(ErrorId err);
|
||||||
|
|
||||||
char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname);
|
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
|
||||||
char* __extendErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname);
|
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
|
||||||
|
|
||||||
typedef struct Maybe{
|
STRUCT(Maybe,
|
||||||
Unitype value;
|
Unitype value;
|
||||||
char* errmsg;
|
char* errmsg;
|
||||||
} Maybe;
|
)
|
||||||
|
|
||||||
// return it if func doesn't return anything
|
// return it if func doesn't return anything
|
||||||
// .value .errmsg
|
// .value .errmsg
|
||||||
@@ -37,38 +37,54 @@ void printMaybe(Maybe e);
|
|||||||
|
|
||||||
#define __RETURN_EXCEPTION(ERRMSG) return (Maybe){.value=UniNull, .errmsg=ERRMSG}
|
#define __RETURN_EXCEPTION(ERRMSG) return (Maybe){.value=UniNull, .errmsg=ERRMSG}
|
||||||
|
|
||||||
#define __EXIT(ERRMSG) ({ kprintf("\e[91m%s\e[0m \n", ERRMSG); free(ERRMSG); exit(128); })
|
#define __EXIT(ERRMSG) ({ kprintf("\e[91m%s\e[0m \n", ERRMSG); free(ERRMSG); exit(128); })
|
||||||
|
|
||||||
char* __doNothing(char* a);
|
char* __doNothing(char* a);
|
||||||
char* __unknownErr( );
|
char* __unknownErr( );
|
||||||
|
|
||||||
#define __stringify_err(E) _Generic(\
|
#define __stringify_err(E) _Generic( \
|
||||||
(E),\
|
(E), \
|
||||||
char*: __doNothing,\
|
char*: __doNothing, \
|
||||||
int: errname,\
|
int: errname, \
|
||||||
default: __unknownErr\
|
default: __unknownErr \
|
||||||
)(E)
|
)(E)
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
|
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
|
||||||
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
|
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
|
||||||
|
|
||||||
|
#define safethrow_id(E, FREEMEM) { FREEMEM; \
|
||||||
|
__RETURN_EXCEPTION(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__))); \
|
||||||
|
}
|
||||||
|
#define safethrow_msg(E, FREEMEM) { FREEMEM; \
|
||||||
|
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||||
|
freeMem; \
|
||||||
|
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
|
return _rezult; \
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
|
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
|
||||||
#define safethrow(E, FREEMEM) { FREEMEM; __RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); }
|
|
||||||
|
|
||||||
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
#define safethrow(E, FREEMEM) { FREEMEM; \
|
||||||
freeMem;\
|
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
|
||||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
|
}
|
||||||
return _rezult;\
|
|
||||||
}
|
|
||||||
|
|
||||||
#define tryLast(_funcCall, _rezult) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
|
|
||||||
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
|
|
||||||
__EXIT(_rezult.errmsg);\
|
|
||||||
}
|
|
||||||
|
|
||||||
|
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||||
|
freeMem; \
|
||||||
|
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
|
return _rezult; \
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define tryLast(_funcCall, _rezult, ON_EXIT) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
|
||||||
|
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
|
||||||
|
__EXIT(_rezult.errmsg); \
|
||||||
|
}
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2,40 +2,40 @@
|
|||||||
|
|
||||||
#include "std.h"
|
#include "std.h"
|
||||||
|
|
||||||
#define __optime_print(opname, t)\
|
#define __optime_print(opname, t) \
|
||||||
char tnames[3][3]={"s\0","ms","us"};\
|
char tnames[3][3]={"s\0","ms","us"}; \
|
||||||
int tni=0;\
|
i32 tni=0; \
|
||||||
if(t>1000000){\
|
if(t>1000000){ \
|
||||||
t/=1000000;\
|
t/=1000000; \
|
||||||
tni=0;\
|
tni=0; \
|
||||||
} else if(t>1000){\
|
} else if(t>1000){ \
|
||||||
t/=1000;\
|
t/=1000; \
|
||||||
tni=1;\
|
tni=1; \
|
||||||
} else tni=2;\
|
} else tni=2; \
|
||||||
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n",\
|
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \
|
||||||
opname, t, tnames[tni]);
|
opname, t, tnames[tni]);
|
||||||
|
|
||||||
#ifdef CLOCK_REALTIME
|
#ifdef CLOCK_REALTIME
|
||||||
/// executes codeblock and prints execution time
|
/// executes codeblock and prints execution time
|
||||||
/// uint64 op_i is counter of the internal loop
|
/// u64 op_i is counter of the internal loop
|
||||||
/// uses non-standard high-precision clock
|
/// uses non-standard high-precision clock
|
||||||
#define optime(opname,repeats,codeblock) ({\
|
#define optime(opname, repeats, codeblock...) { \
|
||||||
struct timespec start, stop;\
|
struct timespec start, stop; \
|
||||||
clock_gettime(CLOCK_REALTIME, &start);\
|
clock_gettime(CLOCK_REALTIME, &start); \
|
||||||
for(uint64 op_i=0;op_i<(uint64)repeats;op_i++)\
|
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
|
||||||
(codeblock);\
|
{ codeblock; } \
|
||||||
clock_gettime(CLOCK_REALTIME, &stop);\
|
clock_gettime(CLOCK_REALTIME, &stop); \
|
||||||
double t=(double)(stop.tv_sec-start.tv_sec)*1000000+(double)(stop.tv_nsec-start.tv_nsec)/1000;\
|
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \
|
||||||
__optime_print(opname,t)\
|
__optime_print(opname,t); \
|
||||||
})
|
}
|
||||||
#else
|
#else
|
||||||
/// uses standard low precision clock
|
/// uses standard low precision clock
|
||||||
#define optime(opname,repeats,codeblock) ({\
|
#define optime(opname, repeats, codeblock...) { \
|
||||||
clock_t start=clock();\
|
clock_t start=clock(); \
|
||||||
for(uint64 op_i=0;op_i<(uint64)repeats;op_i++)\
|
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
|
||||||
(codeblock);\
|
{ codeblock; } \
|
||||||
clock_t stop=clock();\
|
clock_t stop=clock(); \
|
||||||
double t=(double)(stop-start)/CLOCKS_PER_SEC*1000000;\
|
f64 t=(f64)(stop-start)/CLOCKS_PER_SEC*1000000; \
|
||||||
__optime_print(opname,t)\
|
__optime_print(opname,t); \
|
||||||
})
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,32 +8,40 @@ extern "C" {
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
typedef int8_t i8;
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef int16_t i16;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef int32_t i32;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef int64_t i64;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
typedef float f32;
|
||||||
|
typedef double f64;
|
||||||
|
/// anonymous pointer without specified freeMembers() func
|
||||||
|
typedef void* Pointer;
|
||||||
|
|
||||||
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;
|
|
||||||
// Usually bool from stdbool.h is defined as macro,
|
// Usually bool from stdbool.h is defined as macro,
|
||||||
// so in other macros like ktid_##TYPE it will be replaced by _Bool.
|
// so in other macros like ktid_##TYPE it will be replaced by _Bool.
|
||||||
// ktid__Bool will be created instead of ktid_bool
|
// ktid__Bool will be created instead of ktid_bool
|
||||||
// In C++ bool is a keyword, so there is no need to redefine it.
|
// In C++ bool is a keyword, so there is no need to redefine it.
|
||||||
#if !__cplusplus
|
#if !__cplusplus
|
||||||
typedef uint8 bool;
|
typedef u8 bool;
|
||||||
#define true 1
|
#define true 1
|
||||||
#define false 0
|
#define false 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define dbg(N) kprintf("\e[95m%d\n",N)
|
#define dbg(N) kprintf("\e[95m%d\n",N)
|
||||||
|
|
||||||
|
#define nameof(V) #V
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK
|
#pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK
|
||||||
#define _CRT_SECURE_NO_WARNINGS 1
|
#define _CRT_SECURE_NO_WARNINGS 1
|
||||||
@@ -71,27 +79,27 @@ typedef uint8 bool;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define __count_args(\
|
#define __count_args( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7 ,\
|
a0, a1, a2, a3, a4, a5, a6, a7 , \
|
||||||
a8, a9, a10,a11,a12,a13,a14,a15,\
|
a8, a9, a10,a11,a12,a13,a14,a15, \
|
||||||
a16,a17,a18,a19,a20,a21,a22,a23,\
|
a16,a17,a18,a19,a20,a21,a22,a23, \
|
||||||
a24,a25,a26,a27,a28,a29,a30,a31,\
|
a24,a25,a26,a27,a28,a29,a30,a31, \
|
||||||
a32,a33,a34,a35,a36,a37,a38,a39,\
|
a32,a33,a34,a35,a36,a37,a38,a39, \
|
||||||
a40,a41,a42,a43,a44,a45,a46,a47,\
|
a40,a41,a42,a43,a44,a45,a46,a47, \
|
||||||
a48,a49,a50,a51,a52,a53,a54,a55,\
|
a48,a49,a50,a51,a52,a53,a54,a55, \
|
||||||
a56,a57,a58,a59,a60,a61,a62,a63,\
|
a56,a57,a58,a59,a60,a61,a62,a63, \
|
||||||
a64,...) a64
|
a64,...) a64
|
||||||
// Macro for counting variadic arguments (max 64)
|
// Macro for counting variadic arguments (max 64)
|
||||||
// (see usage in kprint.h)
|
// (see usage in kprint.h)
|
||||||
#define count_args(ARGS...) __count_args(\
|
#define count_args(ARGS...) __count_args( \
|
||||||
ARGS,\
|
ARGS, \
|
||||||
64,63,62,61,60,59,58,57,\
|
64,63,62,61,60,59,58,57, \
|
||||||
56,55,54,53,52,51,50,49,\
|
56,55,54,53,52,51,50,49, \
|
||||||
48,47,46,45,44,43,42,41,\
|
48,47,46,45,44,43,42,41, \
|
||||||
40,39,38,37,36,35,34,33,\
|
40,39,38,37,36,35,34,33, \
|
||||||
32,31,30,29,28,27,26,25,\
|
32,31,30,29,28,27,26,25, \
|
||||||
24,23,22,21,20,19,18,17,\
|
24,23,22,21,20,19,18,17, \
|
||||||
16,15,14,13,12,11,10,9,\
|
16,15,14,13,12,11,10,9, \
|
||||||
8, 7, 6, 5, 4, 3, 2, 1, 0)
|
8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -111,16 +119,16 @@ You can even embed it into macro in header (see kprint.h)
|
|||||||
#define PRAGMA_WARNING_DISABLE(wName) _PRAGMA(GCC diagnostic ignored wName)
|
#define PRAGMA_WARNING_DISABLE(wName) _PRAGMA(GCC diagnostic ignored wName)
|
||||||
#define PRAGMA_WARNING_POP _PRAGMA(GCC diagnostic pop)
|
#define PRAGMA_WARNING_POP _PRAGMA(GCC diagnostic pop)
|
||||||
#define W_INT_CONVERSION "-Wint-conversion"
|
#define W_INT_CONVERSION "-Wint-conversion"
|
||||||
|
#define W_IMPLICIT_FALLTHROUGH "-Wimplicit-fallthrough"
|
||||||
#endif
|
#endif
|
||||||
#define WARNING_DISABLE(WARNING, CODE)\
|
#define WARNING_DISABLE(WARNING, CODE...) \
|
||||||
PRAGMA_WARNING_PUSH\
|
PRAGMA_WARNING_PUSH \
|
||||||
PRAGMA_WARNING_DISABLE(WARNING)\
|
PRAGMA_WARNING_DISABLE(WARNING) \
|
||||||
CODE;\
|
CODE; \
|
||||||
PRAGMA_WARNING_POP
|
PRAGMA_WARNING_POP
|
||||||
|
|
||||||
#define PACK_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME {\
|
/// gcc throws warning on unused function return value
|
||||||
ENUM_MEMBERS\
|
#define WARN_UNUSED_REZULT __attribute__((warn_unused_result))
|
||||||
} __attribute__((__packed__)) ENUM_NAME;
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,21 @@ For using some kerep capabilities, such as generic structs, unitype, and kprint,
|
|||||||
|
|
||||||
## type id
|
## type id
|
||||||
|
|
||||||
Every registered type has its own id (`ktid`), which should be declared in header file and defined in source file.
|
Every registered type has its own `ktDescriptor` and `ktid` is an index of the descriptor in descriptors array.
|
||||||
Example:
|
Descriptor should be declared in header file.
|
||||||
|
Following macro declares `typedef struct` and `ktDescriptor`
|
||||||
```c
|
```c
|
||||||
//someStruct.h
|
//someStruct.h
|
||||||
typedef struct { } someStruct;
|
STRUCT(someStruct,
|
||||||
ktid_declare(someStruct);
|
i32 i; i32 j; i32 k;
|
||||||
|
);
|
||||||
```
|
```
|
||||||
|
then you need to define descriptor in a source file
|
||||||
```c
|
```c
|
||||||
//someStruct.c
|
//someStruct.c
|
||||||
ktid_define(someStruct);
|
kt_define(someStruct);
|
||||||
```
|
```
|
||||||
|
and register it.
|
||||||
|
|
||||||
## type descriptors
|
## type descriptors
|
||||||
|
|
||||||
@@ -22,9 +26,9 @@ Every registered type should have it's own descriptor (`ktDescriptor`). It's a s
|
|||||||
|
|
||||||
## type registration
|
## 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()`.
|
To finally register a type, you should call macro `kt_register()` between `kt_beginInit()` and `kt_endInit()`. Better do it at the start of your program. To register all types from kerep, call `kt_initKerepTypes()`.
|
||||||
|
|
||||||
You can free internal ktDescriptors storage by calling `ktDescriptors_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
|
You can free internal ktDescriptors storage by calling `kt_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
|
||||||
Examples:
|
Examples:
|
||||||
+ [ktDescriptors_initKerepTypes()](src/base/type_system/init.c)
|
+ [kerep types registration](src/base/type_system/init.c)
|
||||||
+ [kerep types registration](tests/main.cpp)
|
+ [kt_initKerepTypes()](tests/main.cpp)
|
||||||
|
|||||||
@@ -2,24 +2,27 @@
|
|||||||
#include "../base.h"
|
#include "../base.h"
|
||||||
#include "../../kprint/kprint_format.h"
|
#include "../../kprint/kprint_format.h"
|
||||||
|
|
||||||
char* __toString_char(void* c, uint32 fmt) {
|
|
||||||
//*c=char
|
// accepts char* (ptr to char) and char* (ptr to string)
|
||||||
|
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||||
|
char* __toString_char(void* c, u32 fmt) {
|
||||||
|
// *c=char*
|
||||||
|
if(kp_fmt_dataFormat(fmt)==kp_s){
|
||||||
|
return cptr_copy((char*)c); // to avoid segmentation fault on free() when *c allocalet on stack
|
||||||
|
}
|
||||||
|
// *c=char
|
||||||
if(kp_fmt_dataFormat(fmt)==kp_c){
|
if(kp_fmt_dataFormat(fmt)==kp_c){
|
||||||
char* cc=malloc(2);
|
char* cc=malloc(2);
|
||||||
cc[0]=*(char*)c;
|
cc[0]=*(char*)c;
|
||||||
cc[1]=0;
|
cc[1]=0;
|
||||||
return cc;
|
return cc;
|
||||||
}
|
}
|
||||||
// *c=cstring
|
|
||||||
else if(kp_fmt_dataFormat(fmt)==kp_s){
|
|
||||||
return cptr_copy(*(char**)c);
|
|
||||||
}
|
|
||||||
else throw(ERR_FORMAT);
|
else throw(ERR_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* __toString_bool(void* c, uint32 fmt) {
|
char* __toString_bool(void* c, u32 fmt) {
|
||||||
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
|
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
|
||||||
uint8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
|
u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
|
||||||
char* rez=malloc(6);
|
char* rez=malloc(6);
|
||||||
rez[0]=_strbool[strind][0];
|
rez[0]=_strbool[strind][0];
|
||||||
rez[1]=_strbool[strind][1];
|
rez[1]=_strbool[strind][1];
|
||||||
@@ -30,10 +33,10 @@ char* __toString_bool(void* c, uint32 fmt) {
|
|||||||
return rez;
|
return rez;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* toString_int(int64 n){
|
char* toString_i64(i64 n){
|
||||||
int64 d=n<0 ? -1*n : n;
|
i64 d=n<0 ? -1*n : n;
|
||||||
char str[32];
|
char str[32];
|
||||||
uint8 i=sizeof(str);
|
u8 i=sizeof(str);
|
||||||
str[--i]=0;
|
str[--i]=0;
|
||||||
if(d==0)
|
if(d==0)
|
||||||
str[--i]='0';
|
str[--i]='0';
|
||||||
@@ -46,9 +49,9 @@ char* toString_int(int64 n){
|
|||||||
return cptr_copy((char*)str+i);
|
return cptr_copy((char*)str+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
|
char* toString_u64(u64 n, bool withPostfix, bool uppercase){
|
||||||
char str[32];
|
char str[32];
|
||||||
uint8 i=sizeof(str);
|
u8 i=sizeof(str);
|
||||||
str[--i]=0;
|
str[--i]=0;
|
||||||
if(withPostfix)
|
if(withPostfix)
|
||||||
str[--i]= uppercase ? 'U' : 'u';
|
str[--i]= uppercase ? 'U' : 'u';
|
||||||
@@ -61,53 +64,56 @@ char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
|
|||||||
return cptr_copy((char*)str+i);
|
return cptr_copy((char*)str+i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _toString_float_impl(bufsize, maxPrecision) {\
|
#define _toString_float_impl(bufsize, maxPrecision) { \
|
||||||
char str[bufsize];\
|
char str[bufsize]; \
|
||||||
if(precision>maxPrecision)\
|
if(precision>maxPrecision) \
|
||||||
throw("too big precision");\
|
throw("too big precision"); \
|
||||||
if(precision==0)\
|
if(precision==0) \
|
||||||
precision=toString_float_default_precision;\
|
precision=toString_float_default_precision; \
|
||||||
int cn=sprintf(str, "%.*f", precision, n);\
|
i32 cn=IFMSC( \
|
||||||
/* remove trailing zeroes except .0*/\
|
sprintf_s(str, bufsize, "%.*f", precision, n), \
|
||||||
while(str[cn-1]=='0' && str[cn-2]!='.')\
|
sprintf(str, "%.*f", precision, n) \
|
||||||
cn--;\
|
); \
|
||||||
if(withPostfix)\
|
/* remove trailing zeroes except .0*/ \
|
||||||
str[cn++]= uppercase ? 'F' : 'f';\
|
while(str[cn-1]=='0' && str[cn-2]!='.') \
|
||||||
str[cn]='\0';\
|
cn--; \
|
||||||
return cptr_copy(str);\
|
if(withPostfix) \
|
||||||
|
str[cn++]= uppercase ? 'F' : 'f'; \
|
||||||
|
str[cn]='\0'; \
|
||||||
|
return cptr_copy(str); \
|
||||||
}
|
}
|
||||||
|
|
||||||
char* toString_float32(float32 n, uint8 precision, bool withPostfix, bool uppercase)
|
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
|
||||||
_toString_float_impl(48, toString_float32_max_precision)
|
_toString_float_impl(48, toString_f32_max_precision)
|
||||||
|
|
||||||
char* toString_float64(float64 n, uint8 precision, bool withPostfix, bool uppercase)
|
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase)
|
||||||
_toString_float_impl(512, toString_float64_max_precision)
|
_toString_float_impl(512, toString_f64_max_precision)
|
||||||
|
|
||||||
#define byte_to_bits(byte) {\
|
#define byte_to_bits(byte) { \
|
||||||
str[cn++]='0' + (uint8)((byte>>7)&1); /* 8th bit */\
|
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>6)&1); /* 7th bit */\
|
str[cn++]='0' + (u8)((byte>>6)&1); /* 7th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>5)&1); /* 6th bit */\
|
str[cn++]='0' + (u8)((byte>>5)&1); /* 6th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>4)&1); /* 5th bit */\
|
str[cn++]='0' + (u8)((byte>>4)&1); /* 5th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>3)&1); /* 4th bit */\
|
str[cn++]='0' + (u8)((byte>>3)&1); /* 4th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>2)&1); /* 3th bit */\
|
str[cn++]='0' + (u8)((byte>>2)&1); /* 3th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>1)&1); /* 2th bit */\
|
str[cn++]='0' + (u8)((byte>>1)&1); /* 2th bit */ \
|
||||||
str[cn++]='0' + (uint8)((byte>>0)&1); /* 1th bit */\
|
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
char* toString_bin(void* _bytes, uint32 size, bool inverse, bool withPrefix){
|
char* toString_bin(void* _bytes, u32 size, bool inverse, bool withPrefix){
|
||||||
char* bytes=_bytes;
|
char* bytes=_bytes;
|
||||||
char* str=malloc(size*8 + (withPrefix?2:0) +1);
|
char* str=malloc(size*8 + (withPrefix?2:0) +1);
|
||||||
uint32 cn=0; // char number
|
u32 cn=0; // char number
|
||||||
if(withPrefix){
|
if(withPrefix){
|
||||||
str[cn++]='0';
|
str[cn++]='0';
|
||||||
str[cn++]='b';
|
str[cn++]='b';
|
||||||
}
|
}
|
||||||
if(inverse){
|
if(inverse){
|
||||||
// byte number
|
// byte number
|
||||||
for(int32 bn=size-1; bn>=0; bn--)
|
for(i32 bn=size-1; bn>=0; bn--)
|
||||||
byte_to_bits(bytes[bn])
|
byte_to_bits(bytes[bn])
|
||||||
} else {
|
} else {
|
||||||
for(int32 bn=0; bn<size; bn++)
|
for(u32 bn=0; bn<size; bn++)
|
||||||
byte_to_bits(bytes[bn])
|
byte_to_bits(bytes[bn])
|
||||||
}
|
}
|
||||||
str[cn]=0;
|
str[cn]=0;
|
||||||
@@ -115,7 +121,7 @@ char* toString_bin(void* _bytes, uint32 size, bool inverse, bool withPrefix){
|
|||||||
}
|
}
|
||||||
|
|
||||||
// converts number from 0 to F to char
|
// converts number from 0 to F to char
|
||||||
char _4bitsHex(uint8 u, bool uppercase){
|
char _4bitsHex(u8 u, bool uppercase){
|
||||||
switch(u){
|
switch(u){
|
||||||
case 0: case 1: case 2: case 3: case 4:
|
case 0: case 1: case 2: case 3: case 4:
|
||||||
case 5: case 6: case 7: case 8: case 9:
|
case 5: case 6: case 7: case 8: case 9:
|
||||||
@@ -130,10 +136,10 @@ char _4bitsHex(uint8 u, bool uppercase){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, bool uppercase){
|
char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){
|
||||||
char* bytes=_bytes;
|
char* bytes=_bytes;
|
||||||
char* str=malloc(size*2 + (withPrefix?2:0) + 1);
|
char* str=malloc(size*2 + (withPrefix?2:0) + 1);
|
||||||
uint32 cn=0; // char number
|
u32 cn=0; // char number
|
||||||
if(withPrefix){
|
if(withPrefix){
|
||||||
str[cn++]='0';
|
str[cn++]='0';
|
||||||
str[cn++]='x';
|
str[cn++]='x';
|
||||||
@@ -141,7 +147,7 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
|
|||||||
// left to right
|
// left to right
|
||||||
if(inverse){
|
if(inverse){
|
||||||
// byte number
|
// byte number
|
||||||
for(int32 bn=size-1; bn>=0; bn--){
|
for(i32 bn=size-1; bn>=0; bn--){
|
||||||
unsigned char byte=bytes[bn];
|
unsigned char byte=bytes[bn];
|
||||||
str[cn++]=_4bitsHex(byte/16, uppercase);
|
str[cn++]=_4bitsHex(byte/16, uppercase);
|
||||||
str[cn++]=_4bitsHex(byte%16, uppercase);
|
str[cn++]=_4bitsHex(byte%16, uppercase);
|
||||||
@@ -149,7 +155,7 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
|
|||||||
}
|
}
|
||||||
// right to left
|
// right to left
|
||||||
else {
|
else {
|
||||||
for(int32 bn=0; bn<size; bn++){ // byte number
|
for(u32 bn=0; bn<size; bn++){ // byte number
|
||||||
unsigned char byte=bytes[bn];
|
unsigned char byte=bytes[bn];
|
||||||
str[cn++]=_4bitsHex(byte/16, uppercase);
|
str[cn++]=_4bitsHex(byte/16, uppercase);
|
||||||
str[cn++]=_4bitsHex(byte%16, uppercase);
|
str[cn++]=_4bitsHex(byte%16, uppercase);
|
||||||
@@ -160,60 +166,72 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define __toString_int_def(BITS) char* __toString_int##BITS(void* _n, uint32 f){\
|
#define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){ \
|
||||||
switch(kp_fmt_dataFormat(f)){\
|
switch(kp_fmt_dataFormat(f)){ \
|
||||||
case kp_i: ;\
|
case kp_i: ; \
|
||||||
int##BITS n=*(int##BITS*)_n;\
|
i##BITS n=*(i##BITS*)_n; \
|
||||||
return toString_int(n);\
|
return toString_i64(n); \
|
||||||
case kp_b:\
|
case kp_b: \
|
||||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||||
case kp_h:\
|
case kp_h: \
|
||||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||||
default:\
|
default: \
|
||||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||||
throw(ERR_FORMAT);\
|
throw(ERR_FORMAT); \
|
||||||
return NULL;\
|
return NULL; \
|
||||||
}\
|
} \
|
||||||
}
|
}
|
||||||
__toString_int_def(8)
|
__toString_i32_def(8)
|
||||||
__toString_int_def(16)
|
__toString_i32_def(16)
|
||||||
__toString_int_def(32)
|
__toString_i32_def(32)
|
||||||
__toString_int_def(64)
|
__toString_i32_def(64)
|
||||||
|
|
||||||
#define __toString_uint_def(BITS) char* __toString_uint##BITS(void* _n, uint32 f){\
|
#define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){ \
|
||||||
switch(kp_fmt_dataFormat(f)){\
|
switch(kp_fmt_dataFormat(f)){ \
|
||||||
case kp_u: ;\
|
case kp_u: ; \
|
||||||
uint##BITS n=*(uint##BITS*)_n;\
|
u##BITS n=*(u##BITS*)_n; \
|
||||||
return toString_uint(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
|
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
|
||||||
case kp_b:\
|
case kp_b: \
|
||||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||||
case kp_h:\
|
case kp_h: \
|
||||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||||
default:\
|
default: \
|
||||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||||
throw(ERR_FORMAT);\
|
throw(ERR_FORMAT); \
|
||||||
return NULL;\
|
return NULL; \
|
||||||
}\
|
} \
|
||||||
|
}
|
||||||
|
__toString_u_def(8)
|
||||||
|
__toString_u_def(16)
|
||||||
|
__toString_u_def(32)
|
||||||
|
// __toString_u_def(64)
|
||||||
|
char* __toString_u64(void* _n, u32 f){
|
||||||
|
switch(kp_fmt_dataFormat(f)){
|
||||||
|
case kp_u: ;
|
||||||
|
u64 n=*(u64*)_n;
|
||||||
|
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));
|
||||||
|
case kp_b:
|
||||||
|
return toString_bin(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));
|
||||||
|
case kp_h:
|
||||||
|
return toString_hex(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));
|
||||||
|
default:
|
||||||
|
kprintf("\n%u\n", kp_fmt_dataFormat(f)); throw(ERR_FORMAT); return NULL; }
|
||||||
}
|
}
|
||||||
__toString_uint_def(8)
|
|
||||||
__toString_uint_def(16)
|
|
||||||
__toString_uint_def(32)
|
|
||||||
__toString_uint_def(64)
|
|
||||||
|
|
||||||
#define __toString_float_def(BITS) char* __toString_float##BITS(void* _n, uint32 f){\
|
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){ \
|
||||||
switch(kp_fmt_dataFormat(f)){\
|
switch(kp_fmt_dataFormat(f)){ \
|
||||||
case kp_f: ;\
|
case kp_f: ; \
|
||||||
float##BITS n=*(float##BITS*)_n;\
|
f##BITS n=*(f##BITS*)_n; \
|
||||||
return toString_float64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
|
return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
|
||||||
case kp_b:\
|
case kp_b: \
|
||||||
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
|
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
|
||||||
case kp_h:\
|
case kp_h: \
|
||||||
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
|
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
|
||||||
default:\
|
default: \
|
||||||
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
|
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
|
||||||
throw(ERR_FORMAT);\
|
throw(ERR_FORMAT); \
|
||||||
return NULL;\
|
return NULL; \
|
||||||
}\
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
__toString_float_def(32)
|
__toString_float_def(32)
|
||||||
|
|||||||
@@ -6,41 +6,41 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../errors.h"
|
#include "../errors.h"
|
||||||
|
|
||||||
// char and cstring
|
// accepts char* (ptr to char) and char* (ptr to string)
|
||||||
// has different output for fmtChar and fmtString
|
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||||
char* __toString_char(void* c, uint32 fmt);
|
char* __toString_char(void* c, u32 fmt);
|
||||||
|
|
||||||
// bool
|
// bool
|
||||||
char* __toString_bool(void* c, uint32 fmt);
|
char* __toString_bool(void* c, u32 fmt);
|
||||||
|
|
||||||
// signed int
|
// signed int
|
||||||
char* toString_int(int64 n);
|
char* toString_i64(i64 n);
|
||||||
char* __toString_int8(void* n, uint32 fmt);
|
char* __toString_i8(void* n, u32 fmt);
|
||||||
char* __toString_int16(void* n, uint32 fmt);
|
char* __toString_i16(void* n, u32 fmt);
|
||||||
char* __toString_int32(void* n, uint32 fmt);
|
char* __toString_i32(void* n, u32 fmt);
|
||||||
char* __toString_int64(void* n, uint32 fmt);
|
char* __toString_i64(void* n, u32 fmt);
|
||||||
|
|
||||||
// unsigned int
|
// unsigned int
|
||||||
char* toString_uint(uint64 n, bool withPostfix, bool uppercase);
|
char* toString_u64(u64 n, bool withPostfix, bool uppercase);
|
||||||
char* __toString_uint8(void* n, uint32 fmt);
|
char* __toString_u8(void* n, u32 fmt);
|
||||||
char* __toString_uint16(void* n, uint32 fmt);
|
char* __toString_u16(void* n, u32 fmt);
|
||||||
char* __toString_uint32(void* n, uint32 fmt);
|
char* __toString_u32(void* n, u32 fmt);
|
||||||
char* __toString_uint64(void* n, uint32 fmt);
|
char* __toString_u64(void* n, u32 fmt);
|
||||||
|
|
||||||
// float
|
// float
|
||||||
#define toString_float32_max_precision 6
|
#define toString_f32_max_precision 6
|
||||||
#define toString_float64_max_precision 15
|
#define toString_f64_max_precision 15
|
||||||
#define toString_float_default_precision 6
|
#define toString_float_default_precision 6
|
||||||
char* toString_float32(float32 n, uint8 precision, bool withPostfix, bool uppercase); // uses sprintf
|
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
|
||||||
char* toString_float64(float64 n, uint8 precision, bool withPostfix, bool uppercase); // uses sprintf
|
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
|
||||||
char* __toString_float32(void* n, uint32 fmt);
|
char* __toString_f32(void* n, u32 fmt);
|
||||||
char* __toString_float64(void* n, uint32 fmt);
|
char* __toString_f64(void* n, u32 fmt);
|
||||||
|
|
||||||
|
|
||||||
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
|
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
|
||||||
char* toString_bin(void* bytes, uint32 size, bool inverse, bool withPrefix);
|
char* toString_bin(void* bytes, u32 size, bool inverse, bool withPrefix);
|
||||||
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
|
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
|
||||||
char* toString_hex(void* bytes, uint32 size, bool inverse, bool withPrefix, bool uppercase);
|
char* toString_hex(void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,84 +4,84 @@
|
|||||||
#include "../../SearchTree/SearchTree.h"
|
#include "../../SearchTree/SearchTree.h"
|
||||||
#include "../../Hashtable/Hashtable.h"
|
#include "../../Hashtable/Hashtable.h"
|
||||||
#include "../../String/StringBuilder.h"
|
#include "../../String/StringBuilder.h"
|
||||||
|
#include "../../Filesystem/filesystem.h"
|
||||||
#include "base_toString.h"
|
#include "base_toString.h"
|
||||||
|
|
||||||
void ktDescriptors_initKerepTypes(){
|
void kt_initKerepTypes(){
|
||||||
// null
|
|
||||||
__kt_register("Null", sizeof(NULL), NULL, NULL);
|
|
||||||
ktid_Null=ktid_last;
|
|
||||||
// base types
|
// base types
|
||||||
kt_register(char, NULL, __toString_char);
|
kt_register(Pointer);
|
||||||
kt_register(bool, NULL, __toString_bool);
|
if(ktid_Pointer!=0) // this can break UnitypeNull
|
||||||
kt_register(float32, NULL, __toString_float32);
|
throw("ktid_Pointer!=0, you must init kerep types before any other types");
|
||||||
kt_register(float64, NULL, __toString_float64);
|
|
||||||
kt_register(int8, NULL, __toString_int8);
|
kt_register(char);
|
||||||
kt_register(uint8, NULL, __toString_uint8);
|
kt_register(bool);
|
||||||
kt_register(int16, NULL, __toString_int16);
|
kt_register(f32);
|
||||||
kt_register(uint16, NULL, __toString_uint16);
|
kt_register(f64);
|
||||||
kt_register(int32, NULL, __toString_int32);
|
kt_register(i8);
|
||||||
kt_register(uint32, NULL, __toString_uint32);
|
kt_register(u8);
|
||||||
kt_register(int64, NULL, __toString_int64);
|
kt_register(i16);
|
||||||
kt_register(uint64, NULL, __toString_uint64);
|
kt_register(u16);
|
||||||
|
kt_register(i32);
|
||||||
|
kt_register(u32);
|
||||||
|
kt_register(i64);
|
||||||
|
kt_register(u64);
|
||||||
|
|
||||||
// ktDescriptor
|
// ktDescriptor
|
||||||
kt_register(ktDescriptor, NULL, NULL);
|
kt_register(ktDescriptor);
|
||||||
|
|
||||||
|
|
||||||
// base type arrays
|
// base type arrays
|
||||||
kt_register(Array_char, (freeMembers_t)Array_char_freeValues, NULL);
|
kt_register(Array_char);
|
||||||
kt_register(Array_bool, (freeMembers_t)Array_bool_freeValues, NULL);
|
kt_register(Array_bool);
|
||||||
kt_register(Array_float32, (freeMembers_t)Array_float32_freeValues, NULL);
|
kt_register(Array_f32);
|
||||||
kt_register(Array_float64, (freeMembers_t)Array_float64_freeValues, NULL);
|
kt_register(Array_f64);
|
||||||
kt_register(Array_int8, (freeMembers_t)Array_int8_freeValues, NULL);
|
kt_register(Array_i8);
|
||||||
kt_register(Array_uint8, (freeMembers_t)Array_uint8_freeValues, NULL);
|
kt_register(Array_u8);
|
||||||
kt_register(Array_int16, (freeMembers_t)Array_int16_freeValues, NULL);
|
kt_register(Array_i16);
|
||||||
kt_register(Array_uint16, (freeMembers_t)Array_uint16_freeValues, NULL);
|
kt_register(Array_u16);
|
||||||
kt_register(Array_int32, (freeMembers_t)Array_int32_freeValues, NULL);
|
kt_register(Array_i32);
|
||||||
kt_register(Array_uint32, (freeMembers_t)Array_uint32_freeValues, NULL);
|
kt_register(Array_u32);
|
||||||
kt_register(Array_int64, (freeMembers_t)Array_int64_freeValues, NULL);
|
kt_register(Array_i64);
|
||||||
kt_register(Array_uint64, (freeMembers_t)Array_uint64_freeValues, NULL);
|
kt_register(Array_u64);
|
||||||
|
kt_register(Array_Pointer);
|
||||||
|
|
||||||
// base type autoarrs
|
// base type autoarrs
|
||||||
kt_register(Autoarr_char, ____Autoarr_free_char, NULL);
|
kt_register(Autoarr_Pointer);
|
||||||
kt_register(Autoarr_bool, ____Autoarr_free_bool, NULL);
|
kt_register(Autoarr_char);
|
||||||
kt_register(Autoarr_float32, ____Autoarr_free_float32, NULL);
|
kt_register(Autoarr_bool);
|
||||||
kt_register(Autoarr_float64, ____Autoarr_free_float64, NULL);
|
kt_register(Autoarr_f32);
|
||||||
kt_register(Autoarr_int8, ____Autoarr_free_int8, NULL);
|
kt_register(Autoarr_f64);
|
||||||
kt_register(Autoarr_uint8, ____Autoarr_free_uint8, NULL);
|
kt_register(Autoarr_i8);
|
||||||
kt_register(Autoarr_int16, ____Autoarr_free_int16, NULL);
|
kt_register(Autoarr_u8);
|
||||||
kt_register(Autoarr_uint16, ____Autoarr_free_uint16, NULL);
|
kt_register(Autoarr_i16);
|
||||||
kt_register(Autoarr_int32, ____Autoarr_free_int32, NULL);
|
kt_register(Autoarr_u16);
|
||||||
kt_register(Autoarr_uint32, ____Autoarr_free_uint32, NULL);
|
kt_register(Autoarr_i32);
|
||||||
kt_register(Autoarr_int64, ____Autoarr_free_int64, NULL);
|
kt_register(Autoarr_u32);
|
||||||
kt_register(Autoarr_uint64, ____Autoarr_free_uint64, NULL);
|
kt_register(Autoarr_i64);
|
||||||
|
kt_register(Autoarr_u64);
|
||||||
|
|
||||||
// Unitype
|
// Unitype
|
||||||
kt_register(Unitype, __UnitypePtr_free, NULL);
|
kt_register(Unitype);
|
||||||
kt_register(Array_Unitype, (freeMembers_t)Array_Unitype_freeValues, NULL);
|
kt_register(Array_Unitype);
|
||||||
kt_register(Autoarr_Unitype, ____Autoarr_free_Unitype_, NULL);
|
kt_register(Autoarr_Unitype);
|
||||||
// replacing autogenerated freear() function to custom
|
|
||||||
Autoarr_Unitype* _uar=Autoarr_create(Unitype, 1, 1);
|
|
||||||
_uar->functions->freear=__Autoarr_free_Unitype_;
|
|
||||||
Autoarr_free(_uar, true);
|
|
||||||
|
|
||||||
// SearchTreeNode
|
// STNode
|
||||||
kt_register(STNode, __STNode_free, NULL);
|
kt_register(STNode);
|
||||||
|
|
||||||
// KeyValuePair
|
// KeyValuePair
|
||||||
kt_register(KVPair, __KVPair_free, NULL);
|
kt_register(KVPair);
|
||||||
kt_register(Autoarr_KVPair, ____Autoarr_free_KVPair_, NULL);
|
kt_register(Autoarr_KVPair);
|
||||||
// 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
|
// Hashtable
|
||||||
kt_register(Hashtable, __Hashtable_free, NULL);
|
kt_register(Hashtable);
|
||||||
|
|
||||||
// string
|
// string
|
||||||
kt_register(string, NULL, NULL);
|
kt_register(string);
|
||||||
kt_register(Autoarr_string, ____Autoarr_free_string, NULL);
|
kt_register(Array_string);
|
||||||
|
kt_register(Autoarr_string);
|
||||||
|
|
||||||
// StringBuilder
|
// StringBuilder
|
||||||
kt_register(StringBuilder, __StringBuilder_free, NULL);
|
kt_register(StringBuilder);
|
||||||
|
|
||||||
|
//File
|
||||||
|
kt_register(FileHandle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// call this between ktDescriptors_beginInit() and ktDescriptors_endInit()
|
// call this between kt_beginInit() and kt_endInit()
|
||||||
void ktDescriptors_initKerepTypes();
|
void kt_initKerepTypes();
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,45 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
#include "ktid.h"
|
#include "ktid.h"
|
||||||
|
#include "typedef_macros.h"
|
||||||
|
|
||||||
|
#define kt_declare(TYPE)\
|
||||||
|
ktid_declare(TYPE);\
|
||||||
|
extern ktDescriptor ktDescriptor_##TYPE; \
|
||||||
|
extern ktDescriptor ktDescriptor_##TYPE##_Ptr;
|
||||||
|
|
||||||
|
#define kt_define(TYPE, FREE_MEMBERS_F, TOSTRING_F)\
|
||||||
|
ktid_define(TYPE); \
|
||||||
|
ktDescriptor ktDescriptor_##TYPE={ \
|
||||||
|
.name=#TYPE, \
|
||||||
|
.id=ktid_undefined, \
|
||||||
|
.size=sizeof(TYPE), \
|
||||||
|
.freeMembers=FREE_MEMBERS_F, \
|
||||||
|
.toString=TOSTRING_F \
|
||||||
|
}; \
|
||||||
|
ktDescriptor ktDescriptor_##TYPE##_Ptr={\
|
||||||
|
.name=#TYPE "_Ptr", \
|
||||||
|
.id=ktid_undefined, \
|
||||||
|
.size=sizeof(TYPE), \
|
||||||
|
.freeMembers=FREE_MEMBERS_F, \
|
||||||
|
.toString=TOSTRING_F \
|
||||||
|
};
|
||||||
|
|
||||||
typedef void (*freeMembers_t)(void*);
|
typedef void (*freeMembers_t)(void*);
|
||||||
typedef char* (*toString_t)(void* obj, uint32 fmt);
|
typedef char* (*toString_t)(void* obj, u32 fmt);
|
||||||
typedef struct ktDescriptor{
|
|
||||||
|
STRUCT(ktDescriptor,
|
||||||
char* name;
|
char* name;
|
||||||
ktid id;
|
ktid id;
|
||||||
uint16 size;
|
u16 size;
|
||||||
freeMembers_t freeMembers; // NULL or function which frees all struct members
|
freeMembers_t freeMembers; // NULL or function which frees all struct members
|
||||||
toString_t toString; // NULL or function which generates string representaion of object
|
toString_t toString; // NULL or function which generates string representaion of object
|
||||||
} ktDescriptor;
|
)
|
||||||
|
|
||||||
|
/// gets descriptor for TYPE
|
||||||
|
#define ktDescriptor_name(TYPE) ktDescriptor_##TYPE
|
||||||
|
/// gets descriptor for pointer to TYPE
|
||||||
|
#define ktDescriptor_namePtr(TYPE) ktDescriptor_##TYPE##_Ptr
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,68 +1,86 @@
|
|||||||
#include "../../Autoarr/Autoarr.h"
|
#include "../../Autoarr/Autoarr.h"
|
||||||
|
#include "type_system.h"
|
||||||
|
#include "base_toString.h"
|
||||||
|
|
||||||
Autoarr_declare(ktDescriptor)
|
kt_define(Pointer, NULL, __toString_u64);
|
||||||
Autoarr_define(ktDescriptor)
|
kt_define(char,NULL, __toString_char);
|
||||||
|
kt_define(bool,NULL, __toString_bool);
|
||||||
|
kt_define(f32, NULL, __toString_f32);
|
||||||
|
kt_define(f64, NULL, __toString_f64);
|
||||||
|
kt_define(i8, NULL, __toString_i8);
|
||||||
|
kt_define(u8, NULL, __toString_u8);
|
||||||
|
kt_define(i16, NULL, __toString_i16);
|
||||||
|
kt_define(u16, NULL, __toString_u16);
|
||||||
|
kt_define(i32, NULL, __toString_i32);
|
||||||
|
kt_define(u32, NULL, __toString_u32);
|
||||||
|
kt_define(i64, NULL, __toString_i64);
|
||||||
|
kt_define(u64, NULL, __toString_u64);
|
||||||
|
|
||||||
ktid ktid_Null=-1;
|
|
||||||
|
|
||||||
ktid_define(char);
|
char* ktDescriptor_toString(ktDescriptor* d){
|
||||||
ktid_define(bool);
|
const char* n="null";
|
||||||
ktid_define(float32);
|
char *s0 = toString_u64(d->id, 0,0);
|
||||||
ktid_define(float64);
|
char *s1 = toString_u64(d->size, 0,0);
|
||||||
ktid_define(int8);
|
char *s2 = d->toString ? toString_hex(d->toString, sizeof(void*), 0,1,0) : n;
|
||||||
ktid_define(uint8);
|
char *s3 = d->freeMembers ? toString_hex(d->freeMembers, sizeof(void*), 0,1,0) : n;
|
||||||
ktid_define(int16);
|
char *rez=cptr_concat("ktDescriptor {"
|
||||||
ktid_define(uint16);
|
" name:", d->name,
|
||||||
ktid_define(int32);
|
" id:",s0,
|
||||||
ktid_define(uint32);
|
" size:",s1,
|
||||||
ktid_define(int64);
|
" toString:",s2,
|
||||||
ktid_define(uint64);
|
" freeMembers:",s3,
|
||||||
|
" }");
|
||||||
ktid_define(ktDescriptor);
|
free(s0);
|
||||||
|
free(s1);
|
||||||
// type descriptors are stored here during initialization
|
if(s2!=n) free(s2);
|
||||||
Autoarr(ktDescriptor)* __ktDescriptors=NULL;
|
if(s3!=n) free(s3);
|
||||||
// here type descriptors are stored when initialization is complited
|
return rez;
|
||||||
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(){
|
char* _ktDescriptor_toString(void* _d, u32 fmt) { return ktDescriptor_toString(_d); }
|
||||||
typeDescriptors=Autoarr_toArray(__ktDescriptors);
|
|
||||||
Autoarr_free(__ktDescriptors,true);
|
kt_define(ktDescriptor, NULL, _ktDescriptor_toString);
|
||||||
|
|
||||||
|
typedef ktDescriptor* ktDescriptor_Ptr;
|
||||||
|
|
||||||
|
// type descriptors are stored here during initialization
|
||||||
|
Autoarr(Pointer)* __descriptorPointers=NULL;
|
||||||
|
// here type descriptors are stored when initialization is complited
|
||||||
|
ktDescriptor** typeDescriptors=NULL;
|
||||||
|
ktid ktid_last=-1;
|
||||||
|
|
||||||
|
ENUM(ktDescriptorsState,
|
||||||
|
NotInitialized, Initializing, Initialized
|
||||||
|
)
|
||||||
|
ktDescriptorsState initState=NotInitialized;
|
||||||
|
|
||||||
|
void kt_beginInit(){
|
||||||
|
kprintf("\e[94mtype descriptors initializing...\n");
|
||||||
|
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
void kt_endInit(){
|
||||||
|
if(__descriptorPointers==NULL)
|
||||||
|
throw(ERR_NULLPTR);
|
||||||
|
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
|
||||||
|
Autoarr_free(__descriptorPointers,true);
|
||||||
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
|
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
|
||||||
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32)){
|
void __kt_register(ktDescriptor* descriptor){
|
||||||
ktDescriptor typeDesc={
|
descriptor->id=++ktid_last;
|
||||||
.name=name,
|
Autoarr_add(__descriptorPointers, descriptor);
|
||||||
.size=size,
|
|
||||||
.id=++ktid_last,
|
|
||||||
.freeMembers=freeMembers,
|
|
||||||
.toString=toString
|
|
||||||
};
|
|
||||||
Autoarr_add(__ktDescriptors, typeDesc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ktDescriptor ktDescriptor_get(ktid id){
|
ktDescriptor* ktDescriptor_get(ktid id){
|
||||||
if(id>ktid_last) {
|
if(id>ktid_last || id==ktid_undefined) {
|
||||||
kprintf("\ntype id: %u\n",id);
|
kprintf("\ntype id: %u\n",id);
|
||||||
throw("invalid type id");
|
throw("invalid type id");
|
||||||
}
|
}
|
||||||
return typeDescriptors[id];
|
return typeDescriptors[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ktDescriptors_free(){
|
void kt_free(){
|
||||||
free(typeDescriptors);
|
free(typeDescriptors);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,39 +9,40 @@ extern "C" {
|
|||||||
#include "ktDescriptor.h"
|
#include "ktDescriptor.h"
|
||||||
|
|
||||||
extern ktid ktid_last;
|
extern ktid ktid_last;
|
||||||
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32));
|
void __kt_register(ktDescriptor* descriptor);
|
||||||
|
|
||||||
#define kt_register(TYPE, FREE_MEMBERS_FUNC, TO_STRING_FUNC)\
|
#define kt_register(TYPE) \
|
||||||
__kt_register(#TYPE, sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
|
__kt_register(&ktDescriptor_##TYPE); \
|
||||||
ktid_##TYPE=ktid_last;\
|
ktid_##TYPE=ktid_last; \
|
||||||
__kt_register(#TYPE "*", sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
|
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
|
||||||
ktid_##TYPE##_Ptr=ktid_last;
|
ktid_##TYPE##_Ptr=ktid_last;
|
||||||
|
|
||||||
void ktDescriptors_beginInit();
|
void kt_beginInit();
|
||||||
void ktDescriptors_endInit();
|
void kt_endInit();
|
||||||
|
|
||||||
/// @param id id of registered type
|
/// @param id id of registered type
|
||||||
ktDescriptor ktDescriptor_get(ktid id);
|
ktDescriptor* ktDescriptor_get(ktid id);
|
||||||
|
|
||||||
|
char* ktDescriptor_toString(ktDescriptor* d);
|
||||||
|
|
||||||
// call it to free heap-allocated ktDescriptors array
|
// call it to free heap-allocated ktDescriptors array
|
||||||
void ktDescriptors_free();
|
void kt_free();
|
||||||
|
|
||||||
extern ktid ktid_Null;
|
kt_declare(Pointer);
|
||||||
|
kt_declare(char);
|
||||||
|
kt_declare(bool);
|
||||||
|
kt_declare(f32);
|
||||||
|
kt_declare(f64);
|
||||||
|
kt_declare(i8);
|
||||||
|
kt_declare(u8);
|
||||||
|
kt_declare(i16);
|
||||||
|
kt_declare(u16);
|
||||||
|
kt_declare(i32);
|
||||||
|
kt_declare(u32);
|
||||||
|
kt_declare(i64);
|
||||||
|
kt_declare(u64);
|
||||||
|
|
||||||
ktid_declare(char);
|
kt_declare(ktDescriptor);
|
||||||
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(ktDescriptor);
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,17 +5,22 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../std.h"
|
#include "../std.h"
|
||||||
typedef uint16 ktid;
|
#include "typedef_macros.h"
|
||||||
|
|
||||||
|
typedef u16 ktid;
|
||||||
|
static const ktid ktid_undefined=-1;
|
||||||
|
|
||||||
|
/// gets descriptor id for TYPE
|
||||||
#define ktid_name(TYPE) ktid_##TYPE
|
#define ktid_name(TYPE) ktid_##TYPE
|
||||||
|
/// gets descriptor id for pointer to TYPE
|
||||||
#define ktid_ptrName(TYPE) ktid_##TYPE##_Ptr
|
#define ktid_ptrName(TYPE) ktid_##TYPE##_Ptr
|
||||||
|
|
||||||
#define ktid_declare(TYPE)\
|
#define ktid_declare(TYPE) \
|
||||||
extern ktid ktid_##TYPE;\
|
extern ktid ktid_##TYPE; \
|
||||||
extern ktid ktid_##TYPE##_Ptr;
|
extern ktid ktid_##TYPE##_Ptr;
|
||||||
|
|
||||||
#define ktid_define(TYPE)\
|
#define ktid_define(TYPE) \
|
||||||
ktid ktid_##TYPE=-1;\
|
ktid ktid_##TYPE=-1; \
|
||||||
ktid ktid_##TYPE##_Ptr=-1;
|
ktid ktid_##TYPE##_Ptr=-1;
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "ktid.h"
|
#include "ktid.h"
|
||||||
#include "ktDescriptor.h"
|
#include "ktDescriptor.h"
|
||||||
#include "kt_functions.h"
|
#include "kt_functions.h"
|
||||||
#include "unitype.h"
|
#include "unitype.h"
|
||||||
|
#include "typedef_macros.h"
|
||||||
|
|||||||
15
src/base/type_system/typedef_macros.h
Normal file
15
src/base/type_system/typedef_macros.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
|
||||||
|
ENUM_MEMBERS \
|
||||||
|
} ENUM_NAME;
|
||||||
|
|
||||||
|
#define PACKED_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
|
||||||
|
ENUM_MEMBERS \
|
||||||
|
} __attribute__((__packed__)) ENUM_NAME;
|
||||||
|
|
||||||
|
#define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \
|
||||||
|
typedef struct STRUCT_NAME { \
|
||||||
|
STRUCT_MEMBERS \
|
||||||
|
} STRUCT_NAME; \
|
||||||
|
kt_declare(STRUCT_NAME);
|
||||||
@@ -1,52 +1,100 @@
|
|||||||
|
#include "../../kprint/kprint_format.h"
|
||||||
#include "../base.h"
|
#include "../base.h"
|
||||||
|
|
||||||
ktid_define(Unitype);
|
char *__Unitype_toString(void *_u, u32 fmt)
|
||||||
|
{
|
||||||
|
return Unitype_toString(*(Unitype *)_u, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
void Unitype_free(Unitype u){
|
kt_define(Unitype, __UnitypePtr_free, __Unitype_toString);
|
||||||
ktDescriptor type=ktDescriptor_get(u.typeId);
|
|
||||||
if(type.freeMembers)
|
void Unitype_free(Unitype u)
|
||||||
type.freeMembers(u.VoidPtr);
|
{
|
||||||
if(u.allocatedInHeap)
|
if (u.typeId == ktid_undefined)
|
||||||
|
{
|
||||||
|
if (u.VoidPtr != NULL)
|
||||||
|
throw("unitype with undefined typeId has value");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ktDescriptor *type = ktDescriptor_get(u.typeId);
|
||||||
|
if (type->freeMembers)
|
||||||
|
type->freeMembers(u.VoidPtr);
|
||||||
|
if (u.allocatedInHeap)
|
||||||
free(u.VoidPtr);
|
free(u.VoidPtr);
|
||||||
}
|
}
|
||||||
void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
|
void __UnitypePtr_free(void *u)
|
||||||
|
{
|
||||||
|
Unitype_free(*(Unitype *)u);
|
||||||
|
}
|
||||||
|
|
||||||
char* toString_Unitype(void* _u, uint32 fmt){
|
char *Unitype_toString(Unitype u, u32 fmt)
|
||||||
Unitype* u=_u;
|
{
|
||||||
ktDescriptor type=ktDescriptor_get(u->typeId);
|
if (u.typeId == ktid_undefined)
|
||||||
char* valuestr=type.toString(_u, fmt);
|
{
|
||||||
char* rezult=cptr_concat("{ type: ", type.name,
|
if (u.VoidPtr != NULL)
|
||||||
", allocated on heap: ", (u->allocatedInHeap ? "true" : "false"),
|
throw("unitype with undefined typeId has value");
|
||||||
", value:", valuestr, " }");
|
return cptr_copy("{ERROR_TYPE}");
|
||||||
free(valuestr);
|
}
|
||||||
|
|
||||||
|
if (fmt == 0)
|
||||||
|
{
|
||||||
|
if (u.typeId == ktid_name(bool) || u.typeId == ktid_name(i8) || u.typeId == ktid_name(i16) ||
|
||||||
|
u.typeId == ktid_name(i32) || u.typeId == ktid_name(i64))
|
||||||
|
{
|
||||||
|
// auto format set
|
||||||
|
fmt = kp_i;
|
||||||
|
// replaces value with pointer to value to pass into toString_i64(void*, u32)
|
||||||
|
i64 value = u.Int64;
|
||||||
|
u.VoidPtr = &value;
|
||||||
|
}
|
||||||
|
else if (u.typeId == ktid_name(u8) || u.typeId == ktid_name(u16) || u.typeId == ktid_name(u32) ||
|
||||||
|
u.typeId == ktid_name(u64))
|
||||||
|
{
|
||||||
|
fmt = kp_u;
|
||||||
|
u64 value = u.UInt64;
|
||||||
|
u.VoidPtr = &value;
|
||||||
|
}
|
||||||
|
else if (u.typeId == ktid_name(f32) || u.typeId == ktid_name(f64))
|
||||||
|
{
|
||||||
|
fmt = kp_f;
|
||||||
|
f64 value = u.Float64;
|
||||||
|
u.VoidPtr = &value;
|
||||||
|
}
|
||||||
|
else if (u.typeId == ktid_name(char))
|
||||||
|
{
|
||||||
|
fmt = kp_c;
|
||||||
|
i64 value = u.Int64;
|
||||||
|
u.VoidPtr = &value;
|
||||||
|
}
|
||||||
|
else if (u.typeId == ktid_ptrName(char))
|
||||||
|
{
|
||||||
|
fmt = kp_s;
|
||||||
|
}
|
||||||
|
else if (u.typeId == ktid_name(Pointer))
|
||||||
|
{
|
||||||
|
if (u.VoidPtr == NULL)
|
||||||
|
return cptr_copy("{ UniNull }");
|
||||||
|
fmt = kp_h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ktDescriptor *type = ktDescriptor_get(u.typeId);
|
||||||
|
char *valuestr;
|
||||||
|
if (type->toString)
|
||||||
|
valuestr = type->toString(u.VoidPtr, fmt);
|
||||||
|
else
|
||||||
|
valuestr = "ERR_NO_TOSTRING_FUNC";
|
||||||
|
char *rezult = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
|
||||||
|
", value:", valuestr, " }");
|
||||||
|
if (type->toString)
|
||||||
|
free(valuestr);
|
||||||
return rezult;
|
return rezult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void printuni(Unitype v)
|
||||||
|
{
|
||||||
#define BUFSIZE 64
|
char *s = Unitype_toString(v, 0);
|
||||||
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_name(float64))
|
|
||||||
sprintf_s(buf, BUFSIZE, "{%s : %lf}", type.name,v.Float64);
|
|
||||||
else if(v.typeId==ktid_name(bool) || v.typeId==ktid_name(uint64))
|
|
||||||
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%llu", "%lu") "}", type.name,v.UInt64);
|
|
||||||
else if(v.typeId==ktid_name(int64))
|
|
||||||
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%lld", "%ld") "}", type.name,v.Int64);
|
|
||||||
else if(v.typeId==ktid_ptrName(char)){
|
|
||||||
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);
|
fputs(s, stdout);
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
@@ -5,44 +5,50 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ktid.h"
|
#include "ktid.h"
|
||||||
|
#include "typedef_macros.h"
|
||||||
|
|
||||||
typedef struct Unitype{
|
STRUCT(Unitype,
|
||||||
union {
|
union {
|
||||||
int64 Int64;
|
i64 Int64;
|
||||||
uint64 UInt64;
|
u64 UInt64;
|
||||||
double Float64;
|
f64 Float64;
|
||||||
bool Bool;
|
bool Bool;
|
||||||
void* VoidPtr;
|
void* VoidPtr;
|
||||||
char Bytes[8];
|
char Bytes[8];
|
||||||
};
|
};
|
||||||
ktid typeId;
|
ktid typeId;
|
||||||
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
|
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
|
||||||
} Unitype;
|
)
|
||||||
ktid_declare(Unitype);
|
|
||||||
|
|
||||||
|
|
||||||
#define __UniDef(FIELD, TYPE, VAL) (Unitype){\
|
#define __UniDef(FIELD, TYPE, VAL) ((Unitype){ \
|
||||||
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false}
|
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false})
|
||||||
|
|
||||||
#define UniInt64(VAL) __UniDef(Int64, int64, VAL)
|
#define UniInt64(VAL) __UniDef(Int64, i64, VAL)
|
||||||
#define UniUInt64(VAL) __UniDef(UInt64, uint64, VAL)
|
#define UniUInt64(VAL) __UniDef(UInt64, u64, VAL)
|
||||||
#define UniFloat64(VAL) __UniDef(Float64, float64, VAL)
|
#define UniFloat64(VAL) __UniDef(Float64, f64, VAL)
|
||||||
#define UniBool(VAL) __UniDef(Bool, bool, VAL)
|
#define UniBool(VAL) __UniDef(Bool, bool, VAL)
|
||||||
|
|
||||||
#define UniStackPtr(TYPE, VAL) (Unitype){\
|
#define UniPtr(TYPE_ID, VAL, ALLOCATED_ON_HEAP)((Unitype){ \
|
||||||
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=false}
|
.VoidPtr=VAL, .typeId=TYPE_ID, .allocatedInHeap=ALLOCATED_ON_HEAP })
|
||||||
#define UniHeapPtr(TYPE, VAL) (Unitype){\
|
#define UniStackPtr(TYPE, VAL) UniPtr(ktid_ptrName(TYPE), VAL, false)
|
||||||
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=true}
|
#define UniHeapPtr(TYPE, VAL) UniPtr(ktid_ptrName(TYPE), VAL, true)
|
||||||
|
// 0==ktid_Pointer
|
||||||
#define UniNull (Unitype){.Int64=0, .typeId=ktid_Null, .allocatedInHeap=false}
|
#define UniNull ((Unitype){.Int64=0, .typeId=0, .allocatedInHeap=false})
|
||||||
#define UniTrue UniBool(true)
|
#define UniTrue UniBool(true)
|
||||||
#define UniFalse UniBool(false)
|
#define UniFalse UniBool(false)
|
||||||
|
|
||||||
|
#define Unitype_isUniNull(UNI) (UNI.typeId==0 && UNI.Int64==0)
|
||||||
|
|
||||||
|
#define UniCheckTypeId(UNI, TYPE_ID) (UNI.typeId==TYPE_ID)
|
||||||
|
#define UniCheckType(UNI, TYPE) UniCheckTypeId(UNI, ktid_name(TYPE))
|
||||||
|
#define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE))
|
||||||
|
|
||||||
// frees VoidPtr value or does nothing if type isn't pointer
|
// frees VoidPtr value or does nothing if type isn't pointer
|
||||||
void Unitype_free(Unitype u);
|
void Unitype_free(Unitype u);
|
||||||
void __UnitypePtr_free(void* u);
|
void __UnitypePtr_free(void* u);
|
||||||
|
char* Unitype_toString(Unitype v, u32 fmt);
|
||||||
void printuni(Unitype v);
|
void printuni(Unitype v);
|
||||||
char* sprintuni(Unitype v);
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,18 @@
|
|||||||
It is just my cross-plaform variant of printf.
|
It is just my cross-plaform variant of printf.
|
||||||
Unlike in standard printf, `%l...` and `%ll...` placeholders dont depend on size of `long int` and `long long int`. And you can change terminal colors by unix codes (`\e[92m`) even on Windows.
|
Unlike in standard printf, `%l...` and `%ll...` placeholders dont depend on size of `long int` and `long long int`. And you can change terminal colors by unix codes (`\e[92m`) even on Windows.
|
||||||
|
|
||||||
| type | placeholder |
|
| type | placeholder |
|
||||||
|-------------------------|-------------------------|
|
|----------------|-------------------------|
|
||||||
| int8 / int16 / int32 | %i / %d |
|
| i8 / i16 / i32 | %i / %d |
|
||||||
| int64 | %li / %ld / %lld / %lli |
|
| i64 | %li / %ld / %lld / %lli |
|
||||||
| uint8 / uint16 / uint32 | %u |
|
| u8 / u16 / u32 | %u |
|
||||||
| uint64 | %lu / %llu |
|
| u64 | %lu / %llu |
|
||||||
| float32 / float64 | %f |
|
| f32 / f64 | %f |
|
||||||
| char | %c |
|
| char | %c |
|
||||||
| char[] | %s |
|
| char[] | %s |
|
||||||
| void\* | %p / %x |
|
| void\* | %p |
|
||||||
|
| 32bit or less | %x |
|
||||||
|
| 64bit | %lx |
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
@@ -27,7 +29,7 @@ I don't really like printf function (and its variants), so i made safer and more
|
|||||||
## how to use it:
|
## how to use it:
|
||||||
+ **format construction:**
|
+ **format construction:**
|
||||||
```
|
```
|
||||||
kp_fmt fmt= kp_fgColor | kp_bgColor | kprint_fdataFmt | flags | ktid;
|
kp_fmt fmt= kp_fgColor | kp_bgColor | kp_dataFmt | flags | ktid;
|
||||||
```
|
```
|
||||||
[more about `kp_fmt`](kp_fmt.md)
|
[more about `kp_fmt`](kp_fmt.md)
|
||||||
+ fgColor and bgColor can be set to change console output color
|
+ fgColor and bgColor can be set to change console output color
|
||||||
@@ -47,4 +49,4 @@ I don't really like printf function (and its variants), so i made safer and more
|
|||||||
Maybe m=MaybeNull;
|
Maybe m=MaybeNull;
|
||||||
kprint(kp_fgBlue|kp_s, "Maybe: ", kp_fgGreen|ktid_MaybePtr, &m);
|
kprint(kp_fgBlue|kp_s, "Maybe: ", kp_fgGreen|ktid_MaybePtr, &m);
|
||||||
```
|
```
|
||||||
output: <span style="color:blue">Maybe:</span> <span style="color:lightgreen">{value={0, ktid_Null}}</span>
|
output: <span style="color:blue">Maybe:</span> <span style="color:lightgreen">{value: { Pointer, 0x0 }}</span>
|
||||||
|
|||||||
@@ -9,42 +9,46 @@ ktid __typeFromFormat(kp_fmt f){
|
|||||||
case kp_i:
|
case kp_i:
|
||||||
case kp_h:
|
case kp_h:
|
||||||
case kp_b:
|
case kp_b:
|
||||||
return ktid_name(int64);
|
return ktid_name(i64);
|
||||||
case kp_u:
|
case kp_u:
|
||||||
return ktid_name(uint64);
|
return ktid_name(u64);
|
||||||
case kp_f:
|
case kp_f:
|
||||||
return ktid_name(float64);
|
return ktid_name(f64);
|
||||||
case kp_c:
|
case kp_c:
|
||||||
return ktid_char;
|
return ktid_name(char);
|
||||||
case kp_s:
|
case kp_s:
|
||||||
return ktid_ptrName(char);
|
return ktid_ptrName(char);
|
||||||
default:
|
default:
|
||||||
return -1;
|
return ktid_undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe __next_toString(kp_fmt f, __kp_value_union* object){
|
Maybe __next_toString(kp_fmt f, void* object){
|
||||||
// detecting type
|
// detecting type
|
||||||
ktid typeId=__typeFromFormat(f);
|
ktid typeId=__typeFromFormat(f);
|
||||||
if(typeId==-1)
|
if(typeId==ktid_undefined)
|
||||||
safethrow("typeId is not set, can't autodetect type",;);
|
safethrow("typeId is undefined, can't autodetect type",;);
|
||||||
ktDescriptor typeDesc=ktDescriptor_get(typeId);
|
|
||||||
if(!typeDesc.toString)
|
if(typeId==ktid_ptrName(char))
|
||||||
|
object=*(char**)object; // dereferencing char** to char*
|
||||||
|
|
||||||
|
ktDescriptor* type=ktDescriptor_get(typeId);
|
||||||
|
if(!type->toString)
|
||||||
safethrow("type descriptor doesnt have toString() func",;);
|
safethrow("type descriptor doesnt have toString() func",;);
|
||||||
return SUCCESS(UniHeapPtr(char, typeDesc.toString(object, f)));
|
return SUCCESS(UniHeapPtr(char, type->toString(object, f)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe check_argsN(uint8 n){
|
Maybe check_argsN(u8 n){
|
||||||
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
|
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
|
||||||
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
|
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
|
||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe __ksprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
|
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
try(check_argsN(n), _,;);
|
try(check_argsN(n), _,;);
|
||||||
n/=2;
|
n/=2;
|
||||||
StringBuilder* strb=StringBuilder_create();
|
StringBuilder* strb=StringBuilder_create();
|
||||||
for(uint8 i=0; i<n; i++){
|
for(u8 i=0; i<n; i++){
|
||||||
try(__next_toString(formats[i], &objects[i]),mStr,;);
|
try(__next_toString(formats[i], &objects[i]),mStr,;);
|
||||||
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
|
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
|
||||||
Unitype_free(mStr.value);
|
Unitype_free(mStr.value);
|
||||||
@@ -53,10 +57,10 @@ Maybe __ksprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
|
|||||||
return SUCCESS(UniHeapPtr(char, rezult));
|
return SUCCESS(UniHeapPtr(char, rezult));
|
||||||
}
|
}
|
||||||
|
|
||||||
Maybe __kfprint(FILE* file, uint8 n, kp_fmt* formats, __kp_value_union* objects){
|
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
try(check_argsN(n), _,;);
|
try(check_argsN(n), _,;);
|
||||||
n/=2;
|
n/=2;
|
||||||
for(uint8 i=0; i<n; i++){
|
for(u8 i=0; i<n; i++){
|
||||||
try(__next_toString(formats[i], &objects[i]),maybeStr,;);
|
try(__next_toString(formats[i], &objects[i]),maybeStr,;);
|
||||||
if(fputs(maybeStr.value.VoidPtr, file)==EOF)
|
if(fputs(maybeStr.value.VoidPtr, file)==EOF)
|
||||||
safethrow("can't write string to file", Unitype_free(maybeStr.value));
|
safethrow("can't write string to file", Unitype_free(maybeStr.value));
|
||||||
@@ -66,14 +70,14 @@ Maybe __kfprint(FILE* file, uint8 n, kp_fmt* formats, __kp_value_union* objects)
|
|||||||
return MaybeNull;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __kprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
|
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
tryLast(check_argsN(n), _);
|
tryLast(check_argsN(n), _,;);
|
||||||
n/=2;
|
n/=2;
|
||||||
for(uint8 i=0; i<n; i++){
|
for(u8 i=0; i<n; i++){
|
||||||
kp_fmt fmt=formats[i];
|
kp_fmt fmt=formats[i];
|
||||||
kprint_setColor(fmt);
|
kprint_setColor(fmt);
|
||||||
tryLast(__next_toString(fmt, &objects[i]),maybeStr);
|
tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray));
|
||||||
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF)\
|
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \
|
||||||
throw("can't write string to stdout");
|
throw("can't write string to stdout");
|
||||||
//, Unitype_free(maybeStr.value)
|
//, Unitype_free(maybeStr.value)
|
||||||
Unitype_free(maybeStr.value);
|
Unitype_free(maybeStr.value);
|
||||||
@@ -145,13 +149,13 @@ void kprint_setColor(kp_fmt f){
|
|||||||
#else
|
#else
|
||||||
void kprint_setColor(kp_fmt f){
|
void kprint_setColor(kp_fmt f){
|
||||||
if(kp_fmt_fgColorSet(f)){
|
if(kp_fmt_fgColorSet(f)){
|
||||||
uint8 fg=(f&0x0f000000)>>24;
|
u8 fg=(f&0x0f000000)>>24;
|
||||||
if(fg<8) fg+=30;
|
if(fg<8) fg+=30;
|
||||||
else fg+=90-8;
|
else fg+=90-8;
|
||||||
printf("\e[%um", fg);
|
printf("\e[%um", fg);
|
||||||
}
|
}
|
||||||
if(kp_fmt_bgColorSet(f)){
|
if(kp_fmt_bgColorSet(f)){
|
||||||
uint8 bg=(f&0x00f00000)>>20;
|
u8 bg=(f&0x00f00000)>>20;
|
||||||
if(bg<8) bg+=40;
|
if(bg<8) bg+=40;
|
||||||
else bg+=100-8;
|
else bg+=100-8;
|
||||||
printf("\e[%um", bg);
|
printf("\e[%um", bg);
|
||||||
@@ -159,15 +163,15 @@ void kprint_setColor(kp_fmt f){
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Maybe ksprint_ar(uint32 count, kp_fmt format, ktid typeId, void* array){
|
/* Maybe ksprint_ar(u32 count, kp_fmt format, ktid typeId, void* array){
|
||||||
ktDescriptor typeDesc=ktDescriptor_get(format.typeId);
|
ktDescriptor* type=ktDescriptor_get(format.typeId);
|
||||||
if(!typeDesc.toString)
|
if(!type->toString)
|
||||||
safethrow("type descriptor doesnt have toString() func",;);
|
safethrow("type descriptor doesnt have toString() func",;);
|
||||||
StringBuilder* strb=StringBuilder_create();
|
StringBuilder* strb=StringBuilder_create();
|
||||||
StringBuilder_append_char(strb, '[');
|
StringBuilder_append_char(strb, '[');
|
||||||
for (uint16 e=1; e<count; e++){
|
for (u16 e=1; e<count; e++){
|
||||||
StringBuilder_append_char(strb, ' ');
|
StringBuilder_append_char(strb, ' ');
|
||||||
char* elStr=typeDesc.toString(array+typeDesc.size*e, &format);
|
char* elStr=type->toString(array+type->size*e, &format);
|
||||||
StringBuilder_append_cptr(strb, elStr);
|
StringBuilder_append_cptr(strb, elStr);
|
||||||
StringBuilder_append_char(strb, ',');
|
StringBuilder_append_char(strb, ',');
|
||||||
}
|
}
|
||||||
@@ -175,3 +179,33 @@ void kprint_setColor(kp_fmt f){
|
|||||||
StringBuilder_append_char(strb, ' ');
|
StringBuilder_append_char(strb, ' ');
|
||||||
StringBuilder_append_char(strb, ']');
|
StringBuilder_append_char(strb, ']');
|
||||||
} */
|
} */
|
||||||
|
|
||||||
|
static const char* _kp_colorNames[16]={
|
||||||
|
"black",
|
||||||
|
"dark_red",
|
||||||
|
"dark_green",
|
||||||
|
"dark_yellow",
|
||||||
|
"dark_blue",
|
||||||
|
"dark_magenta",
|
||||||
|
"dark_cyan",
|
||||||
|
"gray",
|
||||||
|
"dark_gray",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"yellow",
|
||||||
|
"blue",
|
||||||
|
"magenta",
|
||||||
|
"cyan",
|
||||||
|
"white"
|
||||||
|
};
|
||||||
|
|
||||||
|
char* kp_bgColor_toString(kp_bgColor c){
|
||||||
|
u32 color_index=(c&0x00f00000)>>20;
|
||||||
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
|
return _kp_colorNames[color_index];
|
||||||
|
}
|
||||||
|
char* kp_fgColor_toString(kp_fgColor c){
|
||||||
|
u32 color_index=(c&0x00f00000)>>24;
|
||||||
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
|
return _kp_colorNames[color_index];
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../base/errors.h"
|
#include "../base/errors.h"
|
||||||
#include "kprint_colors.h"
|
|
||||||
#include "kprint_format.h"
|
#include "kprint_format.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -15,92 +14,89 @@ This file looks like a mess, but all cotnent here just solves the problem of put
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
int64 i64;
|
i64 i64;
|
||||||
uint64 u64;
|
u64 u64;
|
||||||
float64 f64;
|
f64 f64;
|
||||||
void* ptr;
|
void* ptr;
|
||||||
} __kp_value_union;
|
} __kp_value_union;
|
||||||
|
|
||||||
|
|
||||||
static inline __kp_value_union __kpVU_f(float64 f) { return (__kp_value_union){ .f64=f }; }
|
static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; }
|
||||||
inline __kp_value_union __kpVU_i(int64 f) { return (__kp_value_union){ .i64=f }; }
|
static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; }
|
||||||
|
|
||||||
#define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, double: __kpVU_f, default: __kpVU_i)(V)
|
#define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V)
|
||||||
|
|
||||||
#define __kpVU(V) __kpVU_selectType(V)
|
#define __kpVU(V) __kpVU_selectType(V)
|
||||||
|
|
||||||
#define __kp_argsToFmts8(\
|
#define __kp_argsToFmts8( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,...)\
|
a0, a1, a2, a3, a4, a5, a6, a7,...) \
|
||||||
((int32[]){ a0,a2,a4,a6 })
|
((i32[]){ a0,a2,a4,a6 })
|
||||||
#define __kp_argsToObjs8(\
|
#define __kp_argsToObjs8( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,...)\
|
a0, a1, a2, a3, a4, a5, a6, a7,...) \
|
||||||
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7) })
|
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7) })
|
||||||
|
|
||||||
#define __kp_argsToFmts16(\
|
#define __kp_argsToFmts16( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,\
|
a0, a1, a2, a3, a4, a5, a6, a7, \
|
||||||
a8, a9, a10,a11,a12,a13,a14,a15,...)\
|
a8, a9, a10,a11,a12,a13,a14,a15,...) \
|
||||||
((int32[]){ a0,a2,a4,a6,a8,a10,a12,a14 })
|
((i32[]){ a0,a2,a4,a6,a8,a10,a12,a14 })
|
||||||
#define __kp_argsToObjs16(\
|
#define __kp_argsToObjs16( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,\
|
a0, a1, a2, a3, a4, a5, a6, a7, \
|
||||||
a8, a9, a10,a11,a12,a13,a14,a15,...)\
|
a8, a9, a10,a11,a12,a13,a14,a15,...) \
|
||||||
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15) })
|
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15) })
|
||||||
|
|
||||||
#define __kp_argsToFmts32(\
|
#define __kp_argsToFmts32( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,\
|
a0, a1, a2, a3, a4, a5, a6, a7, \
|
||||||
a8, a9, a10,a11,a12,a13,a14,a15,\
|
a8, a9, a10,a11,a12,a13,a14,a15, \
|
||||||
a16,a17,a18,a19,a20,a21,a22,a23,\
|
a16,a17,a18,a19,a20,a21,a22,a23, \
|
||||||
a24,a25,a26,a27,a28,a29,a30,a31,...)\
|
a24,a25,a26,a27,a28,a29,a30,a31,...) \
|
||||||
((int32[]){ a0,a2,a4,a6,a8,a10,a12,a14,a16,a18,a20,a22,a24,a26,a28,a30 })
|
((i32[]){ a0,a2,a4,a6,a8,a10,a12,a14,a16,a18,a20,a22,a24,a26,a28,a30 })
|
||||||
#define __kp_argsToObjs32(\
|
#define __kp_argsToObjs32( \
|
||||||
a0, a1, a2, a3, a4, a5, a6, a7,\
|
a0, a1, a2, a3, a4, a5, a6, a7, \
|
||||||
a8, a9, a10,a11,a12,a13,a14,a15,\
|
a8, a9, a10,a11,a12,a13,a14,a15, \
|
||||||
a16,a17,a18,a19,a20,a21,a22,a23,\
|
a16,a17,a18,a19,a20,a21,a22,a23, \
|
||||||
a24,a25,a26,a27,a28,a29,a30,a31,...)\
|
a24,a25,a26,a27,a28,a29,a30,a31,...) \
|
||||||
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15),__kpVU(a17),__kpVU(a19),__kpVU(a21),__kpVU(a23),__kpVU(a25),__kpVU(a27),__kpVU(a29),__kpVU(a31) })
|
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15),__kpVU(a17),__kpVU(a19),__kpVU(a21),__kpVU(a23),__kpVU(a25),__kpVU(a27),__kpVU(a29),__kpVU(a31) })
|
||||||
|
|
||||||
#define __32zeroes 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
#define __32zeroes 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
|
|
||||||
#define __kp_argsToArrs(COUNT,ARGS...)\
|
#define __kp_argsToArrs(COUNT,ARGS...) \
|
||||||
(kp_fmt*)(\
|
(kp_fmt*)( \
|
||||||
COUNT<=8 ? __kp_argsToFmts8(ARGS) :\
|
COUNT<=8 ? __kp_argsToFmts8(ARGS) : \
|
||||||
COUNT<=16 ? __kp_argsToFmts16(ARGS) :\
|
COUNT<=16 ? __kp_argsToFmts16(ARGS) : \
|
||||||
__kp_argsToFmts32(ARGS)),\
|
__kp_argsToFmts32(ARGS)), \
|
||||||
(__kp_value_union*)(\
|
(__kp_value_union*)( \
|
||||||
COUNT<=8 ? __kp_argsToObjs8(ARGS) :\
|
COUNT<=8 ? __kp_argsToObjs8(ARGS) : \
|
||||||
COUNT<=16 ? __kp_argsToObjs16(ARGS) :\
|
COUNT<=16 ? __kp_argsToObjs16(ARGS) : \
|
||||||
__kp_argsToObjs32(ARGS))
|
__kp_argsToObjs32(ARGS))
|
||||||
|
|
||||||
|
|
||||||
Maybe __ksprint(uint8 n, kp_fmt* formats, __kp_value_union* objects);
|
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
|
||||||
|
|
||||||
/// @param ARGS kp_fmt, value, kp_fmt, value...
|
/// @param ARGS kp_fmt, value, kp_fmt, value...
|
||||||
///@returns Maybe<char*>
|
///@returns Maybe<char*>
|
||||||
#define ksprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION,\
|
#define ksprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
|
||||||
__ksprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes))\
|
__ksprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
|
||||||
)
|
)
|
||||||
/*-Wint-conversion warning was produced during value to __kp_value_union conversion*/
|
/*-Wint-conversion warning was produced during value to __kp_value_union conversion*/
|
||||||
|
|
||||||
Maybe __kfprint(FILE* fd, uint8 n, kp_fmt* formats, __kp_value_union* objects);
|
Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects);
|
||||||
|
|
||||||
/// @param FD FILE*
|
/// @param FD FILE*
|
||||||
/// @param ARGS kp_fmt, value, kp_fmt, value...
|
/// @param ARGS kp_fmt, value, kp_fmt, value...
|
||||||
///@returns Maybe<void>
|
///@returns Maybe<void>
|
||||||
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION,\
|
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
|
||||||
__kfprint(FD, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes))\
|
__kfprint(FD, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
|
||||||
)
|
)
|
||||||
|
|
||||||
void __kprint(uint8 n, kp_fmt* formats, __kp_value_union* objects);
|
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
|
||||||
|
|
||||||
///can use non-catchable throw !!!
|
///can use non-catchable throw !!!
|
||||||
///@param ARGS kp_fmt, value, kp_fmt, value...
|
///@param ARGS kp_fmt, value, kp_fmt, value...
|
||||||
///@returns void
|
///@returns void
|
||||||
#define kprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION,\
|
#define kprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
|
||||||
__kprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes))\
|
__kprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
|
||||||
)
|
)
|
||||||
|
|
||||||
///@param f bgColor | fgColor
|
|
||||||
void kprint_setColor(kp_fmt f);
|
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -8,7 +8,7 @@ extern "C" {
|
|||||||
// ^ ^^^^
|
// ^ ^^^^
|
||||||
// | color num
|
// | color num
|
||||||
// fgColorSet flag
|
// fgColorSet flag
|
||||||
PACK_ENUM(kp_fgColor,
|
PACKED_ENUM(kp_fgColor,
|
||||||
/// black foreground
|
/// black foreground
|
||||||
kp_fgBlack = 0x80000000,
|
kp_fgBlack = 0x80000000,
|
||||||
/// dark red foreground
|
/// dark red foreground
|
||||||
@@ -46,7 +46,7 @@ PACK_ENUM(kp_fgColor,
|
|||||||
// 01000000 00000000 00000000 00000000
|
// 01000000 00000000 00000000 00000000
|
||||||
// ^ ^^^^
|
// ^ ^^^^
|
||||||
// bgColorSet flag color num
|
// bgColorSet flag color num
|
||||||
PACK_ENUM(kp_bgColor,
|
PACKED_ENUM(kp_bgColor,
|
||||||
/// black background
|
/// black background
|
||||||
kp_bgBlack = 0x40000000,
|
kp_bgBlack = 0x40000000,
|
||||||
/// dark red background
|
/// dark red background
|
||||||
@@ -81,6 +81,9 @@ PACK_ENUM(kp_bgColor,
|
|||||||
kp_bgWhite = 0x40f00000
|
kp_bgWhite = 0x40f00000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
char* kp_bgColor_toString(kp_bgColor c);
|
||||||
|
char* kp_fgColor_toString(kp_fgColor c);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -6,11 +6,12 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../base/std.h"
|
#include "../base/std.h"
|
||||||
#include "../base/type_system/ktid.h"
|
#include "../base/type_system/ktid.h"
|
||||||
|
#include "kprint_colors.h"
|
||||||
|
|
||||||
/// kprint_format
|
/// kprint_format
|
||||||
typedef uint32 kp_fmt;
|
typedef u32 kp_fmt;
|
||||||
|
|
||||||
PACK_ENUM(kp_dataFmt,
|
PACKED_ENUM(kp_dataFmt,
|
||||||
// 00000000 00000000 00000000 00000000
|
// 00000000 00000000 00000000 00000000
|
||||||
// ^^^^
|
// ^^^^
|
||||||
// type
|
// type
|
||||||
@@ -44,6 +45,9 @@ PACK_ENUM(kp_dataFmt,
|
|||||||
#define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000)
|
#define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000)
|
||||||
#define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff)
|
#define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff)
|
||||||
|
|
||||||
|
///@param f bgColor | fgColor
|
||||||
|
void kprint_setColor(kp_fmt f);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -54,15 +54,17 @@ bgColorSet─┘││ │ bgColor └data format
|
|||||||
|
|
||||||
## Data format
|
## Data format
|
||||||
|
|
||||||
| format | possible flags | data types | hex value | bin value |
|
| format | possible flags | data types | hex value | bin value |
|
||||||
|-----------|----------------|------------|-----------|-----------|
|
|-----------|----------------|------------|------------|-----------|
|
||||||
| kp_i | | int8... int64 | 0x00000000 | 00000000 00000000... |
|
| kp_i | | i8... i64 | 0x00000000 | 00000000 00000000... |
|
||||||
| kp_u | Postfix, Upper | uint8... uint64 | 0x00010000 | 00000000 00000001... |
|
| kp_u | Postfix, Upper | u8... u64 | 0x00010000 | 00000000 00000001... |
|
||||||
| kp_h | Prefix, Upper | any | 0x00020000 | 00000000 00000010... |
|
| kp_h | Prefix, Upper | any | 0x00020000 | 00000000 00000010... |
|
||||||
| kp_b | Prefix | any | 0x00030000 | 00000000 00000011... |
|
| kp_b | Prefix | any | 0x00030000 | 00000000 00000011... |
|
||||||
| kp_f | Postfix, Upper | float32, float64 | 0x00040000 | 00000000 00000100... |
|
| kp_f | Postfix, Upper | f32, f64 | 0x00040000 | 00000000 00000100... |
|
||||||
| kp_c | | char | 0x00050000 | 00000000 00000101... |
|
| kp_c | | char | 0x00050000 | 00000000 00000101... |
|
||||||
| kp_sing | | char* | 0x00060000 | 00000000 00000110... |
|
| kp_string | | char* | 0x00060000 | 00000000 00000110... |
|
||||||
|
|
||||||
|
P.S. `any` means you must add `kpid` to `kp_fmt` if data type is not base type
|
||||||
|
|
||||||
### *Flags*
|
### *Flags*
|
||||||
| flag | hex value | bin value |
|
| flag | hex value | bin value |
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
#include "kprintf.h"
|
#include "kprintf.h"
|
||||||
#include "../base/base.h"
|
#include "../base/base.h"
|
||||||
#include "../base/type_system/base_toString.h"
|
|
||||||
|
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
WORD unixColorToWin(uint8 c){
|
WORD unixColorToWin(u8 c){
|
||||||
switch(c){
|
switch(c){
|
||||||
//foreground
|
//foreground
|
||||||
case 30: return 0;
|
case 30: return 0;
|
||||||
@@ -49,8 +48,9 @@ WORD unixColorToWin(uint8 c){
|
|||||||
void kprintf(const char* format, ...){
|
void kprintf(const char* format, ...){
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
uint32 i=0;
|
u32 i=0;
|
||||||
for(char c=format[i++]; c!=0; c=format[i++]){
|
for(char c=format[i++]; c!=0; c=format[i++]){
|
||||||
|
// value format specifiers
|
||||||
if(c=='%'){
|
if(c=='%'){
|
||||||
char* argstr=NULL;
|
char* argstr=NULL;
|
||||||
bool l=false;
|
bool l=false;
|
||||||
@@ -58,28 +58,37 @@ void kprintf(const char* format, ...){
|
|||||||
format_escape_seq:
|
format_escape_seq:
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'u':
|
case 'u':
|
||||||
argstr=toString_uint(
|
argstr=toString_u64(
|
||||||
l ? va_arg(vl, uint64) : va_arg(vl, uint32)
|
l ? va_arg(vl, u64) : va_arg(vl, u32)
|
||||||
,0,0);
|
,0,0);
|
||||||
break;
|
break;
|
||||||
case 'i': case 'd':
|
case 'i': case 'd':
|
||||||
argstr=toString_int(
|
argstr=toString_i64(
|
||||||
l ? va_arg(vl, int64) : va_arg(vl, int32)
|
l ? va_arg(vl, i64) : va_arg(vl, i32)
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
// float32 is promoted to float64 when passed through '...'
|
// f32 is promoted to f64 when passed through '...'
|
||||||
argstr=toString_float64(va_arg(vl, float64), toString_float_default_precision,0,0);
|
argstr=toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
l=true;
|
l=true;
|
||||||
if((c=format[i++]))
|
if((c=format[i++]))
|
||||||
goto format_escape_seq;
|
goto format_escape_seq;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p': ;
|
||||||
|
void* phex=va_arg(vl, void*);
|
||||||
|
argstr=toString_hex(&phex,getEndian()==LittleEndian,sizeof(phex),1,0);
|
||||||
|
break;
|
||||||
case 'x': ;
|
case 'x': ;
|
||||||
uint64 px=va_arg(vl, uint64);
|
if(l){
|
||||||
argstr=toString_hex(&px,getEndian()==LittleEndian,sizeof(px),1,0);
|
u64 xhex=va_arg(vl, u64);
|
||||||
|
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u32 xhex=va_arg(vl, u32);
|
||||||
|
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 's': ;
|
case 's': ;
|
||||||
char* cptr=va_arg(vl,char*);
|
char* cptr=va_arg(vl,char*);
|
||||||
@@ -104,19 +113,22 @@ void kprintf(const char* format, ...){
|
|||||||
fputs(argstr, stdout);
|
fputs(argstr, stdout);
|
||||||
free(argstr);
|
free(argstr);
|
||||||
}
|
}
|
||||||
} else if(c=='\e'){
|
}
|
||||||
|
// escape sequences
|
||||||
|
else if(c=='\e'){
|
||||||
IFWIN(
|
IFWIN(
|
||||||
|
/* WINDOWS */
|
||||||
({
|
({
|
||||||
if((c=format[i++])=='['){
|
if((c=format[i++])=='['){
|
||||||
uint8 colorUnix=0;
|
u8 colorUnix=0;
|
||||||
for(int8 n=0; n<6 && c!=0; n++){
|
for(i8 n=0; n<6 && c!=0; n++){
|
||||||
c=format[i++];
|
c=format[i++];
|
||||||
switch (c){
|
switch (c){
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
case '5': case '6': case '7': case '8': case '9':
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
colorUnix=colorUnix*10+c-'0';
|
colorUnix=colorUnix*10+c-'0';
|
||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm': ;
|
||||||
WORD colorWin=unixColorToWin(colorUnix);
|
WORD colorWin=unixColorToWin(colorUnix);
|
||||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
SetConsoleTextAttribute(hConsole, colorWin);
|
SetConsoleTextAttribute(hConsole, colorWin);
|
||||||
@@ -127,13 +139,16 @@ void kprintf(const char* format, ...){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
/* UNIX */
|
||||||
putc(c,stdout);
|
putc(c,stdout);
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
|
// common characters
|
||||||
|
else {
|
||||||
putc(c,stdout);
|
putc(c,stdout);
|
||||||
}
|
}
|
||||||
#if defined(_WIN64) || defined(_WIN32)
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
end_iteration:
|
end_iteration:;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../base/type_system/base_toString.h"
|
||||||
|
|
||||||
// cross-platform printf analog
|
// cross-platform printf analog
|
||||||
void kprintf(const char* format, ...);
|
void kprintf(const char* format, ...);
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ extern "C" {
|
|||||||
/*
|
/*
|
||||||
You can choose any algorithm that has required functions:
|
You can choose any algorithm that has required functions:
|
||||||
|
|
||||||
some_alg32_statePtr some_alg32_init(uint32 seed);
|
some_alg32_statePtr some_alg32_init(u32 seed);
|
||||||
uint32 some_alg32_next(some_alg32_statePtr);
|
u32 some_alg32_next(some_alg32_statePtr);
|
||||||
void some_alg32_free(some_alg32_statePtr);
|
void some_alg32_free(some_alg32_statePtr);
|
||||||
|
|
||||||
#define KRAND_ALG32_init some_alg32_init
|
#define KRAND_ALG32_init some_alg32_init
|
||||||
@@ -51,19 +51,19 @@ typedef void* krand_statePtr;
|
|||||||
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
|
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
|
||||||
|
|
||||||
// ready-to-use functions
|
// ready-to-use functions
|
||||||
static inline int8 krand_next8 (krand_statePtr state, int8 from, int8 to) __krand_next_definition(32)
|
static inline i8 krand_next8 (krand_statePtr state, i8 from, i8 to) __krand_next_definition(32)
|
||||||
static inline int16 krand_next16(krand_statePtr state, int16 from, int16 to) __krand_next_definition(32)
|
static inline i16 krand_next16(krand_statePtr state, i16 from, i16 to) __krand_next_definition(32)
|
||||||
static inline int32 krand_next32(krand_statePtr state, int32 from, int32 to) __krand_next_definition(32)
|
static inline i32 krand_next32(krand_statePtr state, i32 from, i32 to) __krand_next_definition(32)
|
||||||
static inline int64 krand_next64(krand_statePtr state, int64 from, int64 to) __krand_next_definition(64)
|
static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64)
|
||||||
|
|
||||||
// divides random number by 2^64 to return a value between 0 and 1
|
// 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 f32 krand_nextFloat32(krand_statePtr state) {return (u32)KRAND_ALG32_next(state)/0xffffffff; }
|
||||||
static inline float64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
|
static inline f64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
|
||||||
|
|
||||||
|
|
||||||
///@param chance (0-1.0) is probability of success
|
///@param chance (0-1.0) is probability of success
|
||||||
static inline bool fate(krand_statePtr state,float chance){
|
static inline bool fate(krand_statePtr state,float chance){
|
||||||
int limit=1/chance + 0.01f;
|
i32 limit=1/chance + 0.01f;
|
||||||
return KRAND_ALG32_next(state)%limit == 0;
|
return KRAND_ALG32_next(state)%limit == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,18 +13,18 @@ generator.
|
|||||||
|
|
||||||
// The state can be seeded with any (upto) 64 bit integer value.
|
// The state can be seeded with any (upto) 64 bit integer value.
|
||||||
|
|
||||||
void* splitmix64_init(uint64 seed){
|
void* splitmix64_init(u64 seed){
|
||||||
splitmix64_state* state=malloc(sizeof(splitmix64_state));
|
splitmix64_state* state=malloc(sizeof(splitmix64_state));
|
||||||
*state=seed;
|
*state=seed;
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 splitmix64_next(void* _state) {
|
u64 splitmix64_next(void* _state) {
|
||||||
splitmix64_state* state=_state;
|
splitmix64_state* state=_state;
|
||||||
// increment the state variable
|
// increment the state variable
|
||||||
*state += 0x9e3779b97f4a7c15;
|
*state += 0x9e3779b97f4a7c15;
|
||||||
// copy the state to a working variable
|
// copy the state to a working variable
|
||||||
uint64 z = *state;
|
u64 z = *state;
|
||||||
// xor the variable with the variable right bit shifted 30 then multiply by a constant
|
// xor the variable with the variable right bit shifted 30 then multiply by a constant
|
||||||
z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
|
z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
|
||||||
// xor the variable with the variable right bit shifted 27 then multiply by a constant
|
// xor the variable with the variable right bit shifted 27 then multiply by a constant
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ extern "C" {
|
|||||||
|
|
||||||
#include "../../base/base.h"
|
#include "../../base/base.h"
|
||||||
|
|
||||||
typedef uint64 splitmix64_state;
|
typedef u64 splitmix64_state;
|
||||||
typedef void* splitmix64_statePtr;
|
typedef void* splitmix64_statePtr;
|
||||||
|
|
||||||
splitmix64_statePtr splitmix64_init(uint64 seed);
|
splitmix64_statePtr splitmix64_init(u64 seed);
|
||||||
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
|
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
|
||||||
|
|
||||||
uint64 splitmix64_next(splitmix64_statePtr);
|
u64 splitmix64_next(splitmix64_statePtr);
|
||||||
static inline void splitmix64_free(splitmix64_statePtr state) {
|
static inline void splitmix64_free(splitmix64_statePtr state) {
|
||||||
free(state);
|
free(state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ extern "C" {
|
|||||||
#include "../../splitmix64/splitmix64.h"
|
#include "../../splitmix64/splitmix64.h"
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint64 merged;
|
u64 merged;
|
||||||
uint32 s[2];
|
u32 s[2];
|
||||||
} xoroshiro64_state;
|
} xoroshiro64_state;
|
||||||
typedef void* xoroshiro64_statePtr;
|
typedef void* xoroshiro64_statePtr;
|
||||||
|
|
||||||
xoroshiro64_statePtr xoroshiro64_init(uint64 seed);
|
xoroshiro64_statePtr xoroshiro64_init(u64 seed);
|
||||||
#define xoroshiro64star_init xoroshiro64_init
|
#define xoroshiro64star_init xoroshiro64_init
|
||||||
#define xoroshiro64starstar_init xoroshiro64_init
|
#define xoroshiro64starstar_init xoroshiro64_init
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoros
|
|||||||
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
|
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
|
||||||
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
|
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
|
||||||
|
|
||||||
uint32 xoroshiro64star_next(xoroshiro64_statePtr);
|
u32 xoroshiro64star_next(xoroshiro64_statePtr);
|
||||||
uint32 xoroshiro64starstar_next(xoroshiro64_statePtr);
|
u32 xoroshiro64starstar_next(xoroshiro64_statePtr);
|
||||||
|
|
||||||
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
|
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
|
||||||
free(state);
|
free(state);
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
|
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
|
||||||
generator for 32-bit floating-point numbers. We suggest to use its
|
generator for 32-bit floating-poi32 numbers. We suggest to use its
|
||||||
upper bits for floating-point generation, as it is slightly faster than
|
upper bits for floating-poi32 generation, as it is slightly faster than
|
||||||
xoroshiro64**. It passes all tests we are aware of except for linearity
|
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
|
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
|
linear complexity is not considered an issue (as it is usually the
|
||||||
@@ -23,15 +23,15 @@ right shifts to extract subsets of bits.
|
|||||||
The state must be seeded so that it is not everywhere zero.
|
The state must be seeded so that it is not everywhere zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline uint32 rotl(const uint32 x, int k) {
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
return (x << k) | (x >> (32 - k));
|
return (x << k) | (x >> (32 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 xoroshiro64star_next(void* _state) {
|
u32 xoroshiro64star_next(void* _state) {
|
||||||
xoroshiro64_state* state=_state;
|
xoroshiro64_state* state=_state;
|
||||||
const uint32 s0 = state->s[0];
|
const u32 s0 = state->s[0];
|
||||||
uint32 s1 = state->s[1];
|
u32 s1 = state->s[1];
|
||||||
const uint32 result = s0 * 0x9E3779BB;
|
const u32 result = s0 * 0x9E3779BB;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
||||||
@@ -40,7 +40,7 @@ uint32 xoroshiro64star_next(void* _state) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* xoroshiro64_init(uint64 seed){
|
void* xoroshiro64_init(u64 seed){
|
||||||
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
|
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
|
||||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
state->merged=splitmix64_next(splitmix);
|
state->merged=splitmix64_next(splitmix);
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
The state must be seeded so that it is not everywhere zero. */
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint32 rotl(const uint32 x, int k) {
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
return (x << k) | (x >> (32 - k));
|
return (x << k) | (x >> (32 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 xoroshiro64starstar_next(void* _state) {
|
u32 xoroshiro64starstar_next(void* _state) {
|
||||||
xoroshiro64_state* state=_state;
|
xoroshiro64_state* state=_state;
|
||||||
const uint32 s0 = state->s[0];
|
const u32 s0 = state->s[0];
|
||||||
uint32 s1 = state->s[1];
|
u32 s1 = state->s[1];
|
||||||
const uint32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
|
const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint32 s[2];
|
u32 s[2];
|
||||||
} xoroshiro128_state;
|
} xoroshiro128_state;
|
||||||
typedef void* xoroshiro128_statePtr;
|
typedef void* xoroshiro128_statePtr;
|
||||||
|
|
||||||
xoroshiro128_statePtr xoroshiro128_init(uint64 seed);
|
xoroshiro128_statePtr xoroshiro128_init(u64 seed);
|
||||||
#define xoroshiro128plus_init xoroshiro128_init
|
#define xoroshiro128plus_init xoroshiro128_init
|
||||||
#define xoroshiro128plusplus_init xoroshiro128_init
|
#define xoroshiro128plusplus_init xoroshiro128_init
|
||||||
#define xoroshiro128starstar_init xoroshiro128_init
|
#define xoroshiro128starstar_init xoroshiro128_init
|
||||||
@@ -23,9 +23,9 @@ static inline xoroshiro128_statePtr xoroshiro128_initFromTime(void) { return xor
|
|||||||
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
|
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
|
||||||
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
|
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
|
||||||
|
|
||||||
uint64 xoroshiro128plus_next(xoroshiro128_statePtr);
|
u64 xoroshiro128plus_next(xoroshiro128_statePtr);
|
||||||
uint64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
|
u64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
|
||||||
uint64 xoroshiro128starstar_next(xoroshiro128_statePtr);
|
u64 xoroshiro128starstar_next(xoroshiro128_statePtr);
|
||||||
|
|
||||||
static inline void xoroshiro128_free(xoroshiro128_statePtr state) {
|
static inline void xoroshiro128_free(xoroshiro128_statePtr state) {
|
||||||
free(state);
|
free(state);
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
#include "xoroshiro128.h"
|
#include "xoroshiro128.h"
|
||||||
|
|
||||||
/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
|
/* 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 floating-poi32 numbers, but its state space is large enough only
|
||||||
for mild parallelism. We suggest to use its upper bits for
|
for mild parallelism. We suggest to use its upper bits for
|
||||||
floating-point generation, as it is slightly faster than
|
floating-poi32 generation, as it is slightly faster than
|
||||||
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
|
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
|
||||||
except for the four lower bits, which might fail linearity tests (and
|
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
|
just those), so if low linear complexity is not considered an issue (as
|
||||||
@@ -32,15 +32,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
better results in our test than the 2016 version (a=55, b=14, c=36).
|
better results in our test than the 2016 version (a=55, b=14, c=36).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline uint64 rotl(const uint64 x, int k) {
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
return (x << k) | (x >> (64 - k));
|
return (x << k) | (x >> (64 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 xoroshiro128plus_next(void* _state){
|
u64 xoroshiro128plus_next(void* _state){
|
||||||
xoroshiro128_state* state=_state;
|
xoroshiro128_state* state=_state;
|
||||||
const uint64 s0 = state->s[0];
|
const u64 s0 = state->s[0];
|
||||||
uint64 s1 = state->s[1];
|
u64 s1 = state->s[1];
|
||||||
const uint64 result = s0 + s1;
|
const u64 result = s0 + s1;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||||
@@ -49,7 +49,7 @@ uint64 xoroshiro128plus_next(void* _state){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* xoroshiro128_init(uint64 seed){
|
void* xoroshiro128_init(u64 seed){
|
||||||
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
|
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
|
||||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
state->s[0]=splitmix64_next(splitmix);
|
state->s[0]=splitmix64_next(splitmix);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
tests we are aware of, but its state space is large enough only for
|
tests we are aware of, but its state space is large enough only for
|
||||||
mild parallelism.
|
mild parallelism.
|
||||||
|
|
||||||
For generating just floating-point numbers, xoroshiro128+ is even
|
For generating just floating-poi32 numbers, xoroshiro128+ is even
|
||||||
faster (but it has a very mild bias, see notes in the comments).
|
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
|
The state must be seeded so that it is not everywhere zero. If you have
|
||||||
@@ -21,15 +21,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
output to fill s. */
|
output to fill s. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint64 rotl(const uint64 x, int k) {
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
return (x << k) | (x >> (64 - k));
|
return (x << k) | (x >> (64 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 xoroshiro128plusplus_next(void* _state){
|
u64 xoroshiro128plusplus_next(void* _state){
|
||||||
xoroshiro128_state* state=_state;
|
xoroshiro128_state* state=_state;
|
||||||
const uint64 s0 = state->s[0];
|
const u64 s0 = state->s[0];
|
||||||
uint64 s1 = state->s[1];
|
u64 s1 = state->s[1];
|
||||||
const uint64 result = rotl(s0 + s1, 17) + s0;
|
const u64 result = rotl(s0 + s1, 17) + s0;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
state->s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
|
state->s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
tests we are aware of, but its state space is large enough only for
|
tests we are aware of, but its state space is large enough only for
|
||||||
mild parallelism.
|
mild parallelism.
|
||||||
|
|
||||||
For generating just floating-point numbers, xoroshiro128+ is even
|
For generating just floating-poi32 numbers, xoroshiro128+ is even
|
||||||
faster (but it has a very mild bias, see notes in the comments).
|
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
|
The state must be seeded so that it is not everywhere zero. If you have
|
||||||
@@ -21,15 +21,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
output to fill s. */
|
output to fill s. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint64 rotl(const uint64 x, int k) {
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
return (x << k) | (x >> (64 - k));
|
return (x << k) | (x >> (64 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 xoroshiro128starstar_next(void* _state){
|
u64 xoroshiro128starstar_next(void* _state){
|
||||||
xoroshiro128_state* state=_state;
|
xoroshiro128_state* state=_state;
|
||||||
const uint64 s0 = state->s[0];
|
const u64 s0 = state->s[0];
|
||||||
uint64 s1 = state->s[1];
|
u64 s1 = state->s[1];
|
||||||
const uint64 result = rotl(s0 * 5, 7) * 9;
|
const u64 result = rotl(s0 * 5, 7) * 9;
|
||||||
|
|
||||||
s1 ^= s0;
|
s1 ^= s0;
|
||||||
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint64 merged[2];
|
u64 merged[2];
|
||||||
uint32 s[4];
|
u32 s[4];
|
||||||
} xoshiro128_state;
|
} xoshiro128_state;
|
||||||
typedef void* xoshiro128_statePtr;
|
typedef void* xoshiro128_statePtr;
|
||||||
|
|
||||||
xoshiro128_statePtr xoshiro128_init(uint64 seed);
|
xoshiro128_statePtr xoshiro128_init(u64 seed);
|
||||||
#define xoshiro128plus_init xoshiro128_init
|
#define xoshiro128plus_init xoshiro128_init
|
||||||
#define xoshiro128plusplus_init xoshiro128_init
|
#define xoshiro128plusplus_init xoshiro128_init
|
||||||
#define xoshiro128starstar_init xoshiro128_init
|
#define xoshiro128starstar_init xoshiro128_init
|
||||||
@@ -24,9 +24,9 @@ static inline xoshiro128_statePtr xoshiro128_initFromTime(void) { return xoshiro
|
|||||||
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
|
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
|
||||||
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
|
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
|
||||||
|
|
||||||
uint32 xoshiro128plus_next(xoshiro128_statePtr);
|
u32 xoshiro128plus_next(xoshiro128_statePtr);
|
||||||
uint32 xoshiro128plusplus_next(xoshiro128_statePtr);
|
u32 xoshiro128plusplus_next(xoshiro128_statePtr);
|
||||||
uint32 xoshiro128starstar_next(xoshiro128_statePtr);
|
u32 xoshiro128starstar_next(xoshiro128_statePtr);
|
||||||
|
|
||||||
static inline void xoshiro128_free(xoshiro128_statePtr state) {
|
static inline void xoshiro128_free(xoshiro128_statePtr state) {
|
||||||
free(state);
|
free(state);
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
#include "xoshiro128.h"
|
#include "xoshiro128.h"
|
||||||
|
|
||||||
/* This is xoshiro128+ 1.0, our best and fastest 32-bit generator for 32-bit
|
/* 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-poi32 numbers. We suggest to use its upper bits for
|
||||||
floating-point generation, as it is slightly faster than xoshiro128**.
|
floating-poi32 generation, as it is slightly faster than xoshiro128**.
|
||||||
It passes all tests we are aware of except for
|
It passes all tests we are aware of except for
|
||||||
linearity tests, as the lowest four bits have low linear complexity, so
|
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
|
if low linear complexity is not considered an issue (as it is usually
|
||||||
@@ -22,15 +22,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
The state must be seeded so that it is not everywhere zero. */
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint32 rotl(const uint32 x, int k) {
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
return (x << k) | (x >> (32 - k));
|
return (x << k) | (x >> (32 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 xoshiro128plus_next(void* _state){
|
u32 xoshiro128plus_next(void* _state){
|
||||||
xoshiro128_state* state=_state;
|
xoshiro128_state* state=_state;
|
||||||
const uint32 result = state->s[0] + state->s[3];
|
const u32 result = state->s[0] + state->s[3];
|
||||||
|
|
||||||
const uint32 t = state->s[1] << 9;
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
state->s[2] ^= state->s[0];
|
state->s[2] ^= state->s[0];
|
||||||
state->s[3] ^= state->s[1];
|
state->s[3] ^= state->s[1];
|
||||||
@@ -44,7 +44,7 @@ uint32 xoshiro128plus_next(void* _state){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* xoshiro128_init(uint64 seed){
|
void* xoshiro128_init(u64 seed){
|
||||||
xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
|
xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
|
||||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
state->merged[0]=splitmix64_next(splitmix);
|
state->merged[0]=splitmix64_next(splitmix);
|
||||||
|
|||||||
@@ -19,15 +19,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
The state must be seeded so that it is not everywhere zero. */
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint32 rotl(const uint32 x, int k) {
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
return (x << k) | (x >> (32 - k));
|
return (x << k) | (x >> (32 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 xoshiro128plusplus_next(void* _state){
|
u32 xoshiro128plusplus_next(void* _state){
|
||||||
xoshiro128_state* state=_state;
|
xoshiro128_state* state=_state;
|
||||||
const uint32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
|
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
|
||||||
|
|
||||||
const uint32 t = state->s[1] << 9;
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
state->s[2] ^= state->s[0];
|
state->s[2] ^= state->s[0];
|
||||||
state->s[3] ^= state->s[1];
|
state->s[3] ^= state->s[1];
|
||||||
|
|||||||
@@ -22,15 +22,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
The state must be seeded so that it is not everywhere zero. */
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint32 rotl(const uint32 x, int k) {
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
return (x << k) | (x >> (32 - k));
|
return (x << k) | (x >> (32 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 xoshiro128starstar_next(void* _state){
|
u32 xoshiro128starstar_next(void* _state){
|
||||||
xoshiro128_state* state=_state;
|
xoshiro128_state* state=_state;
|
||||||
const uint32 result = rotl(state->s[1] * 5, 7) * 9;
|
const u32 result = rotl(state->s[1] * 5, 7) * 9;
|
||||||
|
|
||||||
const uint32 t = state->s[1] << 9;
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
state->s[2] ^= state->s[0];
|
state->s[2] ^= state->s[0];
|
||||||
state->s[3] ^= state->s[1];
|
state->s[3] ^= state->s[1];
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint64 s[4];
|
u64 s[4];
|
||||||
} xoshiro256_state;
|
} xoshiro256_state;
|
||||||
typedef void* xoshiro256_statePtr;
|
typedef void* xoshiro256_statePtr;
|
||||||
|
|
||||||
xoshiro256_statePtr xoshiro256_init(uint64 seed);
|
xoshiro256_statePtr xoshiro256_init(u64 seed);
|
||||||
#define xoshiro256plus_init xoshiro256_init
|
#define xoshiro256plus_init xoshiro256_init
|
||||||
#define xoshiro256plusplus_init xoshiro256_init
|
#define xoshiro256plusplus_init xoshiro256_init
|
||||||
#define xoshiro256starstar_init xoshiro256_init
|
#define xoshiro256starstar_init xoshiro256_init
|
||||||
@@ -23,9 +23,9 @@ static inline xoshiro256_statePtr xoshiro256_initFromTime(void) { return xoshiro
|
|||||||
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
|
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
|
||||||
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
|
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
|
||||||
|
|
||||||
uint64 xoshiro256plus_next(xoshiro256_statePtr);
|
u64 xoshiro256plus_next(xoshiro256_statePtr);
|
||||||
uint64 xoshiro256plusplus_next(xoshiro256_statePtr);
|
u64 xoshiro256plusplus_next(xoshiro256_statePtr);
|
||||||
uint64 xoshiro256starstar_next(xoshiro256_statePtr);
|
u64 xoshiro256starstar_next(xoshiro256_statePtr);
|
||||||
|
|
||||||
static inline void xoshiro256_free(xoshiro256_statePtr state) {
|
static inline void xoshiro256_free(xoshiro256_statePtr state) {
|
||||||
free(state);
|
free(state);
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
|||||||
output to fill s. */
|
output to fill s. */
|
||||||
|
|
||||||
|
|
||||||
static inline uint64 rotl(const uint64 x, int k) {
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
return (x << k) | (x >> (64 - k));
|
return (x << k) | (x >> (64 - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 xoshiro256plus_next(void* _state){
|
u64 xoshiro256plus_next(void* _state){
|
||||||
xoshiro256_state* state=_state;
|
xoshiro256_state* state=_state;
|
||||||
const uint64 result = state->s[0] + state->s[3];
|
const u64 result = state->s[0] + state->s[3];
|
||||||
|
|
||||||
const uint64 t = state->s[1] << 17;
|
const u64 t = state->s[1] << 17;
|
||||||
|
|
||||||
state->s[2] ^= state->s[0];
|
state->s[2] ^= state->s[0];
|
||||||
state->s[3] ^= state->s[1];
|
state->s[3] ^= state->s[1];
|
||||||
@@ -46,7 +46,7 @@ uint64 xoshiro256plus_next(void* _state){
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* xoshiro256_init(uint64 seed){
|
void* xoshiro256_init(u64 seed){
|
||||||
xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
|
xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
|
||||||
splitmix64_state* splitmix=splitmix64_init(seed);
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
state->s[0]=splitmix64_next(splitmix);
|
state->s[0]=splitmix64_next(splitmix);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user