Skip to content
Snippets Groups Projects

Add test for parser

Merged Loic Hausammann requested to merge increase_coverage into master
6 files
+ 219
216
Compare changes
  • Side-by-side
  • Inline
Files
6
+ 20
210
@@ -146,89 +146,6 @@ void parser_read_file(const char *file_name, struct csds_parser *params) {
fclose(file);
}
/**
* @brief Set or update a parameter using a compressed format.
*
* The compressed format allows a value to be given as a single
* string and has the format "section:parameter:value", with all
* names as would be given in the parameter file.
*
* @param params Structure that holds the parameters.
* @param namevalue the parameter name and value as described.
*/
void parser_set_param(struct csds_parser *params, const char *namevalue) {
/* Get the various parts. */
char name[PARSER_MAX_LINE_SIZE];
char value[PARSER_MAX_LINE_SIZE];
char section[PARSER_MAX_LINE_SIZE];
name[0] = '\0';
value[0] = '\0';
/* Name is part until second colon. */
const char *p1 = strchr(namevalue, ':');
if (p1 != NULL) {
/* Section is first part until a colon. */
memcpy(section, namevalue, p1 - namevalue);
section[p1 - namevalue] = ':';
section[p1 - namevalue + 1] = '\0';
const char *p2 = strchr(p1 + 1, ':');
if (p2 != NULL) {
memcpy(name, namevalue, p2 - namevalue);
name[p2 - namevalue] = '\0';
/* Value is rest after second colon. */
p2++;
strcpy(value, p2);
}
}
/* Sanity check. */
if (strlen(name) == 0 || strlen(value) == 0 || strchr(value, ':') != NULL)
error(
"Cannot parse compressed parameter string: '%s', check syntax "
"should be section:parameter:value",
namevalue);
/* And update or set. */
int updated = 0;
for (int i = 0; i < params->paramCount; i++) {
if (strcmp(name, params->data[i].name) == 0) {
message("Value of '%s' changed from '%s' to '%s'", params->data[i].name,
params->data[i].value, value);
strcpy(params->data[i].value, trim_both(value));
updated = 1;
}
}
if (!updated) {
/* Is this a new section? */
int newsection = 1;
for (int i = 0; i < params->sectionCount; i++) {
if (strcmp(section, params->section[i].name) == 0) {
newsection = 0;
break;
}
}
if (newsection) {
strcpy(params->section[params->sectionCount].name, section);
params->sectionCount++;
if (params->sectionCount == PARSER_MAX_NO_OF_SECTIONS)
error("Too many sections, current maximum is %d.",
params->sectionCount);
}
strcpy(params->data[params->paramCount].name, name);
strcpy(params->data[params->paramCount].value, value);
params->data[params->paramCount].used = 0;
params->data[params->paramCount].is_default = 0;
params->paramCount++;
if (params->paramCount == PARSER_MAX_NO_OF_PARAMS)
error("Too many parameters, current maximum is %d.", params->paramCount);
}
}
/**
* @brief Counts the number of white spaces that prefix a string.
*
@@ -350,7 +267,6 @@ static void parse_line(char *line, struct csds_parser *params) {
* @param params Structure to be written to
*
*/
static void parse_value(char *line, struct csds_parser *params) {
static int inSection = 0;
static char section[PARSER_MAX_LINE_SIZE]; /* Keeps track of current section
@@ -420,8 +336,6 @@ static void parse_value(char *line, struct csds_parser *params) {
* section. */
strcpy(params->data[params->paramCount].name, tmpStr);
strcpy(params->data[params->paramCount].value, token);
params->data[params->paramCount].used = 0;
params->data[params->paramCount].is_default = 0;
if (params->paramCount == PARSER_MAX_NO_OF_PARAMS - 1) {
error(
"Maximal number of parameters in parameter file reached. Aborting "
@@ -480,8 +394,6 @@ static void parse_section_param(char *line, int *isFirstParam,
strcpy(params->data[params->paramCount].name, paramName);
strcpy(params->data[params->paramCount].value, token);
params->data[params->paramCount].used = 0;
params->data[params->paramCount].is_default = 0;
if (params->paramCount == PARSER_MAX_NO_OF_PARAMS - 1) {
error("Maximal number of parameters in parameter file reached. Aborting !");
} else {
@@ -492,50 +404,26 @@ static void parse_section_param(char *line, int *isFirstParam,
// Retrieve parameter value from structure. TYPE is the data type, float, int
// etc. FMT the format required for that data type, i.e. %f, %d etc. and DESC
// a one word description of the type, "float", "int" etc.
#define PARSER_GET_VALUE(TYPE, FMT, DESC) \
static int get_param_##TYPE(struct csds_parser *params, const char *name, \
TYPE *def, TYPE *result) { \
char str[PARSER_MAX_LINE_SIZE]; \
for (int i = 0; i < params->paramCount; i++) { \
if (strcmp(name, params->data[i].name) == 0) { \
/* Check that exactly one number is parsed, capture junk. */ \
if (sscanf(params->data[i].value, " " FMT "%s ", result, str) != 1) { \
error("Tried parsing " DESC \
" '%s' but found '%s' with " \
"illegal trailing characters '%s'.", \
params->data[i].name, params->data[i].value, str); \
} \
/* Ensure same behavior if called multiple times for same parameter */ \
if (params->data[i].is_default && def == NULL) \
error( \
"Tried parsing %s again but cannot parse a default " \
"parameter as mandatory", \
name); \
if (params->data[i].is_default && *def != *result) \
error( \
"Tried parsing %s again but cannot parse a parameter with " \
"two different default value (" FMT "!=" FMT ")", \
name, *def, *result); \
/* This parameter has been used */ \
params->data[i].used = 1; \
return 1; \
} \
} \
if (def == NULL) \
error("Cannot find '%s' in the structure, in file '%s'.", name, \
params->fileName); \
return 0; \
}
// Set a parameter to a value and save for dumping.
#define PARSER_SAVE_VALUE(PREFIX, TYPE, FMT) \
static void save_param_##PREFIX(struct csds_parser *params, \
const char *name, TYPE value) { \
char str[PARSER_MAX_LINE_SIZE]; \
sprintf(str, "%s:" FMT, name, value); \
parser_set_param(params, str); \
params->data[params->paramCount - 1].used = 1; \
params->data[params->paramCount - 1].is_default = 0; \
#define PARSER_GET_VALUE(TYPE, FMT, DESC) \
static int get_param_##TYPE(struct csds_parser *params, const char *name, \
TYPE *def, TYPE *result) { \
char str[PARSER_MAX_LINE_SIZE]; \
for (int i = 0; i < params->paramCount; i++) { \
if (strcmp(name, params->data[i].name) == 0) { \
/* Check that exactly one number is parsed, capture junk. */ \
if (sscanf(params->data[i].value, " " FMT "%s ", result, str) != 1) { \
error("Tried parsing " DESC \
" '%s' but found '%s' with " \
"illegal trailing characters '%s'.", \
params->data[i].name, params->data[i].value, str); \
} \
return 1; \
} \
} \
if (def == NULL) \
error("Cannot find '%s' in the structure, in file '%s'.", name, \
params->fileName); \
return 0; \
}
/* Instantiations. */
@@ -544,12 +432,6 @@ PARSER_GET_VALUE(int, "%d", "int");
PARSER_GET_VALUE(float, "%f", "float");
PARSER_GET_VALUE(double, "%lf", "double");
PARSER_GET_VALUE(longlong, "%lld", "long long");
PARSER_SAVE_VALUE(char, char, "%c");
PARSER_SAVE_VALUE(int, int, "%d");
PARSER_SAVE_VALUE(float, float, "%g");
PARSER_SAVE_VALUE(double, double, "%g");
PARSER_SAVE_VALUE(longlong, longlong, "%lld");
PARSER_SAVE_VALUE(string, const char *, "%s");
/**
* @brief Retrieve integer parameter from structure.
@@ -629,14 +511,7 @@ void parser_get_param_string(struct csds_parser *params, const char *name,
for (int i = 0; i < params->paramCount; i++) {
if (!strcmp(name, params->data[i].name)) {
if (params->data[i].is_default)
error(
"Tried parsing %s again but cannot parse a "
"default parameter as mandatory",
name);
strcpy(retParam, params->data[i].value);
/* this parameter has been used */
params->data[i].used = 1;
return;
}
}
@@ -656,8 +531,6 @@ int parser_get_opt_param_int(struct csds_parser *params, const char *name,
int def) {
int result = 0;
if (get_param_int(params, name, &def, &result)) return result;
save_param_int(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
return def;
}
@@ -673,8 +546,6 @@ char parser_get_opt_param_char(struct csds_parser *params, const char *name,
char def) {
char result = 0;
if (get_param_char(params, name, &def, &result)) return result;
save_param_char(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
return def;
}
@@ -690,8 +561,6 @@ float parser_get_opt_param_float(struct csds_parser *params, const char *name,
float def) {
float result = 0;
if (get_param_float(params, name, &def, &result)) return result;
save_param_float(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
return def;
}
@@ -707,8 +576,6 @@ double parser_get_opt_param_double(struct csds_parser *params, const char *name,
double def) {
double result = 0;
if (get_param_double(params, name, &def, &result)) return result;
save_param_double(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
return def;
}
@@ -724,8 +591,6 @@ long long parser_get_opt_param_longlong(struct csds_parser *params,
const char *name, long long def) {
long long result = 0;
if (get_param_longlong(params, name, &def, &result)) return result;
save_param_longlong(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
return def;
}
@@ -743,20 +608,9 @@ void parser_get_opt_param_string(struct csds_parser *params, const char *name,
for (int i = 0; i < params->paramCount; i++) {
if (!strcmp(name, params->data[i].name)) {
strcpy(retParam, params->data[i].value);
/* Ensure same behavior if called multiple times for same parameter */
if (params->data[i].is_default && strcmp(def, retParam) != 0)
error(
"Tried parsing %s again but cannot parse a parameter with "
"two different default values ('%s' != '%s')",
name, def, retParam);
/* this parameter has been used */
params->data[i].used = 1;
return;
}
}
save_param_string(params, name, def);
params->data[params->paramCount - 1].is_default = 1;
strcpy(retParam, def);
}
@@ -775,11 +629,6 @@ void parser_get_opt_param_string(struct csds_parser *params, const char *name,
\
for (int i = 0; i < params->paramCount; i++) { \
if (!strcmp(name, params->data[i].name)) { \
if (params->data[i].is_default && required) \
error( \
"Tried parsing %s again but cannot parse a default " \
"parameter as mandatory", \
name); \
char *cp = cpy; \
strcpy(cp, params->data[i].value); \
cp = trim_both(cp); \
@@ -806,12 +655,6 @@ void parser_get_opt_param_string(struct csds_parser *params, const char *name,
"illegal " DESC " characters '%s'.", \
name, p, str); \
} \
if (params->data[i].is_default && tmp_value != values[k]) \
error( \
"Tried parsing %s again but cannot parse a " \
"parameter with two different default value " \
"(" FMT "!=" FMT ")", \
name, tmp_value, values[k]); \
values[k] = tmp_value; \
} else { \
error( \
@@ -821,7 +664,6 @@ void parser_get_opt_param_string(struct csds_parser *params, const char *name,
} \
if (k < nval - 1) p = strtok(NULL, ","); \
} \
params->data[i].used = 1; \
return 1; \
} \
} \
@@ -831,33 +673,12 @@ void parser_get_opt_param_string(struct csds_parser *params, const char *name,
return 0; \
}
// Set values of a default parameter so they will be saved correctly.
#define PARSER_SAVE_ARRAY(TYPE, FMT) \
static int save_param_##TYPE##_array( \
struct csds_parser *params, const char *name, int nval, TYPE *values) { \
/* Save values against the parameter. */ \
char str[PARSER_MAX_LINE_SIZE]; \
int k = sprintf(str, "%s: [", name); \
for (int i = 0; i < nval - 1; i++) \
k += sprintf(&str[k], FMT ", ", values[i]); \
sprintf(&str[k], FMT "]", values[nval - 1]); \
parser_set_param(params, str); \
params->data[params->paramCount - 1].used = 1; \
params->data[params->paramCount - 1].is_default = 0; \
return 0; \
}
/* Instantiations. */
PARSER_GET_ARRAY(char, "%c", "char");
PARSER_GET_ARRAY(int, "%d", "int");
PARSER_GET_ARRAY(float, "%f", "float");
PARSER_GET_ARRAY(double, "%lf", "double");
PARSER_GET_ARRAY(longlong, "%lld", "long long");
PARSER_SAVE_ARRAY(char, "%c");
PARSER_SAVE_ARRAY(int, "%d");
PARSER_SAVE_ARRAY(float, "%g");
PARSER_SAVE_ARRAY(double, "%g");
PARSER_SAVE_ARRAY(longlong, "%lld");
/**
* @brief Retrieve char array parameter from structure.
@@ -886,8 +707,6 @@ void parser_get_param_char_array(struct csds_parser *params, const char *name,
int parser_get_opt_param_char_array(struct csds_parser *params,
const char *name, int nval, char *values) {
if (get_param_char_array(params, name, 0, nval, values) != 1) {
save_param_char_array(params, name, nval, values);
params->data[params->paramCount - 1].is_default = 1;
return 0;
}
return 1;
@@ -920,8 +739,6 @@ void parser_get_param_int_array(struct csds_parser *params, const char *name,
int parser_get_opt_param_int_array(struct csds_parser *params, const char *name,
int nval, int *values) {
if (get_param_int_array(params, name, 0, nval, values) != 1) {
save_param_int_array(params, name, nval, values);
params->data[params->paramCount - 1].is_default = 1;
return 0;
}
return 1;
@@ -955,8 +772,6 @@ int parser_get_opt_param_float_array(struct csds_parser *params,
const char *name, int nval,
float *values) {
if (get_param_float_array(params, name, 0, nval, values) != 1) {
save_param_float_array(params, name, nval, values);
params->data[params->paramCount - 1].is_default = 1;
return 0;
}
return 1;
@@ -990,8 +805,6 @@ int parser_get_opt_param_double_array(struct csds_parser *params,
const char *name, int nval,
double *values) {
if (get_param_double_array(params, name, 0, nval, values) != 1) {
save_param_double_array(params, name, nval, values);
params->data[params->paramCount - 1].is_default = 1;
return 0;
}
return 1;
@@ -1026,8 +839,6 @@ int parser_get_opt_param_longlong_array(struct csds_parser *params,
const char *name, int nval,
long long *values) {
if (get_param_longlong_array(params, name, 0, nval, values) != 1) {
save_param_longlong_array(params, name, nval, values);
params->data[params->paramCount - 1].is_default = 1;
return 0;
}
return 1;
@@ -1046,6 +857,5 @@ void parser_print_params(const struct csds_parser *params) {
for (int i = 0; i < params->paramCount; i++) {
printf("Parameter name: %s\n", params->data[i].name);
printf("Parameter value: %s\n", params->data[i].value);
printf("Parameter used: %i\n", params->data[i].used);
}
}
Loading