string struct
This commit is contained in:
parent
89cc9583af
commit
9f3cb51c2d
@ -17,7 +17,7 @@ clang: all
|
||||
CMPARGS= -Wall $(SRC) -o $(OUTFILE)
|
||||
build:
|
||||
@echo -e '\n\e[96m----------------[build]----------------\e[0m'
|
||||
$(CMP) -O1 -flto $(CMPARGS)
|
||||
$(CMP) -O1 -flto -Wno-discarded-qualifiers $(CMPARGS)
|
||||
build_dbg:
|
||||
@echo -e '\n\e[96m--------------[build_dbg]--------------\e[0m'
|
||||
$(CMP) -O0 -g $(CMPARGS).dbg
|
||||
|
||||
@ -6,78 +6,140 @@
|
||||
|
||||
Hashtable* __parse(const char* text, bool called_recursively){
|
||||
Hashtable* dict=Hashtable_create();
|
||||
char c;
|
||||
bool partOfDollarList=false;
|
||||
char c;
|
||||
|
||||
void throw_wrongchar(char _c){
|
||||
char errstr[]="unexpected <c>";
|
||||
errstr[12]=_c;
|
||||
throw(errstr);
|
||||
};
|
||||
|
||||
void SkipComment(){
|
||||
while((c=*text++)!='\n')
|
||||
while((c=*++text)!='\n')
|
||||
if(!c) throw(ERR_ENDOFSTR);
|
||||
};
|
||||
|
||||
char* ReadName(){
|
||||
StringBuilder b=StringBuilder_create(4,32);
|
||||
while ((c=*text)){
|
||||
switch (c){
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
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 StringBuilder_build(&b);
|
||||
return nameStr;
|
||||
case '$':
|
||||
partOfDollarList=true;
|
||||
break;
|
||||
case '=': case ';':
|
||||
case '\'': case '"':
|
||||
case '[': case ']':
|
||||
case '{': case '}':
|
||||
char errstr[]="unexpected <c>";
|
||||
errstr[12]=c;
|
||||
throw(errstr);
|
||||
break;
|
||||
case '{':
|
||||
throw_wrongchar(c);
|
||||
default:
|
||||
StringBuilder_append(&b,c);
|
||||
nameStr.length++;
|
||||
break;
|
||||
}
|
||||
text++;
|
||||
}
|
||||
if(Autoarr2_length((&b))>0) throw(ERR_ENDOFSTR);
|
||||
return NULL;
|
||||
|
||||
if(nameStr.length>0) throw(ERR_ENDOFSTR);
|
||||
return nameStr;
|
||||
};
|
||||
|
||||
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++)){
|
||||
char* name=ReadName();
|
||||
if(!name){
|
||||
free(name);
|
||||
return dict;
|
||||
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 ']':
|
||||
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();
|
||||
if(partOfDollarList){
|
||||
Autoarr2(Unitype)* list;
|
||||
Unitype _lu;
|
||||
if(Hashtable_try_get(dict,name, &_lu))
|
||||
list=(Autoarr2(Unitype)*)_lu.VoidPtr;
|
||||
else {
|
||||
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,name,UniF(AutoarrUnitypePtr,VoidPtr,list));
|
||||
Hashtable_add(dict,nameCPtr,UniPtr(AutoarrUnitypePtr,list));
|
||||
}
|
||||
Autoarr2_add(list,value);
|
||||
}
|
||||
else Hashtable_add(dict,name,value);
|
||||
else Hashtable_add(dict,nameCPtr,value);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
@ -36,3 +36,22 @@ char* mystrmtpl(char c, uint32 n){
|
||||
rez[--n]=c;
|
||||
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
|
||||
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,
|
||||
UInt8, Int8, UInt16, Int16, UInt32, Int32, UInt64, Int64,
|
||||
UInt8Ptr, Int8Ptr, UInt16Ptr, Int16Ptr, UInt32Ptr, Int32Ptr, UInt64Ptr, Int64Ptr,
|
||||
UniversalType, STNodePtr,
|
||||
UniversalType, STNodePtr, HashtablePtr,
|
||||
AutoarrInt8Ptr, AutoarrUInt8Ptr, AutoarrInt16Ptr, AutoarrUInt16Ptr,
|
||||
AutoarrInt32Ptr, AutoarrUInt32Ptr, AutoarrInt64Ptr, AutoarrUInt64Ptr,
|
||||
AutoarrUnitypePtr, AutoarrKVPairPtr
|
||||
@ -40,10 +40,12 @@ typedef struct Unitype{
|
||||
uint64 UInt64;
|
||||
float Float;
|
||||
double Double;
|
||||
char Char;
|
||||
bool Bool;
|
||||
void* VoidPtr;
|
||||
};
|
||||
} Unitype;
|
||||
|
||||
#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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user