[pacman-dev] [PATCH] Highlight changed part of new version numbers to let users easily distiguish between major, minor, bugfix and internal updates

Lars Øyvind Hagland larsoc at gmail.com
Sun Jul 12 22:31:34 UTC 2020


Signed-off-by: Lars Øyvind Hagland <larsoc at gmail.com>
---
 src/pacman/util.c | 55 ++++++++++++++++++++++++++++++++++++++++++-----
 src/pacman/util.h |  2 ++
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/src/pacman/util.c b/src/pacman/util.c
index e9187529..d3c89ecb 100644
--- a/src/pacman/util.c
+++ b/src/pacman/util.c
@@ -531,7 +531,12 @@ static void table_print_line(const alpm_list_t *line, short col_padding,
 		if(cell->mode & CELL_TITLE) {
 			printf("%s%*s%s", config->colstr.title, cell_width, str, config->colstr.nocolor);
 		} else {
-			printf("%*s", cell_width, str);
+			// printf includes ANSI control chars in width, pad manually with actual width
+			if (cell_width > 0) {
+				printf("%*s%s", cell_width - (int)cell->len, "", str);
+			} else {
+				printf("%s%*s", str, -cell_width - (int)cell->len, "");
+			}
 		}
 		need_padding = 1;
 	}
@@ -860,8 +865,10 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
 			target->remove != NULL ? alpm_pkg_get_version(target->remove) : "");
 	add_table_cell(&ret, str, CELL_NORMAL | CELL_FREE);
 
-	pm_asprintf(&str, "%s",
-			target->install != NULL ? alpm_pkg_get_version(target->install) : "");
+	str = version_colorize_diff(
+			target->install ? alpm_pkg_get_version(target->install) : "",
+			target->remove ? alpm_pkg_get_version(target->remove) : "",
+			config->colstr.title);
 	add_table_cell(&ret, str, CELL_NORMAL | CELL_FREE);
 
 	/* and size */
@@ -886,7 +893,7 @@ static alpm_list_t *create_verbose_row(pm_target_t *target)
 /* prepare a list of pkgs to display */
 static void _display_targets(alpm_list_t *targets, int verbose)
 {
-	char *str;
+	char *str, *version;
 	off_t isize = 0, rsize = 0, dlsize = 0;
 	unsigned short cols;
 	alpm_list_t *i, *names = NULL, *header = NULL, *rows = NULL;
@@ -918,8 +925,12 @@ static void _display_targets(alpm_list_t *targets, int verbose)
 		}
 
 		if(target->install) {
+			version = version_colorize_diff(alpm_pkg_get_version(target->install),
+					target->remove ? alpm_pkg_get_version(target->remove) : "",
+					config->colstr.nocolor);
 			pm_asprintf(&str, "%s%s-%s%s", alpm_pkg_get_name(target->install), config->colstr.faint,
-					alpm_pkg_get_version(target->install), config->colstr.nocolor);
+					version, config->colstr.nocolor);
+			free(version);
 		} else if(isize == 0) {
 			pm_asprintf(&str, "%s%s-%s%s", alpm_pkg_get_name(target->remove), config->colstr.faint,
 					alpm_pkg_get_version(target->remove), config->colstr.nocolor);
@@ -1676,6 +1687,40 @@ int colon_printf(const char *fmt, ...)
 	return ret;
 }
 
+/** Highlight the changed part of the version string
+ *
+ * Inserts an ANSI color tag before the first changed version part and a
+ * no-color tag at the end.
+ *
+ * @param version The new version string
+ * @param old_version The old version string
+ * @param color The color of the highlighted part
+ * @return Pointer to the new string
+ */
+char *version_colorize_diff(const char *version, const char *old_version, const char *color)
+{
+	char *ret;
+	char start[strlen(version)], end[strlen(version)];
+	unsigned long pos = 0;
+
+	while ((pos < strlen(version))
+			&& (pos < strlen(old_version))
+			&& (version[pos] == old_version[pos]))
+		pos++;
+	while (pos > 0
+			&& version[pos] != '.'
+			&& version[pos] != '-')
+		pos--;
+	if (pos != 0)
+		pos++;
+
+	strncpy(start, version, pos);
+	start[pos] = '\0';	// strncpy does not add delimiter
+	strcpy(end, &version[pos]);
+	pm_asprintf(&ret, "%s%s%s%s", start, color, end, config->colstr.nocolor);
+	return ret;
+}
+
 int pm_printf(alpm_loglevel_t level, const char *format, ...)
 {
 	int ret;
diff --git a/src/pacman/util.h b/src/pacman/util.h
index c97048fb..7597da40 100644
--- a/src/pacman/util.h
+++ b/src/pacman/util.h
@@ -81,6 +81,8 @@ int yesno(const char *format, ...) __attribute__((format(printf, 1, 2)));
 int noyes(const char *format, ...) __attribute__((format(printf, 1, 2)));
 char *arg_to_string(int argc, char *argv[]);
 char *safe_fgets_stdin(char *s, int size);
+char *version_colorize_diff(const char *version, const char *old_version, const char *color);
+
 void console_cursor_hide(void);
 void console_cursor_show(void);
 void console_cursor_move_up(unsigned int lines);
-- 
2.27.0


More information about the pacman-dev mailing list