]> git.ipfire.org Git - pakfire.git/commitdiff
transaction: Refactor code to dump a transaction
authorMichael Tremer <michael.tremer@ipfire.org>
Mon, 18 Sep 2023 18:53:56 +0000 (18:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Mon, 18 Sep 2023 18:53:56 +0000 (18:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/transaction.c

index 244529a8e41966e171bf404957d484f7c0d1a9ce..ab64307a7e8ae4675475ec452a99acc1f0f65f13 100644 (file)
@@ -334,63 +334,42 @@ static ssize_t pakfire_transaction_downloadsize(struct pakfire_transaction* tran
        return size;
 }
 
-static void pakfire_transaction_append_line(char*** lines, const char* format, ...) {
-       if (!lines)
-               return;
-
-       char* buffer = NULL;
+static int pakfire_transaction_append_line(char** s, const char* format, ...) {
        va_list args;
        int r;
 
        va_start(args, format);
-       r = vasprintf(&buffer, format, args);
+       r = vasprintf(s, format, args);
        va_end(args);
 
-       if (r < 0)
-               return;
-
-       // Count lines
-       unsigned int count = 0;
-       if (*lines) {
-               for (char** l = *lines; *l; l++)
-                       count++;
-       }
-
-       // Increase size of array
-       *lines = reallocarray(*lines, count + 2, sizeof(**lines));
-       if (!*lines)
-               return;
-
-       // Append line and terminate lines
-       (*lines)[count] = buffer;
-       (*lines)[count + 1] = NULL;
+       return r;
 }
 
-static void pakfire_transaction_add_headline(char*** lines, size_t width, const char* headline) {
-       pakfire_transaction_append_line(lines, "%s\n", headline);
+static int pakfire_transaction_add_headline(char** s, size_t width, const char* headline) {
+       return asprintf(s, "%s%s\n", *s, headline);
 }
 
-static void pakfire_transaction_add_newline(char*** lines, size_t width) {
-       pakfire_transaction_append_line(lines, "\n");
+static int pakfire_transaction_add_newline(char** s, size_t width) {
+       return asprintf(s, "%s\n", *s);
 }
 
-static void pakfire_transaction_add_line(char*** lines, size_t width, const char* name,
+static int pakfire_transaction_add_line(char** s, size_t width, const char* name,
                const char* arch, const char* version, const char* repo, const char* size) {
-       pakfire_transaction_append_line(lines, " %-21s %-8s %-21s %-18s %6s \n",
-               name, arch, version, repo, size);
+       return asprintf(s, "%s %-21s %-8s %-21s %-18s %6s \n", *s, name, arch, version, repo, size);
 }
 
-static void pakfire_transaction_add_package(char*** lines, size_t width, struct pakfire_package* pkg) {
+static int pakfire_transaction_add_package(char** s, size_t width, struct pakfire_package* pkg) {
        char size[128];
+       int r;
 
        struct pakfire_repo* repo = pakfire_package_get_repo(pkg);
 
        // Format size
-       int r = pakfire_format_size(size, pakfire_package_get_size(pkg));
+       r = pakfire_format_size(size, pakfire_package_get_size(pkg));
        if (r < 0)
-               return;
+               return r;
 
-       pakfire_transaction_add_line(lines, width,
+       r = pakfire_transaction_add_line(s, width,
                pakfire_package_get_string(pkg, PAKFIRE_PKG_NAME),
                pakfire_package_get_string(pkg, PAKFIRE_PKG_ARCH),
                pakfire_package_get_string(pkg, PAKFIRE_PKG_EVR),
@@ -399,93 +378,89 @@ static void pakfire_transaction_add_package(char*** lines, size_t width, struct
        );
 
        pakfire_repo_unref(repo);
+
+       return r;
 }
 
-static void pakfire_transaction_add_package_change(char*** lines, size_t width,
+static int pakfire_transaction_add_package_change(char** s, size_t width,
                struct pakfire_package* old_pkg, struct pakfire_package* new_pkg) {
+       int r;
+
        // Print the new package first
-       pakfire_transaction_add_package(lines, width, new_pkg);
+       r = pakfire_transaction_add_package(s, width, new_pkg);
+       if (r < 0)
+               return r;
 
-       pakfire_transaction_append_line(lines,
+       // Then show the change
+       r = pakfire_transaction_append_line(s,
                "   --> %s\n", pakfire_package_get_string(old_pkg, PAKFIRE_PKG_NEVRA));
+       if (r < 0)
+               return r;
+
+       return 0;
 }
 
-static void pakfire_transaction_add_separator(char*** lines, size_t width) {
+static int pakfire_transaction_add_separator(char** s, size_t width) {
        char* separator = alloca(width + 1);
 
        for (unsigned int i = 0; i < width; i++)
                separator[i] = '=';
        separator[width] = '\0';
 
-       pakfire_transaction_append_line(lines, "%s\n", separator);
+       return pakfire_transaction_append_line(s, "%s%s\n", *s, separator);
 }
 
-static void pakfire_transaction_add_usage_line(char*** lines, size_t width,
+static int pakfire_transaction_add_usage_line(char** s, size_t width,
                const char* headline, ssize_t size) {
        char buffer[128];
 
        int r = pakfire_format_size(buffer, size);
        if (r < 0)
-               return;
-
-       pakfire_transaction_append_line(lines,  "%-21s: %s\n", headline, buffer);
-}
-
-static char* pakfire_transaction_join_lines(char** lines) {
-       if (!lines)
-               return NULL;
-
-       size_t size = 0;
-
-       // Determine total length
-       for (char** line = lines; *line; line++)
-               size += strlen(*line);
-
-       // Allocate memory large enough to hold the result
-       char* s = calloc(1, size + 1);
-       if (!s)
-               return s;
-
-       char* p = s;
-
-       for (char** line = lines; *line; line++) {
-               p += snprintf(p, s - p - 1, "%s", *line);
-       }
+               return r;
 
-       return s;
+       return pakfire_transaction_append_line(s, "%s%-21s: %s\n", *s, headline, buffer);
 }
 
 PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t width) {
        char headline[1024];
+       char* s = "";
        int r;
 
+       Queue classes;
+       Queue pkgs;
+
+       queue_init(&classes);
+       queue_init(&pkgs);
+
        Pool* pool = transaction->transaction->pool;
        const int mode =
                SOLVER_TRANSACTION_SHOW_OBSOLETES |
                SOLVER_TRANSACTION_OBSOLETE_IS_UPGRADE;
 
-       char** lines = NULL;
-
        // Header
-       pakfire_transaction_add_separator(&lines, width);
-       pakfire_transaction_add_line(&lines, width,
+       r = pakfire_transaction_add_separator(&s, width);
+       if (r < 0)
+               goto ERROR;
+
+       // Show the headline
+       r = pakfire_transaction_add_line(&s, width,
                _("Package"),
                _("Arch"),
                _("Version"),
                _("Repository"),
                _("Size")
        );
-       pakfire_transaction_add_separator(&lines, width);
+       if (r < 0)
+               goto ERROR;
 
-       Queue classes;
-       queue_init(&classes);
+       // Add another separator
+       r = pakfire_transaction_add_separator(&s, width);
+       if (r < 0)
+               goto ERROR;
 
        // Get all classes
        transaction_classify(transaction->transaction, mode, &classes);
 
-       Queue pkgs;
-       queue_init(&pkgs);
-
        /*
                The classes queue now contains a list of all classes as a tuple of:
                        * The class type
@@ -502,63 +477,87 @@ PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transa
 
                switch (class) {
                        case SOLVER_TRANSACTION_INSTALL:
-                               if (count)
-                                       pakfire_string_format(headline, _("Installing %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Installing %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Installing one package:"));
+                                       r = pakfire_string_set(headline, _("Installing one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_REINSTALLED:
-                               if (count)
-                                       pakfire_string_format(headline, _("Reinstalling %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Reinstalling %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Reinstalling one package:"));
+                                       r = pakfire_string_set(headline, _("Reinstalling one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_ERASE:
-                               if (count)
-                                       pakfire_string_format(headline, _("Removing %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Removing %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Removing one package:"));
+                                       r = pakfire_string_set(headline, _("Removing one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_UPGRADED:
-                               if (count)
-                                       pakfire_string_format(headline, _("Updating %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Updating %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Updating one package:"));
+                                       r = pakfire_string_set(headline, _("Updating one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_DOWNGRADED:
-                               if (count)
-                                       pakfire_string_format(headline, _("Downgrading %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Downgrading %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Downgrading one package:"));
+                                       r = pakfire_string_set(headline, _("Downgrading one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_CHANGED:
-                               if (count)
-                                       pakfire_string_format(headline, _("Changing %u packages:"), count);
+                               if (count > 1)
+                                       r = pakfire_string_format(headline, _("Changing %u packages:"), count);
                                else
-                                       pakfire_string_set(headline, _("Changing one package:"));
+                                       r = pakfire_string_set(headline, _("Changing one package:"));
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_ARCHCHANGE:
-                               if (count)
-                                       pakfire_string_format(headline,
+                               if (count > 1)
+                                       r = pakfire_string_format(headline,
                                                _("%u architecture changes from '%s' to '%s':"), count, from, to);
                                else
-                                       pakfire_string_format(headline,
+                                       r = pakfire_string_format(headline,
                                                _("One architecture change from '%s' to '%s':"), from, to);
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_VENDORCHANGE:
                                if (count)
-                                       pakfire_string_format(headline,
+                                       r = pakfire_string_format(headline,
                                                _("%u vendor changes from '%s' to '%s':"), count, from, to);
                                else
-                                       pakfire_string_format(headline,
+                                       r = pakfire_string_format(headline,
                                                _("One vendor change from '%s' to '%s':"), from, to);
+
+                               if (r < 0)
+                                       goto ERROR;
                                break;
 
                        case SOLVER_TRANSACTION_IGNORE:
@@ -566,7 +565,9 @@ PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transa
                }
 
                // Show what we are doing
-               pakfire_transaction_add_headline(&lines, width, headline);
+               r = pakfire_transaction_add_headline(&s, width, headline);
+               if (r < 0)
+                       goto ERROR;
 
                // Fetch packages in this class
                transaction_classify_pkgs(transaction->transaction, mode, class,
@@ -590,11 +591,15 @@ PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transa
                                        if (r)
                                                continue;
 
-                                       pakfire_transaction_add_package_change(&lines, width, old_pkg, new_pkg);
+                                       r = pakfire_transaction_add_package_change(&s, width, old_pkg, new_pkg);
+                                       if (r < 0)
+                                               goto ERROR;
                                        break;
 
                                default:
-                                       pakfire_transaction_add_package(&lines, width, old_pkg);
+                                       r = pakfire_transaction_add_package(&s, width, old_pkg);
+                                       if (r < 0)
+                                               goto ERROR;
                                        break;
                        }
 
@@ -604,42 +609,46 @@ PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transa
                }
 
                // Newline
-               pakfire_transaction_add_newline(&lines, width);
+               r = pakfire_transaction_add_newline(&s, width);
+               if (r < 0)
+                       goto ERROR;
        }
 
-       queue_free(&classes);
-       queue_free(&pkgs);
-
        // Summary
-       pakfire_transaction_add_headline(&lines, width, _("Transaction Summary"));
-       pakfire_transaction_add_separator(&lines, width);
+       r = pakfire_transaction_add_headline(&s, width, _("Transaction Summary"));
+       if (r < 0)
+               goto ERROR;
+
+       r = pakfire_transaction_add_separator(&s, width);
+       if (r < 0)
+               goto ERROR;
 
        // How much do we need to download?
        size_t downloadsize = pakfire_transaction_downloadsize(transaction);
 
-       if (downloadsize > 0)
-               pakfire_transaction_add_usage_line(&lines, width,
+       if (downloadsize > 0) {
+               r = pakfire_transaction_add_usage_line(&s, width,
                        _("Total Download Size"), downloadsize);
+               if (r < 0)
+                       goto ERROR;
+       }
 
        // How much more space do we need?
        ssize_t sizechange = pakfire_transaction_installsizechange(transaction);
-       pakfire_transaction_add_usage_line(&lines, width,
-               (sizechange >= 0) ? _("Required Space") : _("Freed Space"), abs(sizechange));
 
-       // Join all lines together
-       char* string = pakfire_transaction_join_lines(lines);
+       r = pakfire_transaction_add_usage_line(&s, width,
+               (sizechange >= 0) ? _("Required Space") : _("Freed Space"), abs(sizechange));
+       if (r < 0)
+               goto ERROR;
 
-       if (string)
-               DEBUG(transaction->pakfire, "Transaction: %s\n", string);
+       if (s)
+               DEBUG(transaction->pakfire, "%s", s);
 
-       // Free lines
-       if (lines) {
-               for (char** line = lines; *line; line++)
-                       free(*line);
-               free(lines);
-       }
+ERROR:
+       queue_free(&classes);
+       queue_free(&pkgs);
 
-       return string;
+       return s;
 }
 
 static int pakfire_transaction_check_fileconflicts(