[pacman-dev] CVS update of pacman-lib/src/pacman (6 files)

Aaron Griffin aaron at archlinux.org
Sat Feb 3 20:36:45 EST 2007


    Date: Saturday, February 3, 2007 @ 20:36:45
  Author: aaron
    Path: /home/cvs-pacman/pacman-lib/src/pacman

Modified: downloadprog.c (1.8 -> 1.9) pacman.c (1.85 -> 1.86)
          sync.c (1.107 -> 1.108) trans.c (1.30 -> 1.31)
          util.c (1.25 -> 1.26) util.h (1.14 -> 1.15)

* 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


----------------+
 downloadprog.c |   89 +++++++-----------------------
 pacman.c       |    6 +-
 sync.c         |   54 ------------------
 trans.c        |   82 +++++++--------------------
 util.c         |  162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 util.h         |    6 ++
 6 files changed, 218 insertions(+), 181 deletions(-)


Index: pacman-lib/src/pacman/downloadprog.c
diff -u pacman-lib/src/pacman/downloadprog.c:1.8 pacman-lib/src/pacman/downloadprog.c:1.9
--- pacman-lib/src/pacman/downloadprog.c:1.8	Thu Jan 25 21:19:24 2007
+++ pacman-lib/src/pacman/downloadprog.c	Sat Feb  3 20:36:45 2007
@@ -40,58 +40,57 @@
 /* progress bar */
 static float rate_last;
 static int xfered_last;
-static struct timeval last_time;
 static struct timeval initial_time;
 
 /* pacman options */
 extern config_t *config;
 
-#define FILENAME_TRIM_LEN 21
-#define UPDATE_SPEED_SEC 0.1
+#define FILENAME_TRIM_LEN 23
 
 void log_progress(const char *filename, int xfered, int total)
 {
-	static unsigned int lasthash = 0, mouth = 0;
-	unsigned int i, hash;
-	/* a little hard to conceal easter eggs in open-source software,
-	 * but they're still fun. ;) */
-	const unsigned short chomp = alpm_option_get_chomp();
+	const int infolen = 50;
 	char *fname, *p; 
-	unsigned int maxcols = getcols();
-	unsigned int progresslen = maxcols - 57;
-	int percent = (int)((float)xfered) / ((float)total) * 100;
+
 	struct timeval current_time;
 	float rate = 0.0;
 	unsigned int eta_h = 0, eta_m = 0, eta_s = 0;
 	float total_timediff, timediff;
 
+	if(config->noprogressbar) {
+		return;
+	}
+
+	int percent = (int)((float)xfered) / ((float)total) * 100;
+
   if(xfered == 0) {
 		set_output_padding(1); /* we need padding from pm_fprintf output */
 		gettimeofday(&initial_time, NULL);
-		gettimeofday(&last_time, NULL);
 		xfered_last = 0;
 		rate_last = 0.0;
+		timediff = get_update_timediff(1);
+	} else {
+		timediff = get_update_timediff(0);
 	}
 
-	if(config->noprogressbar) {
+	if(percent > 0 && percent < 100 && !timediff) {
+		/* only update the progress bar when
+		 * a) we first start
+		 * b) we end the progress
+		 * c) it has been long enough since the last call
+		 */
 		return;
 	}
 
 	gettimeofday(&current_time, NULL);
 	total_timediff = current_time.tv_sec-initial_time.tv_sec
 		+ (float)(current_time.tv_usec-initial_time.tv_usec) / 1000000;
-	timediff = current_time.tv_sec-last_time.tv_sec
-		+ (float)(current_time.tv_usec-last_time.tv_usec) / 1000000;
 
 	if(xfered == total) {
 		/* compute final values */
 		rate = (float)total / (total_timediff * 1024);
 		eta_s = (unsigned int)total_timediff;
 		set_output_padding(0); /* shut off padding */
-	} else if(timediff < UPDATE_SPEED_SEC) {
-	/* we avoid computing the ETA on too small periods of time, so that
-		 results are more significant */
-		return;
 	} else {
 		rate = (float)(xfered - xfered_last) / (timediff * 1024);
 		rate = (float)(rate + 2*rate_last) / 3;
@@ -99,7 +98,6 @@
 	}
 
 	rate_last = rate;
-	last_time = current_time;
 	xfered_last = xfered;
 	
 	/* fix up time for display */
@@ -116,61 +114,18 @@
 		fname[FILENAME_TRIM_LEN] = '\0';
 	}
 
-	/* hide the cursor i - prevent flicker
-	printf("\033[?25l\033[?1c");
-	*/
-
-	/*
-	 * DL rate cap, for printf formatting - this should be sane for a while
-	 * if anything we can change to MB/s if we need a higher rate
-	 */
+	/* DL rate cap, for printf formatting - this should be sane for a while
+	 * if anything we can change to MB/s if we need a higher rate */
 	if(rate > 9999.9) {
 		rate = 9999.9;
 	}
 
-	printf(" %-*s %6dK %#6.1fK/s %02u:%02u:%02u [", FILENAME_TRIM_LEN, fname, 
+	printf(" %-*s %6dK %#6.1fK/s %02u:%02u:%02u", FILENAME_TRIM_LEN, fname, 
 				 xfered/1024, rate, eta_h, eta_m, eta_s);
 
 	free(fname);
 	
-	hash = (unsigned int)percent*progresslen/100;
-	for(i = progresslen; i > 0; --i) {
-		if(chomp) {
-			if(i > progresslen - hash) {
-				printf("-");
-			} else if(i == progresslen - 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 if(i > progresslen - hash) {
-			printf("#");
-		} else {
-			printf("-");
-		}
-	}
-	printf("] %3d%%\r", percent);
-
-	if(percent == 100) {
-		printf("\n");
-	}
-	fflush(stdout);
+	fill_progress(percent, getcols() - infolen);
 	return;
 }
 
Index: pacman-lib/src/pacman/pacman.c
diff -u pacman-lib/src/pacman/pacman.c:1.85 pacman-lib/src/pacman/pacman.c:1.86
--- pacman-lib/src/pacman/pacman.c:1.85	Wed Jan 31 01:10:22 2007
+++ pacman-lib/src/pacman/pacman.c	Sat Feb  3 20:36:45 2007
@@ -130,6 +130,7 @@
 			printf(_("  -o, --owns <file>   query the package that owns <file>\n"));
 			printf(_("  -p, --file          query the package file [package] instead of the database\n"));
 			printf(_("  -s, --search        search locally-installed packages for matching strings\n"));
+			printf(_("  -u, --upgrades      list all packages that can be upgraded\n"));
 		} else if(op == PM_OP_SYNC) {
 			printf(_("usage:  %s {-S --sync} [options] [package]\n"), myname);
 			printf(_("options:\n"));
@@ -369,7 +370,10 @@
 				config->op_q_search = 1;
 				config->flags |= PM_TRANS_FLAG_RECURSE;
 				break;
-			case 'u': config->op_s_upgrade = 1; break;
+			case 'u':
+				config->op_s_upgrade = 1;
+				/* TODO config->op_q_upgrade = 1; */
+				break;
 			case 'v': (config->verbose)++; break;
 			case 'w':
 				config->op_s_downloadonly = 1;
Index: pacman-lib/src/pacman/sync.c
diff -u pacman-lib/src/pacman/sync.c:1.107 pacman-lib/src/pacman/sync.c:1.108
--- pacman-lib/src/pacman/sync.c:1.107	Sat Feb  3 02:29:51 2007
+++ pacman-lib/src/pacman/sync.c	Sat Feb  3 20:36:45 2007
@@ -626,60 +626,8 @@
 		goto cleanup;
 	}
 
-	/* list targets and get confirmation */
 	if(!(alpm_trans_get_flags() & PM_TRANS_FLAG_PRINTURIS)) {
-		alpm_list_t *list_install = NULL, *list_remove = NULL;
-
-		char *str;
-		unsigned long totalsize = 0;
-		unsigned long totalisize = 0;
-		double mb, umb;
-
-		for(i = packages; i; i = alpm_list_next(i)) {
-			pmsyncpkg_t *sync = alpm_list_getdata(i);
-			pmpkg_t *pkg = alpm_sync_get_package(sync);
-			const char *pkgname, *pkgver;
-
-			if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) {
-				alpm_list_t *data = alpm_sync_get_data(sync);
-				for(j = data; j; j = alpm_list_next(j)) {
-					pmpkg_t *p = alpm_list_getdata(j);
-					const char *pkgname = alpm_pkg_get_name(p);
-					if(!alpm_list_find_str(list_remove, pkgname)) {
-						list_remove = alpm_list_add(list_remove, strdup(pkgname));
-					}
-				}
-			}
-
-			pkgname = alpm_pkg_get_name(pkg);
-			pkgver = alpm_pkg_get_version(pkg);
-			totalsize += alpm_pkg_get_size(pkg);
-			totalisize += alpm_pkg_get_isize(pkg);
-
-			asprintf(&str, "%s-%s", pkgname, pkgver);
-			list_install = alpm_list_add(list_install, str);
-		}
-		if(list_remove) {
-			MSG(NL, "\n"); /* TODO ugly hack. printing a single NL should be easy */
-			list_display(_("Remove:"), list_remove);
-			FREELIST(list_remove);
-		}
-		mb = (double)(totalsize / 1048576.0);
-		umb = (double)(totalisize / 1048576.0);
-		/* round up to 0.1 */
-		if(mb < 0.1) {
-			mb = 0.1;
-		}
-		if(umb > 0 && umb < 0.1) {
-			umb = 0.1;
-		}
-		MSG(NL, "\n");
-		list_display(_("Targets:"), list_install);
-		MSG(NL, _("\nTotal Package Size:   %.1f MB\n"), mb);
-		if(umb > 0) {
-		  MSG(NL, _("Total Installed Size:   %.1f MB\n"), umb);
-		}
-		FREELIST(list_install);
+		display_targets(packages);
 
 		if(config->op_s_downloadonly) {
 			if(config->noconfirm) {
Index: pacman-lib/src/pacman/trans.c
diff -u pacman-lib/src/pacman/trans.c:1.30 pacman-lib/src/pacman/trans.c:1.31
--- pacman-lib/src/pacman/trans.c:1.30	Tue Jan 30 20:37:41 2007
+++ pacman-lib/src/pacman/trans.c	Sat Feb  3 20:36:45 2007
@@ -57,58 +57,6 @@
 	fputs(_("] 100%    LOCAL "), stdout);
 }
 
-/* refactored from cb_trans_progress */
-/* TODO with a little more work, we may be able to incorporate this
- * into the download progress bar as well. */
-static 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");
-	}
-}
-
 /* Callback to handle transaction events
  */
 void cb_trans_evt(pmtransevt_t event, void *data1, void *data2)
@@ -347,9 +295,11 @@
 void cb_trans_progress(pmtransprog_t event, char *pkgname, const int percent,
                        const int howmany, const int remain)
 {
+	float timediff;
+
 	/* size of line to allocate for text printing (e.g. not progressbar) */
 	const int infolen = 50;
-	int i, digits, textlen, pkglen, proglen;
+	int i, digits, textlen, pkglen;
 	char *ptr = NULL;
 
 	if(config->noprogressbar) {
@@ -358,12 +308,22 @@
 
 	if(percent == 0) {
 		set_output_padding(1); /* turn on output padding with ' ' */
-	} else if(percent == 100) {
-		set_output_padding(0); /* shut it off again */
+		timediff = get_update_timediff(1);
+	} else {
+		timediff = get_update_timediff(0);
+	}
+
+	if(percent > 0 && percent < 100 && !timediff) {
+		/* only update the progress bar when
+		 * a) we first start
+		 * b) we end the progress
+		 * c) it has been long enough since the last call
+		 */
+		return;
 	}
 
 	/* if no pkgname, percent is too high or unchanged, then return */
-	if (!pkgname || percent > 100 || percent == prevpercent) {
+	if(!pkgname || percent == prevpercent) {
 		return;
 	}
 
@@ -403,17 +363,19 @@
 			printf("(%*d/%*d) %s %-*.*s", digits, remain, digits, howmany,
 			       ptr, pkglen, pkglen, pkgname);
 			break;
-
 		case PM_TRANS_PROGRESS_CONFLICTS_START:
 			printf("(%*d/%*d) %-*s", digits, remain, digits, howmany,
 			       textlen, ptr);
 			break;
-
 	}
 
 	/* call refactored fill progress function */
-	proglen = getcols() - infolen;
-	fill_progress(percent, proglen);
+	fill_progress(percent, getcols() - infolen);
+
+	if(percent >= 100) {
+		set_output_padding(0); /* restore padding */
+	}
+
 }
 
 /* vim: set ts=2 sw=2 noet: */
Index: pacman-lib/src/pacman/util.c
diff -u pacman-lib/src/pacman/util.c:1.25 pacman-lib/src/pacman/util.c:1.26
--- pacman-lib/src/pacman/util.c:1.25	Thu Feb  1 01:35:30 2007
+++ pacman-lib/src/pacman/util.c	Sat Feb  3 20:36:45 2007
@@ -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 @@
 	}
 }
 
+/* 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: */
Index: pacman-lib/src/pacman/util.h
diff -u pacman-lib/src/pacman/util.h:1.14 pacman-lib/src/pacman/util.h:1.15
--- pacman-lib/src/pacman/util.h:1.14	Thu Feb  1 01:35:30 2007
+++ pacman-lib/src/pacman/util.h	Sat Feb  3 20:36:45 2007
@@ -47,6 +47,9 @@
 	s1[(len)-1] = 0; \
 } while(0)
 
+/* update speed for the fill_progress based functions */
+#define UPDATE_SPEED_SEC 0.2f
+
 #define _(str) gettext(str)
 unsigned int getcols();
 int makepath(char *path);
@@ -56,6 +59,9 @@
 char *strtrim(char *str);
 int reg_match(char *string, char *pattern);
 void list_display(const char *title, alpm_list_t *list);
+void display_targets(alpm_list_t *pkgs);
+float get_update_timediff(int first_call);
+void fill_progress(const int percent, const int proglen);
 
 #endif /* _PM_UTIL_H */
 




More information about the pacman-dev mailing list