--- /dev/null
+#include <stdio.h>
+#include <glob.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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);
+}