#include <pakfire/i18n.h>
#include <pakfire/pakfire.h>
#include <pakfire/progress.h>
+#include <pakfire/string.h>
#include <pakfire/util.h>
#include "progressbar.h"
print_callback print;
free_callback free;
- char* buffer;
+ char buffer[LINE_MAX];
};
struct cli_progressbar {
if (widget->free && widget->data)
widget->free(widget->data);
- if (widget->buffer)
- free(widget->buffer);
-
free(widget);
}
// Print all buffers
STAILQ_FOREACH(widget, &p->widgets, nodes) {
- if (!widget->buffer || !*widget->buffer)
+ if (!*widget->buffer)
continue;
fputs(" ", p->f);
const char* title = NULL;
int r;
- if (!widget->buffer) {
- title = pakfire_progress_get_title(p->progress);
- if (!title)
- return 0;
+ title = pakfire_progress_get_title(p->progress);
+ if (!title)
+ return 0;
- r = asprintf(&widget->buffer, "%s", title);
- if (r < 0)
- return r;
- }
+ r = pakfire_string_format(widget->buffer, "%s", title);
+ if (r < 0)
+ return r;
return strlen(widget->buffer);
}
unsigned long int max_value = pakfire_progress_get_value(p->progress);
// Format the result
- r = asprintf(&widget->buffer, "%lu/%lu", value, max_value);
+ r = pakfire_string_format(widget->buffer, "%lu/%lu", value, max_value);
if (r < 0)
return -errno;
- return r;
+ return strlen(widget->buffer);
}
static int cli_progressbar_add_counter(struct cli_progressbar* p) {
double percentage = pakfire_progress_get_percentage(p->progress);
// Format to string
- r = asprintf(&widget->buffer, "%3.0f%%", percentage);
+ r = pakfire_string_format(widget->buffer, "%3.0f%%", percentage);
if (r < 0)
return -errno;
- return r;
+ return strlen(widget->buffer);
}
static int cli_progressbar_add_percentage(struct cli_progressbar* p) {
if (!width)
return -ENOBUFS;
- // Allocate or adjust the buffer
- widget->buffer = pakfire_realloc(widget->buffer, width + 1);
-
- // Fail if we could not allocate the buffer
- if (!widget->buffer)
- return -errno;
+ // Cap the widths to the buffer
+ if (width >= sizeof(widget->buffer))
+ width = sizeof(widget->buffer) - 1;
// Remove the bar when we are finished so that the terminal is not so cluttered
if (!p->is_running) {
return -errno;
// Format the time
- r = asprintf(&widget->buffer, "%02ld:%02ld", t / 60, t % 60);
+ r = pakfire_string_format(widget->buffer, "%02ld:%02ld", t / 60, t % 60);
if (r < 0)
return -errno;
- return r;
+ return strlen(widget->buffer);
}
static int cli_progressbar_add_elapsed_time(struct cli_progressbar* p) {
// Print a placeholder when we have no ETA (yet)
if (t <= 0) {
- r = asprintf(&widget->buffer, "%-5s: --:--:--", _("ETA"));
+ r = pakfire_string_format(widget->buffer, "%-5s: --:--:--", _("ETA"));
if (r < 0)
return -errno;
// Otherwise show the ETA
} else {
- r = asprintf(&widget->buffer, "%-5s: %02ld:%02ld", _("ETA"), t / 60, t % 60);
+ r = pakfire_string_format(widget->buffer, "%-5s: %02ld:%02ld", _("ETA"), t / 60, t % 60);
if (r < 0)
return -errno;
}
- return r;
+ return strlen(widget->buffer);
}
static int cli_progressbar_add_eta(struct cli_progressbar* p) {
return cli_progressbar_add_widget(p, cli_progressbar_eta, NULL, 0, NULL);
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
-static int cli_progressbar_format_speed(char** s, double value) {
- const char* units[] = {
- "%4.0fB/s",
- "%4.0fkB/s",
- "%4.1fMB/s",
- "%4.1fGB/s",
- "%4.1fTB/s",
- NULL
- };
- int r;
-
- for (const char** unit = units; *unit; unit++) {
- if (value >= 1024.0) {
- value /= 1024.0;
- continue;
- }
-
- // Format the string
- r = asprintf(s, *unit, value);
- if (r < 0)
- return r;
-
- return 0;
- }
-
- return 1;
-}
-
-#define cli_progressbar_format_size(s, size) \
- __cli_progressbar_format_size(s, sizeof(s), size)
-
-static int __cli_progressbar_format_size(char* s, const size_t length, double value) {
- const char* units[] = {
- "%.0f ",
- "%.0fk",
- "%.1fM",
- "%.1fG",
- "%.1fT",
- NULL
- };
- int r;
-
- for (const char** unit = units; *unit; unit++) {
- if (value >= 1024.0) {
- value /= 1024.0;
- continue;
- }
-
- // Format the string
- r = snprintf(s, length, *unit, value);
- if (r < 0)
- return r;
-
- return 0;
- }
-
- return 1;
-}
-#pragma GCC diagnostic pop
-
static ssize_t cli_progressbar_bytes_transferred(struct cli_progressbar* p,
struct cli_progressbar_widget* widget, unsigned int width, void* data) {
char buffer[16];
unsigned long int value = pakfire_progress_get_value(p->progress);
// Format the size
- r = cli_progressbar_format_size(buffer, value);
+ r = pakfire_format_size(buffer, value);
if (r < 0)
return r;
// Add padding so that the string is always at least five characters long
- r = asprintf(&widget->buffer, "%-5s", buffer);
+ r = pakfire_string_format(widget->buffer, "%-5s", buffer);
if (r < 0)
return -errno;
- return r;
+ return strlen(widget->buffer);
}
static int cli_progressbar_add_bytes_transferred(struct cli_progressbar* p) {
return -errno;
// Format the speed
- r = cli_progressbar_format_speed(&widget->buffer, speed);
+ r = pakfire_format_speed(widget->buffer, speed);
if (r < 0)
return r;