summaryrefslogtreecommitdiff
path: root/src/pacman/util.c
diff options
context:
space:
mode:
authorAaron Griffin <aaron@archlinux.org>2007-02-04 01:36:45 +0000
committerAaron Griffin <aaron@archlinux.org>2007-02-04 01:36:45 +0000
commite3c7e92f1090204ba945c063b7aba3b3b1d8095b (patch)
tree08d49f36264059a878c7c40c80d99ec5bbcdcdc0 /src/pacman/util.c
parentd18259b532a09de8025881532bc9ef6152a31891 (diff)
* unified the progress bars (fill_progress function)
* fixed progress output (needs an fflush to move cursor properly) * broke display_targets function out, to display a list of syncpkgs in preparation for a -Qu option * added get_update_time function to deal with progress functions that shouldn't update too fast due to output redraw speeds
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r--src/pacman/util.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 7cff41b7..a30ae617 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
#include "config.h"
#include <stdio.h>
@@ -258,4 +259,165 @@ void list_display(const char *title, alpm_list_t *list)
}
}
+/* Display a list of transaction targets.
+ * `pkgs` should be a list of pmsyncpkg_t's,
+ * retrieved from a transaction object
+ */
+void display_targets(alpm_list_t *pkgs)
+{
+ char *str;
+ alpm_list_t *i, *j;
+ alpm_list_t *targets = NULL, *to_remove = NULL;
+ unsigned long totalsize = 0, totalisize = 0, totalrsize = 0;
+
+ for(i = pkgs; i; i = alpm_list_next(i)) {
+ pmsyncpkg_t *sync = alpm_list_getdata(i);
+ pmpkg_t *pkg = alpm_sync_get_package(sync);
+
+ /* If this sync record is a replacement, the data member contains
+ * a list of packages to be removed due to the package that is being
+ * installed. */
+ if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) {
+ alpm_list_t *to_replace = alpm_sync_get_data(sync);
+
+ for(j = to_replace; j; j = alpm_list_next(j)) {
+ pmpkg_t *rp = alpm_list_getdata(j);
+ const char *name = alpm_pkg_get_name(rp);
+
+ if(!alpm_list_find_str(to_remove, name)) {
+ totalrsize += alpm_pkg_get_isize(rp);
+ to_remove = alpm_list_add(to_remove, strdup(name));
+ }
+ }
+ }
+
+ totalsize += alpm_pkg_get_size(pkg);
+ totalisize += alpm_pkg_get_isize(pkg);
+
+ asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
+ targets = alpm_list_add(targets, str);
+ }
+
+ if(to_remove) {
+ MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */
+ list_display(_("Remove:"), to_remove);
+ FREELIST(to_remove);
+
+ double rmb = (double)(totalrsize) / (1024.0 * 1024.0);
+ if(rmb > 0) {
+ if(rmb < 0.1) {
+ rmb = 0.1;
+ }
+ MSG(NL, _("\nTotal Removed Size: %.2f MB\n"), rmb);
+ }
+ }
+
+ MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */
+ list_display(_("Targets:"), targets);
+
+ double mb = (double)(totalsize) / (1024.0 * 1024.0);
+ if(mb < 0.1) {
+ mb = 0.1;
+ }
+ MSG(NL, _("\nTotal Package Size: %.2f MB\n"), mb);
+
+ double umb = (double)(totalisize) / (1024.0 * 1024.0);
+ if(umb > 0) {
+ if(umb < 0.1) {
+ umb = 0.1;
+ }
+ MSG(NL, _("Total Installed Size: %.2f MB\n"), umb);
+ }
+
+ FREELIST(targets);
+}
+
+/* Silly little helper function, determines if the caller needs a visual update
+ * since the last time this function was called.
+ * This is made for the two progress bar functions, to prevent flicker
+ *
+ * first_call indicates if this is the first time it is called, for
+ * initialization purposes */
+float get_update_timediff(int first_call)
+{
+ float retval = 0.0;
+ static struct timeval last_time = {0};
+ struct timeval this_time;
+
+ if(first_call) {
+ /* always update on the first call */
+ retval = 1.0;
+ } else {
+ gettimeofday(&this_time, NULL);
+
+ float diff_sec = this_time.tv_sec - last_time.tv_sec;
+ float diff_usec = this_time.tv_usec - last_time.tv_usec;
+
+ retval = diff_sec + (diff_usec / 1000000.0f);
+ /*printf("update time: %fs %fus = %f\n", diff_sec, diff_usec, retval);*/
+
+ if(retval < UPDATE_SPEED_SEC) {
+ /* maintain the last_time value for the next call */
+ return(0.0);
+ }
+ }
+
+ /* set the time for the next call */
+ gettimeofday(&last_time, NULL);
+
+ return(retval);
+}
+
+/* refactored from cb_trans_progress */
+void fill_progress(const int percent, const int proglen)
+{
+ const unsigned short chomp = alpm_option_get_chomp();
+ const unsigned int hashlen = proglen - 8;
+ const unsigned int hash = percent * hashlen / 100;
+ unsigned int lasthash = 0, mouth = 0;
+ unsigned int i;
+
+ printf(" [");
+ for(i = hashlen; i > 1; --i) {
+ /* if special progress bar enabled */
+ if(chomp) {
+ if(i > hashlen - hash) {
+ printf("-");
+ } else if(i == hashlen - hash) {
+ if(lasthash == hash) {
+ if(mouth) {
+ printf("\033[1;33mC\033[m");
+ } else {
+ printf("\033[1;33mc\033[m");
+ }
+ } else {
+ lasthash = hash;
+ mouth = mouth == 1 ? 0 : 1;
+ if(mouth) {
+ printf("\033[1;33mC\033[m");
+ } else {
+ printf("\033[1;33mc\033[m");
+ }
+ }
+ } else if(i%3 == 0) {
+ printf("\033[0;37mo\033[m");
+ } else {
+ printf("\033[0;37m \033[m");
+ }
+ } /* else regular progress bar */
+ else if(i > hashlen - hash) {
+ printf("#");
+ } else {
+ printf("-");
+ }
+ }
+ printf("] %3d%%\r", percent);
+
+ if(percent == 100) {
+ printf("\n");
+ }
+ fflush(stdout);
+}
+
+
/* vim: set ts=2 sw=2 noet: */