GNU less can display ANSI-colored text with the -R flag, but this
support has some limitations. One of them is that if an escape
sequence starts on one line and ends on a different line, only the
first line will be colored in less.
As a result, when diff creates colored output with multi-line deletes
or adds, less will only color the first line.
This change resets ANSI color to the default at the end of
each line and restarts it at the beginning of the next. It patches
normal and context mode. Side-by-side already worked in my testing.
* src/context.c (print_context_label, pr_context_hunk): As above.
(pr_unidiff_hunk, print_context_header): Likewise.
* src/normal.c (print_normal_hunk): Likewise.
* tests/colors: Adjust existing tests to accommodate this.
* NEWS (Improvements): Mention it.
Proposed in http://bugs.gnu.org/31105
Problem reported by Hongxu Chen (Bug#31935).
* src/io.c (prepare_text): Strip trailing CR before
doing the rest of the analysis.
* NEWS: Mention the fix.
Co-authored-by: Jim Meyering <jim@meyering.net>
* src/diff.c (usage): Assert that each line length is no longer than
the minimum required size of 4095. This lets newer gcc (currently
9.0.0 20181219) infer that it need not issue this warning:
diff.c:1012:19: error: '%.*s' directive output between 0 and 2147483647
bytes may exceed minimum required size of 4095
[-Werror=format-overflow=]
1012 | printf (" %.*s", msglen, msg);
This improves on yesterday's change, following up on a
remark by Jim Meyering (Bug#22816#21).
* doc/diffutils.texi (Invoking cmp, cmp Options): Follow POSIX more
closely in the documentation of the information appended to the EOF
diagnostic.
* src/cmp.c (cmp): Be more specific about the shorter file's length
and fix some off-by-1 issues in reporting line counts.
* tests/cmp: Adjust to match new behavior.
Don't assume internal details about stdio buffering.
* src/diff.c: To ease translating, fuse four description pieces
into two whole ones. Also reword and rewrap one of them to fit
within eighty characters.
* src/diff.c (main): Always define presume_output_tty.
Otherwise, it would be read uninitialized.
Introduced in v3.3-45-g17e2698
* NEWS (Bug fixes): Mention it.
* NEWS, doc/diffutils.texi (Overview): Document this.
* src/analyze.c (diff_2_files): Restore too_expensive heuristic,
but this time with a floor that is 16 times the old floor. This
should fix Bug#16848, by generating good-quality output for its
test case, while not introducing Bug#24715, by running nearly as
fast as diff-3.3 for that test case.
Use "die (N, ..." rather than "error (N, ..." whenever N is a nonzero
constant. That lets the compiler know that control never goes beyond
that point, and thus makes unnecessary the occasional following
"abort ();" or "break;" statement we have historically added to inform
static analysis tools of this aspect of "error" semantics.
* src/die.h: New file.
* src/Makefile.am (noinst_HEADERS): Add it.
* src/cmp.c: Use die in place of error whenever the first
argument is a nonzero constant. Also remove any immediately-
following call to abort, and include "die.h".
* src/diff.c: Likewise.
* src/diff3.c: Likewise.
* src/sdiff.c: Likewise.
* src/util.c: Likewise.
* src/util.c (get_funky_string): Adjust comment so that GCC 7's
-Wimplicit-fallthrough recognizes it.
* src/diff3.c (main): Cast boolean MERGE to "int" to avoid this:
diff3.c:341:25: error: '~' on a boolean expression \
[-Werror=bool-operation]
Problem reported by Peter Rosin (Bug#24311).
* src/system.h (printint, pI): New typedef and macro.
All uses of 'long int' and "%l" in printf format replaced by
'printint' and "%"pI respectively.
* src/ifdef.c (do_printf_spec): Don't assume pI is length 1.
Commit v3.3-42-g3b74a90, "FIXME: src/diff3: plug a leak" added an
invalid use of free, leading to use-after-free in nearly any invocation
of diff3. Revert that commit.
* NEWS (Bug fixes): Mention it.
* tests/diff3: New file, to add minimal test coverage.
* tests/Makefile.am (TESTS): Add it.
Reported by Bastian Beischer in http://bugs.gnu.org/24210
* src/diff.c (main): With --color or --color=auto, when TERM is
"dumb", disable colorization. Suggested by Daniel Colascione.
* NEWS (Bug fixes): Mention it.
* tests/colors: Add a test that would fail without this change,
yet passes with it.
* src/diff.h (presume_output_tty): New extern variable.
* src/diff.c (PRESUME_OUTPUT_TTY_OPTION): New enum.
(group_format_option): Add '-presume-output-tty'.
(main): Handle PRESUME_OUTPUT_TTY_OPTION.
* src/util.c: New variable `presume_output_tty'.
(check_color_output): Handle presume_output_tty.
(set_color_context): Call process_signals only when color_context is
not RESET_CONTEXT.
* tests/colors: Check that diff doesn't crash when interrupted
in the middle of a color sequence.
Reported by Gisle Vanem in http://debbugs.gnu.org/22067
Normally, it is safe to assume two regular files are different when
their st_size values are different. However, that assumption may
be invalid if either value is zero, as happens with files on Linux
/proc and /sys file systems. Since skipping this optimization will
usually cost very little (one read syscall, to read zero bytes),
it is fine to accommodate those unusual files.
* src/analyze.c (diff_2_files): Do not assume regular files differ
just because their st_size values differ when one or more is 0.
* src/diff.c (compare_files): Likewise.
* tests/brief-vs-proc-stat-zero: New test.
* tests/Makefile.am: Add it.
* NEWS (Bug fixes): Describe it.
Reported by Stephan Müller in http://debbugs.gnu.org/21942
* 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'
* 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.
This fixes the problem that 'diff - file' and 'cat file | diff - file'
fail due to a seek failure with a message 'diff.exe: -: Invalid seek',
because seek does not work on stdin and a pipe on OS/2 kLIBC.
* src/io.c (sip): Set skip_test to true if seek is not possible on
OS/2 kLIBC.
Reported by Tobias Stoeckmann in: http://bugs.gnu.org/18857
* src/diff.c (main): Don't overflow if INTMAX_MAX / 2 < tabsize.
* tests/bignum: New file, to test for this bug.
* tests/Makefile.am (TESTS): Add it.
Reported by Navin Kabra via Eric Blake in:
http://bugs.gnu.org/18402
* src/util.c (analyze_hunk): Don't mishandle incomplete
lines at end of file.
* tests/no-newline-at-eof: Test for the bug.
* src/io.c (find_identical_ends): Fix performance bug:
the test for when the prefix was needed messed up by
the 2002-02-28 integer-overflow fixes, causing performance to be
worse than it needed to be.
Problem reported by Vincent Lefevre in <http://bugs.gnu.org/16864>.
* src/context.c (find_hunk): Threshold is CONTEXT only if
the second change is ignorable.
* tests/ignore-matching-lines: New test.
* tests/Makefile.am (TESTS): Add it.
Problem reported by Vincent Lefevre in <http://bugs.gnu.org/16848>.
The simplest solution is to remove the TOO_EXPENSIVE heuristic
that I added to GNU diff in 1993. Although appropriate for
circa-1993 hardware, these days the heuristic seems to be more
trouble than it's worth.
* NEWS: Document this.
* doc/diffutils.texi (Overview): Modernize citations.
Remove mention of TOO_EXPENSIVE heuristic.
* src/analyze.c (diff_2_files): Adjust to TOO_EXPENSIVE-related
API changes in gnulib's diffseq module.
Problem reported by Vincent Lefevre in <http://bugs.gnu.org/16608>.
* NEWS:
* doc/diffutils.texi (Binary, Invoking diff): Document this.
* src/analyze.c (briefly_report): Return void, not int.
All uses changed. Do not futz with exit status. Simplify.
* tests/binary: Adjust to match new behavior.
On my platform (AMD Phenom II X4 910e, Fedora 17 x86-64), this sped up
'cmp -n 8GiB /dev/full /dev/zero' by a factor of 3.8, and
'cmp -sn 8GiB /dev/full /dev/zero' by a factor of 1.8.
* bootstrap.conf (gnulib_modules): Add rawmemchr.
* src/cmp.c (cmp): Optimize the common case where buffers are the same,
by using count_newlines rather than block_compare_and_count.
(block_compare_and_count): Remove.
(count_newlines): New function.
* src/cmp.c (count_newlines):
* src/io.c (prepare_text):
* src/sdiff.c (lf_copy, lf_skip, lf_snarf):
Use rawmemchr instead of memchr, for speed.
Problem reported by Errembault Philippe in:
http://lists.gnu.org/archive/html/bug-diffutils/2013-03/msg00012.html
* NEWS: Document this.
* src/dir.c (compare_names): Fall back on file_name_cmp if
compare_collated returns 0, unless ignoring file name case.
(diff_dirs): Don't bother with the O(N**2) stuff unless ignoring
file name case.
* tests/Makefile.am (TESTS): Add strcoll-0-names.
* tests/strcoll-0-names: New file.
* src/dir.c (compare_collated): New function.
(compare_names): Use it.
(compare_names_for_qsort): Use it. This is a bit more efficient
as it can avoid a double invocation of file_name_cmp when
file_name_cmp returns zero.
* bootstrap.conf (gnulib_modules): Add gnulib's xvasprintf module.
* src/util.c: Include "xvasprintf.h".
(begin_output): Use xasprintf in place of xmalloc+sprintf.
* src/util.c (c_escape_char): New function.
(c_escape): New function.
(begin_output): Escape file names when needed.
* src/context.c (print_context_header): New names parameter.
(print_context_label): New name parameter.
* src/diff.h (print_context_header): Change prototype.
* tests/filename-quoting: New file.
* NEWS: Document this change.
* src/dir.c (find_dir_file_pathname): Use 'IF_LINT (volatile)' to
silence the gcc warning, rather than using 'volatile', as the
warning appears to be bogus.