--- coreutils-8.28/src/md5sum.c.color-sum 2017-09-11 20:26:42.685875412 +0300 +++ coreutils-8.28/src/md5sum.c 2017-09-11 20:34:11.893617587 +0300 @@ -20,6 +20,8 @@ #include <getopt.h> #include <sys/types.h> +#include <stdio.h> +#include <unistd.h> #include "system.h" #include "argmatch.h" @@ -193,7 +195,8 @@ enum STATUS_OPTION, QUIET_OPTION, STRICT_OPTION, - TAG_OPTION + TAG_OPTION, + COLOR_OPTION }; static struct option const long_options[] = @@ -207,6 +210,7 @@ static struct option const long_options[ { "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 }, @@ -215,6 +219,39 @@ static struct option const long_options[ { NULL, 0, NULL, 0 } }; +/* BEGIN COLOR */ + +#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); +} + +/* END COLOR */ + void usage (int status) { @@ -254,6 +291,9 @@ Print or check %s (%d-bit) checksums.\n\ 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\ @@ -858,6 +898,7 @@ main (int argc, char **argv) /* 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; @@ -982,6 +982,9 @@ main (int argc, char **argv) case 'z': delim = '\0'; break; + case COLOR_OPTION: + do_color = true; + break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: @@ -1069,8 +1113,33 @@ main (int argc, char **argv) if (!prefix_tag && needs_escape) putchar ('\\'); - for (size_t i = 0; i < (digest_hex_bytes / 2); ++i) - printf ("%02x", bin_buffer[i]); + size_t i, j, k; + + /* START COLOR */ + + 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]); + } + + /* FINISH COLOR */ if (!prefix_tag) {