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:
parent
bf534010cb
commit
3835b6e499
63
liberty.c
63
liberty.c
@ -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 *
|
||||||
|
Loading…
Reference in New Issue
Block a user