From 8b42a04bf6df46fa06e2333a0b41b3c92e7ef4f1 Mon Sep 17 00:00:00 2001 From: M.Gergő Date: Fri, 8 May 2020 01:44:08 +0200 Subject: ASCII section --- README.md | 3 ++- src/ini_read.c | 33 +++++++++++++++++++++------------ src/ini_rw.h | 22 +++++++++++----------- src/main.c | 2 +- tests/test.ini | 42 +++++++++++++++++++++++++++++++++++++++--- tests/test0.ini | 29 +++++++++++++++++++++++++++++ 6 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 tests/test0.ini diff --git a/README.md b/README.md index cc51c09..be9ea9e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ **Multiline** values are supported if they are surrounded **with Double-Quotation-Mark (")** signs. Uses Finite State Machine technique for file processing. **Sections, Parameter names** can be **ASCII** alphabetical or numerical characters. -**Values** in alone also ASCII, or between Double-Quotation-Marks(") can be **any UNICODE/UTF8** characters. +**Values** in alone also ASCII, or between Double-Quotation-Marks(") can be **any UNICODE/UTF8** characters. +Maximum line length can be 2^64/2 = 2^63 characters. ## Future Plans diff --git a/src/ini_read.c b/src/ini_read.c index 214e445..d4d535d 100644 --- a/src/ini_read.c +++ b/src/ini_read.c @@ -74,7 +74,9 @@ char unescape(char c){ return '\t'; } else if(c == 'v'){ //Vertical tab return '\v'; - } else if(c == '\\'){ //Backslash + } else if(c == 'e'){ + return 0x1B; + /* } else if(c == '\\'){ //Backslash return '\\'; } else if(c == '\''){ //Apostrophe return '\''; @@ -82,6 +84,7 @@ char unescape(char c){ return '\"'; } else if(c == '?'){ //Question mark return '?'; + */ } else if(c < 0x20){ return '~'; } else { // jó az eredeti @@ -161,7 +164,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ if(data->nodeState == MULTILINE){ //Elküldjük gyűjteni state = DqmW; // Vagy ValW ?? j = data->valueLen-2; //(x-1) => \0; (x-2) => j--; - data->value = strResize(data->value, data->valueLen, data->valueLen+len); + data->value = strResize(data->value, data->valueLen, data->valueLen+len); // strResize(ptr, oldsize, newsize) i--; } else if(in[i] == '\n' || in[i] == '\r' || in[i] == '\0'){ //sorvége state = Stop; // Sorvége @@ -174,7 +177,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ data->comment = strResize(data->comment, data->commentLen, len); memset(data->comment, 0, len); data->commentStartPos = i; - data->sectionLen = 0; //Hogy pucoljon + data->sectionStartPos = -1; //Hogy pucoljon } else if(in[i] == '['){ //Szekció kezdődik j = -1; state = SectEndW; @@ -207,7 +210,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ data->comment = strResize(data->comment, data->commentLen, len); memset(data->comment, 0, len); data->commentStartPos = i; - data->sectionLen = 0; //Hogy pucoljon + data->sectionStartPos = -1; //Hogy pucoljon } else if(in[i] == '['){ //Szekció lesz j = -1; state = SectEndW; @@ -250,7 +253,10 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ state = SectEndD; data->section[j] = '\0'; data->sectionLen = j+1; - } else if(isalnum(in[i]) || in[i] == '/' || in[i] == ' '){ + if(j == 0){ //empty section + state = Error; + } + } else if(isalnum(in[i]) || in[i]=='/' || in[i]==' ' || in[i]=='_' || in[i]=='-' || in[i]=='.'){ data->section[j] = in[i]; } else /*if((in[i] >= 0x00 && in[i] < 0x20) || in[i] == ';' || in[i] == '#' )*/ { // túl korai sorvég, SP(), vagy komment state = Error; @@ -291,7 +297,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ state = ValPSP; data->param[j] = '\0'; data->paramLen = j + 1; - } else if(isalnum(in[i]) || in[i] == '[' || in[i] == ']'){ //A paraméter neve vagy tömb támogatása (Mint PHP-ben) + } else if(isalnum(in[i]) || in[i]=='[' || in[i]==']' || in[i]=='_' || in[i]=='-' || in[i]=='.'){ //A paraméter neve vagy tömb támogatása (Mint PHP-ben) data->param[j] = in[i]; } else if(isspace(in[i]) && in[i] != '\r' && in[i] != '\n'){ //Végén csak space lehet, egyenlő nélkül sorvég nem state = EqW2; @@ -377,7 +383,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ } else if( in[i] == '\\' ){ //Backslash jött //egymás után több backslash is lehet?? j--; //A '\' nem számít bele! state = Bslsh; - } else if( isalnum(in[i]) ){ //Normál betűk, space() csak idézőjelben jöhet! + } else if( isalnum(in[i]) || in[i]=='_' || in[i]=='-' || in[i]=='.' ){ //Normál betűk, space() csak idézőjelben jöhet! data->value[j] = in[i]; } else if(isspace(in[i])){ //Aposztróf nélüli space -> sorvég data->value[j] = '\0'; @@ -475,7 +481,7 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ memset(data->errorMsg, 0, 256) ; if(pstate == SectEndW || pstate == SectEndD){ - data->errorMsgLen = snprintf(data->errorMsg, 256, "Illegal character at SECTION! (line: %ld, pos: %ld)", data->lineNum, i+1); + data->errorMsgLen = snprintf(data->errorMsg, 256, "Illegal character or EMPTY SECTION! (line: %ld, pos: %ld)", data->lineNum, i+1); } else if(pstate == EqW1 || pstate == EqW2){ data->errorMsgLen = snprintf(data->errorMsg, 256, "Illegal character at PARAMETER! (line: %ld, pos: %ld)", data->lineNum, i+1); } else if(pstate == ValPSP || pstate == ValW || pstate == ValFSP ){ @@ -505,6 +511,9 @@ struct lci_data *iniFSM(struct lci_data *data, const char *in, int64_t len){ data->value = strResize(data->value, len, data->valueLen); data->comment = strResize(data->comment, len, data->commentLen); data->errorMsg = strResize(data->errorMsg, 256, data->errorMsgLen); + if(data->section==NULL && data->param==NULL && data->value==NULL && data->comment==NULL && data->errorMsg==NULL){ + data->nodeState = EMPTY; + } return data; } else { //minden más-> hiba state = Error; @@ -539,16 +548,16 @@ lci_data *createNode( lci_data *head, int64_t lineLen ){ memset(curr->section, 0, lineLen); curr->sectionLen = lineLen; - curr->sectionStartPos = 0; + curr->sectionStartPos = -1; memset(curr->param, 0, lineLen); curr->paramLen = lineLen; - curr->paramStartPos = 0; + curr->paramStartPos = -1; memset(curr->value, 0, lineLen); curr->valueLen = lineLen; - curr->valueStartPos = 0; + curr->valueStartPos = -1; memset(curr->comment, 0, lineLen); curr->commentLen = lineLen; - curr->commentStartPos = 0; + curr->commentStartPos = -1; memset(curr->errorMsg, 0, lineLen); curr->errorMsgLen=lineLen; curr->next = NULL; diff --git a/src/ini_rw.h b/src/ini_rw.h index 3e23e03..10b21d3 100644 --- a/src/ini_rw.h +++ b/src/ini_rw.h @@ -8,23 +8,23 @@ typedef struct lci_data { enum nodeState {EMPTY, READY, CONTINUE, MULTILINE, ERROR } nodeState; - uint64_t lineNum; - uint64_t lineLen; + int64_t lineNum; + int64_t lineLen; char *section; - uint64_t sectionLen; - uint64_t sectionStartPos; + int64_t sectionLen; + int64_t sectionStartPos; char *param; - uint64_t paramLen; - uint64_t paramStartPos; + int64_t paramLen; + int64_t paramStartPos; char *value; - uint64_t valueLen; - uint64_t valueStartPos; + int64_t valueLen; + int64_t valueStartPos; char *comment; - uint64_t commentLen; - uint64_t commentStartPos; + int64_t commentLen; + int64_t commentStartPos; char *errorMsg; - uint64_t errorMsgLen; + int64_t errorMsgLen; struct lci_data *next; } lci_data; diff --git a/src/main.c b/src/main.c index 728c6da..72f1718 100644 --- a/src/main.c +++ b/src/main.c @@ -12,7 +12,7 @@ int main() { - char filename[] = "tests/test.ini", *buff1, *buff2, *buff3, *buff4, *buff5; + char filename[] = "tests/test0.ini", *buff1, *buff2, *buff3, *buff4, *buff5; lci_data *ini=NULL, *tmp=NULL; int len=0, elen=50, lens=0, lenp=0, lenv=0, lenc=0; FILE *fp; diff --git a/tests/test.ini b/tests/test.ini index 5c218d0..46710f0 100644 --- a/tests/test.ini +++ b/tests/test.ini @@ -1,4 +1,30 @@ - [A BBCD] + + +# Comments can be '#' or ';' + +;Global variables are allowed +global1 = 11 +global2 = aaa + +; The First character of Section or Parameter name should be alphanumerical, +; another caharacters can ba Alphanumerical or dot(.)/underscore(_)/hyphen(-) +[Sections.are_ASCII-characters] + +; Parameter values, withourt double quotation mark (") +; ban be like Sections! +parameter_names.also-ASCII = first.value-like_ascii + +; For value characters, the Space, or any other special character allowed only between two double-quotation-mark sign. +; Escaped characters, (\n, \t, etc.) or multi-byte characters (é, €, カ, ⠋, ঘঃ, 😍) are allowed here. +parameter2 = "I like \t emojis 😍 but, don't like mosquitoes カ ! :)" + +; Even! +parameter3 = "With double quotation mark \ +I can write multiline values, but I shoud \ +escapse the trailing newline with '\' sign! +" + + [A B€BCD] ghijkl=val1 ; komment ghijkl = val2 ;kom1 ghijkl = val3;kom3 @@ -10,8 +36,10 @@ eee = fff= aa= #commt - ;#//sdfsdf// - +--- ;#//sdfsdf// +[é] +aaa=bbb +cc="=dd" [test2];#coment ggg = aaa #commnta ;ad = "123456\ @@ -19,3 +47,11 @@ ggg = aaa #commnta ;wqeweq \ ;aabcd=efgh " + ;fghfgh +#####; +;abcdefghijklmnopqrst +;;;; +### Test confi\ng +abc= + ;. + diff --git a/tests/test0.ini b/tests/test0.ini new file mode 100644 index 0000000..65dc41c --- /dev/null +++ b/tests/test0.ini @@ -0,0 +1,29 @@ + [A BBCD] + ad = "Withkdoublekque\ +alffsdasdabbbbbbbbbbbf\ +wqeweaaaaaaaaaaaa111aa\ +aabcd=efgh !" + +ppp = aaa +;parameter3 = "With double quotation mark \I can write multiline values, but I shoud \ escapse the trailing newline with '\' sign!" + +ghijkl=val1 ; komment +ghijkl = val2 ;kom1 +ghijkl = val3;kom3 + ghijkl=val14;kom14 + ghijkl = val15;kom15 + ghijkl = val4;kom11 + +eee = +fff= +aa= +#commt + ;#//sdfsdf// + + [test2];#coment +ggg = aaa #commnta +;ad = "123456\ +; aléásdasd #;--Ł$ +;wqeweq \ +;aabcd=efgh " + -- cgit v1.2.3