string -> StringFragment, throw_wrongchar() fixed

This commit is contained in:
root 2022-04-12 22:59:29 +03:00
parent 07c5a0ce69
commit 41f32f4f8c
15 changed files with 268 additions and 236 deletions

View File

@ -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

View File

@ -1,24 +1,40 @@
#include "DtsodV24.h" #include "DtsodV24.h"
#include "../Autoarr/StringBuilder.h" #include "../StringFragment/StringBuilder.h"
#define ARR_BC 8 #define ARR_BC 8
#define ARR_BL 16 #define ARR_BL 16
#define STRB_BC 64 #define STRB_BC 64
#define STRB_BL 1024 #define STRB_BL 1024
Maybe ERROR_WRONGCHAR(char c, char* text){ Maybe ERROR_WRONGCHAR(const char c, char* text, char* text_first, const char* srcfile, int line, const char* funcname){
char errBuf[]="unexpected <c> at:\n \"" char errBuf[33];
"00000000000000000000000000000000\""; errBuf[32]='\0';
errBuf[12]=c; char* errText=text-16;
for(uint8 i=0; i<32; i++) if(errText<text_first) errText=text_first;
for(uint8 i=0; i<32; i++){
//writes 16 chars before and 15 after the wrongchar //writes 16 chars before and 15 after the wrongchar
errBuf[i+22]=*(text - 16 + i); char _c=errText[i];
safethrow(cptr_copy(errBuf)); errBuf[i]=_c;
if(!_c) break;
} }
#define safethrow_wrongchar(C) return ERROR_WRONGCHAR(C, text) char* errmsg=malloc(256);
IFWIN(
sprintf_s(errmsg,256, "unexpected <%c> 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, shared->sh_text_first, __FILE__,__LINE__,__func__)
typedef struct DeserializeSharedData{ typedef struct DeserializeSharedData{
const char* sh_text_first;
char* sh_text; char* sh_text;
bool sh_partOfDollarList; bool sh_partOfDollarList;
bool sh_readingList; bool sh_readingList;
@ -39,7 +55,7 @@ Maybe __SkipComment(DeserializeSharedData* shared) {
Maybe __ReadName(DeserializeSharedData* shared){ Maybe __ReadName(DeserializeSharedData* shared){
char c; char c;
string nameStr={text,0}; StringFragment nameStr={text,0};
text--; text--;
while ((c=*++text)) switch (c){ while ((c=*++text)) switch (c){
case ' ': case '\t': case ' ': case '\t':
@ -65,7 +81,7 @@ Maybe __ReadName(DeserializeSharedData* shared){
if((*++text)!=';') if((*++text)!=';')
safethrow_wrongchar(c); safethrow_wrongchar(c);
case ':': case ':':
return SUCCESS(UniPtr(CharPtr,string_cpToCptr(nameStr))); return SUCCESS(UniPtr(CharPtr,StringFragment_extract(nameStr).ptr));
case '$': case '$':
if(nameStr.length!=0) if(nameStr.length!=0)
safethrow_wrongchar(c); safethrow_wrongchar(c);
@ -100,9 +116,9 @@ Maybe __ReadString(DeserializeSharedData* shared){
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
} }
else { else {
char* str=StringBuilder_build(b); StringFragment str=StringBuilder_build(b);
Autoarr_clear(b); Autoarr_clear(b);
return SUCCESS(UniPtr(CharPtr,str)); return SUCCESS(UniPtr(CharPtr,str.ptr));
} }
} }
else { else {
@ -127,46 +143,39 @@ Maybe __ReadList(DeserializeSharedData* shared){
}; };
#define ReadList() __ReadList(shared) #define ReadList() __ReadList(shared)
Maybe __ParseValue(DeserializeSharedData* shared, string str){ Maybe __ParseValue(DeserializeSharedData* shared, StringFragment str){
//printf("\e[94m<\e[96m%s\e[94m>\n",string_cpToCptr(str)); //printf("\e[94m<\e[96m%s\e[94m>\n",StringFragment_extract(str));
const string nullStr={"null",4}; const StringFragment trueStr= {"true" ,0,4};
const string trueStr={"true",4}; const StringFragment falseStr={"false",0,5};
const string falseStr={"false",5}; switch(str.ptr[str.length-1]){
switch(*str.ptr){ //Bool
case 'n': case 'e': {
if(string_compare(str,nullStr)) if(StringFragment_compare(str,trueStr))
return SUCCESS(UniNull);
else safethrow_wrongchar(*str.ptr);
break;
case 't':
if(string_compare(str,trueStr))
return SUCCESS(UniTrue); return SUCCESS(UniTrue);
else safethrow_wrongchar(*str.ptr); else if(StringFragment_compare(str,falseStr))
break;
case 'f':
if(string_compare(str,falseStr))
return SUCCESS(UniFalse); return SUCCESS(UniFalse);
else safethrow_wrongchar(*str.ptr); else safethrow_wrongchar(*str.ptr);
break; }
default: //Float64
switch(str.ptr[str.length-1]){
case 'f': { case 'f': {
char* _c=string_cpToCptr(str); char* _c=StringFragment_extract(str).ptr;
Unitype rez=Uni(Float64,strtod(_c,NULL)); Unitype rez=Uni(Float64,strtod(_c,NULL));
free(_c); free(_c);
return SUCCESS(rez); return SUCCESS(rez);
} }
//UInt64
case 'u': { case 'u': {
uint64 lu=0; uint64 lu=0;
char* _c=string_cpToCptr(str); char* _c=StringFragment_extract(str).ptr;
sscanf(_c,"%lu",&lu); sscanf(_c,"%lu",&lu);
free(_c); free(_c);
return SUCCESS(Uni(UInt64,lu)); return SUCCESS(Uni(UInt64,lu));
} }
//Int64
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
int64 li=0; int64 li=0;
char* _c=string_cpToCptr(str); char* _c=StringFragment_extract(str).ptr;
if(sscanf(_c,"%li",&li)!=1){ if(sscanf(_c,"%li",&li)!=1){
char err[64]; char err[64];
IFWIN( IFWIN(
@ -178,17 +187,18 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
free(_c); free(_c);
return SUCCESS(Uni(Int64,li)); return SUCCESS(Uni(Int64,li));
} }
//unknown type
default: default:
safethrow_wrongchar(str.ptr[str.length-1]); safethrow_wrongchar(str.ptr[str.length-1]);
} }
}
safethrow(ERR_ENDOFSTR); safethrow(ERR_ENDOFSTR);
}; };
#define ParseValue(str) __ParseValue(shared, str) #define ParseValue(str) __ParseValue(shared, str)
Maybe __ReadValue(DeserializeSharedData* shared){ Maybe __ReadValue(DeserializeSharedData* shared){
char c; char c;
string valueStr={text+1,0}; StringFragment valueStr={text+1,0};
Unitype value; Unitype value;
while ((c=*++text)) switch (c){ while ((c=*++text)) switch (c){
case ' ': case '\t': case ' ': case '\t':
@ -244,6 +254,7 @@ Maybe __ReadValue(DeserializeSharedData* shared){
Maybe __deserialize(char** _text, bool _calledRecursively) { Maybe __deserialize(char** _text, bool _calledRecursively) {
DeserializeSharedData _shared={ DeserializeSharedData _shared={
.sh_text_first=*_text,
.sh_text=*_text, .sh_text=*_text,
.sh_partOfDollarList=false, .sh_partOfDollarList=false,
.sh_readingList=false, .sh_readingList=false,

View File

@ -1,5 +1,5 @@
#include "DtsodV24.h" #include "DtsodV24.h"
#include "../Autoarr/StringBuilder.h" #include "../StringFragment/StringBuilder.h"
//65536 max length! //65536 max length!
#define STRB_BC 64 #define STRB_BC 64
@ -51,8 +51,7 @@ void __AppendValue(SerializeSharedData* shared, Unitype u){
StringBuilder_append_cptr(b, u.Bool ? "true" : "false"); StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
break; break;
case Null: case Null:
if(!u.VoidPtr) StringBuilder_append_cptr(b, "null"); throw("Null isn't supported in DtsodV24");
else throw("Null-type pointer is not 0");
break; break;
case AutoarrUnitypePtr: case AutoarrUnitypePtr:
addc('['); addc('[');
@ -97,7 +96,7 @@ void __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
char* DtsodV24_serialize(Hashtable* dtsod){ char* DtsodV24_serialize(Hashtable* dtsod){
StringBuilder sb=StringBuilder_create(STRB_BC,STRB_BL); StringBuilder sb=StringBuilder_create(STRB_BC,STRB_BL);
__serialize(&sb,0,dtsod); __serialize(&sb,0,dtsod);
char* str=StringBuilder_build(&sb); StringFragment str=StringBuilder_build(&sb);
Autoarr_clear((&sb)); Autoarr_clear((&sb));
return str; return str.ptr;
} }

View File

@ -14,11 +14,10 @@ void StringBuilder_append_cptr(StringBuilder* b, char* s){
Autoarr_add(b,c); Autoarr_add(b,c);
} }
void StringBuilder_append_string(StringBuilder* b, string s){ void StringBuilder_append_string(StringBuilder* b, StringFragment s){
while(s.length>0){ s.ptr+=s.offset;
while(s.length-->0)
Autoarr_add(b,*s.ptr++); Autoarr_add(b,*s.ptr++);
s.length--;
}
} }
void StringBuilder_append_int64(StringBuilder* b, int64 a){ 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; buf[i++]='0'+a%10;
a/=10; a/=10;
} }
string rev=string_reverse((string){buf,i}); StringFragment rev=StringFragment_reverse((StringFragment){buf,0,i});
StringBuilder_append_string(b,rev); StringBuilder_append_string(b,rev);
free(rev.ptr); free(rev.ptr);
} }
@ -52,8 +51,7 @@ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
buf[i++]='0'+a%10; buf[i++]='0'+a%10;
a/=10; a/=10;
} }
string rev=string_reverse((string){buf,i}); StringFragment rev=StringFragment_reverse((StringFragment){buf,0,i});
printf("\e[95mrev:%s\n",string_cpToCptr(rev));
StringBuilder_append_string(b,rev); StringBuilder_append_string(b,rev);
free(rev.ptr); free(rev.ptr);
} }
@ -67,11 +65,14 @@ void StringBuilder_append_double(StringBuilder* b, double a){
StringBuilder_append_cptr(b,buf); StringBuilder_append_cptr(b,buf);
} }
char* StringBuilder_build(StringBuilder* b){ StringFragment StringBuilder_build(StringBuilder* b){
uint32 len=Autoarr_length(b); StringFragment str={
char* str=malloc(len+1); .offset=0,
str[len]=0; .length=Autoarr_length(b)
for(uint32 i=0;i<len;i++) };
str[i]=Autoarr_get(b,i); str.ptr=malloc(str.length+1);
for(uint32 i=0; i<str.length; i++)
str.ptr[i]=Autoarr_get(b,i);
str.ptr[str.length]='\0';
return str; return str;
} }

View File

@ -0,0 +1,24 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../Autoarr/Autoarr.h"
#include "StringFragment.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, StringFragment 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);
//returns StringFragment with '\0' at the end
StringFragment StringBuilder_build(StringBuilder* b);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,42 @@
#include "StringFragment.h"
//copies <length> characters from <ptr+offset> 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; i<str.length; i++)
extr.ptr[i]=str.ptr[i];
extr.ptr[str.length]='\0';
return extr;
}
//compares two strings, NullPtr-friendly
bool StringFragment_compare(StringFragment str0, StringFragment str1){
if(str0.length!=str1.length) return false;
if(!str0.ptr) return str1.ptr ? false : true;
else if(!str1.ptr) return false;
str0.ptr+=str0.offset;
str1.ptr+=str1.offset;
while(str0.length-->0)
if(*str0.ptr++ != *str1.ptr++)
return false;
return true;
}
//creates new StringFragment which is reversed variant of <s>
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<s.length; i++)
r.ptr[i+s.offset]=s.ptr[s.length-i-1];
return r;
}

View File

@ -0,0 +1,29 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
//part of string
typedef struct StringFragment{
char* ptr; //may be without '\0' at the end
uint32 offset;
uint32 length;
} StringFragment;
static const StringFragment stringNull={NULL,0,0};
//copies <length> characters from <ptr+offset> 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 <s>
StringFragment StringFragment_reverse(StringFragment s);
#if __cplusplus
}
#endif

View File

@ -7,7 +7,7 @@ extern "C" {
#include "std.h" #include "std.h"
#include "types.h" #include "types.h"
#include "errors.h" #include "errors.h"
#include "mystr.h" #include "cptr.h"
// executes codeblock and prints execution time // executes codeblock and prints execution time
#ifdef CLOCK_REALTIME //non-standard high-precision clock #ifdef CLOCK_REALTIME //non-standard high-precision clock

36
base/cptr.c Normal file
View File

@ -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;
}

23
base/cptr.h Normal file
View File

@ -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

View File

@ -1,6 +1,6 @@
#include "std.h" #include "std.h"
#include "errors.h" #include "errors.h"
#include "mystr.h" #include "cptr.h"
char* errname(err_t err){ char* errname(err_t err){
switch(err){ switch(err){

View File

@ -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;i<str.length;i++)
str.ptr[i]=cptr[i];
return str;
}
//compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1){
if(str0.length!=str1.length) return false;
if(!str0.ptr) return str1.ptr ? false : true;
else if(!str1.ptr) return false;
while(str0.length-->0)
if(*str0.ptr++ != *str1.ptr++)
return false;
return true;
}
//creates new string which is reversed variant of <s>
string string_reverse(string s){
if(s.length==0) return s;
string r={malloc(s.length), s.length};
for(uint32 i=0; i<s.length; i++)
r.ptr[i]=s.ptr[s.length-i-1];
return r;
}

View File

@ -1,44 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "types.h"
//returns length of string (including \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);
//my fixed length string struct
//doesn't store '\0' at the end
typedef struct string{
char* ptr; //char pointer
uint32 length; //amount of chars in ptr value
} string;
static const string stringNull={NULL,0};
//copies str content to new char pointer value (adding '\0' at the end)
char* string_cpToCptr(string str);
//copies cptr content (excluding '\0' at the end) to new string
string string_cpFromCharPtr(char* cptr);
//compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1);
//creates new string which is reversed variant of <s>
string string_reverse(string s);
#if __cplusplus
}
#endif

View File

@ -13,7 +13,7 @@ void test_all(){
int main(){ int main(){
setlocale(LC_ALL, "en-US.Unicode"); setlocale(LC_ALL, "en-US.Unicode");
printf("\e[92mdtsod parser in c language!\e[97m\n"); 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"); printf("\e[0m\n");
return 0; return 0;
} }

View File

@ -1,16 +1,26 @@
#include "tests.h" #include "tests.h"
#include "../base/mystr.h" #include "../StringFragment/StringFragment.h"
void test_string(){ void test_string(){
optime(__func__,1,({ optime(__func__,1,({
printf("\e[96m-------------[test_string]-------------\n"); printf("\e[96m-------------[test_string]-------------\n");
char c[]="0123456789abcdef"; char c[]="0123456789abcdef";
string s=string_cpFromCharPtr(c);
printf("\e[92m\"%s\" \e[94m-> string_cpFromCharPtr()\n",c); StringFragment s={.ptr=cptr_copy(c),.offset=0,.length=cptr_length(c)};
if(s.length!=16) throw("string created with incorrect length"); printf("\e[92m\"%s\" \e[94m-> StringFragment\n",c);
char* p=string_cpToCptr(s); if(s.length!=16) throw("StringFragment created with incorrect length");
printf("\e[94mstring_cpToCptr() -> \e[92m\"%s\"\n",p);
free(p); 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(s.ptr);
free(extr.ptr);
})); }));
} }