segfault fixed
This commit is contained in:
parent
95fec8d166
commit
590790817b
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,4 +9,5 @@ obj/
|
||||
.editorconfig
|
||||
*.user
|
||||
*.vcxproj.filters
|
||||
*.log
|
||||
current.config
|
||||
|
||||
2
.vscode/tasks.json
vendored
2
.vscode/tasks.json
vendored
@ -24,7 +24,7 @@
|
||||
"focus": true,
|
||||
"panel": "shared",
|
||||
"showReuseMessage": false,
|
||||
"clear": true
|
||||
"clean": true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
67
Makefile
67
Makefile
@ -1,25 +1,68 @@
|
||||
###### Build cbuild/default_tasks #######
|
||||
all: build_exec
|
||||
######################################
|
||||
###### Build tasks #######
|
||||
######################################
|
||||
|
||||
build_exec:
|
||||
@cbuild/call_task.sh build_exec
|
||||
all: build_exec_dbg
|
||||
|
||||
# generates different profile info
|
||||
build_profile:
|
||||
@cbuild/call_task.sh build_profile 2>&1 | tee make_raw.log
|
||||
|
||||
# creates executable using profile info generated by build_profile
|
||||
build_exec: build_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:
|
||||
@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:
|
||||
@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:
|
||||
@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:
|
||||
@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:
|
||||
@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
|
||||
@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_dbg 2>&1 | tee -a make_raw.log
|
||||
|
||||
# executes $EXEC_FILE with valgrind memory checker
|
||||
valgrind: build_exec_dbg
|
||||
@cbuild/call_task.sh valgrind
|
||||
@cbuild/call_task.sh valgrind 2>&1 | tee -a 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
@ -1 +1 @@
|
||||
Subproject commit 1b38b43c547246ca358a676cee5eda85598ab949
|
||||
Subproject commit a0cdbf5522de6d4803eb135f2f52bd6cac5a3b8a
|
||||
110
default.config
110
default.config
@ -1,12 +1,12 @@
|
||||
#!/bin/bash
|
||||
CBUILD_VERSION=4
|
||||
CONFIG_VERSION=4
|
||||
CBUILD_VERSION=5
|
||||
CONFIG_VERSION=5
|
||||
|
||||
PROJECT=kerep
|
||||
CMP_C=gcc
|
||||
CMP_CPP=g++
|
||||
STD_C=c11
|
||||
STD_CPP=c++17
|
||||
PROJECT="kerep"
|
||||
CMP_C="gcc"
|
||||
CMP_CPP="g++"
|
||||
STD_C="c11"
|
||||
STD_CPP="c++17"
|
||||
WARN_C="-Wall -Wno-discarded-qualifiers"
|
||||
WARN_CPP="-Wall"
|
||||
SRC_C="$( find src -name '*.c')"
|
||||
@ -14,75 +14,117 @@ SRC_CPP="$( find src -name '*.cpp')"
|
||||
TESTS_C="$( find tests -name '*.c')"
|
||||
TESTS_CPP="$(find tests -name '*.cpp')"
|
||||
|
||||
OUTDIR=bin
|
||||
OBJDIR=obj
|
||||
EXEC_FILE=$PROJECT.com
|
||||
SHARED_LIB_FILE=$PROJECT.so
|
||||
STATIC_LIB_FILE=$PROJECT.a
|
||||
# OBJDIR structure:
|
||||
# ├── objects - dir where compiled *.o files are stored. cleans every call of build task
|
||||
# ├── profile - dir where gcc *.gcda profiling info files stored
|
||||
# ├── libs - there you can put static libs and linker will find them
|
||||
# └── out - output files are created here and then copied to OUTDIR
|
||||
OBJDIR="obj"
|
||||
OUTDIR="bin"
|
||||
STATIC_LIB_FILE="$PROJECT.a"
|
||||
|
||||
case $TASK in
|
||||
build_exec)
|
||||
C_ARGS="-O2"
|
||||
# OS-specific options
|
||||
case "$OS" in
|
||||
WINDOWS)
|
||||
EXEC_FILE="$PROJECT.exe"
|
||||
SHARED_LIB_FILE="$PROJECT.dll"
|
||||
;;
|
||||
LINUX)
|
||||
EXEC_FILE="$PROJECT.P"
|
||||
SHARED_LIB_FILE="$PROJECT.so"
|
||||
;;
|
||||
*)
|
||||
error "operating system $OS has no configuration variants"
|
||||
;;
|
||||
esac
|
||||
|
||||
# TASKS
|
||||
case "$TASK" in
|
||||
# generates different profile info
|
||||
build_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, it strips away all
|
||||
# -pg adds code to executable, that generates file containing function call info (gmon.out)
|
||||
# -fprofile-generate
|
||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS=""
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
PRE_TASK_SCRIPT=
|
||||
LINKER_ARGS="$CPP_ARGS"
|
||||
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
TASK_SCRIPT=cbuild/default_tasks/profile.sh
|
||||
POST_TASK_SCRIPT=
|
||||
;;
|
||||
# creates executable using profile info generated by build_profile
|
||||
build_exec)
|
||||
# -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, it strips away all
|
||||
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="$CPP_ARGS"
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
POST_TASK_SCRIPT=
|
||||
;;
|
||||
# creates executable with debug info and no optimizations
|
||||
build_exec_dbg)
|
||||
C_ARGS="-O0 -g"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS=""
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
LINKER_ARGS="$CPP_ARGS"
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
|
||||
POST_TASK_SCRIPT=
|
||||
;;
|
||||
# creates shared library
|
||||
build_shared_lib)
|
||||
C_ARGS="-O2 -fpic -flto -shared"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
||||
PRE_TASK_SCRIPT=
|
||||
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)
|
||||
C_ARGS="-O0 -g -fpic -shared"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
LINKER_ARGS="-Wl,-soname,$SHARED_LIB_FILE"
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_shared_lib.sh
|
||||
POST_TASK_SCRIPT=
|
||||
;;
|
||||
# creates static library
|
||||
build_static_lib)
|
||||
C_ARGS="-O2 -fpic"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||
PRE_TASK_SCRIPT=
|
||||
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)
|
||||
C_ARGS="-O0 -g"
|
||||
CPP_ARGS="$C_ARGS"
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||
PRE_TASK_SCRIPT=
|
||||
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
|
||||
POST_TASK_SCRIPT=
|
||||
;;
|
||||
# executes $EXEC_FILE
|
||||
exec)
|
||||
TASK_SCRIPT=cbuild/default_tasks/exec.sh
|
||||
;;
|
||||
# executes $EXEC_FILE with valgrind memory checker
|
||||
valgrind)
|
||||
VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
|
||||
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
|
||||
;;
|
||||
esac
|
||||
|
||||
case $OS in
|
||||
WINDOWS)
|
||||
;;
|
||||
LINUX)
|
||||
# deletes generated files
|
||||
clean)
|
||||
TASK_SCRIPT=cbuild/default_tasks/clean.sh
|
||||
;;
|
||||
# unknown task
|
||||
*)
|
||||
printf "${RED}operating system $OS has no configuration variants\n"
|
||||
exit 1
|
||||
error "task <$TASK> not found"
|
||||
;;
|
||||
esac
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
#include "Autoarr.h"
|
||||
|
||||
Autoarr_define(Unitype);
|
||||
Autoarr_define(Unitype)
|
||||
|
||||
// right func to clear array of unitype values
|
||||
void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr){
|
||||
u32 free_calls=0;
|
||||
|
||||
// right func to clean array of unitype values
|
||||
void __Autoarr_Unitype_free_fixed(Autoarr(Unitype)* ar, bool freePtr){
|
||||
Autoarr_foreach(ar, u,Unitype_free(u));
|
||||
__Autoarr_free_Unitype(ar, freePtr);
|
||||
__Autoarr_Unitype_free_g(ar, freePtr);
|
||||
free_calls++;
|
||||
kprintf("free_calls: %u\n", free_calls);
|
||||
}
|
||||
void ____Autoarr_free_Unitype_(void* ar) {
|
||||
__Autoarr_free_Unitype_((Autoarr(Unitype)*)ar, false);
|
||||
void ____Autoarr_Unitype_free_fixed(void* ar) {
|
||||
__Autoarr_Unitype_free_fixed((Autoarr(Unitype)*)ar, false);
|
||||
}
|
||||
|
||||
@ -10,8 +10,8 @@ extern "C" {
|
||||
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);
|
||||
void __Autoarr_Unitype_free_fixed(Autoarr(Unitype)* ar, bool freePtr);
|
||||
void ____Autoarr_Unitype_free_fixed(void* ar);
|
||||
|
||||
#define Autoarr_foreach(ar,elem,codeblock)({ \
|
||||
if(ar->blocks_count>0) { \
|
||||
|
||||
@ -10,14 +10,16 @@ extern "C" {
|
||||
\
|
||||
struct Autoarr_##type; \
|
||||
\
|
||||
STRUCT(__functions_list_t_##type, \
|
||||
typedef struct __Autoarr_##type##_functions_list_t { \
|
||||
void (*add)(struct Autoarr_##type* ar, type element); \
|
||||
type (*get)(struct Autoarr_##type* ar, u32 index); \
|
||||
type* (*getptr)(struct Autoarr_##type* ar, u32 index); \
|
||||
type* (*getPtr)(struct Autoarr_##type* ar, u32 index); \
|
||||
void (*set)(struct Autoarr_##type* ar, u32 index, type element); \
|
||||
void (*freear)(struct Autoarr_##type* ar, bool freePtr); \
|
||||
type* (*toArray)(struct Autoarr_##type* ar); \
|
||||
) \
|
||||
} __Autoarr_##type##_functions_list_t; \
|
||||
\
|
||||
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
|
||||
\
|
||||
STRUCT(Autoarr_##type, \
|
||||
u16 blocks_count; \
|
||||
@ -25,23 +27,23 @@ STRUCT(Autoarr_##type, \
|
||||
u16 block_length; \
|
||||
u16 max_block_length; \
|
||||
type** values; \
|
||||
__functions_list_t_##type* functions; \
|
||||
__Autoarr_##type##_functions_list_t* functions; \
|
||||
) \
|
||||
\
|
||||
Autoarr_##type* __Autoarr_create_##type(u16 max_blocks_count, u16 max_block_length); \
|
||||
void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr); \
|
||||
void ____Autoarr_free_##type(void* ar);
|
||||
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \
|
||||
void __Autoarr_##type##_free_g(Autoarr_##type* ar, bool freePtr); \
|
||||
void ____Autoarr_##type##_free_g(void* ar);
|
||||
|
||||
#define Autoarr(type) Autoarr_##type
|
||||
|
||||
#define Autoarr_create(type, max_blocks_count, max_block_length) \
|
||||
__Autoarr_create_##type(max_blocks_count, max_block_length)
|
||||
__Autoarr_##type##_create(max_blocks_count, max_block_length)
|
||||
#define Autoarr_add(autoarr, element) \
|
||||
autoarr->functions->add(autoarr, element)
|
||||
#define Autoarr_get(autoarr, index) \
|
||||
autoarr->functions->get(autoarr,index)
|
||||
#define Autoarr_getptr(autoarr, index) \
|
||||
autoarr->functions->getptr(autoarr,index)
|
||||
#define Autoarr_getPtr(autoarr, index) \
|
||||
autoarr->functions->getPtr(autoarr,index)
|
||||
#define Autoarr_set(autoarr, index, element) \
|
||||
autoarr->functions->set(autoarr, index, element)
|
||||
#define Autoarr_free(autoarr, freePtr) \
|
||||
|
||||
@ -8,9 +8,9 @@ extern "C" {
|
||||
|
||||
#define Autoarr_define(type) \
|
||||
\
|
||||
kt_define(Autoarr_##type, ____Autoarr_free_##type, NULL); \
|
||||
kt_define(Autoarr_##type, ____Autoarr_##type##_free_g, NULL); \
|
||||
\
|
||||
void __Autoarr_add_##type(Autoarr_##type* ar, type element){ \
|
||||
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
|
||||
if(!ar->values){ \
|
||||
ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \
|
||||
goto create_block; \
|
||||
@ -26,49 +26,49 @@ create_block: \
|
||||
ar->block_length++; \
|
||||
} \
|
||||
\
|
||||
type __Autoarr_get_##type(Autoarr_##type* ar, u32 index){ \
|
||||
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
|
||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||
return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \
|
||||
} \
|
||||
\
|
||||
type* __Autoarr_getptr_##type(Autoarr_##type* ar, u32 index){ \
|
||||
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
|
||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \
|
||||
} \
|
||||
\
|
||||
void __Autoarr_set_##type(Autoarr_##type* ar, u32 index, type element){ \
|
||||
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
|
||||
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
|
||||
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##_free_g(Autoarr_##type* ar, bool freePtr){ \
|
||||
for(u16 i=0; i<ar->blocks_count;i++) \
|
||||
free(ar->values[i]); \
|
||||
free(ar->values); \
|
||||
if(freePtr) free(ar); \
|
||||
} \
|
||||
void ____Autoarr_free_##type(void* ar){ \
|
||||
__Autoarr_free_##type((Autoarr_##type*)ar, false); \
|
||||
void ____Autoarr_##type##_free_g(void* ar){ \
|
||||
__Autoarr_##type##_free_g((Autoarr_##type*)ar, false); \
|
||||
} \
|
||||
\
|
||||
type* __Autoarr_toArray_##type(Autoarr_##type* ar){ \
|
||||
type* __Autoarr_##type##_toArray(Autoarr_##type* ar){ \
|
||||
u32 length=Autoarr_length(ar); \
|
||||
type* array=malloc(length * sizeof(type)); \
|
||||
for(u32 i=0; i<length; i++) \
|
||||
array[i]=__Autoarr_get_##type(ar, i); \
|
||||
array[i]=__Autoarr_##type##_get(ar, i); \
|
||||
return array; \
|
||||
} \
|
||||
\
|
||||
__functions_list_t_##type __functions_list_##type={ \
|
||||
&__Autoarr_add_##type, \
|
||||
&__Autoarr_get_##type, \
|
||||
&__Autoarr_getptr_##type, \
|
||||
&__Autoarr_set_##type, \
|
||||
&__Autoarr_free_##type, \
|
||||
&__Autoarr_toArray_##type \
|
||||
__Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \
|
||||
&__Autoarr_##type##_add, \
|
||||
&__Autoarr_##type##_get, \
|
||||
&__Autoarr_##type##_getPtr, \
|
||||
&__Autoarr_##type##_set, \
|
||||
&__Autoarr_##type##_free_g, \
|
||||
&__Autoarr_##type##_toArray \
|
||||
}; \
|
||||
\
|
||||
Autoarr_##type* __Autoarr_create_##type(u16 max_blocks_count, u16 max_block_length){ \
|
||||
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, \
|
||||
@ -76,7 +76,7 @@ Autoarr_##type* __Autoarr_create_##type(u16 max_blocks_count, u16 max_block_leng
|
||||
.max_block_length=max_block_length, \
|
||||
.block_length=0, \
|
||||
.values=NULL, \
|
||||
.functions=&__functions_list_##type \
|
||||
.functions=&__Autoarr_##type##_functions_list \
|
||||
}; \
|
||||
return ar; \
|
||||
}
|
||||
|
||||
@ -12,13 +12,13 @@ void DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){
|
||||
|
||||
// checks for dtsod contains value or dont
|
||||
bool DtsodV24_contains(Hashtable* dtsod, char* key){
|
||||
Unitype* val=Hashtable_getptr(dtsod, key);
|
||||
Unitype* val=Hashtable_getPtr(dtsod, key);
|
||||
return val!=NULL;
|
||||
}
|
||||
|
||||
// replaces value with UniNull if key exists in dtsod
|
||||
bool DtsodV24_remove(Hashtable* dtsod, char* key){
|
||||
Unitype* val=Hashtable_getptr(dtsod, key);
|
||||
Unitype* val=Hashtable_getPtr(dtsod, key);
|
||||
if (!val) return false;
|
||||
*val=UniNull;
|
||||
return true;
|
||||
|
||||
@ -50,7 +50,8 @@ void Hashtable_expand(Hashtable* ht){
|
||||
Autoarr_add(newar,p);
|
||||
}
|
||||
// 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_KVPair_free_g(ar, true);
|
||||
}
|
||||
|
||||
free(ht->rows);
|
||||
@ -72,11 +73,11 @@ void Hashtable_add(Hashtable* ht, char* key, Unitype u){
|
||||
}
|
||||
|
||||
// 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);
|
||||
u32 arlen=Autoarr_length(ar);
|
||||
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;
|
||||
}
|
||||
return NULL;
|
||||
@ -99,7 +100,7 @@ bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output){
|
||||
}
|
||||
|
||||
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;
|
||||
else Hashtable_add(ht, key, u);
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ void Hashtable_add(Hashtable* ht, char* key, Unitype u);
|
||||
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u);
|
||||
|
||||
// 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);
|
||||
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output);
|
||||
|
||||
@ -4,20 +4,20 @@ kt_define(KVPair, __KVPair_free, NULL);
|
||||
|
||||
Autoarr_define(KVPair)
|
||||
|
||||
// proper way to clear a KVP
|
||||
// proper way to clean a KVP
|
||||
void KVPair_free(KVPair p){
|
||||
free(p.key);
|
||||
Unitype_free(p.value);
|
||||
}
|
||||
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
|
||||
|
||||
// func for KVP array clearing
|
||||
void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr){
|
||||
// func for KVP array cleaning
|
||||
void __Autoarr_KVPair_free_fixed(Autoarr_KVPair* ar, bool freePtr){
|
||||
Autoarr_foreach(ar,k,KVPair_free(k));
|
||||
__Autoarr_free_KVPair(ar, freePtr);
|
||||
__Autoarr_KVPair_free_g(ar, freePtr);
|
||||
}
|
||||
void ____Autoarr_free_KVPair_(void* ar){
|
||||
__Autoarr_free_KVPair_((Autoarr_KVPair*)ar, false);
|
||||
void ____Autoarr_KVPair_free_fixed(void* ar){
|
||||
__Autoarr_KVPair_free_fixed((Autoarr_KVPair*)ar, false);
|
||||
}
|
||||
|
||||
void printkvp(KVPair p){
|
||||
|
||||
@ -14,13 +14,13 @@ STRUCT(KVPair,
|
||||
|
||||
Autoarr_declare(KVPair)
|
||||
|
||||
// proper way to clear a KVP
|
||||
// proper way to clean a KVP
|
||||
void KVPair_free(KVPair 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);
|
||||
// func to clean KVP array
|
||||
void __Autoarr_KVPair_free_fixed(Autoarr_KVPair* ar, bool freePtr);
|
||||
void ____Autoarr_KVPair_free_fixed(void* ar);
|
||||
|
||||
void printkvp(KVPair p);
|
||||
|
||||
|
||||
@ -68,7 +68,7 @@ void StringBuilder_rmchar(StringBuilder* b){
|
||||
Autoarr_pop(b->curr_buf)
|
||||
else {
|
||||
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--;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,11 +3,12 @@
|
||||
#include "../../kprint/kprint_format.h"
|
||||
|
||||
|
||||
// accepts char* (ptr to char) and char** (ptr to string)
|
||||
// accepts char* (ptr to char) and char* (ptr to string)
|
||||
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||
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
|
||||
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){
|
||||
|
||||
@ -6,7 +6,7 @@ extern "C" {
|
||||
|
||||
#include "../errors.h"
|
||||
|
||||
// accepts char* (ptr to char) and char** (ptr to string)
|
||||
// accepts char* (ptr to char) and char* (ptr to string)
|
||||
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||
char* __toString_char(void* c, u32 fmt);
|
||||
|
||||
|
||||
@ -64,9 +64,10 @@ void ktDescriptors_initKerepTypes(){
|
||||
kt_register(Array_Unitype);
|
||||
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);
|
||||
// in autoarr functions list
|
||||
__Autoarr_Unitype_functions_list.freear=__Autoarr_Unitype_free_fixed;
|
||||
// and in type descriptor
|
||||
ktDescriptor_Autoarr_Unitype.freeMembers=____Autoarr_Unitype_free_fixed;
|
||||
|
||||
// STNode
|
||||
kt_register(STNode);
|
||||
@ -75,9 +76,10 @@ void ktDescriptors_initKerepTypes(){
|
||||
kt_register(KVPair);
|
||||
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);
|
||||
// in autoarr functions list
|
||||
__Autoarr_KVPair_functions_list.freear=__Autoarr_KVPair_free_fixed;
|
||||
// and in type descriptor
|
||||
ktDescriptor_Autoarr_KVPair.freeMembers=____Autoarr_KVPair_free_fixed;
|
||||
|
||||
// Hashtable
|
||||
kt_register(Hashtable);
|
||||
|
||||
@ -1,90 +1,100 @@
|
||||
#include "../base.h"
|
||||
#include "../../kprint/kprint_format.h"
|
||||
#include "../base.h"
|
||||
|
||||
|
||||
char* __Unitype_toString(void* _u, u32 fmt){
|
||||
return Unitype_toString(*(Unitype*)_u, fmt);
|
||||
char *__Unitype_toString(void *_u, u32 fmt)
|
||||
{
|
||||
return Unitype_toString(*(Unitype *)_u, fmt);
|
||||
}
|
||||
|
||||
kt_define(Unitype, __UnitypePtr_free, __Unitype_toString);
|
||||
|
||||
void Unitype_free(Unitype u){
|
||||
if(u.typeId==ktid_undefined){
|
||||
if(u.VoidPtr!=NULL)
|
||||
void Unitype_free(Unitype u)
|
||||
{
|
||||
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)
|
||||
ktDescriptor *type = ktDescriptor_get(u.typeId);
|
||||
if (type->freeMembers)
|
||||
type->freeMembers(u.VoidPtr);
|
||||
if(u.allocatedInHeap)
|
||||
if (u.allocatedInHeap)
|
||||
free(u.VoidPtr);
|
||||
}
|
||||
void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
|
||||
void __UnitypePtr_free(void *u)
|
||||
{
|
||||
Unitype_free(*(Unitype *)u);
|
||||
}
|
||||
|
||||
|
||||
char* Unitype_toString(Unitype u, u32 fmt){
|
||||
if(u.typeId==ktid_undefined){
|
||||
if(u.VoidPtr!=NULL)
|
||||
char *Unitype_toString(Unitype u, u32 fmt)
|
||||
{
|
||||
if (u.typeId == ktid_undefined)
|
||||
{
|
||||
if (u.VoidPtr != NULL)
|
||||
throw("unitype with undefined typeId has value");
|
||||
return cptr_copy("{ERROR_TYPE}");
|
||||
}
|
||||
|
||||
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)){
|
||||
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;
|
||||
fmt = kp_i;
|
||||
// replaces value with pointer to value to pass into toString_i64(void*, u32)
|
||||
i64 value=u.Int64;
|
||||
u.VoidPtr=&value;
|
||||
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(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(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_name(char))
|
||||
{
|
||||
fmt = kp_c;
|
||||
i64 value = u.Int64;
|
||||
u.VoidPtr = &value;
|
||||
}
|
||||
else if(u.typeId==ktid_ptrName(char)){
|
||||
char* value=u.VoidPtr;
|
||||
u.VoidPtr=&value;
|
||||
fmt=kp_s;
|
||||
else if (u.typeId == ktid_ptrName(char))
|
||||
{
|
||||
fmt = kp_s;
|
||||
}
|
||||
else if(u.typeId==ktid_name(Pointer)){
|
||||
if(u.VoidPtr==NULL)
|
||||
else if (u.typeId == ktid_name(Pointer))
|
||||
{
|
||||
if (u.VoidPtr == NULL)
|
||||
return cptr_copy("{ UniNull }");
|
||||
fmt=kp_h;
|
||||
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"),
|
||||
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)
|
||||
if (type->toString)
|
||||
free(valuestr);
|
||||
return rezult;
|
||||
}
|
||||
|
||||
void printuni(Unitype v){
|
||||
char* s=Unitype_toString(v,0);
|
||||
void printuni(Unitype v)
|
||||
{
|
||||
char *s = Unitype_toString(v, 0);
|
||||
fputs(s, stdout);
|
||||
fputc('\n',stdout);
|
||||
free(s);
|
||||
}
|
||||
@ -19,15 +19,19 @@ ktid __typeFromFormat(kp_fmt f){
|
||||
case kp_s:
|
||||
return ktid_ptrName(char);
|
||||
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
|
||||
ktid typeId=__typeFromFormat(f);
|
||||
if(typeId==ktid_undefined)
|
||||
safethrow("typeId is undefined, can't autodetect type",;);
|
||||
|
||||
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",;);
|
||||
|
||||
@ -33,33 +33,39 @@ void print_dtsod(Hashtable* dtsod){
|
||||
}
|
||||
|
||||
void test_dtsod(){
|
||||
optime(__func__,1,({
|
||||
// optime(__func__,1,({
|
||||
kprintf("\e[96m-------------[test_dtsod]-------------\n");
|
||||
Hashtable* dtsod;
|
||||
char* s;
|
||||
|
||||
optime("deserialize",1,({
|
||||
do {
|
||||
// optime("deserialize",1,({
|
||||
tryLast(DtsodV24_deserialize(text),r)
|
||||
dtsod=r.value.VoidPtr;
|
||||
}));
|
||||
// }));
|
||||
} while(0);
|
||||
print_dtsod(dtsod);
|
||||
|
||||
optime("serialize",1,({
|
||||
do {
|
||||
// optime("serialize",1,({
|
||||
tryLast(DtsodV24_serialize(dtsod),r)
|
||||
s=r.value.VoidPtr;
|
||||
}));
|
||||
// }));
|
||||
} while(0);
|
||||
DtsodV24_free(dtsod);
|
||||
kprintf("\e[92m%s",s);
|
||||
|
||||
optime("reserialize",10,({
|
||||
do {
|
||||
// optime("reserialize",10,({
|
||||
tryLast(DtsodV24_deserialize(s),r)
|
||||
dtsod=r.value.VoidPtr;
|
||||
free(s);
|
||||
tryLast(DtsodV24_serialize(dtsod),rr)
|
||||
s=rr.value.VoidPtr;
|
||||
DtsodV24_free(dtsod);
|
||||
}));
|
||||
// }));
|
||||
} while(0);
|
||||
|
||||
free(s);
|
||||
}));
|
||||
// }));
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user