Improve simple_config_update_from_file()

- considerably shorter
 - catch file read errors as we should
 - better error messages, now including the filename
 - disallow empty keys as they are never used
 - allow whitespace before start of comment

NUL characters stop processing now, though.  If anyone cares.
This commit is contained in:
Přemysl Eric Janouch 2017-06-07 19:56:15 +02:00
parent bf534010cb
commit 3835b6e499
Signed by: p
GPG Key ID: B715679E3A361BE6

View File

@ -3495,14 +3495,10 @@ write_file_safe (const char *filename, const void *data, size_t data_len,
// --- Simple configuration ---------------------------------------------------- // --- Simple configuration ----------------------------------------------------
// The keys are stripped of surrounding whitespace, the values are not. // This is the bare minimum to make an application configurable.
// Keys are stripped of surrounding whitespace, values are not.
struct simple_config_item struct simple_config_item { const char *key, *default_value, *description; };
{
const char *key;
const char *default_value;
const char *description;
};
static void static void
simple_config_load_defaults simple_config_load_defaults
@ -3520,51 +3516,28 @@ simple_config_update_from_file (struct str_map *config, struct error **e)
{ {
char *filename = resolve_filename char *filename = resolve_filename
(PROGRAM_NAME ".conf", resolve_relative_config_filename); (PROGRAM_NAME ".conf", resolve_relative_config_filename);
if (!filename) struct str s = str_make ();
return true; bool ok = !filename || read_file (filename, &s, e);
size_t line_no = 0;
FILE *fp = fopen (filename, "r"); for (char *x = strtok (s.str, "\r\n"); ok && x; x = strtok (NULL, "\r\n"))
if (!fp)
{ {
error_set (e, "could not open `%s' for reading: %s", line_no++;
filename, strerror (errno)); if (strchr ("#", *(x += strspn (x, " \t"))))
free (filename);
return false;
}
struct str line = str_make ();
bool errors = false;
for (unsigned line_no = 1; read_line (fp, &line); line_no++)
{
char *start = line.str;
if (*start == '#')
continue; continue;
while (isspace (*start)) char *equals = strchr (x, '=');
start++; if (!equals || equals == x)
ok = error_set (e, "%s: malformed line %zu", filename, line_no);
char *end = strchr (start, '='); else
if (end)
{ {
char *value = end + 1; char *end = equals++;
do do *end = '\0'; while (strchr (" \t", *--end));
*end = '\0'; str_map_set (config, x, xstrdup (equals));
while (isspace (*--end));
str_map_set (config, start, xstrdup (value));
}
else if (*start)
{
error_set (e, "line %u in config: %s", line_no, "malformed input");
errors = true;
break;
} }
} }
str_free (&s);
str_free (&line);
fclose (fp);
free (filename); free (filename);
return !errors; return ok;
} }
static char * static char *