From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 08 Mar 2015 21:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org X-Debbugs-Original-To: bug-diffutils@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.142585181622228 (code B ref -1); Sun, 08 Mar 2015 21:57:02 +0000 Received: (at submit) by debbugs.gnu.org; 8 Mar 2015 21:56:56 +0000 Received: from localhost ([127.0.0.1]:39826 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YUjBv-0005mR-1l for submit@debbugs.gnu.org; Sun, 08 Mar 2015 17:56:55 -0400 Received: from eggs.gnu.org ([208.118.235.92]:51087) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YUjBs-0005mB-6u for submit@debbugs.gnu.org; Sun, 08 Mar 2015 17:56:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YUjBk-0006Su-V8 for submit@debbugs.gnu.org; Sun, 08 Mar 2015 17:56:46 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50 autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:46465) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUjBk-0006Sp-Rw for submit@debbugs.gnu.org; Sun, 08 Mar 2015 17:56:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52797) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUjBi-0001su-VK for bug-diffutils@gnu.org; Sun, 08 Mar 2015 17:56:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YUjBf-0006RF-NO for bug-diffutils@gnu.org; Sun, 08 Mar 2015 17:56:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46754) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YUjBf-0006RA-FO for bug-diffutils@gnu.org; Sun, 08 Mar 2015 17:56:39 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t28LucA7030153 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Sun, 8 Mar 2015 17:56:38 -0400 Received: from localhost.localdomain (vpn1-7-152.ams2.redhat.com [10.36.7.152]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t28LuaYN026868 for ; Sun, 8 Mar 2015 17:56:37 -0400 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:56:31 +0100 Message-Id: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors): New enum to register the current color to use. (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c (specify_colors_style): New function. (BINARY_OPTION): Add COLOR_OPTION. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (check_color_output): New function. (begin_output): Call check_color_output every time the output file is changed. (set_color_context): New function. If colors are enabled, print the right command for the terminal to change the color. --- I got so used to having colors in git diff that I become unable to quickly spot differences in the plain diff output. This patch fills the gap between the two versions. doc/diffutils.texi | 22 ++++++++++++++++++++++ src/context.c | 4 ++++ src/diff.c | 27 ++++++++++++++++++++++++++- src/diff.h | 30 ++++++++++++++++++++++++++++++ src/normal.c | 16 ++++++++++++---- src/side.c | 15 +++++++++++++++ src/util.c | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 145 insertions(+), 5 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..bc7169a 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,28 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +- Do not use color at all. This is the default. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +- Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +- Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=always}. +Piping a colorized listing through a pager like @command{more} or +@command{less} usually produces unreadable results. However, using +@code{more -f} does seem to work. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..88ddfde 100644 --- a/src/context.c +++ b/src/context.c @@ -366,10 +366,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* Then output the inserted part. */ @@ -378,10 +380,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index ff28377..7d14877 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'auto',"), + N_(" or 'always' (the default); more info below"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else if (STREQ (value, "auto")) + colors_style = AUTO; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..cad961b 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,32 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors +{ + /* Reset to the default color. */ + RESET, + + /* Delete lines. Show output in red. */ + DELETE, + + /* Added lines. Show them in green. */ + ADD, +}; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +109,9 @@ enum output_style XTERN enum output_style output_style; +/* True if colors are printed. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +419,4 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_color_context (enum colors); diff --git a/src/normal.c b/src/normal.c index 721fd1a..c5211cb 100644 --- a/src/normal.c +++ b/src/normal.c @@ -56,14 +56,22 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_color_context (DELETE); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_color_context (ADD); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET); + } } diff --git a/src/side.c b/src/side.c index 155512c..e52454e 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..3687b5e 100644 --- a/src/util.c +++ b/src/util.c @@ -153,6 +153,17 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (void) +{ + if (! outfile) + return; + + colors_enabled = (colors_style == ALWAYS) + || (colors_style == AUTO && isatty (fileno (outfile))); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +324,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +332,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (); free (command); #endif } @@ -330,6 +343,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +731,28 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +void +set_color_context (enum colors con) +{ + if (! colors_enabled) + return; + + switch (con) + { + case DELETE: + fprintf (outfile, "\x1B[31m"); + break; + + case ADD: + fprintf (outfile, "\x1B[32m"); + break; + + case RESET: + fprintf(outfile, "\x1b[0m"); + break; + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 09 Mar 2015 14:52:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142591266815168 (code B ref 20062); Mon, 09 Mar 2015 14:52:02 +0000 Received: (at 20062) by debbugs.gnu.org; 9 Mar 2015 14:51:08 +0000 Received: from localhost ([127.0.0.1]:40831 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YUz1P-0003wa-Sv for submit@debbugs.gnu.org; Mon, 09 Mar 2015 10:51:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49280) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YUz1N-0003wC-Bw for 20062@debbugs.gnu.org; Mon, 09 Mar 2015 10:51:06 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t29Ep0ZU004525 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for <20062@debbugs.gnu.org>; Mon, 9 Mar 2015 10:51:01 -0400 Received: from [10.3.113.117] (ovpn-113-117.phx2.redhat.com [10.3.113.117]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t29Ep0gi025256; Mon, 9 Mar 2015 10:51:00 -0400 Message-ID: <54FDB353.8060801@redhat.com> Date: Mon, 09 Mar 2015 08:50:59 -0600 From: Eric Blake Organization: Red Hat, Inc. User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> In-Reply-To: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> OpenPGP: url=http://people.redhat.com/eblake/eblake.gpg Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="qamsl7gvFmNFeHBP2D8AlGSJC4LM3LSt3" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --qamsl7gvFmNFeHBP2D8AlGSJC4LM3LSt3 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 03/08/2015 03:56 PM, Giuseppe Scrivano wrote: > * doc/diffutils.texi (diff Options): Add documentation for --color. > Copied from coreutils ls --color. Cool! > +@item --color [=3D@var{when}] > +@cindex color, distinguishing file types with > +Specify whether to use color for distinguishing file types. @var{when= } > +may be omitted, or one of: > +@itemize @bullet > +@item none > +@vindex none @r{color option} > +- Do not use color at all. This is the default. At first, I was worried that this meant that '--color' =3D=3D '--color=3Dnone'; so maybe you want this to read "This is the default whe= n no --color option is present" > +@item auto > +@vindex auto @r{color option} > +@cindex terminal, using color iff > +- Only use color if standard output is a terminal. > +@item always > +@vindex always @r{color option} > +- Always use color. > +@end itemize > +Specifying @option{--color} and no @var{when} is equivalent to > +@option{--color=3Dalways}. Is this the right default? Some GNU programs default --color to --color=3Dauto; others to --color=3Dalways. I'm 50:50 on which default i= s better, but it's worth thinking about rather than just blindly picking one, as we have both GNU styles as precedent. --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --qamsl7gvFmNFeHBP2D8AlGSJC4LM3LSt3 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJU/bNTAAoJEKeha0olJ0NqhiwH/0ePqTyuvASiwCNjQhbeZmzF +7DMxkAiKW0IMXABzatM1eAY5YGTyk41L72uipYpPrS4zVyMP54JABaSHmXbi8Hr REvyQ59jRkUMzqyjPMNQba5WdEThb0Fm3Mybo5HANqo6wgCTNfrRsBFbHPl6xLvo JaQBG661RDxtRGFk7hsOkPABM+l4uUA+lfs9DoNEST2SuP59nmZqOVJT3Ic5Ip/t S54afWjSFIQkbloVPWYEZJvLqz51NFKEB9eyK3QfWlcUYdO8oWiXGdVeFPaLHvUp 7WjiXZsusKtYZKe0yMPIMvb+XfKVKtTMIEshE3vuSYUrkwRl6F8fcpjpiFPQGi8= =W1q4 -----END PGP SIGNATURE----- --qamsl7gvFmNFeHBP2D8AlGSJC4LM3LSt3-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 09 Mar 2015 21:23:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142593612526543 (code B ref 20062); Mon, 09 Mar 2015 21:23:02 +0000 Received: (at 20062) by debbugs.gnu.org; 9 Mar 2015 21:22:05 +0000 Received: from localhost ([127.0.0.1]:40975 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YV57k-0006u3-Ko for submit@debbugs.gnu.org; Mon, 09 Mar 2015 17:22:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58597) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YV57i-0006tg-R7 for 20062@debbugs.gnu.org; Mon, 09 Mar 2015 17:22:03 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t29LLx2t010736 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for <20062@debbugs.gnu.org>; Mon, 9 Mar 2015 17:22:00 -0400 Received: from foobarbaz (vpn1-4-214.ams2.redhat.com [10.36.4.214]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t29LLu2d014993 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 9 Mar 2015 17:21:58 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> Date: Mon, 09 Mar 2015 22:21:55 +0100 In-Reply-To: <54FDB353.8060801@redhat.com> (Eric Blake's message of "Mon, 09 Mar 2015 08:50:59 -0600") Message-ID: <87fv9dj28c.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Eric Blake writes: >> +@item auto >> +@vindex auto @r{color option} >> +@cindex terminal, using color iff >> +- Only use color if standard output is a terminal. >> +@item always >> +@vindex always @r{color option} >> +- Always use color. >> +@end itemize >> +Specifying @option{--color} and no @var{when} is equivalent to >> +@option{--color=always}. > > Is this the right default? Some GNU programs default --color to > --color=auto; others to --color=always. I'm 50:50 on which default is > better, but it's worth thinking about rather than just blindly picking > one, as we have both GNU styles as precedent. I thought about it as well, and then I decided to go for the same default as ls but I still believe that auto would be a better one. If it is fine for everyone, I can rework the patch and change the default to auto. Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 10 Mar 2015 10:12:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142598226222690 (code B ref 20062); Tue, 10 Mar 2015 10:12:01 +0000 Received: (at 20062) by debbugs.gnu.org; 10 Mar 2015 10:11:02 +0000 Received: from localhost ([127.0.0.1]:41190 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVH7t-0005ta-6h for submit@debbugs.gnu.org; Tue, 10 Mar 2015 06:11:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47894) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVH7q-0005tO-J6 for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 06:11:00 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2AAAuWf001427 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for <20062@debbugs.gnu.org>; Tue, 10 Mar 2015 06:10:56 -0400 Received: from foobarbaz (vpn1-7-177.ams2.redhat.com [10.36.7.177]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2AAAq6W028502 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Tue, 10 Mar 2015 06:10:54 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> Date: Tue, 10 Mar 2015 11:10:51 +0100 In-Reply-To: <87fv9dj28c.fsf@redhat.com> (Giuseppe Scrivano's message of "Mon, 09 Mar 2015 22:21:55 +0100") Message-ID: <874mptgo2c.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Giuseppe Scrivano writes: > Eric Blake writes: > >>> +@item auto >>> +@vindex auto @r{color option} >>> +@cindex terminal, using color iff >>> +- Only use color if standard output is a terminal. >>> +@item always >>> +@vindex always @r{color option} >>> +- Always use color. >>> +@end itemize >>> +Specifying @option{--color} and no @var{when} is equivalent to >>> +@option{--color=always}. >> >> Is this the right default? Some GNU programs default --color to >> --color=auto; others to --color=always. I'm 50:50 on which default is >> better, but it's worth thinking about rather than just blindly picking >> one, as we have both GNU styles as precedent. > > I thought about it as well, and then I decided to go for the same > default as ls but I still believe that auto would be a better one. > > If it is fine for everyone, I can rework the patch and change the > default to auto. This new version changes the default for --color to auto: >From 7c8c9a6258eb37e6d5832362309fef1906f9a939 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors): New enum to register the current color to use. (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c (specify_colors_style): New function. (BINARY_OPTION): Add COLOR_OPTION. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (check_color_output): New function. (begin_output): Call check_color_output every time the output file is changed. (set_color_context): New function. If colors are enabled, print the right command for the terminal to change the color. --- doc/diffutils.texi | 23 +++++++++++++++++++++++ src/context.c | 4 ++++ src/diff.c | 27 ++++++++++++++++++++++++++- src/diff.h | 30 ++++++++++++++++++++++++++++++ src/normal.c | 16 ++++++++++++---- src/side.c | 15 +++++++++++++++ src/util.c | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 146 insertions(+), 5 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..f5e1804 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,29 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +- Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +- Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +- Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. +Piping a colorized listing through a pager like @command{more} or +@command{less} usually produces unreadable results. However, using +@code{more -f} does seem to work. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..88ddfde 100644 --- a/src/context.c +++ b/src/context.c @@ -366,10 +366,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* Then output the inserted part. */ @@ -378,10 +380,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index ff28377..5874646 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..cad961b 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,32 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors +{ + /* Reset to the default color. */ + RESET, + + /* Delete lines. Show output in red. */ + DELETE, + + /* Added lines. Show them in green. */ + ADD, +}; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +109,9 @@ enum output_style XTERN enum output_style output_style; +/* True if colors are printed. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +419,4 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_color_context (enum colors); diff --git a/src/normal.c b/src/normal.c index 721fd1a..c5211cb 100644 --- a/src/normal.c +++ b/src/normal.c @@ -56,14 +56,22 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_color_context (DELETE); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_color_context (ADD); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET); + } } diff --git a/src/side.c b/src/side.c index 155512c..e52454e 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..3687b5e 100644 --- a/src/util.c +++ b/src/util.c @@ -153,6 +153,17 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (void) +{ + if (! outfile) + return; + + colors_enabled = (colors_style == ALWAYS) + || (colors_style == AUTO && isatty (fileno (outfile))); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +324,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +332,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (); free (command); #endif } @@ -330,6 +343,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +731,28 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +void +set_color_context (enum colors con) +{ + if (! colors_enabled) + return; + + switch (con) + { + case DELETE: + fprintf (outfile, "\x1B[31m"); + break; + + case ADD: + fprintf (outfile, "\x1B[32m"); + break; + + case RESET: + fprintf(outfile, "\x1b[0m"); + break; + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 10 Mar 2015 16:23:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Eric Blake Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142600457313924 (code B ref 20062); Tue, 10 Mar 2015 16:23:02 +0000 Received: (at 20062) by debbugs.gnu.org; 10 Mar 2015 16:22:53 +0000 Received: from localhost ([127.0.0.1]:41865 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVMvh-0003cL-E4 for submit@debbugs.gnu.org; Tue, 10 Mar 2015 12:22:51 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:56173) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVMve-0003bz-6P for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 12:22:46 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 1A87DA6000C; Tue, 10 Mar 2015 09:22:40 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ID4ARNYzrTWW; Tue, 10 Mar 2015 09:22:39 -0700 (PDT) Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id E40B6A60007; Tue, 10 Mar 2015 09:22:39 -0700 (PDT) Message-ID: <54FF1A4C.6080104@cs.ucla.edu> Date: Tue, 10 Mar 2015 09:22:36 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> In-Reply-To: <874mptgo2c.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) What happens if I type Control-C while colored output is streaming by my terminal? Can it leave the terminal in a funny colored state? From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 10 Mar 2015 22:20:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142602598119357 (code B ref 20062); Tue, 10 Mar 2015 22:20:02 +0000 Received: (at 20062) by debbugs.gnu.org; 10 Mar 2015 22:19:41 +0000 Received: from localhost ([127.0.0.1]:42010 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVSV2-000528-SG for submit@debbugs.gnu.org; Tue, 10 Mar 2015 18:19:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53456) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVSV0-00051z-8j for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 18:19:39 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2AMJUUB025349 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Mar 2015 18:19:30 -0400 Received: from foobarbaz (vpn1-7-177.ams2.redhat.com [10.36.7.177]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2AMJQ6F019268 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Tue, 10 Mar 2015 18:19:28 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> Date: Tue, 10 Mar 2015 23:19:26 +0100 In-Reply-To: <54FF1A4C.6080104@cs.ucla.edu> (Paul Eggert's message of "Tue, 10 Mar 2015 09:22:36 -0700") Message-ID: <87k2yoebrl.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > What happens if I type Control-C while colored output is streaming by > my terminal? Can it leave the terminal in a funny colored state? No, the Control-C would leave the terminal in a funny state. Thanks to have pointed it out, I completely missed the ls.c code that handles that. What about amending the previous version with the patch below? Regards, Giuseppe diff --git a/src/util.c b/src/util.c index 3687b5e..5b28a07 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -731,24 +732,56 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +static sigset_t old_sigproc_set; void set_color_context (enum colors con) { + int j; + sigset_t set; + static int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + if (! colors_enabled) return; + sigemptyset (&set); + for (j = 0; j < (sizeof (sig) / sizeof (*sig)); j++) + sigaddset (&set, sig[j]); + switch (con) { case DELETE: + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); fprintf (outfile, "\x1B[31m"); break; case ADD: + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); fprintf (outfile, "\x1B[32m"); break; case RESET: - fprintf(outfile, "\x1b[0m"); + fprintf (outfile, "\x1b[0m"); + fflush (outfile); + sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL); break; } } From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 10 Mar 2015 23:00:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142602836828943 (code B ref 20062); Tue, 10 Mar 2015 23:00:03 +0000 Received: (at 20062) by debbugs.gnu.org; 10 Mar 2015 22:59:28 +0000 Received: from localhost ([127.0.0.1]:42020 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVT7X-0007Wl-K1 for submit@debbugs.gnu.org; Tue, 10 Mar 2015 18:59:28 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:47842) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVT7V-0007WW-Et for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 18:59:26 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 064F9A60018; Tue, 10 Mar 2015 15:59:19 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id F-p5+bXJ+hY2; Tue, 10 Mar 2015 15:59:18 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id A2511A60007; Tue, 10 Mar 2015 15:59:18 -0700 (PDT) Message-ID: <54FF7742.6050500@cs.ucla.edu> Date: Tue, 10 Mar 2015 15:59:14 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> In-Reply-To: <87k2yoebrl.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > + sigemptyset (&set); > + for (j = 0; j < (sizeof (sig) / sizeof (*sig)); j++) > + sigaddset (&set, sig[j]); Shouldn't the above part be done just once? Also, it has redundant parentheses. > + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); The sigprocmask module needs to be added to bootstrap.conf. Can the proposed implementation block signals for an unbounded amount of time? That would be bad. ls.c attempts to avoid this problem, and 'diff' should too. Also, 'diff --color' needn't mess with signal handling unless isatty (fileno (outfile)). Also, surely --color is incompatible with --paginate, in the sense that signals arriving while paginating will put outfile into a weird state if outfile is a tty, so I expect that combination of options should be rejected. > What about amending the previous version with the patch below? Yes, we do need the patch to be amended something along these lines. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 10 Mar 2015 23:45:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14260310461303 (code B ref 20062); Tue, 10 Mar 2015 23:45:04 +0000 Received: (at 20062) by debbugs.gnu.org; 10 Mar 2015 23:44:06 +0000 Received: from localhost ([127.0.0.1]:42034 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVToj-0000Kw-UQ for submit@debbugs.gnu.org; Tue, 10 Mar 2015 19:44:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59629) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVToh-0000KX-Fu for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 19:44:04 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2ANi1ZJ013360 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Tue, 10 Mar 2015 19:44:01 -0400 Received: from foobarbaz (vpn1-7-177.ams2.redhat.com [10.36.7.177]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2ANhvbG018974 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Tue, 10 Mar 2015 19:43:59 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> Date: Wed, 11 Mar 2015 00:43:57 +0100 In-Reply-To: <54FF7742.6050500@cs.ucla.edu> (Paul Eggert's message of "Tue, 10 Mar 2015 15:59:14 -0700") Message-ID: <87egowctaa.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Giuseppe Scrivano wrote: > >> + sigemptyset (&set); >> + for (j = 0; j < (sizeof (sig) / sizeof (*sig)); j++) >> + sigaddset (&set, sig[j]); > > Shouldn't the above part be done just once? Also, it has redundant parentheses. > >> + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); > > The sigprocmask module needs to be added to bootstrap.conf. > > Can the proposed implementation block signals for an unbounded amount > of time? That would be bad. ls.c attempts to avoid this problem, and > 'diff' should too. The change of color context is done per line (except in normal.c where at the moment it is per hunk but I will change it to be per line) so the most it can hang is the time needed to print a single line. > Also, 'diff --color' needn't mess with signal handling unless isatty > (fileno (outfile)). Should this also be done if --color=always is used? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 11 Mar 2015 00:07:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14260324093747 (code B ref 20062); Wed, 11 Mar 2015 00:07:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Mar 2015 00:06:49 +0000 Received: from localhost ([127.0.0.1]:42042 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVUAj-0000yM-8k for submit@debbugs.gnu.org; Tue, 10 Mar 2015 20:06:49 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:50870) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVUAh-0000y8-55 for 20062@debbugs.gnu.org; Tue, 10 Mar 2015 20:06:47 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 2CC3EA60018; Tue, 10 Mar 2015 17:06:41 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id z9FIEP4+P6Sy; Tue, 10 Mar 2015 17:06:41 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id DC685A60007; Tue, 10 Mar 2015 17:06:40 -0700 (PDT) Message-ID: <54FF870C.5000902@cs.ucla.edu> Date: Tue, 10 Mar 2015 17:06:36 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> In-Reply-To: <87egowctaa.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > the > most it can hang is the time needed to print a single line. There's no limit on line length though, right? Other than available memory. So this could be a problem. ('ls' doesn't have a similar problem, if I understand it correctly, as OSes typically have reasonably short limits on file name length.) >> >Also, 'diff --color' needn't mess with signal handling unless isatty >> >(fileno (outfile)). > Should this also be done if --color=always is used? Yes. diff needs to mess with signal handling only if both (1) diff is outputting colors and (2) the output is a terminal. This is independent of why diff is doing (1). From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 11 Mar 2015 20:29:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142610571016782 (code B ref 20062); Wed, 11 Mar 2015 20:29:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Mar 2015 20:28:30 +0000 Received: from localhost ([127.0.0.1]:43172 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVnEy-0004MU-Vs for submit@debbugs.gnu.org; Wed, 11 Mar 2015 16:28:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47398) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVnEv-0004MH-Iw for 20062@debbugs.gnu.org; Wed, 11 Mar 2015 16:28:27 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2BKSMfD025864 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 11 Mar 2015 16:28:23 -0400 Received: from foobarbaz (vpn1-5-126.ams2.redhat.com [10.36.5.126]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2BJwFe9002165 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Wed, 11 Mar 2015 15:58:17 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> Date: Wed, 11 Mar 2015 20:58:15 +0100 In-Reply-To: <54FF870C.5000902@cs.ucla.edu> (Paul Eggert's message of "Tue, 10 Mar 2015 17:06:36 -0700") Message-ID: <878uf3b92g.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > There's no limit on line length though, right? Other than available > memory. So this could be a problem. ('ls' doesn't have a similar > problem, if I understand it correctly, as OSes typically have > reasonably short limits on file name length.) > >>> >Also, 'diff --color' needn't mess with signal handling unless isatty >>> >(fileno (outfile)). >> Should this also be done if --color=always is used? > > Yes. diff needs to mess with signal handling only if both (1) diff is > outputting colors and (2) the output is a terminal. This is > independent of why diff is doing (1). ok, thanks for the explanation. I've addressed your comments in the version below. Now I make sure that we don't write more than "max_chunk" bytes in output_1_line and unblock/block the signals. Regards, Giuseppe >From 41b868be5adb8c3de2c57c235693d1f2ec426b12 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * bootstrap.conf (gnulib_modules): Add "sigprocmask". * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors): New enum to register the current color to use. (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (colors_enabled): New boolean variable. (check_color_output): New function. (begin_output): Call check_color_output every time the output file is changed. (set_color_context): New function. If colors are enabled, print the right command for the terminal to change the color. --- bootstrap.conf | 1 + doc/diffutils.texi | 20 +++++++++ src/context.c | 4 ++ src/diff.c | 30 +++++++++++++- src/diff.h | 34 +++++++++++++++ src/normal.c | 20 +++++++-- src/side.c | 15 +++++++ src/util.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 8 files changed, 234 insertions(+), 10 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 9b2de22..63be732 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -61,6 +61,7 @@ readme-release regex sh-quote signal +sigprocmask stat stat-macros stat-time diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..92a7243 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,26 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +- Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +- Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +- Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..88ddfde 100644 --- a/src/context.c +++ b/src/context.c @@ -366,10 +366,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* Then output the inserted part. */ @@ -378,10 +380,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index ff28377..07fcb57 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -645,6 +653,9 @@ main (int argc, char **argv) specify_style (OUTPUT_NORMAL); } + if (colors_style != NEVER && paginate) + error (EXIT_TROUBLE, 0, _("Cannot specify both --color and --paginate.")); + if (output_style != OUTPUT_CONTEXT || hard_locale (LC_TIME)) { #if (defined STAT_TIMESPEC || defined STAT_TIMESPEC_NS \ @@ -940,6 +951,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1021,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..0291fdd 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,36 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors +{ + /* Reset to the default color. */ + RESET, + + /* Delete lines. Show output in red. */ + DELETE, + + /* Added lines. Show them in green. */ + ADD, + + /* Does not modify the context. Use it to periodically process pending + signals. */ + SAME, +}; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +113,9 @@ enum output_style XTERN enum output_style output_style; +/* True if colors are printed. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +423,4 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_color_context (enum colors); diff --git a/src/normal.c b/src/normal.c index 721fd1a..0d53033 100644 --- a/src/normal.c +++ b/src/normal.c @@ -56,14 +56,26 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + for (i = first0; i <= last0; i++) + { + set_color_context (DELETE); + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET); + } + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + for (i = first1; i <= last1; i++) + { + set_color_context (ADD); + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET); + } + } } diff --git a/src/side.c b/src/side.c index 155512c..e52454e 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..dcb3a59 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -153,6 +154,20 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (void) +{ + if (! outfile) + return; + + output_is_tty = isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS) + || (colors_style == AUTO && output_is_tty); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +328,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +336,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (); free (command); #endif } @@ -330,6 +347,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +690,20 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + /* Try to avoid to block for too long and write more than MAX_CHUNK bytes before + checking for pending signals. */ + const size_t max_chunk = 4096; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t len = MIN (left, max_chunk); + fwrite (base, sizeof (char), len, outfile); + set_color_context (SAME); + left -= len; + } + } else { register FILE *out = outfile; @@ -681,6 +711,7 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t written = 0; while (t < limit) switch ((c = *t++)) @@ -690,7 +721,9 @@ output_1_line (char const *base, char const *limit, char const *flag_format, size_t spaces = tab_size - column % tab_size; column += spaces; do - putc (' ', out); + { + written += putc (' ', out); + } while (--spaces); } break; @@ -698,7 +731,7 @@ output_1_line (char const *base, char const *limit, char const *flag_format, case '\r': putc (c, out); if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); + written += fprintf (out, flag_format, line_flag); column = 0; break; @@ -706,17 +739,94 @@ output_1_line (char const *base, char const *limit, char const *flag_format, if (column == 0) continue; column--; - putc (c, out); + written += putc (c, out); break; default: column += isprint (c) != 0; - putc (c, out); + written += putc (c, out); + if (written >= max_chunk) + { + set_color_context (SAME); + written = 0; + } break; } } } +static sigset_t old_sigproc_set; +void +set_color_context (enum colors con) +{ + int j; + static sigset_t set; + static bool set_initialized; + static enum colors last_color_context = RESET; + static int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + if (!colors_enabled || (con == SAME && !output_is_tty)) + return; + + if (output_is_tty && !set_initialized) + { + sigemptyset (&set); + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + sigaddset (&set, sig[j]); + set_initialized = true; + } + +repeat: + switch (con) + { + case DELETE: + if (output_is_tty) + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); + fprintf (outfile, "\x1B[31m"); + break; + + case ADD: + if (output_is_tty) + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); + fprintf (outfile, "\x1B[32m"); + break; + + case SAME: + case RESET: + fprintf (outfile, "\x1b[0m"); + fflush (outfile); + if (output_is_tty) + sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL); + if (con == SAME) + { + con = last_color_context; + goto repeat; + } + break; + } + + last_color_context = con; +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 11 Mar 2015 23:19:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14261159232233 (code B ref 20062); Wed, 11 Mar 2015 23:19:01 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Mar 2015 23:18:43 +0000 Received: from localhost ([127.0.0.1]:43255 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVpti-0000Zx-F3 for submit@debbugs.gnu.org; Wed, 11 Mar 2015 19:18:42 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:47925) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVptg-0000Zi-BO for 20062@debbugs.gnu.org; Wed, 11 Mar 2015 19:18:41 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 0FA00A60031; Wed, 11 Mar 2015 16:18:34 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Y2p4JhVNSzz2; Wed, 11 Mar 2015 16:18:33 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id B3A58A6002D; Wed, 11 Mar 2015 16:18:33 -0700 (PDT) Message-ID: <5500CD49.1060505@cs.ucla.edu> Date: Wed, 11 Mar 2015 16:18:33 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> In-Reply-To: <878uf3b92g.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > signal > +sigprocmask > stat Your mailer is inserting spaces at the start of lines, making the patch hard to read. Perhaps attach the patch instead next time? > +- Do not use color at all. This is the default when no --color option > +is present. That leading "-" doesn't look right. I'd remove it. (Similarly elsewhere.) + if (! outfile) + return; + + output_is_tty = isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS) + || (colors_style == AUTO && output_is_tty); The indenting and parentheses should be something like this: colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); More important, don't call isatty unless it's needed, as isatty can be somewhat expensive on some hosts. It's not needed if COLORS_STYLE == NEVER. + check_color_output (); ... + check_color_output (); ... outfile = stdout; + check_color_output (); The first two calls to check_color_output do unnecessary work, since 'outfile' must be a pipe in that case, so there's no need to call isatty. Only in the last case might isatty be needed. + size_t left = limit - base; + while (left) + { + size_t len = MIN (left, max_chunk); + fwrite (base, sizeof (char), len, outfile); + set_color_context (SAME); + left -= len; + } + } I'm afraid this won't work in general, as set_color_context (SAME) sends bytes to stdout if stdout is a tty, whereas it shouldn't output anything in the normal case. For example, it might try to change color in the middle of a multibyte character, and that's a no-no. Also, I'm a bit dubious about all those calls to sigprocmask. Can't we solve this without having to execute a sigmask-related system call for each buffer? How about using the method that 'ls' uses instead? Install a signal handler that merely sets a static variable. Perhaps the relevant 'ls' code should be Gnulib-ized, so that it can be shared between 'ls' and 'diff'. + fprintf (outfile, "\x1b[0m"); + fflush (outfile); + if (output_is_tty) + sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL); No need to call fflush if output is not a tty. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 12 Mar 2015 09:15:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142615165926606 (code B ref 20062); Thu, 12 Mar 2015 09:15:01 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Mar 2015 09:14:19 +0000 Received: from localhost ([127.0.0.1]:43440 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVzC7-0006v4-Bl for submit@debbugs.gnu.org; Thu, 12 Mar 2015 05:14:19 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55483) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVzC4-0006uq-CA for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 05:14:17 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2C9E7OI007078 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 12 Mar 2015 05:14:07 -0400 Received: from foobarbaz (vpn1-4-71.ams2.redhat.com [10.36.4.71]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2C9E4dc019196 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 12 Mar 2015 05:14:06 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> Date: Thu, 12 Mar 2015 10:14:03 +0100 In-Reply-To: <5500CD49.1060505@cs.ucla.edu> (Paul Eggert's message of "Wed, 11 Mar 2015 16:18:33 -0700") Message-ID: <87twxqa884.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Hi Paul, Paul Eggert writes: > Also, I'm a bit dubious about all those calls to sigprocmask. Can't > we solve this without having to execute a sigmask-related system call > for each buffer? How about using the method that 'ls' uses instead? > Install a signal handler that merely sets a static variable. Perhaps > the relevant 'ls' code should be Gnulib-ized, so that it can be shared > between 'ls' and 'diff'. is it ok for now to keep these calls to sigprocmask and fix all the other issues you reported (until the ls.c code is Gnulib-ized)? They won't affect any existing use-case anyway as they will be used only when --color is used on a tty. Thanks for the detailed review. Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 12 Mar 2015 14:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142617150831843 (code B ref 20062); Thu, 12 Mar 2015 14:46:01 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Mar 2015 14:45:08 +0000 Received: from localhost ([127.0.0.1]:44060 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YW4MF-0008HW-Tw for submit@debbugs.gnu.org; Thu, 12 Mar 2015 10:45:08 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:49801) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YW4MC-0008Gh-AC for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 10:45:05 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 32933A6001B; Thu, 12 Mar 2015 07:44:57 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id DoQfiRwDVbUp; Thu, 12 Mar 2015 07:44:57 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id E04CB39E8018; Thu, 12 Mar 2015 07:44:56 -0700 (PDT) Message-ID: <5501A668.5050104@cs.ucla.edu> Date: Thu, 12 Mar 2015 07:44:56 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> In-Reply-To: <87twxqa884.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > is it ok for now to keep these calls to sigprocmask and fix all the > other issues you reported (until the ls.c code is Gnulib-ized)? Sure, if removing sigprocmask calls is merely an efficiency thing. (It may be that the cost of the sigprocmask calls is not significant, so we can leave them in.) Correctness is the bigger problem here. Another possibility is to refuse to output colors to a terminal. That would simplify a lot of things; we wouldn't need to worry about signals at all. A third possibility is to have a signal handler that resets the terminal (using 'write' not 'fwrite', to make it async-signal-safe). That should remove the need for sigprocmask. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Gisle Vanem Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 12 Mar 2015 15:45:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org X-Debbugs-Original-To: bug-diffutils@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.14261750675166 (code B ref -1); Thu, 12 Mar 2015 15:45:02 +0000 Received: (at submit) by debbugs.gnu.org; 12 Mar 2015 15:44:27 +0000 Received: from localhost ([127.0.0.1]:44106 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YW5He-0001LG-K7 for submit@debbugs.gnu.org; Thu, 12 Mar 2015 11:44:27 -0400 Received: from eggs.gnu.org ([208.118.235.92]:58197) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YVySM-0005kT-8g for submit@debbugs.gnu.org; Thu, 12 Mar 2015 04:27:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YVySC-0000hl-Vx for submit@debbugs.gnu.org; Thu, 12 Mar 2015 04:26:56 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:51777) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVySC-0000hh-TU for submit@debbugs.gnu.org; Thu, 12 Mar 2015 04:26:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59901) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVyS8-0001Ly-4i for bug-diffutils@gnu.org; Thu, 12 Mar 2015 04:26:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YVyS4-0000bl-1m for bug-diffutils@gnu.org; Thu, 12 Mar 2015 04:26:48 -0400 Received: from nm29-vm8.bullet.mail.gq1.yahoo.com ([98.136.216.183]:48168) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YVyS3-0000bU-P6 for bug-diffutils@gnu.org; Thu, 12 Mar 2015 04:26:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.no; s=s2048; t=1426148802; bh=PrukXXLV91aMpq41fdqG7rze4XGvzOvozAC7lAGxvSU=; h=Date:From:To:Subject:References:In-Reply-To:From:Subject; b=WqgFogjPuE7jwRQzEPl8Z9FGMewTEDFSdHkVRGVN5X6/L1Pc/T0IQ/0Z9343YZjNtspY63r6Zvgq8FM+lcaTWeB0xJYpsCsxnMfUlEbW+hcX+jmILUIyVdugEQCuMYtTX5DxVRhxwEFShplcAwqqxYTeFqWeUz6RakAZ4ADYqsvCAlArpnSNyenTUA9hfmGg52ghl6LSrwdZKtmj06gsiCpM+QZe2HbZyMTCR/LWwGbWa3rn1/cgtFhXMaxM+svBxmsJYMgTgsczOYIWUvNOcKOC8Wl1M+b4mJdaWIAssxfS4yLnzauwPyakJT9POXCGWbRC40mxllDiRYWffcov9g== Received: from [98.137.12.59] by nm29.bullet.mail.gq1.yahoo.com with NNFMP; 12 Mar 2015 08:26:42 -0000 Received: from [46.228.39.75] by tm4.bullet.mail.gq1.yahoo.com with NNFMP; 12 Mar 2015 08:26:42 -0000 Received: from [127.0.0.1] by smtp112.mail.ir2.yahoo.com with NNFMP; 12 Mar 2015 08:26:41 -0000 X-Yahoo-Newman-Id: 744691.63501.bm@smtp112.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: VxG7GiQVM1nJg_VZ22OLCQ6cEJGtl1Mgw.IF.B8bOExQm0H _x_Dl50Nb0TwnTUhQKbyX2WLsPAFDSdKUCIsyM8jt2u3MxF9oXwDFJNqqW6E Ig8JlMhT.tHQ4e699iiOMy5DzQEL3CX81Q.4rAkFL.eq0Z85BeOVFYz_mliE 7ZxnmmV86Q98cTmmpDMXJ.rVycWWH5SJlrXxwDHe7ejPcqbpmoirifKGGH6v F29F_MJpt6bI.R5FmnsRw7CRUKY3qjS_ixkFy6JtPNNW93aARQrj8_f0Ig2r xCQgjts2j8GjnOmWWLvPLcfcFIu1vBoP5kIMf5iXtJGphkzZsbE1l57iAR1I OWw5X8ZLGnSowGYCaJxP_PuxaexHQRzeX.vuu8Y.iLTgvjRo1x_QDMCR2NT. T84rFV.xg6l9a0G8SYz5bXiYZ.T4ZmeQ3FEmulB7ezOBFzckoFqzJAUgWCxP ha2C6.DskVJpIYNTxFlAlWysvCGE_UzDr3rGtfkILOZM.QeGTUVFKIn_BV_a fEeH1Bj1g3jB939Tg0mz04w-- X-Yahoo-SMTP: 8zhYLGyswBB3AGU8c4pvFIFOfA-- Message-ID: <55014DC7.3050602@yahoo.no> Date: Thu, 12 Mar 2015 09:26:47 +0100 From: Gisle Vanem User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0 SeaMonkey/2.32.1 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> In-Reply-To: <5500CD49.1060505@cs.ucla.edu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -5.0 (-----) X-Mailman-Approved-At: Thu, 12 Mar 2015 11:44:24 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert wrote: > + fprintf (outfile, "\x1b[0m"); > + fflush (outfile); > + if (output_is_tty) > + sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL); > > No need to call fflush if output is not a tty. And what support do GnuLib have for parsing ANSI-codes and showing colours on Windows? None I guess. But I've written a simple ANSI-color decoder elsewhere I could contribute. Or we could replace those "\x1b[0m" with calls to SetConsoleTextAttribute() instead. -- --gv From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 12 Mar 2015 21:19:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142619511122258 (code B ref 20062); Thu, 12 Mar 2015 21:19:01 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Mar 2015 21:18:31 +0000 Received: from localhost ([127.0.0.1]:44305 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWAUv-0005mt-TT for submit@debbugs.gnu.org; Thu, 12 Mar 2015 17:18:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57460) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWAUs-0005mi-1I for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 17:18:28 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2CLIN1I014178 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 12 Mar 2015 17:18:23 -0400 Received: from foobarbaz (vpn1-6-98.ams2.redhat.com [10.36.6.98]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2CLIIUb032492 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 12 Mar 2015 17:18:20 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> Date: Thu, 12 Mar 2015 22:18:18 +0100 In-Reply-To: <5501A668.5050104@cs.ucla.edu> (Paul Eggert's message of "Thu, 12 Mar 2015 07:44:56 -0700") Message-ID: <87pp8d9ap1.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain Paul Eggert writes: > Giuseppe Scrivano wrote: >> is it ok for now to keep these calls to sigprocmask and fix all the >> other issues you reported (until the ls.c code is Gnulib-ized)? > > Sure, if removing sigprocmask calls is merely an efficiency thing. > (It may be that the cost of the sigprocmask calls is not significant, > so we can leave them in.) Correctness is the bigger problem here. I've attached a new version where I leave sigprocmask when colors are used on a tty. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 68c9ac2ba4c3baf8ce3202c59fa931367a0ec215 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * bootstrap.conf (gnulib_modules): Add "sigprocmask" and "mbiter". * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors): New enum to register the current color to use. (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (colors_enabled): New boolean variable. (check_color_output): New function. (begin_output): Call check_color_output every time the output file is changed. (set_color_context): New function. If colors are enabled, print the right command for the terminal to change the color. --- bootstrap.conf | 2 + doc/diffutils.texi | 20 ++++++++ src/context.c | 4 ++ src/diff.c | 30 +++++++++++- src/diff.h | 34 ++++++++++++++ src/normal.c | 20 ++++++-- src/side.c | 15 ++++++ src/util.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 8 files changed, 251 insertions(+), 10 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 9b2de22..4825401 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -51,6 +51,7 @@ largefile lstat maintainer-makefile manywarnings +mbiter mbrtowc mkstemp mktime @@ -61,6 +62,7 @@ readme-release regex sh-quote signal +sigprocmask stat stat-macros stat-time diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..0a2f1fc 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,26 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..88ddfde 100644 --- a/src/context.c +++ b/src/context.c @@ -366,10 +366,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* Then output the inserted part. */ @@ -378,10 +380,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index ff28377..07fcb57 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -645,6 +653,9 @@ main (int argc, char **argv) specify_style (OUTPUT_NORMAL); } + if (colors_style != NEVER && paginate) + error (EXIT_TROUBLE, 0, _("Cannot specify both --color and --paginate.")); + if (output_style != OUTPUT_CONTEXT || hard_locale (LC_TIME)) { #if (defined STAT_TIMESPEC || defined STAT_TIMESPEC_NS \ @@ -940,6 +951,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1021,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..0291fdd 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,36 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors +{ + /* Reset to the default color. */ + RESET, + + /* Delete lines. Show output in red. */ + DELETE, + + /* Added lines. Show them in green. */ + ADD, + + /* Does not modify the context. Use it to periodically process pending + signals. */ + SAME, +}; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +113,9 @@ enum output_style XTERN enum output_style output_style; +/* True if colors are printed. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +423,4 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_color_context (enum colors); diff --git a/src/normal.c b/src/normal.c index 721fd1a..0d53033 100644 --- a/src/normal.c +++ b/src/normal.c @@ -56,14 +56,26 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + for (i = first0; i <= last0; i++) + { + set_color_context (DELETE); + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET); + } + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + for (i = first1; i <= last1; i++) + { + set_color_context (ADD); + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET); + } + } } diff --git a/src/side.c b/src/side.c index 155512c..e52454e 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..e7161d2 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,8 @@ #include #include #include "xvasprintf.h" +#include +#include char const pr_program[] = PR_PROGRAM; @@ -153,6 +155,21 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (bool is_pipe) +{ + if (! outfile) + return; + + output_is_tty = (colors_style != NEVER && !is_pipe + && isatty (fileno (outfile))); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +330,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +338,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +349,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +692,32 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + /* Try to avoid to block for too long and write more than MAX_CHUNK bytes before + checking for pending signals. */ + const size_t max_chunk = 4096; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + if (!colors_enabled || !output_is_tty) + { + fwrite (base, sizeof (char), limit - base, outfile); + } + else + { + size_t written = 0; + mbi_iterator_t iter; + for (mbi_init (iter, base, limit - base); mbi_avail (iter); mbi_advance (iter)) + { + size_t mbi_len = mb_len (mbi_cur (iter)); + fwrite (mbi_cur_ptr (iter), mbi_len, 1, outfile); + written += mbi_len; + if (written >= max_chunk) + { + set_color_context (SAME); + written = 0; + } + } + } + } else { register FILE *out = outfile; @@ -681,6 +725,7 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t written = 0; while (t < limit) switch ((c = *t++)) @@ -690,7 +735,9 @@ output_1_line (char const *base, char const *limit, char const *flag_format, size_t spaces = tab_size - column % tab_size; column += spaces; do - putc (' ', out); + { + written += putc (' ', out); + } while (--spaces); } break; @@ -698,7 +745,7 @@ output_1_line (char const *base, char const *limit, char const *flag_format, case '\r': putc (c, out); if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); + written += fprintf (out, flag_format, line_flag); column = 0; break; @@ -706,17 +753,96 @@ output_1_line (char const *base, char const *limit, char const *flag_format, if (column == 0) continue; column--; - putc (c, out); + written += putc (c, out); break; default: column += isprint (c) != 0; - putc (c, out); + written += putc (c, out); + if (written >= max_chunk) + { + set_color_context (SAME); + written = 0; + } break; } } } +static sigset_t old_sigproc_set; +void +set_color_context (enum colors con) +{ + int j; + static sigset_t set; + static bool set_initialized; + static enum colors last_color_context = RESET; + static int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + if (!colors_enabled || (con == SAME && !output_is_tty)) + return; + + if (output_is_tty && !set_initialized) + { + sigemptyset (&set); + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + sigaddset (&set, sig[j]); + set_initialized = true; + } + +repeat: + switch (con) + { + case DELETE: + if (output_is_tty) + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); + fprintf (outfile, "\x1B[31m"); + break; + + case ADD: + if (output_is_tty) + sigprocmask (SIG_BLOCK, &set, &old_sigproc_set); + fprintf (outfile, "\x1B[32m"); + break; + + case SAME: + case RESET: + fprintf (outfile, "\x1b[0m"); + if (output_is_tty) + { + fflush (outfile); + sigprocmask (SIG_SETMASK, &old_sigproc_set, NULL); + } + if (con == SAME) + { + con = last_color_context; + goto repeat; + } + break; + } + + last_color_context = con; +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 12 Mar 2015 21:47:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142619679824804 (code B ref 20062); Thu, 12 Mar 2015 21:47:02 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Mar 2015 21:46:38 +0000 Received: from localhost ([127.0.0.1]:44318 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWAw9-0006S0-RV for submit@debbugs.gnu.org; Thu, 12 Mar 2015 17:46:38 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:43172) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWAw7-0006Ro-HF for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 17:46:36 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 4EE42A60031; Thu, 12 Mar 2015 14:46:29 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Qt3ba84lnywJ; Thu, 12 Mar 2015 14:46:29 -0700 (PDT) Received: from Penguin.CS.UCLA.EDU (Penguin.CS.UCLA.EDU [131.179.64.200]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 09490A6002D; Thu, 12 Mar 2015 14:46:29 -0700 (PDT) Message-ID: <55020934.8080505@cs.ucla.edu> Date: Thu, 12 Mar 2015 14:46:28 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> In-Reply-To: <87pp8d9ap1.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) On 03/12/2015 02:18 PM, Giuseppe Scrivano wrote: > +mbiter Ouch. I was hoping we didn't need to do that. I expect the use of mbiter to hurt performance significantly. I hope there's a better way, one that doesn't require counting individual multibyte characters. It may be time to think about having a signal handler that resets the output tty. > char const * const *line = &files[0].linbuf[i++]; > + set_color_context (DELETE); Please use the same indenting (if the original uses tabs, do that), so that it's easier to read the diffs. > + error (EXIT_TROUBLE, 0, _("Cannot specify both --color and --paginate.")); "cannot", not "Cannot", and no period at the end (it's not a sentence). > + fwrite (mbi_cur_ptr (iter), mbi_len, 1, outfile); > + written += mbi_len; fwrite may write fewer than mbi_len characters. > - putc (' ', out); > + { > + written += putc (' ', out); > + } No need for {} here. On the other hand, putc does not return 1-or-0 so this usage is problematic. > + written += fprintf (out, flag_format, line_flag); fprintf might return -1. > + written += putc (c, out); > ... > + written += putc (c, out); Again, putc might return values other than 0 and 1. > + if (output_is_tty && !set_initialized) > + { > + sigemptyset (&set); > + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) > + sigaddset (&set, sig[j]); > + set_initialized = true; > + } This stuff can be done once, by 'main', with no need for a set_initialized var. > +repeat: Let's rephrase it without the goto; it'll be easier to understand that way, and just as efficient I expect. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 13 Mar 2015 00:30:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142620656118080 (code B ref 20062); Fri, 13 Mar 2015 00:30:03 +0000 Received: (at 20062) by debbugs.gnu.org; 13 Mar 2015 00:29:21 +0000 Received: from localhost ([127.0.0.1]:44395 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWDTb-0004hV-Vu for submit@debbugs.gnu.org; Thu, 12 Mar 2015 20:29:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59697) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWDTZ-0004hF-0v for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 20:29:19 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2D0TDLr028708 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Thu, 12 Mar 2015 20:29:14 -0400 Received: from foobarbaz (vpn1-6-98.ams2.redhat.com [10.36.6.98]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2D0T9xG005655 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 12 Mar 2015 20:29:10 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> Date: Fri, 13 Mar 2015 01:29:09 +0100 In-Reply-To: <55020934.8080505@cs.ucla.edu> (Paul Eggert's message of "Thu, 12 Mar 2015 14:46:28 -0700") Message-ID: <87h9tp91uy.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain Paul Eggert writes: > On 03/12/2015 02:18 PM, Giuseppe Scrivano wrote: > >> +mbiter > > Ouch. I was hoping we didn't need to do that. I expect the use of > mbiter to hurt performance significantly. I hope there's a better > way, one that doesn't require counting individual multibyte > characters. It may be time to think about having a signal handler > that resets the output tty. Thanks once again for your prompt and detailed review. I have dropped that and implemented the solution you suggested: now the signal handler directly write(2) to reset the tty if needed and then restore the default handler. It contributes to simplify the code in util.c as the output throttling is not required anymore. Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 45372bec9789e0ec3879c8710dc0e4c799dd0950 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * bootstrap.conf (gnulib_modules): Add "sigprocmask". * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors): New enum to register the current color to use. (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Call install_signal_handlers. Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (colors_enabled): New boolean variable. (check_color_output): New function. (install_signal_handlers): New function. (signal_handler): New function. (begin_output): Call check_color_output every time the output file is changed. (set_color_context): New function. If colors are enabled, print the right command for the terminal to change the color. --- bootstrap.conf | 1 + doc/diffutils.texi | 20 +++++++++++ src/context.c | 4 +++ src/diff.c | 32 ++++++++++++++++- src/diff.h | 31 +++++++++++++++++ src/normal.c | 20 ++++++++--- src/side.c | 15 ++++++++ src/util.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 218 insertions(+), 5 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 9b2de22..63be732 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -61,6 +61,7 @@ readme-release regex sh-quote signal +sigprocmask stat stat-macros stat-time diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..0a2f1fc 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,26 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..f07a581 100644 --- a/src/context.c +++ b/src/context.c @@ -366,10 +366,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[0].linbuf[i++]; + set_color_context (DELETE, false); putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET, false); } /* Then output the inserted part. */ @@ -378,10 +380,12 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_color_context (ADD, false); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); print_1_line (NULL, line); + set_color_context (RESET, false); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index ff28377..637f716 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -285,6 +289,8 @@ main (int argc, char **argv) re_set_syntax (RE_SYNTAX_GREP | RE_NO_POSIX_BACKTRACKING); excluded = new_exclude (); + install_signal_handlers (); + /* Decode the options. */ while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) @@ -627,6 +633,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -645,6 +655,9 @@ main (int argc, char **argv) specify_style (OUTPUT_NORMAL); } + if (colors_style != NEVER && paginate) + error (EXIT_TROUBLE, 0, _("cannot specify both --color and --paginate")); + if (output_style != OUTPUT_CONTEXT || hard_locale (LC_TIME)) { #if (defined STAT_TIMESPEC || defined STAT_TIMESPEC_NS \ @@ -940,6 +953,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1023,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..c18786e 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,32 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors +{ + /* Reset to the default color. */ + RESET, + + /* Delete lines. Show output in red. */ + DELETE, + + /* Added lines. Show them in green. */ + ADD, +}; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +109,9 @@ enum output_style XTERN enum output_style output_style; +/* True if colors are printed. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +419,5 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_color_context (enum colors, bool force); +extern void install_signal_handlers (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..41a97b9 100644 --- a/src/normal.c +++ b/src/normal.c @@ -56,14 +56,26 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + for (i = first0; i <= last0; i++) + { + set_color_context (DELETE, false); + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET, false); + } + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + for (i = first1; i <= last1; i++) + { + set_color_context (ADD, false); + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET, false); + } + } } diff --git a/src/side.c b/src/side.c index 155512c..4d04942 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE, false); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD, false); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET, false); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..4cbd402 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -153,6 +154,21 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (bool is_pipe) +{ + if (! outfile) + return; + + output_is_tty = (colors_style != NEVER && !is_pipe + && isatty (fileno (outfile))); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +329,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +337,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +348,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +736,87 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +static void +signal_handler (int signal) +{ + struct sigaction act; + + if (output_is_tty) + set_color_context (RESET, true); + + /* Restore the default handler, and report the signal again. */ + sigaction (signal, NULL, &act); + act.sa_handler = SIG_DFL; + sigaction (signal, &act, NULL); + raise (signal); +} + +void +install_signal_handlers (void) +{ + int j; + struct sigaction act; + int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + { + act.sa_handler = signal_handler; + sigaction (sig[j], &act, NULL); + } + } +} + +void +set_color_context (enum colors con, bool force) +{ + const char *const reset_sequence = "\x1b[0m"; + if (! colors_enabled) + return; + switch (con) + { + case DELETE: + fprintf (outfile, "\x1B[31m"); + break; + + case ADD: + fprintf (outfile, "\x1B[32m"); + break; + + case RESET: + if (! force) + fprintf (outfile, "%s", reset_sequence); + else + { + if (write (fileno (outfile), reset_sequence, + strlen (reset_sequence)) < 0) + error (EXIT_TROUBLE, 0, "%s", _("write failed")); + } + break; + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 13 Mar 2015 01:09:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142620888224109 (code B ref 20062); Fri, 13 Mar 2015 01:09:01 +0000 Received: (at 20062) by debbugs.gnu.org; 13 Mar 2015 01:08:02 +0000 Received: from localhost ([127.0.0.1]:44416 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWE52-0006Gb-Tf for submit@debbugs.gnu.org; Thu, 12 Mar 2015 21:08:01 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:51616) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWE50-0006GD-2h for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 21:07:59 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id D7730A6004B; Thu, 12 Mar 2015 18:07:51 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id QPsVpGIIQ3nF; Thu, 12 Mar 2015 18:07:51 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 6EB74A60047; Thu, 12 Mar 2015 18:07:51 -0700 (PDT) Message-ID: <55023863.6000407@cs.ucla.edu> Date: Thu, 12 Mar 2015 18:07:47 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> In-Reply-To: <87h9tp91uy.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > +sigprocmask This part of the change isn't needed any more. > + case COLOR_OPTION: > + specify_colors_style (optarg); > + break; Please be consistent about tabs vs spaces. > + if (colors_style != NEVER && paginate) > + error (EXIT_TROUBLE, 0, _("cannot specify both --color and --paginate")); This part isn't needed any more, if I understand aright. > +/* What kind of changes a hunk contains. */ > +enum colors_style The comment doesn't match the code. > +/* True if colors are printed. */ > +XTERN enum colors_style colors_style; The comment doesn't match the code (it's not a boolean). > - for (i = first0; i <= last0; i++) > - print_1_line ("<", &files[0].linbuf[i]); > + { > + for (i = first0; i <= last0; i++) > + { > + set_color_context (DELETE, false); > + print_1_line ("<", &files[0].linbuf[i]); > + set_color_context (RESET, false); > + } > + } > ... > if (changes & NEW) > - for (i = first1; i <= last1; i++) > - print_1_line (">", &files[1].linbuf[i]); > + { > + for (i = first1; i <= last1; i++) > + { > + set_color_context (ADD, false); > + print_1_line (">", &files[1].linbuf[i]); > + set_color_context (RESET, false); > + } > + } No need for the outer braces (twice). > + /* Restore the default handler, and report the signal again. */ > + sigaction (signal, NULL, &act); > + act.sa_handler = SIG_DFL; > + sigaction (signal, &act, NULL); > + raise (signal); This assumes sigaction, but GNU diff is portable to hosts that lack sigaction. Please see the code in sdiff.c, which uses sigaction only if available. You may want to steal and/or librarize it, instead of using the ls.c-inspired code. > + const char *const reset_sequence = "\x1b[0m"; This should be: static char const reset_sequence[] = "\x1b[0m"; (I prefer putting the 'const' after the type, for consistency with "char *const *".) That is, there's no need for the pointer variable here, and you can use 'sizeof reset_sequence - 1' instead of 'strlen (reset_sequence)'. > +void > +set_color_context (enum colors con, bool force) This would be a bit clearer as separate functions for each combination of arguments that are used. In particular, the separate function that can be called from a signal handler should be commented as such, as it has more constraints on its actions. > + fprintf (outfile, "\x1B[31m"); > ... > + fprintf (outfile, "\x1B[32m"); > ... > + fprintf (outfile, "%s", reset_sequence); Use fputs instead of fprintf. > + if (write (fileno (outfile), reset_sequence, > + strlen (reset_sequence)) < 0) > + error (EXIT_TROUBLE, 0, "%s", _("write failed")); We can't use 'fileno' or 'error' inside a signal handler; they're not async-signal-safe. And we can't use 'outfile', as it's not volatile. Instead, I suggest redoing begin_output so that 'outfile' is always stdout and its file descriptor is 1; that way, 'write' can use STDOUT_FILENO instead of fileno (stdout). (You can use dup2 to arrange for this after the pipe calls.) Do not call 'error'; just return and let the signal handler re-raise the signal and exit. Also, don't assume that 'write' will write out the whole string; it might be a partial write. Also, what happens if a signal occurs when 'diff' is outputting an escape sequence? E.g., suppose 'diff' is in the middle of outputting "\x1B[31m" and gets interrupted after the '[', so that it outputs "\x1B[\x1b[0m". Is this guaranteed to reset the terminal? If not, what sequence of bytes is guaranteed to reset the terminal color even if the sequence is output immediately after a truncated escape sequence? > +static void > +signal_handler (int signal) > +{ > + struct sigaction act; > + > + if (output_is_tty) > + set_color_context (RESET, true); Don't have the signal handler inspect output_is_tty, as that would mean output_is_tty would have to be volatile. Instead, install the signal handler only if output_is_tty; that way, the handler itself can assume output_is_tty without having to check it. Isn't signal-handling fun? By the way, are you running "./configure --enable-gcc-warnings"? If not, please do that. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 13 Mar 2015 01:25:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142620989532154 (code B ref 20062); Fri, 13 Mar 2015 01:25:02 +0000 Received: (at 20062) by debbugs.gnu.org; 13 Mar 2015 01:24:55 +0000 Received: from localhost ([127.0.0.1]:44428 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWELP-0008MW-AL for submit@debbugs.gnu.org; Thu, 12 Mar 2015 21:24:55 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:52048) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWELM-0008M9-IM for 20062@debbugs.gnu.org; Thu, 12 Mar 2015 21:24:53 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id DE0FAA6004B; Thu, 12 Mar 2015 18:24:46 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kAS+Pxw3T+Fq; Thu, 12 Mar 2015 18:24:46 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 86AEEA60047; Thu, 12 Mar 2015 18:24:46 -0700 (PDT) Message-ID: <55023C5E.3030600@cs.ucla.edu> Date: Thu, 12 Mar 2015 18:24:46 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> In-Reply-To: <55023863.6000407@cs.ucla.edu> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) One other thing. This: + sigaction (signal, NULL, &act); + act.sa_handler = SIG_DFL; + sigaction (signal, &act, NULL); can be done more simply as 'signal (sig, SIG_DFL)' (assuming you change the local variable's name from 'signal' to 'sig'). From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 13 Mar 2015 10:58:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142624424731848 (code B ref 20062); Fri, 13 Mar 2015 10:58:01 +0000 Received: (at 20062) by debbugs.gnu.org; 13 Mar 2015 10:57:27 +0000 Received: from localhost ([127.0.0.1]:44590 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWNHS-0008Ha-Tx for submit@debbugs.gnu.org; Fri, 13 Mar 2015 06:57:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47993) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWNHQ-0008HR-47 for 20062@debbugs.gnu.org; Fri, 13 Mar 2015 06:57:25 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2DAvFtr003474 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 13 Mar 2015 06:57:15 -0400 Received: from foobarbaz (vpn1-5-157.ams2.redhat.com [10.36.5.157]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2DAvCnh015505 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 13 Mar 2015 06:57:13 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> Date: Fri, 13 Mar 2015 11:57:11 +0100 In-Reply-To: <55023863.6000407@cs.ucla.edu> (Paul Eggert's message of "Thu, 12 Mar 2015 18:07:47 -0700") Message-ID: <87wq2l6u7s.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > We can't use 'fileno' or 'error' inside a signal handler; they're not > async-signal-safe. And we can't use 'outfile', as it's not volatile. > > Instead, I suggest redoing begin_output so that 'outfile' is always > stdout and its file descriptor is 1; that way, 'write' can use > STDOUT_FILENO instead of fileno (stdout). (You can use dup2 to > arrange for this after the pipe calls.) Do not call 'error'; just > return and let the signal handler re-raise the signal and exit. we can do it right now I think, as anyway we use signals only when we are outputting to a terminal so it doesn't cover the pipe case. > Also, what happens if a signal occurs when 'diff' is outputting an > escape sequence? E.g., suppose 'diff' is in the middle of outputting > "\x1B[31m" and gets interrupted after the '[', so that it outputs > "\x1B[\x1b[0m". Is this guaranteed to reset the terminal? If not, > what sequence of bytes is guaranteed to reset the terminal color even > if the sequence is output immediately after a truncated escape > sequence? I could not find any immediate answer, neither in the ncurses, but on the terminals I have tried it is enough to reset even in the middle of another sequence. We could play safe and output it twice, but IMHO it doesn't seem to be needed. I'll send an updated version later today. Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 13 Mar 2015 18:09:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142627011527091 (code B ref 20062); Fri, 13 Mar 2015 18:09:01 +0000 Received: (at 20062) by debbugs.gnu.org; 13 Mar 2015 18:08:35 +0000 Received: from localhost ([127.0.0.1]:45405 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWU0g-00072s-Cl for submit@debbugs.gnu.org; Fri, 13 Mar 2015 14:08:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43553) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWU0d-00072h-C7 for 20062@debbugs.gnu.org; Fri, 13 Mar 2015 14:08:33 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2DI8SqV005313 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 13 Mar 2015 14:08:28 -0400 Received: from foobarbaz (vpn1-5-157.ams2.redhat.com [10.36.5.157]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2DI8OaW006298 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Fri, 13 Mar 2015 14:08:26 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> Date: Fri, 13 Mar 2015 19:08:24 +0100 In-Reply-To: <87wq2l6u7s.fsf@redhat.com> (Giuseppe Scrivano's message of "Fri, 13 Mar 2015 11:57:11 +0100") Message-ID: <87oanw7otj.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain Giuseppe Scrivano writes: > I'll send an updated version later today. and here it is, I've attached the patch. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 749a7466adc192c230b1dde963be18a2c9f408e2 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Add calls to set_color_context. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Add calls to set_color_context * src/side.c (print_1sdiff_line): Add calls to set_color_context. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (colors_enabled): New boolean variable. (check_color_output): New function. (install_signal_handlers): Likewise. (signal_handler): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 20 ++++++++++ src/context.c | 17 +++++++- src/diff.c | 27 ++++++++++++- src/diff.h | 19 +++++++++ src/normal.c | 12 +++++- src/side.c | 15 +++++++ src/util.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 218 insertions(+), 4 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..0a2f1fc 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,26 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..65b7485 100644 --- a/src/context.c +++ b/src/context.c @@ -360,9 +360,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +383,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -385,7 +399,8 @@ pr_unidiff_hunk (struct change *hunk) } /* We're done with this hunk, so on to the next! */ - + if (reset_context) + reset_color_context (false); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index ff28377..be6e6e3 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..abecf2b 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,6 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (bool from_signal); diff --git a/src/normal.c b/src/normal.c index 721fd1a..6fa48be 100644 --- a/src/normal.c +++ b/src/normal.c @@ -57,7 +57,11 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the first file has. */ if (changes & OLD) for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (false); + } if (changes == CHANGED) fputs ("---\n", outfile); @@ -65,5 +69,9 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the second file has. */ if (changes & NEW) for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (false); + } } diff --git a/src/side.c b/src/side.c index 155512c..8327d11 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (false); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..133e42b 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -143,6 +144,59 @@ print_message_queue (void) } } +static void +signal_handler (int sig) +{ + reset_color_context (true); + + /* Restore the default handler, and report the signal again. */ + signal (sig, SIG_DFL); + raise (sig); +} + +static void +install_signal_handlers (void) +{ + int j; +#if HAVE_SIGACTION + struct sigaction act; +#endif + int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + { +#if HAVE_SIGACTION + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + { + act.sa_handler = signal_handler; + sigaction (sig[j], &act, NULL); + } +#else + signal (sig[j], signal_handler); +#endif + } +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -153,6 +207,24 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (bool is_pipe) +{ + if (! outfile) + return; + + output_is_tty = (colors_style != NEVER && !is_pipe + && isatty (fileno (outfile))); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +385,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +393,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +404,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +792,43 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +void +set_add_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); +} + +void +set_delete_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (bool from_signal) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + if (! from_signal) + fputs (reset_sequence, outfile); + else + { + size_t written = 0; + while (written < sizeof reset_sequence - 1) + { + int ret = write (STDOUT_FILENO, reset_sequence + written, + sizeof reset_sequence - 1 - written); + if (ret < 0) + return; + written += ret; + } + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 14 Mar 2015 19:00:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14263595957860 (code B ref 20062); Sat, 14 Mar 2015 19:00:04 +0000 Received: (at 20062) by debbugs.gnu.org; 14 Mar 2015 18:59:55 +0000 Received: from localhost ([127.0.0.1]:46828 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWrHv-00022g-7c for submit@debbugs.gnu.org; Sat, 14 Mar 2015 14:59:55 -0400 Received: from mail-oi0-f50.google.com ([209.85.218.50]:36699) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWrHs-00022W-VL for 20062@debbugs.gnu.org; Sat, 14 Mar 2015 14:59:53 -0400 Received: by oiaz123 with SMTP id z123so10102496oia.3 for <20062@debbugs.gnu.org>; Sat, 14 Mar 2015 11:59:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=60aAdp2A0Ct7jhowrkKi/3d2R56dQahlD4iZqcYXzMQ=; b=HTqsK05xQTUi7RODzq5L7U9Q1w6rKHkwyYuiAT3tDBfqiPDZTKCLyZptsOjs9BtszW cqGHTcbSMf6soCUifiN5VrXmVY2aTLcx4wT/+QTWLVeJFOZEOfz2wMmHnToVBAfI6dBQ h+qz3JWyaEOMY0kfJj+60zYXLc30UfZ+G2/FEl5ebGkq7pMXp/54QyTExPpTrB7X3XR6 PIyckN4VL5fpJ6Wwp0p+CdvRplWL8mvqA0ezidn81t5e/64QvzvRF9yYC98PKSDwh722 THrKhj9veuZm0/+wd1ta5kLonxr2wojiBeTtCsXp7OV/sRfpey783szRGaLhY4/G0Isg 7y0Q== MIME-Version: 1.0 X-Received: by 10.60.73.38 with SMTP id i6mr35056459oev.27.1426359592286; Sat, 14 Mar 2015 11:59:52 -0700 (PDT) Received: by 10.182.118.66 with HTTP; Sat, 14 Mar 2015 11:59:52 -0700 (PDT) In-Reply-To: <87oanw7otj.fsf@redhat.com> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> Date: Sat, 14 Mar 2015 19:59:52 +0100 X-Google-Sender-Auth: Tqo5RpJZ1vL0KKmxNNcgx4IY-Bg Message-ID: From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) Giuseppe, 2015-03-13 19:08 GMT+01:00 Giuseppe Scrivano : > Giuseppe Scrivano writes: > >> I'll send an updated version later today. here are some more comments: * Please have a look at your changes to doc/diffutils.texi, they make no sense. * colors_style is never initialized and defaults to NEVER; it should default to AUTO. * Please colorize the output of non-unified diffs as well. * Please use one of the common existing color schemes, not a new one -- for example, the one used by vim or "git diff". Those colorize patch header lines as well. Thanks, Andreas From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 14 Mar 2015 20:30:04 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= , Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142636498618555 (code B ref 20062); Sat, 14 Mar 2015 20:30:04 +0000 Received: (at 20062) by debbugs.gnu.org; 14 Mar 2015 20:29:46 +0000 Received: from localhost ([127.0.0.1]:46836 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWsgs-0004pD-I8 for submit@debbugs.gnu.org; Sat, 14 Mar 2015 16:29:46 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:49579) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWsgq-0004p2-0e for 20062@debbugs.gnu.org; Sat, 14 Mar 2015 16:29:44 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id A09A039E801F; Sat, 14 Mar 2015 13:29:42 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jEiv1VtXryJF; Sat, 14 Mar 2015 13:29:42 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 4ED1139E8017; Sat, 14 Mar 2015 13:29:42 -0700 (PDT) Message-ID: <55049A36.6000603@cs.ucla.edu> Date: Sat, 14 Mar 2015 13:29:42 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: -3.3 (---) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -3.3 (---) Andreas Grünbacher wrote: > * colors_style is never initialized and defaults to NEVER; it should > default to AUTO. 'grep' and 'ls' default to the equivalent of NEVER; shouldn't 'diff' do the same? From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 14 Mar 2015 20:56:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Giuseppe Scrivano , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142636650720909 (code B ref 20062); Sat, 14 Mar 2015 20:56:02 +0000 Received: (at 20062) by debbugs.gnu.org; 14 Mar 2015 20:55:07 +0000 Received: from localhost ([127.0.0.1]:46859 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWt5P-0005R9-5Q for submit@debbugs.gnu.org; Sat, 14 Mar 2015 16:55:07 -0400 Received: from mail-ob0-f170.google.com ([209.85.214.170]:34386) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YWt5M-0005R1-Fl for 20062@debbugs.gnu.org; Sat, 14 Mar 2015 16:55:05 -0400 Received: by obbgg8 with SMTP id gg8so11773017obb.1 for <20062@debbugs.gnu.org>; Sat, 14 Mar 2015 13:55:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=4/axFOWh6rkN7uxjCk1K+Tjfv+jYRD77NjmY8LoKSBc=; b=buuiIaG8PI0aetHVJuNMcxob1x3B34+UBfqARt4TFI1sjE7DY2Pj8DQ/lLkLPpjt+4 TJcjPK8RcQFz+cWuS6d1KcqOwk1He0Dglxqx84PvFloGW4p4xDzB3fktE94ldlPnBpTB GnAZNIJtrWiMwWPLPjveMUzpo50ULqp9RvLpK/YLs/Ty0Xnbi2m5aNiRV7YUTgzQyRZn afaQmdRF1q+cZrvdw48fCPlWlxaalbb5YtFp9iN+Nl6+fBLtE/X80+LGuCLqnIOfXcLP d16OzBTw8ZbxkG0LhYxEQSr5srL/0NtkuRYVrxZgHqs4UnU2dxMEesxuMhJkaLR2t0JH VdbA== MIME-Version: 1.0 X-Received: by 10.60.73.38 with SMTP id i6mr35259685oev.27.1426366503824; Sat, 14 Mar 2015 13:55:03 -0700 (PDT) Received: by 10.182.118.66 with HTTP; Sat, 14 Mar 2015 13:55:03 -0700 (PDT) In-Reply-To: <55049A36.6000603@cs.ucla.edu> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <55049A36.6000603@cs.ucla.edu> Date: Sat, 14 Mar 2015 21:55:03 +0100 X-Google-Sender-Auth: FfVzpk6WBeQNu0MnawACLEF4McQ Message-ID: From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 2015-03-14 21:29 GMT+01:00 Paul Eggert : > 'grep' and 'ls' default to the equivalent of NEVER; shouldn't 'diff' do the > same? I think color terminals are the standard nowadays, but if you think that the default should be 'never', I could live with that. In any case, the program help text is wrong, too: > --color[=WHEN] colorize the output; WHEN can be 'never', 'always', > or 'auto' (the default) The default for WHEN is still 'always', but when the option is not used at all, the default is either 'auto' (my preference) or 'never'. Confusing ... Thanks, Andreas From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 15 Mar 2015 20:20:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14264507765711 (code B ref 20062); Sun, 15 Mar 2015 20:20:03 +0000 Received: (at 20062) by debbugs.gnu.org; 15 Mar 2015 20:19:36 +0000 Received: from localhost ([127.0.0.1]:47415 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXF0a-0001U3-16 for submit@debbugs.gnu.org; Sun, 15 Mar 2015 16:19:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33483) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXF0X-0001Ts-H0 for 20062@debbugs.gnu.org; Sun, 15 Mar 2015 16:19:34 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2FKJQES001488 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sun, 15 Mar 2015 16:19:26 -0400 Received: from foobarbaz (vpn1-5-113.ams2.redhat.com [10.36.5.113]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2FKJMI6029434 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Sun, 15 Mar 2015 16:19:24 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> Date: Sun, 15 Mar 2015 21:19:22 +0100 In-Reply-To: ("Andreas \=\?utf-8\?Q\?Gr\=C3\=BCnbacher\=22's\?\= message of "Sat, 14 Mar 2015 19:59:52 +0100") Message-ID: <87wq2i3tf9.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Andreas Gr=C3=BCnbacher writes: > Giuseppe, > > 2015-03-13 19:08 GMT+01:00 Giuseppe Scrivano : >> Giuseppe Scrivano writes: >> >>> I'll send an updated version later today. > > here are some more comments: > > * Please have a look at your changes to doc/diffutils.texi, they make no= sense. I've basically copied this section from coreutils. What doesn't make sense to you? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 15 Mar 2015 21:07:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Cc: Paul Eggert , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142645358910428 (code B ref 20062); Sun, 15 Mar 2015 21:07:02 +0000 Received: (at 20062) by debbugs.gnu.org; 15 Mar 2015 21:06:29 +0000 Received: from localhost ([127.0.0.1]:47437 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXFjw-0002i5-KR for submit@debbugs.gnu.org; Sun, 15 Mar 2015 17:06:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37495) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXFjp-0002ho-Ex for 20062@debbugs.gnu.org; Sun, 15 Mar 2015 17:06:27 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 936138EB5B; Sun, 15 Mar 2015 21:06:20 +0000 (UTC) Received: from foobarbaz (vpn1-5-113.ams2.redhat.com [10.36.5.113]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2FL6HIb026774 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Sun, 15 Mar 2015 17:06:18 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <55049A36.6000603@cs.ucla.edu> Date: Sun, 15 Mar 2015 22:06:16 +0100 In-Reply-To: ("Andreas \=\?utf-8\?Q\?Gr\=C3\=BCnbacher\=22's\?\= message of "Sat, 14 Mar 2015 21:55:03 +0100") Message-ID: <87sid63r93.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Andreas Gr=C3=BCnbacher writes: > 2015-03-14 21:29 GMT+01:00 Paul Eggert : >> 'grep' and 'ls' default to the equivalent of NEVER; shouldn't 'diff' do = the >> same? > > I think color terminals are the standard nowadays, but if you think > that the default should be 'never', I could live with that. In any > case, the program help text is wrong, too: > >> --color[=3DWHEN] colorize the output; WHEN can be 'never', = 'always', >> or 'auto' (the default) > > The default for WHEN is still 'always', but when the option is not > used at all, the default is either 'auto' (my preference) or 'never'. > Confusing ... I think the default for --color should be auto. Outputting stdout to a file happens more often with diff than with ls and having the colors commands in a diff file is to be avoided as much as possible (if people really want it, then they can force it with always). grep seems to default to "auto" as well when --color is specified. Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Norihiro Tanaka Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 15 Mar 2015 23:50:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Andreas Grunbacher , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142646337426371 (code B ref 20062); Sun, 15 Mar 2015 23:50:02 +0000 Received: (at 20062) by debbugs.gnu.org; 15 Mar 2015 23:49:34 +0000 Received: from localhost ([127.0.0.1]:47634 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXIHl-0006rH-Iv for submit@debbugs.gnu.org; Sun, 15 Mar 2015 19:49:33 -0400 Received: from mailgw04.kcn.ne.jp ([61.86.7.211]:38290) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXIHi-0006r6-Sm for 20062@debbugs.gnu.org; Sun, 15 Mar 2015 19:49:32 -0400 Received: from mxs02-s (mailgw2.kcn.ne.jp [61.86.15.234]) by mailgw04.kcn.ne.jp (Postfix) with ESMTP id C55EB6C14D5 for <20062@debbugs.gnu.org>; Mon, 16 Mar 2015 08:49:28 +0900 (JST) X-matriXscan-loop-detect: a722b906f7eaffc6d98a04a8e39711daa887e6cd Received: from mail03.kcn.ne.jp ([61.86.6.182]) by mxs02-s with ESMTP; Mon, 16 Mar 2015 08:49:26 +0900 (JST) Received: from [10.120.1.73] (i118-21-128-66.s30.a048.ap.plala.or.jp [118.21.128.66]) by mail03.kcn.ne.jp (Postfix) with ESMTPA id BDA17141009C; Mon, 16 Mar 2015 08:49:26 +0900 (JST) Date: Mon, 16 Mar 2015 08:49:29 +0900 From: Norihiro Tanaka In-Reply-To: <87sid63r93.fsf@redhat.com> References: <87sid63r93.fsf@redhat.com> Message-Id: <20150316084928.498A.27F6AC2D@kcn.ne.jp> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Becky! ver. 2.65.07 [ja] X-matriXscan-CTCmd-AV: Clean X-matriXscan-Action: Approve X-matriXscan: Uncategorized X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Giuseppe Scrivano wrote: > I think the default for --color should be auto. Outputting stdout to a > file happens more often with diff than with ls and having the colors > commands in a diff file is to be avoided as much as possible (if people > really want it, then they can force it with always). I disagree. I think we should not make difference for default among diff, ls and grep, and they should not also be neither AUTO nor ALWAYS. AUTO and ALWAYS are POSIX incompatible, as they change output in byte level. So I think that if only users and/or distributors expect it, they should manually change color option into AUTO or ALWAYS. > grep seems to default to "auto" as well when --color is specified. However, grep will suffer from the disadvantage of performance down with --color option. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Norihiro Tanaka Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 15 Mar 2015 23:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Andreas Grunbacher , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142646365226873 (code B ref 20062); Sun, 15 Mar 2015 23:55:01 +0000 Received: (at 20062) by debbugs.gnu.org; 15 Mar 2015 23:54:12 +0000 Received: from localhost ([127.0.0.1]:47664 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXIMF-0006zN-LC for submit@debbugs.gnu.org; Sun, 15 Mar 2015 19:54:11 -0400 Received: from mailgw04.kcn.ne.jp ([61.86.7.211]:39337) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXIMD-0006zE-P5 for 20062@debbugs.gnu.org; Sun, 15 Mar 2015 19:54:10 -0400 Received: from mxs01-s (mailgw1.kcn.ne.jp [61.86.15.233]) by mailgw04.kcn.ne.jp (Postfix) with ESMTP id 962BF6C16AE for <20062@debbugs.gnu.org>; Mon, 16 Mar 2015 08:54:08 +0900 (JST) X-matriXscan-loop-detect: 0047eac04c330429991ad4fdfbbe6002868c0c6c Received: from mail07.kcn.ne.jp ([61.86.6.186]) by mxs01-s with ESMTP; Mon, 16 Mar 2015 08:54:07 +0900 (JST) Received: from [10.120.1.73] (i118-21-128-66.s30.a048.ap.plala.or.jp [118.21.128.66]) by mail07.kcn.ne.jp (Postfix) with ESMTPA id 85E92D5002B; Mon, 16 Mar 2015 08:54:07 +0900 (JST) Date: Mon, 16 Mar 2015 08:54:09 +0900 From: Norihiro Tanaka In-Reply-To: <20150316084928.498A.27F6AC2D@kcn.ne.jp> References: <87sid63r93.fsf@redhat.com> <20150316084928.498A.27F6AC2D@kcn.ne.jp> Message-Id: <20150316085409.4996.27F6AC2D@kcn.ne.jp> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Becky! ver. 2.65.07 [ja] X-matriXscan-CTCmd-AV: Clean X-matriXscan-Action: Approve X-matriXscan: Uncategorized X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) On Mon, 16 Mar 2015 08:49:29 +0900 Norihiro Tanaka wrote: > AUTO and ALWAYS are POSIX incompatible, In addition, if the default is AUTO, and they are also imcompatible with previous versions of DIFF by default. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 16 Mar 2015 00:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Norihiro Tanaka Cc: Paul Eggert , Andreas Grunbacher , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14264674076116 (code B ref 20062); Mon, 16 Mar 2015 00:57:02 +0000 Received: (at 20062) by debbugs.gnu.org; 16 Mar 2015 00:56:47 +0000 Received: from localhost ([127.0.0.1]:47792 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXJKn-0001aY-MC for submit@debbugs.gnu.org; Sun, 15 Mar 2015 20:56:46 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38455) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXJKj-0001aO-QJ for 20062@debbugs.gnu.org; Sun, 15 Mar 2015 20:56:43 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B0F50C6A01; Mon, 16 Mar 2015 00:56:40 +0000 (UTC) Received: from foobarbaz (vpn1-5-113.ams2.redhat.com [10.36.5.113]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2G0uaUe023908 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Sun, 15 Mar 2015 20:56:38 -0400 From: Giuseppe Scrivano References: <87sid63r93.fsf@redhat.com> <20150316084928.498A.27F6AC2D@kcn.ne.jp> <20150316085409.4996.27F6AC2D@kcn.ne.jp> Date: Mon, 16 Mar 2015 01:56:36 +0100 In-Reply-To: <20150316085409.4996.27F6AC2D@kcn.ne.jp> (Norihiro Tanaka's message of "Mon, 16 Mar 2015 08:54:09 +0900") Message-ID: <8738554v5n.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain Norihiro Tanaka writes: > On Mon, 16 Mar 2015 08:49:29 +0900 > Norihiro Tanaka wrote: > >> AUTO and ALWAYS are POSIX incompatible, > > In addition, if the default is AUTO, and they are also imcompatible with > previous versions of DIFF by default. I meant the default if --color is specified. That is not incompatible with any previous version since --color was not present. Apparently, ls and grep already behaves differently for --color so diff is not going to make any other difference here. "ls --color" means "ls --color=always" while "grep --color" behaves like "grep --color=auto". Having to choose between these two, --color=auto makes more sense for diff where redirection to files is a common operation. I am attaching the latest version of the patch, taking into account comments from Andreas. I have added colors for header and line numbers, following the "git diff" colors scheme. Thanks, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 2d7ae3ebba0eaeda9d8f1e2fca6e8646ec187334 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (colors_enabled): New boolean variable. (check_color_output): New function. (install_signal_handlers): Likewise. (signal_handler): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. --- doc/diffutils.texi | 20 +++++++++ src/context.c | 51 ++++++++++++++++++---- src/diff.c | 27 +++++++++++- src/diff.h | 21 +++++++++ src/normal.c | 18 ++++++-- src/side.c | 15 +++++++ src/util.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 264 insertions(+), 14 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..0a2f1fc 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,26 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} +may be omitted, or one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..9b23d36 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (false); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (false); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (false); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (false); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (false); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index ff28377..be6e6e3 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..553bad1 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (bool from_signal); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..0ce01ee 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (false); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (false); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (false); + } } diff --git a/src/side.c b/src/side.c index 155512c..8327d11 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (false); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..0f8f7a8 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -143,6 +144,59 @@ print_message_queue (void) } } +static void +signal_handler (int sig) +{ + reset_color_context (true); + + /* Restore the default handler, and report the signal again. */ + signal (sig, SIG_DFL); + raise (sig); +} + +static void +install_signal_handlers (void) +{ + int j; +#if HAVE_SIGACTION + struct sigaction act; +#endif + int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + { +#if HAVE_SIGACTION + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + { + act.sa_handler = signal_handler; + sigaction (sig[j], &act, NULL); + } +#else + signal (sig[j], signal_handler); +#endif + } +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -153,6 +207,24 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (bool is_pipe) +{ + if (! outfile) + return; + + output_is_tty = (colors_style != NEVER && !is_pipe + && isatty (fileno (outfile))); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +385,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +393,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +404,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +792,57 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +void +set_header_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[1;39m"); +} + +void +set_line_numbers_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[36m"); +} + +void +set_add_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); +} + +void +set_delete_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (bool from_signal) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + if (! from_signal) + fputs (reset_sequence, outfile); + else + { + size_t written = 0; + while (written < sizeof reset_sequence - 1) + { + int ret = write (STDOUT_FILENO, reset_sequence + written, + sizeof reset_sequence - 1 - written); + if (ret < 0) + return; + written += ret; + } + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Norihiro Tanaka Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 16 Mar 2015 13:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Paul Eggert , Andreas Grunbacher , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142651421921815 (code B ref 20062); Mon, 16 Mar 2015 13:57:02 +0000 Received: (at 20062) by debbugs.gnu.org; 16 Mar 2015 13:56:59 +0000 Received: from localhost ([127.0.0.1]:48659 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXVVq-0005fn-MK for submit@debbugs.gnu.org; Mon, 16 Mar 2015 09:56:59 -0400 Received: from mailgw01.kcn.ne.jp ([61.86.7.208]:37845) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXVVk-0005fd-AM for 20062@debbugs.gnu.org; Mon, 16 Mar 2015 09:56:53 -0400 Received: from mxs02-s (mailgw2.kcn.ne.jp [61.86.15.234]) by mailgw01.kcn.ne.jp (Postfix) with ESMTP id E356E803A6 for <20062@debbugs.gnu.org>; Mon, 16 Mar 2015 22:56:49 +0900 (JST) X-matriXscan-loop-detect: 575294e2d310977090c9f2b1a200879e66ae20e9 Received: from mail08.kcn.ne.jp ([61.86.6.187]) by mxs02-s with ESMTP; Mon, 16 Mar 2015 22:56:47 +0900 (JST) Received: from [10.120.1.36] (i118-21-128-66.s30.a048.ap.plala.or.jp [118.21.128.66]) by mail08.kcn.ne.jp (Postfix) with ESMTPA id E28FF12B8098; Mon, 16 Mar 2015 22:56:46 +0900 (JST) Date: Mon, 16 Mar 2015 22:56:49 +0900 From: Norihiro Tanaka In-Reply-To: <8738554v5n.fsf@redhat.com> References: <20150316085409.4996.27F6AC2D@kcn.ne.jp> <8738554v5n.fsf@redhat.com> Message-Id: <20150316225648.721C.27F6AC2D@kcn.ne.jp> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Becky! ver. 2.65.07 [ja] X-matriXscan-CTCmd-AV: Clean X-matriXscan-Action: Approve X-matriXscan: Uncategorized X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) On Mon, 16 Mar 2015 01:56:36 +0100 Giuseppe Scrivano wrote: > Norihiro Tanaka writes: > > > On Mon, 16 Mar 2015 08:49:29 +0900 > > Norihiro Tanaka wrote: > > > >> AUTO and ALWAYS are POSIX incompatible, > > > > In addition, if the default is AUTO, and they are also imcompatible with > > previous versions of DIFF by default. > > I meant the default if --color is specified. That is not incompatible > with any previous version since --color was not present. > > Apparently, ls and grep already behaves differently for --color so diff > is not going to make any other difference here. "ls --color" means "ls > --color=always" while "grep --color" behaves like "grep --color=auto". > Having to choose between these two, --color=auto makes more sense for > diff where redirection to files is a common operation. > > I am attaching the latest version of the patch, taking into account > comments from Andreas. I have added colors for header and line numbers, > following the "git diff" colors scheme. > > Thanks, > Giuseppe I understood that you said, agree. Thanks, Norihiro From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 16 Mar 2015 16:22:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Paul Eggert , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14265229043322 (code B ref 20062); Mon, 16 Mar 2015 16:22:03 +0000 Received: (at 20062) by debbugs.gnu.org; 16 Mar 2015 16:21:44 +0000 Received: from localhost ([127.0.0.1]:48762 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXXlw-0000rV-3u for submit@debbugs.gnu.org; Mon, 16 Mar 2015 12:21:44 -0400 Received: from mail-oi0-f54.google.com ([209.85.218.54]:33689) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXXlt-0000rN-M5 for 20062@debbugs.gnu.org; Mon, 16 Mar 2015 12:21:42 -0400 Received: by oibu204 with SMTP id u204so42287730oib.0 for <20062@debbugs.gnu.org>; Mon, 16 Mar 2015 09:21:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=ZHGmT6vsUnldwhEtDXhlqa+fuT+NouVMYeTP88Lv3h8=; b=EyN2uiGrowsJaVM3hCPujbO/8oJ+JLJQ9sSBwb3iKywiQRdqqmjnTD3I/B68gkboVG SY3MqeYYQj1GE9Q4VJ+y9yeR8nSP4QxKPbWcFo7PxNRSKKwdZh0XrGOEYx82v/3t12XV G0FIklHjarCwycPK4Ix8/sRRzIy8MdwAlTIg0Gd8npNecEoQZDfHBleFCONaBkMUV0xx 5EiWuM1c6zWYd97qNnDazXS3L356SyRJ1moC6Iqk/waIgRhanYz7RnTQS7mUf/Nn1r5b kq08b86zLtur/Y+ty2pPJ16dcB4hGxEPxT1Ds/xbwRwTt5Chr9czjiyoBHmhiETEF4O0 PlKQ== MIME-Version: 1.0 X-Received: by 10.60.112.65 with SMTP id io1mr39435833oeb.66.1426522900873; Mon, 16 Mar 2015 09:21:40 -0700 (PDT) Received: by 10.182.118.66 with HTTP; Mon, 16 Mar 2015 09:21:40 -0700 (PDT) In-Reply-To: <87wq2i3tf9.fsf@redhat.com> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> Date: Mon, 16 Mar 2015 17:21:40 +0100 X-Google-Sender-Auth: S0-dOyU2FSZxqLxdCP62n7ETIpI Message-ID: From: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) 2015-03-15 21:19 GMT+01:00 Giuseppe Scrivano : > I've basically copied this section from coreutils. What doesn't make > sense to you? +@item --color [=@var{when}] +@cindex color, distinguishing file types with +Specify whether to use color for distinguishing file types. @var{when} [...] Color is used to distinguish between file types in ls, but not in diff. Simply reading what you've copied from coreutils would have been enough to figure that out. Andreas From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 16 Mar 2015 18:31:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Andreas =?UTF-8?Q?Gr=C3=BCnbacher?= Cc: Paul Eggert , 20062 <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142653063716109 (code B ref 20062); Mon, 16 Mar 2015 18:31:03 +0000 Received: (at 20062) by debbugs.gnu.org; 16 Mar 2015 18:30:37 +0000 Received: from localhost ([127.0.0.1]:48829 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXZmf-0004Bl-1P for submit@debbugs.gnu.org; Mon, 16 Mar 2015 14:30:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55711) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YXZmb-0004BV-Rd for 20062@debbugs.gnu.org; Mon, 16 Mar 2015 14:30:34 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2GIUVi9010996 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 16 Mar 2015 14:30:31 -0400 Received: from foobarbaz (vpn1-4-233.ams2.redhat.com [10.36.4.233]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2GIURlq002181 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 16 Mar 2015 14:30:29 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> Date: Mon, 16 Mar 2015 19:30:27 +0100 In-Reply-To: ("Andreas \=\?utf-8\?Q\?Gr\=C3\=BCnbacher\=22's\?\= message of "Mon, 16 Mar 2015 17:21:40 +0100") Message-ID: <87pp88ztfg.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Andreas Gr=C3=BCnbacher writes: > 2015-03-15 21:19 GMT+01:00 Giuseppe Scrivano : >> I've basically copied this section from coreutils. What doesn't make >> sense to you? > > +@item --color [=3D@var{when}] > +@cindex color, distinguishing file types with > +Specify whether to use color for distinguishing file types. @var{when} > [...] > > Color is used to distinguish between file types in ls, but not in > diff. Simply reading what you've copied from coreutils would have been > enough to figure that out. I see, sorry for that. I copied it straight without paying much attention, I had to be more careful. Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 18 Mar 2015 23:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142672190532694 (code B ref 20062); Wed, 18 Mar 2015 23:39:02 +0000 Received: (at 20062) by debbugs.gnu.org; 18 Mar 2015 23:38:25 +0000 Received: from localhost ([127.0.0.1]:52075 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YYNXb-0008VE-Sg for submit@debbugs.gnu.org; Wed, 18 Mar 2015 19:38:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44636) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YYNXZ-0008V4-38 for 20062@debbugs.gnu.org; Wed, 18 Mar 2015 19:38:23 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t2INcJPB004423 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 18 Mar 2015 19:38:19 -0400 Received: from foobarbaz (vpn1-6-206.ams2.redhat.com [10.36.6.206]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2INcFIQ022782 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Wed, 18 Mar 2015 19:38:17 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FDB353.8060801@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> Date: Thu, 19 Mar 2015 00:38:15 +0100 In-Reply-To: <87wq2i3tf9.fsf@redhat.com> (Giuseppe Scrivano's message of "Sun, 15 Mar 2015 21:19:22 +0100") Message-ID: <87wq2duba0.fsf_-_@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) --=-=-= Content-Type: text/plain Hi Paul, I've attached the last version of the patch. Is there anything left that should be done? Thanks, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 8b39f7297c0137af62336ad79044271803b66299 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (colors_enabled): New boolean variable. (check_color_output): New function. (install_signal_handlers): Likewise. (signal_handler): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. --- doc/diffutils.texi | 21 +++++++++ src/context.c | 51 ++++++++++++++++++---- src/diff.c | 27 +++++++++++- src/diff.h | 21 +++++++++ src/normal.c | 18 ++++++-- src/side.c | 15 +++++++ src/util.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 265 insertions(+), 14 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 3e25807..dd5a1c6 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3745,6 +3745,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..9b23d36 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (false); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (false); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (false); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (false); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (false); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index ff28377..be6e6e3 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..553bad1 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (bool from_signal); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..0ce01ee 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (false); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (false); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (false); + } } diff --git a/src/side.c b/src/side.c index 155512c..8327d11 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (false); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..0f8f7a8 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,7 @@ #include #include #include "xvasprintf.h" +#include char const pr_program[] = PR_PROGRAM; @@ -143,6 +144,59 @@ print_message_queue (void) } } +static void +signal_handler (int sig) +{ + reset_color_context (true); + + /* Restore the default handler, and report the signal again. */ + signal (sig, SIG_DFL); + raise (sig); +} + +static void +install_signal_handlers (void) +{ + int j; +#if HAVE_SIGACTION + struct sigaction act; +#endif + int const sig[] = + { + SIGTSTP, + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + + for (j = 0; j < sizeof (sig) / sizeof (*sig); j++) + { +#if HAVE_SIGACTION + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + { + act.sa_handler = signal_handler; + sigaction (sig[j], &act, NULL); + } +#else + signal (sig[j], signal_handler); +#endif + } +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -153,6 +207,24 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; +static bool output_is_tty; + +static void +check_color_output (bool is_pipe) +{ + if (! outfile) + return; + + output_is_tty = (colors_style != NEVER && !is_pipe + && isatty (fileno (outfile))); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +385,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +393,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +404,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -717,6 +792,57 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +void +set_header_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[1;39m"); +} + +void +set_line_numbers_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[36m"); +} + +void +set_add_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); +} + +void +set_delete_color_context (void) +{ + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (bool from_signal) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + if (! from_signal) + fputs (reset_sequence, outfile); + else + { + size_t written = 0; + while (written < sizeof reset_sequence - 1) + { + int ret = write (STDOUT_FILENO, reset_sequence + written, + sizeof reset_sequence - 1 - written); + if (ret < 0) + return; + written += ret; + } + } +} + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.1.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 28 Mar 2015 10:14:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org Cc: Paul Eggert Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142753762310427 (code B ref 20062); Sat, 28 Mar 2015 10:14:01 +0000 Received: (at 20062) by debbugs.gnu.org; 28 Mar 2015 10:13:43 +0000 Received: from localhost ([127.0.0.1]:38567 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YbnkN-0002i7-3J for submit@debbugs.gnu.org; Sat, 28 Mar 2015 06:13:43 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56446) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YbnkK-0002hy-TD for 20062@debbugs.gnu.org; Sat, 28 Mar 2015 06:13:41 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id D5F36AC7D7; Sat, 28 Mar 2015 10:13:39 +0000 (UTC) Received: from foobarbaz (vpn1-6-107.ams2.redhat.com [10.36.6.107]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t2SADaqq025364 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 28 Mar 2015 06:13:38 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> Date: Sat, 28 Mar 2015 11:13:35 +0100 In-Reply-To: <87wq2duba0.fsf_-_@redhat.com> (Giuseppe Scrivano's message of "Thu, 19 Mar 2015 00:38:15 +0100") Message-ID: <87d23t1lbk.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Giuseppe Scrivano writes: > I've attached the last version of the patch. Is there anything left > that should be done? Is there anything holding this version of the patch? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 29 Mar 2015 01:38:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14275930456014 (code B ref 20062); Sun, 29 Mar 2015 01:38:02 +0000 Received: (at 20062) by debbugs.gnu.org; 29 Mar 2015 01:37:25 +0000 Received: from localhost ([127.0.0.1]:39232 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yc2AH-0001Yw-BF for submit@debbugs.gnu.org; Sat, 28 Mar 2015 21:37:25 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:38585) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yc2AE-0001Yd-AQ for 20062@debbugs.gnu.org; Sat, 28 Mar 2015 21:37:23 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 51AB8A60005; Sat, 28 Mar 2015 18:37:15 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id abH0Nv3aJRnt; Sat, 28 Mar 2015 18:37:15 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id 10E6B39E8014; Sat, 28 Mar 2015 18:37:15 -0700 (PDT) Message-ID: <5517574A.2020508@cs.ucla.edu> Date: Sat, 28 Mar 2015 18:37:14 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv9dj28c.fsf@redhat.com> <874mptgo2c.fsf@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> In-Reply-To: <87d23t1lbk.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > Is there anything holding this version of the patch? Sorry, I haven't had time to review it carefully yet. It's definitely on my list of things to do. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 20 Apr 2015 20:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14295618693360 (code B ref 20062); Mon, 20 Apr 2015 20:32:02 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Apr 2015 20:31:09 +0000 Received: from localhost ([127.0.0.1]:33898 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YkILV-0000s8-44 for submit@debbugs.gnu.org; Mon, 20 Apr 2015 16:31:09 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40172) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YkILS-0000rv-0r for 20062@debbugs.gnu.org; Mon, 20 Apr 2015 16:31:07 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t3KKUvwh014825 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 20 Apr 2015 16:30:57 -0400 Received: from foobarbaz (vpn1-5-61.ams2.redhat.com [10.36.5.61]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t3KKUscH004322 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 20 Apr 2015 16:30:56 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> Date: Mon, 20 Apr 2015 22:30:54 +0200 In-Reply-To: <5517574A.2020508@cs.ucla.edu> (Paul Eggert's message of "Sat, 28 Mar 2015 18:37:14 -0700") Message-ID: <87fv7uleyp.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Sorry, I haven't had time to review it carefully yet. It's definitely > on my list of things to do. Nobody else is entitled/interested in the review for this patch? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 20 Apr 2015 22:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142957048021832 (code B ref 20062); Mon, 20 Apr 2015 22:55:01 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Apr 2015 22:54:40 +0000 Received: from localhost ([127.0.0.1]:33979 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YkKaO-0005g3-C4 for submit@debbugs.gnu.org; Mon, 20 Apr 2015 18:54:40 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:54498) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YkKaM-0005fq-2x for 20062@debbugs.gnu.org; Mon, 20 Apr 2015 18:54:38 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id 6AB61A60003; Mon, 20 Apr 2015 15:54:31 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id W9IXrDyIMo3G; Mon, 20 Apr 2015 15:54:30 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id EDEE5A60007; Mon, 20 Apr 2015 15:54:26 -0700 (PDT) Message-ID: <55358394.5040809@cs.ucla.edu> Date: Mon, 20 Apr 2015 15:54:12 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF1A4C.6080104@cs.ucla.edu> <87k2yoebrl.fsf@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> In-Reply-To: <87fv7uleyp.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > Nobody else is entitled/interested in the review for this patch? Apparently nobody else is interested right now, yes. (I don't know what "entitled" means; it's public info that anybody can review.) From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 22 Apr 2015 21:00:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142973639013246 (code B ref 20062); Wed, 22 Apr 2015 21:00:03 +0000 Received: (at 20062) by debbugs.gnu.org; 22 Apr 2015 20:59:50 +0000 Received: from localhost ([127.0.0.1]:36832 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yl1kM-0003RZ-14 for submit@debbugs.gnu.org; Wed, 22 Apr 2015 16:59:50 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33327) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yl1kJ-0003RN-L8 for 20062@debbugs.gnu.org; Wed, 22 Apr 2015 16:59:48 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B30858F2F2; Wed, 22 Apr 2015 20:59:43 +0000 (UTC) Received: from foobarbaz (vpn1-6-102.ams2.redhat.com [10.36.6.102]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t3MKxeeD010125 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 22 Apr 2015 16:59:41 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> Date: Wed, 22 Apr 2015 22:59:39 +0200 In-Reply-To: <55358394.5040809@cs.ucla.edu> (Paul Eggert's message of "Mon, 20 Apr 2015 15:54:12 -0700") Message-ID: <87r3rbg9qc.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.4 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Giuseppe Scrivano wrote: >> Nobody else is entitled/interested in the review for this patch? > > Apparently nobody else is interested right now, yes. (I don't know > what "entitled" means; it's public info that anybody can review.) someone who can decide if the patch is fine or not. Everyone can review it and express an opinion, but not decide about its acceptance. Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 22 Apr 2015 23:01:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.142974364023869 (code B ref 20062); Wed, 22 Apr 2015 23:01:01 +0000 Received: (at 20062) by debbugs.gnu.org; 22 Apr 2015 23:00:40 +0000 Received: from localhost ([127.0.0.1]:36868 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yl3dH-0006Cu-Er for submit@debbugs.gnu.org; Wed, 22 Apr 2015 19:00:39 -0400 Received: from smtp.cs.ucla.edu ([131.179.128.62]:48422) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Yl3dE-0006Cg-6H for 20062@debbugs.gnu.org; Wed, 22 Apr 2015 19:00:36 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp.cs.ucla.edu (Postfix) with ESMTP id D052CA6000E; Wed, 22 Apr 2015 16:00:29 -0700 (PDT) X-Virus-Scanned: amavisd-new at smtp.cs.ucla.edu Received: from smtp.cs.ucla.edu ([127.0.0.1]) by localhost (smtp.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cxXI3XkiC5dI; Wed, 22 Apr 2015 16:00:29 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by smtp.cs.ucla.edu (Postfix) with ESMTPSA id C3768A6000F; Wed, 22 Apr 2015 16:00:28 -0700 (PDT) Message-ID: <55382807.3020408@cs.ucla.edu> Date: Wed, 22 Apr 2015 16:00:23 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> In-Reply-To: <87r3rbg9qc.fsf@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -2.3 (--) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -2.3 (--) Giuseppe Scrivano wrote: > Everyone can review > it and express an opinion, but not decide about its acceptance. Ah, that would be one of the maintainers, either Jim Meyering or me. We're both busy guys, I'm afraid, and this is not a high-priority item. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Gisle Vanem Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 23 Apr 2015 08:01:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org X-Debbugs-Original-To: bug-diffutils@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.142977602513347 (code B ref -1); Thu, 23 Apr 2015 08:01:02 +0000 Received: (at submit) by debbugs.gnu.org; 23 Apr 2015 08:00:25 +0000 Received: from localhost ([127.0.0.1]:37084 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YlC3c-0003TD-JM for submit@debbugs.gnu.org; Thu, 23 Apr 2015 04:00:24 -0400 Received: from eggs.gnu.org ([208.118.235.92]:40046) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1YlC3a-0003Ss-Ig for submit@debbugs.gnu.org; Thu, 23 Apr 2015 04:00:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YlC3U-0007D1-D7 for submit@debbugs.gnu.org; Thu, 23 Apr 2015 04:00:17 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:49827) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YlC3U-0007Cs-Av for submit@debbugs.gnu.org; Thu, 23 Apr 2015 04:00:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53537) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YlC3P-0006GU-Ej for bug-diffutils@gnu.org; Thu, 23 Apr 2015 04:00:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YlC3M-00079a-9l for bug-diffutils@gnu.org; Thu, 23 Apr 2015 04:00:11 -0400 Received: from nm39-vm2.bullet.mail.ir2.yahoo.com ([212.82.97.161]:47188) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YlC3L-00075u-UB for bug-diffutils@gnu.org; Thu, 23 Apr 2015 04:00:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.no; s=s2048; t=1429776006; bh=cn9f+rQGMkYMYtEw4L5lVXH5fAdidZCkAkeO3xP4G3g=; h=Date:From:To:Subject:References:In-Reply-To:From:Subject; b=U/pmbUdtSZfg89Taoahu5fiOIXJriOi0HPgZHBCaRPHeVJ88AOvVn6KWmMbbJlXykQAJpx8xnDtXF2SRrq6FDXeqNDKYczxzoI9K0/mg6KXVrM/9DN3/o0xPmWlO1Or2yKlv8TsNSvYFZgBilcJvHIKGVLw0+NrLW4JpNBa3v4N6brFySLZpyrVS1JNasCyfJEnD/9SG9tajQhyifYmpKANd53UU+Mpk/vVx82LCGYcB1wYrYY97/rVwvtK1cy+Yr6HdEQfqc+1FJI/Le5sRhDf+JVaN4NLFvUoRCF6IbpK+4wJZO9bfvwVEdb9FE5CXektbCZw7BnEmoiU+eXV1mQ== Received: from [212.82.98.51] by nm39.bullet.mail.ir2.yahoo.com with NNFMP; 23 Apr 2015 08:00:06 -0000 Received: from [46.228.39.86] by tm4.bullet.mail.ir2.yahoo.com with NNFMP; 23 Apr 2015 08:00:06 -0000 Received: from [127.0.0.1] by smtp123.mail.ir2.yahoo.com with NNFMP; 23 Apr 2015 08:00:06 -0000 X-Yahoo-Newman-Id: 478970.89917.bm@smtp123.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: mzX2_j4VM1nDIsM54aIUmgOnEmr8Yzm234KBAwlh6SbrAdU HDtq.KdJZqfXP6yqWa6.4BaTSP9E6726viZZwbg4oHEydWvjatn79uEolfbQ tAH1WiuV1xDicgqxcIrtzOAPC08YHnjVtTbaKDozaCPJhsseyjuds_jeH4if l02fDUr22ztlR0D994WHgFSxPtOSOnog8LIrzughi9XBSL6dWZHieiGtnuGU lCe2HR0WjD3qT0UwZsM0yc.MTrXnKd5trf3ulXGH49SSwRf3Vo.nW1ff09Wl fquzLWVDVU_W1ds5e7YLZCrqzEoE6HyymCZ_xs4NMWxbP32VIDwoArgefWw0 tFJapk47MJh7shoZaCxTvfxgIwz5IuohFzksjxfrimLkQDWDHNd8Q91rM0Fg be5LTQboJbEKyvcXIIOvQAyIXtEJ9i.dYP2FgiWMa2FArMsnmXGf.U6x3AVx KBfaBKXUGepdfCUQeoOb6iYNHFKvl3s1B2Gp_.O1tXMYg1OwSJP6lu32SfRo 4ntP.vvDnuIcaqQGvibBT.Pwr X-Yahoo-SMTP: 8zhYLGyswBB3AGU8c4pvFIFOfA-- Message-ID: <5538A68C.8020900@yahoo.no> Date: Thu, 23 Apr 2015 10:00:12 +0200 From: Gisle Vanem User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0 SeaMonkey/2.33.1 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF7742.6050500@cs.ucla.edu> <87egowctaa.fsf@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> In-Reply-To: <87r3rbg9qc.fsf@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Giuseppe Scrivano wrote: >> Giuseppe Scrivano wrote: >>> Nobody else is entitled/interested in the review for this patch? I'm very interested, but I'm on Windows where your use of ANSI-codes are no good. I've fixed that in my private version. > someone who can decide if the patch is fine or not. Everyone can review > it and express an opinion, but not decide about its acceptance. Could fix this? util.c(166) : error C2065: 'SIGTSTP' : undeclared identifier util.c(167) : error C2065: 'SIGALRM' : undeclared identifier util.c(167) : error C2065: 'SIGQUIT' : undeclared identifier MSVC/MingW (with Gnulib) doesn't have these signals. -- --gv From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 19 Jun 2015 13:41:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.143472122120847 (code B ref 20062); Fri, 19 Jun 2015 13:41:03 +0000 Received: (at 20062) by debbugs.gnu.org; 19 Jun 2015 13:40:21 +0000 Received: from localhost ([127.0.0.1]:51721 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Z5wWq-0005QB-Lb for submit@debbugs.gnu.org; Fri, 19 Jun 2015 09:40:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49374) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Z5wWn-0005Px-Al for 20062@debbugs.gnu.org; Fri, 19 Jun 2015 09:40:18 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 80B0B3582A9; Fri, 19 Jun 2015 13:40:11 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-92.ams2.redhat.com [10.36.7.92]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5JDe8qo006885 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 19 Jun 2015 09:40:10 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> Date: Fri, 19 Jun 2015 15:40:07 +0200 In-Reply-To: <55382807.3020408@cs.ucla.edu> (Paul Eggert's message of "Wed, 22 Apr 2015 16:00:23 -0700") Message-ID: <87y4jf24w8.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -5.3 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.3 (-----) Hi Paul, Paul Eggert writes: > Giuseppe Scrivano wrote: >> Everyone can review >> it and express an opinion, but not decide about its acceptance. > > Ah, that would be one of the maintainers, either Jim Meyering or me. > We're both busy guys, I'm afraid, and this is not a high-priority > item. I agree it is not a high-priority item but it was delayed for almost 3 months now. Is there any hope that this patch is going to be reviewed? Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 20 Jun 2015 00:25:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.143475989225768 (code B ref 20062); Sat, 20 Jun 2015 00:25:03 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Jun 2015 00:24:52 +0000 Received: from localhost ([127.0.0.1]:52330 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Z66aa-0006hY-6N for submit@debbugs.gnu.org; Fri, 19 Jun 2015 20:24:52 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:47478) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Z66aX-0006hI-VQ for 20062@debbugs.gnu.org; Fri, 19 Jun 2015 20:24:50 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 1A7F01607F2; Fri, 19 Jun 2015 17:24:44 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id cvKyB_BUWmsl; Fri, 19 Jun 2015 17:24:43 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 77C2816080F; Fri, 19 Jun 2015 17:24:43 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id r9lSHnyo7Iec; Fri, 19 Jun 2015 17:24:43 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 5AEA21607F2; Fri, 19 Jun 2015 17:24:43 -0700 (PDT) Message-ID: <5584B2CB.7040104@cs.ucla.edu> Date: Fri, 19 Jun 2015 17:24:43 -0700 From: Paul Eggert Organization: UCLA Computer Science Department User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <54FF870C.5000902@cs.ucla.edu> <878uf3b92g.fsf@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> In-Reply-To: <87y4jf24w8.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.3 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.3 (/) Giuseppe Scrivano wrote: > Is there any hope that this patch is going to be reviewed? Yes, though not right now. My schedule doesn't free up for at least a week. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 07:03:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org Cc: Paul Eggert Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144195496221328 (code B ref 20062); Fri, 11 Sep 2015 07:03:01 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 07:02:42 +0000 Received: from localhost ([127.0.0.1]:56078 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaIM5-0005Xv-Iq for submit@debbugs.gnu.org; Fri, 11 Sep 2015 03:02:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41942) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaIM3-0005Xn-2B for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 03:02:40 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 4B8BBC0A15EA; Fri, 11 Sep 2015 07:02:38 +0000 (UTC) Received: from foo.bar.baz (vpn1-5-93.ams2.redhat.com [10.36.5.93]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8B72Z9X025056 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 11 Sep 2015 03:02:37 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> Date: Fri, 11 Sep 2015 09:02:34 +0200 In-Reply-To: <5584B2CB.7040104@cs.ucla.edu> (Paul Eggert's message of "Fri, 19 Jun 2015 17:24:43 -0700") Message-ID: <87bnd9sak5.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Giuseppe Scrivano wrote: >> Is there any hope that this patch is going to be reviewed? > > Yes, though not right now. My schedule doesn't free up for at least a week. Can someone please review this patch? It has been waiting for 6 months now... Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 07:34:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144195678724133 (code B ref 20062); Fri, 11 Sep 2015 07:34:01 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 07:33:07 +0000 Received: from localhost ([127.0.0.1]:56105 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaIpW-0006HA-O5 for submit@debbugs.gnu.org; Fri, 11 Sep 2015 03:33:07 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:59020) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaIpS-0006Gn-2E for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 03:33:02 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 168541601BD; Fri, 11 Sep 2015 00:33:01 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id dsp3Y4oTdPDa; Fri, 11 Sep 2015 00:33:00 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 5F193161072; Fri, 11 Sep 2015 00:33:00 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 8a2RiOOzbhwU; Fri, 11 Sep 2015 00:33:00 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 42F311601BD; Fri, 11 Sep 2015 00:33:00 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F283AC.9030704@cs.ucla.edu> Date: Fri, 11 Sep 2015 00:33:00 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <87bnd9sak5.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) I finally got around to looking at it. Doesn't it have the problem that if you type Control-C while it is in the middle of outputting a change-color sequence, your terminal may end up in a strange state? I thought there was a standard way in other GNU programs to deal with this, but am not familiar with the topic. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Gisle Vanem Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 09:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: 20062@debbugs.gnu.org X-Debbugs-Original-To: bug-diffutils@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.14419635801720 (code B ref -1); Fri, 11 Sep 2015 09:27:01 +0000 Received: (at submit) by debbugs.gnu.org; 11 Sep 2015 09:26:20 +0000 Received: from localhost ([127.0.0.1]:56163 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaKb5-0000Rf-9H for submit@debbugs.gnu.org; Fri, 11 Sep 2015 05:26:19 -0400 Received: from eggs.gnu.org ([208.118.235.92]:45587) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaKb3-0000RW-3F for submit@debbugs.gnu.org; Fri, 11 Sep 2015 05:26:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZaKb2-0004gs-62 for submit@debbugs.gnu.org; Fri, 11 Sep 2015 05:26:16 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:47190) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZaKb2-0004gk-3y for submit@debbugs.gnu.org; Fri, 11 Sep 2015 05:26:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55574) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZaKb1-0008Jr-5l for bug-diffutils@gnu.org; Fri, 11 Sep 2015 05:26:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZaKaw-0004cZ-8I for bug-diffutils@gnu.org; Fri, 11 Sep 2015 05:26:15 -0400 Received: from nm2-vm2.bullet.mail.ir2.yahoo.com ([212.82.96.82]:58129) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZaKav-0004bz-U1 for bug-diffutils@gnu.org; Fri, 11 Sep 2015 05:26:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.no; s=s2048; t=1441963568; bh=vvfxcBevzIMf+m9Cev/ZP+Vdevdi6vHTJ+wlQ9ngoec=; h=Subject:To:References:From:Date:In-Reply-To:From:Subject; b=fcwITCPan6hzMHO/X4Jeq+Z3UU/LU/2lLjIFYYLRG+5wzxL/TW3Rv0mIw7xpIJaXOBo4MrGnHqhpiQY9Ghs8TzJc3UpmHqrCCXJi76fgms6zNFy5dmjIWOQRkJVO8sG1OX2shGSjHu3a+L0VXHtUTxeN1Ej1T+KBdV6tZEuyjkwPI5toHKNVsFSQJ1FSOjb1zivCvua4XsobrWN+ZSsLQUgy2qjQHuA6qo5EHq7pPpYscInYLJhjftnvPeZC98w5TH9AtXlzFyrbbOTqI0N2j9RZcmk4mq465GmzXMR5eYEY8cvPFJQWgqm0yzKCbevDmSCRLt/xdBN0gyUQmZo3kA== Received: from [212.82.98.49] by nm2.bullet.mail.ir2.yahoo.com with NNFMP; 11 Sep 2015 09:26:08 -0000 Received: from [46.228.39.86] by tm2.bullet.mail.ir2.yahoo.com with NNFMP; 11 Sep 2015 09:26:08 -0000 Received: from [127.0.0.1] by smtp123.mail.ir2.yahoo.com with NNFMP; 11 Sep 2015 09:26:08 -0000 X-Yahoo-Newman-Id: 443157.84840.bm@smtp123.mail.ir2.yahoo.com X-Yahoo-Newman-Property: ymail-3 X-YMail-OSG: vQBZxa4VM1nd6fW6pCcHeJESuF8Qj5Z38MKLXqkrvOc4w7N PkClyyg9wIzLM0fCLZydxnokuKUilBPobf9BFgxOTLuSTZUFQz8elXe_7Ia. mw1km54qT9.92oweJgRHHNylEdNzRf.lopEyIfs1eqNIgXtnMZpgrJNCySsc E2IKIECEANbvq1jZpOOy5p6Cxvg3.GFj4GJ1xln_6KXlQJmsbU2sWhd6BpWa Po8xetskWePfHIDx3pNJcLGXGZEjHJ3fzLJgye6JJM_pemon9ZiDl3CYDGz1 gtwN04mrCRJHjCL84.1tj8f6GBZ5u8svSF3oKlqY9EtvrOhpK8Wt6AXdqbnK TqF5dyNL8Na0FTpSp0Q8AvA52BXvLnVCyR.8aYXjd2_Se2CKvZh7u29cyozq qZbA0OxYsaijIHfuZ8_ar1soT9krpTObQpTKc_YfA.r_ijyYgX6oedBAW22h E9efgPaYK6IqMUUrQd6lP43lLfJgG8XMWMWARLyOLXAQcH3CnxohvcGYi0u6 PaALeqIiRhBnbPT7nFqoyL34- X-Yahoo-SMTP: 8zhYLGyswBB3AGU8c4pvFIFOfA-- References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> From: Gisle Vanem Message-ID: <55F29E35.50808@yahoo.no> Date: Fri, 11 Sep 2015 11:26:13 +0200 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 SeaMonkey/2.35 MIME-Version: 1.0 In-Reply-To: <55F283AC.9030704@cs.ucla.edu> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert wrote: > I finally got around to looking at it. Doesn't it have the problem that if you type Control-C while it is in the middle > of outputting a change-color sequence, your terminal may end up in a strange state? No. He added a 'reset_color_context (true);' inside 'signal_handler()'. I've applied the colour-patches + my own WinCon patches to get colours on Windows. It has worked fine for 5 mounths. Reading diff-output with colours if so much more plesant than moin-chrome. Please add the patches ASAP. -- --gv From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 15:29:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Gisle Vanem , 20062@debbugs.gnu.org Cc: Giuseppe Scrivano Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14419852948815 (code B ref 20062); Fri, 11 Sep 2015 15:29:01 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 15:28:14 +0000 Received: from localhost ([127.0.0.1]:57108 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaQFJ-0002I7-Nv for submit@debbugs.gnu.org; Fri, 11 Sep 2015 11:28:13 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:41595) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaQFH-0002Hy-7o for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 11:28:11 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 335A01601BA; Fri, 11 Sep 2015 08:28:10 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 8pHXM7RnKeSK; Fri, 11 Sep 2015 08:28:09 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 18C6B16106F; Fri, 11 Sep 2015 08:28:09 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id CGEzBCMd7ZP1; Fri, 11 Sep 2015 08:28:09 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id E5FAF1601BA; Fri, 11 Sep 2015 08:28:08 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5500CD49.1060505@cs.ucla.edu> <87twxqa884.fsf@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F2F304.2070808@cs.ucla.edu> Date: Fri, 11 Sep 2015 08:28:04 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <55F29E35.50808@yahoo.no> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Gisle Vanem wrote: > No. He added a 'reset_color_context (true);' inside > 'signal_handler()'. Ah, sorry, I was looking at the original edition of the patch. I just now looked at and still see some problems. Mainly, it doesn't handle SIGTSTP properly. With SIGTSTP an application is supposed to reset the terminal and then resignal itself with SIGSTOP before really stopping. When restarting the application then needs to restore the terminal to the current state, if the current state is not the default. This is nearly impossible to do correctly with the proposed design. I suggest looking at how GNU ls does it: the signal handler merely sets a flag, and the application checks occasionally at safe places whether a signal has arrived. A nit: when installing signals via 'signal', don't install a handler if 'signal' says the signal is being ignored. Also, copyright papers need to be filed for diffutils before a nontrivial patch like this can be installed. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 16:42:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144198966921580 (code B ref 20062); Fri, 11 Sep 2015 16:42:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 16:41:09 +0000 Received: from localhost ([127.0.0.1]:57143 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaRNs-0005bz-FR for submit@debbugs.gnu.org; Fri, 11 Sep 2015 12:41:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33224) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaRNp-0005bq-IX for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 12:41:06 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C29A691DAA; Fri, 11 Sep 2015 16:41:04 +0000 (UTC) Received: from foo.bar.baz (vpn1-5-93.ams2.redhat.com [10.36.5.93]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8BGf1Bb007505 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 11 Sep 2015 12:41:03 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> Date: Fri, 11 Sep 2015 18:41:01 +0200 In-Reply-To: <55F283AC.9030704@cs.ucla.edu> (Paul Eggert's message of "Fri, 11 Sep 2015 00:33:00 -0700") Message-ID: <877fnwsyci.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Hi Paul, Paul Eggert writes: > I finally got around to looking at it. Doesn't it have the problem > that if you type Control-C while it is in the middle of outputting a > change-color sequence, your terminal may end up in a strange state? I > thought there was a standard way in other GNU programs to deal with > this, but am not familiar with the topic. we are dealing with the issue in the last version of the patch, and that was the main issue reported and that took a while to get addressed :) No, unfortunately there is not a standard way to deal with it. Last time I looked at it, grep was suffering from this issue (Ctrl-C in the middle of a color sequence) would leave the terminal in a funny state. Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 16:57:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144199059122969 (code B ref 20062); Fri, 11 Sep 2015 16:57:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 16:56:31 +0000 Received: from localhost ([127.0.0.1]:57171 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaRck-0005yP-UX for submit@debbugs.gnu.org; Fri, 11 Sep 2015 12:56:31 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:45083) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaRci-0005yF-CX for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 12:56:28 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 11F61161075; Fri, 11 Sep 2015 09:56:27 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id rHJtDVQ92AEh; Fri, 11 Sep 2015 09:56:26 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 165F4161076; Fri, 11 Sep 2015 09:56:26 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id GyNRceVBbXsj; Fri, 11 Sep 2015 09:56:26 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id EA8DD1601BA; Fri, 11 Sep 2015 09:56:25 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <5501A668.5050104@cs.ucla.edu> <87pp8d9ap1.fsf@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <877fnwsyci.fsf@foo.bar.baz> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F307B9.80303@cs.ucla.edu> Date: Fri, 11 Sep 2015 09:56:25 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <877fnwsyci.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Giuseppe Scrivano wrote: > unfortunately there is not a standard way to deal with it. Last > time I looked at it, grep was suffering from this issue (Ctrl-C in the > middle of a color sequence) would leave the terminal in a funny state. That's a bug in grep, and I just now filed a bug report for it here: http://bugs.gnu.org/21461 Admittedly it is a pain to handle signals correctly, but as long as we're adding the feature to diff we should do it right. I suggest looking at how GNU 'ls' does it; 'ls' is reasonably bullet-proof against the problem. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 21:48:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Gisle Vanem , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144200807520509 (code B ref 20062); Fri, 11 Sep 2015 21:48:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 21:47:55 +0000 Received: from localhost ([127.0.0.1]:57446 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWAk-0005Kj-Oe for submit@debbugs.gnu.org; Fri, 11 Sep 2015 17:47:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43861) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWAh-0005KY-Au for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 17:47:52 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 2ED83AB134; Fri, 11 Sep 2015 21:47:50 +0000 (UTC) Received: from foo.bar.baz (vpn1-4-227.ams2.redhat.com [10.36.4.227]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8BLlkw1014642 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 11 Sep 2015 17:47:48 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> Date: Fri, 11 Sep 2015 23:47:46 +0200 In-Reply-To: <55F2F304.2070808@cs.ucla.edu> (Paul Eggert's message of "Fri, 11 Sep 2015 08:28:04 -0700") Message-ID: <87vbbgr5kt.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Hi Paul, thanks for the review: Paul Eggert writes: > Gisle Vanem wrote: >> No. He added a 'reset_color_context (true);' inside >> 'signal_handler()'. > > Ah, sorry, I was looking at the original edition of the patch. > > I just now looked at and still see > some problems. Mainly, it doesn't handle SIGTSTP properly. With > SIGTSTP an application is supposed to reset the terminal and then > resignal itself with SIGSTOP before really stopping. When restarting > the application then needs to restore the terminal to the current > state, if the current state is not the default. This is nearly > impossible to do correctly with the proposed design. I suggest > looking at how GNU ls does it: the signal handler merely sets a flag, > and the application checks occasionally at safe places whether a > signal has arrived. IIRC we agreed on this design so that we react immediately to signals without blocking (now the most we can block is to write the reset sequence, but we can't cut this), blocking signals was done in an older version of the patch. I've tried to handle SIGTSTP with this addition and everything seems to work as expected, I'll test it more before propose a new version of the patch. Do you see any issue with it? Regards, Giuseppe diff --git a/src/util.c b/src/util.c index 0f8f7a8..7f11318 100644 --- a/src/util.c +++ b/src/util.c @@ -28,6 +28,8 @@ char const pr_program[] = PR_PROGRAM; +static const char *last_context_str; + /* Queue up one-line messages to be printed at the end, when -l is specified. Each message is recorded with a 'struct msg'. */ @@ -145,8 +147,35 @@ print_message_queue (void) } static void +safe_write_from_signal (const char *str, size_t len) +{ + size_t written = 0; + while (written < len) + { + int ret = write (STDOUT_FILENO, str + written, + len - written); + if (ret < 0) + return; + written += ret; + } +} + +static void signal_handler (int sig) { + if (sig == SIGCONT) + { + if (last_context_str) + safe_write_from_signal (last_context_str, strlen (last_context_str)); + return; + } + if (sig == SIGTSTP) + { + reset_color_context (true); + raise (SIGSTOP); + return; + } + reset_color_context (true); /* Restore the default handler, and report the signal again. */ @@ -163,6 +192,7 @@ install_signal_handlers (void) #endif int const sig[] = { + SIGCONT, SIGTSTP, SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, #ifdef SIGPOLL @@ -796,28 +826,40 @@ void set_header_color_context (void) { if (colors_enabled) - fprintf (outfile, "\x1B[1;39m"); + { + last_context_str = "\x1B[1;39m"; + fprintf (outfile, "%s", last_context_str); + } } void set_line_numbers_color_context (void) { if (colors_enabled) - fprintf (outfile, "\x1B[36m"); + { + last_context_str = "\x1B[36m"; + fprintf (outfile, "%s", last_context_str); + } } void set_add_color_context (void) { if (colors_enabled) - fprintf (outfile, "\x1B[32m"); + { + last_context_str = "\x1B[32m"; + fprintf (outfile, "%s", last_context_str); + } } void set_delete_color_context (void) { if (colors_enabled) - fprintf (outfile, "\x1B[31m"); + { + last_context_str = "\x1B[31m"; + fprintf (outfile, "%s", last_context_str); + } } void @@ -827,19 +869,12 @@ reset_color_context (bool from_signal) if (! colors_enabled) return; - if (! from_signal) - fputs (reset_sequence, outfile); + if (from_signal) + safe_write_from_signal (reset_sequence, sizeof reset_sequence - 1); else { - size_t written = 0; - while (written < sizeof reset_sequence - 1) - { - int ret = write (STDOUT_FILENO, reset_sequence + written, - sizeof reset_sequence - 1 - written); - if (ret < 0) - return; - written += ret; - } + fputs (reset_sequence, outfile); + last_context_str = NULL; } } From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 22:10:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Paul Eggert Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144200937722452 (code B ref 20062); Fri, 11 Sep 2015 22:10:03 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 22:09:37 +0000 Received: from localhost ([127.0.0.1]:57462 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWVl-0005q3-D1 for submit@debbugs.gnu.org; Fri, 11 Sep 2015 18:09:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47479) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWVi-0005pu-I8 for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 18:09:35 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id D87EEA4459; Fri, 11 Sep 2015 22:09:33 +0000 (UTC) Received: from [10.3.113.15] ([10.3.113.15]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8BM9W9t026150; Fri, 11 Sep 2015 18:09:33 -0400 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg X-Enigmail-Draft-Status: N1110 Organization: Red Hat, Inc. Message-ID: <55F35117.5080005@redhat.com> Date: Fri, 11 Sep 2015 16:09:27 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <87vbbgr5kt.fsf@foo.bar.baz> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="29WWnbQAJvlH5VjGAhpWtq8XUTWhkL0jW" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --29WWnbQAJvlH5VjGAhpWtq8XUTWhkL0jW Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 09/11/2015 03:47 PM, Giuseppe Scrivano wrote: > static void > +safe_write_from_signal (const char *str, size_t len) > +{ > + size_t written =3D 0; > + while (written < len) > + { > + int ret =3D write (STDOUT_FILENO, str + written, > + len - written); This writes unbuffered... > @@ -796,28 +826,40 @@ void > set_header_color_context (void) > { > if (colors_enabled) > - fprintf (outfile, "\x1B[1;39m"); > + { > + last_context_str =3D "\x1B[1;39m"; > + fprintf (outfile, "%s", last_context_str); =2E..while this is buffering output and might not be output right away. I= t is not safe to mix stdio and low-level write() to the same fd without flush()ing between transitions. But at the same time, I don't think that you want to convert everything to use low-level write(). Is it safe to block SIGTSTP around critical sections of when you must not be stopped, then pay attention to the volatile flag to know that you must flush and re-raise() TSTP as soon as possible? I'm a bit fuzzy on what the proper way is to get the terminal to a proper state, particularly if the TSTP arrived in the middle of stdio outputting a terminal escape sequence. It seems like the only safe way is to block TSTP except for in places where you know that you do NOT have pending data that would mess with the terminal, even if the cost of getting the process to a point where it will actually stop in response to the user request takes longer. --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --29WWnbQAJvlH5VjGAhpWtq8XUTWhkL0jW Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJV81EXAAoJEKeha0olJ0NqbzkH/ioq8OUlaulqOTNmZ5GgsjUb KfQ+y83LZgtlinX4u/7Z0wC9PhkeJcORi8jk4O1A8Lb+1HNjZATxDuy74AphFHTn EUDj6j4Ef/qrG71numHhQr1gbquQCPna0u7yGZNtFq7BDn7BdIIpmmTW7tsSHWeB 17GG9OB4pOf9xdlk1ZVpnbgAoxBt8DZrD9XpBglSqetvkn03Nu9PucjFNFiMGX4G GqSKrmT+zGmbwD/lTK/GFHSpeU0TZpT6r164eYsmBj/Ho+n6gaT3r+tMJtrkZlP0 lgFQv0aqNCBhNohup8zjrrdfYmA7gnRWHFyV4tPl8d15fndL/uh0LkNUzVbPE3I= =v9Oh -----END PGP SIGNATURE----- --29WWnbQAJvlH5VjGAhpWtq8XUTWhkL0jW-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 11 Sep 2015 22:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake , Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144200969722923 (code B ref 20062); Fri, 11 Sep 2015 22:15:02 +0000 Received: (at 20062) by debbugs.gnu.org; 11 Sep 2015 22:14:57 +0000 Received: from localhost ([127.0.0.1]:57466 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWav-0005xe-E9 for submit@debbugs.gnu.org; Fri, 11 Sep 2015 18:14:57 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:56283) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZaWat-0005xW-F5 for 20062@debbugs.gnu.org; Fri, 11 Sep 2015 18:14:56 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 5D3E316107C; Fri, 11 Sep 2015 15:14:54 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id HALPnhiJ9Ijk; Fri, 11 Sep 2015 15:14:53 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id A996916107D; Fri, 11 Sep 2015 15:14:53 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id SOZb6a6ii8JC; Fri, 11 Sep 2015 15:14:53 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 8A0D1161078; Fri, 11 Sep 2015 15:14:53 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55020934.8080505@cs.ucla.edu> <87h9tp91uy.fsf@redhat.com> <55023863.6000407@cs.ucla.edu> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F3525D.7050006@cs.ucla.edu> Date: Fri, 11 Sep 2015 15:14:53 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <55F35117.5080005@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Eric Blake wrote: > It seems like the only safe way is to block > TSTP except for in places where you know that you do NOT have pending > data that would mess with the terminal, even if the cost of getting the > process to a point where it will actually stop in response to the user > request takes longer. That's one way to do it, yes. In practice, though, it's easier (and probably faster) to do what GNU ls does, namely to have the the signal handler just set a volatile flag, and to periodically inspect the flag during normal computation in places where you can easily arrange for the terminal to be in a known state before acting on the signal. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 12 Sep 2015 08:55:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144204807114232 (code B ref 20062); Sat, 12 Sep 2015 08:55:01 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Sep 2015 08:54:31 +0000 Received: from localhost ([127.0.0.1]:57604 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZagZr-0003hU-3Z for submit@debbugs.gnu.org; Sat, 12 Sep 2015 04:54:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40703) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZagZo-0003hL-U4 for 20062@debbugs.gnu.org; Sat, 12 Sep 2015 04:54:29 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 01EFCC0B2017; Sat, 12 Sep 2015 08:54:27 +0000 (UTC) Received: from foo.bar.baz (vpn1-4-183.ams2.redhat.com [10.36.4.183]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8C8sOxw032306 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 12 Sep 2015 04:54:26 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> Date: Sat, 12 Sep 2015 10:54:24 +0200 In-Reply-To: <55F3525D.7050006@cs.ucla.edu> (Paul Eggert's message of "Fri, 11 Sep 2015 15:14:53 -0700") Message-ID: <87lhccqapr.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Eric Blake wrote: >> It seems like the only safe way is to block >> TSTP except for in places where you know that you do NOT have pending >> data that would mess with the terminal, even if the cost of getting the >> process to a point where it will actually stop in response to the user >> request takes longer. > > That's one way to do it, yes. In practice, though, it's easier (and > probably faster) to do what GNU ls does, namely to have the the signal > handler just set a volatile flag, and to periodically inspect the flag > during normal computation in places where you can easily arrange for > the terminal to be in a known state before acting on the signal. in a previous version of the patch, I was blocking signals when diff starts using colored output and re-enable them again once exiting from a colored context, but it was rejected because it could block indefinitely on long lines. Would block signals between a set_*_color_context and reset_color_context be enough or do we need more granularity (there are many places where printf is used in the code)? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 12 Sep 2015 09:38:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144205067117983 (code B ref 20062); Sat, 12 Sep 2015 09:38:01 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Sep 2015 09:37:51 +0000 Received: from localhost ([127.0.0.1]:57643 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZahFn-0004fz-8H for submit@debbugs.gnu.org; Sat, 12 Sep 2015 05:37:51 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:40770) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZahFl-0004fr-Lr for 20062@debbugs.gnu.org; Sat, 12 Sep 2015 05:37:50 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 99CCD16106D; Sat, 12 Sep 2015 02:37:48 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id Sbekr6de9RXV; Sat, 12 Sep 2015 02:37:47 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 180EC161076; Sat, 12 Sep 2015 02:37:47 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id tDCeTXnORlxG; Sat, 12 Sep 2015 02:37:46 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id DC66B16106D; Sat, 12 Sep 2015 02:37:46 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87wq2l6u7s.fsf@redhat.com> <87oanw7otj.fsf@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F3F26A.4050400@cs.ucla.edu> Date: Sat, 12 Sep 2015 02:37:46 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <87lhccqapr.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Giuseppe Scrivano wrote: > Would block signals between a set_*_color_context and > reset_color_context be enough or do we need more granularity (there are > many places where printf is used in the code)? No, for reasons Eric described: output is buffered. I suggest looking at the source code of GNU ls and seeing how it does things. In normal execution it never blocks signals at all. (It temporarily blocks signals only when processing a signal.) From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 12 Sep 2015 11:41:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14420580162082 (code B ref 20062); Sat, 12 Sep 2015 11:41:02 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Sep 2015 11:40:16 +0000 Received: from localhost ([127.0.0.1]:57669 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZajAF-0000XW-N7 for submit@debbugs.gnu.org; Sat, 12 Sep 2015 07:40:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36048) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZajAD-0000XJ-0D for 20062@debbugs.gnu.org; Sat, 12 Sep 2015 07:40:14 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B34F42F5166; Sat, 12 Sep 2015 11:40:11 +0000 (UTC) Received: from foo.bar.baz (vpn1-4-183.ams2.redhat.com [10.36.4.183]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8CBe8gk009268 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 12 Sep 2015 07:40:10 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> Date: Sat, 12 Sep 2015 13:40:08 +0200 In-Reply-To: <55F3F26A.4050400@cs.ucla.edu> (Paul Eggert's message of "Sat, 12 Sep 2015 02:37:46 -0700") Message-ID: <87bnd7n9wn.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) Paul Eggert writes: > Giuseppe Scrivano wrote: >> Would block signals between a set_*_color_context and >> reset_color_context be enough or do we need more granularity (there are >> many places where printf is used in the code)? > > No, for reasons Eric described: output is buffered. can't we solve this by flushing the output before enabling signals? In case of using buffered output we would still need to flush it to be sure the reset sequence is printed. > I suggest looking at the source code of GNU ls and seeing how it does > things. In normal execution it never blocks signals at all. (It > temporarily blocks signals only when processing a signal.) we already had this discussion about an older version of the patch where signals were processed after every line. We agreed that one difference between ls and diff is that ls has a limit on the line length, while diff hasn't such a limit and as you noted, it is bound only to the available memory. This was the reason for reacting to signals as soon as diff receives one. Either we block signals or we catch them and process as ls does (calling 'process_signals' periodically) that problem will still be present. What is your call on this? Thanks, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 12 Sep 2015 15:53:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144207314624318 (code B ref 20062); Sat, 12 Sep 2015 15:53:02 +0000 Received: (at 20062) by debbugs.gnu.org; 12 Sep 2015 15:52:26 +0000 Received: from localhost ([127.0.0.1]:58495 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zan6H-0006K9-Vi for submit@debbugs.gnu.org; Sat, 12 Sep 2015 11:52:26 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:46596) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zan6F-0006Jz-E6 for 20062@debbugs.gnu.org; Sat, 12 Sep 2015 11:52:24 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 24FE8161069; Sat, 12 Sep 2015 08:52:22 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id tf5zgYv8rMFB; Sat, 12 Sep 2015 08:52:21 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 285C516106A; Sat, 12 Sep 2015 08:52:21 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id tdOyh8gwYWNg; Sat, 12 Sep 2015 08:52:21 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 07906161069; Sat, 12 Sep 2015 08:52:21 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87wq2i3tf9.fsf@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <55F44A2E.2050506@cs.ucla.edu> Date: Sat, 12 Sep 2015 08:52:14 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <87bnd7n9wn.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Giuseppe Scrivano wrote: > Paul Eggert writes: > >> Giuseppe Scrivano wrote: >>> Would block signals between a set_*_color_context and >>> reset_color_context be enough or do we need more granularity (there are >>> many places where printf is used in the code)? >> >> No, for reasons Eric described: output is buffered. > > can't we solve this by flushing the output before enabling signals? "enabling"? Do you mean, flushing the output when a signal is caught? No, that won't work, as stdio is not safe in the presence of signals. Or do you mean fflush the output before unblocking signals? Yes, that will work, but it's slow. > we already had this discussion about an older version of the patch where > signals were processed after every line. We agreed that one difference > between ls and diff is that ls has a limit on the line length, while > diff hasn't such a limit and as you noted, it is bound only to the > available memory. This was the reason for reacting to signals as soon > as diff receives one. Sorry, I don't remember that discussion. Yes, the point is a valid one, and needs to be addressed. > Either we block signals or we catch them and process as ls does (calling > 'process_signals' periodically) that problem will still be present. True. However, blocking signals means we'll need to periodically fflush-unblock-block, which will slow us down; the whole point of stdio is efficiency via buffering, after all. Doing it the 'ls' way avoids this overhead, as we'll need to fflush only when a signal has actually arrived, plus we avoid the syscall overhead of periodic unblock-block. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 23 Sep 2015 10:15:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144300327324610 (code B ref 20062); Wed, 23 Sep 2015 10:15:02 +0000 Received: (at 20062) by debbugs.gnu.org; 23 Sep 2015 10:14:33 +0000 Received: from localhost ([127.0.0.1]:42360 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zeh4J-0006Oq-TE for submit@debbugs.gnu.org; Wed, 23 Sep 2015 06:14:33 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33413) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zeh4G-0006Oh-PT for 20062@debbugs.gnu.org; Wed, 23 Sep 2015 06:14:31 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 90A9091C02; Wed, 23 Sep 2015 10:14:27 +0000 (UTC) Received: from foo.bar.baz (vpn1-5-213.ams2.redhat.com [10.36.5.213]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t8NAENWd020778 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 23 Sep 2015 06:14:24 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87wq2duba0.fsf_-_@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> Date: Wed, 23 Sep 2015 12:14:22 +0200 In-Reply-To: <55F44A2E.2050506@cs.ucla.edu> (Paul Eggert's message of "Sat, 12 Sep 2015 08:52:14 -0700") Message-ID: <8737y5h281.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Hi Paul, Paul Eggert writes: >> Either we block signals or we catch them and process as ls does (calling >> 'process_signals' periodically) that problem will still be present. > > True. However, blocking signals means we'll need to periodically > fflush-unblock-block, which will slow us down; the whole point of > stdio is efficiency via buffering, after all. Doing it the 'ls' way > avoids this overhead, as we'll need to fflush only when a signal has > actually arrived, plus we avoid the syscall overhead of periodic > unblock-block. I have attached a new version of the patch where I've copied the signals handling code from coreutils and ensure that output_1_line won't block for too long without checking `process_signals'. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 2568e589ad38845ab8eaf895a98a84b94a29b72d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (reset_color_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 51 +++++++-- src/diff.c | 27 ++++- src/diff.h | 21 ++++ src/normal.c | 18 +++- src/side.c | 15 +++ src/util.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 418 insertions(+), 44 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..0944b44 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..8e9a74f 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index ff28377..be6e6e3 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..472fa93 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (void); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..227af10 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (); + } } diff --git a/src/side.c b/src/side.c index 155512c..b762d31 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..b5b39a2 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,152 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + reset_color_context (); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -153,6 +315,24 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +855,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,40 +877,93 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; +void +set_header_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[1;39m"); +} - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_line_numbers_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[36m"); +} - default: - column += isprint (c) != 0; - putc (c, out); - break; - } - } +void +set_add_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); + fflush (outfile); +} + +void +set_delete_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (void) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + fputs (reset_sequence, outfile); } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.4.3 --=-=-= Content-Type: text/plain Regards, Giuseppe --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 14 Oct 2015 09:34:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14448152353029 (code B ref 20062); Wed, 14 Oct 2015 09:34:02 +0000 Received: (at 20062) by debbugs.gnu.org; 14 Oct 2015 09:33:55 +0000 Received: from localhost ([127.0.0.1]:39479 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZmIRV-0000ml-OD for submit@debbugs.gnu.org; Wed, 14 Oct 2015 05:33:55 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47403) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZmIRQ-0000mZ-VE for 20062@debbugs.gnu.org; Wed, 14 Oct 2015 05:33:51 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id CE74F19F228; Wed, 14 Oct 2015 09:33:47 +0000 (UTC) Received: from foo.bar.baz (vpn1-4-156.ams2.redhat.com [10.36.4.156]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9E9Xhf2028902 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 14 Oct 2015 05:33:44 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> Date: Wed, 14 Oct 2015 11:33:42 +0200 In-Reply-To: <8737y5h281.fsf@foo.bar.baz> (Giuseppe Scrivano's message of "Wed, 23 Sep 2015 12:14:22 +0200") Message-ID: <87oag1aj61.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Giuseppe Scrivano writes: > Hi Paul, > > Paul Eggert writes: > >>> Either we block signals or we catch them and process as ls does (calling >>> 'process_signals' periodically) that problem will still be present. >> >> True. However, blocking signals means we'll need to periodically >> fflush-unblock-block, which will slow us down; the whole point of >> stdio is efficiency via buffering, after all. Doing it the 'ls' way >> avoids this overhead, as we'll need to fflush only when a signal has >> actually arrived, plus we avoid the syscall overhead of periodic >> unblock-block. > > I have attached a new version of the patch where I've copied the signals > handling code from coreutils and ensure that output_1_line won't block > for too long without checking `process_signals'. Any comments? Thanks, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 1c74f569083f2dcc7456f6c6fde93f5436dc0c90 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (reset_color_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 51 +++++++-- src/diff.c | 27 ++++- src/diff.h | 21 ++++ src/normal.c | 18 +++- src/side.c | 15 +++ src/util.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 418 insertions(+), 44 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..0944b44 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..8e9a74f 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index efd7e47..4e0f602 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..472fa93 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (void); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..227af10 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (); + } } diff --git a/src/side.c b/src/side.c index 155512c..b762d31 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..b5b39a2 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,152 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + reset_color_context (); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -153,6 +315,24 @@ print_message_queue (void) static char const *current_name0; static char const *current_name1; static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} void setup_output (char const *name0, char const *name1, bool recursive) @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +855,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,40 +877,93 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; +void +set_header_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[1;39m"); +} - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_line_numbers_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[36m"); +} - default: - column += isprint (c) != 0; - putc (c, out); - break; - } - } +void +set_add_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); + fflush (outfile); +} + +void +set_delete_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (void) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + fputs (reset_sequence, outfile); } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.4.3 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 18 Oct 2015 17:27:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14451891825807 (code B ref 20062); Sun, 18 Oct 2015 17:27:02 +0000 Received: (at 20062) by debbugs.gnu.org; 18 Oct 2015 17:26:22 +0000 Received: from localhost ([127.0.0.1]:55316 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Znriw-0001Vb-1T for submit@debbugs.gnu.org; Sun, 18 Oct 2015 13:26:22 -0400 Received: from mail-io0-f174.google.com ([209.85.223.174]:35516) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Znriu-0001VT-E8 for 20062@debbugs.gnu.org; Sun, 18 Oct 2015 13:26:20 -0400 Received: by iofz202 with SMTP id z202so25008674iof.2 for <20062@debbugs.gnu.org>; Sun, 18 Oct 2015 10:26:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=6yaJJexNOauGZeYMuxE1axJkDjif0ZamND1Cx+BvDC0=; b=LdhbW7ZwkXyWOquJ8jFhCm4ZyVlwquPNlTx3/6Wa5a3ABQWLR9VMWzuOgdNiW18Ziv A9aShUBINdTM1GL5KLZiPXFFqvCmv8spFy0fRfftn2SJg121BZPib7MSOZ2Lfp3BgNnN 5XOg3FVBCDPRZ1gqhZK1G+KgoA8mHccEDFSWLm/t3DkMGUVTT5kOzF5E8vEq87+khfqS cYXpej1Hl+CI76x64Gz8HOzhdjPu+SM8XeHBLmONqGdJdFW22yEUsjSeiiq+LkYf4Is0 zV96bnhtpRnAbHUXVsb4EnYU4namFYuO+aIq8UdQWfEKmK/jXBjsJOPwH2++errCA0hm Bc1w== X-Received: by 10.107.166.79 with SMTP id p76mr27417664ioe.163.1445189179956; Sun, 18 Oct 2015 10:26:19 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.10.66 with HTTP; Sun, 18 Oct 2015 10:26:00 -0700 (PDT) In-Reply-To: <87oag1aj61.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87d23t1lbk.fsf@redhat.com> <5517574A.2020508@cs.ucla.edu> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> From: Jim Meyering Date: Sun, 18 Oct 2015 10:26:00 -0700 X-Google-Sender-Auth: 3QNs97FnroFKaOeicyKn8pzsku8 Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) Thank you for that patch and for your patience. I've skimmed through and so far have only a question and a request: Regarding this section: +void +set_header_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[1;39m"); +} + +void +set_line_numbers_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[36m"); +} + +void +set_add_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[32m"); + fflush (outfile); +} + +void +set_delete_color_context (void) +{ + process_signals (); + if (colors_enabled) + fprintf (outfile, "\x1B[31m"); +} + +void +reset_color_context (void) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + fputs (reset_sequence, outfile); +} Why does set_add_color_context call fflush, yet the others do not? Please use fputs rather than fprintf for those literal strings. The former is often far more efficient. Finally, should there be some way to specify different colors, e.g., for those who use different-background-colored terminals, or for the color blind? From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 20 Oct 2015 16:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144535820115317 (code B ref 20062); Tue, 20 Oct 2015 16:24:02 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Oct 2015 16:23:21 +0000 Received: from localhost ([127.0.0.1]:58279 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZh1-0003yw-4I for submit@debbugs.gnu.org; Tue, 20 Oct 2015 12:23:21 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60640) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZgv-0003yj-ED for 20062@debbugs.gnu.org; Tue, 20 Oct 2015 12:23:17 -0400 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 6C02AC0C18A6; Tue, 20 Oct 2015 16:23:12 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-40.ams2.redhat.com [10.36.7.40]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9KGN7oL009859 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 20 Oct 2015 12:23:09 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> Date: Tue, 20 Oct 2015 18:23:06 +0200 In-Reply-To: (Jim Meyering's message of "Sun, 18 Oct 2015 10:26:00 -0700") Message-ID: <87wpuh1pcl.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Hi Jim, Jim Meyering writes: > Thank you for that patch and for your patience. thank you very much for the review! > I've skimmed through and so far have only a question and a request: > > Regarding this section: > > +void > +set_header_color_context (void) > +{ > + process_signals (); > + if (colors_enabled) > + fprintf (outfile, "\x1B[1;39m"); > +} > + > +void > +set_line_numbers_color_context (void) > +{ > + process_signals (); > + if (colors_enabled) > + fprintf (outfile, "\x1B[36m"); > +} > + > +void > +set_add_color_context (void) > +{ > + process_signals (); > + if (colors_enabled) > + fprintf (outfile, "\x1B[32m"); > + fflush (outfile); > +} > + > +void > +set_delete_color_context (void) > +{ > + process_signals (); > + if (colors_enabled) > + fprintf (outfile, "\x1B[31m"); > +} > + > +void > +reset_color_context (void) > +{ > + static char const reset_sequence[] = "\x1b[0m"; > + if (! colors_enabled) > + return; > + > + fputs (reset_sequence, outfile); > +} > > Why does set_add_color_context call fflush, yet the others do not? > Please use fputs rather than fprintf for those literal strings. > The former is often far more efficient. Yes, it shouldn't as well. I have changed it. > Finally, should there be some way to specify different colors, > e.g., for those who use different-background-colored terminals, > or for the color blind? I have took more code from coreutils ls and diff honors DIFF_COLORS now. I added it in a separate patch to facilitate the review. Probably all the shared code should end up in a gnulib module, but it probably needs a better API before it can happen. Changes in the first patch: 1) dropped fflush from set_add_color_context 2) use fputs instead of fprintf (the second patch replaces it) 3) change the code color of the header to the default color to match the "git diff" output. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 581c602ef651f99418a086025ad6a035959a7ad7 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH 1/2] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (reset_color_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 51 +++++++-- src/diff.c | 27 ++++- src/diff.h | 21 ++++ src/normal.c | 18 ++- src/side.c | 15 +++ src/util.c | 316 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 421 insertions(+), 48 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..0944b44 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..8e9a74f 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index efd7e47..4e0f602 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..472fa93 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (void); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..227af10 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (); + } } diff --git a/src/side.c b/src/side.c index 155512c..b762d31 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..6cc1411 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,174 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + reset_color_context (); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + +static char const *current_name0; +static char const *current_name1; +static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -150,10 +334,6 @@ print_message_queue (void) we fork off a 'pr' and make OUTFILE a pipe to it. 'pr' then outputs to our stdout. */ -static char const *current_name0; -static char const *current_name1; -static bool currently_recursive; - void setup_output (char const *name0, char const *name1, bool recursive) { @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +855,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,40 +877,92 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; +void +set_header_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[1m", outfile); +} - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_line_numbers_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[36m", outfile); +} - default: - column += isprint (c) != 0; - putc (c, out); - break; - } - } +void +set_add_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[32m", outfile); +} + +void +set_delete_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[31m", outfile); +} + +void +reset_color_context (void) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + fputs (reset_sequence, outfile); } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.4.3 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-diff-honor-env-variable-DIFF_COLORS.patch >From 2e2e078878d04311791c2facd9cac79ec969f24d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 2/2] diff: honor env variable DIFF_COLORS doc/diffutils.texi: Add documentation for DIFF_COLORS src/utils.c (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_header_color_context): Use put_indicator instead of directly outputting the sequence. (set_line_numbers_colors_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 5 + src/util.c | 431 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 427 insertions(+), 9 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 0944b44..75ad0d7 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3763,6 +3763,11 @@ Always use color. Specifying @option{--color} and no @var{when} is equivalent to @option{--color=auto}. +The colors are defined by the environment variable @env{DIFF_COLORS} +and default to @samp{rs=0:hd=1:ad=32:de=31:ln=36} +for red added lines, green deleted lines, cyan line numbers, bold header. + + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/util.c b/src/util.c index 6cc1411..8d27bc7 100644 --- a/src/util.c +++ b/src/util.c @@ -310,6 +310,388 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the DIFF_COLORS variable; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = getenv ("DIFF_COLORS")) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + DIFF_COLORS string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for DIFF_COLORS environment variable")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +705,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -923,12 +1308,27 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + void set_header_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[1m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_HEADER]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -936,7 +1336,11 @@ set_line_numbers_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[36m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_LINE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -944,7 +1348,11 @@ set_add_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[32m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_ADD]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -952,17 +1360,22 @@ set_delete_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[31m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_DELETE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void reset_color_context (void) { - static char const reset_sequence[] = "\x1b[0m"; - if (! colors_enabled) - return; - - fputs (reset_sequence, outfile); + if (colors_enabled) + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_RESET]); + put_indicator (&color_indicator[C_RIGHT]); + } } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.4.3 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 20 Oct 2015 16:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144535837815589 (code B ref 20062); Tue, 20 Oct 2015 16:27:01 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Oct 2015 16:26:18 +0000 Received: from localhost ([127.0.0.1]:58283 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZju-00043N-3V for submit@debbugs.gnu.org; Tue, 20 Oct 2015 12:26:18 -0400 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:33091) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZjZ-00042g-83 for 20062@debbugs.gnu.org; Tue, 20 Oct 2015 12:26:16 -0400 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 71317160D74; Tue, 20 Oct 2015 09:25:56 -0700 (PDT) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 0IP0dTlU8P_G; Tue, 20 Oct 2015 09:25:55 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id CC198160DFD; Tue, 20 Oct 2015 09:25:55 -0700 (PDT) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 04qFM6XmBnsp; Tue, 20 Oct 2015 09:25:55 -0700 (PDT) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id A76F2160D74; Tue, 20 Oct 2015 09:25:55 -0700 (PDT) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <56266B13.2020503@cs.ucla.edu> Date: Tue, 20 Oct 2015 09:25:55 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <87wpuh1pcl.fsf@foo.bar.baz> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) Giuseppe Scrivano wrote: > diff honors DIFF_COLORS > now. Aren't we trying to move away from environment variables' affecting program behavior, given all the maintenance and security hassles that entails? From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 20 Oct 2015 16:43:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Paul Eggert , Giuseppe Scrivano , Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144535936323292 (code B ref 20062); Tue, 20 Oct 2015 16:43:01 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Oct 2015 16:42:43 +0000 Received: from localhost ([127.0.0.1]:58304 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZzm-00063b-Cq for submit@debbugs.gnu.org; Tue, 20 Oct 2015 12:42:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:52665) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoZzk-00063T-6D for 20062@debbugs.gnu.org; Tue, 20 Oct 2015 12:42:41 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id CAA702FE847; Tue, 20 Oct 2015 16:42:38 +0000 (UTC) Received: from [10.3.113.176] (ovpn-113-176.phx2.redhat.com [10.3.113.176]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9KGgbjg004452; Tue, 20 Oct 2015 12:42:38 -0400 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <56266B13.2020503@cs.ucla.edu> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg X-Enigmail-Draft-Status: N1110 Organization: Red Hat, Inc. Message-ID: <56266EF8.7090908@redhat.com> Date: Tue, 20 Oct 2015 10:42:32 -0600 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56266B13.2020503@cs.ucla.edu> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="8LUvQ0oEw4hwmL8K32NKV9kLockmXtFpH" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --8LUvQ0oEw4hwmL8K32NKV9kLockmXtFpH Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 10/20/2015 10:25 AM, Paul Eggert wrote: > Giuseppe Scrivano wrote: >> diff honors DIFF_COLORS >> now. >=20 > Aren't we trying to move away from environment variables' affecting > program behavior, given all the maintenance and security hassles that > entails? I think there's a difference between an environment variable which only affects optional behavior (LS_COLORS, DIFF_COLORS - only affect things for 'ls --color' or 'diff --color') vs. those that affect ALL behavior (GREP_OPTIONS - cruelly affects all executions of grep, no matter what options were in use). You do have a point that allowing the choice to come through a command line option, and wrapping diff behind an alias or shell function, will let the interactive user set up their terminal to get the same effect (typing 'diff' gets the colored version, whether the details were hidden behind an env-var or a shell alias). Other arguments: In favor of an env-var: LS_COLORS is now understood by more than just 'ls' - at least tcsh honors the contents of LS_COLORS (sometimes good, but also annoying when we extend 'ls' to understand new options and then tcsh spews out error messages about unknown directives in LS_COLORS). Likewise, other programs could be taught to honor DIFF_COLORS (git, perhaps?) - but do we then need a common location to specify how it works so that all future programs buy in to the same interpretation? Against env-var: LS_COLORS is already quite large, and we may be adding yet another large env-var in DIFF_COLORS. On some platforms, the environment space is already limited; on mingw, every byte added in the environment is one less byte towards the command line maximum limit (argv and env share the same 64k block of memory - not quite POSIX-y, but not all the world is POSIX). In an interactive environment, the user is already likely to be creating a shell alias/function to turn 'diff' into 'diff --color' - it is not that much harder to have the alias be 'diff --color --option-to-set-colors' compared to 'DIFF_COLORS=3D... diff --color', but= conceptually having it all through the command line rather than split among two sources makes it easier to trace where the change is made. I don't have a strong opinion on whether an env-var is right or wrong, so long as we have at least SOME way to override default colors. But I _do_ think that this is at least a safe env-var if we want to go that route (since it only affects the behavior of opt-in --color usage, rather than all situations). --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --8LUvQ0oEw4hwmL8K32NKV9kLockmXtFpH Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJWJm74AAoJEKeha0olJ0NqaEUH/0VBeuO54411hZG/O/K5bitt RVCmGbRh0WBW3NQ5TvNvgcJch6wceAZFoJCvt4Xmxo7/cyLs28Hvm9jBJgkZKR2/ T4fTE1GHHhJnDqiUXOYLs7q5+hl/Uc4cShsAafVwhe1WCHXivU66NVRZvKcNqsT3 4O0PoNs2E0s3kDrwm306vPMTvOJMyMgQDdVFJ9T5mUnDtf7+kIaoXJsPKFsKU6WX Pa/J/pQab53UMNhUomgZW2ApNEyKgAY88BKNRby9A2BmURr3eHdHdolpkEX1ljSe /EFl84fNc02BE5jwha2fcAXSDudf5uLy1hNK3LTqAU6FLjotCN31LvfXsyN0Z14= =zBhn -----END PGP SIGNATURE----- --8LUvQ0oEw4hwmL8K32NKV9kLockmXtFpH-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Aaron Davies Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 20 Oct 2015 17:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake Cc: Paul Eggert , Giuseppe Scrivano , "20062@debbugs.gnu.org" <20062@debbugs.gnu.org>, Jim Meyering Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14453623731513 (code B ref 20062); Tue, 20 Oct 2015 17:33:02 +0000 Received: (at 20062) by debbugs.gnu.org; 20 Oct 2015 17:32:53 +0000 Received: from localhost ([127.0.0.1]:58350 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZoamK-0000OJ-Nn for submit@debbugs.gnu.org; Tue, 20 Oct 2015 13:32:53 -0400 Received: from mail-qk0-f177.google.com ([209.85.220.177]:35998) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zoalz-0000Ni-Hl for 20062@debbugs.gnu.org; Tue, 20 Oct 2015 13:32:50 -0400 Received: by qkca6 with SMTP id a6so10888181qkc.3 for <20062@debbugs.gnu.org>; Tue, 20 Oct 2015 10:32:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=content-type:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=UjS0fkVqVm03PEAxr+GCBK6XRgYKydALlgIKqcIUUXI=; b=I9oV386pi4YxcesosddpMG5jTqIwpVHM3E9aqfZcXE0tY9oUcYBj2+Cu3Zx5zoPQaN EP18nSVlLByf69Sj/cB3vPKv2zC+Vc2QQmejLlE9utYa4BFAVf3sKAl/HuCS1j2DFjGu 7pKNjsGWI9LkEi2oHt8GePSg6FmSD8mbPvW70THwSjfQO4lRFNpAZiCMYou9WsCri34b PcLO/8tkl7CWPIRWc3W0mcblPUknzsGBjG/wmLTUGzYv+glymGxngZ50hdNDS7BMTSDe Ksh6F3a8fbDKEUxpzDm2sq/nWtFB/UOcuFRwgUu7M6lxd2UwS0uZaYudXTH2+ixDNGyC vprA== X-Received: by 10.55.55.82 with SMTP id e79mr5223457qka.59.1445362351128; Tue, 20 Oct 2015 10:32:31 -0700 (PDT) Received: from [10.180.255.86] (mobile-107-107-57-41.mycingular.net. [107.107.57.41]) by smtp.gmail.com with ESMTPSA id m26sm1638557qki.28.2015.10.20.10.32.30 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 20 Oct 2015 10:32:30 -0700 (PDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (1.0) From: Aaron Davies X-Mailer: iPhone Mail (12F70) In-Reply-To: <56266EF8.7090908@redhat.com> Date: Tue, 20 Oct 2015 13:32:29 -0400 Content-Transfer-Encoding: quoted-printable Message-Id: References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <56266B13.2020503@cs.ucla.edu> <56266EF8.7090908@redhat.com> X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Oct 20, 2015, at 12:42 PM, Eric Blake wrote: >> On 10/20/2015 10:25 AM, Paul Eggert wrote: >> Giuseppe Scrivano wrote: >>> diff honors DIFF_COLORS >>> now. >>=20 >> Aren't we trying to move away from environment variables' affecting >> program behavior, given all the maintenance and security hassles that >> entails? >=20 > I think there's a difference between an environment variable which only > affects optional behavior (LS_COLORS, DIFF_COLORS - only affect things > for 'ls --color' or 'diff --color') vs. those that affect ALL behavior > (GREP_OPTIONS - cruelly affects all executions of grep, no matter what > options were in use). >=20 > You do have a point that allowing the choice to come through a command > line option, and wrapping diff behind an alias or shell function, will > let the interactive user set up their terminal to get the same effect > (typing 'diff' gets the colored version, whether the details were hidden > behind an env-var or a shell alias). >=20 > Other arguments: > In favor of an env-var: > LS_COLORS is now understood by more than just 'ls' - at least tcsh > honors the contents of LS_COLORS (sometimes good, but also annoying when > we extend 'ls' to understand new options and then tcsh spews out error > messages about unknown directives in LS_COLORS). > Likewise, other programs could be taught to honor DIFF_COLORS (git, > perhaps?) - but do we then need a common location to specify how it > works so that all future programs buy in to the same interpretation? >=20 > Against env-var: > LS_COLORS is already quite large, and we may be adding yet another large > env-var in DIFF_COLORS. On some platforms, the environment space is > already limited; on mingw, every byte added in the environment is one > less byte towards the command line maximum limit (argv and env share the > same 64k block of memory - not quite POSIX-y, but not all the world is > POSIX). > In an interactive environment, the user is already likely to be creating > a shell alias/function to turn 'diff' into 'diff --color' - it is not > that much harder to have the alias be 'diff --color > --option-to-set-colors' compared to 'DIFF_COLORS=3D... diff --color', but > conceptually having it all through the command line rather than split > among two sources makes it easier to trace where the change is made. >=20 > I don't have a strong opinion on whether an env-var is right or wrong, > so long as we have at least SOME way to override default colors. But I > _do_ think that this is at least a safe env-var if we want to go that > route (since it only affects the behavior of opt-in --color usage, > rather than all situations). I'm very new here, so feel free to take my opinions with a grain of salt, bu= t one thing I've been noticing in my scripting work is that environment vari= ables' biggest drawback is often also their big advantage: you don't have to= propagate them manually. Suppose you want to encapsulate some common diff operation in a small shell s= cript. Then anything you want that diff to do that you specified in an alias= or function in your interactive shell has to be written out again. Alternatively, you could have a diff wrapper in your ~/bin setting the optio= n, but it's hard to actually write those correctly to handle things like std= in vs. file args. None of this comes with env vars. Still, I understand your other concerns. Maybe a ~/.diffrc is the solution?= From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Wed, 28 Oct 2015 15:30:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Aaron Davies Cc: Paul Eggert , Eric Blake , Jim Meyering , "20062@debbugs.gnu.org" <20062@debbugs.gnu.org> Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144604617219560 (code B ref 20062); Wed, 28 Oct 2015 15:30:03 +0000 Received: (at 20062) by debbugs.gnu.org; 28 Oct 2015 15:29:32 +0000 Received: from localhost ([127.0.0.1]:42671 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZrSfM-00055P-E0 for submit@debbugs.gnu.org; Wed, 28 Oct 2015 11:29:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49908) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZrSf2-00054x-DJ for 20062@debbugs.gnu.org; Wed, 28 Oct 2015 11:29:31 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 3961F8E235; Wed, 28 Oct 2015 15:29:11 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-84.ams2.redhat.com [10.36.7.84]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9SFT7nL016197 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 28 Oct 2015 11:29:08 -0400 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <56266B13.2020503@cs.ucla.edu> <56266EF8.7090908@redhat.com> Date: Wed, 28 Oct 2015 16:29:06 +0100 In-Reply-To: (Aaron Davies's message of "Tue, 20 Oct 2015 13:32:29 -0400") Message-ID: <87y4enj9kt.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) Aaron Davies writes: > I'm very new here, so feel free to take my opinions with a grain of salt, but one thing I've been noticing in my scripting work is that environment variables' biggest drawback is often also their big advantage: you don't have to propagate them manually. > > Suppose you want to encapsulate some common diff operation in a small shell script. Then anything you want that diff to do that you specified in an alias or function in your interactive shell has to be written out again. > > Alternatively, you could have a diff wrapper in your ~/bin setting the option, but it's hard to actually write those correctly to handle things like stdin vs. file args. > > None of this comes with env vars. > > Still, I understand your other concerns. > > Maybe a ~/.diffrc is the solution? that could be a good solution, and probably other kind of options can be moved but IMHO it seems a bit over-engineered to read just the colors settings. If the choice is between an env variable or adding a new command line argument, the former makes more sense as it works similarly to other tools that people already know. If there is any strong argument against not using an environment variable as this patch is doing, I will rework the patch to use a command line argument instead. Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 05:08:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144644084422847 (code B ref 20062); Mon, 02 Nov 2015 05:08:01 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 05:07:24 +0000 Received: from localhost ([127.0.0.1]:48353 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zt7L1-0005wR-Db for submit@debbugs.gnu.org; Mon, 02 Nov 2015 00:07:23 -0500 Received: from mail-vk0-f52.google.com ([209.85.213.52]:34018) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zt7Kh-0005vw-67 for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 00:07:21 -0500 Received: by vkgs66 with SMTP id s66so78877822vkg.1 for <20062@debbugs.gnu.org>; Sun, 01 Nov 2015 21:07:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=HYpZy5mUz4UekO8Tk29O+RelpMAAweJFQ9XnpPTYXZ8=; b=yBYgapgTaybIFhl3erWtQpLy7wcDK0pTjRZ7xzUwAU50ThgFRib18L3aWNQJDzowJY fB5dyy1KUqVjtxWTvCU/0ECYY6qtlbxOc/1qgCgJ9XhR0vEX7EzqiGPpeopp26legrJo DXTQSEr0NS1mGXHBQ/PDFWRXm42G1ifCy+SbBIwHBxf7qIkOmXo2qNzPLZjw5sqgWECQ K67aNlRyfq8kbf9Gaujkw0BNODHMYZS8noE7XMNA6hH/YaUNBMMdrHa+RSVAHCOMhyRx Txer8v/csZCRVDaR7i/VMPVF6+SGLi71ER2VmVmXXAQtsdnTDSnAZpZkdThfj0w79aNx pFjg== X-Received: by 10.31.155.138 with SMTP id d132mr13687605vke.55.1446440822912; Sun, 01 Nov 2015 21:07:02 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.65.11 with HTTP; Sun, 1 Nov 2015 21:06:43 -0800 (PST) In-Reply-To: <87wpuh1pcl.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> From: Jim Meyering Date: Sun, 1 Nov 2015 21:06:43 -0800 X-Google-Sender-Auth: KIdvUHWApCKROiM1J0x2Vc1oGNY Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Tue, Oct 20, 2015 at 9:23 AM, Giuseppe Scrivano wrote: > Hi Jim, > > Jim Meyering writes: > >> Thank you for that patch and for your patience. > > thank you very much for the review! > >> I've skimmed through and so far have only a question and a request: ... >> Why does set_add_color_context call fflush, yet the others do not? >> Please use fputs rather than fprintf for those literal strings. >> The former is often far more efficient. > > Yes, it shouldn't as well. I have changed it. Thanks for the quick work. I'll try to be quicker, this time. >> Finally, should there be some way to specify different colors, >> e.g., for those who use different-background-colored terminals, >> or for the color blind? > > I have took more code from coreutils ls and diff honors DIFF_COLORS > now. I added it in a separate patch to facilitate the review. Probably > all the shared code should end up in a gnulib module, but it probably > needs a better API before it can happen. > > Changes in the first patch: > > 1) dropped fflush from set_add_color_context > 2) use fputs instead of fprintf (the second patch replaces it) > 3) change the code color of the header to the default color to match > the "git diff" output. Those revisions to your first patch look fine, and I will look over that one once more in the morning, then expect to push. Regarding the support for configurable colors, as already mentioned here, we really do want to avoid adding support for any more environment variables. Would you please adjust the second patch to take the settings from a command line argument instead? With that, it will be trivial to add an envvar-honoring wrapper script, function or alias, for those who desire that convenience. The most important reason not to provide this functionality via an envvar is that it would then allow that envvar setting to alter the behavior of any program that invokes diff, and that sort of interaction is often surprising and undesirable. Thanks again for contributing! From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 15:07:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Paul Eggert , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144647680122848 (code B ref 20062); Mon, 02 Nov 2015 15:07:02 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 15:06:41 +0000 Received: from localhost ([127.0.0.1]:49825 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtGgz-0005wR-05 for submit@debbugs.gnu.org; Mon, 02 Nov 2015 10:06:41 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38178) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtGgv-0005wG-VW for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 10:06:39 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 26D9B19CB9D; Mon, 2 Nov 2015 15:06:36 +0000 (UTC) Received: from foo.bar.baz (vpn1-6-75.ams2.redhat.com [10.36.6.75]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2F6WR3011235 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 2 Nov 2015 10:06:34 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> Date: Mon, 02 Nov 2015 16:06:31 +0100 In-Reply-To: (Jim Meyering's message of "Sun, 1 Nov 2015 21:06:43 -0800") Message-ID: <87h9l4tp8o.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Hi Jim, Jim Meyering writes: > Regarding the support for configurable colors, as already mentioned > here, we really do want to avoid adding support for any more > environment variables. Would you please adjust the second > patch to take the settings from a command line argument instead? > With that, it will be trivial to add an envvar-honoring wrapper script, > function or alias, for those who desire that convenience. > > The most important reason not to provide this functionality via > an envvar is that it would then allow that envvar setting to alter > the behavior of any program that invokes diff, and that sort of > interaction is often surprising and undesirable. > > Thanks again for contributing! Thanks for your review. Would something like this patch work? I have attached the difference from the previous version to make the review easier as few lines are changed. I have included the full ChangeLog entries in the commit message so it will be easier to squash the patch on top of the previous one. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-squash-diff-honor-env-variable-DIFF_COLORS.patch >From 0ed880f2e6f76809563597cc698da4c15b19ba1d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 15:43:23 +0100 Subject: [PATCH] squash! diff: honor env variable DIFF_COLORS diff: add --color-scheme doc/diffutils.texi: Add documentation for --color-scheme src/diff.h (set_color_scheme): New prototype. src/diff.c (set_color_scheme): New function. (color_scheme): New variable. src/utils.c (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_header_color_context): Use put_indicator instead of directly outputting the sequence. (set_line_numbers_colors_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 7 ++++--- src/diff.c | 6 ++++++ src/diff.h | 1 + src/util.c | 10 +++++++++- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 75ad0d7..9f2cdbb 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3763,9 +3763,10 @@ Always use color. Specifying @option{--color} and no @var{when} is equivalent to @option{--color=auto}. -The colors are defined by the environment variable @env{DIFF_COLORS} -and default to @samp{rs=0:hd=1:ad=32:de=31:ln=36} -for red added lines, green deleted lines, cyan line numbers, bold header. +@item --color-scheme=@var{scheme} +It allows to specify what colors are used to colorize the output. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red added lines, +green deleted lines, cyan line numbers, bold header. @item -C @var{lines} diff --git a/src/diff.c b/src/diff.c index 4e0f602..55ed69d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_SCHEME_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -163,6 +164,7 @@ static struct option const longopts[] = {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, {"color", 2, 0, COLOR_OPTION}, + {"color-scheme", 1, 0, COLOR_SCHEME_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_SCHEME_OPTION: + set_color_scheme (optarg); + break; + default: try_help (NULL, NULL); } diff --git a/src/diff.h b/src/diff.h index 472fa93..883119e 100644 --- a/src/diff.h +++ b/src/diff.h @@ -411,3 +411,4 @@ extern void set_add_color_context (void); extern void set_delete_color_context (void); extern void reset_color_context (void); extern void set_line_numbers_color_context (void); +extern void set_color_scheme (const char *scheme); diff --git a/src/util.c b/src/util.c index 8d27bc7..108b8e0 100644 --- a/src/util.c +++ b/src/util.c @@ -562,6 +562,14 @@ static const char *const indicator_name[]= "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL }; +static const char *color_scheme; + +void +set_color_scheme (const char *scheme) +{ + color_scheme = scheme; +} + static void parse_diff_color (void) { @@ -572,7 +580,7 @@ parse_diff_color (void) char label[3]; /* Indicator label */ struct color_ext_type *ext; /* Extension we are working on */ - if ((p = getenv ("DIFF_COLORS")) == NULL || *p == '\0') + if ((p = color_scheme) == NULL || *p == '\0') return; ext = NULL; -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 17:17:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14464845789050 (code B ref 20062); Mon, 02 Nov 2015 17:17:01 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 17:16:18 +0000 Received: from localhost ([127.0.0.1]:49919 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtIiQ-0002Lt-8E for submit@debbugs.gnu.org; Mon, 02 Nov 2015 12:16:18 -0500 Received: from mail-vk0-f50.google.com ([209.85.213.50]:36262) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtIi5-0002Kx-UJ for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 12:16:16 -0500 Received: by vkex70 with SMTP id x70so88872188vke.3 for <20062@debbugs.gnu.org>; Mon, 02 Nov 2015 09:15:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=ZZNL58WAKdmjd7HW/DoLbBngnT4+MRpTPQKTY4I5aUs=; b=D24aJtBM+f9M+Ms2vCNOzxWppT0/vA+PgzF4aSxc6XQKUhqa4pE2utfkaff36PCAqw SaQCUQlVLPwSrsjRt5w+6dc41pVS4+5eRzuBgv69rj1vucYpa/GQSLi4FjUReRbCPRpE uwosc1L8T/RNjun6ZpQel9mMDjyYkJav8OmA2NKAH8/142WPhBERB2NZ7NJyFzFzOB8D Was5kCbdE4anusnKAmHiX4FV3Tx3i6rqoDXbzejtozEFfHo/8ypLL15CZuh2N9RFbNec gfe1n9s6Qoy6j1Zp8hJqaRJDEMyiMYzvcOGKx5trsAdGitzNVAVVtKW9zVBYb3CzTwxM 1w9A== X-Received: by 10.31.8.4 with SMTP id 4mr15358418vki.77.1446484557299; Mon, 02 Nov 2015 09:15:57 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.65.11 with HTTP; Mon, 2 Nov 2015 09:15:37 -0800 (PST) In-Reply-To: References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87fv7uleyp.fsf@redhat.com> <55358394.5040809@cs.ucla.edu> <87r3rbg9qc.fsf@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> From: Jim Meyering Date: Mon, 2 Nov 2015 09:15:37 -0800 X-Google-Sender-Auth: qw36WXKyQclpnwBSP99hlZ5pjgE Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Sun, Nov 1, 2015 at 9:06 PM, Jim Meyering wrote: > On Tue, Oct 20, 2015 at 9:23 AM, Giuseppe Scrivano wrote: >> Hi Jim, >> >> Jim Meyering writes: >> >>> Thank you for that patch and for your patience. >> >> thank you very much for the review! >> >>> I've skimmed through and so far have only a question and a request: > ... >>> Why does set_add_color_context call fflush, yet the others do not? >>> Please use fputs rather than fprintf for those literal strings. >>> The former is often far more efficient. >> >> Yes, it shouldn't as well. I have changed it. > > Thanks for the quick work. > I'll try to be quicker, this time. > >>> Finally, should there be some way to specify different colors, >>> e.g., for those who use different-background-colored terminals, >>> or for the color blind? >> >> I have took more code from coreutils ls and diff honors DIFF_COLORS >> now. I added it in a separate patch to facilitate the review. Probably >> all the shared code should end up in a gnulib module, but it probably >> needs a better API before it can happen. >> >> Changes in the first patch: >> >> 1) dropped fflush from set_add_color_context >> 2) use fputs instead of fprintf (the second patch replaces it) >> 3) change the code color of the header to the default color to match >> the "git diff" output. > > Those revisions to your first patch look fine, and I will look over that > one once more in the morning, then expect to push. Your first patch adds a useful new feature, but includes neither a NEWS addition nor any test. Would you please add those? From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 19:18:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144649183520777 (code B ref 20062); Mon, 02 Nov 2015 19:18:01 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 19:17:15 +0000 Received: from localhost ([127.0.0.1]:49964 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtKbS-0005P2-LJ for submit@debbugs.gnu.org; Mon, 02 Nov 2015 14:17:15 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39868) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtKbP-0005Ot-UC for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 14:17:13 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 17469C1C74E2; Mon, 2 Nov 2015 19:17:11 +0000 (UTC) Received: from foo.bar.baz (vpn1-6-75.ams2.redhat.com [10.36.6.75]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2JH8NC031509 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 2 Nov 2015 14:17:09 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> Date: Mon, 02 Nov 2015 20:17:07 +0100 In-Reply-To: (Jim Meyering's message of "Mon, 2 Nov 2015 09:15:37 -0800") Message-ID: <87bnbcrz2k.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) Jim Meyering writes: > On Sun, Nov 1, 2015 at 9:06 PM, Jim Meyering wrote: >> On Tue, Oct 20, 2015 at 9:23 AM, Giuseppe Scrivano wrote: >>> Hi Jim, >>> >>> Jim Meyering writes: >>> >>>> Thank you for that patch and for your patience. >>> >>> thank you very much for the review! >>> >>>> I've skimmed through and so far have only a question and a request: >> ... >>>> Why does set_add_color_context call fflush, yet the others do not? >>>> Please use fputs rather than fprintf for those literal strings. >>>> The former is often far more efficient. >>> >>> Yes, it shouldn't as well. I have changed it. >> >> Thanks for the quick work. >> I'll try to be quicker, this time. >> >>>> Finally, should there be some way to specify different colors, >>>> e.g., for those who use different-background-colored terminals, >>>> or for the color blind? >>> >>> I have took more code from coreutils ls and diff honors DIFF_COLORS >>> now. I added it in a separate patch to facilitate the review. Probably >>> all the shared code should end up in a gnulib module, but it probably >>> needs a better API before it can happen. >>> >>> Changes in the first patch: >>> >>> 1) dropped fflush from set_add_color_context >>> 2) use fputs instead of fprintf (the second patch replaces it) >>> 3) change the code color of the header to the default color to match >>> the "git diff" output. >> >> Those revisions to your first patch look fine, and I will look over that >> one once more in the morning, then expect to push. > > Your first patch adds a useful new feature, but includes > neither a NEWS addition nor any test. Would you please add those? sure, I will do. I forgot to update "option_help_msgid" in my previous patch which adds --color-scheme to define the colors used by diff. Anyway, I would like an opinion about the new name before I send te full series again. I avoided --colors as it is very similar to --color, but I am not sure how --color-scheme sounds for a native speaker. Regards, Giuseppe From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 19:35:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144649287628729 (code B ref 20062); Mon, 02 Nov 2015 19:35:02 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 19:34:36 +0000 Received: from localhost ([127.0.0.1]:49979 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtKsF-0007TH-Dq for submit@debbugs.gnu.org; Mon, 02 Nov 2015 14:34:35 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43482) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtKrv-0007Sn-8O for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 14:34:34 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 121C88CF6E; Mon, 2 Nov 2015 19:34:13 +0000 (UTC) Received: from [10.3.113.189] (ovpn-113-189.phx2.redhat.com [10.3.113.189]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2JYCKf021740; Mon, 2 Nov 2015 14:34:13 -0500 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg Organization: Red Hat, Inc. Message-ID: <5637BAAC.8020301@redhat.com> Date: Mon, 2 Nov 2015 12:34:04 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <87bnbcrz2k.fsf@foo.bar.baz> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="nKL9lNoDeG4DSb04q0NmtBtwqE74MSR7p" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --nKL9lNoDeG4DSb04q0NmtBtwqE74MSR7p Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 11/02/2015 12:17 PM, Giuseppe Scrivano wrote: > Anyway, I would like an opinion about the new name before I send te ful= l > series again. I avoided --colors as it is very similar to --color, but= > I am not sure how --color-scheme sounds for a native speaker. --color-scheme sounds okay to a native, but has the issue that it cannot be abbreviated (--col would be short for --color, not --color-scheme). Can you come up with a name that does not share a common prefix? Maybe --palette? --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --nKL9lNoDeG4DSb04q0NmtBtwqE74MSR7p Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJWN7qsAAoJEKeha0olJ0NqE5gH/AvfePAaAsejaWJbJckDvCda CNVYWrDzMRjqejdCL61v2XA+oNBU5pU/DdfolTPVd5aZw4Wn3qWxWgS80y29HQK4 TnHO/HasYoWWcDxQ8/Qx1hhdfXOvFjTvvJqgbatBewKzJzomdua7iOuxnkfmXVcP aAgi5ltHg4UPuw33CRVVh/H1zPH9vyHGAhV8u0LHXjN8qHmAe8lfKXlCwd7Rx9PV BcqaXXWgITIESrr5lF+N58zKbVkVJE6e+7dGAszgpgdrvn9RGiXn0f30nplPa1iU XHqmm+SSo5pxmKdyL1mWw/rh9i5pGs3/Xtzffs9QIkx5eG8AXoK/uuaUVE8QTek= =t0mH -----END PGP SIGNATURE----- --nKL9lNoDeG4DSb04q0NmtBtwqE74MSR7p-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 21:22:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake Cc: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14464992916909 (code B ref 20062); Mon, 02 Nov 2015 21:22:01 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 21:21:31 +0000 Received: from localhost ([127.0.0.1]:50028 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtMXi-0001nN-NY for submit@debbugs.gnu.org; Mon, 02 Nov 2015 16:21:30 -0500 Received: from mail-vk0-f50.google.com ([209.85.213.50]:35765) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtMXg-0001nE-1Y for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 16:21:28 -0500 Received: by vkfw189 with SMTP id w189so93492397vkf.2 for <20062@debbugs.gnu.org>; Mon, 02 Nov 2015 13:21:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=TUf9lMrr05wuoo/kHYRcr78aLv3LrkJtqueOpBXF4jU=; b=w3xw2MD/20GAdZEYKupAZ0aXmoI9N+Fy57goLfMJU0yinONUjiEgIok52kxajqGVjt VMA13hAMBO2/P3b+HjgeaMk4/J153ijWp7DzxIzvZMhBNXajduXbTZcEuqXBdAyssVvG HSrAadaesjpbyXe4ZXs17h+c+HYYidMI5BFpE6iA/mumaNrzmpm3noL+8PDJpy8GdvTo WGV+gRfFqXZhryJyLPxSDf5fvUAijdmNTSALswDs6fbblxOfTtnsRd9S2rcR8Y0tu3Vv 7izsbUmMvn04GajRHJdcN1F1VHOfeiRe7U2bivfO2sztUz006uxl3V+ie2rJW9WWs2sS Ctng== X-Received: by 10.31.155.138 with SMTP id d132mr16322221vke.55.1446499287532; Mon, 02 Nov 2015 13:21:27 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.65.11 with HTTP; Mon, 2 Nov 2015 13:21:08 -0800 (PST) In-Reply-To: <5637BAAC.8020301@redhat.com> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> From: Jim Meyering Date: Mon, 2 Nov 2015 13:21:08 -0800 X-Google-Sender-Auth: HVDnyzs1Gdz-B5_DlUX45v5zdto Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Mon, Nov 2, 2015 at 11:34 AM, Eric Blake wrote: > On 11/02/2015 12:17 PM, Giuseppe Scrivano wrote: > >> Anyway, I would like an opinion about the new name before I send te full >> series again. I avoided --colors as it is very similar to --color, but >> I am not sure how --color-scheme sounds for a native speaker. > > --color-scheme sounds okay to a native, but has the issue that it cannot > be abbreviated (--col would be short for --color, not --color-scheme). > Can you come up with a name that does not share a common prefix? Maybe > --palette? Good point. I too prefer --palette='...' That does have the tiny downside that diff's rarely used --paginate option will no longer be able to be abbreviated as "--pa", but that is barely worth mentioning. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Mon, 02 Nov 2015 21:27:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14464995737475 (code B ref 20062); Mon, 02 Nov 2015 21:27:02 +0000 Received: (at 20062) by debbugs.gnu.org; 2 Nov 2015 21:26:13 +0000 Received: from localhost ([127.0.0.1]:50036 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtMcH-0001wU-6v for submit@debbugs.gnu.org; Mon, 02 Nov 2015 16:26:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41034) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtMcE-0001wH-07 for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 16:26:10 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 421EC42E5B2; Mon, 2 Nov 2015 21:26:09 +0000 (UTC) Received: from [10.3.113.189] (ovpn-113-189.phx2.redhat.com [10.3.113.189]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA2LQ7Zt016583; Mon, 2 Nov 2015 16:26:08 -0500 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg Organization: Red Hat, Inc. Message-ID: <5637D4EF.8000604@redhat.com> Date: Mon, 2 Nov 2015 14:26:07 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="vRtUe9oeq3VJt2SQ3C3VBwm8CIerwn1EN" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --vRtUe9oeq3VJt2SQ3C3VBwm8CIerwn1EN Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 11/02/2015 02:21 PM, Jim Meyering wrote: > I too prefer --palette=3D'...' > That does have the tiny downside that diff's rarely used > --paginate option will no longer be able to be abbreviated > as "--pa", but that is barely worth mentioning. Why do we even have -l/--paginate instead of telling people to run 'diff | pr'? Is it worth deprecating that option? --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --vRtUe9oeq3VJt2SQ3C3VBwm8CIerwn1EN Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJWN9TvAAoJEKeha0olJ0NqRP8H/35N7P90S/Ms2PPmfbsvUXKE qhPHboErT6E3n8EfDaU+Y5ocDIVLaIwa14oIyVe7zlrb6HHmez4BGMMAkHRTYMmk GrggvQQBe/sJFvqJHRCz3zzwSFop8NxbrTf46RaQ8hXPxgxnky3qUZrpmvy+j4WI /+QF1R7wo9rFWKFb/vo8zwtxxnLwZrY7CZYtFKA821utly/csL4putE/ZyQLyqWR PjD7/FSq9UkTG6/OTmETcUxxjR7ymr+ftmjr2WgwtXZdQrAvye5/Xcfn8tNi+jVm zfs8pWKTEXIJrSt5t0mUHWb0TvU1CdYc4v8nMQxtyzuWVnShj2ywIymT7HNu3K4= =wSgf -----END PGP SIGNATURE----- --vRtUe9oeq3VJt2SQ3C3VBwm8CIerwn1EN-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Paul Eggert Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 03 Nov 2015 02:22:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake , Jim Meyering Cc: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144651730015008 (code B ref 20062); Tue, 03 Nov 2015 02:22:02 +0000 Received: (at 20062) by debbugs.gnu.org; 3 Nov 2015 02:21:40 +0000 Received: from localhost ([127.0.0.1]:50224 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtREC-0003tz-9s for submit@debbugs.gnu.org; Mon, 02 Nov 2015 21:21:40 -0500 Received: from zimbra.cs.ucla.edu ([131.179.128.68]:53057) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtREA-0003tr-M9 for 20062@debbugs.gnu.org; Mon, 02 Nov 2015 21:21:39 -0500 Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 2CFE516063E; Mon, 2 Nov 2015 18:21:37 -0800 (PST) Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id KyTyRyyfksop; Mon, 2 Nov 2015 18:21:36 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by zimbra.cs.ucla.edu (Postfix) with ESMTP id 6F46B160D6A; Mon, 2 Nov 2015 18:21:36 -0800 (PST) X-Virus-Scanned: amavisd-new at zimbra.cs.ucla.edu Received: from zimbra.cs.ucla.edu ([127.0.0.1]) by localhost (zimbra.cs.ucla.edu [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id nf35Z31Ei0Qw; Mon, 2 Nov 2015 18:21:36 -0800 (PST) Received: from [192.168.1.9] (pool-100-32-155-148.lsanca.fios.verizon.net [100.32.155.148]) by zimbra.cs.ucla.edu (Postfix) with ESMTPSA id 45AD116063E; Mon, 2 Nov 2015 18:21:36 -0800 (PST) References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55382807.3020408@cs.ucla.edu> <87y4jf24w8.fsf@foo.bar.baz> <5584B2CB.7040104@cs.ucla.edu> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <5637D4EF.8000604@redhat.com> From: Paul Eggert Organization: UCLA Computer Science Department Message-ID: <56381A2D.10401@cs.ucla.edu> Date: Mon, 2 Nov 2015 18:21:33 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <5637D4EF.8000604@redhat.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.0 (/) Eric Blake wrote: > Why do we even have -l/--paginate 4.3BSD had it. As you mention, -l was a bad idea, but we wanted to be compatible with BSD. I suppose we could deprecate it at some point.... From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 03 Nov 2015 17:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144657036017050 (code B ref 20062); Tue, 03 Nov 2015 17:06:02 +0000 Received: (at 20062) by debbugs.gnu.org; 3 Nov 2015 17:06:00 +0000 Received: from localhost ([127.0.0.1]:51686 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Ztf1g-0004QS-HF for submit@debbugs.gnu.org; Tue, 03 Nov 2015 12:06:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57147) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Ztf1a-0004QF-RB for 20062@debbugs.gnu.org; Tue, 03 Nov 2015 12:05:36 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id CC8FA19F27D; Tue, 3 Nov 2015 17:05:33 +0000 (UTC) Received: from foo.bar.baz (vpn1-5-245.ams2.redhat.com [10.36.5.245]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3H5TAl015634 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Tue, 3 Nov 2015 12:05:31 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> Date: Tue, 03 Nov 2015 18:05:29 +0100 In-Reply-To: (Jim Meyering's message of "Mon, 2 Nov 2015 13:21:08 -0800") Message-ID: <87fv0nko86.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Jim Meyering writes: > On Mon, Nov 2, 2015 at 11:34 AM, Eric Blake wrote: >> On 11/02/2015 12:17 PM, Giuseppe Scrivano wrote: >> >>> Anyway, I would like an opinion about the new name before I send te full >>> series again. I avoided --colors as it is very similar to --color, but >>> I am not sure how --color-scheme sounds for a native speaker. >> >> --color-scheme sounds okay to a native, but has the issue that it cannot >> be abbreviated (--col would be short for --color, not --color-scheme). >> Can you come up with a name that does not share a common prefix? Maybe >> --palette? > > Good point. > I too prefer --palette='...' > That does have the tiny downside that diff's rarely used > --paginate option will no longer be able to be abbreviated > as "--pa", but that is barely worth mentioning. I have attached the patches that implement --palette, the missing tests and update the NEWS file. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-palette.patch >From f7bf589e9a0c4b893837cfbbdaae5543d72c2b85 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 1/3] diff: add --palette * doc/diffutils.texi: Add documentation for --palette * src/diff.h (set_color_palette): New prototype. * src/diff.c (set_color_palette): New function. (color_palette): New variable. * src/utils.c (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_header_color_context): Use put_indicator instead of directly outputting the sequence. (set_line_numbers_colors_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 6 + src/diff.c | 7 + src/diff.h | 1 + src/util.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 444 insertions(+), 9 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 0944b44..b689673 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3763,6 +3763,7 @@ Always use color. Specifying @option{--color} and no @var{when} is equivalent to @option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of @@ -3890,6 +3891,11 @@ if-then-else format. @xref{Line Formats}. @itemx --show-c-function Show which C function each change is in. @xref{C Function Headings}. +@item --palette=@var{scheme} +It allows to specify what colors are used to colorize the output. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red added lines, +green deleted lines, cyan line numbers, bold header. + @item -q @itemx --brief Report only whether the files differ, not the details of the diff --git a/src/diff.c b/src/diff.c index 4e0f602..f5298e1 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_PALETTE_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -196,6 +197,7 @@ static struct option const longopts[] = {"old-group-format", 1, 0, OLD_GROUP_FORMAT_OPTION}, {"old-line-format", 1, 0, OLD_LINE_FORMAT_OPTION}, {"paginate", 0, 0, 'l'}, + {"palette", 1, 0, COLOR_PALETTE_OPTION}, {"rcs", 0, 0, 'n'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_PALETTE_OPTION: + set_color_palette (optarg); + break; + default: try_help (NULL, NULL); } @@ -950,6 +956,7 @@ static char const * const option_help_msgid[] = { N_(" --speed-large-files assume large files and many scattered small changes"), N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), N_(" or 'auto' (the default)"), + N_(" --palette=SCHEME specify the colors to use when --color is active"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), diff --git a/src/diff.h b/src/diff.h index 472fa93..5930cd1 100644 --- a/src/diff.h +++ b/src/diff.h @@ -411,3 +411,4 @@ extern void set_add_color_context (void); extern void set_delete_color_context (void); extern void reset_color_context (void); extern void set_line_numbers_color_context (void); +extern void set_color_palette (const char *palette); diff --git a/src/util.c b/src/util.c index 6cc1411..50dce82 100644 --- a/src/util.c +++ b/src/util.c @@ -310,6 +310,396 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the DIFF_COLORS variable; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; + +static const char *color_palette; + +void +set_color_palette (const char *palette) +{ + color_palette = palette; +} + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = color_palette) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + DIFF_COLORS string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for DIFF_COLORS environment variable")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +713,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -923,12 +1316,27 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + void set_header_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[1m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_HEADER]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -936,7 +1344,11 @@ set_line_numbers_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[36m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_LINE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -944,7 +1356,11 @@ set_add_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[32m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_ADD]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -952,17 +1368,22 @@ set_delete_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[31m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_DELETE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void reset_color_context (void) { - static char const reset_sequence[] = "\x1b[0m"; - if (! colors_enabled) - return; - - fputs (reset_sequence, outfile); + if (colors_enabled) + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_RESET]); + put_indicator (&color_indicator[C_RIGHT]); + } } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-doc-mention-color-and-palette-in-NEWS.patch >From 1e9f443fcd587bd6e137d7c627d3a250d09ca5c2 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:03:32 +0000 Subject: [PATCH 2/3] doc: mention --color and --palette in NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 7cdfedd..685dc9d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU diffutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + diff accepts two new options --color and --palette to set a colored + output. --color takes an optional argument specifying when to + colorize a line: --color=always, --color=auto, --color=never. + --palette is used to change the used colors. + ** Bug fixes When binary files differ, diff now exits with status 1 as POSIX requires. -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-tests-Add-tests-for-color-and-palette.patch >From 091ffa10f77e0e006d7173b2e7efb21966075824 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:05:10 +0000 Subject: [PATCH 3/3] tests: Add tests for --color and --palette * tests/colors: New file. * tests/Makefile.am (TESTS): Add colors. --- tests/Makefile.am | 3 ++- tests/colors | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100755 tests/colors diff --git a/tests/Makefile.am b/tests/Makefile.am index 438fbdf..805ccc2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ TESTS = \ no-newline-at-eof \ stdin \ strcoll-0-names \ - filename-quoting + filename-quoting \ + colors EXTRA_DIST = \ $(TESTS) init.sh t-local.sh diff --git a/tests/colors b/tests/colors new file mode 100755 index 0000000..9e1ef40 --- /dev/null +++ b/tests/colors @@ -0,0 +1,38 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=UTC0 +export TZ + +fail=0 + +echo a > a +echo b > b + +touch --date='1970-01-01 00:00:00' a b + +# Compare with some known outputs + +diff --color=always a b | sha1sum \ + | grep dbed959c9975cf761ff4950d93d342d7c271c11f || fail=1 + +diff --color=auto a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff --color=never a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff --color a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff -u --color=always a b | sha1sum \ + | grep 5712fbffc94c501eaeec5cb02468ce2bbed6d7c9 || fail=1 + +diff -c --color=always a b | sha1sum \ + | grep 904a91f82474e3532459b759fdacbdb339070e14 || fail=1 + +diff -N --color=always --palette="rs=0:hd=33:ad=34:de=35:ln=36" a b \ + | sha1sum | grep 7796a82c2e7bd1f4ee04cb44352d83e1db87c092 || fail=1 + +Exit $fail -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 03 Nov 2015 17:28:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144657164025243 (code B ref 20062); Tue, 03 Nov 2015 17:28:01 +0000 Received: (at 20062) by debbugs.gnu.org; 3 Nov 2015 17:27:20 +0000 Received: from localhost ([127.0.0.1]:51703 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfMd-0006Z5-If for submit@debbugs.gnu.org; Tue, 03 Nov 2015 12:27:20 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47854) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfMa-0006Yw-T6 for 20062@debbugs.gnu.org; Tue, 03 Nov 2015 12:27:17 -0500 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id DD35EA4507; Tue, 3 Nov 2015 17:27:15 +0000 (UTC) Received: from [10.3.113.189] (ovpn-113-189.phx2.redhat.com [10.3.113.189]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3HRFqf001795; Tue, 3 Nov 2015 12:27:15 -0500 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg X-Enigmail-Draft-Status: N1110 Organization: Red Hat, Inc. Message-ID: <5638EE6E.3050901@redhat.com> Date: Tue, 3 Nov 2015 10:27:10 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <87fv0nko86.fsf@foo.bar.baz> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="iGKRV9wqRvHfDfEgSg7GAsJ6Kj0p6iTmg" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --iGKRV9wqRvHfDfEgSg7GAsJ6Kj0p6iTmg Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 11/03/2015 10:05 AM, Giuseppe Scrivano wrote: > I have attached the patches that implement --palette, the missing tests= > and update the NEWS file. >=20 > +++ b/doc/diffutils.texi > @@ -3763,6 +3763,7 @@ Always use color. > Specifying @option{--color} and no @var{when} is equivalent to > @option{--color=3Dauto}. > =20 > + > @item -C @var{lines} Spurious change? > @itemx --context@r{[}=3D@var{lines}@r{]} > Use the context output format, showing @var{lines} (an integer) lines = of > @@ -3890,6 +3891,11 @@ if-then-else format. @xref{Line Formats}. > @itemx --show-c-function > Show which C function each change is in. @xref{C Function Headings}. > =20 > +@item --palette=3D@var{scheme} > +It allows to specify what colors are used to colorize the output. It Passive voice. Would sound better as: Specify what color palette to use when colored output to use. > +defaults to @samp{rs=3D0:hd=3D1:ad=3D32:de=3D31:ln=3D36} for red added= lines, > +green deleted lines, cyan line numbers, bold header. That says the default, but doesn't say what conventions to apply to get something other than the default. What are 'rs', 'hd', 'ad', 'de', and 'ln'? Can we link to the fact that the values of these variables are generally applied inside a terminal '\e[Xm' sequence, for a given X? Can we link to dircolors output for comparison? Do we need parameters for the '\e[' and 'm' prefix/suffix, in case the terminal understands something different than ANSI escapes for colors? > @@ -950,6 +956,7 @@ static char const * const option_help_msgid[] =3D {= > N_(" --speed-large-files assume large files and many scattered s= mall changes"), > N_(" --color[=3DWHEN] colorize the output; WHEN can be 'n= ever', 'always',"), > N_(" or 'auto' (the default)"), > + N_(" --palette=3DSCHEME specify the colors to use when --color= is active"), > "", > N_(" --help display this help and exit"), > N_("-v, --version output version information and exit"), Where is SCHEME documented in --help? Should it be? > + > +/* Parse a string as part of the DIFF_COLORS variable; this may involv= e Stale reference to envvar instead of --palette. > + > +static struct bin_str color_indicator[] =3D > + { > + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ > + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ > + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ > + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ > + { LEN_STR_PAIR ("1") }, /* hd: Header */ > + { LEN_STR_PAIR ("32") }, /* ad: Add line */ > + { LEN_STR_PAIR ("31") }, /* de: Delete line */ > + { LEN_STR_PAIR ("36") }, /* ln: Line number */ > + }; This needs to be documented in more than just code comments. > + ext =3D NULL; > + strcpy (label, "??"); > + > + /* This is an overly conservative estimate, but any possible > + DIFF_COLORS string will *not* generate a color_buf longer than > + itself, so it is a safe way of allocating a buffer in > + advance. */ > + buf =3D color_buf =3D xstrdup (p); Another stale ref to DIFF_COLORS. > 0002-doc-mention-color-and-palette-in-NEWS.patch >=20 Looked okay to me. > 0003-tests-Add-tests-for-color-and-palette.patch >=20 > + > +# Compare with some known outputs > + > +diff -c --color=3Dalways a b | sha1sum \ > + | grep 904a91f82474e3532459b759fdacbdb339070e14 || fail=3D1 > + > +diff -N --color=3Dalways --palette=3D"rs=3D0:hd=3D33:ad=3D34:de=3D35:l= n=3D36" a b \ > + | sha1sum | grep 7796a82c2e7bd1f4ee04cb44352d83e1db87c092 || fail= =3D1 Nice; a test of a non-default palette. --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --iGKRV9wqRvHfDfEgSg7GAsJ6Kj0p6iTmg Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJWOO5uAAoJEKeha0olJ0NqVcAH/j2U6DM/8le1FeRK5kjam8VA o69eVCjxathMl5uMdi4Rnod2/xoYIcMAkxwO02uObvZyJPe1uYhMRI8nXKa7nrxM zdI5cQLOdOuwOIK4Q5yoNHoJ83SQ3kko7bh+Rblh2LrtQAEgjIV1aewilI016J0k Jk+9up/u1XyzyZMB4zd9j6vdTlclLfUuogkeFaC6i8yluUVzvr0gLutsOOoCjcdw +ODOvcELo7FCE8VS7zEPSu4BbOGLSN4sMccE9S+J8kyc6BQqsbVNKFsGbVsmhWBo n+Hq9LhCH2pJGVLFfQ8nB1Snu97VjSMDXT7Z0db05vq7KIURsaV/P3iYo5ABpvM= =K8+y -----END PGP SIGNATURE----- --iGKRV9wqRvHfDfEgSg7GAsJ6Kj0p6iTmg-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 03 Nov 2015 17:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Eric Blake Cc: Giuseppe Scrivano , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144657188225695 (code B ref 20062); Tue, 03 Nov 2015 17:32:02 +0000 Received: (at 20062) by debbugs.gnu.org; 3 Nov 2015 17:31:22 +0000 Received: from localhost ([127.0.0.1]:51707 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfQG-0006g5-CH for submit@debbugs.gnu.org; Tue, 03 Nov 2015 12:31:22 -0500 Received: from mail-yk0-f170.google.com ([209.85.160.170]:35595) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfQE-0006fp-CU for 20062@debbugs.gnu.org; Tue, 03 Nov 2015 12:31:02 -0500 Received: by ykek133 with SMTP id k133so27881248yke.2 for <20062@debbugs.gnu.org>; Tue, 03 Nov 2015 09:31:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=sebaZ+IHRL7H8273CapE3GmeD+l6dR58aooqytXR6FY=; b=NHkThpxL9CTcaLw3DDUZxV+Y6luSSH9oTKaI45d6IGD1uCWnrdHOMbiP/juyhYfa/H wvbVlDqTRnUj65VNc+1uevbxobgu2VaacT2pPtVRy4vhf79m7rmnkTKMHbdSVPsAJcEh 1EitRgBGX8F/7wakDv7W7JDbn/11dwaeyulRYq6ej/T8Gsah+3tPnRXXRRUfnQMjRuZP pYgJa8fFD0lgKI7dVPR3FTF/mJdbemenrRH2nXdoAHei4uJ56vfO3hVHApmcNB1ltB/R 2xAwI0tEdhzh9AfDjWmmOAHDfl4358mDez1TH5HQpApuvBDheWzN0T5p2D39O3DrXTBe K+LA== X-Received: by 10.31.54.86 with SMTP id d83mr17757357vka.139.1446571861823; Tue, 03 Nov 2015 09:31:01 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.65.11 with HTTP; Tue, 3 Nov 2015 09:30:42 -0800 (PST) In-Reply-To: <5638EE6E.3050901@redhat.com> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> From: Jim Meyering Date: Tue, 3 Nov 2015 09:30:42 -0800 X-Google-Sender-Auth: -5BeHr3cCRp5ro64wfxdL2srM4Q Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Tue, Nov 3, 2015 at 9:27 AM, Eric Blake wrote: > On 11/03/2015 10:05 AM, Giuseppe Scrivano wrote: > >> I have attached the patches that implement --palette, the missing tests >> and update the NEWS file. >> > >> +++ b/doc/diffutils.texi >> @@ -3763,6 +3763,7 @@ Always use color. >> Specifying @option{--color} and no @var{when} is equivalent to >> @option{--color=auto}. >> >> + >> @item -C @var{lines} > > Spurious change? > >> @itemx --context@r{[}=@var{lines}@r{]} >> Use the context output format, showing @var{lines} (an integer) lines of >> @@ -3890,6 +3891,11 @@ if-then-else format. @xref{Line Formats}. >> @itemx --show-c-function >> Show which C function each change is in. @xref{C Function Headings}. >> >> +@item --palette=@var{scheme} >> +It allows to specify what colors are used to colorize the output. It > > Passive voice. Would sound better as: > > Specify what color palette to use when colored output to use. Thanks for the quick review, Eric. I'll wait for the next iteration. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: bug#20062: [PATCH] diff: add support for --color Resent-From: Eric Blake Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 03 Nov 2015 17:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano , Jim Meyering Cc: 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144657232426479 (code B ref 20062); Tue, 03 Nov 2015 17:39:02 +0000 Received: (at 20062) by debbugs.gnu.org; 3 Nov 2015 17:38:44 +0000 Received: from localhost ([127.0.0.1]:51715 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfXg-0006t0-CG for submit@debbugs.gnu.org; Tue, 03 Nov 2015 12:38:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38005) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtfXe-0006sh-04 for 20062@debbugs.gnu.org; Tue, 03 Nov 2015 12:38:42 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 049F7ABC; Tue, 3 Nov 2015 17:38:40 +0000 (UTC) Received: from [10.3.113.189] (ovpn-113-189.phx2.redhat.com [10.3.113.189]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tA3HcdbD003696; Tue, 3 Nov 2015 12:38:40 -0500 References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd9sak5.fsf@foo.bar.baz> <55F283AC.9030704@cs.ucla.edu> <55F29E35.50808@yahoo.no> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> From: Eric Blake Openpgp: url=http://people.redhat.com/eblake/eblake.gpg Organization: Red Hat, Inc. Message-ID: <5638F11E.4020004@redhat.com> Date: Tue, 3 Nov 2015 10:38:38 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <5638EE6E.3050901@redhat.com> Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="1LqF9DMXRXbUiBhnndFXVvLd1BvifOFD9" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) This is an OpenPGP/MIME signed message (RFC 4880 and 3156) --1LqF9DMXRXbUiBhnndFXVvLd1BvifOFD9 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 11/03/2015 10:27 AM, Eric Blake wrote: >> +@item --palette=3D@var{scheme} >> +It allows to specify what colors are used to colorize the output. It= >=20 > Passive voice. Would sound better as: >=20 > Specify what color palette to use when colored output to use. Bad editing on my part. Specify what color palette to use when colored output is enabled. --=20 Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org --1LqF9DMXRXbUiBhnndFXVvLd1BvifOFD9 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Public key at http://people.redhat.com/eblake/eblake.gpg Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iQEcBAEBCAAGBQJWOPEeAAoJEKeha0olJ0NqnM4H/3LzqGKd6S/IBB5zo0gPk4De bmSzu10kHo+CZJrZn6itrbRzMJOwBbcHqbDcSAiERBTO1/q5i9pO83nFibOFBVpZ ZBsj/5ov4GLAHKAY6vuJVaYj1go3ZrjTzceSHi1H+DVnygMov27RbfA5eam+AKgR AA/FCTcLqXTDiPJ1tnoRhrLyTsKCEWACPpHQK2q83qMYBvDVjDnKb1za7VW4xcY3 iA1dGg2nxqc/ru7tNwxBBr5Qo+Rk8uzvc++xrYNNFMtM83wqVyzXI4IoETMQUsjf wcqNyoNbMvNkDSY984FLJ8aeU+0XlucEc36Xe2a7wsP0mQmmvYL6Y0uKobaWqV0= =YGgR -----END PGP SIGNATURE----- --1LqF9DMXRXbUiBhnndFXVvLd1BvifOFD9-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Tue, 17 Nov 2015 00:20:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144771959030509 (code B ref 20062); Tue, 17 Nov 2015 00:20:02 +0000 Received: (at 20062) by debbugs.gnu.org; 17 Nov 2015 00:19:50 +0000 Received: from localhost ([127.0.0.1]:40630 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZyTzx-0007vy-6A for submit@debbugs.gnu.org; Mon, 16 Nov 2015 19:19:50 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52475) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZyTzb-0007vI-A0 for 20062@debbugs.gnu.org; Mon, 16 Nov 2015 19:19:47 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 7883B3B757; Tue, 17 Nov 2015 00:19:25 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-57.ams2.redhat.com [10.36.7.57]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tAH0JJtD002712 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 16 Nov 2015 19:19:22 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> Date: Tue, 17 Nov 2015 01:19:19 +0100 In-Reply-To: (Jim Meyering's message of "Tue, 3 Nov 2015 09:30:42 -0800") Message-ID: <87twol1nqw.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-=-= Content-Type: text/plain Jim Meyering writes: > On Tue, Nov 3, 2015 at 9:27 AM, Eric Blake wrote: >> On 11/03/2015 10:05 AM, Giuseppe Scrivano wrote: >> >>> I have attached the patches that implement --palette, the missing tests >>> and update the NEWS file. >>> >> >>> +++ b/doc/diffutils.texi >>> @@ -3763,6 +3763,7 @@ Always use color. >>> Specifying @option{--color} and no @var{when} is equivalent to >>> @option{--color=auto}. >>> >>> + >>> @item -C @var{lines} >> >> Spurious change? >> >>> @itemx --context@r{[}=@var{lines}@r{]} >>> Use the context output format, showing @var{lines} (an integer) lines of >>> @@ -3890,6 +3891,11 @@ if-then-else format. @xref{Line Formats}. >>> @itemx --show-c-function >>> Show which C function each change is in. @xref{C Function Headings}. >>> >>> +@item --palette=@var{scheme} >>> +It allows to specify what colors are used to colorize the output. It >> >> Passive voice. Would sound better as: >> >> Specify what color palette to use when colored output to use. > > Thanks for the quick review, Eric. > I'll wait for the next iteration. sorry for taking so long, I hope the attached version is fine. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-palette.patch >From 0861846757aa711d1ee5a0176205320e807c306b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 1/3] diff: add --palette * doc/diffutils.texi: Add documentation for --palette * src/diff.h (set_color_palette): New prototype. * src/diff.c (set_color_palette): New function. (color_palette): New variable. * src/utils.c (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_header_color_context): Use put_indicator instead of directly outputting the sequence. (set_line_numbers_colors_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 34 +++++ src/diff.c | 8 + src/diff.h | 1 + src/util.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 473 insertions(+), 9 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 0944b44..39ba35d 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3890,6 +3890,40 @@ if-then-else format. @xref{Line Formats}. @itemx --show-c-function Show which C function each change is in. @xref{C Function Headings}. +@item --palette=@var{palette} +Specify what color palette to use when colored output is enabled. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red deleted lines, +green added lines, cyan line numbers, bold header. + +Supported capabilities are as follows. + +@table @code +@item ad=32 +@vindex ad @r{capability} + +SGR substring for added lines. +The default is green foreground. + +@item de=31 +@vindex de @r{capability} + +SGR substring for deleted lines. +The default is red foreground. + +@item hd=1 +@vindex hd @r{capability} + +SGR substring for chunk header. +The default is bold foreground. + +@item ln=36 +@vindex ln @r{capability} + +SGR substring for line numbers. +The default is cyan foreground. +@end table + + @item -q @itemx --brief Report only whether the files differ, not the details of the diff --git a/src/diff.c b/src/diff.c index 4e0f602..4c3d29a 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_PALETTE_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -196,6 +197,7 @@ static struct option const longopts[] = {"old-group-format", 1, 0, OLD_GROUP_FORMAT_OPTION}, {"old-line-format", 1, 0, OLD_LINE_FORMAT_OPTION}, {"paginate", 0, 0, 'l'}, + {"palette", 1, 0, COLOR_PALETTE_OPTION}, {"rcs", 0, 0, 'n'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_PALETTE_OPTION: + set_color_palette (optarg); + break; + default: try_help (NULL, NULL); } @@ -950,6 +956,8 @@ static char const * const option_help_msgid[] = { N_(" --speed-large-files assume large files and many scattered small changes"), N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), N_(" or 'auto' (the default)"), + N_(" --palette=PALETTE specify the colors to use when --color is active"), + N_(" PALETTE is a colon-separated list terminfo capabilities"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), diff --git a/src/diff.h b/src/diff.h index 472fa93..5930cd1 100644 --- a/src/diff.h +++ b/src/diff.h @@ -411,3 +411,4 @@ extern void set_add_color_context (void); extern void set_delete_color_context (void); extern void reset_color_context (void); extern void set_line_numbers_color_context (void); +extern void set_color_palette (const char *palette); diff --git a/src/util.c b/src/util.c index 6cc1411..dedf3b3 100644 --- a/src/util.c +++ b/src/util.c @@ -310,6 +310,396 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the --palette argument; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; + +static const char *color_palette; + +void +set_color_palette (const char *palette) +{ + color_palette = palette; +} + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = color_palette) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + --palette string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for --palette")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +713,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -923,12 +1316,27 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + void set_header_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[1m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_HEADER]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -936,7 +1344,11 @@ set_line_numbers_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[36m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_LINE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -944,7 +1356,11 @@ set_add_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[32m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_ADD]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -952,17 +1368,22 @@ set_delete_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[31m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_DELETE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void reset_color_context (void) { - static char const reset_sequence[] = "\x1b[0m"; - if (! colors_enabled) - return; - - fputs (reset_sequence, outfile); + if (colors_enabled) + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_RESET]); + put_indicator (&color_indicator[C_RIGHT]); + } } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-doc-mention-color-and-palette-in-NEWS.patch >From 24a52233fd92f2f34b5050aa7f575b15ed51e0ff Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:03:32 +0000 Subject: [PATCH 2/3] doc: mention --color and --palette in NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 7cdfedd..685dc9d 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU diffutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + diff accepts two new options --color and --palette to set a colored + output. --color takes an optional argument specifying when to + colorize a line: --color=always, --color=auto, --color=never. + --palette is used to change the used colors. + ** Bug fixes When binary files differ, diff now exits with status 1 as POSIX requires. -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-tests-Add-tests-for-color-and-palette.patch >From 6537a0d21f3bbb17690effcc33db2c5a7fdea795 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:05:10 +0000 Subject: [PATCH 3/3] tests: Add tests for --color and --palette * tests/colors: New file. * tests/Makefile.am (TESTS): Add colors. --- tests/Makefile.am | 3 ++- tests/colors | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100755 tests/colors diff --git a/tests/Makefile.am b/tests/Makefile.am index 438fbdf..805ccc2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ TESTS = \ no-newline-at-eof \ stdin \ strcoll-0-names \ - filename-quoting + filename-quoting \ + colors EXTRA_DIST = \ $(TESTS) init.sh t-local.sh diff --git a/tests/colors b/tests/colors new file mode 100755 index 0000000..02da181 --- /dev/null +++ b/tests/colors @@ -0,0 +1,38 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=UTC0 +export TZ + +fail=0 + +echo a > a +echo b > b + +touch --date='1970-01-01 00:00:00' a b + +# Compare with some known outputs + +diff --color=always a b | sha1sum \ + | grep dbed959c9975cf761ff4950d93d342d7c271c11f || fail=1 + +diff --color=auto a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff --color=never a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff --color a b | sha1sum \ + | grep 90742ce0d628cc2f2067b232404578e000b80cce || fail=1 + +diff -u --color=always a b | sha1sum \ + | grep 5712fbffc94c501eaeec5cb02468ce2bbed6d7c9 || fail=1 + +diff -c --color=always a b | sha1sum \ + | grep a9bfa18ea6425db547ac69bc13fb78cf9416ad55 || fail=1 + +diff -N --color=always --palette="rs=0:hd=33:ad=34:de=35:ln=36" a b \ + | sha1sum | grep 7796a82c2e7bd1f4ee04cb44352d83e1db87c092 || fail=1 + +Exit $fail -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Thu, 26 Nov 2015 17:18:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14485582672309 (code B ref 20062); Thu, 26 Nov 2015 17:18:01 +0000 Received: (at 20062) by debbugs.gnu.org; 26 Nov 2015 17:17:47 +0000 Received: from localhost ([127.0.0.1]:54563 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a20B0-0000bB-K9 for submit@debbugs.gnu.org; Thu, 26 Nov 2015 12:17:47 -0500 Received: from mail-vk0-f50.google.com ([209.85.213.50]:35184) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a20Ay-0000b3-En for 20062@debbugs.gnu.org; Thu, 26 Nov 2015 12:17:45 -0500 Received: by vkha189 with SMTP id a189so56500873vkh.2 for <20062@debbugs.gnu.org>; Thu, 26 Nov 2015 09:17:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=Pdo1GH/gT5Yfel2Aip1aqZkjV4E+AM0dKJWuMs+itj4=; b=ZP5HkgM6naLAqUP0WFFhXduYy58MGG55SXw2h4D3L0dcEbwy4tmqieZCWfK4+thrWO Vo0rTofTWxUHLb1f2DXMcKr5NtxSAWs5PX18/JPXO5aw9wM6gtZdWtS7zSSYfzohtjHf IgMDJYKGjN67U0UX7Hu4+WpuMPHHjoN/PS8A1BNEkWH4kAtpo7rqjRchfG+grr1C8/1+ 6m/AECf8/LnnM83tTIwTCGG0n3QvV8VDp88Vi+yN7ZdjgEUfx4OM1TPKlMk4cWTuHff5 qOTrxcB89IJ5oGMV129y8s3TtEFLbvUxOa8wEeDV8SO8G42lrJog7x2hSlF4sdP5I27I vI6g== X-Received: by 10.31.183.200 with SMTP id h191mr39482604vkf.147.1448558264017; Thu, 26 Nov 2015 09:17:44 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.84.198 with HTTP; Thu, 26 Nov 2015 09:17:24 -0800 (PST) In-Reply-To: <87twol1nqw.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55F2F304.2070808@cs.ucla.edu> <87vbbgr5kt.fsf@foo.bar.baz> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> From: Jim Meyering Date: Thu, 26 Nov 2015 09:17:24 -0800 X-Google-Sender-Auth: aoUHj1iKURNsqWjYjBMhKcqFHRU Message-ID: Content-Type: multipart/mixed; boundary=001a11439778c38359052574c093 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --001a11439778c38359052574c093 Content-Type: text/plain; charset=UTF-8 On Mon, Nov 16, 2015 at 4:19 PM, Giuseppe Scrivano wrote: > Jim Meyering writes: > >> On Tue, Nov 3, 2015 at 9:27 AM, Eric Blake wrote: >>> On 11/03/2015 10:05 AM, Giuseppe Scrivano wrote: >>> >>>> I have attached the patches that implement --palette, the missing tests >>>> and update the NEWS file. >>>> >>> >>>> +++ b/doc/diffutils.texi >>>> @@ -3763,6 +3763,7 @@ Always use color. >>>> Specifying @option{--color} and no @var{when} is equivalent to >>>> @option{--color=auto}. >>>> >>>> + >>>> @item -C @var{lines} >>> >>> Spurious change? >>> >>>> @itemx --context@r{[}=@var{lines}@r{]} >>>> Use the context output format, showing @var{lines} (an integer) lines of >>>> @@ -3890,6 +3891,11 @@ if-then-else format. @xref{Line Formats}. >>>> @itemx --show-c-function >>>> Show which C function each change is in. @xref{C Function Headings}. >>>> >>>> +@item --palette=@var{scheme} >>>> +It allows to specify what colors are used to colorize the output. It >>> >>> Passive voice. Would sound better as: >>> >>> Specify what color palette to use when colored output to use. >> >> Thanks for the quick review, Eric. >> I'll wait for the next iteration. > > sorry for taking so long, I hope the attached version is fine. I have begun reviewing carefully. I adjusted NEWS. Here is the modified paragraph: ** New features diff accepts two new options --color and --palette to generate and configure colored output. --color takes an optional argument specifying when to colorize a line: --color=always, --color=auto, --color=never. --palette is used to configure which colors are used. I looked at the tests/colors script: we cannot/should not use sha1sum for two reasons. 1) it is a short cut; better to include the precise expected output in each case. Using this approach, if/when a test fails, there is no record of what the expected output was. 2) the "sha1sum" command is not universally available by that name. On BSD-based systems it is called "sha1". Thus, I began the conversion, and in so doing, I found some room for improvement: with the current patches I have, diff -u emits a pair of identical color-changing escape sequences before each "+"-prefixed line: $ diff -u --color=always a b|cat -A ^[[1;39m--- a^I1969-12-31 16:00:00.000000000 -0800$ +++ b^I1969-12-31 16:00:00.000000000 -0800$ ^[[0m^[[36m@@ -1 +1 @@^[[0m$ ^[[31m-a$ ^[[32m^[[32m+b$ ^[[0m Notice also how the final \e[0m is on the final line by itself, with no following newline. Please adjust so that it appears at the end of the final line instead. I confirmed that git-diff appears to do the same thing, but noted that git uses \e[m instead (no "0" part). Do you know of any pros/cons for one or the other? I've attached the beginnings of the adjusted tests/colors script that I used to discover these things. Can you finish the job of converting it to use "compare" rather than sha1sum? --001a11439778c38359052574c093 Content-Type: application/x-sh; name="colors.sh" Content-Disposition: attachment; filename="colors.sh" Content-Transfer-Encoding: base64 X-Attachment-Id: f_ihgi5f3w3 IyEvYmluL3NoCgouICIke3NyY2Rpcj0ufS9pbml0LnNoIjsgcGF0aF9wcmVwZW5kXyAuLi9zcmMK ClRaPVVUQzAKZXhwb3J0IFRaCgpmYWlsPTAKCmVjaG8gYSA+IGEKZWNobyBiID4gYgoKZXBvY2g9 JzE5NzAtMDEtMDEgMDA6MDA6MDAnCnRvdWNoIC0tZGF0ZT0iJGVwb2NoIiBhIGIKCmdlbl9leHBf dSgpCnsKICAgIGxvY2FsIHRhYj0kKHByaW50ZiAnXHQnKQogICAgbG9jYWwgZXBvY2hfcGx1cz0i JGVwb2NoLjAwMDAwMDAwMCArMDAwMCIKICAgIGxvY2FsIHJzPSQocHJpbnRmICJcZVske3JzfW0i KQogICAgbG9jYWwgaGQ9JChwcmludGYgIlxlWyR7aGR9bSIpCiAgICBsb2NhbCBhZD0kKHByaW50 ZiAiXGVbJHthZH1tIikKICAgIGxvY2FsIGRlPSQocHJpbnRmICJcZVske2RlfW0iKQogICAgbG9j YWwgbG49JChwcmludGYgIlxlWyR7bG59bSIpCiAgICBwcmludGYgJyVzJyBcCiIkaGQtLS0gYSR0 YWIkZXBvY2hfcGx1cworKysgYiR0YWIkZXBvY2hfcGx1cwokcnMbWzM2bUBAIC0xICsxIEBAG1sw bQokZGUtYQokYWQkYWQrYgokcnMiCiAgICB9CgojIENvbXBhcmUgd2l0aCBzb21lIGtub3duIG91 dHB1dHMKCmRpZmYgLS1jb2xvcj1hbHdheXMgYSBiIHwgc2hhMXN1bSBcCiAgICAgfCBncmVwIGRi ZWQ5NTljOTk3NWNmNzYxZmY0OTUwZDkzZDM0MmQ3YzI3MWMxMWYgfHwgZmFpbD0xCgpkaWZmIC0t Y29sb3I9YXV0byBhIGIgfCBzaGExc3VtIFwKICAgICB8IGdyZXAgOTA3NDJjZTBkNjI4Y2MyZjIw NjdiMjMyNDA0NTc4ZTAwMGI4MGNjZSB8fCBmYWlsPTEKCmRpZmYgLS1jb2xvcj1uZXZlciBhIGIg fCBzaGExc3VtIFwKICAgICB8IGdyZXAgOTA3NDJjZTBkNjI4Y2MyZjIwNjdiMjMyNDA0NTc4ZTAw MGI4MGNjZSB8fCBmYWlsPTEKCmRpZmYgLS1jb2xvciBhIGIgfCBzaGExc3VtIFwKICAgICB8IGdy ZXAgOTA3NDJjZTBkNjI4Y2MyZjIwNjdiMjMyNDA0NTc4ZTAwMGI4MGNjZSB8fCBmYWlsPTEKCmRp ZmYgLXUgLS1jb2xvcj1hbHdheXMgYSBiIHwgc2hhMXN1bSBcCiAgICAgfCBncmVwIDU3MTJmYmZm Yzk0YzUwMWVhZWVjNWNiMDI0NjhjZTJiYmVkNmQ3YzkgfHwgZmFpbD0xCgpkaWZmIC1jIC0tY29s b3I9YWx3YXlzIGEgYiB8IHNoYTFzdW0gXAogICAgIHwgZ3JlcCBhOWJmYTE4ZWE2NDI1ZGI1NDdh YzY5YmMxM2ZiNzhjZjk0MTZhZDU1IHx8IGZhaWw9MQoKcnM9MCBoZD0zMyBhZD0zNCBkZT0zNSBs bj0zNgpkaWZmIC11IC0tY29sb3I9YWx3YXlzIC0tcGFsZXR0ZT0icnM9MDpoZD0zMzphZD0zNDpk ZT0zNTpsbj0zNiIgYSBiID4gawp0ZXN0ICQ/ID0gMSB8fCBmYWlsPTEKZ2VuX2V4cF91ID4gZXhw IHx8IGZyYW1ld29ya19mYWlsdXJlXwpjb21wYXJlIGsgZXhwIHx8IGZhaWw9MQoKRXhpdCAkZmFp bAo= --001a11439778c38359052574c093-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 27 Nov 2015 15:04:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14486365979252 (code B ref 20062); Fri, 27 Nov 2015 15:04:01 +0000 Received: (at 20062) by debbugs.gnu.org; 27 Nov 2015 15:03:17 +0000 Received: from localhost ([127.0.0.1]:56339 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2KYL-0002P7-GC for submit@debbugs.gnu.org; Fri, 27 Nov 2015 10:03:17 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56174) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2KYF-0002Ov-MK for 20062@debbugs.gnu.org; Fri, 27 Nov 2015 10:03:11 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id CE60A8F4EF; Fri, 27 Nov 2015 15:03:06 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-113.ams2.redhat.com [10.36.7.113]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tARF30Vi018751 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Fri, 27 Nov 2015 10:03:02 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> Date: Fri, 27 Nov 2015 16:01:56 +0100 In-Reply-To: (Jim Meyering's message of "Thu, 26 Nov 2015 09:17:24 -0800") Message-ID: <87a8pz4haz.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -4.1 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.1 (----) --=-=-= Content-Type: text/plain Hi Jim, thanks for the great advices. Jim Meyering writes: > I looked at the tests/colors script: we cannot/should not use sha1sum > for two reasons. 1) it is a short cut; better to include the precise expected > output in each case. Using this approach, if/when a test fails, there is > no record of what the expected output was. 2) the "sha1sum" command > is not universally available by that name. On BSD-based systems it is > called "sha1". Thus, I began the conversion, and in so doing, I found > some room for improvement: with the current patches I have, diff -u > emits a pair of identical color-changing escape sequences before each > "+"-prefixed line: > > $ diff -u --color=always a b|cat -A > ^[[1;39m--- a^I1969-12-31 16:00:00.000000000 -0800$ > +++ b^I1969-12-31 16:00:00.000000000 -0800$ > ^[[0m^[[36m@@ -1 +1 @@^[[0m$ > ^[[31m-a$ > ^[[32m^[[32m+b$ > ^[[0m > > Notice also how the final \e[0m is on the final line by itself, > with no following newline. Please adjust so that it appears at the > end of the final line instead. I confirmed that git-diff appears > to do the same thing, but noted that git uses \e[m instead (no > "0" part). Do you know of any pros/cons for one or the other? I don't know if there is any difference in practice between \e[m and \e0[m. I took the implementation in ls as reference which uses \e0[m. > I've attached the beginnings of the adjusted tests/colors > script that I used to discover these things. Can you finish the job > of converting it to use "compare" rather than sha1sum? Sure. The new tests helped me to spot two issues in the "diff: add support for --color" patch. I also added some extra check to avoid to enter the same colors context twice. These fixes are in 0004-fixup-diff-add-support-for-color.patch. To generate sequences on the same line they belong, I have created a new patch to facilitate the review. Probably the patch should get squashed into 0001-diff-add-support-for-color.patch and 0005-tests-Add-tests-for-color-and-palette.patch once reviewed. I have not changed the first two patches of the series, I am including them just for completeness. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 50def324f48ff09501e6f07cecae2a6cd5a16e3c Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH 1/6] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_add_color_context): Add function definition. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (reset_color_context): Likewise. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (reset_color_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (set_header_color_context): Likewise. (set_line_numbers_color_context): Likewise. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 51 +++++++-- src/diff.c | 27 ++++- src/diff.h | 21 ++++ src/normal.c | 18 ++- src/side.c | 15 +++ src/util.c | 316 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 421 insertions(+), 48 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..0944b44 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..8e9a74f 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_header_color_context (); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + reset_color_context (); } /* Print an edit script in context format. */ @@ -215,6 +217,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,12 +228,18 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_delete_color_context (); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + reset_color_context (); } } @@ -244,6 +253,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +264,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_add_color_context (); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + reset_color_context (); } } } @@ -330,11 +345,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_line_numbers_color_context (); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + reset_color_context (); if (function) print_context_function (out, function); @@ -360,9 +377,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_delete_color_context (); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,9 +400,15 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_add_color_context (); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; + set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); @@ -386,6 +417,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + reset_color_context (); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index efd7e47..4e0f602 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..472fa93 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* What kind of changes a hunk contains. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,8 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); +extern void set_header_color_context (void); +extern void set_add_color_context (void); +extern void set_delete_color_context (void); +extern void reset_color_context (void); +extern void set_line_numbers_color_context (void); diff --git a/src/normal.c b/src/normal.c index 721fd1a..227af10 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_line_numbers_color_context (); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + reset_color_context (); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_delete_color_context (); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + reset_color_context (); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_add_color_context (); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + reset_color_context (); + } } diff --git a/src/side.c b/src/side.c index 155512c..b762d31 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_delete_color_context (); + color_to_reset = true; + } + else if (sep == '>') + { + set_add_color_context (); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + reset_color_context (); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..6cc1411 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,174 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + reset_color_context (); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + +static char const *current_name0; +static char const *current_name1; +static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -150,10 +334,6 @@ print_message_queue (void) we fork off a 'pr' and make OUTFILE a pipe to it. 'pr' then outputs to our stdout. */ -static char const *current_name0; -static char const *current_name1; -static bool currently_recursive; - void setup_output (char const *name0, char const *name1, bool recursive) { @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +855,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,40 +877,92 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; +void +set_header_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[1m", outfile); +} - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_line_numbers_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[36m", outfile); +} - default: - column += isprint (c) != 0; - putc (c, out); - break; - } - } +void +set_add_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[32m", outfile); +} + +void +set_delete_color_context (void) +{ + process_signals (); + if (colors_enabled) + fputs ("\x1B[31m", outfile); +} + +void +reset_color_context (void) +{ + static char const reset_sequence[] = "\x1b[0m"; + if (! colors_enabled) + return; + + fputs (reset_sequence, outfile); } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-diff-add-palette.patch >From 0bbbbc9ce6a2b68e2ff20a1a8b4ed69a7e43619b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 2/6] diff: add --palette * doc/diffutils.texi: Add documentation for --palette * src/diff.h (set_color_palette): New prototype. * src/diff.c (set_color_palette): New function. (color_palette): New variable. * src/utils.c (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_header_color_context): Use put_indicator instead of directly outputting the sequence. (set_line_numbers_colors_context): Likewise. (set_add_color_context): Likewise. (set_delete_color_context): Likewise. (reset_color_context): Likewise. --- doc/diffutils.texi | 34 +++++ src/diff.c | 8 + src/diff.h | 1 + src/util.c | 439 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 473 insertions(+), 9 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 0944b44..39ba35d 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3890,6 +3890,40 @@ if-then-else format. @xref{Line Formats}. @itemx --show-c-function Show which C function each change is in. @xref{C Function Headings}. +@item --palette=@var{palette} +Specify what color palette to use when colored output is enabled. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red deleted lines, +green added lines, cyan line numbers, bold header. + +Supported capabilities are as follows. + +@table @code +@item ad=32 +@vindex ad @r{capability} + +SGR substring for added lines. +The default is green foreground. + +@item de=31 +@vindex de @r{capability} + +SGR substring for deleted lines. +The default is red foreground. + +@item hd=1 +@vindex hd @r{capability} + +SGR substring for chunk header. +The default is bold foreground. + +@item ln=36 +@vindex ln @r{capability} + +SGR substring for line numbers. +The default is cyan foreground. +@end table + + @item -q @itemx --brief Report only whether the files differ, not the details of the diff --git a/src/diff.c b/src/diff.c index 4e0f602..4c3d29a 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_PALETTE_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -196,6 +197,7 @@ static struct option const longopts[] = {"old-group-format", 1, 0, OLD_GROUP_FORMAT_OPTION}, {"old-line-format", 1, 0, OLD_LINE_FORMAT_OPTION}, {"paginate", 0, 0, 'l'}, + {"palette", 1, 0, COLOR_PALETTE_OPTION}, {"rcs", 0, 0, 'n'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_PALETTE_OPTION: + set_color_palette (optarg); + break; + default: try_help (NULL, NULL); } @@ -950,6 +956,8 @@ static char const * const option_help_msgid[] = { N_(" --speed-large-files assume large files and many scattered small changes"), N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), N_(" or 'auto' (the default)"), + N_(" --palette=PALETTE specify the colors to use when --color is active"), + N_(" PALETTE is a colon-separated list terminfo capabilities"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), diff --git a/src/diff.h b/src/diff.h index 472fa93..5930cd1 100644 --- a/src/diff.h +++ b/src/diff.h @@ -411,3 +411,4 @@ extern void set_add_color_context (void); extern void set_delete_color_context (void); extern void reset_color_context (void); extern void set_line_numbers_color_context (void); +extern void set_color_palette (const char *palette); diff --git a/src/util.c b/src/util.c index 6cc1411..dedf3b3 100644 --- a/src/util.c +++ b/src/util.c @@ -310,6 +310,396 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the --palette argument; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; + +static const char *color_palette; + +void +set_color_palette (const char *palette) +{ + color_palette = palette; +} + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = color_palette) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + --palette string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for --palette")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +713,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -923,12 +1316,27 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + void set_header_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[1m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_HEADER]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -936,7 +1344,11 @@ set_line_numbers_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[36m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_LINE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -944,7 +1356,11 @@ set_add_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[32m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_ADD]); + put_indicator (&color_indicator[C_RIGHT]); + } } void @@ -952,17 +1368,22 @@ set_delete_color_context (void) { process_signals (); if (colors_enabled) - fputs ("\x1B[31m", outfile); + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_DELETE]); + put_indicator (&color_indicator[C_RIGHT]); + } } void reset_color_context (void) { - static char const reset_sequence[] = "\x1b[0m"; - if (! colors_enabled) - return; - - fputs (reset_sequence, outfile); + if (colors_enabled) + { + put_indicator (&color_indicator[C_LEFT]); + put_indicator (&color_indicator[C_RESET]); + put_indicator (&color_indicator[C_RIGHT]); + } } char const change_letter[] = { 0, 'd', 'a', 'c' }; -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-doc-mention-color-and-palette-in-NEWS.patch >From 88b6384539d6d6e5c74e07efa55dbc6f4b12de6d Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:03:32 +0000 Subject: [PATCH 3/6] doc: mention --color and --palette in NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 7cdfedd..088f13b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU diffutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + diff accepts two new options --color and --palette to generate + and configure colored output. --color takes an optional argument + specifying when to colorize a line: --color=always, --color=auto, + --color=never. --palette is used to configure which colors are used. + ** Bug fixes When binary files differ, diff now exits with status 1 as POSIX requires. -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-fixup-diff-add-support-for-color.patch >From 49d2d3887f3358874a9e548209b0bd83ec347234 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 27 Nov 2015 11:43:58 +0000 Subject: [PATCH 4/6] fixup! diff: add support for --color --- src/context.c | 5 ++++- src/util.c | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/context.c b/src/context.c index 8e9a74f..216f547 100644 --- a/src/context.c +++ b/src/context.c @@ -207,9 +207,11 @@ pr_context_hunk (struct change *hunk) if (function) print_context_function (out, function); + set_line_numbers_color_context (); fputs ("\n*** ", out); print_context_number_range (&files[0], first0, last0); fputs (" ****\n", out); + reset_color_context (); if (changes & OLD) { @@ -243,9 +245,11 @@ pr_context_hunk (struct change *hunk) } } + set_line_numbers_color_context (); fputs ("--- ", out); print_context_number_range (&files[1], first1, last1); fputs (" ----\n", out); + reset_color_context (); if (changes & NEW) { @@ -408,7 +412,6 @@ pr_unidiff_hunk (struct change *hunk) while (k--) { char const * const *line = &files[1].linbuf[j++]; - set_add_color_context (); putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); diff --git a/src/util.c b/src/util.c index dedf3b3..b0e277b 100644 --- a/src/util.c +++ b/src/util.c @@ -1327,15 +1327,18 @@ put_indicator (const struct bin_str *ind) fwrite (ind->string, ind->len, 1, outfile); } +static enum indicator_no last_context = C_RESET; + void set_header_color_context (void) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != C_HEADER) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_HEADER]); put_indicator (&color_indicator[C_RIGHT]); + last_context = C_HEADER; } } @@ -1343,11 +1346,12 @@ void set_line_numbers_color_context (void) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != C_LINE) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_LINE]); put_indicator (&color_indicator[C_RIGHT]); + last_context = C_LINE; } } @@ -1355,11 +1359,12 @@ void set_add_color_context (void) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != C_ADD) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_ADD]); put_indicator (&color_indicator[C_RIGHT]); + last_context = C_ADD; } } @@ -1367,22 +1372,24 @@ void set_delete_color_context (void) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != C_DELETE) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_DELETE]); put_indicator (&color_indicator[C_RIGHT]); + last_context = C_DELETE; } } void reset_color_context (void) { - if (colors_enabled) + if (colors_enabled && last_context != C_RESET) { put_indicator (&color_indicator[C_LEFT]); put_indicator (&color_indicator[C_RESET]); put_indicator (&color_indicator[C_RIGHT]); + last_context = C_RESET; } } -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0005-tests-Add-tests-for-color-and-palette.patch >From a2b6721675cb4d90fc0322a5b2fc9d5c1d4c35df Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:05:10 +0000 Subject: [PATCH 5/6] tests: Add tests for --color and --palette * tests/colors: New file. * tests/Makefile.am (TESTS): Add colors. --- tests/Makefile.am | 3 +- tests/colors | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100755 tests/colors diff --git a/tests/Makefile.am b/tests/Makefile.am index 438fbdf..805ccc2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ TESTS = \ no-newline-at-eof \ stdin \ strcoll-0-names \ - filename-quoting + filename-quoting \ + colors EXTRA_DIST = \ $(TESTS) init.sh t-local.sh diff --git a/tests/colors b/tests/colors new file mode 100755 index 0000000..5a62232 --- /dev/null +++ b/tests/colors @@ -0,0 +1,119 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=UTC0 +export TZ + +fail=0 + +echo a > a +echo b > b + +epoch='1970-01-01 00:00:00' +touch --date="$epoch" a b + +gen_exp_u() +{ + local tab=$(printf '\t') + local epoch_plus="$epoch.000000000 +0000" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd--- a$tab$epoch_plus ++++ b$tab$epoch_plus +$rs${ln}@@ -1 +1 @@$rs +$de-a +$ad+b +$rs" +} + +gen_exp_c() +{ + local tab=$(printf '\t') + local epoch_posix_1003_1_2001="Thu Jan 1 00:00:00 1970" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd*** a$tab$epoch_posix_1003_1_2001 +--- b$tab$epoch_posix_1003_1_2001 +$rs***************$ln +*** 1 **** +$rs$de! a +$rs$ln--- 1 ---- +$rs$ad! b +$rs" +} + +gen_exp_default() +{ + printf '%s' \ +"1c1 +< a +--- +> b +" +} + +gen_exp_default_colors() +{ + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"${ln}1c1 +$rs$de< a +$rs--- +$ad> b +$rs" +} + +# Compare with some known outputs + +rs=0 hd=1 ad=32 de=31 ln=36 + +diff --color=auto a b > k +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp k || fail=1 + +diff --color=never a b > k +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp k || fail=1 + +diff a b > k +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp k || fail=1 + +diff --color=always a b > k +test $? = 1 || fail=1 +gen_exp_default_colors > exp || framework_failure_ +compare exp k || fail=1 + +diff -u --color=always a b > k +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp k || fail=1 + +diff -c --color=always a b > k +test $? = 1 || fail=1 +gen_exp_c > exp || framework_failure_ +compare exp k || fail=1 + +rs=0 hd=33 ad=34 de=35 ln=36 +diff -u --color=always --palette="rs=0:hd=33:ad=34:de=35:ln=36" a b > k +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp k || fail=1 + +Exit $fail -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0006-Generate-terminal-sequences-on-the-line-they-belong.patch >From 031a5778004cc492fbf33f647838116780a73938 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 27 Nov 2015 13:56:05 +0100 Subject: [PATCH 6/6] Generate terminal sequences on the line they belong * src/diff.h: New function 'print_1_line_nl'. * src/context.c (pr_context_hunk): Use 'print_1_line_nl'. Generate terminal sequences on the line they belong. (pr_unidiff_hunk): Likewise. * src/normal.c (print_normal_hunk): Likewise. * src/util.c (print_1_line_nl): New function. (print_1_line): Become a wrapper of 'print_1_line_nl'. * tests/colors: Adjust tests. --- src/context.c | 64 ++++++++++++++++++++++++++++++++++------------------------- src/diff.h | 1 + src/normal.c | 26 +++++++++++++++++------- src/util.c | 19 ++++++++++++++++-- tests/colors | 28 +++++++++++++------------- 5 files changed, 88 insertions(+), 50 deletions(-) diff --git a/src/context.c b/src/context.c index 216f547..0834079 100644 --- a/src/context.c +++ b/src/context.c @@ -207,19 +207,23 @@ pr_context_hunk (struct change *hunk) if (function) print_context_function (out, function); + putc ('\n', out); set_line_numbers_color_context (); - fputs ("\n*** ", out); + fputs ("*** ", out); print_context_number_range (&files[0], first0, last0); - fputs (" ****\n", out); + fputs (" ****", out); reset_color_context (); + putc ('\n', out); if (changes & OLD) { struct change *next = hunk; + if (first0 <= last0) + set_delete_color_context (); + for (i = first0; i <= last0; i++) { - bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -231,33 +235,36 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) { - reset_context = true; - set_delete_color_context (); /* The change NEXT covers this line. If lines were inserted here in file 1, this is "changed". Otherwise it is "deleted". */ prefix = (next->inserted > 0 ? "!" : "-"); } - print_1_line (prefix, &files[0].linbuf[i]); - if (reset_context) + print_1_line_nl (prefix, &files[0].linbuf[i], true); + if (i == last0) reset_color_context (); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } set_line_numbers_color_context (); fputs ("--- ", out); print_context_number_range (&files[1], first1, last1); - fputs (" ----\n", out); + fputs (" ----", out); reset_color_context (); + putc ('\n', out); if (changes & NEW) { struct change *next = hunk; + if (first1 <= last1) + set_add_color_context (); + for (i = first1; i <= last1; i++) { - bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -269,16 +276,16 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) { - reset_context = true; - set_add_color_context (); /* The change NEXT covers this line. If lines were deleted here in file 0, this is "changed". Otherwise it is "inserted". */ prefix = (next->deleted > 0 ? "!" : "+"); } - print_1_line (prefix, &files[1].linbuf[i]); - if (reset_context) + print_1_line_nl (prefix, &files[1].linbuf[i], true); + if (i == last1) reset_color_context (); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } } @@ -381,16 +388,11 @@ pr_unidiff_hunk (struct change *hunk) } else { - bool reset_context = false; - /* For each difference, first output the deleted part. */ k = next->deleted; if (k) - { - reset_context = true; - set_delete_color_context (); - } + set_delete_color_context (); while (k--) { @@ -398,30 +400,38 @@ pr_unidiff_hunk (struct change *hunk) putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + reset_color_context (); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* Then output the inserted part. */ k = next->inserted; if (k) - { - reset_context = true; - set_add_color_context (); - } + set_add_color_context (); + while (k--) { char const * const *line = &files[1].linbuf[j++]; putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + reset_color_context (); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* We're done with this hunk, so on to the next! */ - if (reset_context) - reset_color_context (); next = next->link; } } diff --git a/src/diff.h b/src/diff.h index 5930cd1..791c29e 100644 --- a/src/diff.h +++ b/src/diff.h @@ -399,6 +399,7 @@ extern void output_1_line (char const *, char const *, char const *, extern void perror_with_name (char const *); extern void pfatal_with_name (char const *) __attribute__((noreturn)); extern void print_1_line (char const *, char const * const *); +extern void print_1_line_nl (char const *, char const * const *, bool); extern void print_message_queue (void); extern void print_number_range (char, struct file_data *, lin, lin); extern void print_script (struct change *, struct change * (*) (struct change *), diff --git a/src/normal.c b/src/normal.c index 227af10..5a1e687 100644 --- a/src/normal.c +++ b/src/normal.c @@ -53,16 +53,22 @@ print_normal_hunk (struct change *hunk) print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); - fputc ('\n', outfile); reset_color_context (); + fputc ('\n', outfile); /* Print the lines that the first file has. */ if (changes & OLD) { - set_delete_color_context (); + if (first0 <= last0) + set_delete_color_context (); for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); - reset_color_context (); + { + print_1_line_nl ("<", &files[0].linbuf[i], true); + if (i == last0) + reset_color_context (); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } } if (changes == CHANGED) @@ -71,9 +77,15 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the second file has. */ if (changes & NEW) { - set_add_color_context (); + if (first1 <= last1) + set_add_color_context (); for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); - reset_color_context (); + { + print_1_line_nl (">", &files[1].linbuf[i], true); + if (i == last1) + reset_color_context (); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } } } diff --git a/src/util.c b/src/util.c index b0e277b..65b06e9 100644 --- a/src/util.c +++ b/src/util.c @@ -1206,6 +1206,18 @@ print_script (struct change *script, void print_1_line (char const *line_flag, char const *const *line) { + print_1_line_nl (line_flag, line, false); +} + +/* Print the text of a single line LINE, + flagging it with the characters in LINE_FLAG (which say whether + the line is inserted, deleted, changed, etc.). LINE_FLAG must not + end in a blank, unless it is a single blank. If SKIP_NL is set, then + the final '\n' is not printed. */ + +void +print_1_line_nl (char const *line_flag, char const *const *line, bool skip_nl) +{ char const *base = line[0], *limit = line[1]; /* Help the compiler. */ FILE *out = outfile; /* Help the compiler some more. */ char const *flag_format = 0; @@ -1233,10 +1245,13 @@ print_1_line (char const *line_flag, char const *const *line) fprintf (out, flag_format_1, line_flag_1); } - output_1_line (base, limit, flag_format, line_flag); + output_1_line (base, limit - (skip_nl && limit[-1] == '\n'), flag_format, line_flag); if ((!line_flag || line_flag[0]) && limit[-1] != '\n') - fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + { + reset_color_context (); + fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + } } /* Output a line from BASE up to LIMIT. diff --git a/tests/colors b/tests/colors index 5a62232..7593ca9 100755 --- a/tests/colors +++ b/tests/colors @@ -26,9 +26,9 @@ gen_exp_u() "$hd--- a$tab$epoch_plus +++ b$tab$epoch_plus $rs${ln}@@ -1 +1 @@$rs -$de-a -$ad+b -$rs" +$de-a$rs +$ad+b$rs +" } gen_exp_c() @@ -43,12 +43,12 @@ gen_exp_c() printf '%s' \ "$hd*** a$tab$epoch_posix_1003_1_2001 --- b$tab$epoch_posix_1003_1_2001 -$rs***************$ln -*** 1 **** -$rs$de! a -$rs$ln--- 1 ---- -$rs$ad! b -$rs" +$rs*************** +$ln*** 1 ****$rs +$de! a$rs +$ln--- 1 ----$rs +$ad! b$rs +" } gen_exp_default() @@ -69,11 +69,11 @@ gen_exp_default_colors() local de=$(printf "\e[${de}m") local ln=$(printf "\e[${ln}m") printf '%s' \ -"${ln}1c1 -$rs$de< a -$rs--- -$ad> b -$rs" +"${ln}1c1$rs +$de< a$rs +--- +$ad> b$rs +" } # Compare with some known outputs -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Fri, 27 Nov 2015 19:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.14486535459570 (code B ref 20062); Fri, 27 Nov 2015 19:46:01 +0000 Received: (at 20062) by debbugs.gnu.org; 27 Nov 2015 19:45:45 +0000 Received: from localhost ([127.0.0.1]:56469 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2Oxk-0002UH-NX for submit@debbugs.gnu.org; Fri, 27 Nov 2015 14:45:45 -0500 Received: from mail-vk0-f51.google.com ([209.85.213.51]:33556) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2Oxh-0002U4-G2 for 20062@debbugs.gnu.org; Fri, 27 Nov 2015 14:45:42 -0500 Received: by vkca188 with SMTP id a188so17632537vkc.0 for <20062@debbugs.gnu.org>; Fri, 27 Nov 2015 11:45:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=EL4GteLfwO5JOrw5ddQ6Y+NKuSqBENvflH3E0Pcu1w8=; b=A40iwneP+oUlPX6p0hBJHnoLW+rHMSqU6EbcVq/IXeQ5efoSd9kUua5iEit7f5A5Bl 6+YEBx6pSTx6b7eqDpvkKMtm4hQ7CjJuomNgi5uX5/pA6z/wkP5tKQTaAl/r5Mdw2N1e 18mNitRiGkqR1WNtbLFI61ebKhce2cZ/2rP0KL1URyBoR+54+V57ZsAWxS0ykbFcO9Cr x7MnDLRqTPOxNuCLhxe20l1L2p6XScmWPXjhelEyo51ppAju7q4jH5YfMyksqjxKOIEq GEPCNPA04h2ifXsxZdl72+NCC2Ucc+5spOuQJ4fS93FktuJhGJksXk2UDaxdantQtijT 0ycg== X-Received: by 10.31.183.200 with SMTP id h191mr44547393vkf.147.1448653540950; Fri, 27 Nov 2015 11:45:40 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.84.198 with HTTP; Fri, 27 Nov 2015 11:45:21 -0800 (PST) In-Reply-To: <87a8pz4haz.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <55F35117.5080005@redhat.com> <55F3525D.7050006@cs.ucla.edu> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> <87a8pz4haz.fsf@foo.bar.baz> From: Jim Meyering Date: Fri, 27 Nov 2015 11:45:21 -0800 X-Google-Sender-Auth: 3iC-SfYLtPocKJSm-lcKeIF0lUs Message-ID: Content-Type: multipart/mixed; boundary=001a11439778b61cd805258aefdb X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --001a11439778b61cd805258aefdb Content-Type: text/plain; charset=UTF-8 On Fri, Nov 27, 2015 at 7:01 AM, Giuseppe Scrivano wrote: > Hi Jim, > > thanks for the great advices. > > Jim Meyering writes: > >> I looked at the tests/colors script: we cannot/should not use sha1sum >> for two reasons. 1) it is a short cut; better to include the precise expected >> output in each case. Using this approach, if/when a test fails, there is >> no record of what the expected output was. 2) the "sha1sum" command >> is not universally available by that name. On BSD-based systems it is >> called "sha1". Thus, I began the conversion, and in so doing, I found >> some room for improvement: with the current patches I have, diff -u >> emits a pair of identical color-changing escape sequences before each >> "+"-prefixed line: >> >> $ diff -u --color=always a b|cat -A >> ^[[1;39m--- a^I1969-12-31 16:00:00.000000000 -0800$ >> +++ b^I1969-12-31 16:00:00.000000000 -0800$ >> ^[[0m^[[36m@@ -1 +1 @@^[[0m$ >> ^[[31m-a$ >> ^[[32m^[[32m+b$ >> ^[[0m >> >> Notice also how the final \e[0m is on the final line by itself, >> with no following newline. Please adjust so that it appears at the >> end of the final line instead. I confirmed that git-diff appears >> to do the same thing, but noted that git uses \e[m instead (no >> "0" part). Do you know of any pros/cons for one or the other? > > I don't know if there is any difference in practice between \e[m and > \e0[m. I took the implementation in ls as reference which uses \e0[m. > > >> I've attached the beginnings of the adjusted tests/colors >> script that I used to discover these things. Can you finish the job >> of converting it to use "compare" rather than sha1sum? > > Sure. The new tests helped me to spot two issues in the "diff: add > support for --color" patch. I also added some extra check to avoid to > enter the same colors context twice. These fixes are in > 0004-fixup-diff-add-support-for-color.patch. > > To generate sequences on the same line they belong, I have created a new > patch to facilitate the review. Probably the patch should get squashed > into 0001-diff-add-support-for-color.patch and 0005-tests-Add-tests-for-color-and-palette.patch > once reviewed. > > I have not changed the first two patches of the series, I am including > them just for completeness. Thank you for the quick and nice work. Please adjust the test to use "out" rather than (my fault) "k" as the output file name. Your fixup diff highlights the fact that there is too much duplication in the definitions of the reset_color_context and the four set_*_color_context functions. Any reason not to use a single function named e.g., set_color_context, and pass it the C_* enum constant? This comment was clearly intended for a different enum: +/* What kind of changes a hunk contains. */ +enum colors_style Two nits in the .texi: +Do not use color at all. This is the default when no --color option +is present. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Only use color if standard output is a terminal. s/present/specified/ s/Only use color/Use color only/ In the --help output addition, the spacing is slightly off: N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), The "c" in the added description, "colorize the ..." is indented two spaces too much. Same for the continuation line. In your palette option description, the continuation line must be indented by two spaces, so that help2man knows to format it as such: + N_(" --palette=PALETTE specify the colors to use when --color is active"), + N_(" PALETTE is a colon-separated list terminfo capabilities"), Nit: s/const char/char const/, e.g., here: +extern void set_color_palette (const char *palette); For any pair of arrays whose lengths must be aligned, e.g., +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[]= + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; Please add the following to ensure that no one adds an element to one without also adding the matching element in the other: ARGMATCH_VERIFY (indicator_name, color_indicator); But that would be the first use of argmatch.h and the argmatch module, so you'll actually have to make two more changes (include the .h and add the argmatch module to bootstrap.conf). I've attached a tiny patch. With that, I think we'll be ready to go. Thank you for your patience. --001a11439778b61cd805258aefdb Content-Type: text/x-patch; charset=US-ASCII; name="argmatch.patch" Content-Disposition: attachment; filename="argmatch.patch" Content-Transfer-Encoding: base64 X-Attachment-Id: f_ihi2jtbu6 ZGlmZiAtLWdpdCBhL2Jvb3RzdHJhcC5jb25mIGIvYm9vdHN0cmFwLmNvbmYKaW5kZXggOWIyZGUy Mi4uM2FiMmM4YiAxMDA2NDQKLS0tIGEvYm9vdHN0cmFwLmNvbmYKKysrIGIvYm9vdHN0cmFwLmNv bmYKQEAgLTE5LDYgKzE5LDcgQEAKICMgZ251bGliIG1vZHVsZXMgdXNlZCBieSB0aGlzIHBhY2th Z2UuCiBnbnVsaWJfbW9kdWxlcz0nCiBhbm5vdW5jZS1nZW4KK2FyZ21hdGNoCiBiaW5hcnktaW8K IGMtc3RhY2sKIGNvbmZpZy1oCmRpZmYgLS1naXQgYS9zcmMvdXRpbC5jIGIvc3JjL3V0aWwuYwpp bmRleCA2NWIwNmU5Li5kMjdkMjAyIDEwMDY0NAotLS0gYS9zcmMvdXRpbC5jCisrKyBiL3NyYy91 dGlsLmMKQEAgLTE5LDYgKzE5LDcgQEAKICAgIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiAgSWYg bm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LiAgKi8KCiAjaW5jbHVkZSAi ZGlmZi5oIgorI2luY2x1ZGUgImFyZ21hdGNoLmgiCiAjaW5jbHVkZSA8ZGlybmFtZS5oPgogI2lu Y2x1ZGUgPGVycm9yLmg+CiAjaW5jbHVkZSA8c3lzdGVtLXF1b3RlLmg+CkBAIC01NjEsNiArNTYy LDcgQEAgc3RhdGljIGNvbnN0IGNoYXIgKmNvbnN0IGluZGljYXRvcl9uYW1lW109CiAgIHsKICAg ICAibGMiLCAicmMiLCAiZWMiLCAicnMiLCAiaGQiLCAiYWQiLCAiZGUiLCAibG4iLCBOVUxMCiAg IH07CitBUkdNQVRDSF9WRVJJRlkgKGluZGljYXRvcl9uYW1lLCBjb2xvcl9pbmRpY2F0b3IpOwoK IHN0YXRpYyBjb25zdCBjaGFyICpjb2xvcl9wYWxldHRlOwoK --001a11439778b61cd805258aefdb-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sat, 28 Nov 2015 20:38:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144874302131198 (code B ref 20062); Sat, 28 Nov 2015 20:38:01 +0000 Received: (at 20062) by debbugs.gnu.org; 28 Nov 2015 20:37:01 +0000 Received: from localhost ([127.0.0.1]:58459 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2mEr-000870-VK for submit@debbugs.gnu.org; Sat, 28 Nov 2015 15:37:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43161) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2mEm-00086o-DT for 20062@debbugs.gnu.org; Sat, 28 Nov 2015 15:36:56 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 26ED7C0B7ACA; Sat, 28 Nov 2015 20:36:51 +0000 (UTC) Received: from foo.bar.baz (vpn1-7-167.ams2.redhat.com [10.36.7.167]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tASKajlj031414 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sat, 28 Nov 2015 15:36:46 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> <87a8pz4haz.fsf@foo.bar.baz> Date: Sat, 28 Nov 2015 21:36:44 +0100 In-Reply-To: (Jim Meyering's message of "Fri, 27 Nov 2015 11:45:21 -0800") Message-ID: <87610l509v.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Spam-Score: -4.1 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.1 (----) --=-=-= Content-Type: text/plain Jim Meyering writes: > diff --git a/bootstrap.conf b/bootstrap.conf > index 9b2de22..3ab2c8b 100644 > --- a/bootstrap.conf > +++ b/bootstrap.conf > @@ -19,6 +19,7 @@ > # gnulib modules used by this package. > gnulib_modules=' > announce-gen > +argmatch > binary-io > c-stack > config-h > diff --git a/src/util.c b/src/util.c > index 65b06e9..d27d202 100644 > --- a/src/util.c > +++ b/src/util.c > @@ -19,6 +19,7 @@ > along with this program. If not, see . */ > > #include "diff.h" > +#include "argmatch.h" > #include > #include > #include > @@ -561,6 +562,7 @@ static const char *const indicator_name[]= > { > "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL > }; > +ARGMATCH_VERIFY (indicator_name, color_indicator); > > static const char *color_palette; thanks for the review and the patch. I had to add this chunk as reported by "make syntax-check": diff --git a/po/POTFILES.in b/po/POTFILES.in index 74fb756..af39427 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +lib/argmatch.c lib/c-stack.c lib/error.c lib/file-type.c As it is hopefully getting closer to be accepted, I am attaching the full series with the amended changes. I've verified that each patch passes "make check" and "make syntax-check". Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 900ab32b3cd9d06a9c002c53eb5c9738047f203f Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH 1/5] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (set_color_context): New function. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 54 ++++++++-- src/diff.c | 27 ++++- src/diff.h | 27 +++++ src/normal.c | 18 +++- src/side.c | 15 +++ src/util.c | 308 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 423 insertions(+), 47 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..b2c39da 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is specified. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Use color only if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..104c90b 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_color_context (HEADER_CONTEXT); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + set_color_context (RESET_CONTEXT); } /* Print an edit script in context format. */ @@ -205,9 +207,11 @@ pr_context_hunk (struct change *hunk) if (function) print_context_function (out, function); + set_color_context (LINE_NUMBER_CONTEXT); fputs ("\n*** ", out); print_context_number_range (&files[0], first0, last0); fputs (" ****\n", out); + set_color_context (RESET_CONTEXT); if (changes & OLD) { @@ -215,6 +219,7 @@ pr_context_hunk (struct change *hunk) for (i = first0; i <= last0; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -225,18 +230,26 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); + { + reset_context = true; + set_color_context (DELETE_CONTEXT); + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } print_1_line (prefix, &files[0].linbuf[i]); + if (reset_context) + set_color_context (RESET_CONTEXT); } } + set_color_context (LINE_NUMBER_CONTEXT); fputs ("--- ", out); print_context_number_range (&files[1], first1, last1); fputs (" ----\n", out); + set_color_context (RESET_CONTEXT); if (changes & NEW) { @@ -244,6 +257,7 @@ pr_context_hunk (struct change *hunk) for (i = first1; i <= last1; i++) { + bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -254,12 +268,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - + { + reset_context = true; + set_color_context (ADD_CONTEXT); + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } print_1_line (prefix, &files[1].linbuf[i]); + if (reset_context) + set_color_context (RESET_CONTEXT); } } } @@ -330,11 +349,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_color_context (LINE_NUMBER_CONTEXT); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + set_color_context (RESET_CONTEXT); if (function) print_context_function (out, function); @@ -360,9 +381,17 @@ pr_unidiff_hunk (struct change *hunk) } else { + bool reset_context = false; + /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + { + reset_context = true; + set_color_context (DELETE_CONTEXT); + } + while (k--) { char const * const *line = &files[0].linbuf[i++]; @@ -375,6 +404,11 @@ pr_unidiff_hunk (struct change *hunk) /* Then output the inserted part. */ k = next->inserted; + if (k) + { + reset_context = true; + set_color_context (ADD_CONTEXT); + } while (k--) { char const * const *line = &files[1].linbuf[j++]; @@ -386,6 +420,8 @@ pr_unidiff_hunk (struct change *hunk) /* We're done with this hunk, so on to the next! */ + if (reset_context) + set_color_context (RESET_CONTEXT); next = next->link; } } diff --git a/src/diff.c b/src/diff.c index efd7e47..536f545 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..3c46042 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* When colors should be used in the output. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -390,3 +406,14 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); + +enum color_context +{ + HEADER_CONTEXT, + ADD_CONTEXT, + DELETE_CONTEXT, + RESET_CONTEXT, + LINE_NUMBER_CONTEXT, +}; + +extern void set_color_context (enum color_context color_context); diff --git a/src/normal.c b/src/normal.c index 721fd1a..82aee77 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,31 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_color_context (LINE_NUMBER_CONTEXT); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); fputc ('\n', outfile); + set_color_context (RESET_CONTEXT); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + set_color_context (DELETE_CONTEXT); + for (i = first0; i <= last0; i++) + print_1_line ("<", &files[0].linbuf[i]); + set_color_context (RESET_CONTEXT); + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + set_color_context (ADD_CONTEXT); + for (i = first1; i <= last1; i++) + print_1_line (">", &files[1].linbuf[i]); + set_color_context (RESET_CONTEXT); + } } diff --git a/src/side.c b/src/side.c index 155512c..a0213c4 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE_CONTEXT); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD_CONTEXT); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET_CONTEXT); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..694f4d9 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,174 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + set_color_context (RESET_CONTEXT); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + +static char const *current_name0; +static char const *current_name1; +static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -150,10 +334,6 @@ print_message_queue (void) we fork off a 'pr' and make OUTFILE a pipe to it. 'pr' then outputs to our stdout. */ -static char const *current_name0; -static char const *current_name1; -static bool currently_recursive; - void setup_output (char const *name0, char const *name1, bool recursive) { @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -672,8 +855,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,39 +877,85 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_color_context (enum color_context color_context) +{ + process_signals (); + if (colors_enabled) + { + switch (color_context) + { + case HEADER_CONTEXT: + fputs ("\x1B[1m", outfile); + break; - default: - column += isprint (c) != 0; - putc (c, out); - break; - } + case LINE_NUMBER_CONTEXT: + fputs ("\x1B[36m", outfile); + + break; + + case ADD_CONTEXT: + fputs ("\x1B[32m", outfile); + break; + + case DELETE_CONTEXT: + fputs ("\x1B[31m", outfile); + break; + + case RESET_CONTEXT: + fputs ("\x1b[0m", outfile); + break; + + default: + abort (); + } } } -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-diff-add-palette.patch >From f860a90da16f6d21939611718696347c3506b075 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 2/5] diff: add --palette * bootstrap (gnulib_modules): Add 'argmatch'. * doc/diffutils.texi: Add documentation for --palette * src/diff.h (set_color_palette): New prototype. * src/diff.c (set_color_palette): New function. (color_palette): New variable. * src/utils.c: Include "argmatch.h". (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_color_context): Use put_indicator instead of directly outputting the sequence. * po/POTFILES.in: Add 'lib/argmatch.c' --- bootstrap.conf | 1 + doc/diffutils.texi | 34 +++++ po/POTFILES.in | 1 + src/diff.c | 8 + src/diff.h | 1 + src/util.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 462 insertions(+), 7 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 9b2de22..3ab2c8b 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -19,6 +19,7 @@ # gnulib modules used by this package. gnulib_modules=' announce-gen +argmatch binary-io c-stack config-h diff --git a/doc/diffutils.texi b/doc/diffutils.texi index b2c39da..4ec9a0b 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3890,6 +3890,40 @@ if-then-else format. @xref{Line Formats}. @itemx --show-c-function Show which C function each change is in. @xref{C Function Headings}. +@item --palette=@var{palette} +Specify what color palette to use when colored output is enabled. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red deleted lines, +green added lines, cyan line numbers, bold header. + +Supported capabilities are as follows. + +@table @code +@item ad=32 +@vindex ad @r{capability} + +SGR substring for added lines. +The default is green foreground. + +@item de=31 +@vindex de @r{capability} + +SGR substring for deleted lines. +The default is red foreground. + +@item hd=1 +@vindex hd @r{capability} + +SGR substring for chunk header. +The default is bold foreground. + +@item ln=36 +@vindex ln @r{capability} + +SGR substring for line numbers. +The default is cyan foreground. +@end table + + @item -q @itemx --brief Report only whether the files differ, not the details of the diff --git a/po/POTFILES.in b/po/POTFILES.in index 74fb756..af39427 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +lib/argmatch.c lib/c-stack.c lib/error.c lib/file-type.c diff --git a/src/diff.c b/src/diff.c index 536f545..46ac99d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_PALETTE_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -196,6 +197,7 @@ static struct option const longopts[] = {"old-group-format", 1, 0, OLD_GROUP_FORMAT_OPTION}, {"old-line-format", 1, 0, OLD_LINE_FORMAT_OPTION}, {"paginate", 0, 0, 'l'}, + {"palette", 1, 0, COLOR_PALETTE_OPTION}, {"rcs", 0, 0, 'n'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_PALETTE_OPTION: + set_color_palette (optarg); + break; + default: try_help (NULL, NULL); } @@ -950,6 +956,8 @@ static char const * const option_help_msgid[] = { N_(" --speed-large-files assume large files and many scattered small changes"), N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), N_(" or 'auto' (the default)"), + N_(" --palette=PALETTE specify the colors to use when --color is active"), + N_(" PALETTE is a colon-separated list terminfo capabilities"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), diff --git a/src/diff.h b/src/diff.h index 3c46042..c5fe4f9 100644 --- a/src/diff.h +++ b/src/diff.h @@ -417,3 +417,4 @@ enum color_context }; extern void set_color_context (enum color_context color_context); +extern void set_color_palette (char const *palette); diff --git a/src/util.c b/src/util.c index 694f4d9..3bd828f 100644 --- a/src/util.c +++ b/src/util.c @@ -19,6 +19,7 @@ along with this program. If not, see . */ #include "diff.h" +#include "argmatch.h" #include #include #include @@ -310,6 +311,397 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the --palette argument; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[] = + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; +ARGMATCH_VERIFY (indicator_name, color_indicator); + +static char const *color_palette; + +void +set_color_palette (char const *palette) +{ + color_palette = palette; +} + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = color_palette) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + --palette string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for --palette")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +715,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -923,42 +1318,57 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + +static enum color_context last_context = RESET_CONTEXT; void set_color_context (enum color_context color_context) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != color_context) { + put_indicator (&color_indicator[C_LEFT]); switch (color_context) { case HEADER_CONTEXT: - fputs ("\x1B[1m", outfile); + put_indicator (&color_indicator[C_HEADER]); break; case LINE_NUMBER_CONTEXT: - fputs ("\x1B[36m", outfile); - + put_indicator (&color_indicator[C_LINE]); break; case ADD_CONTEXT: - fputs ("\x1B[32m", outfile); + put_indicator (&color_indicator[C_ADD]); break; case DELETE_CONTEXT: - fputs ("\x1B[31m", outfile); + put_indicator (&color_indicator[C_DELETE]); break; case RESET_CONTEXT: - fputs ("\x1b[0m", outfile); + put_indicator (&color_indicator[C_RESET]); break; default: abort (); } + put_indicator (&color_indicator[C_RIGHT]); + last_context = color_context; } } + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-doc-mention-color-and-palette-in-NEWS.patch >From bebef1281fdb6d53f725b0eb1d18703e8845d768 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:03:32 +0000 Subject: [PATCH 3/5] doc: mention --color and --palette in NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 7cdfedd..088f13b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU diffutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + diff accepts two new options --color and --palette to generate + and configure colored output. --color takes an optional argument + specifying when to colorize a line: --color=always, --color=auto, + --color=never. --palette is used to configure which colors are used. + ** Bug fixes When binary files differ, diff now exits with status 1 as POSIX requires. -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-tests-Add-tests-for-color-and-palette.patch >From e58c36a9062168bf56a8447d1c4287879ef54e9f Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:05:10 +0000 Subject: [PATCH 4/5] tests: Add tests for --color and --palette * tests/colors: New file. * tests/Makefile.am (TESTS): Add colors. --- tests/Makefile.am | 3 +- tests/colors | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100755 tests/colors diff --git a/tests/Makefile.am b/tests/Makefile.am index 438fbdf..805ccc2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ TESTS = \ no-newline-at-eof \ stdin \ strcoll-0-names \ - filename-quoting + filename-quoting \ + colors EXTRA_DIST = \ $(TESTS) init.sh t-local.sh diff --git a/tests/colors b/tests/colors new file mode 100755 index 0000000..92c0452 --- /dev/null +++ b/tests/colors @@ -0,0 +1,119 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=UTC0 +export TZ + +fail=0 + +echo a > a +echo b > b + +epoch='1970-01-01 00:00:00' +touch --date="$epoch" a b + +gen_exp_u() +{ + local tab=$(printf '\t') + local epoch_plus="$epoch.000000000 +0000" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd--- a$tab$epoch_plus ++++ b$tab$epoch_plus +$rs${ln}@@ -1 +1 @@$rs +$de-a +$ad+b +$rs" +} + +gen_exp_c() +{ + local tab=$(printf '\t') + local epoch_posix_1003_1_2001="Thu Jan 1 00:00:00 1970" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd*** a$tab$epoch_posix_1003_1_2001 +--- b$tab$epoch_posix_1003_1_2001 +$rs***************$ln +*** 1 **** +$rs$de! a +$rs$ln--- 1 ---- +$rs$ad! b +$rs" +} + +gen_exp_default() +{ + printf '%s' \ +"1c1 +< a +--- +> b +" +} + +gen_exp_default_colors() +{ + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"${ln}1c1 +$rs$de< a +$rs--- +$ad> b +$rs" +} + +# Compare with some known outputs + +rs=0 hd=1 ad=32 de=31 ln=36 + +diff --color=auto a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff --color=never a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff --color=always a b > out +test $? = 1 || fail=1 +gen_exp_default_colors > exp || framework_failure_ +compare exp out || fail=1 + +diff -u --color=always a b > out +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp out || fail=1 + +diff -c --color=always a b > out +test $? = 1 || fail=1 +gen_exp_c > exp || framework_failure_ +compare exp out || fail=1 + +rs=0 hd=33 ad=34 de=35 ln=36 +diff -u --color=always --palette="rs=0:hd=33:ad=34:de=35:ln=36" a b > out +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp out || fail=1 + +Exit $fail -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0005-Generate-terminal-sequences-on-the-line-they-belong.patch >From a61b7dc46b43459656cde44824d23948cc28d5f9 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 27 Nov 2015 13:56:05 +0100 Subject: [PATCH 5/5] Generate terminal sequences on the line they belong * src/diff.h: New function 'print_1_line_nl'. * src/context.c (pr_context_hunk): Use 'print_1_line_nl'. Generate terminal sequences on the line they belong. (pr_unidiff_hunk): Likewise. * src/normal.c (print_normal_hunk): Likewise. * src/util.c (print_1_line_nl): New function. (print_1_line): Become a wrapper of 'print_1_line_nl'. * tests/colors: Adjust tests. --- src/context.c | 67 +++++++++++++++++++++++++++++++++-------------------------- src/diff.h | 1 + src/normal.c | 26 ++++++++++++++++------- src/util.c | 19 +++++++++++++++-- tests/colors | 28 ++++++++++++------------- 5 files changed, 89 insertions(+), 52 deletions(-) diff --git a/src/context.c b/src/context.c index 104c90b..46b5b1f 100644 --- a/src/context.c +++ b/src/context.c @@ -207,19 +207,23 @@ pr_context_hunk (struct change *hunk) if (function) print_context_function (out, function); + putc ('\n', out); set_color_context (LINE_NUMBER_CONTEXT); - fputs ("\n*** ", out); + fputs ("*** ", out); print_context_number_range (&files[0], first0, last0); - fputs (" ****\n", out); + fputs (" ****", out); set_color_context (RESET_CONTEXT); + putc ('\n', out); if (changes & OLD) { struct change *next = hunk; + if (first0 <= last0) + set_color_context (DELETE_CONTEXT); + for (i = first0; i <= last0; i++) { - bool reset_context = false; /* Skip past changes that apply (in file 0) only to lines before line I. */ @@ -231,33 +235,35 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) { - reset_context = true; - set_color_context (DELETE_CONTEXT); /* The change NEXT covers this line. If lines were inserted here in file 1, this is "changed". Otherwise it is "deleted". */ prefix = (next->inserted > 0 ? "!" : "-"); } - - print_1_line (prefix, &files[0].linbuf[i]); - if (reset_context) + print_1_line_nl (prefix, &files[0].linbuf[i], true); + if (i == last0) set_color_context (RESET_CONTEXT); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } set_color_context (LINE_NUMBER_CONTEXT); fputs ("--- ", out); print_context_number_range (&files[1], first1, last1); - fputs (" ----\n", out); + fputs (" ----", out); set_color_context (RESET_CONTEXT); + putc ('\n', out); if (changes & NEW) { struct change *next = hunk; + if (first1 <= last1) + set_color_context (ADD_CONTEXT); + for (i = first1; i <= last1; i++) { - bool reset_context = false; /* Skip past changes that apply (in file 1) only to lines before line I. */ @@ -269,16 +275,16 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) { - reset_context = true; - set_color_context (ADD_CONTEXT); /* The change NEXT covers this line. If lines were deleted here in file 0, this is "changed". Otherwise it is "inserted". */ prefix = (next->deleted > 0 ? "!" : "+"); } - print_1_line (prefix, &files[1].linbuf[i]); - if (reset_context) + print_1_line_nl (prefix, &files[1].linbuf[i], true); + if (i == last1) set_color_context (RESET_CONTEXT); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } } @@ -381,16 +387,11 @@ pr_unidiff_hunk (struct change *hunk) } else { - bool reset_context = false; - /* For each difference, first output the deleted part. */ k = next->deleted; if (k) - { - reset_context = true; - set_color_context (DELETE_CONTEXT); - } + set_color_context (DELETE_CONTEXT); while (k--) { @@ -398,30 +399,38 @@ pr_unidiff_hunk (struct change *hunk) putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + set_color_context (RESET_CONTEXT); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* Then output the inserted part. */ k = next->inserted; if (k) - { - reset_context = true; - set_color_context (ADD_CONTEXT); - } - while (k--) + set_color_context (ADD_CONTEXT); + + while (k--) { char const * const *line = &files[1].linbuf[j++]; putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + set_color_context (RESET_CONTEXT); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* We're done with this hunk, so on to the next! */ - if (reset_context) - set_color_context (RESET_CONTEXT); next = next->link; } } diff --git a/src/diff.h b/src/diff.h index c5fe4f9..6f1bb34 100644 --- a/src/diff.h +++ b/src/diff.h @@ -399,6 +399,7 @@ extern void output_1_line (char const *, char const *, char const *, extern void perror_with_name (char const *); extern void pfatal_with_name (char const *) __attribute__((noreturn)); extern void print_1_line (char const *, char const * const *); +extern void print_1_line_nl (char const *, char const * const *, bool); extern void print_message_queue (void); extern void print_number_range (char, struct file_data *, lin, lin); extern void print_script (struct change *, struct change * (*) (struct change *), diff --git a/src/normal.c b/src/normal.c index 82aee77..e78e8ba 100644 --- a/src/normal.c +++ b/src/normal.c @@ -53,16 +53,22 @@ print_normal_hunk (struct change *hunk) print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); - fputc ('\n', outfile); set_color_context (RESET_CONTEXT); + fputc ('\n', outfile); /* Print the lines that the first file has. */ if (changes & OLD) { - set_color_context (DELETE_CONTEXT); + if (first0 <= last0) + set_color_context (DELETE_CONTEXT); for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); - set_color_context (RESET_CONTEXT); + { + print_1_line_nl ("<", &files[0].linbuf[i], true); + if (i == last0) + set_color_context (RESET_CONTEXT); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } } if (changes == CHANGED) @@ -71,9 +77,15 @@ print_normal_hunk (struct change *hunk) /* Print the lines that the second file has. */ if (changes & NEW) { - set_color_context (ADD_CONTEXT); + if (first1 <= last1) + set_color_context (ADD_CONTEXT); for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); - set_color_context (RESET_CONTEXT); + { + print_1_line_nl (">", &files[1].linbuf[i], true); + if (i == last1) + set_color_context (RESET_CONTEXT); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } } } diff --git a/src/util.c b/src/util.c index 3bd828f..1fa61fa 100644 --- a/src/util.c +++ b/src/util.c @@ -1208,6 +1208,18 @@ print_script (struct change *script, void print_1_line (char const *line_flag, char const *const *line) { + print_1_line_nl (line_flag, line, false); +} + +/* Print the text of a single line LINE, + flagging it with the characters in LINE_FLAG (which say whether + the line is inserted, deleted, changed, etc.). LINE_FLAG must not + end in a blank, unless it is a single blank. If SKIP_NL is set, then + the final '\n' is not printed. */ + +void +print_1_line_nl (char const *line_flag, char const *const *line, bool skip_nl) +{ char const *base = line[0], *limit = line[1]; /* Help the compiler. */ FILE *out = outfile; /* Help the compiler some more. */ char const *flag_format = 0; @@ -1235,10 +1247,13 @@ print_1_line (char const *line_flag, char const *const *line) fprintf (out, flag_format_1, line_flag_1); } - output_1_line (base, limit, flag_format, line_flag); + output_1_line (base, limit - (skip_nl && limit[-1] == '\n'), flag_format, line_flag); if ((!line_flag || line_flag[0]) && limit[-1] != '\n') - fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + { + set_color_context (RESET_CONTEXT); + fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + } } /* Output a line from BASE up to LIMIT. diff --git a/tests/colors b/tests/colors index 92c0452..facfd8d 100755 --- a/tests/colors +++ b/tests/colors @@ -26,9 +26,9 @@ gen_exp_u() "$hd--- a$tab$epoch_plus +++ b$tab$epoch_plus $rs${ln}@@ -1 +1 @@$rs -$de-a -$ad+b -$rs" +$de-a$rs +$ad+b$rs +" } gen_exp_c() @@ -43,12 +43,12 @@ gen_exp_c() printf '%s' \ "$hd*** a$tab$epoch_posix_1003_1_2001 --- b$tab$epoch_posix_1003_1_2001 -$rs***************$ln -*** 1 **** -$rs$de! a -$rs$ln--- 1 ---- -$rs$ad! b -$rs" +$rs*************** +$ln*** 1 ****$rs +$de! a$rs +$ln--- 1 ----$rs +$ad! b$rs +" } gen_exp_default() @@ -69,11 +69,11 @@ gen_exp_default_colors() local de=$(printf "\e[${de}m") local ln=$(printf "\e[${ln}m") printf '%s' \ -"${ln}1c1 -$rs$de< a -$rs--- -$ad> b -$rs" +"${ln}1c1$rs +$de< a$rs +--- +$ad> b$rs +" } # Compare with some known outputs -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 29 Nov 2015 04:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144877166113329 (code B ref 20062); Sun, 29 Nov 2015 04:35:01 +0000 Received: (at 20062) by debbugs.gnu.org; 29 Nov 2015 04:34:21 +0000 Received: from localhost ([127.0.0.1]:58644 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2tgr-0003Su-5x for submit@debbugs.gnu.org; Sat, 28 Nov 2015 23:34:21 -0500 Received: from mail-vk0-f47.google.com ([209.85.213.47]:34081) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a2tgo-0003Sm-Vg for 20062@debbugs.gnu.org; Sat, 28 Nov 2015 23:34:19 -0500 Received: by vkbs1 with SMTP id s1so85940144vkb.1 for <20062@debbugs.gnu.org>; Sat, 28 Nov 2015 20:34:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=PZ/K8pxc2DaZl637ZwDgcU+kNQpbqdSmFKNZWXi2lCM=; b=b+LF68bfoUNef/EIk50nDjAUMbSfdAv+0Lfvk78kDh5KESk2qURJH5Hpj+JM21ZcOq QHVNaaWHK9JfPkMivEf8FZZQuWEX/OXU4H7AtMfX/sh+sWWoMbNdrVIaalkFz5kjGBSM YCiZztQIiwwT8+PJb5rJu9Dp31au9qNcrTaiz+93fNs3Lg45L+3pifwPYTDMt6C1GgJx KdIKSbbZ5i1G5M1MHwGY5d2yTZaXWg3Gn2kyLKul9/JgPhIRRDKaywFNsVRbkVQsnBWM O2fZAR7umNucx+zmPgOnnr+UCb9Bk/in6bbeJY4N2jb2iCgvI0a95KScd9r0Ol2ESar8 Nqzg== X-Received: by 10.31.52.207 with SMTP id b198mr48650330vka.77.1448771658547; Sat, 28 Nov 2015 20:34:18 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.84.198 with HTTP; Sat, 28 Nov 2015 20:33:59 -0800 (PST) In-Reply-To: <87610l509v.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87lhccqapr.fsf@foo.bar.baz> <55F3F26A.4050400@cs.ucla.edu> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> <87a8pz4haz.fsf@foo.bar.baz> <87610l509v.fsf@foo.bar.baz> From: Jim Meyering Date: Sat, 28 Nov 2015 20:33:59 -0800 X-Google-Sender-Auth: doVdA05o8vDSwhhEBWXagJbq16U Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Sat, Nov 28, 2015 at 12:36 PM, Giuseppe Scrivano wrote: .... > As it is hopefully getting closer to be accepted, I am attaching the > full series with the amended changes. I've verified that each patch > passes "make check" and "make syntax-check". Thanks, I see no problem. I can push as-is, but wondered if you wanted to merge your 0005 patch into the others? Probably not worth the work. Either way is fine. From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Giuseppe Scrivano Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 29 Nov 2015 13:46:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Jim Meyering Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144880475414290 (code B ref 20062); Sun, 29 Nov 2015 13:46:01 +0000 Received: (at 20062) by debbugs.gnu.org; 29 Nov 2015 13:45:54 +0000 Received: from localhost ([127.0.0.1]:58834 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a32IY-0003iM-Sl for submit@debbugs.gnu.org; Sun, 29 Nov 2015 08:45:53 -0500 Received: from mx1.redhat.com ([209.132.183.28]:43723) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a32IA-0003hq-VR for 20062@debbugs.gnu.org; Sun, 29 Nov 2015 08:45:48 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B5171C0B7AC6; Sun, 29 Nov 2015 13:45:25 +0000 (UTC) Received: from foo.bar.baz (vpn1-6-166.ams2.redhat.com [10.36.6.166]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id tATDjJoN009772 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Sun, 29 Nov 2015 08:45:21 -0500 From: Giuseppe Scrivano References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> <87a8pz4haz.fsf@foo.bar.baz> <87610l509v.fsf@foo.bar.baz> Date: Sun, 29 Nov 2015 14:45:19 +0100 In-Reply-To: (Jim Meyering's message of "Sat, 28 Nov 2015 20:33:59 -0800") Message-ID: <871tb85380.fsf@foo.bar.baz> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Spam-Score: -4.1 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.1 (----) --=-=-= Content-Type: text/plain Jim Meyering writes: > On Sat, Nov 28, 2015 at 12:36 PM, Giuseppe Scrivano wrote: > .... >> As it is hopefully getting closer to be accepted, I am attaching the >> full series with the amended changes. I've verified that each patch >> passes "make check" and "make syntax-check". > > Thanks, I see no problem. > I can push as-is, but wondered if you wanted to merge > your 0005 patch into the others? Probably not worth the work. > Either way is fine. it was not much work as there were no conflicts to solve, so I splitted 0005 into 0001 and 0004. I verified again that each step passes all the tests. Regards, Giuseppe --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-diff-add-support-for-color.patch >From 4b944653c3c27d99312f77813394a4c965c5c787 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Sun, 8 Mar 2015 22:45:11 +0100 Subject: [PATCH 1/4] diff: add support for --color * doc/diffutils.texi (diff Options): Add documentation for --color. Copied from coreutils ls --color. * src/context.c (pr_unidiff_hunk): Set the color context. (print_context_header): Likewise. (pr_context_hunk): Likewise. * src/diff.h (enum colors_style): New enum to record when to use colors. (colors_style): New variable to memorize the argument value. (set_color_context): Add function definition. * src/diff.c: : Define COLOR_OPTION. (specify_colors_style): New function. (longopts): Add --color. (main): Handle --color argument. (option_help_msgid): Add usage string for --color. * src/normal.c (print_normal_hunk): Set the color context. * src/side.c (print_1sdiff_line): Likewise. * src/util.c (print_1_line_nl): New function. (print_1_line): Make it a wrapper of 'print_1_line_nl'. (colors_enabled): New boolean variable. (begin_output): Call check_color_output once the output file is configured. (output_1_line): Periodically call `process_signals'. (caught_signals): New sigset_t. (colors_enabled): New boolean variable. (interrupt_signal): New sig_atomic_t. (stop_signal_count): New sig_atomic_t. (check_color_output): New function. (install_signal_handlers): Likewise. Copied from coreutils ls. (process_signals): Likewise. Copied from coreutils ls. (set_color_context): New function. (sighandler): Likewise. Copied from coreutils ls. (stophandler): Likewise. Copied from coreutils ls. --- doc/diffutils.texi | 21 ++++ src/context.c | 81 ++++++++++--- src/diff.c | 27 ++++- src/diff.h | 28 +++++ src/normal.c | 30 ++++- src/side.c | 15 +++ src/util.c | 327 +++++++++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 471 insertions(+), 58 deletions(-) diff --git a/doc/diffutils.texi b/doc/diffutils.texi index 091257f..b2c39da 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3742,6 +3742,27 @@ Read and write data in binary mode. @xref{Binary}. Use the context output format, showing three lines of context. @xref{Context Format}. +@item --color [=@var{when}] +@cindex color, distinguishing different context +Specify whether to use color for distinguishing different contexts, +like header, added or removed lines. @var{when} may be omitted, or +one of: +@itemize @bullet +@item none +@vindex none @r{color option} +Do not use color at all. This is the default when no --color option +is specified. +@item auto +@vindex auto @r{color option} +@cindex terminal, using color iff +Use color only if standard output is a terminal. +@item always +@vindex always @r{color option} +Always use color. +@end itemize +Specifying @option{--color} and no @var{when} is equivalent to +@option{--color=auto}. + @item -C @var{lines} @itemx --context@r{[}=@var{lines}@r{]} Use the context output format, showing @var{lines} (an integer) lines of diff --git a/src/context.c b/src/context.c index e0f21c4..46b5b1f 100644 --- a/src/context.c +++ b/src/context.c @@ -80,6 +80,7 @@ print_context_label (char const *mark, void print_context_header (struct file_data inf[], char const *const *names, bool unidiff) { + set_color_context (HEADER_CONTEXT); if (unidiff) { print_context_label ("---", &inf[0], names[0], file_label[0]); @@ -90,6 +91,7 @@ print_context_header (struct file_data inf[], char const *const *names, bool uni print_context_label ("***", &inf[0], names[0], file_label[0]); print_context_label ("---", &inf[1], names[1], file_label[1]); } + set_color_context (RESET_CONTEXT); } /* Print an edit script in context format. */ @@ -205,14 +207,21 @@ pr_context_hunk (struct change *hunk) if (function) print_context_function (out, function); - fputs ("\n*** ", out); + putc ('\n', out); + set_color_context (LINE_NUMBER_CONTEXT); + fputs ("*** ", out); print_context_number_range (&files[0], first0, last0); - fputs (" ****\n", out); + fputs (" ****", out); + set_color_context (RESET_CONTEXT); + putc ('\n', out); if (changes & OLD) { struct change *next = hunk; + if (first0 <= last0) + set_color_context (DELETE_CONTEXT); + for (i = first0; i <= last0; i++) { /* Skip past changes that apply (in file 0) @@ -225,23 +234,34 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line0 <= i) - /* The change NEXT covers this line. - If lines were inserted here in file 1, this is "changed". - Otherwise it is "deleted". */ - prefix = (next->inserted > 0 ? "!" : "-"); - - print_1_line (prefix, &files[0].linbuf[i]); + { + /* The change NEXT covers this line. + If lines were inserted here in file 1, this is "changed". + Otherwise it is "deleted". */ + prefix = (next->inserted > 0 ? "!" : "-"); + } + print_1_line_nl (prefix, &files[0].linbuf[i], true); + if (i == last0) + set_color_context (RESET_CONTEXT); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } + set_color_context (LINE_NUMBER_CONTEXT); fputs ("--- ", out); print_context_number_range (&files[1], first1, last1); - fputs (" ----\n", out); + fputs (" ----", out); + set_color_context (RESET_CONTEXT); + putc ('\n', out); if (changes & NEW) { struct change *next = hunk; + if (first1 <= last1) + set_color_context (ADD_CONTEXT); + for (i = first1; i <= last1; i++) { /* Skip past changes that apply (in file 1) @@ -254,12 +274,17 @@ pr_context_hunk (struct change *hunk) prefix = " "; if (next && next->line1 <= i) - /* The change NEXT covers this line. - If lines were deleted here in file 0, this is "changed". - Otherwise it is "inserted". */ - prefix = (next->deleted > 0 ? "!" : "+"); - - print_1_line (prefix, &files[1].linbuf[i]); + { + /* The change NEXT covers this line. + If lines were deleted here in file 0, this is "changed". + Otherwise it is "inserted". */ + prefix = (next->deleted > 0 ? "!" : "+"); + } + print_1_line_nl (prefix, &files[1].linbuf[i], true); + if (i == last1) + set_color_context (RESET_CONTEXT); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', out); } } } @@ -330,11 +355,13 @@ pr_unidiff_hunk (struct change *hunk) begin_output (); out = outfile; + set_color_context (LINE_NUMBER_CONTEXT); fputs ("@@ -", out); print_unidiff_number_range (&files[0], first0, last0); fputs (" +", out); print_unidiff_number_range (&files[1], first1, last1); fputs (" @@", out); + set_color_context (RESET_CONTEXT); if (function) print_context_function (out, function); @@ -363,25 +390,43 @@ pr_unidiff_hunk (struct change *hunk) /* For each difference, first output the deleted part. */ k = next->deleted; + if (k) + set_color_context (DELETE_CONTEXT); + while (k--) { char const * const *line = &files[0].linbuf[i++]; putc ('-', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + set_color_context (RESET_CONTEXT); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* Then output the inserted part. */ k = next->inserted; - while (k--) + if (k) + set_color_context (ADD_CONTEXT); + + while (k--) { char const * const *line = &files[1].linbuf[j++]; putc ('+', out); if (initial_tab && ! (suppress_blank_empty && **line == '\n')) putc ('\t', out); - print_1_line (NULL, line); + print_1_line_nl (NULL, line, true); + + if (!k) + set_color_context (RESET_CONTEXT); + + if (line[1][-1] == '\n') + putc ('\n', out); } /* We're done with this hunk, so on to the next! */ diff --git a/src/diff.c b/src/diff.c index efd7e47..536f545 100644 --- a/src/diff.c +++ b/src/diff.c @@ -70,6 +70,7 @@ static void add_regexp (struct regexp_list *, char const *); static void summarize_regexp_list (struct regexp_list *); static void specify_style (enum output_style); static void specify_value (char const **, char const *, char const *); +static void specify_colors_style (char const *); static void try_help (char const *, char const *) __attribute__((noreturn)); static void check_stdout (void); static void usage (void); @@ -136,7 +137,9 @@ enum UNCHANGED_GROUP_FORMAT_OPTION, OLD_GROUP_FORMAT_OPTION, NEW_GROUP_FORMAT_OPTION, - CHANGED_GROUP_FORMAT_OPTION + CHANGED_GROUP_FORMAT_OPTION, + + COLOR_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -159,6 +162,7 @@ static struct option const longopts[] = {"binary", 0, 0, BINARY_OPTION}, {"brief", 0, 0, 'q'}, {"changed-group-format", 1, 0, CHANGED_GROUP_FORMAT_OPTION}, + {"color", 2, 0, COLOR_OPTION}, {"context", 2, 0, 'C'}, {"ed", 0, 0, 'e'}, {"exclude", 1, 0, 'x'}, @@ -627,6 +631,10 @@ main (int argc, char **argv) specify_value (&group_format[c], optarg, group_format_option[c]); break; + case COLOR_OPTION: + specify_colors_style (optarg); + break; + default: try_help (NULL, NULL); } @@ -940,6 +948,8 @@ static char const * const option_help_msgid[] = { N_("-d, --minimal try hard to find a smaller set of changes"), N_(" --horizon-lines=NUM keep NUM lines of the common prefix and suffix"), N_(" --speed-large-files assume large files and many scattered small changes"), + N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), + N_(" or 'auto' (the default)"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), @@ -1008,6 +1018,21 @@ specify_style (enum output_style style) output_style = style; } } + +/* Set the color mode. */ +static void +specify_colors_style (char const *value) +{ + if (value == NULL || STREQ (value, "auto")) + colors_style = AUTO; + else if (STREQ (value, "always")) + colors_style = ALWAYS; + else if (STREQ (value, "never")) + colors_style = NEVER; + else + try_help ("invalid color '%s'", value); +} + /* Set the last-modified time of *ST to be the current time. */ diff --git a/src/diff.h b/src/diff.h index 465e4bc..7bf7344 100644 --- a/src/diff.h +++ b/src/diff.h @@ -38,6 +38,19 @@ enum changes /* Both deletes and inserts: a hunk containing both old and new lines. */ CHANGED }; + +/* When colors should be used in the output. */ +enum colors_style +{ + /* Never output colors. */ + NEVER, + + /* Output colors if the output is a terminal. */ + AUTO, + + /* Always output colors. */ + ALWAYS, +}; /* Variables for command line options */ @@ -83,6 +96,9 @@ enum output_style XTERN enum output_style output_style; +/* Define the current color context used to print a line. */ +XTERN enum colors_style colors_style; + /* Nonzero if output cannot be generated for identical files. */ XTERN bool no_diff_means_no_output; @@ -383,6 +399,7 @@ extern void output_1_line (char const *, char const *, char const *, extern void perror_with_name (char const *); extern void pfatal_with_name (char const *) __attribute__((noreturn)); extern void print_1_line (char const *, char const * const *); +extern void print_1_line_nl (char const *, char const * const *, bool); extern void print_message_queue (void); extern void print_number_range (char, struct file_data *, lin, lin); extern void print_script (struct change *, struct change * (*) (struct change *), @@ -390,3 +407,14 @@ extern void print_script (struct change *, struct change * (*) (struct change *) extern void setup_output (char const *, char const *, bool); extern void translate_range (struct file_data const *, lin, lin, long int *, long int *); + +enum color_context +{ + HEADER_CONTEXT, + ADD_CONTEXT, + DELETE_CONTEXT, + RESET_CONTEXT, + LINE_NUMBER_CONTEXT, +}; + +extern void set_color_context (enum color_context color_context); diff --git a/src/normal.c b/src/normal.c index 721fd1a..e78e8ba 100644 --- a/src/normal.c +++ b/src/normal.c @@ -49,21 +49,43 @@ print_normal_hunk (struct change *hunk) begin_output (); /* Print out the line number header for this hunk */ + set_color_context (LINE_NUMBER_CONTEXT); print_number_range (',', &files[0], first0, last0); fputc (change_letter[changes], outfile); print_number_range (',', &files[1], first1, last1); + set_color_context (RESET_CONTEXT); fputc ('\n', outfile); /* Print the lines that the first file has. */ if (changes & OLD) - for (i = first0; i <= last0; i++) - print_1_line ("<", &files[0].linbuf[i]); + { + if (first0 <= last0) + set_color_context (DELETE_CONTEXT); + for (i = first0; i <= last0; i++) + { + print_1_line_nl ("<", &files[0].linbuf[i], true); + if (i == last0) + set_color_context (RESET_CONTEXT); + if (files[0].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } + } if (changes == CHANGED) fputs ("---\n", outfile); /* Print the lines that the second file has. */ if (changes & NEW) - for (i = first1; i <= last1; i++) - print_1_line (">", &files[1].linbuf[i]); + { + if (first1 <= last1) + set_color_context (ADD_CONTEXT); + for (i = first1; i <= last1; i++) + { + print_1_line_nl (">", &files[1].linbuf[i], true); + if (i == last1) + set_color_context (RESET_CONTEXT); + if (files[1].linbuf[i + 1][-1] == '\n') + putc ('\n', outfile); + } + } } diff --git a/src/side.c b/src/side.c index 155512c..a0213c4 100644 --- a/src/side.c +++ b/src/side.c @@ -206,6 +206,18 @@ print_1sdiff_line (char const *const *left, char sep, size_t c2o = sdiff_column2_offset; size_t col = 0; bool put_newline = false; + bool color_to_reset = false; + + if (sep == '<') + { + set_color_context (DELETE_CONTEXT); + color_to_reset = true; + } + else if (sep == '>') + { + set_color_context (ADD_CONTEXT); + color_to_reset = true; + } if (left) { @@ -233,6 +245,9 @@ print_1sdiff_line (char const *const *left, char sep, if (put_newline) putc ('\n', out); + + if (color_to_reset) + set_color_context (RESET_CONTEXT); } /* Print lines common to both files in side-by-side format. */ diff --git a/src/util.c b/src/util.c index 2d6d3fc..78b1a2d 100644 --- a/src/util.c +++ b/src/util.c @@ -24,6 +24,22 @@ #include #include #include "xvasprintf.h" +#include + +/* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is + present. */ +#ifndef SA_NOCLDSTOP +# define SA_NOCLDSTOP 0 +# define sigprocmask(How, Set, Oset) /* empty */ +# define sigset_t int +# if ! HAVE_SIGINTERRUPT +# define siginterrupt(sig, flag) /* empty */ +# endif +#endif + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif char const pr_program[] = PR_PROGRAM; @@ -143,6 +159,174 @@ print_message_queue (void) } } +/* The set of signals that are caught. */ + +static sigset_t caught_signals; + +/* If nonzero, the value of the pending fatal signal. */ + +static sig_atomic_t volatile interrupt_signal; + +/* A count of the number of pending stop signals that have been received. */ + +static sig_atomic_t volatile stop_signal_count; + +/* An ordinary signal was received; arrange for the program to exit. */ + +static void +sighandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, SIG_IGN); + if (! interrupt_signal) + interrupt_signal = sig; +} + +/* A SIGTSTP was received; arrange for the program to suspend itself. */ + +static void +stophandler (int sig) +{ + if (! SA_NOCLDSTOP) + signal (sig, stophandler); + if (! interrupt_signal) + stop_signal_count++; +} +/* Process any pending signals. If signals are caught, this function + should be called periodically. Ideally there should never be an + unbounded amount of time when signals are not being processed. + Signal handling can restore the default colors, so callers must + immediately change colors after invoking this function. */ + +static void +process_signals (void) +{ + while (interrupt_signal || stop_signal_count) + { + int sig; + int stops; + sigset_t oldset; + + set_color_context (RESET_CONTEXT); + fflush (stdout); + + sigprocmask (SIG_BLOCK, &caught_signals, &oldset); + + /* Reload interrupt_signal and stop_signal_count, in case a new + signal was handled before sigprocmask took effect. */ + sig = interrupt_signal; + stops = stop_signal_count; + + /* SIGTSTP is special, since the application can receive that signal + more than once. In this case, don't set the signal handler to the + default. Instead, just raise the uncatchable SIGSTOP. */ + if (stops) + { + stop_signal_count = stops - 1; + sig = SIGSTOP; + } + else + signal (sig, SIG_DFL); + + /* Exit or suspend the program. */ + raise (sig); + sigprocmask (SIG_SETMASK, &oldset, NULL); + + /* If execution reaches here, then the program has been + continued (after being suspended). */ + } +} + +static void +install_signal_handlers (void) +{ + /* The signals that are trapped, and the number of such signals. */ + static int const sig[] = + { + /* This one is handled specially. */ + SIGTSTP, + + /* The usual suspects. */ + SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, +#ifdef SIGPOLL + SIGPOLL, +#endif +#ifdef SIGPROF + SIGPROF, +#endif +#ifdef SIGVTALRM + SIGVTALRM, +#endif +#ifdef SIGXCPU + SIGXCPU, +#endif +#ifdef SIGXFSZ + SIGXFSZ, +#endif + }; + enum { nsigs = sizeof (sig) / sizeof *(sig) }; + +#if ! SA_NOCLDSTOP + bool caught_sig[nsigs]; +#endif + { + int j; +#if SA_NOCLDSTOP + struct sigaction act; + + sigemptyset (&caught_signals); + for (j = 0; j < nsigs; j++) + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; + + for (j = 0; j < nsigs; j++) + if (sigismember (&caught_signals, sig[j])) + { + act.sa_handler = sig[j] == SIGTSTP ? stophandler : sighandler; + sigaction (sig[j], &act, NULL); + } +#else + for (j = 0; j < nsigs; j++) + { + caught_sig[j] = (signal (sig[j], SIG_IGN) != SIG_IGN); + if (caught_sig[j]) + { + signal (sig[j], sig[j] == SIGTSTP ? stophandler : sighandler); + siginterrupt (sig[j], 0); + } + } +#endif + } +} + +static char const *current_name0; +static char const *current_name1; +static bool currently_recursive; +static bool colors_enabled; + +static void +check_color_output (bool is_pipe) +{ + bool output_is_tty; + + if (! outfile || colors_style == NEVER) + return; + + output_is_tty = !is_pipe && isatty (fileno (outfile)); + + colors_enabled = (colors_style == ALWAYS + || (colors_style == AUTO && output_is_tty)); + + if (output_is_tty) + install_signal_handlers (); +} + /* Call before outputting the results of comparing files NAME0 and NAME1 to set up OUTFILE, the stdio stream for the output to go to. @@ -150,10 +334,6 @@ print_message_queue (void) we fork off a 'pr' and make OUTFILE a pipe to it. 'pr' then outputs to our stdout. */ -static char const *current_name0; -static char const *current_name1; -static bool currently_recursive; - void setup_output (char const *name0, char const *name1, bool recursive) { @@ -313,6 +493,7 @@ begin_output (void) outfile = fdopen (pipes[1], "w"); if (!outfile) pfatal_with_name ("fdopen"); + check_color_output (true); } #else char *command = system_quote_argv (SCI_SYSTEM, (char **) argv); @@ -320,6 +501,7 @@ begin_output (void) outfile = popen (command, "w"); if (!outfile) pfatal_with_name (command); + check_color_output (true); free (command); #endif } @@ -330,6 +512,7 @@ begin_output (void) /* If -l was not specified, output the diff straight to 'stdout'. */ outfile = stdout; + check_color_output (false); /* If handling multiple files (because scanning a directory), print which files the following output is about. */ @@ -630,6 +813,18 @@ print_script (struct change *script, void print_1_line (char const *line_flag, char const *const *line) { + print_1_line_nl (line_flag, line, false); +} + +/* Print the text of a single line LINE, + flagging it with the characters in LINE_FLAG (which say whether + the line is inserted, deleted, changed, etc.). LINE_FLAG must not + end in a blank, unless it is a single blank. If SKIP_NL is set, then + the final '\n' is not printed. */ + +void +print_1_line_nl (char const *line_flag, char const *const *line, bool skip_nl) +{ char const *base = line[0], *limit = line[1]; /* Help the compiler. */ FILE *out = outfile; /* Help the compiler some more. */ char const *flag_format = 0; @@ -657,10 +852,13 @@ print_1_line (char const *line_flag, char const *const *line) fprintf (out, flag_format_1, line_flag_1); } - output_1_line (base, limit, flag_format, line_flag); + output_1_line (base, limit - (skip_nl && limit[-1] == '\n'), flag_format, line_flag); if ((!line_flag || line_flag[0]) && limit[-1] != '\n') - fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + { + set_color_context (RESET_CONTEXT); + fprintf (out, "\n\\ %s\n", _("No newline at end of file")); + } } /* Output a line from BASE up to LIMIT. @@ -672,8 +870,21 @@ void output_1_line (char const *base, char const *limit, char const *flag_format, char const *line_flag) { + const size_t MAX_CHUNK = 1024; if (!expand_tabs) - fwrite (base, sizeof (char), limit - base, outfile); + { + size_t left = limit - base; + while (left) + { + size_t to_write = MIN (left, MAX_CHUNK); + size_t written = fwrite (base, sizeof (char), to_write, outfile); + if (written < to_write) + return; + base += written; + left -= written; + process_signals (); + } + } else { register FILE *out = outfile; @@ -681,39 +892,85 @@ output_1_line (char const *base, char const *limit, char const *flag_format, register char const *t = base; register size_t column = 0; size_t tab_size = tabsize; + size_t counter_proc_signals = 0; while (t < limit) - switch ((c = *t++)) - { - case '\t': - { - size_t spaces = tab_size - column % tab_size; - column += spaces; - do - putc (' ', out); - while (--spaces); - } - break; + { + counter_proc_signals++; + if (counter_proc_signals == MAX_CHUNK) + { + process_signals (); + counter_proc_signals = 0; + } + + switch ((c = *t++)) + { + case '\t': + { + size_t spaces = tab_size - column % tab_size; + column += spaces; + do + putc (' ', out); + while (--spaces); + } + break; + + case '\r': + putc (c, out); + if (flag_format && t < limit && *t != '\n') + fprintf (out, flag_format, line_flag); + column = 0; + break; + + case '\b': + if (column == 0) + continue; + column--; + putc (c, out); + break; + + default: + column += isprint (c) != 0; + putc (c, out); + break; + } + } + } +} - case '\r': - putc (c, out); - if (flag_format && t < limit && *t != '\n') - fprintf (out, flag_format, line_flag); - column = 0; - break; - case '\b': - if (column == 0) - continue; - column--; - putc (c, out); - break; +void +set_color_context (enum color_context color_context) +{ + process_signals (); + if (colors_enabled) + { + switch (color_context) + { + case HEADER_CONTEXT: + fputs ("\x1B[1m", outfile); + break; - default: - column += isprint (c) != 0; - putc (c, out); - break; - } + case LINE_NUMBER_CONTEXT: + fputs ("\x1B[36m", outfile); + + break; + + case ADD_CONTEXT: + fputs ("\x1B[32m", outfile); + break; + + case DELETE_CONTEXT: + fputs ("\x1B[31m", outfile); + break; + + case RESET_CONTEXT: + fputs ("\x1b[0m", outfile); + break; + + default: + abort (); + } } } -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0002-diff-add-palette.patch >From 8ab5aeabc752dfc746ebd385d1ce569d96d051b5 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 19 Oct 2015 10:29:41 +0200 Subject: [PATCH 2/4] diff: add --palette * bootstrap (gnulib_modules): Add 'argmatch'. * doc/diffutils.texi: Add documentation for --palette * src/diff.h (set_color_palette): New prototype. * src/diff.c (set_color_palette): New function. (color_palette): New variable. * src/utils.c: Include "argmatch.h". (struct bin_str): New struct. (struct color_ext_type): New struct. (color_indicator): New array. (indicator_name): New array. (indicator_no): New enum. (parse_state): New enum. (put_indicator): New function. (get_funky_string): New function. Copied from coreutils ls. (parse_diff_color): New function. Copied from coreutils ls "parse_ls_color" function. (set_color_context): Use put_indicator instead of directly outputting the sequence. * po/POTFILES.in: Add 'lib/argmatch.c' --- bootstrap.conf | 1 + doc/diffutils.texi | 34 +++++ po/POTFILES.in | 1 + src/diff.c | 8 + src/diff.h | 1 + src/util.c | 424 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 462 insertions(+), 7 deletions(-) diff --git a/bootstrap.conf b/bootstrap.conf index 9b2de22..3ab2c8b 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -19,6 +19,7 @@ # gnulib modules used by this package. gnulib_modules=' announce-gen +argmatch binary-io c-stack config-h diff --git a/doc/diffutils.texi b/doc/diffutils.texi index b2c39da..4ec9a0b 100644 --- a/doc/diffutils.texi +++ b/doc/diffutils.texi @@ -3890,6 +3890,40 @@ if-then-else format. @xref{Line Formats}. @itemx --show-c-function Show which C function each change is in. @xref{C Function Headings}. +@item --palette=@var{palette} +Specify what color palette to use when colored output is enabled. It +defaults to @samp{rs=0:hd=1:ad=32:de=31:ln=36} for red deleted lines, +green added lines, cyan line numbers, bold header. + +Supported capabilities are as follows. + +@table @code +@item ad=32 +@vindex ad @r{capability} + +SGR substring for added lines. +The default is green foreground. + +@item de=31 +@vindex de @r{capability} + +SGR substring for deleted lines. +The default is red foreground. + +@item hd=1 +@vindex hd @r{capability} + +SGR substring for chunk header. +The default is bold foreground. + +@item ln=36 +@vindex ln @r{capability} + +SGR substring for line numbers. +The default is cyan foreground. +@end table + + @item -q @itemx --brief Report only whether the files differ, not the details of the diff --git a/po/POTFILES.in b/po/POTFILES.in index 74fb756..af39427 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -15,6 +15,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +lib/argmatch.c lib/c-stack.c lib/error.c lib/file-type.c diff --git a/src/diff.c b/src/diff.c index 536f545..46ac99d 100644 --- a/src/diff.c +++ b/src/diff.c @@ -140,6 +140,7 @@ enum CHANGED_GROUP_FORMAT_OPTION, COLOR_OPTION, + COLOR_PALETTE_OPTION, }; static char const group_format_option[][sizeof "--unchanged-group-format"] = @@ -196,6 +197,7 @@ static struct option const longopts[] = {"old-group-format", 1, 0, OLD_GROUP_FORMAT_OPTION}, {"old-line-format", 1, 0, OLD_LINE_FORMAT_OPTION}, {"paginate", 0, 0, 'l'}, + {"palette", 1, 0, COLOR_PALETTE_OPTION}, {"rcs", 0, 0, 'n'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, @@ -635,6 +637,10 @@ main (int argc, char **argv) specify_colors_style (optarg); break; + case COLOR_PALETTE_OPTION: + set_color_palette (optarg); + break; + default: try_help (NULL, NULL); } @@ -950,6 +956,8 @@ static char const * const option_help_msgid[] = { N_(" --speed-large-files assume large files and many scattered small changes"), N_(" --color[=WHEN] colorize the output; WHEN can be 'never', 'always',"), N_(" or 'auto' (the default)"), + N_(" --palette=PALETTE specify the colors to use when --color is active"), + N_(" PALETTE is a colon-separated list terminfo capabilities"), "", N_(" --help display this help and exit"), N_("-v, --version output version information and exit"), diff --git a/src/diff.h b/src/diff.h index 7bf7344..6f1bb34 100644 --- a/src/diff.h +++ b/src/diff.h @@ -418,3 +418,4 @@ enum color_context }; extern void set_color_context (enum color_context color_context); +extern void set_color_palette (char const *palette); diff --git a/src/util.c b/src/util.c index 78b1a2d..1fa61fa 100644 --- a/src/util.c +++ b/src/util.c @@ -19,6 +19,7 @@ along with this program. If not, see . */ #include "diff.h" +#include "argmatch.h" #include #include #include @@ -310,6 +311,397 @@ static char const *current_name1; static bool currently_recursive; static bool colors_enabled; +static struct color_ext_type *color_ext_list = NULL; + +struct bin_str + { + size_t len; /* Number of bytes */ + const char *string; /* Pointer to the same */ + }; + +struct color_ext_type + { + struct bin_str ext; /* The extension we're looking for */ + struct bin_str seq; /* The sequence to output when we do */ + struct color_ext_type *next; /* Next in list */ + }; + +/* Parse a string as part of the --palette argument; this may involve + decoding all kinds of escape characters. If equals_end is set an + unescaped equal sign ends the string, otherwise only a : or \0 + does. Set *OUTPUT_COUNT to the number of bytes output. Return + true if successful. + + The resulting string is *not* null-terminated, but may contain + embedded nulls. + + Note that both dest and src are char **; on return they point to + the first free byte after the array and the character that ended + the input string, respectively. */ + +static bool +get_funky_string (char **dest, const char **src, bool equals_end, + size_t *output_count) +{ + char num; /* For numerical codes */ + size_t count; /* Something to count with */ + enum { + ST_GND, ST_BACKSLASH, ST_OCTAL, ST_HEX, ST_CARET, ST_END, ST_ERROR + } state; + const char *p; + char *q; + + p = *src; /* We don't want to double-indirect */ + q = *dest; /* the whole darn time. */ + + count = 0; /* No characters counted in yet. */ + num = 0; + + state = ST_GND; /* Start in ground state. */ + while (state < ST_END) + { + switch (state) + { + case ST_GND: /* Ground state (no escapes) */ + switch (*p) + { + case ':': + case '\0': + state = ST_END; /* End of string */ + break; + case '\\': + state = ST_BACKSLASH; /* Backslash scape sequence */ + ++p; + break; + case '^': + state = ST_CARET; /* Caret escape */ + ++p; + break; + case '=': + if (equals_end) + { + state = ST_END; /* End */ + break; + } + /* else fall through */ + default: + *(q++) = *(p++); + ++count; + break; + } + break; + + case ST_BACKSLASH: /* Backslash escaped character */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + state = ST_OCTAL; /* Octal sequence */ + num = *p - '0'; + break; + case 'x': + case 'X': + state = ST_HEX; /* Hex sequence */ + num = 0; + break; + case 'a': /* Bell */ + num = '\a'; + break; + case 'b': /* Backspace */ + num = '\b'; + break; + case 'e': /* Escape */ + num = 27; + break; + case 'f': /* Form feed */ + num = '\f'; + break; + case 'n': /* Newline */ + num = '\n'; + break; + case 'r': /* Carriage return */ + num = '\r'; + break; + case 't': /* Tab */ + num = '\t'; + break; + case 'v': /* Vtab */ + num = '\v'; + break; + case '?': /* Delete */ + num = 127; + break; + case '_': /* Space */ + num = ' '; + break; + case '\0': /* End of string */ + state = ST_ERROR; /* Error! */ + break; + default: /* Escaped character like \ ^ : = */ + num = *p; + break; + } + if (state == ST_BACKSLASH) + { + *(q++) = num; + ++count; + state = ST_GND; + } + ++p; + break; + + case ST_OCTAL: /* Octal sequence */ + if (*p < '0' || *p > '7') + { + *(q++) = num; + ++count; + state = ST_GND; + } + else + num = (num << 3) + (*(p++) - '0'); + break; + + case ST_HEX: /* Hex sequence */ + switch (*p) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + num = (num << 4) + (*(p++) - '0'); + break; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + num = (num << 4) + (*(p++) - 'a') + 10; + break; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + num = (num << 4) + (*(p++) - 'A') + 10; + break; + default: + *(q++) = num; + ++count; + state = ST_GND; + break; + } + break; + + case ST_CARET: /* Caret escape */ + state = ST_GND; /* Should be the next state... */ + if (*p >= '@' && *p <= '~') + { + *(q++) = *(p++) & 037; + ++count; + } + else if (*p == '?') + { + *(q++) = 127; + ++count; + } + else + state = ST_ERROR; + break; + + default: + abort (); + } + } + + *dest = q; + *src = p; + *output_count = count; + + return state != ST_ERROR; +} + +enum parse_state + { + PS_START = 1, + PS_2, + PS_3, + PS_4, + PS_DONE, + PS_FAIL + }; + +#define LEN_STR_PAIR(s) sizeof (s) - 1, s + +static struct bin_str color_indicator[] = + { + { LEN_STR_PAIR ("\033[") }, /* lc: Left of color sequence */ + { LEN_STR_PAIR ("m") }, /* rc: Right of color sequence */ + { 0, NULL }, /* ec: End color (replaces lc+rs+rc) */ + { LEN_STR_PAIR ("0") }, /* rs: Reset to ordinary colors */ + { LEN_STR_PAIR ("1") }, /* hd: Header */ + { LEN_STR_PAIR ("32") }, /* ad: Add line */ + { LEN_STR_PAIR ("31") }, /* de: Delete line */ + { LEN_STR_PAIR ("36") }, /* ln: Line number */ + }; + +static const char *const indicator_name[] = + { + "lc", "rc", "ec", "rs", "hd", "ad", "de", "ln", NULL + }; +ARGMATCH_VERIFY (indicator_name, color_indicator); + +static char const *color_palette; + +void +set_color_palette (char const *palette) +{ + color_palette = palette; +} + +static void +parse_diff_color (void) +{ + char *color_buf; + const char *p; /* Pointer to character being parsed */ + char *buf; /* color_buf buffer pointer */ + int ind_no; /* Indicator number */ + char label[3]; /* Indicator label */ + struct color_ext_type *ext; /* Extension we are working on */ + + if ((p = color_palette) == NULL || *p == '\0') + return; + + ext = NULL; + strcpy (label, "??"); + + /* This is an overly conservative estimate, but any possible + --palette string will *not* generate a color_buf longer than + itself, so it is a safe way of allocating a buffer in + advance. */ + buf = color_buf = xstrdup (p); + + enum parse_state state = PS_START; + while (true) + { + switch (state) + { + case PS_START: /* First label character */ + switch (*p) + { + case ':': + ++p; + break; + + case '*': + /* Allocate new extension block and add to head of + linked list (this way a later definition will + override an earlier one, which can be useful for + having terminal-specific defs override global). */ + + ext = xmalloc (sizeof *ext); + ext->next = color_ext_list; + color_ext_list = ext; + + ++p; + ext->ext.string = buf; + + state = (get_funky_string (&buf, &p, true, &ext->ext.len) + ? PS_4 : PS_FAIL); + break; + + case '\0': + state = PS_DONE; /* Done! */ + goto done; + + default: /* Assume it is file type label */ + label[0] = *(p++); + state = PS_2; + break; + } + break; + + case PS_2: /* Second label character */ + if (*p) + { + label[1] = *(p++); + state = PS_3; + } + else + state = PS_FAIL; /* Error */ + break; + + case PS_3: /* Equal sign after indicator label */ + state = PS_FAIL; /* Assume failure... */ + if (*(p++) == '=')/* It *should* be... */ + { + for (ind_no = 0; indicator_name[ind_no] != NULL; ++ind_no) + { + if (STREQ (label, indicator_name[ind_no])) + { + color_indicator[ind_no].string = buf; + state = (get_funky_string (&buf, &p, false, + &color_indicator[ind_no].len) + ? PS_START : PS_FAIL); + break; + } + } + if (state == PS_FAIL) + error (0, 0, _("unrecognized prefix: %s"), label); + } + break; + + case PS_4: /* Equal sign after *.ext */ + if (*(p++) == '=') + { + ext->seq.string = buf; + state = (get_funky_string (&buf, &p, false, &ext->seq.len) + ? PS_START : PS_FAIL); + } + else + state = PS_FAIL; + break; + + case PS_FAIL: + goto done; + + default: + abort (); + } + } + done: + + if (state == PS_FAIL) + { + struct color_ext_type *e; + struct color_ext_type *e2; + + error (0, 0, + _("unparsable value for --palette")); + free (color_buf); + for (e = color_ext_list; e != NULL; /* empty */) + { + e2 = e; + e = e->next; + free (e2); + } + colors_enabled = false; + } +} + static void check_color_output (bool is_pipe) { @@ -323,6 +715,9 @@ check_color_output (bool is_pipe) colors_enabled = (colors_style == ALWAYS || (colors_style == AUTO && output_is_tty)); + if (colors_enabled) + parse_diff_color (); + if (output_is_tty) install_signal_handlers (); } @@ -938,42 +1333,57 @@ output_1_line (char const *base, char const *limit, char const *flag_format, } } +enum indicator_no + { + C_LEFT, C_RIGHT, C_END, C_RESET, C_HEADER, C_ADD, C_DELETE, C_LINE + }; + +static void +put_indicator (const struct bin_str *ind) +{ + fwrite (ind->string, ind->len, 1, outfile); +} + +static enum color_context last_context = RESET_CONTEXT; void set_color_context (enum color_context color_context) { process_signals (); - if (colors_enabled) + if (colors_enabled && last_context != color_context) { + put_indicator (&color_indicator[C_LEFT]); switch (color_context) { case HEADER_CONTEXT: - fputs ("\x1B[1m", outfile); + put_indicator (&color_indicator[C_HEADER]); break; case LINE_NUMBER_CONTEXT: - fputs ("\x1B[36m", outfile); - + put_indicator (&color_indicator[C_LINE]); break; case ADD_CONTEXT: - fputs ("\x1B[32m", outfile); + put_indicator (&color_indicator[C_ADD]); break; case DELETE_CONTEXT: - fputs ("\x1B[31m", outfile); + put_indicator (&color_indicator[C_DELETE]); break; case RESET_CONTEXT: - fputs ("\x1b[0m", outfile); + put_indicator (&color_indicator[C_RESET]); break; default: abort (); } + put_indicator (&color_indicator[C_RIGHT]); + last_context = color_context; } } + char const change_letter[] = { 0, 'd', 'a', 'c' }; /* Translate an internal line number (an index into diff's table of lines) -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0003-doc-mention-color-and-palette-in-NEWS.patch >From 773498ed3956af73ae3caff69c62f3b84a632cca Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:03:32 +0000 Subject: [PATCH 3/4] doc: mention --color and --palette in NEWS --- NEWS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS b/NEWS index 7cdfedd..088f13b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU diffutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + diff accepts two new options --color and --palette to generate + and configure colored output. --color takes an optional argument + specifying when to colorize a line: --color=always, --color=auto, + --color=never. --palette is used to configure which colors are used. + ** Bug fixes When binary files differ, diff now exits with status 1 as POSIX requires. -- 2.5.0 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0004-tests-Add-tests-for-color-and-palette.patch >From 4a69b46c3d71dd7299cf5d3b1dde3ce6902d3afe Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Mon, 2 Nov 2015 19:05:10 +0000 Subject: [PATCH 4/4] tests: Add tests for --color and --palette * tests/colors: New file. * tests/Makefile.am (TESTS): Add colors. --- tests/Makefile.am | 3 +- tests/colors | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100755 tests/colors diff --git a/tests/Makefile.am b/tests/Makefile.am index 438fbdf..805ccc2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,8 @@ TESTS = \ no-newline-at-eof \ stdin \ strcoll-0-names \ - filename-quoting + filename-quoting \ + colors EXTRA_DIST = \ $(TESTS) init.sh t-local.sh diff --git a/tests/colors b/tests/colors new file mode 100755 index 0000000..facfd8d --- /dev/null +++ b/tests/colors @@ -0,0 +1,119 @@ +#!/bin/sh + +. "${srcdir=.}/init.sh"; path_prepend_ ../src + +TZ=UTC0 +export TZ + +fail=0 + +echo a > a +echo b > b + +epoch='1970-01-01 00:00:00' +touch --date="$epoch" a b + +gen_exp_u() +{ + local tab=$(printf '\t') + local epoch_plus="$epoch.000000000 +0000" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd--- a$tab$epoch_plus ++++ b$tab$epoch_plus +$rs${ln}@@ -1 +1 @@$rs +$de-a$rs +$ad+b$rs +" +} + +gen_exp_c() +{ + local tab=$(printf '\t') + local epoch_posix_1003_1_2001="Thu Jan 1 00:00:00 1970" + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"$hd*** a$tab$epoch_posix_1003_1_2001 +--- b$tab$epoch_posix_1003_1_2001 +$rs*************** +$ln*** 1 ****$rs +$de! a$rs +$ln--- 1 ----$rs +$ad! b$rs +" +} + +gen_exp_default() +{ + printf '%s' \ +"1c1 +< a +--- +> b +" +} + +gen_exp_default_colors() +{ + local rs=$(printf "\e[${rs}m") + local hd=$(printf "\e[${hd}m") + local ad=$(printf "\e[${ad}m") + local de=$(printf "\e[${de}m") + local ln=$(printf "\e[${ln}m") + printf '%s' \ +"${ln}1c1$rs +$de< a$rs +--- +$ad> b$rs +" +} + +# Compare with some known outputs + +rs=0 hd=1 ad=32 de=31 ln=36 + +diff --color=auto a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff --color=never a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff a b > out +test $? = 1 || fail=1 +gen_exp_default > exp || framework_failure_ +compare exp out || fail=1 + +diff --color=always a b > out +test $? = 1 || fail=1 +gen_exp_default_colors > exp || framework_failure_ +compare exp out || fail=1 + +diff -u --color=always a b > out +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp out || fail=1 + +diff -c --color=always a b > out +test $? = 1 || fail=1 +gen_exp_c > exp || framework_failure_ +compare exp out || fail=1 + +rs=0 hd=33 ad=34 de=35 ln=36 +diff -u --color=always --palette="rs=0:hd=33:ad=34:de=35:ln=36" a b > out +test $? = 1 || fail=1 +gen_exp_u > exp || framework_failure_ +compare exp out || fail=1 + +Exit $fail -- 2.5.0 --=-=-=-- From unknown Mon Aug 18 09:00:54 2025 X-Loop: help-debbugs@gnu.org Subject: bug#20062: [bug-diffutils] bug#20062: [PATCH] diff: add support for --color Resent-From: Jim Meyering Original-Sender: "Debbugs-submit" Resent-CC: bug-diffutils@gnu.org Resent-Date: Sun, 29 Nov 2015 16:42:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 20062 X-GNU-PR-Package: diffutils X-GNU-PR-Keywords: patch To: Giuseppe Scrivano Cc: Eric Blake , 20062@debbugs.gnu.org Received: via spool by 20062-submit@debbugs.gnu.org id=B20062.144881526230738 (code B ref 20062); Sun, 29 Nov 2015 16:42:02 +0000 Received: (at 20062) by debbugs.gnu.org; 29 Nov 2015 16:41:02 +0000 Received: from localhost ([127.0.0.1]:59623 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a3524-0007zW-Rh for submit@debbugs.gnu.org; Sun, 29 Nov 2015 11:41:01 -0500 Received: from mail-vk0-f46.google.com ([209.85.213.46]:34196) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a351k-0007z6-Ee for 20062@debbugs.gnu.org; Sun, 29 Nov 2015 11:40:59 -0500 Received: by vkbs1 with SMTP id s1so89961998vkb.1 for <20062@debbugs.gnu.org>; Sun, 29 Nov 2015 08:40:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=j0F8sxs5jMqWaDaZDr+zQZMNmB+RHlj05+kwErRZS9M=; b=yd9OrNMnTqQ0MgMq93+ZDRzS0BF6JM3KEugVwEt3zmo4yaalZOmCMD+W1XfudjJ27Y DlXjfpnX87Gce9uIam4wBGvErvNi5qISoLEbnjivL5CIbJOmOgf9bfW5pv23c5pLatNs vPx54O+22RuUyDcE1yCl4+FYrA2Ugvvx9HPBiLaiEe+qBbjyF/JoJbEQIG4+mGnkLDqz Vr+c9e9s6u7jX+/B6HosOVUG31fiivf2bCxsqMQb/a9hNLOLKjQCc7GHm1qLsCQggekU 2hT0vV/8KK0FQW2WxNUfeXkBy3TJWtaCx+T5I6A5RUqXcAfu2OWJAEJ+CG2v620n7BKl QiWw== X-Received: by 10.31.152.78 with SMTP id a75mr50618485vke.55.1448815239893; Sun, 29 Nov 2015 08:40:39 -0800 (PST) MIME-Version: 1.0 Received: by 10.31.84.198 with HTTP; Sun, 29 Nov 2015 08:40:20 -0800 (PST) In-Reply-To: <871tb85380.fsf@foo.bar.baz> References: <1425851791-29188-1-git-send-email-gscrivan@redhat.com> <87bnd7n9wn.fsf@foo.bar.baz> <55F44A2E.2050506@cs.ucla.edu> <8737y5h281.fsf@foo.bar.baz> <87oag1aj61.fsf@foo.bar.baz> <87wpuh1pcl.fsf@foo.bar.baz> <87bnbcrz2k.fsf@foo.bar.baz> <5637BAAC.8020301@redhat.com> <87fv0nko86.fsf@foo.bar.baz> <5638EE6E.3050901@redhat.com> <87twol1nqw.fsf@foo.bar.baz> <87a8pz4haz.fsf@foo.bar.baz> <87610l509v.fsf@foo.bar.baz> <871tb85380.fsf@foo.bar.baz> From: Jim Meyering Date: Sun, 29 Nov 2015 08:40:20 -0800 X-Google-Sender-Auth: mPfITxsoAOAPFXFMAXFNdfj7WMo Message-ID: Content-Type: text/plain; charset=UTF-8 X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On Sun, Nov 29, 2015 at 5:45 AM, Giuseppe Scrivano wrote: > Jim Meyering writes: > >> On Sat, Nov 28, 2015 at 12:36 PM, Giuseppe Scrivano wrote: >> .... >>> As it is hopefully getting closer to be accepted, I am attaching the >>> full series with the amended changes. I've verified that each patch >>> passes "make check" and "make syntax-check". >> >> Thanks, I see no problem. >> I can push as-is, but wondered if you wanted to merge >> your 0005 patch into the others? Probably not worth the work. >> Either way is fine. > > it was not much work as there were no conflicts to solve, so I splitted > 0005 into 0001 and 0004. I verified again that each step passes all the > tests. Good! Worthwhile after all. Thank you. I have just pushed those commits. From debbugs-submit-bounces@debbugs.gnu.org Fri May 05 01:47:23 2017 Received: (at control) by debbugs.gnu.org; 5 May 2017 05:47:23 +0000 Received: from localhost ([127.0.0.1]:55178 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d6W5L-0001M5-8e for submit@debbugs.gnu.org; Fri, 05 May 2017 01:47:23 -0400 Received: from mail-ua0-f174.google.com ([209.85.217.174]:35326) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1d6W5K-0001Hc-7d for control@debbugs.gnu.org; Fri, 05 May 2017 01:47:22 -0400 Received: by mail-ua0-f174.google.com with SMTP id e55so22670120uaa.2 for ; Thu, 04 May 2017 22:47:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:sender:from:date:message-id:subject:to; bh=IDmO77xVJTNQUpjx8FJaF4IrmYHRSJzGAU9AwmR6oEw=; b=dAUiUX/uJBSpCKm/MnD+ZSAlBGEvRoK+LBm6rHAP51lI30ClnYvcGn7jspZSdj4Mun ALpLUy3qS/xkuFJfiEDgGDFmvEjDE3ofX7ZpvWtujkmuzgrO/ckoHbIPUYRqnchOklA6 PuPjxoteZ37GFOdqK09Y66ENVyHcBVZst8pjWKQwnC7DwxvHkut6wPhITfK9i+axL4uj uUzblXCTWSaY6bNhdKxO67LRUIIFOUZAnOg1C/8/1v/eHIv/agzbz7UmhMl1rA0W0beG 2TeHk+gU+Cdte1FI9JVzRZn9fSw+e452Mb90NvwPIms+mhZRPwUsGIW4Vc49RVo1ptNG X2QQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:sender:from:date:message-id:subject :to; bh=IDmO77xVJTNQUpjx8FJaF4IrmYHRSJzGAU9AwmR6oEw=; b=qmui6iMQvo/t781BatUHZhYjssMV6N/uC6ONZg73R3nvhBzmezD+TdF0+BA0l9FsnO 4ri8nNWyxJp06YhM92O98Men+OtVYniQDOTu9uyK9HqQZZ69ZNr9hFeoUkbQLx+4kaMR 9GxiiD4D/lZG37flbAUmVfAHGn5rO8TwpTErX9OgwODf3LLemvh/mLhQ0zCHFI57QVrc Brq35Qqp4B1JHeJBQ3rf6upWrspGncHIGy7xVIJmX/+cx5EnMMGioC06SNWFmE52tdSW uCUdpHGx3x1lICz3bKJ8UVLvnaMsmFDTkftMDm0G37FKXW0KE1okBwn1Ak5FXQnvs7ZE lubQ== X-Gm-Message-State: AODbwcDPrbvVeHo1zVcqinSBy5kfoclYn8IHkLKJBVou2NNX0Ru7RCsg cFL9uhh9MlEtHq5Pi2+s7XBuWtu4XH5R X-Received: by 10.159.53.45 with SMTP id o42mr2774152uao.113.1493963236119; Thu, 04 May 2017 22:47:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.176.86.86 with HTTP; Thu, 4 May 2017 22:46:55 -0700 (PDT) From: Jim Meyering Date: Thu, 4 May 2017 22:46:55 -0700 X-Google-Sender-Auth: 0ZQKbPVFwNTMRKHERyRtOnfxDxY Message-ID: Subject: close long-completed issue: [was Re: diff: add support for --color To: GNU bug tracker automated control server Content-Type: text/plain; charset=UTF-8 X-Spam-Score: 0.7 (/) X-Debbugs-Envelope-To: control X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.7 (/) close 20062