Signed-off-by: Lars Øyvind Hagland
---
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 cha