diff --git a/!TODO.md b/!TODO.md new file mode 100644 index 0000000..3a6bbe1 --- /dev/null +++ b/!TODO.md @@ -0,0 +1,3 @@ +- add toString() to type descriptor +- find better way to check typeId without hundreds of if() statements +- update autoarr to use type descriptor \ No newline at end of file diff --git a/build_scripts/default.config.sh b/build_scripts/default.config.sh index fa3755e..7c2c541 100644 --- a/build_scripts/default.config.sh +++ b/build_scripts/default.config.sh @@ -6,8 +6,8 @@ CMP_C=gcc CMP_CPP=g++ STD_C=c11 STD_CPP=c++17 -WARN_C="-Wall -Wno-discarded-qualifiers" #-Wextra -WARN_CPP="-Wall -Wno-unused-variable -Wno-return-type" #-Wextra +WARN_C="-Wall -Wno-discarded-qualifiers" +WARN_CPP="-Wall" SRC_C="$( find src -name '*.c')" SRC_CPP="$( find src -name '*.cpp')" TESTS_C="$( find tests -name '*.c')" @@ -21,7 +21,7 @@ BUILD_TEST_CPP_ARGS="$BUILD_TEST_C_ARGS" BUILD_TEST_LINKER_ARGS="" # build_test_dbg -TEST_DBG_FILE=$TEST_FILE +TEST_DBG_FILE=$TEST_FILE.dbg BUILD_TEST_DBG_C_ARGS="-O0 -g" BUILD_TEST_DBG_CPP_ARGS="$BUILD_TEST_DBG_C_ARGS" BUILD_TEST_DBG_LINKER_ARGS="" diff --git a/src/Autoarr/Autoarr.c b/src/Autoarr/Autoarr.c index 48d595a..abff22b 100644 --- a/src/Autoarr/Autoarr.c +++ b/src/Autoarr/Autoarr.c @@ -1,19 +1,51 @@ #include "Autoarr.h" -Autoarr_define(uint8); -Autoarr_define(int8); -Autoarr_define(uint16); -Autoarr_define(int16); -Autoarr_define(uint32); -Autoarr_define(int32); -Autoarr_define(uint64); -Autoarr_define(int64); -Autoarr_define(float); -Autoarr_define(double); -Autoarr_define(Unitype); +Autoarr_define(char) +Autoarr_define(bool) +Autoarr_define(float32) +Autoarr_define(float64) +Autoarr_define(uint8) +Autoarr_define(int8) +Autoarr_define(uint16) +Autoarr_define(int16) +Autoarr_define(uint32) +Autoarr_define(int32) +Autoarr_define(uint64) +Autoarr_define(int64) + +kerepTypeId_define(kerepTypeId_AutoarrChar); +kerepTypeId_define(kerepTypeId_AutoarrBool); +kerepTypeId_define(kerepTypeId_AutoarrFloat32); +kerepTypeId_define(kerepTypeId_AutoarrFloat64); +kerepTypeId_define(kerepTypeId_AutoarrInt8); +kerepTypeId_define(kerepTypeId_AutoarrUInt8); +kerepTypeId_define(kerepTypeId_AutoarrInt16); +kerepTypeId_define(kerepTypeId_AutoarrUInt16); +kerepTypeId_define(kerepTypeId_AutoarrInt32); +kerepTypeId_define(kerepTypeId_AutoarrUInt32); +kerepTypeId_define(kerepTypeId_AutoarrInt64); +kerepTypeId_define(kerepTypeId_AutoarrUInt64); + +kerepTypeId_define(kerepTypeId_AutoarrCharPtr); +kerepTypeId_define(kerepTypeId_AutoarrBoolPtr); +kerepTypeId_define(kerepTypeId_AutoarrFloat32Ptr); +kerepTypeId_define(kerepTypeId_AutoarrFloat64Ptr); +kerepTypeId_define(kerepTypeId_AutoarrInt8Ptr); +kerepTypeId_define(kerepTypeId_AutoarrUInt8Ptr); +kerepTypeId_define(kerepTypeId_AutoarrInt16Ptr); +kerepTypeId_define(kerepTypeId_AutoarrUInt16Ptr); +kerepTypeId_define(kerepTypeId_AutoarrInt32Ptr); +kerepTypeId_define(kerepTypeId_AutoarrUInt32Ptr); +kerepTypeId_define(kerepTypeId_AutoarrInt64Ptr); +kerepTypeId_define(kerepTypeId_AutoarrUInt64Ptr); + +Autoarr_define(Unitype) +kerepTypeId_define(kerepTypeId_AutoarrUnitype); +kerepTypeId_define(kerepTypeId_AutoarrUnitypePtr); // right func to clear array of unitype values -void Autoarr_free_Unitype(Autoarr(Unitype)* ar){ +void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr){ Autoarr_foreach(ar, u,Unitype_free(u)); - Autoarr_free(ar); + __Autoarr_free_Unitype(ar, freePtr); } +void ____Autoarr_free_Unitype_(void* ar) { __Autoarr_free_Unitype_((Autoarr(Unitype)*)ar, false); } \ No newline at end of file diff --git a/src/Autoarr/Autoarr.h b/src/Autoarr/Autoarr.h index 89440a4..d96fcf6 100644 --- a/src/Autoarr/Autoarr.h +++ b/src/Autoarr/Autoarr.h @@ -7,20 +7,52 @@ extern "C" { #include "Autoarr_declare.h" #include "Autoarr_define.h" -Autoarr_declare(uint8) +Autoarr_declare(char) +Autoarr_declare(bool) +Autoarr_declare(float32) +Autoarr_declare(float64) Autoarr_declare(int8) -Autoarr_declare(uint16) +Autoarr_declare(uint8) Autoarr_declare(int16) -Autoarr_declare(uint32) +Autoarr_declare(uint16) Autoarr_declare(int32) -Autoarr_declare(uint64) +Autoarr_declare(uint32) Autoarr_declare(int64) -Autoarr_declare(float) -Autoarr_declare(double) -Autoarr_declare(Unitype) +Autoarr_declare(uint64) -// right func to clear array of unitype values -void Autoarr_free_Unitype(Autoarr(Unitype)* ar); +kerepTypeId_declare(kerepTypeId_AutoarrChar); +kerepTypeId_declare(kerepTypeId_AutoarrBool); +kerepTypeId_declare(kerepTypeId_AutoarrFloat32); +kerepTypeId_declare(kerepTypeId_AutoarrFloat64); +kerepTypeId_declare(kerepTypeId_AutoarrInt8); +kerepTypeId_declare(kerepTypeId_AutoarrUInt8); +kerepTypeId_declare(kerepTypeId_AutoarrInt16); +kerepTypeId_declare(kerepTypeId_AutoarrUInt16); +kerepTypeId_declare(kerepTypeId_AutoarrInt32); +kerepTypeId_declare(kerepTypeId_AutoarrUInt32); +kerepTypeId_declare(kerepTypeId_AutoarrInt64); +kerepTypeId_declare(kerepTypeId_AutoarrUInt64); + +kerepTypeId_declare(kerepTypeId_AutoarrCharPtr); +kerepTypeId_declare(kerepTypeId_AutoarrBoolPtr); +kerepTypeId_declare(kerepTypeId_AutoarrFloat32Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrFloat64Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrInt8Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrUInt8Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrInt16Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrUInt16Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrInt32Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrUInt32Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrInt64Ptr); +kerepTypeId_declare(kerepTypeId_AutoarrUInt64Ptr); + +Autoarr_declare(Unitype) +kerepTypeId_declare(kerepTypeId_AutoarrUnitype); +kerepTypeId_declare(kerepTypeId_AutoarrUnitypePtr); + +// this function is injected in kerep_init() +void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr); +void ____Autoarr_free_Unitype_(void* ar); #define Autoarr_foreach(ar,elem,codeblock)({\ if(ar->blocks_count>0) {\ diff --git a/src/Autoarr/Autoarr_KVPair_exported.c b/src/Autoarr/Autoarr_KVPair_exported.c index 18fa4aa..8bfbd56 100644 --- a/src/Autoarr/Autoarr_KVPair_exported.c +++ b/src/Autoarr/Autoarr_KVPair_exported.c @@ -10,7 +10,7 @@ EXPORT void CALL kerep_Autoarr_KVPair_create(uint16 max_blocks_count, uint16 max } EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){ - Autoarr_free_KVPair(ar); + Autoarr_free(ar, true); } EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, uint32 index, KVPair* output){ diff --git a/src/Autoarr/Autoarr_Unitype_exported.c b/src/Autoarr/Autoarr_Unitype_exported.c index 8ad5efd..2aded2e 100644 --- a/src/Autoarr/Autoarr_Unitype_exported.c +++ b/src/Autoarr/Autoarr_Unitype_exported.c @@ -9,7 +9,7 @@ EXPORT void CALL kerep_Autoarr_Unitype_create(uint16 max_blocks_count, uint16 ma } EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){ - Autoarr_free_Unitype(ar); + Autoarr_free(ar, true); } EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, uint32 index, Unitype* output){ diff --git a/src/Autoarr/Autoarr_declare.h b/src/Autoarr/Autoarr_declare.h index 80169bd..404a361 100644 --- a/src/Autoarr/Autoarr_declare.h +++ b/src/Autoarr/Autoarr_declare.h @@ -15,7 +15,8 @@ typedef struct {\ type (*get)(struct Autoarr_##type* ar, uint32 index);\ type* (*getptr)(struct Autoarr_##type* ar, uint32 index);\ void (*set)(struct Autoarr_##type* ar, uint32 index, type element);\ - void (*_free)(struct Autoarr_##type* ar);\ + void (*freear)(struct Autoarr_##type* ar, bool freePtr);\ + type* (*toArray)(struct Autoarr_##type* ar);\ } __functions_list_t_##type;\ \ typedef struct Autoarr_##type{\ @@ -27,15 +28,14 @@ typedef struct Autoarr_##type{\ __functions_list_t_##type* functions;\ } Autoarr_##type;\ \ -void __Autoarr_add_##type(Autoarr_##type* ar, type element);\ -type __Autoarr_get_##type(Autoarr_##type* ar, uint32 index);\ -type* __Autoarr_getptr_##type(Autoarr_##type* ar, uint32 index);\ -void __Autoarr_set_##type(Autoarr_##type* ar, uint32 index, type element);\ -void __Autoarr_free_##type(Autoarr_##type* ar);\ -Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length); +Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_block_length);\ +void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr);\ +void ____Autoarr_free_##type(void* ar); #define Autoarr(type) Autoarr_##type +#define Autoarr_create(type, max_blocks_count, max_block_length)\ + __Autoarr_create_##type(max_blocks_count, max_block_length) #define Autoarr_add(autoarr, element)\ autoarr->functions->add(autoarr, element) #define Autoarr_get(autoarr, index)\ @@ -44,10 +44,10 @@ Autoarr_##type* __Autoarr_create_##type(uint16 max_blocks_count, uint16 max_bloc autoarr->functions->getptr(autoarr,index) #define Autoarr_set(autoarr, index, element)\ autoarr->functions->set(autoarr, index, element) -#define Autoarr_free(autoarr)\ - autoarr->functions->_free(autoarr) -#define Autoarr_create(type, max_blocks_count, max_block_length)\ - __Autoarr_create_##type(max_blocks_count, max_block_length) +#define Autoarr_free(autoarr, freePtr)\ + autoarr->functions->freear(autoarr, freePtr) +#define Autoarr_toArray(autoarr)\ + autoarr->functions->toArray(autoarr) #define Autoarr_length(autoarr) \ (uint32)(!autoarr->blocks_count ? 0 : \ diff --git a/src/Autoarr/Autoarr_define.h b/src/Autoarr/Autoarr_define.h index 441c9b6..b70ad86 100644 --- a/src/Autoarr/Autoarr_define.h +++ b/src/Autoarr/Autoarr_define.h @@ -39,11 +39,22 @@ void __Autoarr_set_##type(Autoarr_##type* ar, uint32 index, type element){\ ar->values[index/ar->max_block_length][index%ar->max_block_length]=element;\ }\ \ -void __Autoarr_free_##type(Autoarr_##type* ar){\ +void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr){\ for(uint16 i=0; iblocks_count;i++)\ free(ar->values[i]); \ free(ar->values);\ - free(ar);\ + if(freePtr) free(ar);\ +}\ +void ____Autoarr_free_##type(void* ar){\ + __Autoarr_free_##type((Autoarr_##type*)ar, false);\ +}\ +\ +type* __Autoarr_toArray_##type(Autoarr_##type* ar){\ + uint32 length=Autoarr_length(ar);\ + type* array=malloc(length * sizeof(type));\ + for(uint32 i=0; i0) safethrow(ERR_ENDOFSTR,;); - return SUCCESS(UniPtr(CharPtr,NULL)); + return SUCCESS(UniPtrHeap(kerepTypeId_CharPtr,NULL)); } #define ReadName() __ReadName(shared) @@ -137,7 +137,7 @@ Maybe __ReadString(DeserializeSharedData* shared){ } else { char* str=StringBuilder_build(b).ptr; - return SUCCESS(UniPtr(CharPtr,str)); + return SUCCESS(UniPtrHeap(kerepTypeId_CharPtr,str)); } } else { @@ -154,16 +154,16 @@ Maybe __ReadList(DeserializeSharedData* shared){ Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL); bool readingList=true; while (true){ - try(ReadValue((&readingList)), val, Autoarr_free_Unitype(list)) + try(ReadValue((&readingList)), val, Autoarr_free(list, true)) Autoarr_add(list,val.value); if (!readingList){ - if(val.value.type==Null) + if(val.value.typeId==kerepTypeId_Null) Autoarr_pop(list); break; } } - return SUCCESS(UniPtr(AutoarrUnitypePtr,list)); + return SUCCESS(UniPtrHeap(kerepTypeId_AutoarrUnitypePtr,list)); }; #define ReadList() __ReadList(shared) @@ -275,7 +275,7 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){ case ';': case ',': if(valueStr.length!=0){ - if(value.type!=Null) + if(value.typeId!=kerepTypeId_Null) safethrow_wrongchar(c,Unitype_free(value)); try(ParseValue(valueStr),maybeParsed,;) value=maybeParsed.value; @@ -321,7 +321,7 @@ Maybe __deserialize(char** _text, bool _calledRecursively) { } else{ list=Autoarr_create(Unitype,ARR_BC,ARR_BL); - Hashtable_add(dict,nameCPtr,UniPtr(AutoarrUnitypePtr,list)); + Hashtable_add(dict,nameCPtr,UniPtrHeap(kerepTypeId_AutoarrUnitypePtr,list)); } Autoarr_add(list,val.value); } @@ -331,7 +331,7 @@ Maybe __deserialize(char** _text, bool _calledRecursively) { END: *_text=text; - return SUCCESS(UniPtr(HashtablePtr,dict)); + return SUCCESS(UniPtrHeap(kerepTypeId_HashtablePtr,dict)); } Maybe DtsodV24_deserialize(char* _text) { diff --git a/src/DtsodParser/DtsodV24_serialize.c b/src/DtsodParser/DtsodV24_serialize.c index 4618104..601c0c0 100644 --- a/src/DtsodParser/DtsodV24_serialize.c +++ b/src/DtsodParser/DtsodV24_serialize.c @@ -23,70 +23,65 @@ void __AppendTabs(SerializeSharedData* shared) { Maybe __AppendValue(SerializeSharedData* shared, Unitype u); #define AppendValue(UNI) __AppendValue(shared, UNI) Maybe __AppendValue(SerializeSharedData* shared, Unitype u){ - switch(u.type){ - case Int64: - StringBuilder_append_int64(b,u.Int64); - break; - case UInt64: - StringBuilder_append_uint64(b,u.UInt64); - addc('u'); - break; - case Float64: - StringBuilder_append_float64(b,u.Float64); - addc('f'); - break; - case CharPtr: - addc('"'); - char c; - while((c=*(char*)(u.VoidPtr++))){ - if(c=='\"') addc('\\'); - addc(c); - } - addc('"'); - break; - case Bool: - StringBuilder_append_cptr(b, u.Bool ? "true" : "false"); - break; - case Null: - safethrow("Null isn't supported in DtsodV24",;); - case AutoarrUnitypePtr: - if(Autoarr_length(((Autoarr_Unitype*)(u.VoidPtr)))){ + if(u.typeId==kerepTypeId_Int64){ + StringBuilder_append_int64(b,u.Int64); + } + else if(u.typeId==kerepTypeId_UInt64){ + StringBuilder_append_uint64(b,u.UInt64); + addc('u'); + } + else if(u.typeId==kerepTypeId_Float64){ + StringBuilder_append_float64(b,u.Float64); + addc('f'); + } + else if(u.typeId==kerepTypeId_CharPtr){ + addc('"'); + char c; + while((c=*(char*)(u.VoidPtr++))){ + if(c=='\"') addc('\\'); + addc(c); + } + addc('"'); + } + else if(u.typeId==kerepTypeId_Bool){ + StringBuilder_append_cptr(b, u.Bool ? "true" : "false"); + } + else if(u.typeId==kerepTypeId_Null){ + safethrow("Null isn't supported in DtsodV24",;); + } + else if(u.typeId==kerepTypeId_AutoarrUnitypePtr){ + if(Autoarr_length(((Autoarr_Unitype*)(u.VoidPtr)))){ + addc('\n'); + AppendTabs(); + addc('['); + tabs++; + Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({ addc('\n'); AppendTabs(); - addc('['); - tabs++; - Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({ - addc('\n'); - AppendTabs(); - try(AppendValue(e),__,;); - addc(','); - })); - StringBuilder_rmchar(b); - addc('\n'); - tabs--; - AppendTabs(); - addc(']'); - } - else { - addc('['); - addc(']'); - } - break; - case HashtablePtr: - // check hashtable is blank - Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({ - goto hashtableNotBlank; - if(__.key); // weird way to disable warning + try(AppendValue(e),__,;); + addc(','); })); - - - // blank hashtable - addc('{'); - addc('}'); + StringBuilder_rmchar(b); + addc('\n'); + tabs--; + AppendTabs(); + addc(']'); + } + else { + addc('['); + addc(']'); + } + } + else if(u.typeId==kerepTypeId_HashtablePtr){ + // check hashtable is blank + bool hashtableNotBlank=false; + Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({ + hashtableNotBlank=true; + if(__.key); // weird way to disable warning break; - - // not blank hashtable - hashtableNotBlank: + })); + + if(hashtableNotBlank){ addc('\n'); AppendTabs(); addc('{'); @@ -94,10 +89,16 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){ try(__serialize(b,tabs+1,u.VoidPtr),___,;); AppendTabs(); addc('}'); - break; - default: dbg((u.type)); safethrow(ERR_WRONGTYPE,;); + } + else { + addc('{'); + addc('}'); + } + } + else { + dbg((u.typeId)); + safethrow(ERR_WRONGTYPE,;); } - return MaybeNull; }; @@ -125,5 +126,5 @@ Maybe DtsodV24_serialize(Hashtable* dtsod){ StringBuilder* sb=StringBuilder_create(); try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb)); char* str=StringBuilder_build(sb).ptr; - return SUCCESS(UniPtr(CharPtr, str)); + return SUCCESS(UniPtrHeap(kerepTypeId_CharPtr, str)); } diff --git a/src/Hashtable/Hashtable.c b/src/Hashtable/Hashtable.c index 992ef5e..4b1b921 100644 --- a/src/Hashtable/Hashtable.c +++ b/src/Hashtable/Hashtable.c @@ -1,5 +1,8 @@ #include "Hashtable.h" +kerepTypeId_define(kerepTypeId_Hashtable); +kerepTypeId_define(kerepTypeId_HashtablePtr); + // amount of rows static const uint16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521}; #define HT_HEIN_MIN 0 @@ -17,10 +20,14 @@ Hashtable* Hashtable_create(){ return ht; } -void Hashtable_free(Hashtable* ht){ +void __Hashtable_free(void* _ht){ + Hashtable* ht=_ht; for(uint16 i=0;ihein];i++) - Autoarr_free_KVPair(ht->rows[i]); + Autoarr_free(ht->rows[i], true); free(ht->rows); +} +void Hashtable_free(Hashtable* ht){ + __Hashtable_free(ht); free(ht); } @@ -43,7 +50,8 @@ void Hashtable_expand(Hashtable* ht){ Autoarr(KVPair)* newar=newrows[newrown]; Autoarr_add(newar,p); } - Autoarr_free(ar); + // there is no need to free array values, because they are copied into new array + __Autoarr_free_KVPair(ar, true); } free(ht->rows); @@ -88,7 +96,7 @@ Unitype Hashtable_get(Hashtable* ht, char* key){ bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output){ Unitype u=Hashtable_get(ht,key); *output=u; - return u.type!=Null; + return u.typeId!=kerepTypeId_Null; } void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u){ diff --git a/src/Hashtable/Hashtable.h b/src/Hashtable/Hashtable.h index 3500199..58f446d 100644 --- a/src/Hashtable/Hashtable.h +++ b/src/Hashtable/Hashtable.h @@ -11,9 +11,12 @@ typedef struct Hashtable{ uint8 hein; // height=HT_HEIGHTS[hein] Autoarr(KVPair)** rows; // Autoarr[height] } Hashtable; +kerepTypeId_declare(kerepTypeId_Hashtable); +kerepTypeId_declare(kerepTypeId_HashtablePtr); Hashtable* Hashtable_create(); void Hashtable_free(Hashtable* ht); +void __Hashtable_free(void* ht); // amount of rows uint16 Hashtable_height(Hashtable* ht); diff --git a/src/Hashtable/KeyValuePair.c b/src/Hashtable/KeyValuePair.c index cbe22dd..22c3f5e 100644 --- a/src/Hashtable/KeyValuePair.c +++ b/src/Hashtable/KeyValuePair.c @@ -1,18 +1,26 @@ #include "KeyValuePair.h" -Autoarr_define(KVPair) +kerepTypeId_define(kerepTypeId_KVPair); +kerepTypeId_define(kerepTypeId_KVPairPtr); +Autoarr_define(KVPair) +kerepTypeId_define(kerepTypeId_AutoarrKVPair); +kerepTypeId_define(kerepTypeId_AutoarrKVPairPtr); // proper way to clear a KVP void KVPair_free(KVPair p){ free(p.key); Unitype_free(p.value); } +void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); } // func for KVP array clearing -void Autoarr_free_KVPair(Autoarr_KVPair* ar){ +void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr){ Autoarr_foreach(ar,k,KVPair_free(k)); - Autoarr_free(ar); + __Autoarr_free_KVPair(ar, freePtr); +} +void ____Autoarr_free_KVPair_(void* ar){ + __Autoarr_free_KVPair_((Autoarr_KVPair*)ar, false); } void printkvp(KVPair p){ diff --git a/src/Hashtable/KeyValuePair.h b/src/Hashtable/KeyValuePair.h index 19cc277..832c6c7 100644 --- a/src/Hashtable/KeyValuePair.h +++ b/src/Hashtable/KeyValuePair.h @@ -11,14 +11,20 @@ typedef struct KVPair{ char* key; Unitype value; } KVPair; +kerepTypeId_declare(kerepTypeId_KVPair); +kerepTypeId_declare(kerepTypeId_KVPairPtr); Autoarr_declare(KVPair) +kerepTypeId_declare(kerepTypeId_AutoarrKVPair); +kerepTypeId_declare(kerepTypeId_AutoarrKVPairPtr); // proper way to clear a KVP void KVPair_free(KVPair p); +void __KVPair_free(void* p); // func to clear KVP array -void Autoarr_free_KVPair(Autoarr_KVPair* ar); +void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr); +void ____Autoarr_free_KVPair_(void* ar); void printkvp(KVPair p); diff --git a/src/SearchTree/SearchTree.c b/src/SearchTree/SearchTree.c index e7cfac6..23aa853 100644 --- a/src/SearchTree/SearchTree.c +++ b/src/SearchTree/SearchTree.c @@ -1,14 +1,18 @@ #include "SearchTree.h" +kerepTypeId_define(kerepTypeId_STNode); +kerepTypeId_define(kerepTypeId_STNodePtr); + STNode* STNode_create(){ STNode* node=malloc(sizeof(STNode)); node->branches=NULL; - node->value.type=Null; + node->value.typeId=kerepTypeId_Null; node->value.UInt64=0; return node; } -void STNode_free(STNode* node){ +void __STNode_free(void* _node){ + STNode* node=_node; if (!node) throw(ERR_NULLPTR); if(node->branches){ for(uint8 n32 = 0;n32<8;n32++){ @@ -32,6 +36,9 @@ void STNode_free(STNode* node){ } if(node->value.VoidPtr) Unitype_free(node->value); +} +void STNode_free(STNode* node){ + __STNode_free(node); free(node); } diff --git a/src/SearchTree/SearchTree.h b/src/SearchTree/SearchTree.h index fc4eb8c..3d1a8e0 100644 --- a/src/SearchTree/SearchTree.h +++ b/src/SearchTree/SearchTree.h @@ -11,9 +11,12 @@ typedef struct SearchTreeNode{ struct SearchTreeNode**** branches; // *STNode[8][8][4] Unitype value; } STNode; +kerepTypeId_declare(kerepTypeId_STNode); +kerepTypeId_declare(kerepTypeId_STNodePtr); STNode* STNode_create(); void STNode_free(STNode* node); +void __STNode_free(void* node); void ST_push(STNode* node, char* key, Unitype value); void ST_pushString(STNode* node, string key, Unitype value); diff --git a/src/String/StringBuilder.c b/src/String/StringBuilder.c index c0b46a9..167e916 100644 --- a/src/String/StringBuilder.c +++ b/src/String/StringBuilder.c @@ -1,6 +1,11 @@ #include "StringBuilder.h" Autoarr_define(string) +kerepTypeId_define(kerepTypeId_AutoarrString); +kerepTypeId_define(kerepTypeId_AutoarrStringPtr); + +kerepTypeId_define(kerepTypeId_StringBuilder); +kerepTypeId_define(kerepTypeId_StringBuilderPtr); #define BL_C 32 #define BL_L 1024 @@ -17,7 +22,7 @@ void complete_buf(StringBuilder* b){ str.ptr[i++]=c; })); Autoarr_add(b->compl_bufs,str); - Autoarr_free(b->curr_buf); + Autoarr_free(b->curr_buf, true); b->curr_buf=Autoarr_create(int8,BL_C,BL_L); } @@ -34,9 +39,13 @@ StringBuilder* StringBuilder_create(){ return b; } +void __StringBuilder_free(void* _b){ + StringBuilder* b=_b; + if(b->compl_bufs) Autoarr_free(b->compl_bufs, true); + Autoarr_free(b->curr_buf, true); +} void StringBuilder_free(StringBuilder* b){ - if(b->compl_bufs) Autoarr_free(b->compl_bufs); - Autoarr_free(b->curr_buf); + __StringBuilder_free(b); free(b); } diff --git a/src/String/StringBuilder.h b/src/String/StringBuilder.h index 8e19420..50e63a7 100644 --- a/src/String/StringBuilder.h +++ b/src/String/StringBuilder.h @@ -8,14 +8,19 @@ extern "C" { #include "string.h" Autoarr_declare(string) +kerepTypeId_declare(kerepTypeId_AutoarrString); +kerepTypeId_declare(kerepTypeId_AutoarrStringPtr); typedef struct StringBuilder{ Autoarr(string)* compl_bufs; Autoarr(int8)* curr_buf; } StringBuilder; +kerepTypeId_declare(kerepTypeId_StringBuilder); +kerepTypeId_declare(kerepTypeId_StringBuilderPtr); StringBuilder* StringBuilder_create(void); void StringBuilder_free(StringBuilder* b); +void __StringBuilder_free(void* b); // Joins all strings from compl_bufs. // Returns zero-terminated string. // No need to call string_extract()! diff --git a/src/base/base.h b/src/base/base.h index d49b6d7..cd9346a 100644 --- a/src/base/base.h +++ b/src/base/base.h @@ -5,10 +5,12 @@ extern "C" { #endif #include "std.h" -#include "types.h" #include "errors.h" #include "cptr.h" #include "optime.h" +#include "types.h" +#include "unitype.h" +#include "init.h" #if __cplusplus } diff --git a/src/base/errors.h b/src/base/errors.h index de7c713..4109782 100644 --- a/src/base/errors.h +++ b/src/base/errors.h @@ -5,7 +5,7 @@ extern "C" { #endif #include "std.h" -#include "types.h" +#include "unitype.h" typedef enum ErrorId { SUCCESS, // not an error diff --git a/src/base/init.c b/src/base/init.c new file mode 100644 index 0000000..f838c64 --- /dev/null +++ b/src/base/init.c @@ -0,0 +1,97 @@ +#include "base.h" +#include "../Autoarr/Autoarr.h" +#include "../SearchTree/SearchTree.h" +#include "../Hashtable/Hashtable.h" +#include "../String/StringBuilder.h" + +void kerepTypeDescriptors_initKerepTypes(){ + // null + kerepType_register(NULL, kerepTypeId_Null, NULL); + // base types + kerepType_register(char, kerepTypeId_Char, NULL); + kerepType_register(bool, kerepTypeId_Bool, NULL); + kerepType_register(float32, kerepTypeId_Float32, NULL); + kerepType_register(float64, kerepTypeId_Float64, NULL); + kerepType_register(int8, kerepTypeId_Int8, NULL); + kerepType_register(uint8, kerepTypeId_UInt8, NULL); + kerepType_register(int16, kerepTypeId_Int16, NULL); + kerepType_register(uint16, kerepTypeId_UInt16, NULL); + kerepType_register(int32, kerepTypeId_Int32, NULL); + kerepType_register(uint32, kerepTypeId_UInt32, NULL); + kerepType_register(int64, kerepTypeId_Int64, NULL); + kerepType_register(uint64, kerepTypeId_UInt64, NULL); + // base type pointers + kerepType_register(char*, kerepTypeId_CharPtr, NULL); + kerepType_register(bool*, kerepTypeId_BoolPtr, NULL); + kerepType_register(float32*, kerepTypeId_Float32Ptr, NULL); + kerepType_register(float64*, kerepTypeId_Float64Ptr, NULL); + kerepType_register(int8*, kerepTypeId_Int8Ptr, NULL); + kerepType_register(uint8*, kerepTypeId_UInt8Ptr, NULL); + kerepType_register(int16*, kerepTypeId_Int16Ptr, NULL); + kerepType_register(uint16*, kerepTypeId_UInt16Ptr, NULL); + kerepType_register(int32*, kerepTypeId_Int32Ptr, NULL); + kerepType_register(uint32*, kerepTypeId_UInt32Ptr, NULL); + kerepType_register(int64*, kerepTypeId_Int64Ptr, NULL); + kerepType_register(uint64*, kerepTypeId_UInt64Ptr, NULL); + + // base type autoarrs + kerepType_register(Autoarr_char, kerepTypeId_AutoarrChar, ____Autoarr_free_char); + kerepType_register(Autoarr_bool, kerepTypeId_AutoarrBool, ____Autoarr_free_bool); + kerepType_register(Autoarr_float32, kerepTypeId_AutoarrFloat32, ____Autoarr_free_float32); + kerepType_register(Autoarr_float64, kerepTypeId_AutoarrFloat64, ____Autoarr_free_float64); + kerepType_register(Autoarr_int8, kerepTypeId_AutoarrInt8, ____Autoarr_free_int8); + kerepType_register(Autoarr_uint8, kerepTypeId_AutoarrUInt8, ____Autoarr_free_uint8); + kerepType_register(Autoarr_int16, kerepTypeId_AutoarrInt16, ____Autoarr_free_int16); + kerepType_register(Autoarr_uint16, kerepTypeId_AutoarrUInt16, ____Autoarr_free_uint16); + kerepType_register(Autoarr_int32, kerepTypeId_AutoarrInt32, ____Autoarr_free_int32); + kerepType_register(Autoarr_uint32, kerepTypeId_AutoarrUInt32, ____Autoarr_free_uint32); + kerepType_register(Autoarr_int64, kerepTypeId_AutoarrInt64, ____Autoarr_free_int64); + kerepType_register(Autoarr_uint64, kerepTypeId_AutoarrUInt64, ____Autoarr_free_uint64); + // base type autoarr pointers + kerepType_register(Autoarr_char*, kerepTypeId_AutoarrCharPtr, ____Autoarr_free_char); + kerepType_register(Autoarr_bool*, kerepTypeId_AutoarrBoolPtr, ____Autoarr_free_bool); + kerepType_register(Autoarr_float32*, kerepTypeId_AutoarrFloat32Ptr, ____Autoarr_free_float32); + kerepType_register(Autoarr_float64*, kerepTypeId_AutoarrFloat64Ptr, ____Autoarr_free_float64); + kerepType_register(Autoarr_int8*, kerepTypeId_AutoarrInt8Ptr, ____Autoarr_free_int8); + kerepType_register(Autoarr_uint8*, kerepTypeId_AutoarrUInt8Ptr, ____Autoarr_free_uint8); + kerepType_register(Autoarr_int16*, kerepTypeId_AutoarrInt16Ptr, ____Autoarr_free_int16); + kerepType_register(Autoarr_uint16*, kerepTypeId_AutoarrUInt16Ptr, ____Autoarr_free_uint16); + kerepType_register(Autoarr_int32*, kerepTypeId_AutoarrInt32Ptr, ____Autoarr_free_int32); + kerepType_register(Autoarr_uint32*, kerepTypeId_AutoarrUInt32Ptr, ____Autoarr_free_uint32); + kerepType_register(Autoarr_int64*, kerepTypeId_AutoarrInt64Ptr, ____Autoarr_free_int64); + kerepType_register(Autoarr_uint64*, kerepTypeId_AutoarrUInt64Ptr, ____Autoarr_free_uint64); + + // Unitype + kerepType_register(Unitype, kerepTypeId_Unitype, __UnitypePtr_free); + kerepType_register(Unitype*, kerepTypeId_UnitypePtr, __UnitypePtr_free); + kerepType_register(Autoarr_Unitype, kerepTypeId_AutoarrUnitype, ____Autoarr_free_Unitype_); + kerepType_register(Autoarr_Unitype*, kerepTypeId_AutoarrUnitypePtr, ____Autoarr_free_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 + kerepType_register(STNode, kerepTypeId_STNode, __STNode_free); + kerepType_register(STNode*, kerepTypeId_STNodePtr, __STNode_free); + + // KeyValuePair + kerepType_register(KVPair, kerepTypeId_KVPair, __KVPair_free); + kerepType_register(KVPair*, kerepTypeId_KVPairPtr, __KVPair_free); + kerepType_register(Autoarr_KVPair, kerepTypeId_AutoarrKVPair, ____Autoarr_free_KVPair_); + kerepType_register(Autoarr_KVPair*, kerepTypeId_AutoarrKVPairPtr, ____Autoarr_free_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 + kerepType_register(Hashtable, kerepTypeId_Hashtable, __Hashtable_free); + kerepType_register(Hashtable*, kerepTypeId_HashtablePtr, __Hashtable_free); + + // StringBuilder + kerepType_register(Autoarr_string, kerepTypeId_AutoarrString, ____Autoarr_free_string); + kerepType_register(Autoarr_string*, kerepTypeId_AutoarrStringPtr, ____Autoarr_free_string); + kerepType_register(StringBuilder, kerepTypeId_StringBuilder, __StringBuilder_free); + kerepType_register(StringBuilder*, kerepTypeId_StringBuilderPtr, __StringBuilder_free); +} diff --git a/src/base/init.h b/src/base/init.h new file mode 100644 index 0000000..dfe5e69 --- /dev/null +++ b/src/base/init.h @@ -0,0 +1,12 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +// call this between kerepTypeDescriptors_beginInit() and kerepTypeDescriptors_endInit() +void kerepTypeDescriptors_initKerepTypes(); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/src/base/std.h b/src/base/std.h index 6024772..1a69b10 100644 --- a/src/base/std.h +++ b/src/base/std.h @@ -12,10 +12,19 @@ extern "C" { #include #include +typedef int8_t int8; +typedef uint8_t uint8; +typedef int16_t int16; +typedef uint16_t uint16; +typedef int32_t int32; +typedef uint32_t uint32; +typedef int64_t int64; +typedef uint64_t uint64; +typedef float float32; +typedef double float64; #define dbg(N) printf("\e[95m%d\n",N) - #ifdef _MSC_VER #pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK #define _CRT_SECURE_NO_WARNINGS 1 @@ -29,13 +38,12 @@ extern "C" { #define CALL #endif #ifndef typeof - #define typeof __typeof__ + #define typeof(X) __typeof__(X) #endif #else #pragma GCC error "unknown compiler" #endif - #ifdef _MSC_VER #define IFWIN(YES, NO) YES #define IFMSC(YES, NO) YES @@ -49,6 +57,9 @@ extern "C" { #pragma GCC error "unknown compiler" #endif +#ifndef sprintf_s + #define sprintf_s(BUF, BUFSIZE, FORMAT, ...) sprintf(BUF, FORMAT, ## __VA_ARGS__) +#endif #if __cplusplus } diff --git a/src/base/types.c b/src/base/types.c index fed1f0b..b96bdb6 100644 --- a/src/base/types.c +++ b/src/base/types.c @@ -1,154 +1,71 @@ -#include "types.h" -#include "errors.h" #include "../Autoarr/Autoarr.h" -#include "../Hashtable/Hashtable.h" -#include "../SearchTree/SearchTree.h" +#include "unitype.h" -const char* my_type_name(my_type t){ - switch (t) { - case Null: return "Null"; - case Float64: return "Float64"; - case Float32: return "Float32"; - case Bool: return "Bool"; - case Char: return "Char"; - case Int8: return "Int8"; - case UInt8: return "UInt8"; - case Int16: return "Int16"; - case UInt16: return "UInt16"; - case Int32: return "Int32"; - case UInt32: return "UInt32"; - case Int64: return "Int64"; - case UInt64: return "UInt64"; - case Int8Ptr: return "Int8Ptr"; - case UInt8Ptr: return "UInt8Ptr"; - case Int16Ptr: return "Int16Ptr"; - case UInt16Ptr: return "UInt16Ptr"; - case Int32Ptr: return "Int32Ptr"; - case UInt32Ptr: return "UInt32Ptr"; - case Int64Ptr: return "Int64Ptr"; - case UInt64Ptr: return "UInt64Ptr"; - case CharPtr: return "CharPtr"; - case STNodePtr: return "STNodePtr"; - case HashtablePtr: return "HashtablePtr"; - case UniversalType: return "Unitype"; - case AutoarrInt8Ptr: return "AutoarrInt8Ptr"; - case AutoarrUInt8Ptr: return "AutoarrUInt8Ptr"; - case AutoarrInt16Ptr: return "AutoarrInt16Ptr"; - case AutoarrUInt16Ptr: return "AutoarrUInt16Ptr"; - case AutoarrInt32Ptr: return "AutoarrInt32Ptr"; - case AutoarrUInt32Ptr: return "AutoarrUInt32Ptr"; - case AutoarrInt64Ptr: return "AutoarrInt64Ptr"; - case AutoarrUInt64Ptr: return "AutoarrUInt64Ptr"; - case AutoarrUnitypePtr: return "AutoarrUnitypePtr"; - case AutoarrKVPairPtr: return "AutoarrKVPairPtr"; - default: throw(ERR_WRONGTYPE); - } +Autoarr_declare(kerepTypeDescriptor) +Autoarr_define(kerepTypeDescriptor) + +kerepTypeId_define(kerepTypeId_Null); + +kerepTypeId_define(kerepTypeId_Char); +kerepTypeId_define(kerepTypeId_Bool); +kerepTypeId_define(kerepTypeId_Float32); +kerepTypeId_define(kerepTypeId_Float64); +kerepTypeId_define(kerepTypeId_Int8); +kerepTypeId_define(kerepTypeId_UInt8); +kerepTypeId_define(kerepTypeId_Int16); +kerepTypeId_define(kerepTypeId_UInt16); +kerepTypeId_define(kerepTypeId_Int32); +kerepTypeId_define(kerepTypeId_UInt32); +kerepTypeId_define(kerepTypeId_Int64); +kerepTypeId_define(kerepTypeId_UInt64); + +kerepTypeId_define(kerepTypeId_CharPtr); +kerepTypeId_define(kerepTypeId_BoolPtr); +kerepTypeId_define(kerepTypeId_Float32Ptr); +kerepTypeId_define(kerepTypeId_Float64Ptr); +kerepTypeId_define(kerepTypeId_Int8Ptr); +kerepTypeId_define(kerepTypeId_UInt8Ptr); +kerepTypeId_define(kerepTypeId_Int16Ptr); +kerepTypeId_define(kerepTypeId_UInt16Ptr); +kerepTypeId_define(kerepTypeId_Int32Ptr); +kerepTypeId_define(kerepTypeId_UInt32Ptr); +kerepTypeId_define(kerepTypeId_Int64Ptr); +kerepTypeId_define(kerepTypeId_UInt64Ptr); + +// type descriptors are stored here during initialization +Autoarr(kerepTypeDescriptor)* __kerepTypeDescriptors=NULL; +// here type descriptors are stored when initialization is complited +kerepTypeDescriptor* typeDescriptors=NULL; +kerepTypeId kerepTypeId_last=-1; + +typedef enum{ + NotInitialized, Initializing, Initialized +} kerepTypeDescriptorsState; +kerepTypeDescriptorsState initState=NotInitialized; + +void kerepTypeDescriptors_beginInit(){ + printf("\e[94mtype descriptors initializing...\n"); + __kerepTypeDescriptors=Autoarr_create(kerepTypeDescriptor, 256, 256); + if(__kerepTypeDescriptors==NULL) throw(ERR_NULLPTR); } -// frees VoidPtr value or does nothing if type isn't pointer -void Unitype_free(Unitype u){ - switch (u.type) { - case Null: - case Float32: - case Float64: - case Char: - case Bool: - case Int8: - case UInt8: - case Int16: - case UInt16: - case Int32: - case UInt32: - case Int64: - case UInt64: - break; - case Int8Ptr: - case UInt8Ptr: - case Int16Ptr: - case UInt16Ptr: - case Int32Ptr: - case UInt32Ptr: - case Int64Ptr: - case UInt64Ptr: - case CharPtr: - free(u.VoidPtr); - break; - case HashtablePtr: - Hashtable_free(u.VoidPtr); - break; - case STNodePtr: - STNode_free(u.VoidPtr); - break; - case AutoarrInt8Ptr: - __Autoarr_free_int8(u.VoidPtr); - break; - case AutoarrUInt8Ptr: - __Autoarr_free_uint8(u.VoidPtr); - break; - case AutoarrInt16Ptr: - __Autoarr_free_int16(u.VoidPtr); - break; - case AutoarrUInt16Ptr: - __Autoarr_free_uint16(u.VoidPtr); - break; - case AutoarrInt32Ptr: - __Autoarr_free_int32(u.VoidPtr); - break; - case AutoarrUInt32Ptr: - __Autoarr_free_uint32(u.VoidPtr); - break; - case AutoarrInt64Ptr: - __Autoarr_free_int64(u.VoidPtr); - break; - case AutoarrUInt64Ptr: - __Autoarr_free_uint64(u.VoidPtr); - break; - case AutoarrUnitypePtr: - Autoarr_free_Unitype(u.VoidPtr); - break; - case AutoarrKVPairPtr: - Autoarr_free_KVPair(u.VoidPtr); - break; - default: throw(ERR_WRONGTYPE); - } +void kerepTypeDescriptors_endInit(){ + typeDescriptors=Autoarr_toArray(__kerepTypeDescriptors); + Autoarr_free(__kerepTypeDescriptors,true); + if(typeDescriptors==NULL) throw(ERR_NULLPTR); + printf("\e[92minitialized %u type descriptors\n", kerepTypeId_last); } -#define BUFSIZE 64 -char* sprintuni(Unitype v){ - char* buf=malloc(BUFSIZE); - IFMSC( - switch (v.type) { - case Null: sprintf_s(buf, BUFSIZE, "{Null}");break; - case Float64: sprintf_s(buf, BUFSIZE, "{%s : %lf}", my_type_name(v.type),v.Float64);break; - case Bool: - case UInt64: sprintf_s(buf, BUFSIZE, "{%s : %lu}", my_type_name(v.type),v.UInt64);break; - case Int64: sprintf_s(buf, BUFSIZE, "{%s : %ld}", my_type_name(v.type),v.Int64);break; - case CharPtr: ; - size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2; - buf=realloc(buf, newBUFSIZE); - sprintf_s(buf, newBUFSIZE, "{%s : \"%s\"}", my_type_name(v.type),(char*)v.VoidPtr); - break; - default: sprintf_s(buf, BUFSIZE, "{%s : %p}", my_type_name(v.type),v.VoidPtr);break; - }, - switch (v.type) { - case Null: sprintf(buf, "{Null}"); break; - case Float64: sprintf(buf, "{%s : %lf}", my_type_name(v.type),v.Float64); break; - case Bool: - case UInt64: sprintf(buf, "{%s : " IFWIN("%llu", "%lu") "}", my_type_name(v.type),v.UInt64); break; - case Int64: sprintf(buf, "{%s : " IFWIN("%lld", "%ld") "}", my_type_name(v.type),v.Int64); break; - case CharPtr: ; - size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2; - buf=realloc(buf, newBUFSIZE); - sprintf(buf, "{%s : \"%s\"}", my_type_name(v.type),(char*)v.VoidPtr); - break; - default: sprintf(buf, "{%s : %p}", my_type_name(v.type),v.VoidPtr);break; - } - ); - return buf; +void __kerepType_register(char* name, int16 size, void (*free_members)(void*)){ + kerepTypeDescriptor typeDesc={ + .name=name, + .size=size, + .free_members=free_members, + .id=++kerepTypeId_last + }; + Autoarr_add(__kerepTypeDescriptors, typeDesc); } -void printuni(Unitype v){ - char* s=sprintuni(v); - fputs(s, stdout); - free(s); -} \ No newline at end of file +kerepTypeDescriptor kerepTypeDescriptor_get(kerepTypeId id){ + return typeDescriptors[id]; +} diff --git a/src/base/types.h b/src/base/types.h index e34d95f..8d5dd23 100644 --- a/src/base/types.h +++ b/src/base/types.h @@ -6,52 +6,58 @@ extern "C" { #include "std.h" -typedef int8_t int8; -typedef uint8_t uint8; -typedef int16_t int16; -typedef uint16_t uint16; -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; -typedef float float32; -typedef double float64; -typedef enum __attribute__((__packed__)) my_type { - Null, Float32, Float64, Char, Bool, - UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64, - UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr, - CharPtr, STNodePtr, HashtablePtr, - UniversalType, - AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr, - AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr, - AutoarrUnitypePtr, AutoarrKVPairPtr, knSocketPtr -} my_type; -#define my_type_last knSocketPtr +typedef uint16 kerepTypeId; -const char* my_type_name(my_type t); +typedef struct kerepTypeDescriptor{ + void (*free_members)(void*); // NULL or function which frees all struct members + char* name; + kerepTypeId id; + uint16 size; +} kerepTypeDescriptor; -typedef struct Unitype{ - union { - int64 Int64; - uint64 UInt64; - double Float64; - bool Bool; - void* VoidPtr; - }; - my_type type; -} Unitype; +#define kerepTypeId_declare(ID_VAR_NAME)\ + extern kerepTypeId ID_VAR_NAME +#define kerepTypeId_define(ID_VAR_NAME)\ + kerepTypeId ID_VAR_NAME=-1 -static const Unitype UniNull={.VoidPtr=NULL,.type=Null}; -static const Unitype UniTrue={.Bool=true,.type=Bool}; -static const Unitype UniFalse={.Bool=false,.type=Bool}; +extern kerepTypeId kerepTypeId_last; +void __kerepType_register(char* name, int16 size, void (*free_members)(void*)); -#define Uni(TYPE,VAL) (Unitype){.type=TYPE,.TYPE=VAL} -#define UniPtr(TYPE,VAL) (Unitype){.type=TYPE,.VoidPtr=VAL} +#define kerepType_register(TYPE, ID_VAR_NAME, FREE_MEMBERS_FUNC)\ + __kerepType_register(#ID_VAR_NAME, sizeof(TYPE), FREE_MEMBERS_FUNC);\ + ID_VAR_NAME=kerepTypeId_last; -// frees VoidPtr value or does nothing if type isn't pointer -void Unitype_free(Unitype u); -void printuni(Unitype v); -char* sprintuni(Unitype v); +void kerepTypeDescriptors_beginInit(); +void kerepTypeDescriptors_endInit(); +kerepTypeDescriptor kerepTypeDescriptor_get(kerepTypeId id); + +kerepTypeId_declare(kerepTypeId_Null); + +kerepTypeId_declare(kerepTypeId_Char); +kerepTypeId_declare(kerepTypeId_Bool); +kerepTypeId_declare(kerepTypeId_Float32); +kerepTypeId_declare(kerepTypeId_Float64); +kerepTypeId_declare(kerepTypeId_Int8); +kerepTypeId_declare(kerepTypeId_UInt8); +kerepTypeId_declare(kerepTypeId_Int16); +kerepTypeId_declare(kerepTypeId_UInt16); +kerepTypeId_declare(kerepTypeId_Int32); +kerepTypeId_declare(kerepTypeId_UInt32); +kerepTypeId_declare(kerepTypeId_Int64); +kerepTypeId_declare(kerepTypeId_UInt64); + +kerepTypeId_declare(kerepTypeId_CharPtr); +kerepTypeId_declare(kerepTypeId_BoolPtr); +kerepTypeId_declare(kerepTypeId_Float32Ptr); +kerepTypeId_declare(kerepTypeId_Float64Ptr); +kerepTypeId_declare(kerepTypeId_Int8Ptr); +kerepTypeId_declare(kerepTypeId_UInt8Ptr); +kerepTypeId_declare(kerepTypeId_Int16Ptr); +kerepTypeId_declare(kerepTypeId_UInt16Ptr); +kerepTypeId_declare(kerepTypeId_Int32Ptr); +kerepTypeId_declare(kerepTypeId_UInt32Ptr); +kerepTypeId_declare(kerepTypeId_Int64Ptr); +kerepTypeId_declare(kerepTypeId_UInt64Ptr); #if __cplusplus } diff --git a/src/base/unitype.c b/src/base/unitype.c new file mode 100644 index 0000000..8a555c5 --- /dev/null +++ b/src/base/unitype.c @@ -0,0 +1,40 @@ +#include "base.h" + +kerepTypeId_define(kerepTypeId_Unitype); +kerepTypeId_define(kerepTypeId_UnitypePtr); + +void Unitype_free(Unitype u){ + kerepTypeDescriptor type=kerepTypeDescriptor_get(u.typeId); + if(type.free_members) + type.free_members(u.VoidPtr); + if(u.allocatedInHeap) + free(u.VoidPtr); +} +void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); } + +#define BUFSIZE 64 +char* sprintuni(Unitype v){ + char* buf=malloc(BUFSIZE); + kerepTypeDescriptor type=kerepTypeDescriptor_get(v.typeId); + if(v.typeId==kerepTypeId_Null) + sprintf_s(buf, BUFSIZE, "{Null}"); + else if(v.typeId==kerepTypeId_Float64) + sprintf_s(buf, BUFSIZE, "{%s : %lf}", type.name,v.Float64); + else if(v.typeId==kerepTypeId_Bool || v.typeId==kerepTypeId_UInt64) + sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%llu", "%lu") "}", type.name,v.UInt64); + else if(v.typeId==kerepTypeId_Int64) + sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%lld", "%ld") "}", type.name,v.Int64); + else if(v.typeId==kerepTypeId_CharPtr){ + size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2; + buf=realloc(buf, newBUFSIZE); + sprintf_s(buf, BUFSIZE, "{%s : \"%s\"}", type.name,(char*)v.VoidPtr); + } + else sprintf_s(buf, BUFSIZE, "{%s : %p}", type.name,v.VoidPtr); + return buf; +} + +void printuni(Unitype v){ + char* s=sprintuni(v); + fputs(s, stdout); + free(s); +} \ No newline at end of file diff --git a/src/base/unitype.h b/src/base/unitype.h new file mode 100644 index 0000000..146c5d1 --- /dev/null +++ b/src/base/unitype.h @@ -0,0 +1,50 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include "types.h" + +typedef struct Unitype{ + union { + int64 Int64; + uint64 UInt64; + double Float64; + bool Bool; + void* VoidPtr; + char Bytes[8]; + }; + kerepTypeId typeId; + bool allocatedInHeap; // should Unitype_free call free() to VoidPtr* +} Unitype; +kerepTypeId_declare(kerepTypeId_Unitype); +kerepTypeId_declare(kerepTypeId_UnitypePtr); + + +#define Uni(TYPE, VAL) (Unitype){\ + .TYPE=VAL, .typeId=kerepTypeId_##TYPE, .allocatedInHeap=false} + +#define UniInt64(VAL) Uni(Int64, VAL) +#define UniUInt64(VAL) Uni(UInt64, VAL) +#define UniFloat64(VAL) Uni(Float64, VAL) +#define UniBool(VAL) Uni(Bool, VAL) + +#define UniPtrStack(ID_VAR_NAME, VAL) (Unitype){\ + .VoidPtr=VAL, .typeId=ID_VAR_NAME, .allocatedInHeap=false} +#define UniPtrHeap(ID_VAR_NAME, VAL) (Unitype){\ + .VoidPtr=VAL, .typeId=ID_VAR_NAME, .allocatedInHeap=true} + +#define UniNull UniPtrStack(kerepTypeId_Null, NULL) +#define UniTrue UniBool(true) +#define UniFalse UniBool(false) + +// frees VoidPtr value or does nothing if type isn't pointer +void Unitype_free(Unitype u); +void __UnitypePtr_free(void* u); +void printuni(Unitype v); +char* sprintuni(Unitype v); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/tests/main.cpp b/tests/main.cpp index 10f54f3..1f74e68 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -13,7 +13,10 @@ void test_all(){ int main(){ setlocale(LC_ALL, "en-US.Unicode"); - printf("\e[92mkerep tests are starting!\e[97m\n"); + kerepTypeDescriptors_beginInit(); + kerepTypeDescriptors_initKerepTypes(); + kerepTypeDescriptors_endInit(); + printf("\e[97mkerep tests are starting!\n"); optime("test_all",1,test_all()); printf("\e[0m\n"); return 0; diff --git a/tests/test_autoarr.c b/tests/test_autoarr.c index 11b818d..34dc121 100644 --- a/tests/test_autoarr.c +++ b/tests/test_autoarr.c @@ -47,7 +47,7 @@ void test_autoarr(){ resetar(ar); printf("\e[92mautoarr values reset\n"); printallval(ar); - Autoarr_free(ar); + Autoarr_free(ar, true); printf("\e[92mautoarr deleted\n"); })); } diff --git a/tests/test_dtsod.c b/tests/test_dtsod.c index cf238d2..f14c582 100644 --- a/tests/test_dtsod.c +++ b/tests/test_dtsod.c @@ -18,7 +18,7 @@ void print_dtsod(Hashtable* dtsod){ printf("\e[92m"); Hashtable_foreach(dtsod, p,({ printkvp(p); - if(p.value.type==HashtablePtr){ + if(p.value.typeId==kerepTypeId_HashtablePtr){ printf(": {\n"); Hashtable* sub=p.value.VoidPtr; Hashtable_foreach(sub, _p,({ diff --git a/tests/test_hash_functions.c b/tests/test_hash_functions.c index 10c6aee..b046bfd 100644 --- a/tests/test_hash_functions.c +++ b/tests/test_hash_functions.c @@ -33,7 +33,7 @@ char data[]="iojihiojopijiugbjmoihftytryfdrh"; }\ printf("\e[93m%u \e[94mcollisions detected in %u hashes\n", collisions, COLLISION_TESTS);\ }));\ - Autoarr_free(hashes);\ + Autoarr_free(hashes, true);\ printf("\e[96m--------------------------------------\n");\ }) diff --git a/tests/test_marshalling.c b/tests/test_marshalling.c index 3dde3c0..21c5721 100644 --- a/tests/test_marshalling.c +++ b/tests/test_marshalling.c @@ -4,7 +4,7 @@ EXPORT void CALL test_marshalling(char* text, KVPair** kptr){ KVPair* k=malloc(sizeof(KVPair)); k->key="message"; char* tc=cptr_copy(text); - Unitype u={.VoidPtr=tc, .type=CharPtr}; + Unitype u=UniPtrHeap(kerepTypeId_CharPtr,tc); k->value=u; *kptr=k; } diff --git a/tests/test_searchtree.c b/tests/test_searchtree.c index cff22a5..6309e85 100644 --- a/tests/test_searchtree.c +++ b/tests/test_searchtree.c @@ -6,8 +6,9 @@ void printstnode(STNode* node){ IFWIN("%llu", "%lu") "\n address: %p\n value: ",sizeof(STNode),node); printuni(node->value); + printf("\n"); // prints pointers to all existing branches - /* printf("\n branches: %p\n", node->branches); + /* printf(" branches: %p\n", node->branches); if(node->branches) for(uint8 i=0;i<8;i++){ printf(" \e[90m[%u]=%p\n",i,node->branches[i]); if(node->branches[i]) @@ -27,27 +28,27 @@ void test_searchtree(){ STNode* node=STNode_create(); printf("\e[92mnode created\n"); printf("push:\e[94m\n "); - Unitype u={.type=Int64,.Int64=-3}; + Unitype u=UniInt64(-3); printuni(u); ST_push(node,"type", u); printf(" -> type\n "); - u=(Unitype){.type=Int64,.Int64=25}; + u=UniInt64(25); printuni(u); ST_push(node,"time", u); printf(" -> time\n "); - u=(Unitype){.type=Float64,.Float64=-542.00600}; + u=UniFloat64(-542.00600); printuni(u); ST_push(node,"author_id", u); printf(" -> author_id\n "); - u=(Unitype){.type=Int64,.Int64=-31255}; + u=UniInt64(-31255); printuni(u); ST_push(node,"channel_id", u); printf(" -> channel_id\n "); - u=(Unitype){.type=Float64,.Float64=32.2004}; + u=UniPtrHeap(kerepTypeId_CharPtr, cptr_copy("32.2004")); printuni(u); ST_push(node,"message_id", u); printf(" -> message_id\n "); - u=(Unitype){.type=CharPtr,.VoidPtr=cptr_copy("some text UwU")}; + u=UniPtrStack(kerepTypeId_CharPtr,"some text UwU"); printuni(u); ST_push(node,"text", u); printf(" -> text\n");