On 11.03.2017 6:01, Baptiste Daroussin wrote:
> Author: bapt
> Date: Sat Mar 11 05:01:29 2017
> New Revision: 315051
> URL: https://svnweb.freebsd.org/changeset/base/315051
> 
> Log:
>   Import diff from OpenBSD and remove GNU diff
>   
>   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
> 

It seems that this commit breaks mergemaster (but I'm not sure):

-----
diff: unable to limit rights on: /etc/casper/system.dns: Function not
implemented
---

Michal

> Added:
>   head/usr.bin/diff/
>   head/usr.bin/diff/Makefile   (contents, props changed)
>   head/usr.bin/diff/TODO   (contents, props changed)
>   head/usr.bin/diff/diff.1   (contents, props changed)
>   head/usr.bin/diff/diff.c   (contents, props changed)
>   head/usr.bin/diff/diff.h   (contents, props changed)
>   head/usr.bin/diff/diffdir.c   (contents, props changed)
>   head/usr.bin/diff/diffreg.c   (contents, props changed)
>   head/usr.bin/diff/tests/
>   head/usr.bin/diff/tests/Makefile   (contents, props changed)
>   head/usr.bin/diff/tests/diff.sh   (contents, props changed)
>   head/usr.bin/diff/tests/input1.in   (contents, props changed)
>   head/usr.bin/diff/tests/input2.in   (contents, props changed)
>   head/usr.bin/diff/tests/input_c1.in   (contents, props changed)
>   head/usr.bin/diff/tests/input_c2.in   (contents, props changed)
>   head/usr.bin/diff/tests/simple.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_b.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_e.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_i.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_n.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_p.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_u.out   (contents, props changed)
>   head/usr.bin/diff/tests/simple_w.out   (contents, props changed)
>   head/usr.bin/diff/tests/unified_9999.out   (contents, props changed)
>   head/usr.bin/diff/tests/unified_c9999.out   (contents, props changed)
>   head/usr.bin/diff/tests/unified_p.out   (contents, props changed)
>   head/usr.bin/diff/xmalloc.c   (contents, props changed)
>   head/usr.bin/diff/xmalloc.h   (contents, props changed)
> Deleted:
>   head/gnu/usr.bin/diff/
> Modified:
>   head/ObsoleteFiles.inc
>   head/UPDATING
>   head/gnu/usr.bin/Makefile
>   head/usr.bin/Makefile
> 
> Modified: head/ObsoleteFiles.inc
> ==============================================================================
> --- head/ObsoleteFiles.inc    Sat Mar 11 04:57:52 2017        (r315050)
> +++ head/ObsoleteFiles.inc    Sat Mar 11 05:01:29 2017        (r315051)
> @@ -38,6 +38,8 @@
>  #   xargs -n1 | sort | uniq -d;
>  # done
>  
> +# 20170311: remove GNU diff
> +OLD_FILES+=usr/share/man/man7/diff.7.gz
>  # 20170308: rename some tests
>  OLD_FILES+=usr/tests/bin/pwait/pwait
>  OLD_FILES+=usr/tests/usr.bin/timeout/timeout
> 
> Modified: head/UPDATING
> ==============================================================================
> --- head/UPDATING     Sat Mar 11 04:57:52 2017        (r315050)
> +++ head/UPDATING     Sat Mar 11 05:01:29 2017        (r315051)
> @@ -51,6 +51,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12
>  
>  ****************************** SPECIAL WARNING: 
> ******************************
>  
> +20170311:
> +     GNU diff has been replaced by a BSD licensed diff. Some features of GNU
> +     diff has not been implemented, if those are needed a newer version of
> +     GNU diff is available via the diffutils package under the gdiff name.
> +
>  20170302:
>       Clang, llvm, lldb, compiler-rt and libc++ have been upgraded to 4.0.0.
>       Please see the 20141231 entry below for information about prerequisites
> 
> Modified: head/gnu/usr.bin/Makefile
> ==============================================================================
> --- head/gnu/usr.bin/Makefile Sat Mar 11 04:57:52 2017        (r315050)
> +++ head/gnu/usr.bin/Makefile Sat Mar 11 05:01:29 2017        (r315051)
> @@ -17,7 +17,7 @@ SUBDIR.${MK_GDB}+=  gdb
>  .endif
>  
>  SUBDIR.${MK_GCC}+=   cc
> -SUBDIR.${MK_GNU_DIFF}+=      diff diff3
> +SUBDIR.${MK_GNU_DIFF}+=      diff3
>  SUBDIR.${MK_GNU_GREP}+=      grep
>  SUBDIR.${MK_GPL_DTC}+=       dtc
>  SUBDIR.${MK_TESTS}+= tests
> 
> Modified: head/usr.bin/Makefile
> ==============================================================================
> --- head/usr.bin/Makefile     Sat Mar 11 04:57:52 2017        (r315050)
> +++ head/usr.bin/Makefile     Sat Mar 11 05:01:29 2017        (r315051)
> @@ -34,6 +34,7 @@ SUBDIR=     alias \
>       csplit \
>       ctlstat \
>       cut \
> +     diff \
>       dirname \
>       du \
>       elf2aout \
> 
> Added: head/usr.bin/diff/Makefile
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/diff/Makefile        Sat Mar 11 05:01:29 2017        
> (r315051)
> @@ -0,0 +1,12 @@
> +# $FreeBSD$
> +
> +.include <src.opts.mk>
> +
> +PROG=        diff
> +SRCS=        diff.c diffdir.c diffreg.c xmalloc.c
> +
> +.if ${MK_TESTS} != "no"
> +SUBDIR+= tests
> +.endif
> +
> +.include <bsd.prog.mk>
> 
> Added: head/usr.bin/diff/TODO
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/diff/TODO    Sat Mar 11 05:01:29 2017        (r315051)
> @@ -0,0 +1,18 @@
> +-y:
> +  * soc implemented it via calling sdiff directly, but some options are
> +  incompatible so it is fragile
> +  * just recommend the user to run sdiff directly and do not implement it
> +  * 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
> +--LTYPE-line-format
> +--speed-large-file: (Do we need that? only a stub?)
> +--help (We have a manpage already)
> 
> Added: head/usr.bin/diff/diff.1
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/diff/diff.1  Sat Mar 11 05:01:29 2017        (r315051)
> @@ -0,0 +1,506 @@
> +.\" $OpenBSD: diff.1,v 1.47 2015/11/24 19:35:41 jmc Exp $
> +.\"
> +.\" Copyright (c) 1980, 1990, 1993
> +.\"  The Regents of the University of California.  All rights reserved.
> +.\"
> +.\" Redistribution and use in source and binary forms, with or without
> +.\" modification, are permitted provided that the following conditions
> +.\" are met:
> +.\" 1. Redistributions of source code must retain the above copyright
> +.\"    notice, this list of conditions and the following disclaimer.
> +.\" 2. Redistributions in binary form must reproduce the above copyright
> +.\"    notice, this list of conditions and the following disclaimer in the
> +.\"    documentation and/or other materials provided with the distribution.
> +.\" 3. Neither the name of the University nor the names of its contributors
> +.\"    may be used to endorse or promote products derived from this software
> +.\"    without specific prior written permission.
> +.\"
> +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
> +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
> PURPOSE
> +.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
> +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
> CONSEQUENTIAL
> +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
> STRICT
> +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> +.\" SUCH DAMAGE.
> +.\"
> +.\"     @(#)diff.1   8.1 (Berkeley) 6/30/93
> +.\" $FreeBSD$
> +.\"
> +.Dd Septembr 03, 2017
> +.Dt DIFF 1
> +.Os
> +.Sh NAME
> +.Nm diff
> +.Nd differential file and directory comparator
> +.Sh SYNOPSIS
> +.Nm diff
> +.Op Fl abdipTtw
> +.Oo
> +.Fl c | e | f |
> +.Fl n | q | u
> +.Oc
> +.Op Fl -ignore-case
> +.Op Fl -no-ignore-case
> +.Op Fl -normal
> +.Op Fl -strip-trailing-cr
> +.Op Fl -tabsize
> +.Op Fl I Ar pattern
> +.Op Fl L Ar label
> +.Ar file1 file2
> +.Nm diff
> +.Op Fl abdilpTtw
> +.Op Fl I Ar pattern
> +.Op Fl L Ar label
> +.Op Fl -ignore-case
> +.Op Fl -no-ignore-case
> +.Op Fl -normal
> +.Op Fl -strip-trailing-cr
> +.Op Fl -tabsize
> +.Fl C Ar number
> +.Ar file1 file2
> +.Nm diff
> +.Op Fl abdiltw
> +.Op Fl I Ar pattern
> +.Op Fl -ignore-case
> +.Op Fl -no-ignore-case
> +.Op Fl -normal
> +.Op Fl -strip-trailing-cr
> +.Op Fl -tabsize
> +.Fl D Ar string
> +.Ar file1 file2
> +.Nm diff
> +.Op Fl abdilpTtw
> +.Op Fl I Ar pattern
> +.Op Fl L Ar label
> +.Op Fl -ignore-case
> +.Op Fl -no-ignore-case
> +.Op Fl -normal
> +.Op Fl -tabsize
> +.Op Fl -strip-trailing-cr
> +.Fl U Ar number
> +.Ar file1 file2
> +.Nm diff
> +.Op Fl abdilNPprsTtw
> +.Oo
> +.Fl c | e | f |
> +.Fl n | q | u
> +.Oc
> +.Op Fl -ignore-case
> +.Op Fl -no-ignore-case
> +.Op Fl -normal
> +.Op Fl -tabsize
> +.Op Fl I Ar pattern
> +.Bk -words
> +.Op Fl L Ar label
> +.Op Fl S Ar name
> +.Op Fl X Ar file
> +.Op Fl x Ar pattern
> +.Ek
> +.Ar dir1 dir2
> +.Sh DESCRIPTION
> +The
> +.Nm
> +utility compares the contents of
> +.Ar file1
> +and
> +.Ar file2
> +and writes to the standard output the list of changes necessary to
> +convert one file into the other.
> +No output is produced if the files are identical.
> +.Pp
> +Output options (mutually exclusive):
> +.Bl -tag -width Ds
> +.It Fl C Ar number
> +Like
> +.Fl c
> +but produces a diff with
> +.Ar number
> +lines of context.
> +.It Fl c
> +Produces a diff with 3 lines of context.
> +With
> +.Fl c
> +the output format is modified slightly:
> +the output begins with identification of the files involved and
> +their creation dates and then each change is separated
> +by a line with fifteen
> +.Li * Ns 's .
> +The lines removed from
> +.Ar file1
> +are marked with
> +.Sq \&-\ \& ;
> +those added to
> +.Ar file2
> +are marked
> +.Sq \+\ \& .
> +Lines which are changed from one file to the other are marked in
> +both files with
> +.Sq !\ \& .
> +Changes which lie within 3 lines of each other are grouped together on
> +output.
> +.It Fl D Ar string
> +Creates a merged version of
> +.Ar file1
> +and
> +.Ar file2
> +on the standard output, with C preprocessor controls included so that
> +a compilation of the result without defining
> +.Ar string
> +is equivalent to compiling
> +.Ar file1 ,
> +while defining
> +.Ar string
> +will yield
> +.Ar file2 .
> +.It Fl e
> +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.
> +.Pp
> +Extra commands are added to the output when comparing directories with
> +.Fl e ,
> +so that the result is a
> +.Xr sh 1
> +script for converting text files which are common to the two directories
> +from their state in
> +.Ar dir1
> +to their state in
> +.Ar dir2 .
> +.It Fl f
> +Identical output to that of the
> +.Fl e
> +flag, but in reverse order.
> +It cannot be digested by
> +.Xr ed 1 .
> +.It Fl n
> +Produces a script similar to that of
> +.Fl e ,
> +but in the opposite order and with a count of changed lines on each
> +insert or delete command.
> +This is the form used by
> +.Xr rcsdiff 1 .
> +.It Fl q
> +Just print a line when the files differ.
> +Does not output a list of changes.
> +.It Fl U Ar number
> +Like
> +.Fl u
> +but produces a diff with
> +.Ar number
> +lines of context.
> +.It Fl u
> +Produces a
> +.Em unified
> +diff with 3 lines of context.
> +A unified diff is similar to the context diff produced by the
> +.Fl c
> +option.
> +However, unlike with
> +.Fl c ,
> +all lines to be changed (added and/or removed) are present in
> +a single section.
> +.El
> +.Pp
> +Comparison options:
> +.Bl -tag -width Ds
> +.It Fl a
> +Treat all files as
> +.Tn ASCII
> +text.
> +Normally
> +.Nm
> +will simply print
> +.Dq Binary files ... differ
> +if files contain binary characters.
> +Use of this option forces
> +.Nm
> +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
> +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
> +Ignores changes, insertions, and deletions whose lines match the
> +extended regular expression
> +.Ar pattern .
> +Multiple
> +.Fl I
> +patterns may be specified.
> +All lines in the change must match some pattern for the change to be
> +ignored.
> +See
> +.Xr re_format 7
> +for more information on regular expression patterns.
> +.It Fl i
> +Ignores the case of letters.
> +E.g.,
> +.Dq A
> +will compare equal to
> +.Dq a .
> +.It Fl l
> +Pass the output through
> +.Xr pr 1
> +to paginate it.
> +.It Fl L 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
> +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
> +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
> +Will expand tabs in output lines.
> +Normal or
> +.Fl c
> +output adds character(s) to the front of each line which may screw up
> +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
> +Is similar to
> +.Fl b
> +but causes whitespace (blanks and tabs) to be totally ignored.
> +E.g.,
> +.Dq if (\ \&a == b \&)
> +will compare equal to
> +.Dq if(a==b) .
> +.El
> +.Pp
> +Directory comparison options:
> +.Bl -tag -width Ds
> +.It Fl N
> +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
> +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
> +Causes application of
> +.Nm
> +recursively to common subdirectories encountered.
> +.It Fl S Ar name
> +Re-starts a directory
> +.Nm
> +in the middle, beginning with file
> +.Ar name .
> +.It Fl s
> +Causes
> +.Nm
> +to report files which are the same, which are otherwise not mentioned.
> +.It Fl X 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
> +Exclude files and subdirectories from comparison whose basenames match
> +.Ar pattern .
> +Patterns are matched using shell-style globbing via
> +.Xr fnmatch 3 .
> +Multiple
> +.Fl x
> +options may be specified.
> +.El
> +.Pp
> +If both arguments are directories,
> +.Nm
> +sorts the contents of the directories by name, and then runs the
> +regular file
> +.Nm
> +algorithm, producing a change list,
> +on text files which are different.
> +Binary files which differ,
> +common subdirectories, and files which appear in only one directory
> +are described as such.
> +In directory mode only regular files and directories are compared.
> +If a non-regular file such as a device special file or
> +.Tn FIFO
> +is encountered, a diagnostic message is printed.
> +.Pp
> +If only one of
> +.Ar file1
> +and
> +.Ar file2
> +is a directory,
> +.Nm
> +is applied to the non-directory file and the file contained in
> +the directory file with a filename that is the same as the
> +last component of the non-directory file.
> +.Pp
> +If either
> +.Ar file1
> +or
> +.Ar file2
> +is
> +.Sq - ,
> +the standard input is
> +used in its place.
> +.Ss Output Style
> +The default (without
> +.Fl e ,
> +.Fl c ,
> +or
> +.Fl n
> +.\" -C
> +options)
> +output contains lines of these forms, where
> +.Va XX , YY , ZZ , QQ
> +are line numbers respective of file order.
> +.Pp
> +.Bl -tag -width "XX,YYcZZ,QQ" -compact
> +.It Li XX Ns Ic a Ns Li YY
> +At (the end of) line
> +.Va XX
> +of
> +.Ar file1 ,
> +append the contents
> +of line
> +.Va YY
> +of
> +.Ar file2
> +to make them equal.
> +.It Li XX Ns Ic a Ns Li YY,ZZ
> +Same as above, but append the range of lines,
> +.Va YY
> +through
> +.Va ZZ
> +of
> +.Ar file2
> +to line
> +.Va XX
> +of file1.
> +.It Li XX Ns Ic d Ns Li YY
> +At line
> +.Va XX
> +delete
> +the line.
> +The value
> +.Va YY
> +tells to which line the change would bring
> +.Ar file1
> +in line with
> +.Ar file2 .
> +.It Li XX,YY Ns Ic d Ns Li ZZ
> +Delete the range of lines
> +.Va XX
> +through
> +.Va YY
> +in
> +.Ar file1 .
> +.It Li XX Ns Ic c Ns Li YY
> +Change the line
> +.Va XX
> +in
> +.Ar file1
> +to the line
> +.Va YY
> +in
> +.Ar file2 .
> +.It Li XX,YY Ns Ic c Ns Li ZZ
> +Replace the range of specified lines with the line
> +.Va ZZ .
> +.It Li XX,YY Ns Ic c Ns Li ZZ,QQ
> +Replace the range
> +.Va XX , Ns Va YY
> +from
> +.Ar file1
> +with the range
> +.Va ZZ , Ns Va QQ
> +from
> +.Ar file2 .
> +.El
> +.Pp
> +These lines resemble
> +.Xr ed 1
> +subcommands to convert
> +.Ar file1
> +into
> +.Ar file2 .
> +The line numbers before the action letters pertain to
> +.Ar file1 ;
> +those after pertain to
> +.Ar file2 .
> +Thus, by exchanging
> +.Ic a
> +for
> +.Ic d
> +and reading the line in reverse order, one can also
> +determine how to convert
> +.Ar file2
> +into
> +.Ar file1 .
> +As in
> +.Xr ed 1 ,
> +identical
> +pairs (where num1 = num2) are abbreviated as a single
> +number.
> +.Sh FILES
> +.Bl -tag -width /tmp/diff.XXXXXXXX -compact
> +.It Pa /tmp/diff. Ns Ar XXXXXXXX
> +Temporary file used when comparing a device or the standard input.
> +Note that the temporary file is unlinked as soon as it is created
> +so it will not show up in a directory listing.
> +.El
> +.Sh EXIT STATUS
> +The
> +.Nm
> +utility exits with one of the following values:
> +.Pp
> +.Bl -tag -width Ds -offset indent -compact
> +.It 0
> +No differences were found.
> +.It 1
> +Differences were found.
> +.It >1
> +An error occurred.
> +.El
> +.Sh SEE ALSO
> +.Xr cmp 1 ,
> +.Xr comm 1 ,
> +.Xr diff3 1 ,
> +.Xr ed 1 ,
> +.Xr patch 1 ,
> +.Xr sdiff 1
> +.Rs
> +.%A James W. Hunt
> +.%A M. Douglas McIlroy
> +.%T "An Algorithm for Differential File Comparison"
> +.%J Computing Science Technical Report
> +.%Q Bell Laboratories 41
> +.%D June 1976
> +.Re
> +.Sh STANDARDS
> +The
> +.Nm
> +utility is compliant with the
> +.St -p1003.1-2008
> +specification.
> +.Pp
> +The flags
> +.Op Fl aDdIiLlNnPpqSsTtwXx
> +are extensions to that specification.
> +.Sh HISTORY
> +A
> +.Nm
> +command appeared in
> +.At v6 .
> 
> Added: head/usr.bin/diff/diff.c
> ==============================================================================
> --- /dev/null 00:00:00 1970   (empty, because file is newly added)
> +++ head/usr.bin/diff/diff.c  Sat Mar 11 05:01:29 2017        (r315051)
> @@ -0,0 +1,454 @@
> +/*   $OpenBSD: diff.c,v 1.65 2015/12/29 19:04:46 gsoares Exp $       */
> +
> +/*
> + * Copyright (c) 2003 Todd C. Miller <todd.mil...@courtesan.com>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + *
> + * Sponsored in part by the Defense Advanced Research Projects
> + * Agency (DARPA) and Air Force Research Laboratory, Air Force
> + * Materiel Command, USAF, under agreement number F39502-99-1-0512.
> + */
> +
> +#include <sys/cdefs.h>
> +__FBSDID("$FreeBSD$");
> +
> +#include <sys/stat.h>
> +
> +#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>
> +
> +#include "diff.h"
> +#include "xmalloc.h"
> +
> +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;
> +struct stat stb1, stb2;
> +struct excludes *excludes_list;
> +regex_t       ignore_re;
> +
> +#define      OPTIONS "0123456789aBbC:cdD:efhI:iL:lnNPpqrS:sTtU:uwX:x:"
> +enum {
> +     OPT_TSIZE = CHAR_MAX + 1,
> +     OPT_STRIPCR,
> +     OPT_IGN_FN_CASE,
> +     OPT_NO_IGN_FN_CASE,
> +     OPT_NORMAL,
> +};
> +
> +static struct option longopts[] = {
> +     { "text",                       no_argument,            0,      'a' },
> +     { "ignore-space-change",        no_argument,            0,      'b' },
> +     { "context",                    optional_argument,      0,      'C' },
> +     { "ifdef",                      required_argument,      0,      'D' },
> +     { "minimal",                    no_argument,            0,      'd' },
> +     { "ed",                         no_argument,            0,      'e' },
> +     { "forward-ed",                 no_argument,            0,      'f' },
> +     { "ignore-matching-lines",      required_argument,      0,      'I' },
> +     { "ignore-case",                no_argument,            0,      'i' },
> +     { "paginate",                   no_argument,            NULL,   'l' },
> +     { "label",                      required_argument,      0,      'L' },
> +     { "new-file",                   no_argument,            0,      'N' },
> +     { "rcs",                        no_argument,            0,      'n' },
> +     { "unidirectional-new-file",    no_argument,            0,      'P' },
> +     { "show-c-function",            no_argument,            0,      'p' },
> +     { "brief",                      no_argument,            0,      'q' },
> +     { "recursive",                  no_argument,            0,      'r' },
> +     { "report-identical-files",     no_argument,            0,      's' },
> +     { "starting-file",              required_argument,      0,      'S' },
> +     { "expand-tabs",                no_argument,            0,      't' },
> +     { "initial-tab",                no_argument,            0,      'T' },
> +     { "unified",                    optional_argument,      0,      'U' },
> +     { "ignore-all-space",           no_argument,            0,      'w' },
> +     { "exclude",                    required_argument,      0,      'x' },
> +     { "exclude-from",               required_argument,      0,      'X' },
> +     { "ignore-file-name-case",      no_argument,            NULL,   
> OPT_IGN_FN_CASE },
> +     { "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 },
> +     { NULL,                         0,                      0,      '\0'}
> +};
> +
> +void usage(void) __dead2;
> +void push_excludes(char *);
> +void push_ignore_pats(char *);
> +void read_excludes_file(char *file);
> +void set_argstr(char **, char **);
> +
> +int
> +main(int argc, char **argv)
> +{
> +     const char *errstr = NULL;
> +     char *ep, **oargv;
> +     long  l;
> +     int   ch, dflags, lastch, gotstdin, prevoptind, newarg;
> +
> +     oargv = argv;
> +     gotstdin = 0;
> +     dflags = 0;
> +     lastch = '\0';
> +     prevoptind = 1;
> +     newarg = 1;
> +     diff_context = 3;
> +     diff_format = 0;
> +     while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) {
> +             switch (ch) {
> +             case '0': case '1': case '2': case '3': case '4':
> +             case '5': case '6': case '7': case '8': case '9':
> +                     if (newarg)
> +                             usage();        /* disallow -[0-9]+ */
> +                     else if (lastch == 'c' || lastch == 'u')
> +                             diff_context = 0;
> +                     else if (!isdigit(lastch) || diff_context > INT_MAX / 
> 10)
> +                             usage();
> +                     diff_context = (diff_context * 10) + (ch - '0');
> +                     break;
> +             case 'a':
> +                     dflags |= D_FORCEASCII;
> +                     break;
> +             case 'b':
> +                     dflags |= D_FOLDBLANKS;
> +                     break;
> +             case 'C':
> +             case 'c':
> +                     cflag = 1;
> +                     diff_format = D_CONTEXT;
> +                     if (optarg != NULL) {
> +                             l = strtol(optarg, &ep, 10);
> +                             if (*ep != '\0' || l < 0 || l >= INT_MAX)
> +                                     usage();
> +                             diff_context = (int)l;
> +                     }
> +                     break;
> +             case 'd':
> +                     dflags |= D_MINIMAL;
> +                     break;
> +             case 'D':
> +                     diff_format = D_IFDEF;
> +                     ifdefname = optarg;
> +                     break;
> +             case 'e':
> +                     diff_format = D_EDIT;
> +                     break;
> +             case 'f':
> +                     diff_format = D_REVERSE;
> +                     break;
> +             case 'h':
> +                     /* silently ignore for backwards compatibility */
> +                     break;
> +             case 'I':
> +                     push_ignore_pats(optarg);
> +                     break;
> +             case 'i':
> +                     dflags |= D_IGNORECASE;
> +                     break;
> +             case 'L':
> +                     if (label[0] == NULL)
> +                             label[0] = optarg;
> +                     else if (label[1] == NULL)
> +                             label[1] = optarg;
> +                     else
> +                             usage();
> +                     break;
> +             case 'l':
> +                     lflag = 1;
> +                     break;
> +             case 'N':
> +                     Nflag = 1;
> +                     break;
> +             case 'n':
> +                     diff_format = D_NREVERSE;
> +                     break;
> +             case 'p':
> +                     if (diff_format == 0)
> +                             diff_format = D_CONTEXT;
> +                     dflags |= D_PROTOTYPE;
> +                     break;
> +             case 'P':
> +                     Pflag = 1;
> +                     break;
> +             case 'r':
> +                     rflag = 1;
> +                     break;
> +             case 'q':
> +                     diff_format = D_BRIEF;
> +                     break;
> +             case 'S':
> +                     start = optarg;
> +                     break;
> +             case 's':
> +                     sflag = 1;
> +                     break;
> +             case 'T':
> +                     Tflag = 1;
> +                     break;
> +             case 't':
> +                     dflags |= D_EXPANDTABS;
> +                     break;
> +             case 'U':
> +             case 'u':
> +                     diff_format = D_UNIFIED;
> +                     if (optarg != NULL) {
> +                             l = strtol(optarg, &ep, 10);
> +                             if (*ep != '\0' || l < 0 || l >= INT_MAX)
> +                                     usage();
> +                             diff_context = (int)l;
> +                     }
> +                     break;
> +             case 'w':
> +                     dflags |= D_IGNOREBLANKS;
> +                     break;
> +             case 'X':
> +                     read_excludes_file(optarg);
> +                     break;
> +             case 'x':
> +                     push_excludes(optarg);
> +                     break;
> +             case OPT_IGN_FN_CASE:
> +                     ignore_file_case = 1;
> +                     break;
> +             case OPT_NO_IGN_FN_CASE:
> +                     ignore_file_case = 0;
> +                     break;
> +             case OPT_NORMAL:
> +                     diff_format = D_NORMAL;
> +                     break;
> +             case OPT_TSIZE:
> +                     tabsize = (int) strtonum(optarg, 1, INT_MAX, &errstr);
> +                     if (errstr) {
> +                             warnx("Invalid argument for tabsize");
> +                             usage();
> +                     }
> +                     break;
> +             case OPT_STRIPCR:
> +                     dflags |= D_STRIPCR;
> +                     break;
> +             default:
> +                     usage();
> +                     break;
> +             }
> +             lastch = ch;
> +             newarg = optind != prevoptind;
> +             prevoptind = optind;
> +     }
> +     argc -= optind;
> +     argv += optind;
> +
> +#ifdef __OpenBSD__
> +     if (pledge("stdio rpath tmppath", NULL) == -1)
> +             err(2, "pledge");
> +#endif
> +
> +     /*
> +      * Do sanity checks, fill in stb1 and stb2 and call the appropriate
> +      * driver routine.  Both drivers use the contents of stb1 and stb2.
> +      */
> +     if (argc != 2)
> +             usage();
> +     if (ignore_pats != NULL) {
> +             char buf[BUFSIZ];
> +             int error;
> +
> +             if ((error = regcomp(&ignore_re, ignore_pats,
> +                                  REG_NEWLINE | REG_EXTENDED)) != 0) {
> +                     regerror(error, &ignore_re, buf, sizeof(buf));
> +                     if (*ignore_pats != '\0')
> +                             errx(2, "%s: %s", ignore_pats, buf);
> +                     else
> +                             errx(2, "%s", buf);
> +             }
> +     }
> +     if (strcmp(argv[0], "-") == 0) {
> +             fstat(STDIN_FILENO, &stb1);
> +             gotstdin = 1;
> +     } else if (stat(argv[0], &stb1) != 0)
> +             err(2, "%s", argv[0]);
> +     if (strcmp(argv[1], "-") == 0) {
> +             fstat(STDIN_FILENO, &stb2);
> +             gotstdin = 1;
> +     } else if (stat(argv[1], &stb2) != 0)
> +             err(2, "%s", argv[1]);
> +     if (gotstdin && (S_ISDIR(stb1.st_mode) || S_ISDIR(stb2.st_mode)))
> +             errx(2, "can't compare - to a directory");
> +     set_argstr(oargv, argv);
> +     if (S_ISDIR(stb1.st_mode) && S_ISDIR(stb2.st_mode)) {
> +             if (diff_format == D_IFDEF)
> +                     errx(2, "-D option not supported with directories");
> +             diffdir(argv[0], argv[1], dflags);
> +     } else {
> +             if (S_ISDIR(stb1.st_mode)) {
> +                     argv[0] = splice(argv[0], argv[1]);
> +                     if (stat(argv[0], &stb1) < 0)
> +                             err(2, "%s", argv[0]);
> +             }
> +             if (S_ISDIR(stb2.st_mode)) {
> +                     argv[1] = splice(argv[1], argv[0]);
> +                     if (stat(argv[1], &stb2) < 0)
> +                             err(2, "%s", argv[1]);
> +             }
> +             print_status(diffreg(argv[0], argv[1], dflags, 1), argv[0],
> +                 argv[1], "");
> +     }
> +     exit(status);
> +}
> +
> +void
> +set_argstr(char **av, char **ave)
> +{
> +     size_t argsize;
> +     char **ap;
> +
> +     argsize = 4 + *ave - *av + 1;
> +     diffargs = xmalloc(argsize);
> +     strlcpy(diffargs, "diff", argsize);
> +     for (ap = av + 1; ap < ave; ap++) {
> +             if (strcmp(*ap, "--") != 0) {
> +                     strlcat(diffargs, " ", argsize);
> +                     strlcat(diffargs, *ap, argsize);
> +             }
> +     }
> +}
> +
> +/*
> + * Read in an excludes file and push each line.
> + */
> +void
> +read_excludes_file(char *file)
> +{
> +     FILE *fp;
> +     char *buf, *pattern;
> +     size_t len;
> +
> +     if (strcmp(file, "-") == 0)
> +             fp = stdin;
> +     else if ((fp = fopen(file, "r")) == NULL)
> +             err(2, "%s", file);
> +     while ((buf = fgetln(fp, &len)) != NULL) {
> +             if (buf[len - 1] == '\n')
> +                     len--;
> +             pattern = xmalloc(len + 1);
> +             memcpy(pattern, buf, len);
> +             pattern[len] = '\0';
> +             push_excludes(pattern);
> +     }
> +     if (strcmp(file, "-") != 0)
> +             fclose(fp);
> +}
> +
> +/*
> + * Push a pattern onto the excludes list.
> + */
> +void
> +push_excludes(char *pattern)
> +{
> +     struct excludes *entry;
> +
> +     entry = xmalloc(sizeof(*entry));
> +     entry->pattern = pattern;
> +     entry->next = excludes_list;
> +     excludes_list = entry;
> +}
> +
> +void
> +push_ignore_pats(char *pattern)
> +{
> +     size_t len;
> +
> +     if (ignore_pats == NULL)
> +             ignore_pats = xstrdup(pattern);
> +     else {
> +             /* old + "|" + new + NUL */
> +             len = strlen(ignore_pats) + strlen(pattern) + 2;
> +             ignore_pats = xreallocarray(ignore_pats, 1, len);
> +             strlcat(ignore_pats, "|", len);
> +             strlcat(ignore_pats, pattern, len);
> +     }
> +}
> +
> +void
> +print_only(const char *path, size_t dirlen, const char *entry)
> +{
> +     if (dirlen > 1)
> +             dirlen--;
> +     printf("Only in %.*s: %s\n", (int)dirlen, path, entry);
> +}
> +
> +void
> +print_status(int val, char *path1, char *path2, const char *entry)
> +{
> +     switch (val) {
> +     case D_BINARY:
> +             printf("Binary files %s%s and %s%s differ\n",
> +                 path1, entry, path2, entry);
> +             break;
> +     case D_DIFFER:
> +             if (diff_format == D_BRIEF)
> 
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
> 
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to