config: handle trailing comments and empty values

This commit is contained in:
Daniel Eklöf 2020-07-28 19:55:09 +02:00
parent 7eee2d715d
commit f8d9bf18e5
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 33 additions and 16 deletions

View file

@ -23,6 +23,7 @@
* Crash when starting a selection inside the margins.
* Improved font size consistency across multiple monitors with
different DPI (https://codeberg.org/dnkl/foot/issues/47).
* Handle trailing comments in `footrc`
## 1.4.3

View file

@ -792,7 +792,7 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
break;
}
/* Strip whitespace */
/* Strip leading whitespace */
char *line = _line;
{
while (isspace(*line))
@ -809,11 +809,15 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
if (line[0] == '\0' || line[0] == '#')
continue;
/* Split up into key/value pair + trailing comment */
char *key_value = strtok(line, "#");
char *comment __attribute__((unused)) = strtok(NULL, "\n");
/* Check for new section */
if (line[0] == '[') {
char *end = strchr(line, ']');
if (key_value[0] == '[') {
char *end = strchr(key_value, ']');
if (end == NULL) {
LOG_ERR("%s:%d: syntax error: %s", path, lineno, line);
LOG_ERR("%s:%d: syntax error: %s", path, lineno, key_value);
goto err;
}
@ -821,13 +825,13 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
section = SECTION_COUNT;
for (enum section i = 0; i < SECTION_COUNT; i++) {
if (strcmp(&line[1], section_info[i].name) == 0) {
if (strcmp(&key_value[1], section_info[i].name) == 0) {
section = i;
}
}
if (section == SECTION_COUNT) {
LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &line[1]);
LOG_ERR("%s:%d: invalid section name: %s", path, lineno, &key_value[1]);
goto err;
}
@ -835,11 +839,20 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
continue;
}
char *key = strtok(line, "=");
char *key = strtok(key_value, "=");
if (key == NULL) {
LOG_ERR("%s:%d: syntax error: no key specified", path, lineno);
goto err;
}
char *value = strtok(NULL, "\n");
if (value == NULL) {
/* Empty value, i.e. "key=" */
value = key + strlen(key);
}
/* Strip trailing whitespace from key (leading stripped earlier) */
{
if (key[0] != '\0') {
assert(!isspace(*key));
char *end = key + strlen(key) - 1;
@ -850,25 +863,28 @@ parse_config_file(FILE *f, struct config *conf, const char *path)
if (value == NULL) {
if (key != NULL && strlen(key) > 0 && key[0] != '#') {
LOG_ERR("%s:%d: syntax error: %s", path, lineno, line);
LOG_ERR("%s:%d: syntax error: %s", path, lineno, key_value);
goto err;
}
continue;
}
/* Strip leading whitespace from value (trailing stripped earlier) */
/* Strip leading+trailing whitespace from value */
{
while (isspace(*value))
value++;
assert(!isspace(*(value + strlen(value) - 1)));
if (value[0] != '\0') {
char *end = value + strlen(value) - 1;
while (isspace(*end))
end--;
*(end + 1) = '\0';
}
}
if (key[0] == '#')
continue;
LOG_DBG("section=%s, key='%s', value='%s'",
section_names[section], key, value);
LOG_DBG("section=%s, key='%s', value='%s', comment='%s'",
section_info[section].name, key, value, comment);
parser_fun_t section_parser = section_info[section].fun;
assert(section_parser != NULL);