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;
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;
#include <fnmatch.h>
#include "efi-string.h"
+#include "fileio.h"
#include "tests.h"
TEST(strlen8) {
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;