From: Michael Tremer Date: Mon, 18 Sep 2023 18:53:56 +0000 (+0000) Subject: transaction: Refactor code to dump a transaction X-Git-Tag: 0.9.30~1682 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a41f9069f195230c870ce63870d626035ff520a;p=pakfire.git transaction: Refactor code to dump a transaction Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index 244529a8e..ab64307a7 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -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(