boot: Move line_get_key_value to efi-string

No functional changes.
This commit is contained in:
Jan Janssen
2023-10-15 10:09:55 +02:00
parent 539d000740
commit f17670a0c3
4 changed files with 128 additions and 74 deletions

View File

@@ -1166,80 +1166,6 @@ static BootEntry* boot_entry_free(BootEntry *entry) {
DEFINE_TRIVIAL_CLEANUP_FUNC(BootEntry *, boot_entry_free);
static char *line_get_key_value(
char *content,
const char *sep,
size_t *pos,
char **key_ret,
char **value_ret) {
char *line, *value;
size_t linelen;
assert(content);
assert(sep);
assert(pos);
assert(key_ret);
assert(value_ret);
for (;;) {
line = content + *pos;
if (*line == '\0')
return NULL;
linelen = 0;
while (line[linelen] && !strchr8("\n\r", line[linelen]))
linelen++;
/* move pos to next line */
*pos += linelen;
if (content[*pos])
(*pos)++;
/* empty line */
if (linelen == 0)
continue;
/* terminate line */
line[linelen] = '\0';
/* remove leading whitespace */
while (strchr8(" \t", *line)) {
line++;
linelen--;
}
/* remove trailing whitespace */
while (linelen > 0 && strchr8(" \t", line[linelen - 1]))
linelen--;
line[linelen] = '\0';
if (*line == '#')
continue;
/* split key/value */
value = line;
while (*value && !strchr8(sep, *value))
value++;
if (*value == '\0')
continue;
*value = '\0';
value++;
while (*value && strchr8(sep, *value))
value++;
/* unquote */
if (value[0] == '"' && line[linelen - 1] == '"') {
value++;
line[linelen - 1] = '\0';
}
*key_ret = line;
*value_ret = value;
return line;
}
}
static void config_defaults_load_from_file(Config *config, char *content) {
char *line;
size_t pos = 0;

View File

@@ -412,6 +412,74 @@ bool parse_boolean(const char *v, bool *ret) {
return false;
}
char *line_get_key_value(char *s, const char *sep, size_t *pos, char **ret_key, char **ret_value) {
char *line, *value;
size_t linelen;
assert(s);
assert(sep);
assert(pos);
assert(ret_key);
assert(ret_value);
for (;;) {
line = s + *pos;
if (*line == '\0')
return NULL;
linelen = 0;
while (line[linelen] && !strchr8("\n\r", line[linelen]))
linelen++;
/* move pos to next line */
*pos += linelen;
if (s[*pos])
(*pos)++;
/* empty line */
if (linelen == 0)
continue;
/* terminate line */
line[linelen] = '\0';
/* remove leading whitespace */
while (strchr8(" \t", *line)) {
line++;
linelen--;
}
/* remove trailing whitespace */
while (linelen > 0 && strchr8(" \t", line[linelen - 1]))
linelen--;
line[linelen] = '\0';
if (*line == '#')
continue;
/* split key/value */
value = line;
while (*value && !strchr8(sep, *value))
value++;
if (*value == '\0')
continue;
*value = '\0';
value++;
while (*value && strchr8(sep, *value))
value++;
/* unquote */
if (value[0] == '"' && line[linelen - 1] == '"') {
value++;
line[linelen - 1] = '\0';
}
*ret_key = line;
*ret_value = value;
return line;
}
}
char16_t *hexdump(const void *data, size_t size) {
static const char hex[16] = "0123456789abcdef";
const uint8_t *d = data;

View File

@@ -110,6 +110,8 @@ bool parse_number16(const char16_t *s, uint64_t *ret_u, const char16_t **ret_tai
bool parse_boolean(const char *v, bool *ret);
char *line_get_key_value(char *s, const char *sep, size_t *pos, char **ret_key, char **ret_value);
char16_t *hexdump(const void *data, size_t size);
#ifdef __clang__

View File

@@ -3,6 +3,7 @@
#include <fnmatch.h>
#include "efi-string.h"
#include "fileio.h"
#include "tests.h"
TEST(strlen8) {
@@ -504,6 +505,63 @@ TEST(parse_boolean) {
assert_se(parse_boolean("off", &b) && b == false);
}
TEST(line_get_key_value) {
char s1[] = "key=value\n"
" \t # comment line \n"
"k-e-y=\"quoted value\"\n\r"
" wrong= 'quotes' \n"
"odd= stripping # with comments ";
char s2[] = "this parser\n"
"\t\t\t# is\t\r"
" also\tused \r\n"
"for \"the conf\"\n"
"format\t !!";
size_t pos = 0;
char *key, *value;
assert_se(!line_get_key_value((char[]){ "" }, "=", &pos, &key, &value));
assert_se(line_get_key_value(s1, "=", &pos, &key, &value));
assert_se(streq8(key, "key"));
assert_se(streq8(value, "value"));
assert_se(line_get_key_value(s1, "=", &pos, &key, &value));
assert_se(streq8(key, "k-e-y"));
assert_se(streq8(value, "quoted value"));
assert_se(line_get_key_value(s1, "=", &pos, &key, &value));
assert_se(streq8(key, "wrong"));
assert_se(streq8(value, " 'quotes'"));
assert_se(line_get_key_value(s1, "=", &pos, &key, &value));
assert_se(streq8(key, "odd"));
assert_se(streq8(value, " stripping # with comments"));
assert_se(!line_get_key_value(s1, "=", &pos, &key, &value));
pos = 0;
assert_se(line_get_key_value(s2, " \t", &pos, &key, &value));
assert_se(streq8(key, "this"));
assert_se(streq8(value, "parser"));
assert_se(line_get_key_value(s2, " \t", &pos, &key, &value));
assert_se(streq8(key, "also"));
assert_se(streq8(value, "used"));
assert_se(line_get_key_value(s2, " \t", &pos, &key, &value));
assert_se(streq8(key, "for"));
assert_se(streq8(value, "the conf"));
assert_se(line_get_key_value(s2, " \t", &pos, &key, &value));
assert_se(streq8(key, "format"));
assert_se(streq8(value, "!!"));
assert_se(!line_get_key_value(s2, " \t", &pos, &key, &value));
/* Let's make sure we don't fail on real os-release data. */
_cleanup_free_ char *osrel = NULL;
if (read_full_file("/usr/lib/os-release", &osrel, NULL) >= 0) {
pos = 0;
while (line_get_key_value(osrel, "=", &pos, &key, &value)) {
assert_se(key);
assert_se(value);
printf("%s = %s\n", key, value);
}
}
}
TEST(hexdump) {
char16_t *hex;