diff(1): Implement -B/--ignore-blank-lines
As noted by cem in r338035, coccinelle invokes diff(1) with the -B flag. This was not previously implemented here, so one was forced to create a link for GNU diff to /usr/local/bin/diff Implement the -B flag and add some primitive tests for it. It is implemented in the same fashion that -I is implemented; each chunk's lines are scanned, and if a non-blank line is encountered then the chunk will be output. Otherwise, it's skipped. MFC after: 2 weeks
This commit is contained in:
parent
d17f8070a1
commit
e68edb8cf0
@ -5,7 +5,6 @@
|
|||||||
* make a libsdiff and use that directly to avoid duplicating the code
|
* make a libsdiff and use that directly to avoid duplicating the code
|
||||||
|
|
||||||
to be implemented:
|
to be implemented:
|
||||||
--ignore-blank-lines
|
|
||||||
--horizon-lines
|
--horizon-lines
|
||||||
--ignore-tab-expansion
|
--ignore-tab-expansion
|
||||||
--line-format
|
--line-format
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
.\" @(#)diff.1 8.1 (Berkeley) 6/30/93
|
.\" @(#)diff.1 8.1 (Berkeley) 6/30/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 20, 2017
|
.Dd August 18, 2018
|
||||||
.Dt DIFF 1
|
.Dt DIFF 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -38,7 +38,7 @@
|
|||||||
.Nd differential file and directory comparator
|
.Nd differential file and directory comparator
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm diff
|
.Nm diff
|
||||||
.Op Fl abdipTtw
|
.Op Fl aBbdipTtw
|
||||||
.Oo
|
.Oo
|
||||||
.Fl c | e | f |
|
.Fl c | e | f |
|
||||||
.Fl n | q | u
|
.Fl n | q | u
|
||||||
@ -67,7 +67,7 @@
|
|||||||
.Op Fl L Ar label | Fl -label Ar label
|
.Op Fl L Ar label | Fl -label Ar label
|
||||||
.Ar file1 file2
|
.Ar file1 file2
|
||||||
.Nm diff
|
.Nm diff
|
||||||
.Op Fl abdilpTtw
|
.Op Fl aBbdilpTtw
|
||||||
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
||||||
.Op Fl L Ar label | Fl -label Ar label
|
.Op Fl L Ar label | Fl -label Ar label
|
||||||
.Op Fl -brief
|
.Op Fl -brief
|
||||||
@ -93,7 +93,7 @@
|
|||||||
.Fl C Ar number | -context Ar number
|
.Fl C Ar number | -context Ar number
|
||||||
.Ar file1 file2
|
.Ar file1 file2
|
||||||
.Nm diff
|
.Nm diff
|
||||||
.Op Fl abdiltw
|
.Op Fl aBbdiltw
|
||||||
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
||||||
.Op Fl -brief
|
.Op Fl -brief
|
||||||
.Op Fl -changed-group-format Ar GFMT
|
.Op Fl -changed-group-format Ar GFMT
|
||||||
@ -118,7 +118,7 @@
|
|||||||
.Fl D Ar string | Fl -ifdef Ar string
|
.Fl D Ar string | Fl -ifdef Ar string
|
||||||
.Ar file1 file2
|
.Ar file1 file2
|
||||||
.Nm diff
|
.Nm diff
|
||||||
.Op Fl abdilpTtw
|
.Op Fl aBbdilpTtw
|
||||||
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern
|
||||||
.Op Fl L Ar label | Fl -label Ar label
|
.Op Fl L Ar label | Fl -label Ar label
|
||||||
.Op Fl -brief
|
.Op Fl -brief
|
||||||
@ -144,7 +144,7 @@
|
|||||||
.Fl U Ar number | Fl -unified Ar number
|
.Fl U Ar number | Fl -unified Ar number
|
||||||
.Ar file1 file2
|
.Ar file1 file2
|
||||||
.Nm diff
|
.Nm diff
|
||||||
.Op Fl abdilNPprsTtw
|
.Op Fl aBbdilNPprsTtw
|
||||||
.Oo
|
.Oo
|
||||||
.Fl c | e | f |
|
.Fl c | e | f |
|
||||||
.Fl n | q | u
|
.Fl n | q | u
|
||||||
@ -300,6 +300,8 @@ if files contain binary characters.
|
|||||||
Use of this option forces
|
Use of this option forces
|
||||||
.Nm
|
.Nm
|
||||||
to produce a diff.
|
to produce a diff.
|
||||||
|
.It Fl B Fl -ignore-blank-lines
|
||||||
|
Causes chunks that include only blank lines to be ignored.
|
||||||
.It Fl b
|
.It Fl b
|
||||||
Causes trailing blanks (spaces and tabs) to be ignored, and other
|
Causes trailing blanks (spaces and tabs) to be ignored, and other
|
||||||
strings of blanks to compare equal.
|
strings of blanks to compare equal.
|
||||||
|
@ -66,6 +66,7 @@ static struct option longopts[] = {
|
|||||||
{ "ed", no_argument, 0, 'e' },
|
{ "ed", no_argument, 0, 'e' },
|
||||||
{ "forward-ed", no_argument, 0, 'f' },
|
{ "forward-ed", no_argument, 0, 'f' },
|
||||||
{ "speed-large-files", no_argument, NULL, 'H' },
|
{ "speed-large-files", no_argument, NULL, 'H' },
|
||||||
|
{ "ignore-blank-lines", no_argument, 0, 'B' },
|
||||||
{ "ignore-matching-lines", required_argument, 0, 'I' },
|
{ "ignore-matching-lines", required_argument, 0, 'I' },
|
||||||
{ "ignore-case", no_argument, 0, 'i' },
|
{ "ignore-case", no_argument, 0, 'i' },
|
||||||
{ "paginate", no_argument, NULL, 'l' },
|
{ "paginate", no_argument, NULL, 'l' },
|
||||||
@ -164,6 +165,9 @@ main(int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
/* silently ignore for backwards compatibility */
|
/* silently ignore for backwards compatibility */
|
||||||
break;
|
break;
|
||||||
|
case 'B':
|
||||||
|
dflags |= D_SKIPBLANKLINES;
|
||||||
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
push_ignore_pats(optarg);
|
push_ignore_pats(optarg);
|
||||||
break;
|
break;
|
||||||
@ -447,18 +451,18 @@ void
|
|||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void)fprintf(stderr,
|
(void)fprintf(stderr,
|
||||||
"usage: diff [-abdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
|
"usage: diff [-aBbdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
|
||||||
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n"
|
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n"
|
||||||
" [-I pattern] [-L label] file1 file2\n"
|
" [-I pattern] [-L label] file1 file2\n"
|
||||||
" diff [-abdilpTtw] [-I pattern] [-L label] [--ignore-case]\n"
|
" diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n"
|
||||||
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n"
|
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n"
|
||||||
" -C number file1 file2\n"
|
" -C number file1 file2\n"
|
||||||
" diff [-abdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n"
|
" diff [-aBbdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n"
|
||||||
" [--normal] [--strip-trailing-cr] [--tabsize] -D string file1 file2\n"
|
" [--normal] [--strip-trailing-cr] [--tabsize] -D string file1 file2\n"
|
||||||
" diff [-abdilpTtw] [-I pattern] [-L label] [--ignore-case]\n"
|
" diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n"
|
||||||
" [--no-ignore-case] [--normal] [--tabsize] [--strip-trailing-cr]\n"
|
" [--no-ignore-case] [--normal] [--tabsize] [--strip-trailing-cr]\n"
|
||||||
" -U number file1 file2\n"
|
" -U number file1 file2\n"
|
||||||
" diff [-abdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
|
" diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n"
|
||||||
" [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n"
|
" [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n"
|
||||||
" [-S name] [-X file] [-x pattern] dir1 dir2\n");
|
" [-S name] [-X file] [-x pattern] dir1 dir2\n");
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#define D_EXPANDTABS 0x100 /* Expand tabs to spaces */
|
#define D_EXPANDTABS 0x100 /* Expand tabs to spaces */
|
||||||
#define D_IGNOREBLANKS 0x200 /* Ignore white space changes */
|
#define D_IGNOREBLANKS 0x200 /* Ignore white space changes */
|
||||||
#define D_STRIPCR 0x400 /* Strip trailing cr */
|
#define D_STRIPCR 0x400 /* Strip trailing cr */
|
||||||
|
#define D_SKIPBLANKLINES 0x800 /* Skip blank lines */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Status values for print_status() and diffreg() return values
|
* Status values for print_status() and diffreg() return values
|
||||||
|
@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -1000,6 +1001,31 @@ restart:
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (*pflags & D_SKIPBLANKLINES) {
|
||||||
|
char *line;
|
||||||
|
/*
|
||||||
|
* All lines in the change, insert, or delete must not be
|
||||||
|
* empty for the change to be ignored.
|
||||||
|
*/
|
||||||
|
if (a <= b) { /* Changes and deletes. */
|
||||||
|
for (i = a; i <= b; i++) {
|
||||||
|
line = preadline(fileno(f1),
|
||||||
|
ixold[i] - ixold[i - 1], ixold[i - 1]);
|
||||||
|
if (*line != '\0')
|
||||||
|
goto proceed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a > b || c <= d) { /* Changes and inserts. */
|
||||||
|
for (i = c; i <= d; i++) {
|
||||||
|
line = preadline(fileno(f2),
|
||||||
|
ixnew[i] - ixnew[i - 1], ixnew[i - 1]);
|
||||||
|
if (*line != '\0')
|
||||||
|
goto proceed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
proceed:
|
proceed:
|
||||||
if (*pflags & D_HEADER && diff_format != D_BRIEF) {
|
if (*pflags & D_HEADER && diff_format != D_BRIEF) {
|
||||||
diff_output("%s %s %s\n", diffargs, file1, file2);
|
diff_output("%s %s %s\n", diffargs, file1, file2);
|
||||||
|
2
usr.bin/diff/tests/Bflag_C.out
Normal file
2
usr.bin/diff/tests/Bflag_C.out
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1a2
|
||||||
|
>
|
2
usr.bin/diff/tests/Bflag_D.out
Normal file
2
usr.bin/diff/tests/Bflag_D.out
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
1a2
|
||||||
|
> C
|
4
usr.bin/diff/tests/Bflag_F.out
Normal file
4
usr.bin/diff/tests/Bflag_F.out
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
7c8
|
||||||
|
< G
|
||||||
|
---
|
||||||
|
> X
|
@ -5,6 +5,9 @@ PACKAGE= tests
|
|||||||
ATF_TESTS_SH= diff_test
|
ATF_TESTS_SH= diff_test
|
||||||
|
|
||||||
${PACKAGE}FILES+= \
|
${PACKAGE}FILES+= \
|
||||||
|
Bflag_C.out \
|
||||||
|
Bflag_D.out \
|
||||||
|
Bflag_F.out \
|
||||||
input1.in \
|
input1.in \
|
||||||
input2.in \
|
input2.in \
|
||||||
input_c1.in \
|
input_c1.in \
|
||||||
|
@ -9,6 +9,7 @@ atf_test_case group_format
|
|||||||
atf_test_case side_by_side
|
atf_test_case side_by_side
|
||||||
atf_test_case brief_format
|
atf_test_case brief_format
|
||||||
atf_test_case b230049
|
atf_test_case b230049
|
||||||
|
atf_test_case Bflag
|
||||||
|
|
||||||
simple_body()
|
simple_body()
|
||||||
{
|
{
|
||||||
@ -150,6 +151,21 @@ brief_format_body()
|
|||||||
diff -Nrq A D
|
diff -Nrq A D
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bflag_body()
|
||||||
|
{
|
||||||
|
atf_check -x 'printf "A\nB\n" > A'
|
||||||
|
atf_check -x 'printf "A\n\nB\n" > B'
|
||||||
|
atf_check -x 'printf "A\n \nB\n" > C'
|
||||||
|
atf_check -x 'printf "A\nC\nB\n" > D'
|
||||||
|
atf_check -x 'printf "A\nB\nC\nD\nE\nF\nG\nH" > E'
|
||||||
|
atf_check -x 'printf "A\n\nB\nC\nD\nE\nF\nX\nH" > F'
|
||||||
|
|
||||||
|
atf_check -s exit:0 -o inline:"" diff -B A B
|
||||||
|
atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_C.out" diff -B A C
|
||||||
|
atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_D.out" diff -B A D
|
||||||
|
atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_F.out" diff -B E F
|
||||||
|
}
|
||||||
|
|
||||||
atf_init_test_cases()
|
atf_init_test_cases()
|
||||||
{
|
{
|
||||||
atf_add_test_case simple
|
atf_add_test_case simple
|
||||||
@ -161,4 +177,5 @@ atf_init_test_cases()
|
|||||||
atf_add_test_case side_by_side
|
atf_add_test_case side_by_side
|
||||||
atf_add_test_case brief_format
|
atf_add_test_case brief_format
|
||||||
atf_add_test_case b230049
|
atf_add_test_case b230049
|
||||||
|
atf_add_test_case Bflag
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user