X-Git-Url: http://git.itanic.dy.fi/?p=log-plotter;a=blobdiff_plain;f=config.c;fp=config.c;h=54f672e287d43ed74228fe62d1df251b755687b3;hp=0000000000000000000000000000000000000000;hb=84ab13170c021724847f80663c9136ec8badac57;hpb=d44a215cef8d81a7dbb0f52168f5cca2cfc31aed diff --git a/config.c b/config.c new file mode 100644 index 0000000..54f672e --- /dev/null +++ b/config.c @@ -0,0 +1,135 @@ +#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); +}