return size;
}
-static void pakfire_transaction_add_headline(char** str, size_t width, const char* headline) {
- asprintf(str, "%s%s\n", strdup(*str), headline);
+static void pakfire_transaction_append_line(char*** lines, const char* format, ...) {
+ if (!lines)
+ return;
+
+ char* buffer = NULL;
+ va_list args;
+ int r;
+
+ va_start(args, format);
+ r = vasprintf(&buffer, 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;
}
-static void pakfire_transaction_add_newline(char** str, size_t width) {
- asprintf(str, "%s\n", strdupa(*str));
+static void pakfire_transaction_add_headline(char*** lines, size_t width, const char* headline) {
+ pakfire_transaction_append_line(lines, "%s\n", headline);
}
-static void pakfire_transaction_add_line(char** str, size_t width, const char* name,
+static void pakfire_transaction_add_newline(char*** lines, size_t width) {
+ pakfire_transaction_append_line(lines, "\n");
+}
+
+static void pakfire_transaction_add_line(char*** lines, size_t width, const char* name,
const char* arch, const char* version, const char* repo, const char* size) {
- // XXX need to adapt to size
- asprintf(str, "%s %-21s %-8s %-21s %-18s %6s \n", strdupa(*str),
+ pakfire_transaction_append_line(lines, " %-21s %-8s %-21s %-18s %6s \n",
name, arch, version, repo, size);
}
-static void pakfire_transaction_add_package(char** str, size_t width, PakfirePackage pkg) {
+static void pakfire_transaction_add_package(char*** lines, size_t width, PakfirePackage pkg) {
char size[128];
PakfireRepo repo = pakfire_package_get_repo(pkg);
// Format size
pakfire_format_size(size, sizeof(size) - 1, pakfire_package_get_size(pkg));
- pakfire_transaction_add_line(str, width,
+ pakfire_transaction_add_line(lines, width,
pakfire_package_get_name(pkg),
pakfire_package_get_arch(pkg),
pakfire_package_get_evr(pkg),
pakfire_repo_unref(repo);
}
-static void pakfire_transaction_add_package_change(char** str, size_t width,
+static void pakfire_transaction_add_package_change(char*** lines, size_t width,
PakfirePackage old_pkg, PakfirePackage new_pkg) {
// Print the new package first
- pakfire_transaction_add_package(str, width, new_pkg);
+ pakfire_transaction_add_package(lines, width, new_pkg);
- asprintf(str, "%s --> %s\n", strdupa(*str), pakfire_package_get_nevra(old_pkg));
+ pakfire_transaction_append_line(lines,
+ " --> %s\n", pakfire_package_get_nevra(old_pkg));
}
-static void pakfire_transaction_add_separator(char** str, size_t width) {
+static void pakfire_transaction_add_separator(char*** lines, size_t width) {
char* separator = alloca(width + 1);
- // Make separator of appropriate length
for (unsigned int i = 0; i < width; i++)
separator[i] = '=';
separator[width] = '\0';
- // newline
- asprintf(str, "%s%s\n", strdupa(*str), separator);
+ pakfire_transaction_append_line(lines, "%s\n", separator);
}
-static void pakfire_transaction_add_usage_line(char** str, size_t width, const char* headline, ssize_t size) {
+static void pakfire_transaction_add_usage_line(char*** lines, size_t width,
+ const char* headline, ssize_t size) {
char buffer[128];
pakfire_format_size(buffer, sizeof(buffer) - 1, size);
- asprintf(str, "%s%-21s: %s\n", strdupa(*str), headline, buffer);
+ 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 s;
}
PAKFIRE_EXPORT char* pakfire_transaction_dump(struct pakfire_transaction* transaction, size_t width) {
char headline[1024];
- char* string = strdup("");
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(&string, width);
- pakfire_transaction_add_line(&string, width,
+ pakfire_transaction_add_separator(&lines, width);
+ pakfire_transaction_add_line(&lines, width,
_("Package"),
_("Arch"),
_("Version"),
_("Repository"),
_("Size")
);
- pakfire_transaction_add_separator(&string, width);
+ pakfire_transaction_add_separator(&lines, width);
Queue classes;
queue_init(&classes);
}
// Show what we are doing
- pakfire_transaction_add_headline(&string, width, headline);
+ pakfire_transaction_add_headline(&lines, width, headline);
// Fetch packages in this class
transaction_classify_pkgs(transaction->transaction, mode, class,
new_pkg = pakfire_package_create_from_solvable(transaction->pakfire,
transaction_obs_pkg(transaction->transaction, pkgs.elements[j]));
- pakfire_transaction_add_package_change(&string, width, old_pkg, new_pkg);
+ pakfire_transaction_add_package_change(&lines, width, old_pkg, new_pkg);
break;
default:
- pakfire_transaction_add_package(&string, width, old_pkg);
+ pakfire_transaction_add_package(&lines, width, old_pkg);
break;
}
}
// Newline
- pakfire_transaction_add_newline(&string, width);
+ pakfire_transaction_add_newline(&lines, width);
}
queue_free(&classes);
queue_free(&pkgs);
// Summary
- pakfire_transaction_add_headline(&string, width, _("Transaction Summary"));
- pakfire_transaction_add_separator(&string, width);
+ pakfire_transaction_add_headline(&lines, width, _("Transaction Summary"));
+ pakfire_transaction_add_separator(&lines, width);
// How much do we need to download?
size_t downloadsize = pakfire_transaction_downloadsize(transaction);
if (downloadsize > 0)
- pakfire_transaction_add_usage_line(&string, width,
+ pakfire_transaction_add_usage_line(&lines, width,
_("Total Download Size"), downloadsize);
// How much more space do we need?
ssize_t sizechange = pakfire_transaction_installsizechange(transaction);
- pakfire_transaction_add_usage_line(&string, width,
+ pakfire_transaction_add_usage_line(&lines, width,
(sizechange >= 0) ? _("Installed Size") : _("Freed Size"), sizechange);
- // Remove trailing newline
- pakfire_remove_trailing_newline(string);
+ // Join all lines together
+ char* string = pakfire_transaction_join_lines(lines);
DEBUG(transaction->pakfire, "Transaction: %s\n", string);
+ // Free lines
+ if (lines) {
+ for (char** line = lines; *line; line++)
+ free(*line);
+ free(lines);
+ }
+
return string;
}