From 75cde2390efe114893268da743ca86ac1fcd3571 Mon Sep 17 00:00:00 2001 From: M.Gergő Date: Fri, 22 May 2020 13:40:45 +0200 Subject: New functions: lciniGetStr(), lciniGETShort() --- README.md | 4 +- src/ini_read.c | 173 ++++++++++++++++++++++++++++++++--------------------- src/lightconfini.h | 11 ++-- src/main.c | 56 +++++++++++++---- tests/bom.ini | 8 ++- 5 files changed, 162 insertions(+), 90 deletions(-) diff --git a/README.md b/README.md index 7ec88f7..fbb4234 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,11 @@ 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. -Maximum line length can be 2^(32/2)^ characters. +Maximum line length can be 2^(32/2) characters. ## Future Plans -- Writing and Rewriting support for ini files. +- Writing and Rewriting ini files. - Writing support for comments. - Modifying one or more values/parameters/sections in ini files. diff --git a/src/ini_read.c b/src/ini_read.c index 817aa15..5650c41 100644 --- a/src/ini_read.c +++ b/src/ini_read.c @@ -34,7 +34,7 @@ static size_t strLcpy(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t sr *(tdst++) = *(tsrc++); /* dst[n] = src[n]; n++; */ } *tdst = '\0'; /* Applies from dstlen=n=1 */ - return tdst-dst+1; /* full buffer (incl. '\0') */ + return tdst-dst+1; /* all copied bytes, incl. '\0' */ } } @@ -57,7 +57,7 @@ static uint8_t *lciniStrResize(uint8_t *ptr, size_t oldsize, size_t newsize){ } else { /*strncpy(tmp, ptr, newsize);*/ /* c89 */ /*snprintf(tmp, newsize, "%s", ptr);*/ /* c99 */ - strLcpy(tmp, newsize, ptr, oldsize); + strLcpy(tmp, newsize, ptr, oldsize); /* c89, thread-safe */ free(ptr); return tmp; } @@ -175,7 +175,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int int32_t i,j, vallen=len; enum lcini_states pstate=Start, state=Start; - /*char cc; */ + /* char cc; */ if(data == NULL){ return NULL; } else { @@ -277,6 +277,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int data->comment[j] = in[i]; } pstate = CommEndW; + data->commentLen = j+1; break; @@ -313,12 +314,13 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int j = -1; state = CommEndW; data->comment = lciniStrResize(data->comment, data->commentLen, len); - memset(data->comment, 0, len); + memset(data->comment, 0, len*sizeof(uint8_t)); data->commentStartPos = i; data->commentSign = in[i]; data->nodeState = lcini_CONTINUE; } else { state = Error; /* wrong character in line */ + data->sectionLen = j+1; i--; } pstate = SectEndD; @@ -338,6 +340,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int data->paramLen = j + 1; } else { state = Error; + data->paramLen = j+1; i--; } pstate = EqW1; @@ -434,6 +437,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int i--; } else { state = Error; + data->valueLen = j+1; i--; } pstate = ValW; @@ -515,6 +519,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int i--; } else if( pstate != Bslsh && (in[i] == '\r' || in[i] == '\n' || in[i] == '\0')){ /* Too early Line_end */ state = Error; + data->valueLen = j+1; i--; } else { data->value[j] = in[i]; @@ -583,7 +588,7 @@ static struct lcini_data *iniFSM(struct lcini_data *data, const uint8_t *in, int lcini_data *lciniCreateNode( lcini_data *head, int lineLen ){ /* Creates one Node */ lcini_data *curr; - curr = (lcini_data *) calloc(1, sizeof(lcini_data)); + curr = (lcini_data *) malloc(1*sizeof(lcini_data)); curr->nodeState = lcini_EMPTY; curr->lineNum = 0; curr->lineLen = lineLen; @@ -614,7 +619,29 @@ lcini_data *lciniCreateNode( lcini_data *head, int lineLen ){ /* Creates one Nod head->next = curr; } return curr; -} +} + + +lcini_shortret *lciniMKShortRet(int bufflen){ + lcini_shortret *dt=NULL; + + dt = (lcini_shortret *) malloc(1*sizeof(lcini_shortret)); + if(dt){ + dt->ret = (char *) calloc(bufflen, sizeof(char)); + dt->retlen = bufflen; + dt->retType = lcini_shortretEMPTY; + } + return dt; +} + + +void lciniDestroyShortRet(lcini_shortret *dt){ + if(dt){ + free(dt->ret); + } + free(dt); +} + lcini_data *lciniDestroyNodes( lcini_data *head){ /* Destroys Nodes from HEAD to the end */ lcini_data *tmp, *node=head; @@ -632,25 +659,24 @@ lcini_data *lciniDestroyNodes( lcini_data *head){ /* Destroys Nodes from HEAD to } - struct lcini_data *lciniReadOut(const char *filename){ /* Reads the entire file to a linked-list */ int c=0; uint8_t *buff; FILE *fp=NULL; int32_t linemax, line=0, pos=0; - /*char cc;*/ struct lcini_data *prev=NULL, *curr=NULL, *list=NULL; + /*char cc;*/ fp = fopen(filename, "rb"); - if(!fp ){ /* fp == NULL */ + if(!fp ){ list = lciniCreateNode(NULL, 256); list->errorMsg = lciniStrResize(list->errorMsg, list->errorMsgLen, 256); list->errorMsgLen = sprintf((char*)list->errorMsg, "File opening error. Errno: %d (%s)", errno, strerror(errno) ); list->nodeState = lcini_ERROR; } else { - linemax = lciniFileMaxLineLen(fp) +1; + linemax = lciniFileMaxLineLen(fp) +3; /* EOF => "\n\n\0" */ buff = (uint8_t*)malloc(linemax*sizeof(uint8_t)); memset(buff, 0, linemax*sizeof(uint8_t)); @@ -659,6 +685,7 @@ struct lcini_data *lciniReadOut(const char *filename){ /* Reads the entire /*cc = c;*/ /* debug */ if( c == '\n' || c == EOF){ + line++; buff[pos] = '\n'; @@ -670,8 +697,9 @@ struct lcini_data *lciniReadOut(const char *filename){ /* Reads the entire } if(prev && curr && prev != curr && prev->section ){ /* Copy SECTION string from previous node to current */ curr->section = lciniStrResize(curr->section, curr->sectionLen, prev->sectionLen); - memcpy(curr->section, prev->section, prev->sectionLen); curr->sectionLen = prev->sectionLen; + strLcpy(curr->section, curr->sectionLen, prev->section, prev->sectionLen); + /* memcpy(curr->section, prev->section, prev->sectionLen); */ } if(curr){ /* Call the Finite-State-Machine processor */ curr->lineNum = line; @@ -698,6 +726,12 @@ struct lcini_data *lciniReadOut(const char *filename){ /* Reads the entire if(curr && curr->nodeState == lcini_ERROR){ /* Stop on first ERROR */ /* return list; */ } + if(c == EOF && curr && curr->nodeState == lcini_MULTILINE){ + curr->nodeState = lcini_ERROR; + curr->errorMsg = lciniStrResize(curr->errorMsg, curr->errorMsgLen, 43); + curr->errorMsgLen = 43; + sprintf((char*)curr->errorMsg, "File ended without double quotation mark!"); + } pos = 0; memset(buff, 0, linemax*sizeof(uint8_t)); } else { @@ -751,14 +785,21 @@ int lciniReadOutOwn(const char *filename){ /* Reads the entire file to a li curr->lineLen = pos + 1; iniFSM(curr, buff, linemax); } - if(curr->nodeState != lcini_EMPTY && mylciniReadOutFunct != NULL ){ /* Call with function ptr */ + if(c == EOF && curr && curr->nodeState == lcini_MULTILINE){ + curr->nodeState = lcini_ERROR; + curr->errorMsg = lciniStrResize(curr->errorMsg, curr->errorMsgLen, 43); + curr->errorMsgLen = 43; + sprintf((char*)curr->errorMsg, "File ended without double quotation mark!"); + } + if(curr->nodeState != lcini_EMPTY && curr->nodeState != lcini_MULTILINE && mylciniReadOutFunct != NULL ){ /* Call with function ptr */ (*mylciniReadOutFunct)(line, pos+1, (char*)curr->section, curr->sectionLen, (char*)curr->param, curr->paramLen, (char*)curr->value, curr->valueLen, (char*)curr->comment, curr->commentLen, (char*)curr->errorMsg, curr->errorMsgLen); } - curr->paramLen = 0; - curr->valueLen = 0; - curr->commentLen = 0; - curr->errorMsgLen = 0; - + if(curr->nodeState != lcini_MULTILINE){ + curr->paramLen = 0; + curr->valueLen = 0; + curr->commentLen = 0; + curr->errorMsgLen = 0; + } pos = 0; memset(buff, 0, linemax*sizeof(uint8_t)); } else { @@ -777,64 +818,58 @@ int lciniReadOutOwn(const char *filename){ /* Reads the entire file to a li } +lcini_data *lciniGet(lcini_data *head, const char *section, const char *parameter){ /* Retuires null-terminated string */ -/* -char *lciniGetFromFileStr(const char *filename, const char *section, const char *parameter, char *buff, int len){ - - int c=0; - uint8_t *buff=NULL; - char *value=NULL; - FILE *fp=NULL; - int64_t linemax, line=0, pos=0; - struct lcini_data *curr; - - fp = fopen(filename, "rb"); - - if(!fp){ - return NULL; - } else { - linemax = lciniFileMaxLineLen(fp) +1; - curr = lciniCreateNode(NULL,linemax); - buff = (uint8_t *) malloc(linemax*sizeof(uint8_t)); - memset(buff, 0, linemax*sizeof(uint8_t)); - value = malloc(1*sizeof(char)); - - while( c != EOF){ - c = fgetc(fp); + lcini_data *curr=head, *ret=NULL; + if( parameter != NULL){ - if( c == '\n' || c == EOF){ - line++; - buff[pos] = '\n'; + while(curr != NULL){ - if(curr){ - curr->lineNum = line; - curr->lineLen = pos + 1; - iniFSM(curr, buff, linemax); - } - if(curr->nodeState != lcini_EMPTY && value && section && param){ - if(strcmp(curr->section, section) == 0 && strcmp(curr->param, param) == 0){ - value = lciniStrResize(value, 1, curr->valueLen); - } + if((!section && !curr->section) || (section && curr->section && !strcmp(section, (char*)curr->section)) ){ + if(curr->param && !strcmp(parameter, (char*)curr->param) ){ + ret = curr; + /* break; */ /* for first hit */ } - curr->paramLen = 0; - curr->valueLen = 0; - curr->commentLen = 0; - curr->errorMsgLen = 0; - - pos = 0; - memset(buff, 0, linemax*sizeof(uint8_t)); - } else { - buff[pos] = c; - pos++; - } + } + curr = curr->next; } - lciniDestroyNodes(curr); - free(buff); } + return ret; +} - if(fp){ - fclose(fp); + +int lciniGetStr(lcini_data *head, const char *section, const char *parameter, char *dst, int dstlen){ /* Retuires null-terminated string */ + + int r=0; + lcini_data *curr=NULL; + + curr = lciniGet(head, section, parameter); + if(curr){ /* curr !== NULL */ + r = strLcpy((uint8_t*)dst, dstlen, curr->value, curr->valueLen); + if(curr->nodeState == lcini_ERROR){ + r = 0-r; + } } - return value; + return r; } -*/ \ No newline at end of file + +lcini_shortret *lciniGetShort(lcini_data *head, const char *section, const char *parameter){ /* Retuires null-terminated string */ + + lcini_shortret *dt=NULL; + lcini_data *curr=NULL; + + curr = lciniGet(head, section, parameter); + dt = lciniMKShortRet(1); + if(curr && dt){ /* curr !== NULL */ + if(curr->nodeState == lcini_ERROR){ + dt->ret = (char *) lciniStrResize((uint8_t *)dt->ret, dt->retlen, curr->errorMsgLen); + dt->retlen = strLcpy((uint8_t*)dt->ret, curr->errorMsgLen, curr->errorMsg, curr->errorMsgLen); + dt->retType = lcini_shortretERROR; + } else { + dt->ret = (char *) lciniStrResize((uint8_t *)dt->ret, dt->retlen, curr->valueLen); + dt->retlen = strLcpy((uint8_t*)dt->ret, curr->valueLen, curr->value, curr->valueLen); + dt->retType = lcini_shortretOK; + } + } + return dt; +} \ No newline at end of file diff --git a/src/lightconfini.h b/src/lightconfini.h index e2b4e2d..b2cdf03 100644 --- a/src/lightconfini.h +++ b/src/lightconfini.h @@ -29,8 +29,8 @@ typedef struct lcini_data { typedef struct lcini_shortret{ - uint8_t *ret; - int32_t retlen; + char *ret; + int retlen; enum retType{lcini_shortretOK, lcini_shortretERROR, lcini_shortretEMPTY} retType; } lcini_shortret; @@ -45,10 +45,10 @@ struct lcini_data *lciniReadOut(const char *filename); int lciniReadOutOwn(const char *filename); lcini_data *lciniGet(lcini_data *head, const char *section, const char *parameter); /* FETCH requested value TO an lcini_data object, FROM lcini_data list*/ -char *lciniGetStr(lcini_data *head, const char *section, const char *parameter, char *dst, int dstlen); /* FETCH requested value TO null-terminated-string, FROM lcini_data list */ +int lciniGetStr(lcini_data *head, const char *section, const char *parameter, char *dst, int dstlen); /* FETCH requested value TO null-terminated-string, FROM lcini_data list */ lcini_shortret *lciniGetShort(lcini_data *head, const char *section, const char *parameter); /* FETCH requested value TO shortret object, FROM lcini_data list*/ lcini_shortret *lciniGetFromFileShort(const char *filename, const char *section, const char *parameter); /* FETCH requested value TO shortret object FROM file */ -char *lciniGetFromFileStr(const char *filename, const char *section, const char *parameter, char *buff, int len); +int lciniGetFromFileStr(const char *filename, const char *section, const char *parameter, char *buff, int len); @@ -57,5 +57,8 @@ lcini_data *lciniDestroyNodes( lcini_data *head); lcini_data *lciniCreateNode( lcini_data *head, int lineLen ); size_t lciniFileMaxLineLen(FILE *tfd); +lcini_shortret *lciniMKShortRet(int bufflen); +void lciniDestroyShortRet(lcini_shortret *dt); + #endif /* LIGHTCONFINI_H_INCLUDED */ diff --git a/src/main.c b/src/main.c index 04c911a..71b4d3c 100644 --- a/src/main.c +++ b/src/main.c @@ -10,6 +10,7 @@ #define main_c +/* int lens=46, lenp=36, lenv=56, lenc=74, elen=65; */ int lens=16, lenp=16, lenv=16, lenc=24, elen=55; lcinimyReadFunc mylciniReadOutFunct=myfunct; /*lcinimyReadFunc mylciniReadOutFunct=NULL;*/ @@ -21,17 +22,18 @@ lcinimyReadFunc mylciniReadOutFunct=myfunct; void myfunct(int line, int linelen, char *section, int sectionlen, char *param, int paramlen, char *value, int valuelen, char *comment, int commentlen, char *error, int errorlen ){ - printf("LN: %d,\tLL: %d,\tSC: %*s,%2d P: %*s,%2d V: %*s,%2d C: %*s,%2d ER: %*s,%2d\n", line, linelen, lens, section,sectionlen, + printf("LN: %d,\tLL: %d, \tSC: %*s,%2d P: %*s,%2d V: %*s,%2d C: %*s,%2d ER: %*s,%2d\n", line, linelen, lens, section,sectionlen, lenp, param, paramlen, lenv, value, valuelen, lenc, comment, commentlen, elen, error, errorlen); } int main(int argc, char* argv[]){ - int len; - char filename[4096] = "tests/test.ini", *buff1, *buff2, *buff3, *buff4, *buff5; + int len,r; + char filename[4096] = "tests/test.ini", *buff1, *buff2, *buff3, *buff4, *buff5, *buff6; lcini_data *ini=NULL, *tmp=NULL; FILE *fp; + lcini_shortret *sret; if(argc > 1){ memset(filename, 0, 4096); @@ -49,13 +51,15 @@ int main(int argc, char* argv[]){ buff3 = calloc((len+100), sizeof(char)); buff4 = calloc((len+100), sizeof(char)); buff5 = calloc((elen+100),sizeof(char)); + buff6 = calloc(100, sizeof(char)); printf("\nLineMax: %d\n\n",len); + printf("FUNC: lciniReadOut() \n\n"); ini = lciniReadOut(filename); tmp = ini; - while(tmp != NULL){ + while(tmp != NULL){ /* snprintf(buff1, len+3, "'%s' %3ld",tmp->section, tmp->sectionLen); snprintf(buff2, len+3, "'%s' %3ld",tmp->param, tmp->paramLen); snprintf(buff3, len+3, "'%s' %3ld",tmp->value, tmp->valueLen); @@ -69,25 +73,51 @@ int main(int argc, char* argv[]){ sprintf(buff5, "'%s' %3d",tmp->errorMsg, tmp->errorMsgLen); - printf("LN: %d,\tLL: %d,\tSC: %*s,%2d P: %*s,%2d V: %*s,%2d C: %*s,%2d ER: %*s \n", tmp->lineNum, tmp->lineLen, lens, buff1,tmp->sectionStartPos, - lenp, buff2, tmp->paramStartPos, lenv, buff3, tmp->valueStartPos, lenc, buff4, tmp->commentStartPos, elen, buff5); + printf("LN: %d,\tLL: %d, \tSC: %*s,%2d P: %*s,%2d V: %*s,%2d C: %*s,%2d ER: %*s \n", tmp->lineNum, tmp->lineLen, lens, buff1,tmp->sectionStartPos, lenp, buff2, tmp->paramStartPos, lenv, buff3, tmp->valueStartPos, lenc, buff4, tmp->commentStartPos, elen, buff5); + /* myfunct(tmp->lineNum, tmp->lineLen, (char*)tmp->section, tmp->sectionLen, (char*)tmp->param, tmp->paramLen, (char*)tmp->value, tmp->valueLen, (char*)tmp->comment, tmp->commentLen, (char*)tmp->errorMsg, tmp->errorMsgLen); */ tmp=tmp->next; } - free(buff1); - free(buff2); - free(buff3); - free(buff4); - free(buff5); - lciniDestroyNodes( ini); + + + printf("\n\nFUNC: lciniReadOutOwn()\n\n"); + lciniReadOutOwn(filename); + printf("\n\n FUNC: lciniGet()\n\n"); + tmp = lciniGet(ini, "bom_section", "mmm"); + printf("X->0x%x\n", tmp); + if(tmp){ + printf("x->S: '%s', x->P: '%s', x->V: '%s', x->E: '%s'\n",tmp->section, tmp->param, tmp->value, tmp->errorMsg); + } + printf("\n\n FUNC: lciniGetStr()\n\n"); + r=lciniGetStr(ini, "bom_section", "mmm", buff6, 100); + printf("r: %d, R: '%s' \n",r,buff6); + - lciniReadOutOwn(filename); + printf("\n\n FUNC: lciniGetShort()\n\n"); + sret = lciniGetShort(ini, "bom_section", "key"); + printf("SR: '%s', %d, t: ",sret->ret,sret->retlen); + if(sret->retType == lcini_shortretEMPTY){ + printf("sret_empty\n"); + }else if(sret->retType == lcini_shortretERROR){ + printf("sret_err\n"); + } else { + printf("sret_ok\n"); + } + lciniDestroyShortRet(sret); + lciniDestroyNodes(ini); + free(buff1); + free(buff2); + free(buff3); + free(buff4); + free(buff5); + free(buff6); + printf("\n"); return 0; } diff --git a/tests/bom.ini b/tests/bom.ini index 2a403ad..04c028e 100644 --- a/tests/bom.ini +++ b/tests/bom.ini @@ -1,5 +1,9 @@ -[bom_section] ;OK +global1 = 12121 ;OK +[bom_section] ;OK bom_name=bom_value ;OK key “= value“ ;ER key="value" ;OK -10= 10 \ No newline at end of file +10= 10 +mmm="1234567890\ +123456789asdfgh\ +19205250410 \ \ No newline at end of file -- cgit v1.2.3