svn commit: r315051 - in head: . gnu/usr.bin gnu/usr.bin/diff usr.bin usr.bin/diff usr.bin/diff/tests
Michal Meloun
melounmichal at gmail.com
Mon Mar 13 08:55:57 UTC 2017
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.Miller at 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 ***
>
More information about the svn-src-all
mailing list