string struct
This commit is contained in:
parent
89cc9583af
commit
9f3cb51c2d
@ -17,7 +17,7 @@ clang: all
|
|||||||
CMPARGS= -Wall $(SRC) -o $(OUTFILE)
|
CMPARGS= -Wall $(SRC) -o $(OUTFILE)
|
||||||
build:
|
build:
|
||||||
@echo -e '\n\e[96m----------------[build]----------------\e[0m'
|
@echo -e '\n\e[96m----------------[build]----------------\e[0m'
|
||||||
$(CMP) -O1 -flto $(CMPARGS)
|
$(CMP) -O1 -flto -Wno-discarded-qualifiers $(CMPARGS)
|
||||||
build_dbg:
|
build_dbg:
|
||||||
@echo -e '\n\e[96m--------------[build_dbg]--------------\e[0m'
|
@echo -e '\n\e[96m--------------[build_dbg]--------------\e[0m'
|
||||||
$(CMP) -O0 -g $(CMPARGS).dbg
|
$(CMP) -O0 -g $(CMPARGS).dbg
|
||||||
|
|||||||
@ -6,78 +6,140 @@
|
|||||||
|
|
||||||
Hashtable* __parse(const char* text, bool called_recursively){
|
Hashtable* __parse(const char* text, bool called_recursively){
|
||||||
Hashtable* dict=Hashtable_create();
|
Hashtable* dict=Hashtable_create();
|
||||||
char c;
|
|
||||||
bool partOfDollarList=false;
|
bool partOfDollarList=false;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
void throw_wrongchar(char _c){
|
||||||
|
char errstr[]="unexpected <c>";
|
||||||
|
errstr[12]=_c;
|
||||||
|
throw(errstr);
|
||||||
|
};
|
||||||
|
|
||||||
void SkipComment(){
|
void SkipComment(){
|
||||||
while((c=*text++)!='\n')
|
while((c=*++text)!='\n')
|
||||||
if(!c) throw(ERR_ENDOFSTR);
|
if(!c) throw(ERR_ENDOFSTR);
|
||||||
};
|
};
|
||||||
|
|
||||||
char* ReadName(){
|
string ReadName(){
|
||||||
StringBuilder b=StringBuilder_create(4,32);
|
string nameStr={text,0};
|
||||||
while ((c=*text)){
|
while ((c=*++text)) switch (c){
|
||||||
switch (c){
|
case ' ': case '\t':
|
||||||
case ' ':
|
case '\r': case '\n':
|
||||||
case '\t':
|
|
||||||
case '\r':
|
|
||||||
case '\n':
|
|
||||||
break;
|
break;
|
||||||
case '#':
|
case '#':
|
||||||
SkipComment();
|
SkipComment();
|
||||||
break;
|
break;
|
||||||
|
case '}':
|
||||||
|
if(!called_recursively) throw_wrongchar(c);
|
||||||
case ':':
|
case ':':
|
||||||
return StringBuilder_build(&b);
|
return nameStr;
|
||||||
case '$':
|
case '$':
|
||||||
partOfDollarList=true;
|
partOfDollarList=true;
|
||||||
break;
|
break;
|
||||||
case '=': case ';':
|
case '=': case ';':
|
||||||
case '\'': case '"':
|
case '\'': case '"':
|
||||||
case '[': case ']':
|
case '[': case ']':
|
||||||
case '{': case '}':
|
case '{':
|
||||||
char errstr[]="unexpected <c>";
|
throw_wrongchar(c);
|
||||||
errstr[12]=c;
|
|
||||||
throw(errstr);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
StringBuilder_append(&b,c);
|
nameStr.length++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
text++;
|
|
||||||
}
|
if(nameStr.length>0) throw(ERR_ENDOFSTR);
|
||||||
if(Autoarr2_length((&b))>0) throw(ERR_ENDOFSTR);
|
return nameStr;
|
||||||
return NULL;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Unitype ReadValue(){
|
Unitype ReadValue(){
|
||||||
Unitype value=UniNull;
|
string valueStr={text,0};
|
||||||
|
bool endOfList=false;
|
||||||
|
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(){
|
||||||
|
|
||||||
return value;
|
throw(ERR_ENDOFSTR);
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
Hashtable* ReadDtsod(){
|
||||||
|
|
||||||
|
throw(ERR_ENDOFSTR);
|
||||||
|
return NULL;
|
||||||
|
};
|
||||||
|
Unitype ParseValue(string str){
|
||||||
|
|
||||||
|
throw(ERR_ENDOFSTR);
|
||||||
|
return UniNull;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
while ((c=*++text)) switch (c){
|
||||||
while((c=*text++)){
|
case ' ': case '\t':
|
||||||
char* name=ReadName();
|
case '\r': case '\n':
|
||||||
if(!name){
|
break;
|
||||||
free(name);
|
case '#':
|
||||||
return dict;
|
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 ']':
|
||||||
|
endOfList=true;
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
return UniPtr(HashtablePtr,ReadDtsod());
|
||||||
|
case '=': case ':':
|
||||||
|
case '}': case '$':
|
||||||
|
throw_wrongchar(c);
|
||||||
|
default:
|
||||||
|
valueStr.length++;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
throw(ERR_ENDOFSTR);
|
||||||
|
return UniNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
text--;
|
||||||
|
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_toCharPtr(name);
|
||||||
Unitype value=ReadValue();
|
Unitype value=ReadValue();
|
||||||
if(partOfDollarList){
|
if(partOfDollarList){
|
||||||
Autoarr2(Unitype)* list;
|
Autoarr2(Unitype)* list;
|
||||||
Unitype _lu;
|
Unitype lu;
|
||||||
if(Hashtable_try_get(dict,name, &_lu))
|
if(Hashtable_try_get(dict,nameCPtr, &lu))
|
||||||
list=(Autoarr2(Unitype)*)_lu.VoidPtr;
|
list=(Autoarr2(Unitype)*)lu.VoidPtr;
|
||||||
else{
|
else{
|
||||||
list=malloc(sizeof(Autoarr2(Unitype)));
|
list=malloc(sizeof(Autoarr2(Unitype)));
|
||||||
*list=Autoarr2_create(Unitype,ARR_BC,ARR_BL);
|
*list=Autoarr2_create(Unitype,ARR_BC,ARR_BL);
|
||||||
Hashtable_add(dict,name,UniF(AutoarrUnitypePtr,VoidPtr,list));
|
Hashtable_add(dict,nameCPtr,UniPtr(AutoarrUnitypePtr,list));
|
||||||
}
|
}
|
||||||
Autoarr2_add(list,value);
|
Autoarr2_add(list,value);
|
||||||
}
|
}
|
||||||
else Hashtable_add(dict,name,value);
|
else Hashtable_add(dict,nameCPtr,value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -36,3 +36,22 @@ char* mystrmtpl(char c, uint32 n){
|
|||||||
rez[--n]=c;
|
rez[--n]=c;
|
||||||
return rez;
|
return rez;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* string_toCharPtr(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];
|
||||||
|
return cptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
string string_fromCharPtr(char* cptr){
|
||||||
|
if(!cptr) return stringNull;
|
||||||
|
string str;
|
||||||
|
str.length=mystrlen(cptr);
|
||||||
|
str.ptr=malloc(str.length);
|
||||||
|
for(uint32 i=0;i>str.length;i++)
|
||||||
|
str.ptr[i]=cptr[i];
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|||||||
@ -13,3 +13,18 @@ bool mystrcmp(char* key0, char* key1);
|
|||||||
|
|
||||||
//multiplies char n times
|
//multiplies char n times
|
||||||
char* mystrmtpl(char c, uint32 n);
|
char* mystrmtpl(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_toCharPtr(string str);
|
||||||
|
|
||||||
|
//copies cptr content (excluding '\0' at the end) to new string
|
||||||
|
string string_fromCharPtr(char* cptr);
|
||||||
|
|||||||
@ -14,7 +14,7 @@ typedef enum my_type{
|
|||||||
Null, Float, Double, Char, Bool,
|
Null, Float, Double, Char, Bool,
|
||||||
UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
|
UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
|
||||||
UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
|
UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
|
||||||
UniversalType, STNodePtr,
|
UniversalType, STNodePtr, HashtablePtr,
|
||||||
AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
|
AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
|
||||||
AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
|
AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
|
||||||
AutoarrUnitypePtr, AutoarrKVPairPtr
|
AutoarrUnitypePtr, AutoarrKVPairPtr
|
||||||
@ -40,10 +40,12 @@ typedef struct Unitype{
|
|||||||
uint64 UInt64;
|
uint64 UInt64;
|
||||||
float Float;
|
float Float;
|
||||||
double Double;
|
double Double;
|
||||||
|
char Char;
|
||||||
|
bool Bool;
|
||||||
void* VoidPtr;
|
void* VoidPtr;
|
||||||
};
|
};
|
||||||
} Unitype;
|
} Unitype;
|
||||||
|
|
||||||
#define Uni(TYPE,VAL) (Unitype){.type=TYPE,.TYPE=VAL}
|
#define Uni(TYPE,VAL) (Unitype){.type=TYPE,.TYPE=VAL}
|
||||||
#define UniF(TYPE,FIELD,VAL) (Unitype){.type=TYPE,.FIELD=VAL}
|
#define UniPtr(TYPE,VAL) (Unitype){.type=TYPE,.VoidPtr=VAL}
|
||||||
#define UniNull (Unitype){Null,.VoidPtr=NULL}
|
#define UniNull (Unitype){Null,.VoidPtr=NULL}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user