From df39b92cfd7c1ec97b448317ea5032bdd5c06c6b Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Tue, 1 Mar 2022 22:31:26 +0300 Subject: [PATCH] DtsodV24 deserialization almost completed --- .vscode/settings.json | 4 +- DtsodC/Makefile | 5 +- DtsodC/src/DtsodParser/DtsodV24.c | 129 +++++++++++--- DtsodC/src/DtsodParser/DtsodV24.c.backup | 187 +++++++++++++++++++++ DtsodC/src/DtsodParser/DtsodV24.h | 3 +- DtsodC/src/Hashtable/Hashtable.c | 5 +- DtsodC/src/Hashtable/Hashtable.h | 2 +- DtsodC/src/SearchTree/SearchTree.h | 2 +- DtsodC/src/base/base.h | 10 ++ DtsodC/src/base/mystr.c | 51 +++--- DtsodC/src/base/mystr.h | 15 +- DtsodC/src/base/types.h | 7 +- DtsodC/src/main.c | 12 -- DtsodC/src/tests/tests.h | 21 --- DtsodC/{src/tests/tests.c => tests/main.c} | 15 +- DtsodC/{src => }/tests/test_autoarr2.c | 2 +- DtsodC/tests/test_dtsod.c | 19 +++ DtsodC/{src => }/tests/test_hashtable.c | 10 +- DtsodC/{src => }/tests/test_searchtree.c | 2 +- DtsodC/tests/test_string.c | 16 ++ DtsodC/tests/tests.h | 11 ++ 21 files changed, 427 insertions(+), 101 deletions(-) create mode 100644 DtsodC/src/DtsodParser/DtsodV24.c.backup delete mode 100644 DtsodC/src/main.c delete mode 100644 DtsodC/src/tests/tests.h rename DtsodC/{src/tests/tests.c => tests/main.c} (80%) rename DtsodC/{src => }/tests/test_autoarr2.c (97%) create mode 100644 DtsodC/tests/test_dtsod.c rename DtsodC/{src => }/tests/test_hashtable.c (87%) rename DtsodC/{src => }/tests/test_searchtree.c (98%) create mode 100644 DtsodC/tests/test_string.c create mode 100644 DtsodC/tests/tests.h diff --git a/.vscode/settings.json b/.vscode/settings.json index 568cbfb..6e4b5f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,9 @@ "functional": "c", "istream": "c", "ranges": "c", - "streambuf": "c" + "streambuf": "c", + "chrono": "c", + "string": "c" }, "C_Cpp.errorSquiggles": "Disabled" } \ No newline at end of file diff --git a/DtsodC/Makefile b/DtsodC/Makefile index 89c179e..a0b800c 100644 --- a/DtsodC/Makefile +++ b/DtsodC/Makefile @@ -1,4 +1,5 @@ SRC=$(wildcard src/*c) $(wildcard src/**/*.c) +TESTS=$(wildcard tests/*c) $(wildcard tests/**/*.c) OUTDIR=bin/ OUTFILE=$(OUTDIR)dtsodc.com CMP=gcc @@ -14,10 +15,10 @@ clear_bin: clang: CMP=clang clang: all -CMPARGS= -Wall $(SRC) -o $(OUTFILE) +CMPARGS= -Wall $(SRC) $(TESTS) -o $(OUTFILE) build: @echo -e '\n\e[96m----------------[build]----------------\e[0m' - $(CMP) -O1 -flto -Wno-discarded-qualifiers $(CMPARGS) + $(CMP) -O1 -flto $(CMPARGS) build_dbg: @echo -e '\n\e[96m--------------[build_dbg]--------------\e[0m' $(CMP) -O0 -g $(CMPARGS).dbg diff --git a/DtsodC/src/DtsodParser/DtsodV24.c b/DtsodC/src/DtsodParser/DtsodV24.c index cfe7e8f..3e6fb73 100644 --- a/DtsodC/src/DtsodParser/DtsodV24.c +++ b/DtsodC/src/DtsodParser/DtsodV24.c @@ -4,15 +4,20 @@ #define ARR_BC 2 #define ARR_BL 8 -Hashtable* __parse(const char* text, bool called_recursively){ +Hashtable* __deserialize(char* text, bool calledRecursively){ Hashtable* dict=Hashtable_create(); - bool partOfDollarList=false; char c; + bool partOfDollarList=false; + bool readingList=false; void throw_wrongchar(char _c){ - char errstr[]="unexpected "; - errstr[12]=_c; - throw(errstr); + char errBuf[]="unexpected at:\n \"" + "00000000000000000000000000000000" + "\""; + errBuf[12]=_c; + for(uint8 i=0;i<32;i++) + errBuf[i+22]=*(text-16+i); + throw(errBuf); }; void SkipComment(){ @@ -30,7 +35,7 @@ Hashtable* __parse(const char* text, bool called_recursively){ SkipComment(); break; case '}': - if(!called_recursively) throw_wrongchar(c); + if(!calledRecursively) throw_wrongchar(c); case ':': return nameStr; case '$': @@ -39,8 +44,9 @@ Hashtable* __parse(const char* text, bool called_recursively){ case '=': case ';': case '\'': case '"': case '[': case ']': - case '{': + case '{': throw_wrongchar(c); + break; default: nameStr.length++; break; @@ -52,11 +58,13 @@ Hashtable* __parse(const char* text, bool called_recursively){ Unitype ReadValue(){ string valueStr={text,0}; - bool endOfList=false; + + //returns part of with quotes string ReadString(){ bool prevIsBackslash = false; string str={text,1}; while ((c=*++text)!='"' || prevIsBackslash){ + printf("%c",c); if (!c) throw(ERR_ENDOFSTR); prevIsBackslash= c=='\\' && !prevIsBackslash; str.length++; @@ -64,19 +72,96 @@ Hashtable* __parse(const char* text, bool called_recursively){ str.length++; return str; }; + Autoarr2(Unitype)* ReadList(){ - - throw(ERR_ENDOFSTR); - return NULL; + Autoarr2(Unitype)* list=malloc(sizeof(Autoarr2(Unitype))); + *list=Autoarr2_create(Unitype,ARR_BC,ARR_BL); + readingList=true; + while (true){ + Autoarr2_add(list,ReadValue()); + if (!readingList) break; + } + return list; }; + Hashtable* ReadDtsod(){ - - throw(ERR_ENDOFSTR); - return NULL; + if(*++text) //skips { + return __deserialize(text,true); + else { + throw(ERR_ENDOFSTR); + return NULL; + } }; - Unitype ParseValue(string str){ - throw(ERR_ENDOFSTR); + Unitype ParseValue(string str){ + const string nullStr={"null",4}; + const string trueStr={"true",4}; + const string falseStr={"false",5}; + switch(*str.ptr){ + case 'n': + if(string_compare(str,nullStr)) + return UniNull; + else throw_wrongchar(*str.ptr); + break; + case 't': + if(string_compare(str,trueStr)) + return UniTrue; + else throw_wrongchar(*str.ptr); + break; + case 'f': + if(string_compare(str,falseStr)) + return UniFalse; + else throw_wrongchar(*str.ptr); + break; + case '"': + if(str.ptr[str.length-1]=='"'){ + //removing quotes + string _str={str.ptr+1,str.length-1}; + return UniPtr(CharPtr, string_cpToCharPtr(_str)); + } + else throw_wrongchar(*str.ptr); + break; + default: + switch(str.ptr[str.length-1]){ + case 's': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToUShort() + : value_str.Remove(value_str.Length - 1).ToShort(); + case 'u': + return value_str.Remove(value_str.Length - 1).ToUInt(); + case 'i': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToUInt() + : value_str.Remove(value_str.Length - 1).ToInt(); + case 'l': + return value_str[value_str.Length - 2] == 'u' + ? value_str.Remove(value_str.Length - 2).ToULong() + : value_str.Remove(value_str.Length - 1).ToLong(); + case 'b': + return value_str[value_str.Length - 2] == 's' + ? value_str.Remove(value_str.Length - 2).ToSByte() + : value_str.Remove(value_str.Length - 1).ToByte(); + case 'f': + return value_str.Remove(value_str.Length - 1).ToFloat(); + case 'e': + return value_str[value_str.Length - 2] == 'd' + ? value_str.Remove(value_str.Length - 2).ToDecimal() + : throw new Exception("can't parse value:" + value_str); + default: + /* if (value_str.Contains('.')) + return (object)(value_str.ToDouble()); + else + { + try { return (object)(value_str.ToInt()); } + catch (FormatException) + { + Log("r", $"can't parse value: {value_str}"); + return null; + } + } */ + } + } + throw(ERR_NOTIMPLEMENTED); return UniNull; }; @@ -103,13 +188,14 @@ Hashtable* __parse(const char* text, bool called_recursively){ case '[': return UniPtr(AutoarrUnitypePtr,ReadList()); case ']': - endOfList=true; + readingList=false; break; case '{': return UniPtr(HashtablePtr,ReadDtsod()); case '=': case ':': case '}': case '$': throw_wrongchar(c); + break; default: valueStr.length++; break; @@ -119,12 +205,11 @@ Hashtable* __parse(const char* text, bool called_recursively){ return UniNull; }; - text--; - while((c=*++text)){ + while((c=*text++)){ string name=ReadName(); - if(name.length==0) //closing figure bracket in recursive call or end of file + if(name.length==0) //end of file or '}' in recursive call return dict; - char* nameCPtr=string_toCharPtr(name); + char* nameCPtr=string_cpToCharPtr(name); Unitype value=ReadValue(); if(partOfDollarList){ Autoarr2(Unitype)* list; @@ -143,4 +228,4 @@ Hashtable* __parse(const char* text, bool called_recursively){ return dict; } -Hashtable* DtsodV24_parse(const char* text) { return __parse(text,false); } +Hashtable* DtsodV24_deserialize(char* text) { return __deserialize(text,false); } diff --git a/DtsodC/src/DtsodParser/DtsodV24.c.backup b/DtsodC/src/DtsodParser/DtsodV24.c.backup new file mode 100644 index 0000000..bb9fc3e --- /dev/null +++ b/DtsodC/src/DtsodParser/DtsodV24.c.backup @@ -0,0 +1,187 @@ +#include "DtsodV24.h" +#include "../Autoarr/StringBuilder.h" + +#define ARR_BC 2 +#define ARR_BL 8 + +Hashtable* __parse(string textStr, bool called_recursively){ + Hashtable* dict=Hashtable_create(); + char* text=textStr.ptr; + char c; + bool partOfDollarList=false; + bool readingList=false; + + void throw_wrongchar(char _c){ + char errstr[]="unexpected "; + errstr[12]=_c; + throw(errstr); + }; + + void SkipComment(){ + while((c=*++text)!='\n') + if(!c) throw(ERR_ENDOFSTR); + }; + + string ReadName(){ + string nameStr={text,0}; + while ((c=*++text)) switch (c){ + case ' ': case '\t': + case '\r': case '\n': + break; + case '#': + SkipComment(); + break; + case '}': + if(!called_recursively) throw_wrongchar(c); + case ':': + return nameStr; + case '$': + partOfDollarList=true; + break; + case '=': case ';': + case '\'': case '"': + case '[': case ']': + case '{': + throw_wrongchar(c); + default: + nameStr.length++; + break; + } + + if(nameStr.length>0) throw(ERR_ENDOFSTR); + return nameStr; + }; + + Unitype ReadValue(){ + string valueStr={text,0}; + + //returns part of with brackets + string ReadString(){ + bool prevIsBackslash = false; + string str={text,1}; + while ((c=*++text)!='"' || prevIsBackslash){ + if (!c) throw(ERR_ENDOFSTR); + prevIsBackslash= c=='\\' && !prevIsBackslash; + str.length++; + } + str.length++; + return str; + }; + + Autoarr2(Unitype)* ReadList(){ + Autoarr2(Unitype)* list=malloc(sizeof(Autoarr2(Unitype))); + *list=Autoarr2_create(Unitype,ARR_BC,ARR_BL); + readingList=true; + while (true){ + Autoarr2_add(list,ReadValue()); + if (!readingList) break; + } + return list; + }; + + Hashtable* ReadDtsod(){ + short bracketBalance = 1; + string dtsodStr={text+1,0}; + while ((c=*++text))//пропускает начальный символ '{' + { + if(bracketBalance) switch (c) + { + case ' ': case '\t': + case '\r': case '\n': + break; + case '#': + SkipComment(); + break; + case '{': + bracketBalance++; + dtsodStr.length++; + break; + case '}': + bracketBalance--; + if (bracketBalance != 0) + dtsodStr.length++; + break; + case '"': + string _str=ReadString(); + dtsodStr.length+=_str.length; + break; + default: + dtsodStr.length++; + break; + } + else return __parse(dtsodStr,true); + } + + throw(ERR_ENDOFSTR); + return NULL; + }; + + Unitype ParseValue(string str){ + + throw(ERR_NOTIMPLEMENTED); + return UniNull; + }; + + while ((c=*++text)) switch (c){ + case ' ': case '\t': + case '\r': case '\n': + break; + case '#': + SkipComment(); + break; + case '"': + valueStr=ReadString(); + break; + case '\'': + text++; + char valueChar=*++text; + if (*++text != '\'') throw("after <'> should be char"); + else if (valueStr.length!=0) throw("char assignement error"); + else return Uni(Char,valueChar); + break; + case ';': + case ',': + return ParseValue(valueStr); + case '[': + return UniPtr(AutoarrUnitypePtr,ReadList()); + case ']': + readingList=false; + break; + case '{': + return UniPtr(HashtablePtr,ReadDtsod()); + case '=': case ':': + case '}': case '$': + throw_wrongchar(c); + default: + valueStr.length++; + break; + } + + throw(ERR_ENDOFSTR); + return UniNull; + }; + + while((c=*text++)){ + string name=ReadName(); + if(name.length==0) //closing figure bracket in recursive call or end of file + return dict; + char* nameCPtr=string_cpToCharPtr(name); + Unitype value=ReadValue(); + if(partOfDollarList){ + Autoarr2(Unitype)* list; + Unitype lu; + if(Hashtable_try_get(dict,nameCPtr, &lu)) + list=(Autoarr2(Unitype)*)lu.VoidPtr; + else{ + list=malloc(sizeof(Autoarr2(Unitype))); + *list=Autoarr2_create(Unitype,ARR_BC,ARR_BL); + Hashtable_add(dict,nameCPtr,UniPtr(AutoarrUnitypePtr,list)); + } + Autoarr2_add(list,value); + } + else Hashtable_add(dict,nameCPtr,value); + } + return dict; +} + +Hashtable* DtsodV24_parse(const char* text) { return __parse((text,false); } diff --git a/DtsodC/src/DtsodParser/DtsodV24.h b/DtsodC/src/DtsodParser/DtsodV24.h index 6a40bdd..c4c2aa8 100644 --- a/DtsodC/src/DtsodParser/DtsodV24.h +++ b/DtsodC/src/DtsodParser/DtsodV24.h @@ -2,4 +2,5 @@ #include "../base/base.h" #include "../Hashtable/Hashtable.h" -Hashtable* DtsodV24_parse(const char* text); +Hashtable* DtsodV24_deserialize(char* text); +string DtsodV24_serialize(Hashtable* dtsod); diff --git a/DtsodC/src/Hashtable/Hashtable.c b/DtsodC/src/Hashtable/Hashtable.c index 58f848c..0e950bb 100644 --- a/DtsodC/src/Hashtable/Hashtable.c +++ b/DtsodC/src/Hashtable/Hashtable.c @@ -53,7 +53,6 @@ void Hashtable_expand(Hashtable* ht){ ht->rows=newrows; } -#include "../tests/tests.h" Autoarr2(KeyValuePair)* getrow(Hashtable* ht, char* key, bool can_expand){ Autoarr2(KeyValuePair)* ar=ht->rows+ihash(key)%HT_HEIGHTS[ht->hein]; if(can_expand && Autoarr2_length(ar)==Autoarr2_max_length(ar)) @@ -76,7 +75,7 @@ Unitype* Hashtable_getptr(Hashtable* ht, char* key){ uint32 arlen=Autoarr2_length(ar); for(uint32 i=0;ikey)) return &p->value; + if(charbuf_compare(key,p->key)) return &p->value; } return NULL; } @@ -86,7 +85,7 @@ Unitype Hashtable_get(Hashtable* ht, char* key){ uint32 arlen=Autoarr2_length(ar); for(uint32 i=0;i0) @@ -16,42 +16,53 @@ char* mystrcpy(char* src){ return dst; } -//compares two strings, NullPtr-friendly -bool mystrcmp(char* key0, char* key1){ - if(!key0) return key1 ? 0 : 1; - else if(!key1) return 0; - while(*key0&&*key1){ - if(*key0!=*key1) return 0; - key0++; - key1++; - } - return 1; +//compares two char buffers, NullPtr-friendly +bool charbuf_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 -char* mystrmtpl(char c, uint32 n){ +char* char_multiply(char c, uint32 n){ char* rez=malloc(n+1); rez[n]=0; - while(n>0) - rez[--n]=c; + while(n-->0) + rez[n]=c; return rez; } -char* string_toCharPtr(string str){ +//copies str content to new char pointer value (adding '\0' at the end) +char* string_cpToCharPtr(string str){ char* cptr=malloc(str.length*sizeof(char)+1); if(str.length==0) return NULL; cptr[str.length]=0; - while(str.length>0) - cptr[--str.length]=str.ptr[str.length]; + while(str.length-->0) + cptr[str.length]=str.ptr[str.length]; return cptr; } -string string_fromCharPtr(char* cptr){ +//copies cptr content (excluding '\0' at the end) to new string +string string_cpFromCharPtr(char* cptr){ if(!cptr) return stringNull; string str; - str.length=mystrlen(cptr); + str.length=mystrlen(cptr)-1; str.ptr=malloc(str.length); - for(uint32 i=0;i>str.length;i++) + for(uint32 i=0;i0) + if(*str0.ptr++ != *str1.ptr++) + return false; + return true; +} diff --git a/DtsodC/src/base/mystr.h b/DtsodC/src/base/mystr.h index 0bd4b70..3ccd9aa 100644 --- a/DtsodC/src/base/mystr.h +++ b/DtsodC/src/base/mystr.h @@ -6,13 +6,13 @@ uint32 mystrlen(char* str); //allocates new char[] and copies src there -char* mystrcpy(char* src); +char* charbuf_copy(char* src); -//compares two strings, NullPtr-friendly -bool mystrcmp(char* key0, char* key1); +//compares two char buffers, NullPtr-friendly +bool charbuf_compare(char* key0, char* key1); //multiplies char n times -char* mystrmtpl(char c, uint32 n); +char* char_multiply(char c, uint32 n); //my fixed length string struct //doesn't store '\0' at the end @@ -24,7 +24,10 @@ typedef struct string{ static const string stringNull={NULL,0}; //copies str content to new char pointer value (adding '\0' at the end) -char* string_toCharPtr(string str); +char* string_cpToCharPtr(string str); //copies cptr content (excluding '\0' at the end) to new string -string string_fromCharPtr(char* cptr); +string string_cpFromCharPtr(char* cptr); + +//compares two strings, NullPtr-friendly +bool string_compare(string str0, string str1); diff --git a/DtsodC/src/base/types.h b/DtsodC/src/base/types.h index 2ffaa33..ca3359e 100644 --- a/DtsodC/src/base/types.h +++ b/DtsodC/src/base/types.h @@ -14,7 +14,7 @@ typedef enum my_type{ Null, Float, Double, Char, Bool, UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64, UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr, - UniversalType, STNodePtr, HashtablePtr, + CharPtr, UniversalType, STNodePtr, HashtablePtr, AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr, AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr, AutoarrUnitypePtr, AutoarrKVPairPtr @@ -46,6 +46,9 @@ typedef struct Unitype{ }; } Unitype; +static const Unitype UniNull={Null,.VoidPtr=NULL}; +static const Unitype UniTrue={Bool,.Bool=true}; +static const Unitype UniFalse={Bool,.Bool=false}; + #define Uni(TYPE,VAL) (Unitype){.type=TYPE,.TYPE=VAL} #define UniPtr(TYPE,VAL) (Unitype){.type=TYPE,.VoidPtr=VAL} -#define UniNull (Unitype){Null,.VoidPtr=NULL} diff --git a/DtsodC/src/main.c b/DtsodC/src/main.c deleted file mode 100644 index 8bbccd1..0000000 --- a/DtsodC/src/main.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "base/base.h" -#include "tests/tests.h" -#include "Autoarr/Autoarr2.h" -#include "Hashtable/Hashtable.h" - -int main(){ - setlocale(LC_ALL, "en-US.Unicode"); - printf("\e[92mdtsod parser in c language!\e[97m\n"); - optime("test_all",1,{test_all();}); - printf("\e[0m\n"); - return 0; -} diff --git a/DtsodC/src/tests/tests.h b/DtsodC/src/tests/tests.h deleted file mode 100644 index 4b0268f..0000000 --- a/DtsodC/src/tests/tests.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../base/base.h" - -void printuni(Unitype v); - -void test_all(void); -void test_searchtree(void); -void test_autoarr2(void); -void test_hashtable(void); - -// executes codeblock and prints execution time -// should be used like optime({foo();}), because just optime(foo()) works slower -#define optime(opname,repeats,codeblock) ({\ - clock_t start=clock();\ - for(uint64 ___OPREP=0;___OPREP0) { - char* str0=mystrmtpl(' ',i>=100?0:(i>=10?1:2)); - char* str1=mystrmtpl(' ',lgs[i]>=100?0:(lgs[i]>=10?1:2)); - char* str2=mystrmtpl('#',lgs[i]/100); + char* str0=char_multiply(' ',i>=100?0:(i>=10?1:2)); + char* str1=char_multiply(' ',lgs[i]>=100?0:(lgs[i]>=10?1:2)); + char* str2=char_multiply('#',lgs[i]/100); printf("\e[94m length: \e[96m%u %s \e[94mfrequency: \e[96m%u %s \e[90m%s\n",i,str0,lgs[i],str1,str2); free(str0); free(str1); @@ -61,7 +61,7 @@ Unitype gett(Hashtable* ht){ } -void test_hashtable(void){ +void test_hashtable(){ optime("test_hashtable",1,({ printf("\e[96m-----------[test_hashtable]------------\n"); Hashtable* ht=Hashtable_create(); diff --git a/DtsodC/src/tests/test_searchtree.c b/DtsodC/tests/test_searchtree.c similarity index 98% rename from DtsodC/src/tests/test_searchtree.c rename to DtsodC/tests/test_searchtree.c index 0b83b59..cf4d476 100644 --- a/DtsodC/src/tests/test_searchtree.c +++ b/DtsodC/tests/test_searchtree.c @@ -1,5 +1,5 @@ #include "tests.h" -#include "../SearchTree/SearchTree.h" +#include "../src/SearchTree/SearchTree.h" void printstnode(STNode* node){ printf("\e[94mSTNode: %lu\n address: %p\n value: ",sizeof(STNode),node); diff --git a/DtsodC/tests/test_string.c b/DtsodC/tests/test_string.c new file mode 100644 index 0000000..87a05d2 --- /dev/null +++ b/DtsodC/tests/test_string.c @@ -0,0 +1,16 @@ +#include "tests.h" +#include "../src/base/mystr.h" + +void test_string(){ + optime(__func__,1,({ + printf("\e[96m-------------[test_string]-------------\n"); + char c[]="0123456789abcdef"; + string s=string_cpFromCharPtr(c); + printf("\e[92m\"%s\" -> string_cpFromCharPtr()\n",c); + if(s.length!=16) throw("string created with incorrect length"); + char* p=string_cpToCharPtr(s); + printf("\e[92mstring_cpToCharPtr() -> \"%s\"\n",p); + free(p); + free(s.ptr); + })); +} \ No newline at end of file diff --git a/DtsodC/tests/tests.h b/DtsodC/tests/tests.h new file mode 100644 index 0000000..20f12b6 --- /dev/null +++ b/DtsodC/tests/tests.h @@ -0,0 +1,11 @@ +#pragma once + +#include "../src/base/base.h" + +void printuni(Unitype v); + +void test_searchtree(); +void test_autoarr2(); +void test_hashtable(); +void test_string(); +void test_dtsod();