# #
#############################################################################*/
+#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <pakfire/config.h>
#include <pakfire/util.h>
+#define KEY_MAX_LENGTH 32
+#define VALUE_MAX_LENGTH 1024
+#define SECTION_MAX_LENGTH 32
+#define LINE_MAX_LENGTH 1024
+
struct pakfire_config_entry {
STAILQ_ENTRY(pakfire_config_entry) nodes;
// Section name
- char section[32];
+ char section[SECTION_MAX_LENGTH];
// Key & Value
- char key[32];
- char value[1024];
+ char key[KEY_MAX_LENGTH];
+ char value[VALUE_MAX_LENGTH];
};
struct pakfire_config {
// Otherwise return the default value
return _default;
}
+
+static ssize_t strip(char* s) {
+ if (!s)
+ return 0;
+
+ size_t l = strlen(s);
+
+ // Remove leading space
+ while (isspace(s[0]))
+ memmove(s, s + 1, l--);
+
+ // Remove trailing space
+ while (isspace(s[l - 1]))
+ s[l-- - 1] = '\0';
+
+ return l;
+}
+
+int pakfire_config_read(struct pakfire_config* config, FILE* f) {
+ char section[SECTION_MAX_LENGTH] = "";
+
+ char* line = NULL;
+ size_t l = 0;
+
+ while (!feof(f)) {
+ ssize_t length = getline(&line, &l, f);
+ if (length < 0)
+ break;
+
+ // Break if there was an error
+ if (ferror(f))
+ break;
+
+ // Terminate line after comment sign
+ char* comment = strchr(line, '#');
+ if (comment) {
+ *comment = '\0';
+ length = comment - line;
+ }
+
+ // Remove trailing space
+ length = strip(line);
+
+ // Skip empty lines
+ if (*line == '\0')
+ continue;
+
+ // Is this a new section?
+ if (line[0] == '[' && line[length - 1] == ']') {
+ line[length - 1] = '\0';
+
+ int r = snprintf(section, sizeof(section) - 1, "%s", line + 1);
+ if (r == sizeof(section))
+ return ENOBUFS;
+
+ continue;
+ }
+
+ // Handle any assignments
+
+ // Find the separator
+ char* value = strchr(line, '=');
+ if (!value)
+ continue;
+
+ // Split the string
+ *value++ = '\0';
+
+ // Remove trailing space
+ strip(line);
+ strip(value);
+
+ int r = pakfire_config_set(config, section, line, value);
+ if (r)
+ return r;
+ }
+
+ if (line)
+ free(line);
+
+ return 0;
+}
return EXIT_SUCCESS;
}
+
+static int test_parse(const struct test* t) {
+ char* TEST_INPUT =
+ "key1 = value1\n"
+ "\n"
+ "# This is a comment\n"
+ "[section1]\n"
+ "key1 = value1\n"
+ "key2 = value2\n"
+ "[section2]\n"
+ "key1 = value1\n"
+ "key2 = value2\n";
+
+ FILE* f = fmemopen(TEST_INPUT, strlen(TEST_INPUT), "r");
+ ASSERT(f);
+
+ struct pakfire_config* config;
+
+ ASSERT_SUCCESS(pakfire_config_create(&config));
+ ASSERT_SUCCESS(pakfire_config_read(config, f));
+
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "", "key1", NULL), "value1");
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "section1", "key1", NULL), "value1");
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "section1", "key2", NULL), "value2");
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "section2", "key1", NULL), "value1");
+ ASSERT_STRING_EQUALS(pakfire_config_get(config, "section2", "key2", NULL), "value2");
+
+ pakfire_config_free(config);
+
+ fclose(f);
+
+ return EXIT_SUCCESS;
+}
+
int main(int argc, char** argv) {
testsuite_add_test(test_get_and_set);
+ testsuite_add_test(test_parse);
return testsuite_run();
}