return pakfire_string_set(entry->value, value);
}
+static int pakfire_config_append(struct pakfire_config* config,
+ const char* section, const char* key, const char* value2) {
+ char* buffer = NULL;
+ int r;
+
+ // Fetch the current value
+ const char* value1 = pakfire_config_get(config, section, key, NULL);
+
+ // Short cut if value1 is empty
+ if (!value1 || !*value1)
+ return pakfire_config_set(config, section, key, value2);
+
+ // Join both values together
+ r = asprintf(&buffer, "%s\n%s", value1, value2);
+ if (r < 0)
+ return 1;
+
+ // Set the new value
+ r = pakfire_config_set(config, section, key, buffer);
+
+ if (buffer)
+ free(buffer);
+
+ return r;
+}
+
const char* pakfire_config_get(struct pakfire_config* config,
const char* section, const char* key, const char* _default) {
struct pakfire_config_entry* entry = pakfire_config_find(config, section, key);
return 0;
}
-static ssize_t strip(char* s) {
+static ssize_t lstrip(char* s) {
if (!s)
return 0;
while (isspace(s[0]))
memmove(s, s + 1, l--);
+ return l;
+}
+
+static ssize_t rstrip(char* s) {
+ if (!s)
+ return 0;
+
+ size_t l = strlen(s);
+
// Remove trailing space
while (isspace(s[l - 1]))
s[l-- - 1] = '\0';
return l;
}
+static ssize_t strip(char* s) {
+ ssize_t l = lstrip(s);
+
+ if (l)
+ l = rstrip(s);
+
+ return l;
+}
+
int pakfire_config_read(struct pakfire_config* config, FILE* f) {
char section[SECTION_MAX_LENGTH] = "";
+ char key[KEY_MAX_LENGTH] = "";
+ int r;
char* line = NULL;
size_t l = 0;
}
// Remove trailing space
- length = strip(line);
+ length = rstrip(line);
// Skip empty lines
if (*line == '\0')
if (line[0] == '[' && line[length - 1] == ']') {
line[length - 1] = '\0';
- int r = pakfire_string_set(section, line + 1);
+ // Clear the previous key
+ *key = '\0';
+
+ r = pakfire_string_set(section, line + 1);
if (r)
- return r;
+ goto ERROR;
continue;
}
+ // Check if this is a multiline value
+ if (isspace(*line)) {
+ // We cannot assign this value anywhere
+ if (!*key) {
+ errno = EINVAL;
+ r = 1;
+ goto ERROR;
+ }
+
+ // Strip any leading whitespace
+ lstrip(line);
+
+ // Append the value to the existing one
+ r = pakfire_config_append(config, section, key, line);
+ if (r)
+ goto ERROR;
+ }
+
// Handle any assignments
// Find the separator
strip(line);
strip(value);
- int r = pakfire_config_set(config, section, line, value);
+ // Update the key
+ pakfire_string_set(key, line);
+
+ // Store the value
+ r = pakfire_config_set(config, section, key, value);
if (r)
- return r;
+ goto ERROR;
}
+ERROR:
if (line)
free(line);
- return 0;
+ return r;
}
return r;
}
+static int test_parse_multiline(const struct test* t) {
+ int r = EXIT_FAILURE;
+
+ char* TEST_INPUT =
+ "key1 =\n"
+ " value1\n"
+ " value2\n"
+ "\n"
+ "key2 = value1\n";
+
+ FILE* f = fmemopen(TEST_INPUT, strlen(TEST_INPUT), "r");
+ ASSERT(f);
+
+ struct pakfire_config* config = NULL;
+
+ ASSERT_SUCCESS(pakfire_config_create(&config));
+ ASSERT_SUCCESS(pakfire_config_read(config, f));
+
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "", "key1", NULL), "value1\nvalue2");
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "", "key2", NULL), "value1");
+
+ // Everything passed
+ r = EXIT_SUCCESS;
+
+FAIL:
+ if (f)
+ fclose(f);
+ pakfire_config_unref(config);
+
+ return r;
+}
+
int main(int argc, const char* argv[]) {
testsuite_add_test(test_get_and_set);
testsuite_add_test(test_parse);
+ testsuite_add_test(test_parse_multiline);
return testsuite_run(argc, argv);
}