[pacman-dev] [PATCH] Improve and colourize VerbosePkgList

Simon Gomizelj simongmzlj at gmail.com
Wed May 22 03:41:11 EDT 2013


Improve VerbosePkgList by caching attributes then and cell's length with
the cell's label instead of recalculating.

Right align every cell that containing a file size, not just the last
collumn.

Simplify printf statements and the alignment application.

Signed-off-by: Simon Gomizelj <simongmzlj at gmail.com>
---
 src/pacman/util.c | 135 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 75 insertions(+), 60 deletions(-)

diff --git a/src/pacman/util.c b/src/pacman/util.c
index 862c8e8..70a76b8 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -52,6 +52,18 @@ struct table_row_t {
 	int size;
 };
 
+struct verbose_cell_t {
+	char *label;
+	size_t len;
+	int mode;
+};
+
+enum {
+	CELL_NORMAL      = 0,
+	CELL_TITLE       = 1,
+	CELL_RIGHT_ALIGN = 1 << 2
+};
+
 int trans_init(alpm_transflag_t flags, int check_valid)
 {
 	int ret;
@@ -424,6 +436,35 @@ static size_t string_length(const char *s)
 	return len;
 }
 
+static void add_verbose_cell(alpm_list_t **row, char *label, int mode)
+{
+	struct verbose_cell_t *cell = malloc(sizeof(struct verbose_cell_t));
+
+	cell->label = label;
+	cell->mode = mode;
+	cell->len = string_length(label);
+
+	*row = alpm_list_add(*row, cell);
+}
+
+static void free_verbose_cell(void *ptr)
+{
+	struct verbose_cell_t *cell = ptr;
+
+	free(cell->label);
+	free(cell);
+}
+
+static void add_transaction_sizes_row(alpm_list_t **table, const char *label, int size)
+{
+	struct table_row_t *row = malloc(sizeof(struct table_row_t));
+
+	row->label = label;
+	row->size = size;
+
+	*table = alpm_list_add(*table, row);
+}
+
 void string_display(const char *title, const char *string, unsigned short cols)
 {
 	if(title) {
@@ -442,43 +483,30 @@ void string_display(const char *title, const char *string, unsigned short cols)
 static void table_print_line(const alpm_list_t *line, short col_padding,
 		size_t colcount, size_t *widths, int *has_data)
 {
-	size_t i, lastcol = 0;
+	size_t i;
 	int need_padding = 0;
 	const alpm_list_t *curcell;
 
-	for(i = colcount; i > 0; i--) {
-		if(has_data[i - 1]) {
-			lastcol = i - 1;
-			break;
-		}
-	}
-
 	for(i = 0, curcell = line; curcell && i < colcount;
 			i++, curcell = alpm_list_next(curcell)) {
-		const char *value;
+		const struct verbose_cell_t *cell = curcell->data;
+		const char *str = (cell->label ? cell->label : "");
 		int cell_padding;
 
 		if(!has_data[i]) {
 			continue;
 		}
 
-		value = curcell->data;
-		if(!value) {
-			value = "";
-		}
-		/* silly printf requires padding size to be an int */
-		cell_padding = (int)widths[i] - (int)string_length(value);
-		if(cell_padding < 0) {
-			cell_padding = 0;
-		}
+		cell_padding = (cell->mode & CELL_RIGHT_ALIGN ? (int)widths[i] : -(int)widths[i]);
+
 		if(need_padding) {
 			printf("%*s", col_padding, "");
 		}
-		/* left-align all but the last column */
-		if(i != lastcol) {
-			printf("%s%*s", value, cell_padding, "");
+
+		if(cell->mode & CELL_TITLE) {
+			printf("%s%*s%s", config->colstr.title, cell_padding, str, config->colstr.nocolor);
 		} else {
-			printf("%*s%s", cell_padding, "", value);
+			printf("%*s", cell_padding, str);
 		}
 		need_padding = 1;
 	}
@@ -487,7 +515,6 @@ static void table_print_line(const alpm_list_t *line, short col_padding,
 }
 
 
-
 /**
  * Find the max string width of each column. Also determines whether values
  * exist in the column and sets the value in has_data accordingly.
@@ -522,7 +549,8 @@ static size_t table_calc_widths(const alpm_list_t *header,
 	}
 	/* header determines column count and initial values of longest_strs */
 	for(i = header, curcol = 0; i; i = alpm_list_next(i), curcol++) {
-		colwidths[curcol] = string_length(i->data);
+		const struct verbose_cell_t *row = i->data;
+		colwidths[curcol] = row->len;
 		/* note: header does not determine whether column has data */
 	}
 
@@ -531,8 +559,8 @@ static size_t table_calc_widths(const alpm_list_t *header,
 		/* grab first column of each row and iterate through columns */
 		const alpm_list_t *j = i->data;
 		for(curcol = 0; j; j = alpm_list_next(j), curcol++) {
-			const char *str = j->data;
-			size_t str_len = string_length(str);
+			const struct verbose_cell_t *row = j->data;
+			size_t str_len = row ? row->len : 0;
 
 			if(str_len > colwidths[curcol]) {
 				colwidths[curcol] = str_len;
@@ -597,11 +625,10 @@ static int table_display(const char *title, const alpm_list_t *header,
 	}
 
 	if(title != NULL) {
-		printf("%s\n\n", title);
+		printf("%s%s%s\n\n", config->colstr.title, title, config->colstr.nocolor);
 	}
 
 	table_print_line(header, padding, totalcols, widths, has_data);
-	printf("\n");
 
 	for(i = rows; i; i = alpm_list_next(i)) {
 		table_print_line(i->data, padding, totalcols, widths, has_data);
@@ -761,21 +788,15 @@ void signature_display(const char *title, alpm_siglist_t *siglist,
 /* creates a header row for use with table_display */
 static alpm_list_t *create_verbose_header(void)
 {
-	alpm_list_t *res = NULL;
-	char *str;
+	alpm_list_t *ret = NULL;
 
-	str = _("Name");
-	res = alpm_list_add(res, str);
-	str = _("Old Version");
-	res = alpm_list_add(res, str);
-	str = _("New Version");
-	res = alpm_list_add(res, str);
-	str = _("Net Change");
-	res = alpm_list_add(res, str);
-	str = _("Download Size");
-	res = alpm_list_add(res, str);
-
-	return res;
+	add_verbose_cell(&ret, _("Name"), CELL_TITLE);
+	add_verbose_cell(&ret, _("Old Version"), CELL_TITLE);
+	add_verbose_cell(&ret, _("New Version"), CELL_TITLE);
+	add_verbose_cell(&ret, _("Net Change"), CELL_TITLE);
+	add_verbose_cell(&ret, _("Download Size"), CELL_TITLE);
+
+	return ret;
 }
 
 /* returns package info as list of strings */
@@ -798,23 +819,23 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
 	} else {
 		pm_asprintf(&str, "%s", alpm_pkg_get_name(target->remove));
 	}
-	ret = alpm_list_add(ret, str);
+	add_verbose_cell(&ret, str, CELL_NORMAL);
 
 	/* old and new versions */
 	pm_asprintf(&str, "%s",
 			target->remove != NULL ? alpm_pkg_get_version(target->remove) : "");
-	ret = alpm_list_add(ret, str);
+	add_verbose_cell(&ret, str, CELL_NORMAL);
 
 	pm_asprintf(&str, "%s",
 			target->install != NULL ? alpm_pkg_get_version(target->install) : "");
-	ret = alpm_list_add(ret, str);
+	add_verbose_cell(&ret, str, CELL_NORMAL);
 
 	/* and size */
 	size -= target->remove ? alpm_pkg_get_isize(target->remove) : 0;
 	size += target->install ? alpm_pkg_get_isize(target->install) : 0;
 	human_size = humanize_size(size, 'M', 2, &label);
 	pm_asprintf(&str, "%.2f %s", human_size, label);
-	ret = alpm_list_add(ret, str);
+	add_verbose_cell(&ret, str, CELL_RIGHT_ALIGN);
 
 	size = target->install ? alpm_pkg_download_size(target->install) : 0;
 	if(size != 0) {
@@ -823,21 +844,11 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
 	} else {
 		str = NULL;
 	}
-	ret = alpm_list_add(ret, str);
+	add_verbose_cell(&ret, str, CELL_RIGHT_ALIGN);
 
 	return ret;
 }
 
-static void add_transaction_sizes_row(alpm_list_t **table, const char *label, int size)
-{
-	struct table_row_t *row = malloc(sizeof(struct table_row_t));
-
-	row->label = label;
-	row->size = size;
-
-	*table = alpm_list_add(*table, row);
-}
-
 static void display_transaction_sizes(alpm_list_t *table)
 {
 	alpm_list_t *i;
@@ -894,7 +905,10 @@ static void _display_targets(alpm_list_t *targets, int verbose)
 	for(i = targets; i; i = alpm_list_next(i)) {
 		pm_target_t *target = i->data;
 
-		rows = alpm_list_add(rows, create_verbose_row(target));
+		if(verbose) {
+			rows = alpm_list_add(rows, create_verbose_row(target));
+		}
+
 		if(target->install) {
 			pm_asprintf(&str, "%s-%s", alpm_pkg_get_name(target->install),
 					alpm_pkg_get_version(target->install));
@@ -927,8 +941,9 @@ static void _display_targets(alpm_list_t *targets, int verbose)
 
 	/* rows is a list of lists of strings, free inner lists here */
 	for(i = rows; i; i = alpm_list_next(i)) {
-		alpm_list_t *lp = i->data;
-		FREELIST(lp);
+		if(i->data) {
+			alpm_list_free_inner(i->data, free_verbose_cell);
+		}
 	}
 	alpm_list_free(rows);
 	FREELIST(names);
-- 
1.8.2.3



More information about the pacman-dev mailing list