From: Michael Tremer Date: Sun, 1 Oct 2023 11:52:10 +0000 (+0000) Subject: progressbar: Drop old implementation X-Git-Tag: 0.9.30~1578 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e198530e88b8509defdfb9d90a0c760e266ab519;p=pakfire.git progressbar: Drop old implementation Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 4bfb4b328..8fecee031 100644 --- a/Makefile.am +++ b/Makefile.am @@ -238,7 +238,6 @@ libpakfire_la_SOURCES = \ src/libpakfire/parser.c \ src/libpakfire/problem.c \ src/libpakfire/progress.c \ - src/libpakfire/progressbar.c \ src/libpakfire/pwd.c \ src/libpakfire/repo.c \ src/libpakfire/repolist.c \ @@ -279,7 +278,6 @@ pkginclude_HEADERS += \ src/libpakfire/include/pakfire/private.h \ src/libpakfire/include/pakfire/problem.h \ src/libpakfire/include/pakfire/progress.h \ - src/libpakfire/include/pakfire/progressbar.h \ src/libpakfire/include/pakfire/pwd.h \ src/libpakfire/include/pakfire/repo.h \ src/libpakfire/include/pakfire/repolist.h \ diff --git a/src/libpakfire/include/pakfire/progressbar.h b/src/libpakfire/include/pakfire/progressbar.h deleted file mode 100644 index 929085ac2..000000000 --- a/src/libpakfire/include/pakfire/progressbar.h +++ /dev/null @@ -1,50 +0,0 @@ -/*############################################################################# -# # -# Pakfire - The IPFire package management system # -# Copyright (C) 2021 Pakfire development team # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -#############################################################################*/ - -#ifndef PAKFIRE_PROGRESSBAR_H -#define PAKFIRE_PROGRESSBAR_H - -#include - -struct pakfire_progressbar; - -int pakfire_progressbar_create(struct pakfire_progressbar** progressbar, FILE* f); - -struct pakfire_progressbar* pakfire_progressbar_ref(struct pakfire_progressbar* p); -struct pakfire_progressbar* pakfire_progressbar_unref(struct pakfire_progressbar* p); - -int pakfire_progressbar_start(struct pakfire_progressbar* p, unsigned long value); -int pakfire_progressbar_update(struct pakfire_progressbar* p, unsigned long value); -int pakfire_progressbar_increment(struct pakfire_progressbar* p, unsigned long value); -int pakfire_progressbar_finish(struct pakfire_progressbar* p); -int pakfire_progressbar_reset(struct pakfire_progressbar* p); - -void pakfire_progressbar_set_max(struct pakfire_progressbar* p, unsigned long value); - -int pakfire_progressbar_add_string(struct pakfire_progressbar* p, const char* format, ...); -int pakfire_progressbar_add_counter(struct pakfire_progressbar* p); -int pakfire_progressbar_add_percentage(struct pakfire_progressbar* p); -int pakfire_progressbar_add_bar(struct pakfire_progressbar* p); -int pakfire_progressbar_add_timer(struct pakfire_progressbar* p); -int pakfire_progressbar_add_bytes_transferred(struct pakfire_progressbar* p); -int pakfire_progressbar_add_eta(struct pakfire_progressbar* p); -int pakfire_progressbar_add_transfer_speed(struct pakfire_progressbar* p); - -#endif /* PAKFIRE_PROGRESSBAR_H */ diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index f662d3ec2..5e437ee9d 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -223,25 +223,6 @@ global: pakfire_progress_set_start_callback; pakfire_progress_set_update_callback; - # progressbar - pakfire_progressbar_add_bar; - pakfire_progressbar_add_bytes_transferred; - pakfire_progressbar_add_counter; - pakfire_progressbar_add_eta; - pakfire_progressbar_add_percentage; - pakfire_progressbar_add_string; - pakfire_progressbar_add_timer; - pakfire_progressbar_add_transfer_speed; - pakfire_progressbar_create; - pakfire_progressbar_finish; - pakfire_progressbar_increment; - pakfire_progressbar_ref; - pakfire_progressbar_reset; - pakfire_progressbar_set_max; - pakfire_progressbar_start; - pakfire_progressbar_unref; - pakfire_progressbar_update; - # repo pakfire_repo_cmp; pakfire_repo_compose; diff --git a/src/libpakfire/progressbar.c b/src/libpakfire/progressbar.c deleted file mode 100644 index 5e5e77199..000000000 --- a/src/libpakfire/progressbar.c +++ /dev/null @@ -1,611 +0,0 @@ -/*############################################################################# -# # -# Pakfire - The IPFire package management system # -# Copyright (C) 2021 Pakfire development team # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -#############################################################################*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define DRAWS_PER_SECOND 20 - -static const struct timespec TIMER = { - .tv_sec = 0, - .tv_nsec = 1000000000 / DRAWS_PER_SECOND, -}; - -struct pakfire_progressbar_widget { - STAILQ_ENTRY(pakfire_progressbar_widget) nodes; - - int expandable; - void* data; - - const char* (*print)(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data); - void (*free)(void* data); - - char buffer[1024]; -}; - -struct pakfire_progressbar { - int nrefs; - FILE* f; - - volatile enum pakfire_progressbar_status { - PAKFIRE_PROGRESSBAR_INIT = 0, - PAKFIRE_PROGRESSBAR_RUNNING, - PAKFIRE_PROGRESSBAR_FINISHED, - } status; - - // The progress - volatile unsigned long value; - volatile unsigned long value_max; - - struct timespec time_start; - - // Reference to the thread that is drawing the progress bar - pthread_t renderer; - - // Widgets - STAILQ_HEAD(widgets, pakfire_progressbar_widget) widgets; - unsigned int num_widgets; -}; - -// Store terminal settings globally -static struct pakfire_terminal { - int rows; - int cols; -} terminal; - -static void pakfire_progressbar_update_terminal_size(int signum) { - const int fd = STDOUT_FILENO; - - // Set defaults - terminal.rows = 80; - terminal.cols = 20; - - // Check if output file is a TTY - int r = isatty(fd); - if (r != 1) - return; - - struct winsize w; - r = ioctl(fd, TIOCGWINSZ, &w); - if (r) - return; - - // Save result - terminal.rows = w.ws_row; - terminal.cols = w.ws_col; -} - -static void pakfire_progressbar_widget_free(struct pakfire_progressbar_widget* widget) { - // Call own free method - if (widget->free && widget->data) - widget->free(widget->data); - - free(widget); -} - -static void pakfire_progressbar_free_widgets(struct pakfire_progressbar* p) { - struct pakfire_progressbar_widget* widget; - - // Free widgets - while (!STAILQ_EMPTY(&p->widgets)) { - widget = STAILQ_FIRST(&p->widgets); - STAILQ_REMOVE_HEAD(&p->widgets, nodes); - - pakfire_progressbar_widget_free(widget); - } -} - -static int __pakfire_progressbar_finish(struct pakfire_progressbar* p) { - int r; - void* retval = NULL; - - // Do nothing if already finished - if (p->status == PAKFIRE_PROGRESSBAR_FINISHED) - return 0; - - // Set status - p->status = PAKFIRE_PROGRESSBAR_FINISHED; - - // Wait until the render thread is done - if (p->renderer) { - r = pthread_join(p->renderer, &retval); - if (r) - return r; - } - - return (intptr_t)retval; -} - -static void pakfire_progressbar_free(struct pakfire_progressbar* p) { - // Ensure the progressbar has finished - __pakfire_progressbar_finish(p); - - pakfire_progressbar_free_widgets(p); - free(p); -} - -static int pakfire_progressbar_draw(struct pakfire_progressbar* p) { - struct pakfire_progressbar_widget* widget; - - // Update terminal size if not set - if (!terminal.cols) - pakfire_progressbar_update_terminal_size(SIGWINCH); - - unsigned int cols_left = terminal.cols - p->num_widgets - 2; - unsigned int i = 0; - - // Create an array with the result of all print functions - const char* elements[p->num_widgets]; - - // Reset all elements - for (i = 0; i < p->num_widgets; i++) - elements[i] = NULL; - - // Reset i - i = 0; - - // Process all non-expandable widgets in the first pass - STAILQ_FOREACH(widget, &p->widgets, nodes) { - const char* element = NULL; - - // Clear any previous content - if (*widget->buffer) - memset(widget->buffer, '\0', sizeof(widget->buffer)); - - if (!widget->expandable) { - element = widget->print(p, widget, 0, widget->data); - if (element) - cols_left -= strlen(element); - } - - elements[i++] = element; - } - - // How many expandable widgets are left? - int num_expandables = p->num_widgets - i; - - // How much space do we allocate to each of them? - int width = cols_left - num_expandables; - - i = 0; - - // Process all expandable widgets - STAILQ_FOREACH(widget, &p->widgets, nodes) { - const char* element = elements[i]; - - if (widget->expandable) { - element = widget->print(p, widget, width, widget->data); - } - - elements[i++] = element; - } - - // Reset the line - fputs("\r", p->f); - - // Print all elements - for (i = 0; i < p->num_widgets; i++) { - // Skip anything that returned nothing - if (!elements[i]) - continue; - - fputs(" ", p->f); - fputs(elements[i], p->f); - } - - // Flush everything - fflush(p->f); - - return 0; -} - -PAKFIRE_EXPORT int pakfire_progressbar_create( - struct pakfire_progressbar** progressbar, FILE* f) { - // Allocate main object - struct pakfire_progressbar* p = calloc(1, sizeof(*p)); - if (!p) - return 1; - - // Initialise reference counting - p->nrefs = 1; - - // Set output to stdout if nothing was set - if (!f) - f = stdout; - - // Store output - p->f = stdout; - - // Register signal handler to update terminal size - signal(SIGWINCH, pakfire_progressbar_update_terminal_size); - - // Setup widgets - STAILQ_INIT(&p->widgets); - - // Done - *progressbar = p; - - return 0; -} - -PAKFIRE_EXPORT struct pakfire_progressbar* pakfire_progressbar_ref(struct pakfire_progressbar* p) { - ++p->nrefs; - - return p; -} - -PAKFIRE_EXPORT struct pakfire_progressbar* pakfire_progressbar_unref(struct pakfire_progressbar* p) { - if (--p->nrefs > 0) - return p; - - pakfire_progressbar_free(p); - return NULL; -} - -static time_t pakfire_progressbar_elapsed_time(struct pakfire_progressbar* p) { - struct timespec now; - - int r = clock_gettime(CLOCK_REALTIME, &now); - if (r) - return r; - - return now.tv_sec - p->time_start.tv_sec; -} - -static void* __pakfire_progressbar_renderer(void* __p) { - struct pakfire_progressbar* p = (struct pakfire_progressbar*)__p; - int r; - - do { - // Redraw the progress bar - r = pakfire_progressbar_draw(p); - if (r) - goto ERROR; - - // Sleep for a short moment - nanosleep(&TIMER, NULL); - - // Keep doing this for as long as we are running - } while (p->status == PAKFIRE_PROGRESSBAR_RUNNING); - - // Set to maximum value - r = pakfire_progressbar_update(p, p->value_max); - if (r) - goto ERROR; - - // Perform a final draw - r = pakfire_progressbar_draw(p); - if (r) - goto ERROR; - - // Finish line - r = fputs("\n", p->f); - if (r <= 0 || r == EOF) { - r = 1; - goto ERROR; - } - - // Success - r = 0; - -ERROR: - return (void *)(intptr_t)r; -} - -PAKFIRE_EXPORT int pakfire_progressbar_start(struct pakfire_progressbar* p, unsigned long value) { - int r; - - if (p->status == PAKFIRE_PROGRESSBAR_RUNNING) - return EINVAL; - - // Set status - p->status = PAKFIRE_PROGRESSBAR_RUNNING; - - // Set maximum value - pakfire_progressbar_set_max(p, value); - - // Set start time - r = clock_gettime(CLOCK_REALTIME, &p->time_start); - if (r) - return r; - - // Set initial value - r = pakfire_progressbar_update(p, 0); - if (r) - return r; - - // Launch the renderer thread - return pthread_create(&p->renderer, NULL, __pakfire_progressbar_renderer, p); -} - -PAKFIRE_EXPORT int pakfire_progressbar_update(struct pakfire_progressbar* p, unsigned long value) { - if (p->status == PAKFIRE_PROGRESSBAR_INIT) - return EINVAL; - - p->value = value; - return 0; -} - -PAKFIRE_EXPORT int pakfire_progressbar_increment(struct pakfire_progressbar* p, unsigned long value) { - return pakfire_progressbar_update(p, p->value + value); -} - -PAKFIRE_EXPORT int pakfire_progressbar_finish(struct pakfire_progressbar* p) { - if (p->status != PAKFIRE_PROGRESSBAR_RUNNING) - return EINVAL; - - return __pakfire_progressbar_finish(p); -} - -PAKFIRE_EXPORT int pakfire_progressbar_reset(struct pakfire_progressbar* p) { - // Free all widgets - pakfire_progressbar_free_widgets(p); - - // Reset all values - p->value = 0; - p->value_max = 0; - p->time_start.tv_sec = 0; - p->time_start.tv_nsec = 0; - - return 0; -} - -PAKFIRE_EXPORT void pakfire_progressbar_set_max( - struct pakfire_progressbar* p, unsigned long value) { - // Store maximum value - p->value_max = value; -} - -static int pakfire_progressbar_add_widget(struct pakfire_progressbar* p, - const char* (*print)(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data), - void (*free)(void* data), int expandable, void* data) { - // Allocate the widget - struct pakfire_progressbar_widget* widget = calloc(1, sizeof(*widget)); - if (!widget) - return ENOMEM; - - // Assign everything - widget->print = print; - widget->free = free; - widget->expandable = expandable; - widget->data = data; - - // Append it to the list - STAILQ_INSERT_TAIL(&p->widgets, widget, nodes); - p->num_widgets++; - - return 0; -} - -// String widget - -static const char* pakfire_progressbar_string(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - return (const char*)data; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_string(struct pakfire_progressbar* p, - const char* format, ...) { - char* s = NULL; - va_list args; - - va_start(args, format); - int r = vasprintf(&s, format, args); - va_end(args); - - if (r < 0) - return r; - - return pakfire_progressbar_add_widget(p, pakfire_progressbar_string, free, 0, s); -} - -// Counter - -static const char* pakfire_progressbar_counter(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - int r = pakfire_string_format(widget->buffer, "%lu/%lu", p->value, p->value_max); - if (r) - return NULL; - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_counter(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_counter, NULL, 0, NULL); -} - -// Percentage - -static const char* pakfire_progressbar_percentage(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - double percentage = p->value * 100.0 / p->value_max; - - int r = pakfire_string_format(widget->buffer, "%3.0f%%", percentage); - if (r) - return NULL; - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_percentage(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_percentage, NULL, 0, NULL); -} - -// Bar - -static const char* pakfire_progressbar_bar(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - if (width >= sizeof(widget->buffer) || width < 2) - return NULL; - - // Remove the bar when we are finished so that the terminal is not so cluttered - if (p->status == PAKFIRE_PROGRESSBAR_FINISHED) { - for (unsigned int i = 0; i < width; i++) - widget->buffer[i] = ' '; - widget->buffer[width] = '\0'; - - return widget->buffer; - } - - unsigned int fill = 0; - - if (p->value_max) - fill = p->value * (width - 2) / p->value_max; - - // Write brackets - widget->buffer[0] = '['; - widget->buffer[width-1] = ']'; - - // Write bar - for (unsigned int i = 1; i < width - 1; i++) { - if (i <= fill) - widget->buffer[i] = '#'; - else - widget->buffer[i] = '-'; - } - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_bar(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_bar, NULL, 1, NULL); -} - -// Timer - -static const char* pakfire_progressbar_timer(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - time_t t = pakfire_progressbar_elapsed_time(p); - if (t < 0) - return NULL; - - int r = pakfire_string_format(widget->buffer, "%02lu:%02lu", t / 60, t % 60); - if (r) - return NULL; - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_timer(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_timer, NULL, 0, NULL); -} - -// ETA - -static const char* pakfire_progressbar_eta(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - int r; - - time_t t = pakfire_progressbar_elapsed_time(p); - if (t < 0) - return NULL; - - // Show total time when finished - if (p->status == PAKFIRE_PROGRESSBAR_FINISHED) - return pakfire_progressbar_timer(p, widget, width, data); - - // Print a placeholder when we haven't started yet - if (p->value == 0) { - r = pakfire_string_format(widget->buffer, "%-5s: --:--:--", _("ETA")); - if (r) - return NULL; - - // Show total time when finished - } else if (p->status == PAKFIRE_PROGRESSBAR_FINISHED) { - r = pakfire_string_format(widget->buffer, "%-5s: %02lu:%02lu", - _("Time"), t / 60, t % 60); - if (r) - return NULL; - - // Calculate the ETA - } else { - time_t eta = t * p->value_max / p->value - t; - - r = pakfire_string_format(widget->buffer, "%-5s: %02lu:%02lu", - _("ETA"), eta / 60, eta % 60); - if (r) - return NULL; - } - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_eta(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_eta, NULL, 0, NULL); -} - -// Bytes Transferred - -static const char* pakfire_progressbar_bytes_transferred(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - char buffer[16]; - - int r = pakfire_format_size(buffer, p->value); - if (r < 0) - return NULL; - - // Add padding so that the string is always at least five characters long - pakfire_string_format(widget->buffer, "%-5s", buffer); - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_bytes_transferred(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget(p, pakfire_progressbar_bytes_transferred, NULL, 0, NULL); -} - -// Speed - -static const char* pakfire_progressbar_transfer_speed(struct pakfire_progressbar* p, - struct pakfire_progressbar_widget* widget, unsigned int width, void* data) { - if (!p->value) - return NULL; - - time_t t = pakfire_progressbar_elapsed_time(p); - if (t <= 0) - return NULL; - - int r = pakfire_format_speed(widget->buffer, sizeof(widget->buffer), p->value / t); - if (r < 0) - return NULL; - - return widget->buffer; -} - -PAKFIRE_EXPORT int pakfire_progressbar_add_transfer_speed(struct pakfire_progressbar* p) { - return pakfire_progressbar_add_widget( - p, pakfire_progressbar_transfer_speed, NULL, 0, NULL); -}