aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorM.Gergő2020-05-22 13:40:45 +0200
committerM.Gergő2020-05-22 13:40:45 +0200
commit75cde2390efe114893268da743ca86ac1fcd3571 (patch)
treeb7ff8024ec81592388449b50ccd41a5669bb489a
parentee15e1da29eea49057ea3b87ac861e6a2f1fea96 (diff)
downloadlightconfini-75cde2390efe114893268da743ca86ac1fcd3571.tar.gz
lightconfini-75cde2390efe114893268da743ca86ac1fcd3571.zip
New functions: lciniGetStr(), lciniGETShort()
-rw-r--r--README.md4
-rw-r--r--src/ini_read.c173
-rw-r--r--src/lightconfini.h11
-rw-r--r--src/main.c56
-rw-r--r--tests/bom.ini8
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