string -> StringFragment, throw_wrongchar() fixed
This commit is contained in:
parent
07c5a0ce69
commit
41f32f4f8c
@ -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
|
|
||||||
@ -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;
|
||||||
// writes 16 chars before and 15 after the wrongchar
|
for(uint8 i=0; i<32; i++){
|
||||||
errBuf[i+22]=*(text - 16 + i);
|
//writes 16 chars before and 15 after the wrongchar
|
||||||
safethrow(cptr_copy(errBuf));
|
char _c=errText[i];
|
||||||
|
errBuf[i]=_c;
|
||||||
|
if(!_c) break;
|
||||||
|
}
|
||||||
|
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)
|
#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,68 +143,62 @@ 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=StringFragment_extract(str).ptr;
|
||||||
char* _c=string_cpToCptr(str);
|
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));
|
||||||
}
|
}
|
||||||
case '0': case '1': case '2': case '3': case '4':
|
//Int64
|
||||||
case '5': case '6': case '7': case '8': case '9': {
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
int64 li=0;
|
case '5': case '6': case '7': case '8': case '9': {
|
||||||
char* _c=string_cpToCptr(str);
|
int64 li=0;
|
||||||
if(sscanf(_c,"%li",&li)!=1){
|
char* _c=StringFragment_extract(str).ptr;
|
||||||
char err[64];
|
if(sscanf(_c,"%li",&li)!=1){
|
||||||
IFWIN(
|
char err[64];
|
||||||
sprintf_s(err,64,"can't parse to int: <%s>",_c),
|
IFWIN(
|
||||||
sprintf(err,"can't parse to int: <%s>",_c)
|
sprintf_s(err,64,"can't parse to int: <%s>",_c),
|
||||||
);
|
sprintf(err,"can't parse to int: <%s>",_c)
|
||||||
safethrow(err);
|
);
|
||||||
}
|
safethrow(err);
|
||||||
free(_c);
|
|
||||||
return SUCCESS(Uni(Int64,li));
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
safethrow_wrongchar(str.ptr[str.length-1]);
|
|
||||||
}
|
}
|
||||||
|
free(_c);
|
||||||
|
return SUCCESS(Uni(Int64,li));
|
||||||
|
}
|
||||||
|
//unknown type
|
||||||
|
default:
|
||||||
|
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,
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
24
StringFragment/StringBuilder.h
Normal file
24
StringFragment/StringBuilder.h
Normal 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
|
||||||
42
StringFragment/StringFragment.c
Normal file
42
StringFragment/StringFragment.c
Normal 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;
|
||||||
|
}
|
||||||
29
StringFragment/StringFragment.h
Normal file
29
StringFragment/StringFragment.h
Normal 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
|
||||||
@ -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
36
base/cptr.c
Normal 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
23
base/cptr.h
Normal 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
|
||||||
@ -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){
|
||||||
|
|||||||
77
base/mystr.c
77
base/mystr.c
@ -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;
|
|
||||||
}
|
|
||||||
44
base/mystr.h
44
base/mystr.h
@ -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
|
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user