#include #include #include #include #include #include "config.h" #include "trace.h" static int parse_config_line(char *line, char **variable, char **value) { #define SKIP_UNTIL(_str, _cond) \ while (*_str && (_cond)) \ _str++; SKIP_UNTIL(line, isspace(*line)); /* Skip comments */ if (*line == '#') return -1; /* The actual variable name begins here */ *variable = line; /* Find where the variable name ends */ SKIP_UNTIL(line, !isspace(*line) && *line != '='); if (*line == '=') { *line = '\0'; line++; goto value_start; } /* If we encounter line end already, the line can't be valid */ if (!*line) return -1; /* Terminate the variable name */ *line = '\0'; line++; /* Find the equal sign */ SKIP_UNTIL(line, *line != '='); if (*line != '=') return -1; line++; SKIP_UNTIL(line, isspace(*line)); value_start: *value = line; SKIP_UNTIL(line, *line != '\n' && *line != '#'); *line = 0; return 0; } static int store_variable_value_to_plotter_config(const char *variable, const char *value, struct plotter_config *cfg) { #define TEST_STR_STORE_STR_RETURN(_cfg, _variable, _str, _value) \ if (!strcmp(_variable, #_str) && !cfg->_str) { \ cfg->_str = strdup(_value); \ return 0; \ } #define TEST_STR_STORE_INT_RETURN(_cfg, _variable, _str, _value) \ if (!strcmp(_variable, #_str)) { \ cfg->_str = atoi(_value); \ return 0; \ } TEST_STR_STORE_STR_RETURN(cfg, variable, charger_name, value); TEST_STR_STORE_STR_RETURN(cfg, variable, plotter_scripts_dir, value); TEST_STR_STORE_STR_RETURN(cfg, variable, images_output_dir, value); TEST_STR_STORE_STR_RETURN(cfg, variable, device_path, value); TEST_STR_STORE_STR_RETURN(cfg, variable, log_path, value); TEST_STR_STORE_INT_RETURN(cfg, variable, baudrate, value); return -1; } static int read_config_file(FILE *file, struct plotter_config *cfg) { char line[1024]; char *variable, *value; while (fgets(line, sizeof(line), file)) { if (parse_config_line(line, &variable, &value)) continue; if (!store_variable_value_to_plotter_config(variable, value, cfg)) continue; pr_debug("Discarding unsupported config variable %s\n", variable); } return 0; } int populate_config_data_from_file(const char *path, struct plotter_config *cfg) { glob_t globbuf; FILE *file; int ret; ret = glob(path, GLOB_TILDE, NULL, &globbuf); if (ret) return -1; if (globbuf.gl_pathc == 0) { pr_debug("No config file foud from path %s\n", path); return -1; } if (globbuf.gl_pathc > 1) { pr_warn("Found multiple config files from path %s, using the first one\n", path); } file = fopen(globbuf.gl_pathv[0], "r"); if (!file) { pr_err("Failed to open config file %s: %m\n", globbuf.gl_pathv[0]); return -1; } return read_config_file(file, cfg); }