>From 268fc82a3de37471bead8320bef5bcf068e62197 Mon Sep 17 00:00:00 2001
From: Justin Lampley <jrlampley@gmail.com>
Date: Sun, 2 Mar 2008 13:47:19 -0500
Subject: [PATCH] Add VerboseUpgradeInfo Option

Adds the config option VerboseUpgradeInfo, which displays the
old version and size in column format during upgrade operations.


Signed-off-by: Justin Lampley <jrlampley@gmail.com>
---
 doc/pacman.conf.5.txt |    5 ++
 src/pacman/conf.h     |    2 +
 src/pacman/pacman.c   |    3 +
 src/pacman/util.c     |  153 +++++++++++++++++++++++++++++++++++++++++++++----
 src/pacman/util.h     |    1 +
 5 files changed, 152 insertions(+), 12 deletions(-)

diff --git a/doc/pacman.conf.5.txt b/doc/pacman.conf.5.txt
index e8f7454..f2c2c41 100644
--- a/doc/pacman.conf.5.txt
+++ b/doc/pacman.conf.5.txt
@@ -130,6 +130,11 @@ Options
 	and completed percentage of the entire download list list rather
 	than the percent of each individual download target. The progress
 	bar is still based solely on the current file download.
+	
+*VerboseUpgradeInfo*::
+	When listing targets to install in '\--sync' and '\--query' upgrade modes, 
+	display the old version as well as the size of the individual packages.
+
 
 Repository Sections
 -------------------
diff --git a/src/pacman/conf.h b/src/pacman/conf.h
index f804f56..1aa6a4b 100644
--- a/src/pacman/conf.h
+++ b/src/pacman/conf.h
@@ -67,6 +67,8 @@ typedef struct __config_t {
 	unsigned short chomp; /* I Love Candy! */
 	unsigned short usecolor; /* enable colorful output */
 	unsigned short showsize; /* show individual package sizes */
+	unsigned short verboseupgradeinfo; /* show old package version as well as size
+	                                 when displaying the upgrade target list*/
 	unsigned short totaldownload; /* When downloading, display the amount
 	                                 downloaded, rate, ETA, and percent
 	                                 downloaded of the total download list */
diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c
index 61e0042..38885c7 100644
--- a/src/pacman/pacman.c
+++ b/src/pacman/pacman.c
@@ -635,6 +635,9 @@ static int _parseconfig(const char *file, const char *givensection,
 				} else if(strcmp(key, "ShowSize") == 0 || strcmp(upperkey, "SHOWSIZE") == 0) {
 					config->showsize = 1;
 					pm_printf(PM_LOG_DEBUG, "config: showsize\n");
+				} else if(strcmp(key, "VerboseUpgradeInfo") == 0 || strcmp(upperkey, "VERBOSEUPGRADEINFO") == 0) {
+					config->verboseupgradeinfo = 1;
+					pm_printf(PM_LOG_DEBUG, "config: verboselistinfo\n");
 				} else if(strcmp(key, "UseDelta") == 0 || strcmp(upperkey, "USEDELTA") == 0) {
 					alpm_option_set_usedelta(1);
 					pm_printf(PM_LOG_DEBUG, "config: usedelta\n");
diff --git a/src/pacman/util.c b/src/pacman/util.c
index 19e6444..ad5ecc8 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -361,6 +361,65 @@ void string_display(const char *title, const char *string)
 	}
 }
 
+/** Displays the list in column format according to format string provided
+ *
+ * @param title  the title of the list
+ * @param header  the column headers seperated by a delimeter
+ * @param rows  a list of the rows, with columns seperated by a delimeter
+ * @param formatstring  the format that the rows should be printed in, with the formats
+ * for each column seperate by a delimeter.
+ * @param delim  the delimeter used in the header, rows, and formatstring parameters
+ *
+ */
+void columned_list_display(const char *title, const char *header, const alpm_list_t *rows, const char *formatstring, const char delim)
+{
+	alpm_list_t *currow, *curformat, *columns, *curcolumn;
+	alpm_list_t *formats = strsplit(formatstring,delim);
+	currow = alpm_list_first(rows);
+	printf("%s ", title);
+	
+	if(rows && formats) {
+		printf("\n\n");
+		
+		if(header) {
+			alpm_list_t *splitheader = strsplit(header,delim);
+			alpm_list_t *curheader = alpm_list_first(splitheader);
+			curformat = alpm_list_first(formats);
+			
+			do {
+				printf(alpm_list_getdata(curformat),alpm_list_getdata(curheader));
+				
+				curheader = alpm_list_next(curheader);
+				curformat = alpm_list_next(curformat);
+			} while (curheader && curformat);
+
+			printf("\n\n");
+			
+			FREELIST(splitheader);
+		}
+		
+		do {
+			columns = strsplit(alpm_list_getdata(currow),delim);
+			curformat = alpm_list_first(formats);
+			curcolumn = alpm_list_first(columns);
+	
+			do {
+				printf(alpm_list_getdata(curformat),alpm_list_getdata(curcolumn));
+				curcolumn = alpm_list_next(curcolumn);
+				curformat = alpm_list_next(curformat);
+			} while (curcolumn && curformat);
+			printf("\n");
+			FREELIST(columns);
+			currow = alpm_list_next(currow);
+		} while (currow);
+	} else {
+		printf(_("None\n"));
+	}
+	
+	FREELIST(formats);
+}
+
+
 void list_display(const char *title, const alpm_list_t *list)
 {
 	const alpm_list_t *i;
@@ -398,13 +457,37 @@ void list_display(const char *title, const alpm_list_t *list)
 /* TODO move to output.c? or just combine util and output */
 void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
 {
-	char *str;
+	char *str, *format, *oldpkgver, *pkgsize, *header = NULL;
 	const alpm_list_t *i, *j;
 	alpm_list_t *targets = NULL, *to_remove = NULL;
+	int lenpkgname = 0, lenpkgver = 0, lenoldpkgver = 0, lenpkgsize = 0;
+	/* padding to use for columns */
+	int padding = 2;
 	/* TODO these are some messy variable names */
 	unsigned long isize = 0, rsize = 0, dispsize = 0, dlsize = 0;
 	double mbisize = 0.0, mbrsize = 0.0, mbdispsize = 0.0, mbdlsize = 0.0;
 
+	if(config->verboseupgradeinfo) {
+		/* setup the header */
+		char *pkgname, *newver, *oldver, *size;
+		asprintf(&pkgname,"%s",_("Pkg Name"));
+		asprintf(&newver,"%s",_("New Version"));
+		asprintf(&oldver,"%s",_("Old Version"));
+		asprintf(&size,"%s",_("Size"));
+		/* initially set up size of columns as the length of the headers */
+		lenpkgname = strlen(pkgname);
+		lenoldpkgver = strlen(oldver);
+		lenpkgver = strlen(newver);
+		lenpkgsize = strlen(size);
+		
+		asprintf(&header,"%s,%s,%s,%s", pkgname, newver, oldver, size);
+		
+		free(pkgname);
+		free(newver);
+		free(oldver);
+		free(size);
+	}
+	
 	for(i = syncpkgs; i; i = alpm_list_next(i)) {
 		pmsyncpkg_t *sync = alpm_list_getdata(i);
 		pmpkg_t *pkg = alpm_sync_get_pkg(sync);
@@ -429,17 +512,52 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
 		dispsize = alpm_pkg_get_size(pkg);
 		dlsize += alpm_pkg_download_size(pkg, db_local);
 		isize += alpm_pkg_get_isize(pkg);
-
-		/* print the package size with the output if ShowSize option set */
-		if(config->showsize) {
-			/* Convert byte size to MB */
-			mbdispsize = dispsize / (1024.0 * 1024.0);
-
-			asprintf(&str, "%s-%s [%.2f MB]", alpm_pkg_get_name(pkg),
-					alpm_pkg_get_version(pkg), mbdispsize);
+		
+		/* Convert byte size to MB */
+		mbdispsize = dispsize / (1024.0 * 1024.0);
+		
+		if(config->verboseupgradeinfo) {
+			
+			/* if it is an upgrade, print the old version of the package */
+			if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_UPGRADE) {
+					pmpkg_t *oldpkg = alpm_sync_get_data(sync);
+					asprintf(&oldpkgver, "%s",alpm_pkg_get_version(oldpkg));
+			}
+			else
+				asprintf(&oldpkgver, "%s","");
+			
+			/* get the size of the package */
+			asprintf(&pkgsize,"%.2f MB",mbdispsize);
+			
+			asprintf(&str,"%s,%s,%s,%s",alpm_pkg_get_name(pkg), 
+					alpm_pkg_get_version(pkg), oldpkgver, pkgsize);
+							
+			/* check the column sizes of the newly added row */
+			if(strlen(alpm_pkg_get_name(pkg)) > lenpkgname) {
+				lenpkgname = strlen(alpm_pkg_get_name(pkg));
+			}
+			if(strlen(oldpkgver) > lenoldpkgver) {
+				lenoldpkgver = strlen(oldpkgver);
+			}
+			if(strlen(alpm_pkg_get_version(pkg)) > lenpkgver) {
+				lenpkgver = strlen(alpm_pkg_get_version(pkg));
+			}
+			if(strlen(pkgsize) > lenpkgsize) {
+				lenpkgsize = strlen(pkgsize);
+			}
+			
+			free(oldpkgver);
+			free(pkgsize);
 		} else {
-			asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg),
-					alpm_pkg_get_version(pkg));
+
+			/* print the package size with the output if ShowSize option set */
+			if(config->showsize) {
+				asprintf(&str, "%s-%s [%.2f MB]", alpm_pkg_get_name(pkg),
+						alpm_pkg_get_version(pkg), mbdispsize);
+			} else {
+				asprintf(&str, "%s-%s", alpm_pkg_get_name(pkg),
+						alpm_pkg_get_version(pkg));
+			}
 		}
 		targets = alpm_list_add(targets, str);
 	}
@@ -461,7 +579,18 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local)
 		printf("\n");
 	}
 
-	list_display(_("Targets:"), targets);
+	if(config->verboseupgradeinfo) {
+		/* create the format for the list */
+		asprintf(&format,"%%-%ds,%%-%ds,%%-%ds,%%%ds", lenpkgname+padding, 
+						lenpkgver+padding, lenoldpkgver+padding, lenpkgsize);
+		
+		columned_list_display(_("Targets:"),header,targets,format,',');
+		
+		free(format);
+	} else {
+		list_display(_("Targets:"), targets);
+	}
+	
 	printf("\n");
 
 	printf(_("Total Download Size:    %.2f MB\n"), mbdlsize);
diff --git a/src/pacman/util.h b/src/pacman/util.h
index 00c8894..4d15997 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -47,6 +47,7 @@ char *strtrim(char *str);
 char *strreplace(const char *str, const char *needle, const char *replace);
 alpm_list_t *strsplit(const char *str, const char splitchar);
 void string_display(const char *title, const char *string);
+void columned_list_display(const char *title, const char *header, const alpm_list_t *rows, const char *formatstring, const char delim);
 void list_display(const char *title, const alpm_list_t *list);
 void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local);
 int yesno(char *fmt, ...);
-- 
1.5.3.7

