Date: Fri, 23 Mar 2018 21:06:06 +0000 (UTC) From: Ian Lepore <ian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r331465 - in stable/11/usr.bin: . diff diff/tests Message-ID: <201803232106.w2NL66nX042691@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ian Date: Fri Mar 23 21:06:06 2018 New Revision: 331465 URL: https://svnweb.freebsd.org/changeset/base/331465 Log: MFC r315051, r315101, r315103, r315107, r315180, r315197, r315293, r315319, r315590, r315649, r315726, r315743, r315746-r315747, r315779, r315985, r316002, r316639, r316959, r317187, r317194, r317205-r317207, r317381, r319489, r319847, r321076-r321079, r321227, r326822 Add the BSD-licensed diff from OpenBSD, which is optionally built and installed when WITHOUT_GNU_DIFF is set. r315051: Import diff from OpenBSD Some of the modifications from the previous summer of code has been integrated Modification for compatibility with GNU diff output has been added Main difference with OpenBSD: Implement multiple GNU diff options: * --ignore-file-name-case * --no-ignore-file-name-case * --normal * --tabsize * --strip-trailing-cr Make diff -p compatible with GNU diff Implement diff -l Make diff -r compatible with GNU diff Capsicumize diffing 2 regular files Add a simple test suite Approved by: AsiaBSDcon devsummit Obtained from: OpenBSD, GSoC Relnotes: yes r315101: Fix wrong date in diff(1) Reported by: rgrimes r315103: Implement a stub --horizon-lines=NUM for compatibility with GNU diff3 some options of GNU diff3 would call diff with --horizon-lines, rcs is depending on that. Reported by: antoine r315107: Fix building with recent gcc Reported by: lwhsu, ngie r315180: Readd codes that creates a tmp file for diffing stdout or devices r315197: Do not die if cap_rights_limit reports ENOSYS Reported by: mmel r315293: Integrate contrib/netbsd-tests/usr.bin/diff/t_diff.sh in as .../usr.bin/diff/diff_test Some minor adjustment needed to be done for :same as it currently has the test script hardcoded into the test, instead of using an idiom like $(dirname $0) Sponsored by: Dell EMC Isilon r315319: diff(1): sort long options under -D example in SYNOPSYS Sponsored by: Dell EMC Isilon r315590: diff(1): add --strip-trailing-cr to last example in the SYNOPSIS This syncs the last example in the SYNOPSIS with the other examples. Reviewed by: bapt Sponsored by: Dell EMC Isilon Differential Revision: D10017 r315649: Cache tzdata when running under capsicum PR: 217957 Reported by: tobik@ r315726: diff(1): fix SYNOPSIS section noting non-existent option, --no-ignore-case `--no-ignore-case` should be `--no-ignore-file-name-case` per code for compatibility with [g]diff(1). Sponsored by: Dell EMC Isilon r315743: Use MAX and MIN macros from sys/param.h r315746: Use strndup(3) instead of malloc + memcpy r315747: Use MIN macros from sys/param.h r315779: diff(1): document remaining long options While here, try and tie together some of the short options with their long option equivalents, where possible. Sponsored by: Dell EMC Isilon r315985: diff: Fix mtime of file1 in -u/-c header line. PR: 218018 Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D10140 r316002: diff: Show nanoseconds in -u/-c header line. Show nanoseconds in the -u/-c header line. The present portability conditionals cannot handle the POSIX standard st_mtim, so remove them and unconditionally use st_mtim. PR: 218018 Reported by: jbeich Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D10145 r316639: add a stub --speed-large-files for compatibility with GNU diff There is no intention to implement it, but lots of scripts/tools using diff(1) passes GNU diff option r316959: Clean up headers declaration r317187: Add a regression test for diff -D r317194: Implement a basic --changed-group-format etcupdate(8) requires that option, while GNU diff supports many more variation of that options, their behaviour beside the simple verion implemented here are quite inconsistent as such I do not plan to implement those. The only special keyword supported by this implementation are: %< and %> %= is not implemented as the documentation of GNU diff says: common lines, but it actually when tested print the changes from the first file r317205: Document all long options r317206: Update the TODO list to reflect what has been changed r317207: Cross reference pr(1) which diff might call with -l option r317381: Fix the following warning from gcc 4.2 in usr.bin/diff: usr.bin/diff/diffreg.c: In function 'change': usr.bin/diff/diffreg.c:1085: warning: 'i' may be used uninitialized in this function This version of gcc is not smart enough to see that 'i' cannot actually be used unitialized. However, the variable is confusingly re-used, so it is better to give it another name, and clearly initialize it before attempting to use it. Reviewed by: bapt Differential Revision: https://reviews.freebsd.org/D10484 r319489: Add -H as an alias for --speed-large-file to match GNU diff. This is undocumented to match GNU diff where -H is also undocumented. Some existing software (such as kompare) uses this option by default. Reviewed by: emaste, rpokala Differential Revision: https://reviews.freebsd.org/D11022 r319847: Add some testcases for `diff --side-by-side` support These are were created proactively, in anticipation of the support being fully implemented sometime in the future. The tests currently fail on ^/head@r319845, however. Expect them to fail. PR: 219933 Tested with: gdiff r321076: Don't emit "diff: diff <options> arguments" when diffing files if -q is specified. This improves compatibility with GNU diff. Found by accident with `diff -Nrq /usr/tests /usr/tests.new | grep Kyuafile`. Relnotes: yes r321077: Add some tests for brief (--brief/-q) format MFC with: r321076 r321078: Fix exit status with -rq when there is a file in one directory but not another, i.e., when print_only is called. Prior to this change, -rq was always returning 0. After this change it will return 1 if there is a difference between two directories. This fixes compatibility with GNU diff and unbreaks backwards compatibility expectations. Found when trying to extend diff_test:brief_format_test. MFC with: r321076, r321077 r321079: Add tests that exercise -q, like -rq and add tests that test -q like -Nrq MFC with: r321076, r321077, r321078 r321227: Use more flexible expression for replacing t_diff in contrib/netbsd-tests/usr.bin/diff/t_diff.sh with the name of the script via `basename $0`. This was a change I forgot to port over from ^/head/gnu/usr.bin/diff/tests/Makefile@r272787. r326822: Replace homemade equivalent of tolower(3) by towlower(3) This will help in the futur making diff -i works with multibyte Relnotes: Yes Added: stable/11/usr.bin/diff/ - copied from r315051, head/usr.bin/diff/ stable/11/usr.bin/diff/tests/diff_test.sh - copied, changed from r315051, head/usr.bin/diff/tests/diff.sh stable/11/usr.bin/diff/tests/group-format.out - copied unchanged from r317194, head/usr.bin/diff/tests/group-format.out stable/11/usr.bin/diff/tests/header.out - copied unchanged from r315985, head/usr.bin/diff/tests/header.out stable/11/usr.bin/diff/tests/header_ns.out - copied unchanged from r316002, head/usr.bin/diff/tests/header_ns.out stable/11/usr.bin/diff/tests/ifdef.out - copied unchanged from r317187, head/usr.bin/diff/tests/ifdef.out Deleted: stable/11/usr.bin/diff/tests/diff.sh Modified: stable/11/usr.bin/Makefile stable/11/usr.bin/diff/TODO stable/11/usr.bin/diff/diff.1 stable/11/usr.bin/diff/diff.c stable/11/usr.bin/diff/diff.h stable/11/usr.bin/diff/diffdir.c stable/11/usr.bin/diff/diffreg.c stable/11/usr.bin/diff/tests/Makefile Directory Properties: stable/11/ (props changed) Modified: stable/11/usr.bin/Makefile ============================================================================== --- stable/11/usr.bin/Makefile Fri Mar 23 21:02:46 2018 (r331464) +++ stable/11/usr.bin/Makefile Fri Mar 23 21:06:06 2018 (r331465) @@ -217,6 +217,9 @@ SUBDIR.${MK_GAMES}+= number SUBDIR.${MK_GAMES}+= pom SUBDIR.${MK_GAMES}+= primes SUBDIR.${MK_GAMES}+= random +.if ${MK_GNU_DIFF} == "no" +SUBDIR+= diff +.endif .if ${MK_GPL_DTC} != "yes" .if ${COMPILER_FEATURES:Mc++11} SUBDIR+= dtc Modified: stable/11/usr.bin/diff/TODO ============================================================================== --- head/usr.bin/diff/TODO Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/TODO Fri Mar 23 21:06:06 2018 (r331465) @@ -5,14 +5,14 @@ * make a libsdiff and use that directly to avoid duplicating the code to be implemented: ---suppress-common-lines: depends on -y --ignore-blank-lines --horizon-lines --ignore-tab-expansion --line-format Will probably be not implemented: ---GTYPE-group-format +--GTYPE-group-format (partially implement - minimal) --LTYPE-line-format ---speed-large-file: (Do we need that? only a stub?) --help (We have a manpage already) +--suppress-common-lines: depends on -y (won't be implemented, as it conflicts +the way sdiff expects it and in any case we have sdiff for that feature) Modified: stable/11/usr.bin/diff/diff.1 ============================================================================== --- head/usr.bin/diff/diff.1 Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/diff.1 Fri Mar 23 21:06:06 2018 (r331465) @@ -30,7 +30,7 @@ .\" @(#)diff.1 8.1 (Berkeley) 6/30/93 .\" $FreeBSD$ .\" -.Dd Septembr 03, 2017 +.Dd April 20, 2017 .Dt DIFF 1 .Os .Sh NAME @@ -43,45 +43,105 @@ .Fl c | e | f | .Fl n | q | u .Oc +.Op Fl -brief +.Op Fl -changed-group-format Ar GFMT +.Op Fl -ed +.Op Fl -expand-tabs +.Op Fl -forward-ed +.Op Fl -ignore-all-space .Op Fl -ignore-case -.Op Fl -no-ignore-case +.Op Fl -ignore-space-change +.Op Fl -initial-tab +.Op Fl -minimal +.Op Fl -no-ignore-file-name-case .Op Fl -normal +.Op Fl -rcs +.Op Fl -show-c-function +.Op Fl -starting-file +.Op Fl -speed-large-files .Op Fl -strip-trailing-cr .Op Fl -tabsize -.Op Fl I Ar pattern -.Op Fl L Ar label +.Op Fl -text +.Op Fl -unified +.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern +.Op Fl L Ar label | Fl -label Ar label .Ar file1 file2 .Nm diff .Op Fl abdilpTtw -.Op Fl I Ar pattern -.Op Fl L Ar label +.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern +.Op Fl L Ar label | Fl -label Ar label +.Op Fl -brief +.Op Fl -changed-group-format Ar GFMT +.Op Fl -ed +.Op Fl -expand-tabs +.Op Fl -forward-ed +.Op Fl -ignore-all-space .Op Fl -ignore-case -.Op Fl -no-ignore-case +.Op Fl -ignore-space-change +.Op Fl -initial-tab +.Op Fl -minimal +.Op Fl -no-ignore-file-name-case .Op Fl -normal +.Op Fl -paginate +.Op Fl -rcs +.Op Fl -show-c-function +.Op Fl -speed-large-files +.Op Fl -starting-file .Op Fl -strip-trailing-cr .Op Fl -tabsize -.Fl C Ar number +.Op Fl -text +.Fl C Ar number | -context Ar number .Ar file1 file2 .Nm diff .Op Fl abdiltw -.Op Fl I Ar pattern +.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern +.Op Fl -brief +.Op Fl -changed-group-format Ar GFMT +.Op Fl -ed +.Op Fl -expand-tabs +.Op Fl -forward-ed +.Op Fl -ignore-all-space .Op Fl -ignore-case -.Op Fl -no-ignore-case +.Op Fl -ignore-space-change +.Op Fl -initial-tab +.Op Fl -minimal +.Op Fl -no-ignore-file-name-case .Op Fl -normal +.Op Fl -paginate +.Op Fl -rcs +.Op Fl -show-c-function +.Op Fl -speed-large-files +.Op Fl -starting-file .Op Fl -strip-trailing-cr .Op Fl -tabsize -.Fl D Ar string +.Op Fl -text +.Fl D Ar string | Fl -ifdef Ar string .Ar file1 file2 .Nm diff .Op Fl abdilpTtw -.Op Fl I Ar pattern -.Op Fl L Ar label +.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern +.Op Fl L Ar label | Fl -label Ar label +.Op Fl -brief +.Op Fl -changed-group-format Ar GFMT +.Op Fl -ed +.Op Fl -expand-tabs +.Op Fl -forward-ed +.Op Fl -ignore-all-space .Op Fl -ignore-case -.Op Fl -no-ignore-case +.Op Fl -ignore-space-change +.Op Fl -initial-tab +.Op Fl -minimal +.Op Fl -no-ignore-file-name-case .Op Fl -normal -.Op Fl -tabsize +.Op Fl -paginate +.Op Fl -rcs +.Op Fl -show-c-function +.Op Fl -speed-large-files +.Op Fl -starting-file .Op Fl -strip-trailing-cr -.Fl U Ar number +.Op Fl -tabsize +.Op Fl -text +.Fl U Ar number | Fl -unified Ar number .Ar file1 file2 .Nm diff .Op Fl abdilNPprsTtw @@ -89,16 +149,37 @@ .Fl c | e | f | .Fl n | q | u .Oc +.Op Fl -brief +.Op Fl -changed-group-format Ar GFMT +.Op Fl -context +.Op Fl -ed +.Op Fl -expand-tabs +.Op Fl -forward-ed +.Op Fl -ignore-all-space .Op Fl -ignore-case -.Op Fl -no-ignore-case +.Op Fl -ignore-space-change +.Op Fl -initial-tab +.Op Fl -minimal +.Op Fl -new-file +.Op Fl -no-ignore-file-name-case .Op Fl -normal +.Op Fl -paginate +.Op Fl -rcs +.Op Fl -recursive +.Op Fl -report-identical-files +.Op Fl -show-c-function +.Op Fl -speed-large-files +.Op Fl -strip-trailing-cr .Op Fl -tabsize -.Op Fl I Ar pattern +.Op Fl -text +.Op Fl -unidirectional-new-file +.Op Fl -unified +.Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Bk -words -.Op Fl L Ar label -.Op Fl S Ar name -.Op Fl X Ar file -.Op Fl x Ar pattern +.Op Fl L Ar label | Fl -label Ar label +.Op Fl S Ar name | Fl -starting-file Ar name +.Op Fl X Ar file | Fl -exclude-from Ar file +.Op Fl x Ar pattern | Fl -exclude Ar pattern .Ek .Ar dir1 dir2 .Sh DESCRIPTION @@ -114,7 +195,7 @@ No output is produced if the files are identical. .Pp Output options (mutually exclusive): .Bl -tag -width Ds -.It Fl C Ar number +.It Fl C Ar number Fl -context Ar number Like .Fl c but produces a diff with @@ -142,7 +223,7 @@ both files with .Sq !\ \& . Changes which lie within 3 lines of each other are grouped together on output. -.It Fl D Ar string +.It Fl D Ar string Fl -ifdef Ar string Creates a merged version of .Ar file1 and @@ -156,7 +237,7 @@ while defining .Ar string will yield .Ar file2 . -.It Fl e +.It Fl e -ed Produces output in a form suitable as input for the editor utility, .Xr ed 1 , which can then be used to convert file1 into file2. @@ -170,7 +251,7 @@ from their state in .Ar dir1 to their state in .Ar dir2 . -.It Fl f +.It Fl f -forward-ed Identical output to that of the .Fl e flag, but in reverse order. @@ -183,10 +264,10 @@ but in the opposite order and with a count of changed insert or delete command. This is the form used by .Xr rcsdiff 1 . -.It Fl q +.It Fl q -brief Just print a line when the files differ. Does not output a list of changes. -.It Fl U Ar number +.It Fl U Ar number Fl -unified Ar number Like .Fl u but produces a diff with @@ -207,7 +288,7 @@ a single section. .Pp Comparison options: .Bl -tag -width Ds -.It Fl a +.It Fl a -text Treat all files as .Tn ASCII text. @@ -222,11 +303,11 @@ to produce a diff. .It Fl b Causes trailing blanks (spaces and tabs) to be ignored, and other strings of blanks to compare equal. -.It Fl d +.It Fl d -minimal Try very hard to produce a diff as small as possible. This may consume a lot of processing power and memory when processing large files with many changes. -.It Fl I Ar pattern +.It Fl I Ar pattern Fl -ignore-matching-lines Ar pattern Ignores changes, insertions, and deletions whose lines match the extended regular expression .Ar pattern . @@ -238,32 +319,32 @@ ignored. See .Xr re_format 7 for more information on regular expression patterns. -.It Fl i +.It Fl i -ignore-case Ignores the case of letters. E.g., .Dq A will compare equal to .Dq a . -.It Fl l +.It Fl l -paginate Pass the output through .Xr pr 1 to paginate it. -.It Fl L Ar label +.It Fl L Ar label Fl -label Ar label Print .Ar label instead of the first (and second, if this option is specified twice) file name and time in the context or unified diff header. -.It Fl p +.It Fl p -show-c-function With unified and context diffs, show with each change the first 40 characters of the last line before the context beginning with a letter, an underscore or a dollar sign. For C source code following standard layout conventions, this will show the prototype of the function the change applies to. -.It Fl T +.It Fl T -initial-tab Print a tab rather than a space before the rest of the line for the normal, context or unified output formats. This makes the alignment of tabs in the line consistent. -.It Fl t +.It Fl t -expand-tabs Will expand tabs in output lines. Normal or .Fl c @@ -271,48 +352,70 @@ output adds character(s) to the front of each line whi the indentation of the original source lines and make the output listing difficult to interpret. This option will preserve the original source's indentation. -.It Fl w +.It Fl w -ignore-all-blanks Is similar to -.Fl b +.Fl b -ignore-space-change but causes whitespace (blanks and tabs) to be totally ignored. E.g., .Dq if (\ \&a == b \&) will compare equal to .Dq if(a==b) . +.It Fl -changed-group-format Ar GFMT +Format input groups in the provided +.Pp +the format is a string with special keywords: +.Bl -tag -width %< +.It %< +lines from FILE1 +.It %< +lines from FILE2 .El +.It Fl -ignore-file-name-case +ignore case when comparing file names +.It Fl -no-ignore-file-name-case +do not ignore case wen comparing file names (default) +.It Fl -normal +default diff output +.It Fl -speed-large-files +stub option for compatibility with GNU diff +.It Fl -strip-trailing-cr +strip carriage return on input files +.It Fl tabsize Ar number +Number of spaces representing a tab (default 8) +.El .Pp Directory comparison options: .Bl -tag -width Ds -.It Fl N +.It Fl N -new-file If a file is found in only one directory, act as if it was found in the other directory too but was of zero size. -.It Fl P +.It Fl P -unidirectional-new-file If a file is found only in .Ar dir2 , act as if it was found in .Ar dir1 too but was of zero size. -.It Fl r +.It Fl r -recursive Causes application of .Nm recursively to common subdirectories encountered. -.It Fl S Ar name +.It Fl S Ar name Fl -starting-file Ar name Re-starts a directory .Nm in the middle, beginning with file .Ar name . -.It Fl s +.It Fl s -report-identical-files Causes .Nm to report files which are the same, which are otherwise not mentioned. -.It Fl X Ar file +.It Fl X Ar file Fl -exclude-from Ar file Exclude files and subdirectories from comparison whose basenames match lines in .Ar file . Multiple .Fl X options may be specified. -.It Fl x Ar pattern +.It Fl x Ar pattern Fl -exclude Ar pattern Exclude files and subdirectories from comparison whose basenames match .Ar pattern . Patterns are matched using shell-style globbing via @@ -360,7 +463,7 @@ The default (without .Fl e , .Fl c , or -.Fl n +.Fl n -rcs .\" -C options) output contains lines of these forms, where @@ -480,6 +583,7 @@ An error occurred. .Xr diff3 1 , .Xr ed 1 , .Xr patch 1 , +.Xr pr 1 , .Xr sdiff 1 .Rs .%A James W. Hunt Modified: stable/11/usr.bin/diff/diff.c ============================================================================== --- head/usr.bin/diff/diff.c Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/diff.c Fri Mar 23 21:06:06 2018 (r331465) @@ -27,11 +27,9 @@ __FBSDID("$FreeBSD$"); #include <ctype.h> #include <err.h> -#include <errno.h> #include <getopt.h> #include <stdlib.h> #include <stdio.h> -#include <stdarg.h> #include <string.h> #include <unistd.h> #include <limits.h> @@ -43,17 +41,20 @@ int lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; int diff_format, diff_context, status, ignore_file_case; int tabsize = 8; char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; +char *group_format = NULL; struct stat stb1, stb2; struct excludes *excludes_list; regex_t ignore_re; -#define OPTIONS "0123456789aBbC:cdD:efhI:iL:lnNPpqrS:sTtU:uwX:x:" +#define OPTIONS "0123456789aBbC:cdD:efHhI:iL:lnNPpqrS:sTtU:uwX:x:" enum { OPT_TSIZE = CHAR_MAX + 1, OPT_STRIPCR, OPT_IGN_FN_CASE, OPT_NO_IGN_FN_CASE, OPT_NORMAL, + OPT_HORIZON_LINES, + OPT_CHANGED_GROUP_FORMAT, }; static struct option longopts[] = { @@ -64,6 +65,7 @@ static struct option longopts[] = { { "minimal", no_argument, 0, 'd' }, { "ed", no_argument, 0, 'e' }, { "forward-ed", no_argument, 0, 'f' }, + { "speed-large-files", no_argument, NULL, 'H' }, { "ignore-matching-lines", required_argument, 0, 'I' }, { "ignore-case", no_argument, 0, 'i' }, { "paginate", no_argument, NULL, 'l' }, @@ -83,10 +85,12 @@ static struct option longopts[] = { { "exclude", required_argument, 0, 'x' }, { "exclude-from", required_argument, 0, 'X' }, { "ignore-file-name-case", no_argument, NULL, OPT_IGN_FN_CASE }, + { "horizon-lines", required_argument, NULL, OPT_HORIZON_LINES }, { "no-ignore-file-name-case", no_argument, NULL, OPT_NO_IGN_FN_CASE }, { "normal", no_argument, NULL, OPT_NORMAL }, { "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, { "tabsize", optional_argument, NULL, OPT_TSIZE }, + { "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT}, { NULL, 0, 0, '\0'} }; @@ -154,6 +158,9 @@ main(int argc, char **argv) case 'f': diff_format = D_REVERSE; break; + case 'H': + /* ignore but needed for compatibility with GNU diff */ + break; case 'h': /* silently ignore for backwards compatibility */ break; @@ -225,6 +232,12 @@ main(int argc, char **argv) case 'x': push_excludes(optarg); break; + case OPT_CHANGED_GROUP_FORMAT: + diff_format = D_GFORMAT; + group_format = optarg; + break; + case OPT_HORIZON_LINES: + break; /* XXX TODO for compatibility with GNU diff3 */ case OPT_IGN_FN_CASE: ignore_file_case = 1; break; @@ -347,9 +360,8 @@ read_excludes_file(char *file) while ((buf = fgetln(fp, &len)) != NULL) { if (buf[len - 1] == '\n') len--; - pattern = xmalloc(len + 1); - memcpy(pattern, buf, len); - pattern[len] = '\0'; + if ((pattern = strndup(buf, len)) == NULL) + err(2, "xstrndup"); push_excludes(pattern); } if (strcmp(file, "-") != 0) Modified: stable/11/usr.bin/diff/diff.h ============================================================================== --- head/usr.bin/diff/diff.h Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/diff.h Fri Mar 23 21:06:06 2018 (r331465) @@ -47,6 +47,7 @@ #define D_NREVERSE 5 /* Reverse ed script with numbered lines and no trailing . */ #define D_BRIEF 6 /* Say if the files differ */ +#define D_GFORMAT 7 /* Diff with defined changed group format */ /* * Output flags @@ -87,6 +88,7 @@ extern int lflag, Nflag, Pflag, rflag, sflag, Tflag, c extern int diff_format, diff_context, status, ignore_file_case; extern int tabsize; extern char *start, *ifdefname, *diffargs, *label[2], *ignore_pats; +extern char *group_format; extern struct stat stb1, stb2; extern struct excludes *excludes_list; extern regex_t ignore_re; Modified: stable/11/usr.bin/diff/diffdir.c ============================================================================== --- head/usr.bin/diff/diffdir.c Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/diffdir.c Fri Mar 23 21:06:06 2018 (r331465) @@ -28,17 +28,13 @@ __FBSDID("$FreeBSD$"); #include <dirent.h> #include <err.h> #include <errno.h> -#include <fcntl.h> #include <fnmatch.h> -#include <paths.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include <limits.h> #include "diff.h" -#include "xmalloc.h" static int selectfile(const struct dirent *); static void diffit(struct dirent *, char *, size_t, char *, size_t, int); @@ -57,6 +53,8 @@ diffdir(char *p1, char *p2, int flags) char path1[PATH_MAX], path2[PATH_MAX]; int pos; + edp1 = edp2 = NULL; + dirlen1 = strlcpy(path1, *p1 ? p1 : ".", sizeof(path1)); if (dirlen1 >= sizeof(path1) - 1) { warnc(ENAMETOOLONG, "%s", p1); @@ -136,16 +134,20 @@ diffdir(char *p1, char *p2, int flags) if (Nflag) diffit(dent1, path1, dirlen1, path2, dirlen2, flags); - else + else { print_only(path1, dirlen1, dent1->d_name); + status = 1; + } dp1++; } else { /* file only in second dir, only diff if -N or -P */ if (Nflag || Pflag) diffit(dent2, path1, dirlen1, path2, dirlen2, flags); - else + else { print_only(path2, dirlen2, dent2->d_name); + status = 1; + } dp2++; } } Modified: stable/11/usr.bin/diff/diffreg.c ============================================================================== --- head/usr.bin/diff/diffreg.c Sat Mar 11 05:01:29 2017 (r315051) +++ stable/11/usr.bin/diff/diffreg.c Fri Mar 23 21:06:06 2018 (r331465) @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <paths.h> +#include <regex.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -94,15 +95,6 @@ __FBSDID("$FreeBSD$"); #define _PATH_PR "/usr/bin/pr" -#ifdef ST_MTIM_NSEC -# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC) -#else -# define TIMESPEC_NS(timespec) 0 -#endif - -#define MINIMUM(a, b) (((a) < (b)) ? (a) : (b)) -#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) - /* * diff - compare two files. */ @@ -194,13 +186,14 @@ struct context_vec { }; #define diff_output printf +static FILE *opentemp(const char *); static void output(char *, FILE *, char *, FILE *, int); static void check(FILE *, FILE *, int); static void range(int, int, const char *); static void uni_range(int, int); static void dump_context_vec(FILE *, FILE *, int); static void dump_unified_vec(FILE *, FILE *, int); -static void prepare(int, FILE *, off_t, int); +static void prepare(int, FILE *, size_t, int); static void prune(void); static void equiv(struct line *, int, struct line *, int, int *); static void unravel(int); @@ -236,7 +229,7 @@ static long *ixold; /* will be overlaid on klist */ static struct cand *clist; /* merely a free storage pot for candidates */ static int clistlen; /* the length of clist */ static struct line *sfile[2]; /* shortened by pruning common prefix/suffix */ -static u_char *chrtran; /* translation table for case-folding */ +static int (*chrtran)(int); /* translation table for case-folding */ static struct context_vec *context_vec_start; static struct context_vec *context_vec_end; static struct context_vec *context_vec_ptr; @@ -246,65 +239,20 @@ static char lastbuf[FUNCTION_CONTEXT_SIZE]; static int lastline; static int lastmatchline; +static int +clow2low(int c) +{ -/* - * chrtran points to one of 2 translation tables: cup2low if folding upper to - * lower case clow2low if not folding case - */ -static u_char clow2low[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, - 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, - 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, - 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, - 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, - 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, - 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, - 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, - 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, - 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, - 0xfd, 0xfe, 0xff -}; + return (c); +} -static u_char cup2low[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, - 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, - 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x60, 0x61, - 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, - 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x60, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, - 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, - 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, - 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, - 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, - 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, - 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, - 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, - 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, - 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, - 0xfd, 0xfe, 0xff -}; +static int +cup2low(int c) +{ + return tolower(c); +} + int diffreg(char *file1, char *file2, int flags, int capsicum) { @@ -315,6 +263,8 @@ diffreg(char *file1, char *file2, int flags, int capsi struct kevent *e; cap_rights_t rights_ro; + e = NULL; + kq = -1; f1 = f2 = NULL; rval = D_SAME; anychange = 0; @@ -333,7 +283,14 @@ diffreg(char *file1, char *file2, int flags, int capsi if (flags & D_EMPTY1) f1 = fopen(_PATH_DEVNULL, "r"); else { - if (strcmp(file1, "-") == 0) + if (!S_ISREG(stb1.st_mode)) { + if ((f1 = opentemp(file1)) == NULL || + fstat(fileno(f1), &stb1) < 0) { + warn("%s", file1); + status |= 2; + goto closem; + } + } else if (strcmp(file1, "-") == 0) f1 = stdin; else f1 = fopen(file1, "r"); @@ -347,7 +304,14 @@ diffreg(char *file1, char *file2, int flags, int capsi if (flags & D_EMPTY2) f2 = fopen(_PATH_DEVNULL, "r"); else { - if (strcmp(file2, "-") == 0) + if (!S_ISREG(stb2.st_mode)) { + if ((f2 = opentemp(file2)) == NULL || + fstat(fileno(f2), &stb2) < 0) { + warn("%s", file2); + status |= 2; + goto closem; + } + } else if (strcmp(file2, "-") == 0) f2 = stdin; else f2 = fopen(file2, "r"); @@ -407,9 +371,11 @@ diffreg(char *file1, char *file2, int flags, int capsi if (capsicum) { cap_rights_init(&rights_ro, CAP_READ, CAP_FSTAT, CAP_SEEK); - if (cap_rights_limit(fileno(f1), &rights_ro) < 0) + if (cap_rights_limit(fileno(f1), &rights_ro) < 0 + && errno != ENOSYS) err(2, "unable to limit rights on: %s", file1); - if (cap_rights_limit(fileno(f2), &rights_ro) < 0) + if (cap_rights_limit(fileno(f2), &rights_ro) < 0 && + errno != ENOSYS) err(2, "unable to limit rights on: %s", file2); if (fileno(f1) == STDIN_FILENO || fileno(f2) == STDIN_FILENO) { /* stding has already been limited */ @@ -421,6 +387,7 @@ diffreg(char *file1, char *file2, int flags, int capsi err(2, "unable to limit stdio"); caph_cache_catpages(); + caph_cache_tzdata(); if (cap_enter() < 0 && errno != ENOSYS) err(2, "unable to enter capability mode"); } @@ -474,7 +441,7 @@ diffreg(char *file1, char *file2, int flags, int capsi ixnew = xreallocarray(ixnew, len[1] + 2, sizeof(*ixnew)); check(f1, f2, flags); output(file1, f1, file2, f2, flags); - if (ostdout != -1) { + if (ostdout != -1 && e != NULL) { /* close the pipe to pr and restore stdout */ int wstatus; @@ -537,6 +504,37 @@ files_differ(FILE *f1, FILE *f2, int flags) } } +static FILE * +opentemp(const char *f) +{ + char buf[BUFSIZ], tempfile[PATH_MAX]; + ssize_t nread; + int ifd, ofd; + + if (strcmp(f, "-") == 0) + ifd = STDIN_FILENO; + else if ((ifd = open(f, O_RDONLY, 0644)) < 0) + return (NULL); + + (void)strlcpy(tempfile, _PATH_TMP "/diff.XXXXXXXX", sizeof(tempfile)); + + if ((ofd = mkstemp(tempfile)) < 0) { + close(ifd); + return (NULL); + } + unlink(tempfile); + while ((nread = read(ifd, buf, BUFSIZ)) > 0) { + if (write(ofd, buf, nread) != nread) { + close(ifd); + close(ofd); + return (NULL); + } + } + close(ifd); + lseek(ofd, (off_t)0, SEEK_SET); + return (fdopen(ofd, "r")); +} + char * splice(char *dir, char *path) { @@ -555,7 +553,7 @@ splice(char *dir, char *path) } static void -prepare(int i, FILE *fd, off_t filesize, int flags) +prepare(int i, FILE *fd, size_t filesize, int flags) { struct line *p; int h; @@ -563,7 +561,7 @@ prepare(int i, FILE *fd, off_t filesize, int flags) rewind(fd); - sz = ((unsigned long)filesize <= SIZE_MAX ? filesize : SIZE_MAX) / 25; + sz = MIN(filesize, SIZE_MAX) / 25; if (sz < 100) sz = 100; @@ -658,7 +656,7 @@ stone(int *a, int n, int *b, int *c, int flags) bound = UINT_MAX; else { sq = isqrt(n); - bound = MAXIMUM(256, sq); + bound = MAX(256, sq); } k = 0; @@ -830,7 +828,7 @@ check(FILE *f1, FILE *f2, int flags) ctnew++; } } - if (chrtran[c] != chrtran[d]) { + if (chrtran(c) != chrtran(d)) { jackpot++; J[i] = 0; if (c != '\n' && c != EOF) @@ -965,7 +963,7 @@ output(char *file1, FILE *f1, char *file2, FILE *f2, i } if (m == 0) change(file1, f1, file2, f2, 1, 0, 1, len[1], &flags); - if (diff_format == D_IFDEF) { + if (diff_format == D_IFDEF || diff_format == D_GFORMAT) { for (;;) { #define c i0 if ((c = getc(f1)) == EOF) @@ -1038,10 +1036,13 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, i int *pflags) { static size_t max_context = 64; - int i; + long curpos; + int i, nc, f; + const char *walk; restart: - if (diff_format != D_IFDEF && a > b && c > d) + if ((diff_format != D_IFDEF || diff_format == D_GFORMAT) && + a > b && c > d) return; if (ignore_pats != NULL) { char *line; @@ -1069,7 +1070,7 @@ restart: return; } proceed: - if (*pflags & D_HEADER) { + if (*pflags & D_HEADER && diff_format != D_BRIEF) { diff_output("%s %s %s\n", diffargs, file1, file2); *pflags &= ~D_HEADER; } @@ -1138,13 +1139,40 @@ proceed: } break; } + if (diff_format == D_GFORMAT) { + curpos = ftell(f1); + /* print through if append (a>b), else to (nb: 0 vs 1 orig) */ + nc = ixold[a > b ? b : a - 1] - curpos; + for (i = 0; i < nc; i++) + diff_output("%c", getc(f1)); + for (walk = group_format; *walk != '\0'; walk++) { + if (*walk == '%') { + walk++; + switch (*walk) { + case '<': + fetch(ixold, a, b, f1, '<', 1, *pflags); + break; + case '>': + fetch(ixnew, c, d, f2, '>', 0, *pflags); + break; + default: + diff_output("%%%c", *walk); + break; + } + continue; + } + diff_output("%c", *walk); + } + } if (diff_format == D_NORMAL || diff_format == D_IFDEF) { fetch(ixold, a, b, f1, '<', 1, *pflags); if (a <= b && c <= d && diff_format == D_NORMAL) diff_output("---\n"); } - i = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); - if (i != 0 && diff_format == D_EDIT) { + f = 0; + if (diff_format != D_GFORMAT) + f = fetch(ixnew, c, d, f2, diff_format == D_NORMAL ? '>' : '\0', 0, *pflags); + if (f != 0 && diff_format == D_EDIT) { /* * A non-zero return value for D_EDIT indicates that the * last line printed was a bare dot (".") that has been @@ -1153,10 +1181,10 @@ proceed: * back and restart where we left off. */ diff_output(".\n"); - diff_output("%ds/.//\n", a + i - 1); - b = a + i - 1; + diff_output("%ds/.//\n", a + f - 1); + b = a + f - 1; a = b + 1; - c += i; + c += f; goto restart; } if ((diff_format == D_EDIT || diff_format == D_REVERSE) && c <= d) @@ -1177,7 +1205,7 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int old * When doing #ifdef's, copy down to current line * if this is the first file, so that stuff makes it to output. */ - if (diff_format == D_IFDEF && oldfile) { + if ((diff_format == D_IFDEF) && oldfile) { long curpos = ftell(lb); /* print through if append (a>b), else to (nb: 0 vs 1 orig) */ nc = f[a > b ? b : a - 1] - curpos; @@ -1201,7 +1229,8 @@ fetch(long *f, int a, int b, FILE *lb, int ch, int old for (i = a; i <= b; i++) { fseek(lb, f[i - 1], SEEK_SET); nc = f[i] - f[i - 1]; - if (diff_format != D_IFDEF && ch != '\0') { + if ((diff_format != D_IFDEF && diff_format != D_GFORMAT) && + ch != '\0') { diff_output("%c", ch); if (Tflag && (diff_format == D_NORMAL || diff_format == D_CONTEXT || diff_format == D_UNIFIED)) @@ -1271,7 +1300,7 @@ readhash(FILE *f, int flags) return (0); break; } - sum = sum * 127 + chrtran[t]; + sum = sum * 127 + chrtran(t); } else for (i = 0; (t = getc(f)) != '\n'; i++) { @@ -1303,7 +1332,7 @@ readhash(FILE *f, int flags) i++; space = 0; } - sum = sum * 127 + chrtran[t]; + sum = sum * 127 + chrtran(t); i++; continue; case EOF: @@ -1395,10 +1424,10 @@ dump_context_vec(FILE *f1, FILE *f2, int flags) return; b = d = 0; /* gcc */ - lowa = MAXIMUM(1, cvp->a - diff_context); - upb = MINIMUM(len[0], context_vec_ptr->b + diff_context); - lowc = MAXIMUM(1, cvp->c - diff_context); - upd = MINIMUM(len[1], context_vec_ptr->d + diff_context); + lowa = MAX(1, cvp->a - diff_context); + upb = MIN(len[0], context_vec_ptr->b + diff_context); + lowc = MAX(1, cvp->c - diff_context); + upd = MIN(len[1], context_vec_ptr->d + diff_context); diff_output("***************"); if ((flags & D_PROTOTYPE)) { @@ -1498,10 +1527,10 @@ dump_unified_vec(FILE *f1, FILE *f2, int flags) return; b = d = 0; /* gcc */ - lowa = MAXIMUM(1, cvp->a - diff_context); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803232106.w2NL66nX042691>