diff --git a/Autoarr/StringBuilder.h b/Autoarr/StringBuilder.h deleted file mode 100644 index 0b52429..0000000 --- a/Autoarr/StringBuilder.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#if __cplusplus -extern "C" { -#endif - -#include "Autoarr.h" - - typedef Autoarr(int8) StringBuilder; - - StringBuilder StringBuilder_create(uint16 max_blocks_count, uint16 max_block_length); - void StringBuilder_append_char(StringBuilder* b, char c); - void StringBuilder_append_cptr(StringBuilder* b, char* s); - void StringBuilder_append_string(StringBuilder* b, string s); - void StringBuilder_append_int64(StringBuilder* b, int64 a); - void StringBuilder_append_uint64(StringBuilder* b, uint64 a); - void StringBuilder_append_double(StringBuilder* b, double a); - char* StringBuilder_build(StringBuilder* b); - -#if __cplusplus -} -#endif \ No newline at end of file diff --git a/DtsodParser/DtsodV24_deserialize.c b/DtsodParser/DtsodV24_deserialize.c index 7e3a354..686f8c5 100644 --- a/DtsodParser/DtsodV24_deserialize.c +++ b/DtsodParser/DtsodV24_deserialize.c @@ -1,24 +1,40 @@ #include "DtsodV24.h" -#include "../Autoarr/StringBuilder.h" +#include "../StringFragment/StringBuilder.h" #define ARR_BC 8 #define ARR_BL 16 #define STRB_BC 64 #define STRB_BL 1024 -Maybe ERROR_WRONGCHAR(char c, char* text){ - char errBuf[]="unexpected at:\n \"" - "00000000000000000000000000000000\""; - errBuf[12]=c; - for(uint8 i=0; i<32; i++) - // writes 16 chars before and 15 after the wrongchar - errBuf[i+22]=*(text - 16 + i); - safethrow(cptr_copy(errBuf)); +Maybe ERROR_WRONGCHAR(const char c, char* text, char* text_first, const char* srcfile, int line, const char* funcname){ + char errBuf[33]; + errBuf[32]='\0'; + char* errText=text-16; + if(errText at:\n" + " \"%s\"\n" + "\\___[%s:%d] %s()", + c,errBuf, srcfile,line,funcname), + sprintf(errmsg, "unexpected <%c> at:\n" + " \"%s\"\n" + " \\___[%s:%d] %s()", + c,errBuf, srcfile,line,funcname) + ); + safethrow(cptr_copy(errmsg)); } -#define safethrow_wrongchar(C) return ERROR_WRONGCHAR(C, text) +#define safethrow_wrongchar(C) return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__) typedef struct DeserializeSharedData{ + const char* sh_text_first; char* sh_text; bool sh_partOfDollarList; bool sh_readingList; @@ -39,7 +55,7 @@ Maybe __SkipComment(DeserializeSharedData* shared) { Maybe __ReadName(DeserializeSharedData* shared){ char c; - string nameStr={text,0}; + StringFragment nameStr={text,0}; text--; while ((c=*++text)) switch (c){ case ' ': case '\t': @@ -65,7 +81,7 @@ Maybe __ReadName(DeserializeSharedData* shared){ if((*++text)!=';') safethrow_wrongchar(c); case ':': - return SUCCESS(UniPtr(CharPtr,string_cpToCptr(nameStr))); + return SUCCESS(UniPtr(CharPtr,StringFragment_extract(nameStr).ptr)); case '$': if(nameStr.length!=0) safethrow_wrongchar(c); @@ -100,9 +116,9 @@ Maybe __ReadString(DeserializeSharedData* shared){ StringBuilder_append_char(b,c); } else { - char* str=StringBuilder_build(b); + StringFragment str=StringBuilder_build(b); Autoarr_clear(b); - return SUCCESS(UniPtr(CharPtr,str)); + return SUCCESS(UniPtr(CharPtr,str.ptr)); } } else { @@ -127,68 +143,62 @@ Maybe __ReadList(DeserializeSharedData* shared){ }; #define ReadList() __ReadList(shared) -Maybe __ParseValue(DeserializeSharedData* shared, string str){ - //printf("\e[94m<\e[96m%s\e[94m>\n",string_cpToCptr(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 SUCCESS(UniNull); - else safethrow_wrongchar(*str.ptr); - break; - case 't': - if(string_compare(str,trueStr)) +Maybe __ParseValue(DeserializeSharedData* shared, StringFragment str){ + //printf("\e[94m<\e[96m%s\e[94m>\n",StringFragment_extract(str)); + const StringFragment trueStr= {"true" ,0,4}; + const StringFragment falseStr={"false",0,5}; + switch(str.ptr[str.length-1]){ + //Bool + case 'e': { + if(StringFragment_compare(str,trueStr)) return SUCCESS(UniTrue); - else safethrow_wrongchar(*str.ptr); - break; - case 'f': - if(string_compare(str,falseStr)) + else if(StringFragment_compare(str,falseStr)) return SUCCESS(UniFalse); else safethrow_wrongchar(*str.ptr); - break; - default: - switch(str.ptr[str.length-1]){ - case 'f': { - char* _c=string_cpToCptr(str); - Unitype rez=Uni(Float64,strtod(_c,NULL)); - free(_c); - return SUCCESS(rez); - } - case 'u': { - uint64 lu=0; - char* _c=string_cpToCptr(str); - sscanf(_c,"%lu",&lu); - free(_c); - return SUCCESS(Uni(UInt64,lu)); - } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - int64 li=0; - char* _c=string_cpToCptr(str); - if(sscanf(_c,"%li",&li)!=1){ - char err[64]; - IFWIN( - sprintf_s(err,64,"can't parse to int: <%s>",_c), - sprintf(err,"can't parse to int: <%s>",_c) - ); - safethrow(err); - } - free(_c); - return SUCCESS(Uni(Int64,li)); - } - default: - safethrow_wrongchar(str.ptr[str.length-1]); + } + //Float64 + case 'f': { + char* _c=StringFragment_extract(str).ptr; + Unitype rez=Uni(Float64,strtod(_c,NULL)); + free(_c); + return SUCCESS(rez); + } + //UInt64 + case 'u': { + uint64 lu=0; + char* _c=StringFragment_extract(str).ptr; + sscanf(_c,"%lu",&lu); + free(_c); + return SUCCESS(Uni(UInt64,lu)); + } + //Int64 + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + int64 li=0; + char* _c=StringFragment_extract(str).ptr; + if(sscanf(_c,"%li",&li)!=1){ + char err[64]; + IFWIN( + sprintf_s(err,64,"can't parse to int: <%s>",_c), + sprintf(err,"can't parse to int: <%s>",_c) + ); + safethrow(err); } + free(_c); + return SUCCESS(Uni(Int64,li)); + } + //unknown type + default: + safethrow_wrongchar(str.ptr[str.length-1]); } + safethrow(ERR_ENDOFSTR); }; #define ParseValue(str) __ParseValue(shared, str) Maybe __ReadValue(DeserializeSharedData* shared){ char c; - string valueStr={text+1,0}; + StringFragment valueStr={text+1,0}; Unitype value; while ((c=*++text)) switch (c){ case ' ': case '\t': @@ -244,6 +254,7 @@ Maybe __ReadValue(DeserializeSharedData* shared){ Maybe __deserialize(char** _text, bool _calledRecursively) { DeserializeSharedData _shared={ + .sh_text_first=*_text, .sh_text=*_text, .sh_partOfDollarList=false, .sh_readingList=false, diff --git a/DtsodParser/DtsodV24_serialize.c b/DtsodParser/DtsodV24_serialize.c index 5b7c455..bf87775 100644 --- a/DtsodParser/DtsodV24_serialize.c +++ b/DtsodParser/DtsodV24_serialize.c @@ -1,5 +1,5 @@ #include "DtsodV24.h" -#include "../Autoarr/StringBuilder.h" +#include "../StringFragment/StringBuilder.h" //65536 max length! #define STRB_BC 64 @@ -51,8 +51,7 @@ void __AppendValue(SerializeSharedData* shared, Unitype u){ StringBuilder_append_cptr(b, u.Bool ? "true" : "false"); break; case Null: - if(!u.VoidPtr) StringBuilder_append_cptr(b, "null"); - else throw("Null-type pointer is not 0"); + throw("Null isn't supported in DtsodV24"); break; case AutoarrUnitypePtr: addc('['); @@ -97,7 +96,7 @@ void __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){ char* DtsodV24_serialize(Hashtable* dtsod){ StringBuilder sb=StringBuilder_create(STRB_BC,STRB_BL); __serialize(&sb,0,dtsod); - char* str=StringBuilder_build(&sb); + StringFragment str=StringBuilder_build(&sb); Autoarr_clear((&sb)); - return str; + return str.ptr; } diff --git a/Autoarr/StringBuilder.c b/StringFragment/StringBuilder.c similarity index 70% rename from Autoarr/StringBuilder.c rename to StringFragment/StringBuilder.c index 6a12265..4066c5a 100644 --- a/Autoarr/StringBuilder.c +++ b/StringFragment/StringBuilder.c @@ -14,11 +14,10 @@ void StringBuilder_append_cptr(StringBuilder* b, char* s){ Autoarr_add(b,c); } -void StringBuilder_append_string(StringBuilder* b, string s){ - while(s.length>0){ +void StringBuilder_append_string(StringBuilder* b, StringFragment s){ + s.ptr+=s.offset; + while(s.length-->0) Autoarr_add(b,*s.ptr++); - s.length--; - } } void StringBuilder_append_int64(StringBuilder* b, int64 a){ @@ -36,7 +35,7 @@ void StringBuilder_append_int64(StringBuilder* b, int64 a){ buf[i++]='0'+a%10; a/=10; } - string rev=string_reverse((string){buf,i}); + StringFragment rev=StringFragment_reverse((StringFragment){buf,0,i}); StringBuilder_append_string(b,rev); free(rev.ptr); } @@ -52,8 +51,7 @@ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){ buf[i++]='0'+a%10; a/=10; } - string rev=string_reverse((string){buf,i}); - printf("\e[95mrev:%s\n",string_cpToCptr(rev)); + StringFragment rev=StringFragment_reverse((StringFragment){buf,0,i}); StringBuilder_append_string(b,rev); free(rev.ptr); } @@ -67,11 +65,14 @@ void StringBuilder_append_double(StringBuilder* b, double a){ StringBuilder_append_cptr(b,buf); } -char* StringBuilder_build(StringBuilder* b){ - uint32 len=Autoarr_length(b); - char* str=malloc(len+1); - str[len]=0; - for(uint32 i=0;i characters from to new StringFragment (adding '\0' at the end) +StringFragment StringFragment_extract(StringFragment str){ + if(str.length==0) return stringNull; + StringFragment extr={ + .offset=0, + .length=str.length, + .ptr=malloc(str.length+1) + }; + str.ptr+=str.offset; + for(uint32 i=0; i0) + if(*str0.ptr++ != *str1.ptr++) + return false; + return true; +} + +//creates new StringFragment which is reversed variant of +StringFragment StringFragment_reverse(StringFragment s){ + if(s.length==0) return s; + StringFragment r={ + .offset=0, + .length=s.length, + .ptr=malloc(s.length) + }; + for(uint32 i=0; i characters from to new StringFragment (adding '\0' at the end) +StringFragment StringFragment_extract(StringFragment str); + +//compares two strings, NullPtr-friendly +bool StringFragment_compare(StringFragment str0, StringFragment str1); + +//creates new StringFragment which is reversed variant of +StringFragment StringFragment_reverse(StringFragment s); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/base/base.h b/base/base.h index ad651e6..b23b92d 100644 --- a/base/base.h +++ b/base/base.h @@ -7,7 +7,7 @@ extern "C" { #include "std.h" #include "types.h" #include "errors.h" -#include "mystr.h" +#include "cptr.h" // executes codeblock and prints execution time #ifdef CLOCK_REALTIME //non-standard high-precision clock diff --git a/base/cptr.c b/base/cptr.c new file mode 100644 index 0000000..0646b15 --- /dev/null +++ b/base/cptr.c @@ -0,0 +1,36 @@ +#include "base.h" + +//returns length of string (without \0) +uint32 cptr_length(char* str){ + uint32 len=0; + while(*(str++)) len++; + return len; +} + +//allocates new char[] and copies src there +char* cptr_copy(char* src){ + uint32 len=cptr_length(src)+1; + char* dst=malloc(len); + while(len-->0) + dst[len]=src[len]; + return dst; +} + +//compares two char buffers, NullPtr-friendly +bool cptr_compare(char* key0, char* key1){ + if(!key0) return key1 ? false : true; + if(!key1) return false; + while(*key0&&*key1) + if(*key0++ != *key1++) + return false; + return true; +} + +//multiplies char n times +char* char_multiply(char c, uint32 n){ + char* rez=malloc(n+1); + rez[n]=0; + while(n-->0) + rez[n]=c; + return rez; +} \ No newline at end of file diff --git a/base/cptr.h b/base/cptr.h new file mode 100644 index 0000000..46f6679 --- /dev/null +++ b/base/cptr.h @@ -0,0 +1,23 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include "types.h" + +//returns length of string (without \0) +uint32 cptr_length(char* str); + +//allocates new char[] and copies src there +char* cptr_copy(char* src); + +//compares two char buffers, NullPtr-friendly +bool cptr_compare(char* key0, char* key1); + +//multiplies char n times +char* char_multiply(char c, uint32 n); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/base/errors.c b/base/errors.c index d10d5d1..f56687a 100644 --- a/base/errors.c +++ b/base/errors.c @@ -1,6 +1,6 @@ #include "std.h" #include "errors.h" -#include "mystr.h" +#include "cptr.h" char* errname(err_t err){ switch(err){ diff --git a/base/mystr.c b/base/mystr.c deleted file mode 100644 index 5503b46..0000000 --- a/base/mystr.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "base.h" - -//returns length of string (including \0) -uint32 cptr_length(char* str){ - uint32 len=0; - while(*(str++)) len++; - return ++len; -} - -//allocates new char[] and copies src there -char* cptr_copy(char* src){ - uint32 len=cptr_length(src); - char* dst=malloc(len*sizeof(char)); - while(len-->0) - dst[len]=src[len]; - return dst; -} - -//compares two char buffers, NullPtr-friendly -bool cptr_compare(char* key0, char* key1){ - if(!key0) return key1 ? false : true; - if(!key1) return false; - while(*key0&&*key1) - if(*key0++ != *key1++) - return false; - return true; -} - -//multiplies char n times -char* char_multiply(char c, uint32 n){ - char* rez=malloc(n+1); - rez[n]=0; - while(n-->0) - rez[n]=c; - return rez; -} - -//copies str content to new char pointer value (adding '\0' at the end) -char* string_cpToCptr(string str){ - if(str.length==0) return NULL; - char* cptr=malloc(str.length*sizeof(char)+1); - cptr[str.length]=0; - while(str.length-->0) - cptr[str.length]=str.ptr[str.length]; - return 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=cptr_length(cptr)-1; - str.ptr=malloc(str.length); - for(uint32 i=0;i0) - if(*str0.ptr++ != *str1.ptr++) - return false; - return true; -} - -//creates new string which is reversed variant of -string string_reverse(string s){ - if(s.length==0) return s; - string r={malloc(s.length), s.length}; - for(uint32 i=0; i -string string_reverse(string s); - -#if __cplusplus -} -#endif \ No newline at end of file diff --git a/tests/main.c b/tests/main.c index 4b3149d..6b3b54b 100644 --- a/tests/main.c +++ b/tests/main.c @@ -13,7 +13,7 @@ void test_all(){ int main(){ setlocale(LC_ALL, "en-US.Unicode"); printf("\e[92mdtsod parser in c language!\e[97m\n"); - optime("test_all",1,{test_all();}); + optime("test_all",1,test_all()); printf("\e[0m\n"); return 0; } diff --git a/tests/test_string.c b/tests/test_string.c index e9e249f..5783047 100644 --- a/tests/test_string.c +++ b/tests/test_string.c @@ -1,16 +1,26 @@ #include "tests.h" -#include "../base/mystr.h" +#include "../StringFragment/StringFragment.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\" \e[94m-> string_cpFromCharPtr()\n",c); - if(s.length!=16) throw("string created with incorrect length"); - char* p=string_cpToCptr(s); - printf("\e[94mstring_cpToCptr() -> \e[92m\"%s\"\n",p); - free(p); + + StringFragment s={.ptr=cptr_copy(c),.offset=0,.length=cptr_length(c)}; + printf("\e[92m\"%s\" \e[94m-> StringFragment\n",c); + if(s.length!=16) throw("StringFragment created with incorrect length"); + + StringFragment extr=StringFragment_extract(s); + printf("\e[94mStringFragment_extract() -> \e[92m\"%s\"\n",extr.ptr); + if(extr.length!=16) throw("StringFragment extracted with incorrect length"); + free(extr.ptr); + + s.offset+=2; s.length-=4; + printf("\e[94mStringFragment offset+=2 length-=4\n"); + extr=StringFragment_extract(s); + printf("\e[94mStringFragment_extract() -> \e[92m\"%s\"\n",extr.ptr); + if(extr.length!=12) throw("StringFragment extracted with incorrect length"); free(s.ptr); + free(extr.ptr); })); } \ No newline at end of file