#include"config.h" #include #include #include #include /** @brief Here we check if the given string contains a section for example [SECTIONName] here delimiterLeft is [ and delimiterRight is ] if a section is found, the section name will be written to sectionName @brief Input: @param char **str: the string to check @param char delimiterLeft: the left delimiter to check for @param char delimiterRight: the right delimiter to check for @brief Output: @param char **sectionName: if found the section Name of the section @brief Return: @param int status_code: one of the following values: */ int checkSection(char *str,char delimiterLeft,char delimiterRight,char **sectionName) { char section[MAX_LEN_SECTIONNAME]; int i = 0; //most outer loop -> character of string if(str == NULL) { return ERROR_STR; } int len = strlen(str); int state = ST_INIT; int leftDelimiterPos=0; int rightDelimiterPos=0; char *sectionName2 = NULL; while(state != ST_FINISH) { switch(state) { case ST_INIT: for(i=0;i<=len;i++) //find first (left) delimiter { if(str[i] == delimiterLeft) { state = ST_FOUND_LEFT_DELIMITER; leftDelimiterPos = i; break; } } if(state != ST_FOUND_LEFT_DELIMITER) { return ST_ERROR_NOT_FOUND_LEFT_DELIMITER; } break; case ST_FOUND_LEFT_DELIMITER: for(i=0;i<=len;i++) //find second (right) delimiter { if(str[i] == delimiterRight) { state = ST_FOUND_RIGHT_DELIMITER; rightDelimiterPos = i; break; } } if(state != ST_FOUND_RIGHT_DELIMITER) { return ST_ERROR_NOT_FOUND_RIGHT_DELIMITER; } break; case ST_FOUND_RIGHT_DELIMITER: int ret=0; if((ret=getStrAtPos(str,leftDelimiterPos,rightDelimiterPos,sectionName,MAX_LEN_SECTIONNAME)) == NO_ERROR) { state = ST_FINISH; }else{ return ret; } case ST_FINISH: return FOUND_SECTION; } } return NO_SECTION; } /** @brief Here we get / cut from fromPos to toPos and write it to an address @brief Input: @param char *str: the string to cut @param int fromPos: from which position we want to copy, the pos is included and zero indexed @param int toPos: to which position we want to copy, the pos is included and zero indexed @brief Output: @param char **name: here we will write the section name to @brief Input: @param int sizeName: the size of the user allocated buffer at **name */ int getStrAtPos(char *str,int fromPos,int toPos,char **name,int sizeName) { if(*name == NULL) { int error = errno; printf("Pointer NULL:%d\n",error); return error; } int i=fromPos; //character iterator, which starts from specified pos int j=0; //the character iterator for the target string int diffLen=toPos-fromPos; char *ptr_name=*name; if(diffLen > MAX_LEN_SECTIONNAME || diffLen>sizeName) { return ERROR_MAX_LEN; } for(i=fromPos,j=0;i<=toPos;i++,j++) { ptr_name[j] = str[i]; } ptr_name[j+1]='\0'; return NO_ERROR; } /** Here we get a "pair" of data, parsed from *str, witch consists of a keyname and a keyvalue. These are written to the pointers at char **name and char **value. These pair can be in the form of: \n ex1: \n NAME=VALUE \n ____^_____^ \n ____|_____Here we have no delimiter this means rightDelimiterPos must be NULL \n ____This is the left delimiter \n ex2: \n name(value) \n ____^_____^ \n ____|_____This is the rightDelimiterPos and must be ')' \n ____This is leftDelimiterPos which must be '(' \n @brief Input: @param char *str: the line in the form of a string where a key value pair is stored @param char leftDelimiterPos: the left delimiter for example '=' @param char rightDelimiterPos: the right delimiter can be NULL in most cases, if NULL we assume that there is only one delimiter, which is in this case the leftDelimiterPos @brief Output: @param char **name: The address where we store the name of the Key @param char **value: The address where we store the key value @param int sizeName: for size checking against memory allocated at **name @param int sizeValue: for size checking against memory allocated at **value @brief Return: @return will return NO_ERROR (0) if successfull. If not it will return the error of the subroutine */ int getNameValuePair(char *str,char leftDelimiterPos,char rightDelimiterPos,char **name,char **value,int sizeName,int sizeValue) { if(*name == NULL || *value == NULL) { int error = errno; printf("Pointer NULL:%d\n",error); return error; } int state=ST_INIT; char *ptr_name=*name; char *ptr_value=*value; int ret=0; char *ptrDelimiter=NULL; int posDelimiter=0; int posEnd=0; ptrDelimiter=strchr(str,leftDelimiterPos); if(ptrDelimiter==NULL) { return ERROR_DELIMITER_NOT_FOUND; } posDelimiter = (ptrDelimiter - str); printf("LenUntilDelimiter: %d\n",posDelimiter); if((ret=getStrAtPos(str,0,posDelimiter-1,&ptr_name,sizeName)) == NO_ERROR) { printf("ptr_name:%s\n",ptr_name); }else { printf("Error at getStrAtPos:%d\n",ret); return ret; } if(rightDelimiterPos == 0) { posEnd = strlen(str); }else{ posEnd = rightDelimiterPos; } if((ret=getStrAtPos(str,posDelimiter+1,posEnd,&ptr_value,sizeValue)) == NO_ERROR) { printf("ptr_name:%s\n",ptr_value); }else { return ret; } return NO_ERROR; } /** Given a null terminated buffer of content(ex. from a file) an parse it with a default syntax of: Sections -> [SECTIONNAME] name / value -> name=value Input: char *originalBuffer: the buffer which holds the string for parsing. struct configEntry **entry: a user allocated buffer to which we write the parsed config data. int configSizeCount: the user allocated size of **entry. Output: int *returnedCount: to this variable the function writes the count of struct, which will be required to store all alavaible data. Note: The funtion returns the maximum allowed data structures, determined by configSizeCount. All data which exceeds will be dropped. To get the whole data we run the funtion a second time with the realloced configSizeCount in the size of [returnedCount] structures. */ int parseConfig(char *originalBuffer,struct configEntry **entry,int configSizeCount,int *returnedCount) { int state=ST_INIT; int ret=0; int i=0; *returnedCount=0; char *sectionName=NULL; struct configEntry *ptr_entry = *entry; char *keyName=NULL; char *keyValue=NULL; char *buffer=NULL; buffer = malloc(strlen(originalBuffer)+1); if(buffer == NULL) { int error = errno; printf("ERROR MALLOC:%d",error); return ERR_PARSECONFIG_UNKNOWN; } memset(buffer,0,strlen(originalBuffer)+1); strcpy(buffer,originalBuffer); //this step is necessary, because the strok function modifys the originalBuffer //so we make a copy of it strcpy(buffer,originalBuffer); printf("buffer:%s\n--",buffer); sectionName = malloc(MAX_LEN_SECTIONNAME); memset(sectionName,0,MAX_LEN_SECTIONNAME); //read buffer line by line char *token; token = strtok(buffer,"\n"); while(token != NULL && state != ST_FINISH) { switch(state) { case ST_INIT: if((ret=checkSection(token,'[',']',§ionName))==FOUND_SECTION) { state = ST_FOUND_SECTION; printf("FOUND_SECTION:%s\n",sectionName); } break; case ST_FOUND_SECTION: keyName = malloc(MAX_LEN_SECTIONNAME); keyValue = malloc(MAX_LEN_SECTIONNAME); if(keyName == NULL || keyValue == NULL) { int error = errno; printf("MALLOC:%d\n",error); return error; } memset(keyName,0,MAX_LEN_SECTIONNAME); memset(keyValue,0,MAX_LEN_SECTIONNAME); ret=getNameValuePair(token,'=',0,&keyName,&keyValue,MAX_LEN_SECTIONNAME,MAX_LEN_SECTIONNAME); if(ret==NO_ERROR) { printf("configSizeCount: %d, i:%d\n",configSizeCount,i); if(i