diff --git a/src/parser.c b/src/parser.c index f11d48208c3720206aa9740746c60bd81fbfc15c..e97ad16b1ef5e33477091532edcdbf8fa3a187ba 100644 --- a/src/parser.c +++ b/src/parser.c @@ -34,6 +34,7 @@ /* Private functions. */ static int count_char(char *str, char val); static void parse_line(FILE *fp, struct swift_params *params); +static void parse_param(char *line, struct swift_params *params); /** * @brief Reads an input file and stores each parameter in a structure. @@ -43,21 +44,20 @@ static void parse_line(FILE *fp, struct swift_params *params); */ void parser_read_file(const char *file_name, struct swift_params *params) { - /* Open file for reading */ FILE *file = fopen(file_name, "r"); - + /* Initialise parameter count. */ params->count = 0; /* Check if parameter file exits. */ - if(file == NULL) { - error("Error opening parameter file: %s",file_name); + if (file == NULL) { + error("Error opening parameter file: %s", file_name); } - + /* Read until the end of the file is reached.*/ - while(!feof(file)) { - parse_line(file,params); + while (!feof(file)) { + parse_line(file, params); } fclose(file); @@ -71,7 +71,6 @@ void parser_read_file(const char *file_name, struct swift_params *params) { */ static int count_char(char *str, char val) { - int count = 0; /* Check if the line contains the character */ @@ -91,49 +90,77 @@ static int count_char(char *str, char val) { */ static void parse_line(FILE *fp, struct swift_params *params) { - - char line [PARSER_MAX_LINE_SIZE]; - char trim_line [PARSER_MAX_LINE_SIZE]; - char tmp_str [PARSER_MAX_LINE_SIZE]; - char param_name [PARSER_MAX_LINE_SIZE]; - static char section [PARSER_MAX_LINE_SIZE]; + char line[PARSER_MAX_LINE_SIZE]; + char trim_line[PARSER_MAX_LINE_SIZE]; /* Read a line of the file if it doesn't begin with a comment*/ - if(fgets(line,PARSER_MAX_LINE_SIZE,fp) != NULL && (*line != PARSER_COMMENT_CHAR) ) { - + if (fgets(line, PARSER_MAX_LINE_SIZE, fp) != NULL && + (*line != PARSER_COMMENT_CHAR)) { char *token; - /* Remove comments */ - token = strtok(line,PARSER_COMMENT_STRING); - strcpy(trim_line,token); - - /* Check if the line contains a value */ - if(strchr(trim_line,PARSER_VALUE_CHAR)) { - /* Check for more than one parameter on the same line. */ - if(count_char(trim_line,PARSER_VALUE_CHAR) > 1) { - error("Found more than one parameter in '%s', only one allowed.",line); - } - else { - /* Take first token as the parameter name and trim leading white space. */ - token = strtok(trim_line," :\t"); - strcpy(tmp_str,token); - - /* Take second token as the parameter value. */ - token = strtok(NULL, " #\n"); - - /* If second token is NULL then the line must be a section heading. */ - if(token == NULL) { - strcat(tmp_str,PARSER_VALUE_STRING); - strcpy(section,tmp_str); - } - else { - /* Prefix the parameter name with its section name and - * copy it into the parameter structure. */ - strcpy(param_name,section); - strcat(param_name,tmp_str); - strcpy(params->data[params->count].name,param_name); - strcpy(params->data[params->count++].value,token); - } - } + /* Remove comments at the end of a line. */ + token = strtok(line, PARSER_COMMENT_STRING); + strcpy(trim_line, token); + + /* Check if the line contains a value and parse it. */ + if (strchr(trim_line, PARSER_VALUE_CHAR)) { + parse_param(trim_line, params); + } + } +} + +/** + * @brief Performs error checking and stores a parameter in a structure. + * + * @param line Line containing the parameter + * @param params Structure to be written to + * + */ + +static void parse_param(char *line, struct swift_params *params) { + static char + section[PARSER_MAX_LINE_SIZE]; /* Keeps track of current section name. */ + char tmp_str[PARSER_MAX_LINE_SIZE]; + char param_name[PARSER_MAX_LINE_SIZE]; + char *token; + + /* Check for more than one parameter on the same line. */ + if (count_char(line, PARSER_VALUE_CHAR) > 1) { + error("Found more than one parameter in '%s', only one allowed.", line); + } + + /* Check that it is a parameter inside a section.*/ + if (*line == ' ' || *line == '\t') { + /* Take first token as the parameter name and trim leading white space. */ + token = strtok(line, " :\t"); + strcpy(tmp_str, token); + + /* Take second token as the parameter value. */ + token = strtok(NULL, " #\n"); + + /* Prefix the parameter name with its section name and + * copy it into the parameter structure. */ + strcpy(param_name, section); + strcat(param_name, tmp_str); + strcpy(params->data[params->count].name, param_name); + strcpy(params->data[params->count++].value, token); + + } else { /*Else it is the start of a new section or standalone parameter. */ + /* Take first token as the parameter name. */ + token = strtok(line, " :\t"); + strcpy(tmp_str, token); + + /* Take second token as the parameter value. */ + token = strtok(NULL, " #\n"); + + /* If second token is NULL then the line must be a section heading. */ + if (token == NULL) { + strcat(tmp_str, PARSER_VALUE_STRING); + strcpy(section, tmp_str); + } else { + /* Must be a standalone parameter so no need to prefix name with a + * section. */ + strcpy(params->data[params->count].name, tmp_str); + strcpy(params->data[params->count++].value, token); } } } @@ -147,15 +174,13 @@ static void parse_line(FILE *fp, struct swift_params *params) { * */ -void parser_get_param_int(struct swift_params *params, char * name, int * retParam) { - - char str [PARSER_MAX_LINE_SIZE]; +void parser_get_param_int(struct swift_params *params, char *name, + int *retParam) { + char str[PARSER_MAX_LINE_SIZE]; for (int i = 0; i < params->count; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { - /* Check that exactly one number is parsed. */ if (sscanf(params->data[i].value, "%d%s", retParam, str) != 1) { error( @@ -180,28 +205,26 @@ void parser_get_param_int(struct swift_params *params, char * name, int * retPar * */ -void parser_get_param_float(struct swift_params *params, char * name, float * retParam) { - - char str [PARSER_MAX_LINE_SIZE]; - - for(int i=0; i<params->count; i++) { +void parser_get_param_float(struct swift_params *params, char *name, + float *retParam) { + char str[PARSER_MAX_LINE_SIZE]; + for (int i = 0; i < params->count; i++) { /*strcmp returns 0 if both strings are the same.*/ - if(!strcmp(name,params->data[i].name)) { - + if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ - if(sscanf(params->data[i].value,"%f%s",retParam,str) != 1) { + if (sscanf(params->data[i].value, "%f%s", retParam, str) != 1) { error( "Tried parsing float '%s' but found '%s' with illegal float " "characters '%s'.", - params->data[i].name, params->data[i].value,str); + params->data[i].name, params->data[i].value, str); } return; } } - message("Cannot find '%s' in the structure.",name); + message("Cannot find '%s' in the structure.", name); } /** @@ -213,25 +236,26 @@ void parser_get_param_float(struct swift_params *params, char * name, float * re * */ -void parser_get_param_double(struct swift_params *params, char * name, double * retParam) { - - char str [PARSER_MAX_LINE_SIZE]; - - for(int i=0; i<params->count; i++) { +void parser_get_param_double(struct swift_params *params, char *name, + double *retParam) { + char str[PARSER_MAX_LINE_SIZE]; + for (int i = 0; i < params->count; i++) { /*strcmp returns 0 if both strings are the same.*/ - if(!strcmp(name,params->data[i].name)) { - + if (!strcmp(name, params->data[i].name)) { /* Check that exactly one number is parsed. */ - if(sscanf(params->data[i].value,"%lf",retParam) != 1) { - error("Tried parsing double '%s' but found '%s' with illegal double characters '%s'.",params->data[i].name,params->data[i].value,str); + if (sscanf(params->data[i].value, "%lf", retParam) != 1) { + error( + "Tried parsing double '%s' but found '%s' with illegal double " + "characters '%s'.", + params->data[i].name, params->data[i].value, str); } - + return; } } - message("Cannot find '%s' in the structure.",name); + message("Cannot find '%s' in the structure.", name); } /** @@ -245,9 +269,7 @@ void parser_get_param_double(struct swift_params *params, char * name, double * void parser_get_param_string(struct swift_params *params, char *name, char *retParam) { - for (int i = 0; i < params->count; i++) { - /*strcmp returns 0 if both strings are the same.*/ if (!strcmp(name, params->data[i].name)) { strcpy(retParam, params->data[i].value); @@ -264,7 +286,6 @@ void parser_get_param_string(struct swift_params *params, char *name, */ void parser_print_params(struct swift_params *params) { - printf("\n--------------------------\n"); printf("| SWIFT Parameter File |\n"); printf("--------------------------\n"); @@ -275,50 +296,52 @@ void parser_print_params(struct swift_params *params) { } } -/** - * @brief Write the contents of the parameter structure to a file in YAML format. +/** + * @brief Write the contents of the parameter structure to a file in YAML + *format. * * @param params Structure that holds the parameters * @param file_name Name of file to be written * */ -void parser_write_params_to_file(struct swift_params *params, const char *file_name) { +void parser_write_params_to_file(struct swift_params *params, + const char *file_name) { + FILE *file = fopen(file_name, "w"); + char section[PARSER_MAX_LINE_SIZE]; + char param_name[PARSER_MAX_LINE_SIZE]; + char *token; - FILE *file = fopen(file_name, "w"); - char section [PARSER_MAX_LINE_SIZE]; - char param_name [PARSER_MAX_LINE_SIZE]; - char *token; + /* Start of file identifier in YAML. */ + fprintf(file, "%s\n", PARSER_START_OF_FILE); - /* Start of file identifier in YAML. */ - fprintf(file,"%s\n",PARSER_START_OF_FILE); - - for(int i=0; i<params->count; i++) { - - /* Check that the parameter name contains a section name. */ - if(strchr(params->data[i].name,PARSER_VALUE_CHAR)) { - /* Copy the parameter name into a temporary string and find the section name. */ - strcpy(param_name,params->data[i].name); - token = strtok(param_name,PARSER_VALUE_STRING); - - /* If a new section name is found print it to the file. */ - if(strcmp(token,section)) { - strcpy(section,token); - fprintf(file,"\n%s%c\n",section,PARSER_VALUE_CHAR); - } - - /* Remove white space from parameter name and write it to the file. */ - token = strtok(NULL, " #\n"); - - fprintf(file,"\t%s%c %s\n",token,PARSER_VALUE_CHAR,params->data[i].value); - } - else { - fprintf(file,"%s%c %s\n",params->data[i].name,PARSER_VALUE_CHAR,params->data[i].value); - } + for (int i = 0; i < params->count; i++) { + /* Check that the parameter name contains a section name. */ + if (strchr(params->data[i].name, PARSER_VALUE_CHAR)) { + /* Copy the parameter name into a temporary string and find the section + * name. */ + strcpy(param_name, params->data[i].name); + token = strtok(param_name, PARSER_VALUE_STRING); + + /* If a new section name is found print it to the file. */ + if (strcmp(token, section)) { + strcpy(section, token); + fprintf(file, "\n%s%c\n", section, PARSER_VALUE_CHAR); + } + + /* Remove white space from parameter name and write it to the file. */ + token = strtok(NULL, " #\n"); + + fprintf(file, "\t%s%c %s\n", token, PARSER_VALUE_CHAR, + params->data[i].value); + } else { + fprintf(file, "\n%s%c %s\n", params->data[i].name, PARSER_VALUE_CHAR, + params->data[i].value); } + } - /* End of file identifier in YAML. */ - fprintf(file,PARSER_END_OF_FILE); - - fclose(file); + /* End of file identifier in YAML. */ + fprintf(file, PARSER_END_OF_FILE); + + fclose(file); } diff --git a/src/parser.h b/src/parser.h index 8f4bcefbe9d1f143aba7fe6a5511e2c24c833cb2..acd2bf3adb375801b70589389177e6c5051feeff 100644 --- a/src/parser.h +++ b/src/parser.h @@ -44,7 +44,8 @@ struct swift_params { /* Public API. */ void parser_read_file(const char *file_name, struct swift_params *params); void parser_print_params(struct swift_params *params); -void parser_write_params_to_file(struct swift_params *params, const char *file_name); +void parser_write_params_to_file(struct swift_params *params, + const char *file_name); void parser_get_param_int(struct swift_params *params, char *name, int *retParam); void parser_get_param_float(struct swift_params *params, char *name,