From: Florent Monnier Date: Tue, 24 Dec 2013 12:33:36 +0100 Subject: add --color option to md5sum and shaXsum * add --color option to md5sum and shaXsum takes action only if stdout is a tty. diff -Naur coreutils-8.22/src/md5sum.c coreutils-8.22-sum-color/src/md5sum.c --- coreutils-8.22/src/md5sum.c 2013-12-04 15:48:30.000000000 +0100 +++ coreutils-8.22-sum-color/src/md5sum.c 2013-12-24 13:02:42.593519641 +0100 @@ -20,6 +20,8 @@ #include #include +#include +#include #include "system.h" @@ -136,7 +138,8 @@ STATUS_OPTION = CHAR_MAX + 1, QUIET_OPTION, STRICT_OPTION, - TAG_OPTION + TAG_OPTION, + COLOR_OPTION }; static struct option const long_options[] = @@ -146,6 +149,7 @@ { "quiet", no_argument, NULL, QUIET_OPTION }, { "status", no_argument, NULL, STATUS_OPTION }, { "text", no_argument, NULL, 't' }, + { "color", no_argument, NULL, COLOR_OPTION }, { "warn", no_argument, NULL, 'w' }, { "strict", no_argument, NULL, STRICT_OPTION }, { "tag", no_argument, NULL, TAG_OPTION }, @@ -154,6 +158,35 @@ { NULL, 0, NULL, 0 } }; +#define CODCOL_BRIGHT "0" + +struct color { + int r; + int g; + int b; + const char *code; +}; + +static struct color const colors[] = +{ + {255, 0, 0, "31"}, + { 0, 255, 0, "32"}, + {255, 255, 0, "33"}, + { 0, 0, 255, "34"}, + {255, 0, 255, "35"}, + { 0, 255, 255, "36"}, +}; + +unsigned int square_dist( + const struct color *c1, + const struct color *c2) +{ + int xd = c2->r - c1->r; + int yd = c2->g - c1->g; + int zd = c2->b - c1->b; + return (xd * xd + yd * yd + zd * zd); +} + void usage (int status) { @@ -184,6 +217,9 @@ fputs (_("\ --tag create a BSD-style checksum\n\ "), stdout); + fputs (_("\ + --color print with colors\n\ +"), stdout); if (O_BINARY) fputs (_("\ -t, --text read in text mode (default if reading tty stdin)\n\ @@ -693,6 +729,7 @@ /* Make sure bin_buffer is properly aligned. */ unsigned char *bin_buffer = ptr_align (bin_buffer_unaligned, DIGEST_ALIGN); bool do_check = false; + bool do_color = false; int opt; bool ok = true; int binary = -1; @@ -745,6 +782,9 @@ prefix_tag = true; binary = 1; break; + case COLOR_OPTION: + do_color = true; + break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: @@ -847,15 +887,34 @@ fputs (") = ", stdout); } - size_t i; + size_t i, j, k; /* Output a leading backslash if the file name contains a newline or backslash. */ if (!prefix_tag && needs_escape) putchar ('\\'); - for (i = 0; i < (digest_hex_bytes / 2); ++i) - printf ("%02x", bin_buffer[i]); + if (!do_color || !isatty (fileno(stdout))) { + for (i = 0; i < (digest_hex_bytes / 2); ++i) + printf ("%02x", bin_buffer[i]); + } else { + for (i = 0, j = 0; i < (digest_hex_bytes / (2*3)); ++i) { + struct color c; + unsigned int m, n, col; + c.r = bin_buffer[j++]; + c.g = bin_buffer[j++]; + c.b = bin_buffer[j++]; + for (k = 0, n = 0, m = 195076; k < 6; ++k) { + unsigned int n = square_dist(&colors[k], &c); + if (n < m) { m = n; col = k; } + } + printf ("\x1B[%s;1m%02x%02x%02x\x1B[0m", + colors[col].code, c.r, c.g, c.b); + } + for (; j < (digest_hex_bytes / 2); ++j) + printf ("\x1B[%s;1m%02x\x1B[0m", + CODCOL_BRIGHT, bin_buffer[j]); + } if (!prefix_tag) {