]> git.ipfire.org Git - pakfire.git/commitdiff
config: Dump configuration files
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 11 Oct 2022 14:37:18 +0000 (14:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 11 Oct 2022 14:37:18 +0000 (14:37 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/config.c
src/libpakfire/include/pakfire/config.h
tests/libpakfire/config.c

index a3509a237e339ad3327105304f143b086befe48f..2697b48f38bd2e4463c4ecf353436fe52f39342d 100644 (file)
@@ -94,6 +94,15 @@ struct pakfire_config* pakfire_config_unref(struct pakfire_config* config) {
        return NULL;
 }
 
+static int pakfire_config_entry_is_multiline(const struct pakfire_config_entry* entry) {
+       const char* p = strchr(entry->value, '\n');
+
+       if (p)
+               return 1;
+
+       return 0;
+}
+
 static struct pakfire_config_entry* pakfire_config_create_entry(
                struct pakfire_config* config, const char* section, const char* key) {
        struct pakfire_config_entry* entry = calloc(1, sizeof(*entry));
@@ -451,3 +460,114 @@ ERROR:
 
        return r;
 }
+
+static int pakfire_config_dump_multiline_entry(struct pakfire_config_entry* entry, FILE* f) {
+       char* value = NULL;
+       char* p = NULL;
+       int r;
+
+       // Write the key line
+       r = fprintf(f, "%s =\n", entry->key);
+       if (r <= 0)
+               goto ERROR;
+
+       // Copy the value
+       value = strdup(entry->value);
+       if (!value) {
+               r = 1;
+               goto ERROR;
+       }
+
+       // Write it line by line
+       char* line = strtok_r(value, "\n", &p);
+       while (line) {
+               r = fprintf(f, "  %s\n", line);
+               if (r <= 0)
+                       goto ERROR;
+
+               line = strtok_r(NULL, "\n", &p);
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       if (value)
+               free(value);
+
+       return r;
+}
+
+static int pakfire_config_dump_entry(struct pakfire_config_entry* entry, FILE* f) {
+       int r;
+
+       // Handle multiline entries separately
+       if (pakfire_config_entry_is_multiline(entry))
+               return pakfire_config_dump_multiline_entry(entry, f);
+
+       // Write the entry
+       r = fprintf(f, "%s = %s\n", entry->key, entry->value);
+       if (r <= 0)
+               return r;
+
+       return 0;
+}
+
+static int pakfire_config_dump_section(struct pakfire_config* config,
+               const char* section, FILE* f) {
+       struct pakfire_config_entry* entry = NULL;
+       int r = 0;
+
+       // Print the section name
+       if (*section) {
+               r = fprintf(f, "\n[%s]\n", section);
+               if (r <= 0)
+                       goto ERROR;
+       }
+
+       // Iterate over all entries
+       STAILQ_FOREACH(entry, &config->entries, nodes) {
+               // Dump all entries that match this section
+               if (strcmp(entry->section, section) == 0) {
+                       r = pakfire_config_dump_entry(entry, f);
+                       if (r)
+                               goto ERROR;
+               }
+       }
+
+       // Success
+       r = 0;
+
+ERROR:
+       return r;
+}
+
+int pakfire_config_dump(struct pakfire_config* config, FILE* f) {
+       int r;
+
+       // Fetch a list of all available sections
+       char** sections = pakfire_config_sections(config);
+
+       // Dump the default section
+       r = pakfire_config_dump_section(config, "", f);
+       if (r)
+               goto ERROR;
+
+       // Dump all sections
+       if (sections) {
+               for (char** section = sections; *section; section++) {
+                       r = pakfire_config_dump_section(config, *section, f);
+                       if (r)
+                               goto ERROR;
+               }
+       }
+
+ERROR:
+       if (sections) {
+               for (char** section = sections; *section; section++)
+                       free(*section);
+               free(sections);
+       }
+
+       return r;
+}
index cad1b5e310d382cfe0b7e04ccc24647d64a3b0d7..5688c015b7e9289266dfde162eec85dc91e1c80a 100644 (file)
@@ -50,6 +50,8 @@ int pakfire_config_has_section(struct pakfire_config* config, const char* sectio
 
 int pakfire_config_read(struct pakfire_config* config, FILE* f);
 
+int pakfire_config_dump(struct pakfire_config* config, FILE* f);
+
 #endif
 
 #endif /* PAKFIRE_CONFIG_H */
index 8ac2571d9fb216d8812659ebf7140c6cfe2cdf82..946fd2ba9031eab9144c244ff69e95e0d4567b70 100644 (file)
@@ -64,6 +64,9 @@ static int test_get_and_set(const struct test* t) {
        ASSERT(pakfire_config_has_section(config, "section1"));
        ASSERT(!pakfire_config_has_section(config, "section3"));
 
+       // Dump the configuration file
+       ASSERT_SUCCESS(pakfire_config_dump(config, stdout));
+
        // Everything passed
        r = EXIT_SUCCESS;
 
@@ -99,6 +102,9 @@ static int test_parse(const struct test* t) {
        ASSERT_SUCCESS(pakfire_config_create(&config));
        ASSERT_SUCCESS(pakfire_config_read(config, f));
 
+       // Dump the configuration file
+       ASSERT_SUCCESS(pakfire_config_dump(config, stdout));
+
        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");
@@ -162,6 +168,9 @@ static int test_parse_multiline(const struct test* t) {
        ASSERT_SUCCESS(pakfire_config_create(&config));
        ASSERT_SUCCESS(pakfire_config_read(config, f));
 
+       // Dump the configuration file
+       ASSERT_SUCCESS(pakfire_config_dump(config, stdout));
+
        ASSERT_STRING_EQUALS(pakfire_config_get(config, "", "key1", NULL), "value1\nvalue2");
        ASSERT_STRING_EQUALS(pakfire_config_get(config, "", "key2", NULL), "value1");