MFC: diffutils 2.8.7.
This commit is contained in:
parent
5b61f61af0
commit
b6dce5eba4
@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@ -279,7 +279,7 @@ POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -305,14 +305,15 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
# $FreeBSD$
|
||||
Import of GNU diff 2.7
|
||||
|
||||
Original source available as ftp://prep.ai.mit.edu/pub/gnu/diffutils-2.7.tar.gz
|
||||
|
||||
The following files and directories were removed for this import:
|
||||
|
||||
Makefile.in
|
||||
INSTALL
|
||||
alloca.c
|
||||
cmp.c
|
||||
diff.info
|
||||
diff.info-1
|
||||
diff.info-2
|
||||
diff.info-3
|
||||
diff.info-4
|
||||
error.c
|
||||
fnmatch.c
|
||||
fnmatch.h
|
||||
memchr.c
|
||||
mkinstalldirs
|
||||
regex.c
|
||||
regex.h
|
||||
texinfo.tex
|
||||
waitpid.c
|
||||
getopt*
|
@ -1,198 +0,0 @@
|
||||
# Makefile for GNU DIFF
|
||||
# Copyright (C) 1988,1989,1991,1992,1993,1994 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is part of GNU DIFF.
|
||||
#
|
||||
# GNU DIFF is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# GNU DIFF is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GNU DIFF; see the file COPYING. If not, write to
|
||||
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
DEFS = @DEFS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
|
||||
# Some System V machines do not come with libPW.
|
||||
# If this is true for you, use the GNU alloca.o here.
|
||||
ALLOCA = @ALLOCA@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
edit_program_name = sed '@program_transform_name@'
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
|
||||
infodir = $(prefix)/info
|
||||
|
||||
DEFAULT_EDITOR_PROGRAM = ed
|
||||
DIFF_PROGRAM = $(bindir)/`echo diff | $(edit_program_name)`
|
||||
NULL_DEVICE = /dev/null
|
||||
PR_PROGRAM = /bin/pr
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# The source files for all of the programs.
|
||||
srcs=diff.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c normal.c ifdef.c \
|
||||
util.c dir.c memchr.c waitpid.c \
|
||||
version.c diff.h regex.c regex.h side.c system.h \
|
||||
diff3.c sdiff.c cmp.c error.c xmalloc.c getopt.c getopt1.c getopt.h \
|
||||
fnmatch.c fnmatch.h alloca.c
|
||||
distfiles = $(srcs) README INSTALL NEWS diagmeet.note Makefile.in \
|
||||
stamp-h.in config.hin configure configure.in COPYING ChangeLog \
|
||||
diff.texi diff.info* texinfo.tex \
|
||||
install-sh mkinstalldirs
|
||||
|
||||
PROGRAMS = cmp diff diff3 sdiff
|
||||
|
||||
all: $(PROGRAMS) info
|
||||
|
||||
COMPILE = $(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS)
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) $<
|
||||
|
||||
diff_o = diff.o analyze.o cmpbuf.o dir.o io.o util.o \
|
||||
context.o ed.o ifdef.o normal.o side.o \
|
||||
fnmatch.o getopt.o getopt1.o regex.o version.o $(ALLOCA) $(LIBOBJS)
|
||||
diff: $(diff_o)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(diff_o) $(LIBS)
|
||||
|
||||
diff3_o = diff3.o getopt.o getopt1.o version.o $(LIBOBJS)
|
||||
diff3: $(diff3_o)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(diff3_o) $(LIBS)
|
||||
|
||||
sdiff_o = sdiff.o getopt.o getopt1.o version.o $(LIBOBJS)
|
||||
sdiff: $(sdiff_o)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(sdiff_o) $(LIBS)
|
||||
|
||||
cmp_o = cmp.o cmpbuf.o error.o getopt.o getopt1.o xmalloc.o version.o $(LIBOBJS)
|
||||
cmp: $(cmp_o)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(cmp_o) $(LIBS)
|
||||
|
||||
info: diff.info
|
||||
diff.info: diff.texi
|
||||
$(MAKEINFO) $(srcdir)/diff.texi --output=$@
|
||||
|
||||
dvi: diff.dvi
|
||||
diff.dvi: diff.texi
|
||||
$(TEXI2DVI) $(srcdir)/diff.texi
|
||||
|
||||
$(diff_o): diff.h system.h
|
||||
cmp.o diff3.o sdiff.o: system.h
|
||||
context.o diff.o regex.o: regex.h
|
||||
cmp.o diff.o diff3.o sdiff.o getopt.o getopt1.o: getopt.h
|
||||
diff.o fnmatch.o: fnmatch.h
|
||||
analyze.o cmpbuf.o cmp.o: cmpbuf.h
|
||||
|
||||
cmp.o: cmp.c
|
||||
$(COMPILE) -DNULL_DEVICE=\"$(NULL_DEVICE)\" $(srcdir)/cmp.c
|
||||
|
||||
diff3.o: diff3.c
|
||||
$(COMPILE) -DDIFF_PROGRAM=\"$(DIFF_PROGRAM)\" $(srcdir)/diff3.c
|
||||
|
||||
sdiff.o: sdiff.c
|
||||
$(COMPILE) -DDEFAULT_EDITOR_PROGRAM=\"$(DEFAULT_EDITOR_PROGRAM)\" \
|
||||
-DDIFF_PROGRAM=\"$(DIFF_PROGRAM)\" $(srcdir)/sdiff.c
|
||||
|
||||
util.o: util.c
|
||||
$(COMPILE) -DPR_PROGRAM=\"$(PR_PROGRAM)\" $(srcdir)/util.c
|
||||
|
||||
TAGS: $(srcs)
|
||||
etags $(srcs)
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROGRAMS) core
|
||||
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.h config.log config.status stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS *.info*
|
||||
|
||||
install: all installdirs
|
||||
for p in $(PROGRAMS); do \
|
||||
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | $(edit_program_name)`; \
|
||||
done
|
||||
{ test -f diff.info || cd $(srcdir); } && \
|
||||
for f in diff.info*; do \
|
||||
$(INSTALL_DATA) $$f $(infodir)/$$f; \
|
||||
done
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
|
||||
|
||||
# We need more tests.
|
||||
check:
|
||||
./cmp cmp cmp
|
||||
./diff diff diff
|
||||
./diff3 diff3 diff3 diff3
|
||||
./sdiff sdiff sdiff
|
||||
|
||||
uninstall:
|
||||
for p in $(PROGRAMS); do \
|
||||
rm -f $(bindir)/`echo $$p | $(edit_program_name)`; \
|
||||
done
|
||||
rm -f $(infodir)/diff.info*
|
||||
|
||||
configure: configure.in
|
||||
cd $(srcdir) && autoconf
|
||||
|
||||
# autoheader might not change config.hin.
|
||||
config.hin: stamp-h.in
|
||||
stamp-h.in: configure.in
|
||||
cd $(srcdir) && autoheader
|
||||
date > $(srcdir)/stamp-h.in
|
||||
|
||||
config.status: configure
|
||||
./config.status --recheck
|
||||
|
||||
# config.status might not change config.h, but it changes stamp-h.
|
||||
config.h: stamp-h
|
||||
stamp-h: config.hin config.status
|
||||
./config.status
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status
|
||||
|
||||
dist: $(distfiles)
|
||||
echo diffutils-`sed -e '/version_string/!d' -e 's/[^0-9]*\([0-9a-z.]*\).*/\1/' -e q version.c` > .fname
|
||||
rm -rf `cat .fname`
|
||||
mkdir `cat .fname`
|
||||
-ln $(distfiles) `cat .fname`
|
||||
for file in $(distfiles); do \
|
||||
[ -r `cat .fname`/$$file ] || cp -p $$file `cat .fname` || exit; \
|
||||
done
|
||||
tar -chf - `cat .fname` | gzip >`cat .fname`.tar.gz
|
||||
rm -rf `cat .fname` .fname
|
||||
|
||||
# Prevent GNU make v3 from overflowing arg limit on SysV.
|
||||
.NOEXPORT:
|
@ -1,6 +1,102 @@
|
||||
Version 2.8.7 contains no user-visible changes.
|
||||
|
||||
User-visible changes in version 2.8.6:
|
||||
|
||||
* New diff3 option --strip-trailing-cr.
|
||||
|
||||
* With -N and -P, inaccessible empty regular files (the kind of files
|
||||
that 'patch' creates to indicate nonexistent backups) are now
|
||||
treated as nonexistent when they are in the 'backup' file position.
|
||||
|
||||
* If multiple SKIP values are given to cmp, e.g., `cmp -i 10 -i 20',
|
||||
cmp now uses the maximal value instead of the last one.
|
||||
|
||||
* diff now omits the ".000000000" on hosts that do not support
|
||||
fractional time stamps.
|
||||
|
||||
Version 2.8.5 was not publicly released.
|
||||
|
||||
User-visible changes in version 2.8.4:
|
||||
|
||||
* Diff now simply prints "Files A and B differ" instead of "Binary
|
||||
files A and B differ". The message is output if either A or B
|
||||
appears to be a binary file, and the old wording was misleading
|
||||
because it implied that both files are binary, which is not
|
||||
necessarily the case.
|
||||
|
||||
User-visible changes in version 2.8.3:
|
||||
|
||||
* New locale: en_US.
|
||||
|
||||
User-visible changes in version 2.8.2:
|
||||
|
||||
* New diff and sdiff option:
|
||||
--tabsize=COLUMNS
|
||||
* If --ignore-space-change or --ignore-all-space is also specified,
|
||||
--ignore-blank-lines now considers lines to be empty if they contain
|
||||
only white space.
|
||||
* More platforms now handle multibyte characters correctly when
|
||||
excluding files by name (diff -x and -X).
|
||||
* New locales: hu, pt_BR.
|
||||
|
||||
User-visible changes in version 2.8.1:
|
||||
|
||||
* Documentation fixes.
|
||||
|
||||
User-visible changes in version 2.8:
|
||||
|
||||
* cmp and diff now conform to POSIX 1003.1-2001 (IEEE Std 1003.1-2001)
|
||||
if the underlying system conforms to POSIX and if the _POSIX2_VERSION
|
||||
environment variable is set to 200112. Conformance removes support
|
||||
for `diff -NUM', where NUM is a number. Use -C NUM or -U NUM instead.
|
||||
* cmp now supports trailing operands SKIP1 and SKIP2, like BSD cmp.
|
||||
* cmp -i or --ignore-initial now accepts SKIP1:SKIP2 option value.
|
||||
* New cmp option: -n or --bytes.
|
||||
* cmp's old -c or --print-chars option has been renamed;
|
||||
use -b or --print-bytes instead.
|
||||
* cmp now outputs "byte" rather than "char" outside the POSIX locale.
|
||||
* cmp -l's index column width now adjusts to fit larger (or smaller) files.
|
||||
* cmp -l -s and cmp -s -l are not allowed. Use cmp -s or cmp -l instead.
|
||||
* diff uses ISO 8601 style time stamps for output times (e.g. "2001-11-23
|
||||
16:44:36.875702460 -0800") unless in the C or POSIX locale and the
|
||||
-c style is specified.
|
||||
* diff's -I and -F options use the regexp syntax of grep, not of Emacs.
|
||||
* diff now accepts multiple context arguments, and uses their maximum value.
|
||||
* New diff and sdiff options:
|
||||
-E --ignore-tab-expansion
|
||||
--strip-trailing-cr
|
||||
* New diff options:
|
||||
--from-file=FILE, --to-file=FILE
|
||||
--ignore-file-name-case
|
||||
--no-ignore-file-name-case
|
||||
* New diff3 and sdiff option:
|
||||
--diff-program=PROGRAM
|
||||
* The following diff options are still accepted, but are no longer documented.
|
||||
They may be withdrawn in future releases.
|
||||
-h (omit; it has no effect)
|
||||
-H (use --speed-large-files instead)
|
||||
-L (use --label instead)
|
||||
-P (use --unidirectional-new-file instead)
|
||||
--inhibit-hunk-merge (omit; it has no effect)
|
||||
* Recursive diffs now sort file names according to the LC_COLLATE locale
|
||||
category if possible, instead of using native byte comparison.
|
||||
* Recursive diffs now detect and report directory loops.
|
||||
* Diff printf specs can now use the "0" and "'" flags.
|
||||
* The new sdiff interactive command `ed' precedes each version with a header.
|
||||
* On 64-bit hosts, files larger than 2 GB can be compared.
|
||||
* Some internationalization support has been added, but multibyte locales
|
||||
are still not completely supported yet.
|
||||
* Some diagnostics have been reworded slightly for consistency.
|
||||
Also, `diff -D FOO' now outputs `/* ! FOO */' instead of `/* not FOO */'.
|
||||
* The `patch' part of the manual now describes `patch' version 2.5.4.
|
||||
* Man pages are now distributed and installed.
|
||||
* There is support for DJGPP; see the 'ms' subdirectory and the files
|
||||
m4/dos.m4 and */setmode.*.
|
||||
|
||||
|
||||
User-visible changes in version 2.7:
|
||||
|
||||
* New diff option: --binary (useful only on non-Posix hosts)
|
||||
* New diff option: --binary (useful only on non-POSIX hosts)
|
||||
* diff -b and -w now ignore line incompleteness; -B no longer does this.
|
||||
* cmp -c now uses locale to decide which output characters to quote.
|
||||
* Help and version messages are reorganized.
|
||||
@ -64,8 +160,8 @@ User-visible changes in version 2.4:
|
||||
* The format spec %0 introduced in version 2.1 has been removed, since it
|
||||
is incompatible with printf specs like %02d. To represent a null char,
|
||||
use %c'\0' instead.
|
||||
* cmp and diff now conform to Posix.2 (ISO/IEC 9945-2:1993)
|
||||
if the underlying system conforms to Posix:
|
||||
* cmp and diff now conform to POSIX 1003.2-1992 (ISO/IEC 9945-2:1993)
|
||||
if the underlying system conforms to POSIX:
|
||||
- Some messages' wordings are changed in minor ways.
|
||||
- ``White space'' is now whatever C's `isspace' says it is.
|
||||
- When comparing directories, if `diff' finds a file that is not a regular
|
||||
@ -124,3 +220,25 @@ User-visible changes in version 2.0:
|
||||
* Add long-named equivalents for other diff3 options.
|
||||
* diff options -F (--show-function-line) and -I (--ignore-matching-lines)
|
||||
can now be given more than once.
|
||||
|
||||
|
||||
|
||||
Copyright (C) 1993, 1994, 1998, 2001, 2002, 2004 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
This file is part of GNU Diffutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that they will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
@ -1,9 +1,69 @@
|
||||
README for GNU DIFF
|
||||
|
||||
This directory contains the GNU diff, diff3, sdiff, and cmp utilities.
|
||||
Their features are a superset of the Unix features and they are
|
||||
significantly faster. cmp has been moved here from the GNU textutils.
|
||||
significantly faster.
|
||||
|
||||
See the file COPYING for copying conditions.
|
||||
See the file diff.texi (or diff.info*) for documentation.
|
||||
See the file INSTALL for compilation and installation instructions.
|
||||
Please see the file COPYING for copying conditions.
|
||||
|
||||
Report bugs to bug-gnu-utils@prep.ai.mit.edu
|
||||
Please see the file doc/version.texi for version information.
|
||||
|
||||
Please see the file doc/diff.texi (or doc/diff.info) for documentation
|
||||
that can be printed with TeX, or read with the `info' program or with
|
||||
Emacs's `M-x info'. Brief man pages are in man/*, but they are no
|
||||
substitute for the documentation.
|
||||
|
||||
Please see the file ABOUT-NLS for notes about translations.
|
||||
|
||||
Please see the file INSTALL for generic compilation and installation
|
||||
instructions. Briefly, you can run "./configure; make install". The
|
||||
command "./configure --help" lists the supported --enable and --with
|
||||
options.
|
||||
|
||||
If you have a problem with internationalization, you might be able to
|
||||
work around it as described in ABOUT-NLS by invoking `./configure
|
||||
--disable-nls'. Many of the problems arise from dynamic linking
|
||||
issues on non-GNU platforms (e.g. with the iconv library). Such
|
||||
problems tend to be shared by other GNU applications on these
|
||||
platforms, and can usually be fixed by carefully tweaking your non-GNU
|
||||
installation. If you have an older version of libiconv, please
|
||||
upgrade to the latest one; see <ftp://ftp.gnu.org/gnu/libiconv/>. If
|
||||
the problem seems isolated to diffutils, though, please report a bug.
|
||||
|
||||
This program requires a Standard C compiler (C89 or later). If you
|
||||
have a nonstandard compiler, please install GCC first.
|
||||
|
||||
If you make changes to the source code, you may need appropriate
|
||||
versions of GNU build tools to regenerate the intermediate files. The
|
||||
following versions were used to generate the intermediate files in
|
||||
this distribution:
|
||||
|
||||
* Autoconf 2.59 <ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz>
|
||||
* Automake 1.8.3 <ftp://ftp.gnu.org/gnu/automake/automake-1.8.3.tar.gz>
|
||||
* gettext 0.14.1 <ftp://ftp.gnu.org/gnu/gettext/gettext-0.14.1.tar.gz>
|
||||
* help2man 1.33 <ftp://ftp.gnu.org/gnu/help2man/help2man-1.33.1.tar.gz>
|
||||
* Texinfo 4.7 <ftp://ftp.gnu.org/gnu/texinfo/texinfo-4.7.tar.gz>
|
||||
|
||||
Please report bugs to <bug-gnu-utils@gnu.org>.
|
||||
|
||||
-----
|
||||
|
||||
Copyright (C) 1992, 1998, 2001, 2002, 2004 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This file is part of GNU Diffutils.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,40 +0,0 @@
|
||||
/* Buffer primitives for comparison operations.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include "cmpbuf.h"
|
||||
|
||||
/* Least common multiple of two buffer sizes A and B. */
|
||||
|
||||
size_t
|
||||
buffer_lcm (a, b)
|
||||
size_t a, b;
|
||||
{
|
||||
size_t m, n, r;
|
||||
|
||||
/* Yield reasonable values if buffer sizes are zero. */
|
||||
if (!a)
|
||||
return b ? b : 8 * 1024;
|
||||
if (!b)
|
||||
return a;
|
||||
|
||||
/* n = gcd (a, b) */
|
||||
for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
|
||||
continue;
|
||||
|
||||
return a/n * b;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/* Buffer primitives for comparison operations.
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
size_t buffer_lcm PARAMS((size_t, size_t));
|
@ -1,118 +1,573 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.hin. Generated automatically from configure.in by autoheader. */
|
||||
/* config.h. Generated by configure. */
|
||||
/* config.hin. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
/* #undef C_ALLOCA */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||
systems. This function is required for `alloca.c' support on those systems.
|
||||
*/
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
/* Define to 1 if using `alloca.c'. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Name of editor program, unless overridden. */
|
||||
#define DEFAULT_EDITOR_PROGRAM "/usr/bin/vi"
|
||||
|
||||
/* Define the default level of POSIX conformance. The value is of the form
|
||||
YYYYMM, specifying the year and month the standard was adopted. If not
|
||||
defined here, it defaults to the value of _POSIX2_VERSION in <unistd.h>.
|
||||
Define to 199209 to default to POSIX 1003.2-1992, which makes standard
|
||||
programs like `head', `tail', and `sort' accept obsolete options like `+10'
|
||||
and `-10'. Define to 200112 to default to POSIX 1003.1-2001, which makes
|
||||
these standard programs treat leading-`+' operands as file names and
|
||||
require modern usages like `-n 10' instead of `-10'. Whether defined here
|
||||
or not, the default can be overridden at run time via the _POSIX2_VERSION
|
||||
environment variable. */
|
||||
/* #undef DEFAULT_POSIX2_VERSION */
|
||||
|
||||
/* Define to 1 if translation of program messages to the user's native
|
||||
language is requested. */
|
||||
#define ENABLE_NLS 0
|
||||
|
||||
/* Define on systems for which file names may have a so-called `drive letter'
|
||||
prefix, define this to compute the length of that prefix, including the
|
||||
colon. */
|
||||
#define FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0
|
||||
|
||||
/* Define if the backslash character may also serve as a file name component
|
||||
separator. */
|
||||
#define FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0
|
||||
|
||||
#if FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
|
||||
# define FILESYSTEM_PREFIX_LEN(Filename) \
|
||||
((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
|
||||
#else
|
||||
# define FILESYSTEM_PREFIX_LEN(Filename) 0
|
||||
#endif
|
||||
|
||||
/* Define if gettimeofday clobbers localtime's static buffer. */
|
||||
/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME_BUFFER */
|
||||
|
||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||
#define HAVE_ALLOCA 1
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
/* #undef HAVE_DOPRNT */
|
||||
/* Define to 1 if you have the `btowc' function. */
|
||||
#define HAVE_BTOWC 1
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#define HAVE_ST_BLKSIZE 1
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#define HAVE_CLOCK_GETTIME 1
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
/* Define to 1 if C supports variable-length arrays. */
|
||||
#define HAVE_C_VARARRAYS 1
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
/* #undef HAVE_DCGETTEXT */
|
||||
|
||||
/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_CLEARERR_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_FEOF_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FERROR_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FFLUSH_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FGETS_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FPUTC_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FPUTS_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FREAD_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_FWRITE_UNLOCKED 0
|
||||
|
||||
/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_GETCHAR_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `getcontext', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_GETCONTEXT 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_GETC_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
|
||||
*/
|
||||
#define HAVE_DECL_GETENV 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if
|
||||
you don't. */
|
||||
#define HAVE_DECL_PUTCHAR_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_PUTC_UNLOCKED 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `sigaltstack', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_SIGALTSTACK 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRTOIMAX 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRTOLL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRTOULL 1
|
||||
|
||||
/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you
|
||||
don't. */
|
||||
#define HAVE_DECL_STRTOUMAX 1
|
||||
|
||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define to 1 if you have the `dup2' function. */
|
||||
#define HAVE_DUP2 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `fork' function. */
|
||||
#define HAVE_FORK 1
|
||||
|
||||
/* Define to 1 if you have the `getcontext' function. */
|
||||
#define HAVE_GETCONTEXT 1
|
||||
|
||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
||||
/* #undef HAVE_GETTEXT */
|
||||
|
||||
/* Define to 1 if you have the `gettimeofday' function. */
|
||||
#define HAVE_GETTIMEOFDAY 1
|
||||
|
||||
/* Define if you have the iconv() function. */
|
||||
/* #undef HAVE_ICONV */
|
||||
|
||||
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
|
||||
#define HAVE_INTMAX_T 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
|
||||
declares uintmax_t. */
|
||||
#define HAVE_INTTYPES_H_WITH_UINTMAX 1
|
||||
|
||||
/* Define to 1 if you have the `isascii' function. */
|
||||
#define HAVE_ISASCII 1
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#define HAVE_LOCALE_H 1
|
||||
|
||||
/* Define if you have the 'long long' type. */
|
||||
#define HAVE_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the `mblen' function. */
|
||||
#define HAVE_MBLEN 1
|
||||
|
||||
/* Define to 1 if you have the `mbrlen' function. */
|
||||
#define HAVE_MBRLEN 1
|
||||
|
||||
/* Define to 1 if you have the `mbsrtowcs' function. */
|
||||
#define HAVE_MBSRTOWCS 1
|
||||
|
||||
/* Define to 1 if <wchar.h> declares mbstate_t. */
|
||||
#define HAVE_MBSTATE_T 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mempcpy' function. */
|
||||
/* #undef HAVE_MEMPCPY */
|
||||
|
||||
/* Define to 1 if you have the `mkstemp' function. */
|
||||
#define HAVE_MKSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
||||
and to 0 otherwise. */
|
||||
#define HAVE_REALLOC 1
|
||||
|
||||
/* Define to 1 if you have run the test for working tzset. */
|
||||
#define HAVE_RUN_TZSET_TEST 1
|
||||
|
||||
/* Define to 1 if you have the `setlocale' function. */
|
||||
#define HAVE_SETLOCALE 1
|
||||
|
||||
/* Define to 1 if you have the DOS-style `setmode' function. */
|
||||
/* #undef HAVE_SETMODE_DOS */
|
||||
|
||||
/* Define to 1 if you have the `setrlimit' function. */
|
||||
#define HAVE_SETRLIMIT 1
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
/* Define to 1 if you have the `sigaltstack' function. */
|
||||
#define HAVE_SIGALTSTACK 1
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
#define HAVE_SIGPROCMASK 1
|
||||
|
||||
/* Define to 1 if the system has the type `stack_t'. */
|
||||
#define HAVE_STACK_T 1
|
||||
|
||||
/* Define to 1 if stdbool.h conforms to C99. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
|
||||
uintmax_t. */
|
||||
#define HAVE_STDINT_H_WITH_UINTMAX 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecmp' function. */
|
||||
#define HAVE_STRCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strcasecoll' function. */
|
||||
/* #undef HAVE_STRCASECOLL */
|
||||
|
||||
/* Define to 1 if you have the `strerror_r' function. */
|
||||
#define HAVE_STRERROR_R 1
|
||||
|
||||
/* Define to 1 if you have the `strftime' function. */
|
||||
#define HAVE_STRFTIME 1
|
||||
|
||||
/* Define to 1 if you have the `stricoll' function. */
|
||||
/* #undef HAVE_STRICOLL */
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strncasecmp' function. */
|
||||
#define HAVE_STRNCASECMP 1
|
||||
|
||||
/* Define to 1 if you have the `strtoimax' function. */
|
||||
#define HAVE_STRTOIMAX 1
|
||||
|
||||
/* Define to 1 if you have the `strtol' function. */
|
||||
#define HAVE_STRTOL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoll' function. */
|
||||
#define HAVE_STRTOLL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoul' function. */
|
||||
#define HAVE_STRTOUL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoull' function. */
|
||||
#define HAVE_STRTOULL 1
|
||||
|
||||
/* Define to 1 if you have the `strtoumax' function. */
|
||||
#define HAVE_STRTOUMAX 1
|
||||
|
||||
/* Define to 1 if `sa_sigaction' is member of `struct sigaction'. */
|
||||
#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1
|
||||
|
||||
/* Define to 1 if `st_blksize' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
|
||||
|
||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
||||
|
||||
/* Define to 1 if `tm_zone' is member of `struct tm'. */
|
||||
#define HAVE_STRUCT_TM_TM_ZONE 1
|
||||
|
||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||
*/
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
||||
#define HAVE_SYS_RESOURCE_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define to 1 if localtime_r, etc. have the type signatures that POSIX
|
||||
requires. */
|
||||
#define HAVE_TIME_R_POSIX 1
|
||||
|
||||
/* Define if struct tm has the tm_gmtoff member. */
|
||||
#define HAVE_TM_GMTOFF 1
|
||||
|
||||
/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
|
||||
`HAVE_STRUCT_TM_TM_ZONE' instead. */
|
||||
#define HAVE_TM_ZONE 1
|
||||
|
||||
/* Define to 1 if you don't have `tm_zone' but do have the external array
|
||||
`tzname'. */
|
||||
/* #undef HAVE_TZNAME */
|
||||
|
||||
/* Define to 1 if you have the `tzset' function. */
|
||||
#define HAVE_TZSET 1
|
||||
|
||||
/* Define to 1 if you have the <ucontext.h> header file. */
|
||||
#define HAVE_UCONTEXT_H 1
|
||||
|
||||
/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
|
||||
#define HAVE_UINTMAX_T 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define if you have the 'unsigned long long' type. */
|
||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
||||
|
||||
/* Define to 1 if you have the `vfork' function. */
|
||||
#define HAVE_VFORK 1
|
||||
|
||||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
/* #undef HAVE_VFORK_H */
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#define HAVE_VPRINTF 1
|
||||
/* Define to 1 if you have the `waitpid' function. */
|
||||
#define HAVE_WAITPID 1
|
||||
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#define HAVE_WCHAR_H 1
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef pid_t */
|
||||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#define HAVE_WCTYPE_H 1
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
/* Define to 1 if you have the `wmempcpy' function. */
|
||||
/* #undef HAVE_WMEMPCPY */
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
/* Define to 1 if `fork' works. */
|
||||
#define HAVE_WORKING_FORK 1
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#define RETSIGTYPE void
|
||||
/* Define to 1 if `vfork' works. */
|
||||
#define HAVE_WORKING_VFORK 1
|
||||
|
||||
/* Define to 1 if extending the stack slightly past the limit causes a
|
||||
SIGSEGV, and an alternate stack can be established with sigaltstack, and
|
||||
the signal handler is passed a context that specifies the run time stack.
|
||||
This behavior is defined by POSIX 1003.1-2001 with the X/Open System
|
||||
Interface (XSI) option and is a standardized way to implement a SEGV-based
|
||||
stack overflow detection heuristic. */
|
||||
/* #undef HAVE_XSI_STACK_OVERFLOW_HEURISTIC */
|
||||
|
||||
/* Define to 1 if the system has the type `_Bool'. */
|
||||
#define HAVE__BOOL 1
|
||||
|
||||
/* Define to 1 if you have the `__secure_getenv' function. */
|
||||
/* #undef HAVE___SECURE_GETENV */
|
||||
|
||||
#if FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
|
||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
||||
#else
|
||||
# define ISSLASH(C) ((C) == '/')
|
||||
#endif
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "diffutils"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "bug-gnu-utils@gnu.org"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "GNU diffutils"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "GNU diffutils 2.8.7"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "diffutils"
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "2.8.7"
|
||||
|
||||
/* Name of "pr" program. */
|
||||
#define PR_PROGRAM "/usr/bin/pr"
|
||||
|
||||
/* Define to 1 to avoid alloca in the regular-expression implementation. */
|
||||
#define REGEX_MALLOC 1
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
/* #undef STACK_DIRECTION */
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* #undef STAT_MACROS_BROKEN */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if <sys/wait.h> is compatible with Posix applications. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
/* Define to 1 if strerror_r returns char *. */
|
||||
/* #undef STRERROR_R_CHAR_P */
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
/* Define to be the nanoseconds member of struct stat's st_mtim, if it exists.
|
||||
*/
|
||||
#define ST_MTIM_NSEC tv_nsec
|
||||
|
||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
||||
#define TIME_WITH_SYS_TIME 1
|
||||
|
||||
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||
/* #undef TM_IN_SYS_TIME */
|
||||
|
||||
/* Define if tzset clobbers localtime's static buffer. */
|
||||
/* #undef TZSET_CLOBBERS_LOCALTIME_BUFFER */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "2.8.7"
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
/* # undef _ALL_SOURCE */
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
/* #undef _POSIX_1_SOURCE */
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
/* #undef _POSIX_SOURCE */
|
||||
|
||||
/* Enable extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to a replacement function name for fnmatch(). */
|
||||
/* #undef fnmatch */
|
||||
|
||||
/* Define to rpl_gettimeofday if the replacement function should be used. */
|
||||
/* #undef gettimeofday */
|
||||
|
||||
/* Define to rpl_gmtime if the replacement function should be used. */
|
||||
/* #undef gmtime */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
/* #undef inline */
|
||||
#endif
|
||||
|
||||
/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
|
||||
/* #undef intmax_t */
|
||||
|
||||
/* Define to rpl_localtime if the replacement function should be used. */
|
||||
/* #undef localtime */
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to a type if <wchar.h> does not define. */
|
||||
/* #undef mbstate_t */
|
||||
|
||||
/* Define to rpl_mkstemp if the replacement function should be used. */
|
||||
/* #undef mkstemp */
|
||||
|
||||
/* Define to the name of the strftime replacement function. */
|
||||
#define my_strftime nstrftime
|
||||
|
||||
/* Define to `long' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
/* Define to rpl_realloc if the replacement function should be used. */
|
||||
/* #undef realloc */
|
||||
|
||||
/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
|
||||
supported. Do not define if restrict is supported directly. */
|
||||
#define restrict __restrict
|
||||
|
||||
/* Define to rpl_tzset if the wrapper function should be used. */
|
||||
/* #undef tzset */
|
||||
|
||||
/* Define to unsigned long or unsigned long long if <stdint.h> and
|
||||
<inttypes.h> don't define. */
|
||||
/* #undef uintmax_t */
|
||||
|
||||
/* Define as `fork' if `vfork' does not work. */
|
||||
/* #undef vfork */
|
||||
|
||||
/* Define if you have the dup2 function. */
|
||||
#define HAVE_DUP2 1
|
||||
|
||||
/* Define if you have the memchr function. */
|
||||
#define HAVE_MEMCHR 1
|
||||
|
||||
/* Define if you have the sigaction function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define if you have the tmpnam function. */
|
||||
#define HAVE_TMPNAM 1
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
@ -1,117 +0,0 @@
|
||||
/* config.hin. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef CLOSEDIR_VOID
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#undef HAVE_ST_BLKSIZE
|
||||
|
||||
/* Define if you have <vfork.h>. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define as the return type of signal handlers (int or void). */
|
||||
#undef RETSIGTYPE
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define if <sys/wait.h> is compatible with Posix applications. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
#undef vfork
|
||||
|
||||
/* Define if you have the dup2 function. */
|
||||
#undef HAVE_DUP2
|
||||
|
||||
/* Define if you have the memchr function. */
|
||||
#undef HAVE_MEMCHR
|
||||
|
||||
/* Define if you have the sigaction function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#undef HAVE_STRCHR
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the tmpnam function. */
|
||||
#undef HAVE_TMPNAM
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#undef HAVE_TIME_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
2149
contrib/diff/configure
vendored
2149
contrib/diff/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(diff.h)
|
||||
AC_CONFIG_HEADER(config.h:config.hin)
|
||||
AC_ARG_PROGRAM
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_ISC_POSIX
|
||||
AC_MINIX
|
||||
AC_C_CONST
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(unistd.h fcntl.h limits.h stdlib.h string.h sys/file.h time.h)
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STAT
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_SIGNAL
|
||||
AC_CHECK_FUNCS(dup2 memchr sigaction strchr strerror tmpnam)
|
||||
AC_REPLACE_FUNCS(memchr waitpid)
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
dnl No need for AC_FUNC_MEMCMP, since memcmp is used only to test for equality.
|
||||
AC_FUNC_VFORK
|
||||
AC_FUNC_VPRINTF
|
||||
AC_STRUCT_ST_BLKSIZE
|
||||
AC_OUTPUT(Makefile, [date > stamp-h])
|
@ -1,468 +0,0 @@
|
||||
/* Context-format output routines for GNU DIFF.
|
||||
Copyright (C) 1988,1989,1991,1992,1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
static struct change *find_hunk PARAMS((struct change *));
|
||||
static void find_function PARAMS((struct file_data const *, int, char const **, size_t *));
|
||||
static void mark_ignorable PARAMS((struct change *));
|
||||
static void pr_context_hunk PARAMS((struct change *));
|
||||
static void pr_unidiff_hunk PARAMS((struct change *));
|
||||
static void print_context_label PARAMS ((char const *, struct file_data *, char const *));
|
||||
static void print_context_number_range PARAMS((struct file_data const *, int, int));
|
||||
static void print_unidiff_number_range PARAMS((struct file_data const *, int, int));
|
||||
|
||||
/* Last place find_function started searching from. */
|
||||
static int find_function_last_search;
|
||||
|
||||
/* The value find_function returned when it started searching there. */
|
||||
static int find_function_last_match;
|
||||
|
||||
/* Print a label for a context diff, with a file name and date or a label. */
|
||||
|
||||
static void
|
||||
print_context_label (mark, inf, label)
|
||||
char const *mark;
|
||||
struct file_data *inf;
|
||||
char const *label;
|
||||
{
|
||||
if (label)
|
||||
fprintf (outfile, "%s %s\n", mark, label);
|
||||
else
|
||||
{
|
||||
char const *ct = ctime (&inf->stat.st_mtime);
|
||||
if (!ct)
|
||||
ct = "?\n";
|
||||
/* See Posix.2 section 4.17.6.1.4 for this format. */
|
||||
fprintf (outfile, "%s %s\t%s", mark, inf->name, ct);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a header for a context diff, with the file names and dates. */
|
||||
|
||||
void
|
||||
print_context_header (inf, unidiff_flag)
|
||||
struct file_data inf[];
|
||||
int unidiff_flag;
|
||||
{
|
||||
if (unidiff_flag)
|
||||
{
|
||||
print_context_label ("---", &inf[0], file_label[0]);
|
||||
print_context_label ("+++", &inf[1], file_label[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
print_context_label ("***", &inf[0], file_label[0]);
|
||||
print_context_label ("---", &inf[1], file_label[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print an edit script in context format. */
|
||||
|
||||
void
|
||||
print_context_script (script, unidiff_flag)
|
||||
struct change *script;
|
||||
int unidiff_flag;
|
||||
{
|
||||
if (ignore_blank_lines_flag || ignore_regexp_list)
|
||||
mark_ignorable (script);
|
||||
else
|
||||
{
|
||||
struct change *e;
|
||||
for (e = script; e; e = e->link)
|
||||
e->ignore = 0;
|
||||
}
|
||||
|
||||
find_function_last_search = - files[0].prefix_lines;
|
||||
find_function_last_match = find_function_last_search - 1;
|
||||
|
||||
if (unidiff_flag)
|
||||
print_script (script, find_hunk, pr_unidiff_hunk);
|
||||
else
|
||||
print_script (script, find_hunk, pr_context_hunk);
|
||||
}
|
||||
|
||||
/* Print a pair of line numbers with a comma, translated for file FILE.
|
||||
If the second number is not greater, use the first in place of it.
|
||||
|
||||
Args A and B are internal line numbers.
|
||||
We print the translated (real) line numbers. */
|
||||
|
||||
static void
|
||||
print_context_number_range (file, a, b)
|
||||
struct file_data const *file;
|
||||
int a, b;
|
||||
{
|
||||
int trans_a, trans_b;
|
||||
translate_range (file, a, b, &trans_a, &trans_b);
|
||||
|
||||
/* Note: we can have B < A in the case of a range of no lines.
|
||||
In this case, we should print the line number before the range,
|
||||
which is B. */
|
||||
if (trans_b > trans_a)
|
||||
fprintf (outfile, "%d,%d", trans_a, trans_b);
|
||||
else
|
||||
fprintf (outfile, "%d", trans_b);
|
||||
}
|
||||
|
||||
/* Print a portion of an edit script in context format.
|
||||
HUNK is the beginning of the portion to be printed.
|
||||
The end is marked by a `link' that has been nulled out.
|
||||
|
||||
Prints out lines from both files, and precedes each
|
||||
line with the appropriate flag-character. */
|
||||
|
||||
static void
|
||||
pr_context_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int first0, last0, first1, last1, show_from, show_to, i;
|
||||
struct change *next;
|
||||
char const *prefix;
|
||||
char const *function;
|
||||
size_t function_length;
|
||||
FILE *out;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
|
||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to);
|
||||
|
||||
if (!show_from && !show_to)
|
||||
return;
|
||||
|
||||
/* Include a context's width before and after. */
|
||||
|
||||
i = - files[0].prefix_lines;
|
||||
first0 = max (first0 - context, i);
|
||||
first1 = max (first1 - context, i);
|
||||
last0 = min (last0 + context, files[0].valid_lines - 1);
|
||||
last1 = min (last1 + context, files[1].valid_lines - 1);
|
||||
|
||||
/* If desired, find the preceding function definition line in file 0. */
|
||||
function = 0;
|
||||
if (function_regexp_list)
|
||||
find_function (&files[0], first0, &function, &function_length);
|
||||
|
||||
begin_output ();
|
||||
out = outfile;
|
||||
|
||||
/* If we looked for and found a function this is part of,
|
||||
include its name in the header of the diff section. */
|
||||
fprintf (out, "***************");
|
||||
|
||||
if (function)
|
||||
{
|
||||
fprintf (out, " ");
|
||||
fwrite (function, 1, min (function_length - 1, 40), out);
|
||||
}
|
||||
|
||||
fprintf (out, "\n*** ");
|
||||
print_context_number_range (&files[0], first0, last0);
|
||||
fprintf (out, " ****\n");
|
||||
|
||||
if (show_from)
|
||||
{
|
||||
next = hunk;
|
||||
|
||||
for (i = first0; i <= last0; i++)
|
||||
{
|
||||
/* Skip past changes that apply (in file 0)
|
||||
only to lines before line I. */
|
||||
|
||||
while (next && next->line0 + next->deleted <= i)
|
||||
next = next->link;
|
||||
|
||||
/* Compute the marking for line I. */
|
||||
|
||||
prefix = " ";
|
||||
if (next && next->line0 <= i)
|
||||
/* The change NEXT covers this line.
|
||||
If lines were inserted here in file 1, this is "changed".
|
||||
Otherwise it is "deleted". */
|
||||
prefix = (next->inserted > 0 ? "!" : "-");
|
||||
|
||||
print_1_line (prefix, &files[0].linbuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (out, "--- ");
|
||||
print_context_number_range (&files[1], first1, last1);
|
||||
fprintf (out, " ----\n");
|
||||
|
||||
if (show_to)
|
||||
{
|
||||
next = hunk;
|
||||
|
||||
for (i = first1; i <= last1; i++)
|
||||
{
|
||||
/* Skip past changes that apply (in file 1)
|
||||
only to lines before line I. */
|
||||
|
||||
while (next && next->line1 + next->inserted <= i)
|
||||
next = next->link;
|
||||
|
||||
/* Compute the marking for line I. */
|
||||
|
||||
prefix = " ";
|
||||
if (next && next->line1 <= i)
|
||||
/* The change NEXT covers this line.
|
||||
If lines were deleted here in file 0, this is "changed".
|
||||
Otherwise it is "inserted". */
|
||||
prefix = (next->deleted > 0 ? "!" : "+");
|
||||
|
||||
print_1_line (prefix, &files[1].linbuf[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a pair of line numbers with a comma, translated for file FILE.
|
||||
If the second number is smaller, use the first in place of it.
|
||||
If the numbers are equal, print just one number.
|
||||
|
||||
Args A and B are internal line numbers.
|
||||
We print the translated (real) line numbers. */
|
||||
|
||||
static void
|
||||
print_unidiff_number_range (file, a, b)
|
||||
struct file_data const *file;
|
||||
int a, b;
|
||||
{
|
||||
int trans_a, trans_b;
|
||||
translate_range (file, a, b, &trans_a, &trans_b);
|
||||
|
||||
/* Note: we can have B < A in the case of a range of no lines.
|
||||
In this case, we should print the line number before the range,
|
||||
which is B. */
|
||||
if (trans_b <= trans_a)
|
||||
fprintf (outfile, trans_b == trans_a ? "%d" : "%d,0", trans_b);
|
||||
else
|
||||
fprintf (outfile, "%d,%d", trans_a, trans_b - trans_a + 1);
|
||||
}
|
||||
|
||||
/* Print a portion of an edit script in unidiff format.
|
||||
HUNK is the beginning of the portion to be printed.
|
||||
The end is marked by a `link' that has been nulled out.
|
||||
|
||||
Prints out lines from both files, and precedes each
|
||||
line with the appropriate flag-character. */
|
||||
|
||||
static void
|
||||
pr_unidiff_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int first0, last0, first1, last1, show_from, show_to, i, j, k;
|
||||
struct change *next;
|
||||
char const *function;
|
||||
size_t function_length;
|
||||
FILE *out;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
|
||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to);
|
||||
|
||||
if (!show_from && !show_to)
|
||||
return;
|
||||
|
||||
/* Include a context's width before and after. */
|
||||
|
||||
i = - files[0].prefix_lines;
|
||||
first0 = max (first0 - context, i);
|
||||
first1 = max (first1 - context, i);
|
||||
last0 = min (last0 + context, files[0].valid_lines - 1);
|
||||
last1 = min (last1 + context, files[1].valid_lines - 1);
|
||||
|
||||
/* If desired, find the preceding function definition line in file 0. */
|
||||
function = 0;
|
||||
if (function_regexp_list)
|
||||
find_function (&files[0], first0, &function, &function_length);
|
||||
|
||||
begin_output ();
|
||||
out = outfile;
|
||||
|
||||
fprintf (out, "@@ -");
|
||||
print_unidiff_number_range (&files[0], first0, last0);
|
||||
fprintf (out, " +");
|
||||
print_unidiff_number_range (&files[1], first1, last1);
|
||||
fprintf (out, " @@");
|
||||
|
||||
/* If we looked for and found a function this is part of,
|
||||
include its name in the header of the diff section. */
|
||||
|
||||
if (function)
|
||||
{
|
||||
putc (' ', out);
|
||||
fwrite (function, 1, min (function_length - 1, 40), out);
|
||||
}
|
||||
putc ('\n', out);
|
||||
|
||||
next = hunk;
|
||||
i = first0;
|
||||
j = first1;
|
||||
|
||||
while (i <= last0 || j <= last1)
|
||||
{
|
||||
|
||||
/* If the line isn't a difference, output the context from file 0. */
|
||||
|
||||
if (!next || i < next->line0)
|
||||
{
|
||||
putc (tab_align_flag ? '\t' : ' ', out);
|
||||
print_1_line (0, &files[0].linbuf[i++]);
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For each difference, first output the deleted part. */
|
||||
|
||||
k = next->deleted;
|
||||
while (k--)
|
||||
{
|
||||
putc ('-', out);
|
||||
if (tab_align_flag)
|
||||
putc ('\t', out);
|
||||
print_1_line (0, &files[0].linbuf[i++]);
|
||||
}
|
||||
|
||||
/* Then output the inserted part. */
|
||||
|
||||
k = next->inserted;
|
||||
while (k--)
|
||||
{
|
||||
putc ('+', out);
|
||||
if (tab_align_flag)
|
||||
putc ('\t', out);
|
||||
print_1_line (0, &files[1].linbuf[j++]);
|
||||
}
|
||||
|
||||
/* We're done with this hunk, so on to the next! */
|
||||
|
||||
next = next->link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan a (forward-ordered) edit script for the first place that more than
|
||||
2*CONTEXT unchanged lines appear, and return a pointer
|
||||
to the `struct change' for the last change before those lines. */
|
||||
|
||||
static struct change *
|
||||
find_hunk (start)
|
||||
struct change *start;
|
||||
{
|
||||
struct change *prev;
|
||||
int top0, top1;
|
||||
int thresh;
|
||||
|
||||
do
|
||||
{
|
||||
/* Compute number of first line in each file beyond this changed. */
|
||||
top0 = start->line0 + start->deleted;
|
||||
top1 = start->line1 + start->inserted;
|
||||
prev = start;
|
||||
start = start->link;
|
||||
/* Threshold distance is 2*CONTEXT between two non-ignorable changes,
|
||||
but only CONTEXT if one is ignorable. */
|
||||
thresh = ((prev->ignore || (start && start->ignore))
|
||||
? context
|
||||
: 2 * context + 1);
|
||||
/* It is not supposed to matter which file we check in the end-test.
|
||||
If it would matter, crash. */
|
||||
if (start && start->line0 - top0 != start->line1 - top1)
|
||||
abort ();
|
||||
} while (start
|
||||
/* Keep going if less than THRESH lines
|
||||
elapse before the affected line. */
|
||||
&& start->line0 < top0 + thresh);
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* Set the `ignore' flag properly in each change in SCRIPT.
|
||||
It should be 1 if all the lines inserted or deleted in that change
|
||||
are ignorable lines. */
|
||||
|
||||
static void
|
||||
mark_ignorable (script)
|
||||
struct change *script;
|
||||
{
|
||||
while (script)
|
||||
{
|
||||
struct change *next = script->link;
|
||||
int first0, last0, first1, last1, deletes, inserts;
|
||||
|
||||
/* Turn this change into a hunk: detach it from the others. */
|
||||
script->link = 0;
|
||||
|
||||
/* Determine whether this change is ignorable. */
|
||||
analyze_hunk (script, &first0, &last0, &first1, &last1, &deletes, &inserts);
|
||||
/* Reconnect the chain as before. */
|
||||
script->link = next;
|
||||
|
||||
/* If the change is ignorable, mark it. */
|
||||
script->ignore = (!deletes && !inserts);
|
||||
|
||||
/* Advance to the following change. */
|
||||
script = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the last function-header line in FILE prior to line number LINENUM.
|
||||
This is a line containing a match for the regexp in `function_regexp'.
|
||||
Store the address of the line text into LINEP and the length of the
|
||||
line into LENP.
|
||||
Do not store anything if no function-header is found. */
|
||||
|
||||
static void
|
||||
find_function (file, linenum, linep, lenp)
|
||||
struct file_data const *file;
|
||||
int linenum;
|
||||
char const **linep;
|
||||
size_t *lenp;
|
||||
{
|
||||
int i = linenum;
|
||||
int last = find_function_last_search;
|
||||
find_function_last_search = i;
|
||||
|
||||
while (--i >= last)
|
||||
{
|
||||
/* See if this line is what we want. */
|
||||
struct regexp_list *r;
|
||||
char const *line = file->linbuf[i];
|
||||
size_t len = file->linbuf[i + 1] - line;
|
||||
|
||||
for (r = function_regexp_list; r; r = r->next)
|
||||
if (0 <= re_search (&r->buf, line, len, 0, len, 0))
|
||||
{
|
||||
*linep = line;
|
||||
*lenp = len;
|
||||
find_function_last_match = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* If we search back to where we started searching the previous time,
|
||||
find the line we found last time. */
|
||||
if (find_function_last_match >= - file->prefix_lines)
|
||||
{
|
||||
i = find_function_last_match;
|
||||
*linep = file->linbuf[i];
|
||||
*lenp = file->linbuf[i + 1] - *linep;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
Here is a comparison matrix which shows a case in which
|
||||
it is possible for the forward and backward scan in `diag'
|
||||
to meet along a nonzero length of diagonal simultaneous
|
||||
(so that bdiag[d] and fdiag[d] are not equal)
|
||||
even though there is no snake on that diagonal at the meeting point.
|
||||
|
||||
|
||||
85 1 1 1 159 1 1 17
|
||||
1 2 3 4
|
||||
60
|
||||
1 2
|
||||
1
|
||||
2 2 3 4
|
||||
71
|
||||
3 3 4 5
|
||||
85
|
||||
4 3 4 5
|
||||
17
|
||||
5 4 5
|
||||
1
|
||||
6 4 5 6
|
||||
183
|
||||
7 5 6 7
|
||||
10
|
||||
8 6 7
|
||||
1
|
||||
9 6 7 8
|
||||
12
|
||||
7 8 9 10
|
||||
13
|
||||
10 8 9 10
|
||||
14
|
||||
10 9 10
|
||||
17
|
||||
10 10
|
||||
1
|
||||
10 9 10
|
||||
1
|
||||
8 10 10 10
|
||||
183
|
||||
8 7 9 9 9
|
||||
10
|
||||
7 6 8 9 8 8
|
||||
1
|
||||
6 5 7 7
|
||||
1
|
||||
5 6 6
|
||||
1
|
||||
5 5 5
|
||||
50
|
||||
5 4 4 4
|
||||
1
|
||||
4 3 3
|
||||
85
|
||||
5 4 3 2 2
|
||||
1
|
||||
2 1
|
||||
17
|
||||
5 4 3 2 1 1
|
||||
1
|
||||
1 0
|
||||
85 1 1 1 159 1 1 17
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1121
contrib/diff/diff.c
1121
contrib/diff/diff.c
File diff suppressed because it is too large
Load Diff
@ -1,341 +0,0 @@
|
||||
/* Shared definitions for GNU DIFF
|
||||
Copyright (C) 1988, 89, 91, 92, 93 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include "regex.h"
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
/* Variables for command line options */
|
||||
|
||||
#ifndef GDIFF_MAIN
|
||||
#define EXTERN extern
|
||||
#else
|
||||
#define EXTERN
|
||||
#endif
|
||||
|
||||
enum output_style {
|
||||
/* Default output style. */
|
||||
OUTPUT_NORMAL,
|
||||
/* Output the differences with lines of context before and after (-c). */
|
||||
OUTPUT_CONTEXT,
|
||||
/* Output the differences in a unified context diff format (-u). */
|
||||
OUTPUT_UNIFIED,
|
||||
/* Output the differences as commands suitable for `ed' (-e). */
|
||||
OUTPUT_ED,
|
||||
/* Output the diff as a forward ed script (-f). */
|
||||
OUTPUT_FORWARD_ED,
|
||||
/* Like -f, but output a count of changed lines in each "command" (-n). */
|
||||
OUTPUT_RCS,
|
||||
/* Output merged #ifdef'd file (-D). */
|
||||
OUTPUT_IFDEF,
|
||||
/* Output sdiff style (-y). */
|
||||
OUTPUT_SDIFF
|
||||
};
|
||||
|
||||
/* True for output styles that are robust,
|
||||
i.e. can handle a file that ends in a non-newline. */
|
||||
#define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
|
||||
|
||||
EXTERN enum output_style output_style;
|
||||
|
||||
/* Nonzero if output cannot be generated for identical files. */
|
||||
EXTERN int no_diff_means_no_output;
|
||||
|
||||
/* Number of lines of context to show in each set of diffs.
|
||||
This is zero when context is not to be shown. */
|
||||
EXTERN int context;
|
||||
|
||||
/* Consider all files as text files (-a).
|
||||
Don't interpret codes over 0177 as implying a "binary file". */
|
||||
EXTERN int always_text_flag;
|
||||
|
||||
/* Number of lines to keep in identical prefix and suffix. */
|
||||
EXTERN int horizon_lines;
|
||||
|
||||
/* Ignore changes in horizontal white space (-b). */
|
||||
EXTERN int ignore_space_change_flag;
|
||||
|
||||
/* Ignore all horizontal white space (-w). */
|
||||
EXTERN int ignore_all_space_flag;
|
||||
|
||||
/* Ignore changes that affect only blank lines (-B). */
|
||||
EXTERN int ignore_blank_lines_flag;
|
||||
|
||||
/* 1 if lines may match even if their contents do not match exactly.
|
||||
This depends on various options. */
|
||||
EXTERN int ignore_some_line_changes;
|
||||
|
||||
/* 1 if files may match even if their contents are not byte-for-byte identical.
|
||||
This depends on various options. */
|
||||
EXTERN int ignore_some_changes;
|
||||
|
||||
/* Ignore differences in case of letters (-i). */
|
||||
EXTERN int ignore_case_flag;
|
||||
|
||||
/* File labels for `-c' output headers (-L). */
|
||||
EXTERN char *file_label[2];
|
||||
|
||||
struct regexp_list
|
||||
{
|
||||
struct re_pattern_buffer buf;
|
||||
struct regexp_list *next;
|
||||
};
|
||||
|
||||
/* Regexp to identify function-header lines (-F). */
|
||||
EXTERN struct regexp_list *function_regexp_list;
|
||||
|
||||
/* Ignore changes that affect only lines matching this regexp (-I). */
|
||||
EXTERN struct regexp_list *ignore_regexp_list;
|
||||
|
||||
/* Say only whether files differ, not how (-q). */
|
||||
EXTERN int no_details_flag;
|
||||
|
||||
/* Report files compared that match (-s).
|
||||
Normally nothing is output when that happens. */
|
||||
EXTERN int print_file_same_flag;
|
||||
|
||||
/* Output the differences with exactly 8 columns added to each line
|
||||
so that any tabs in the text line up properly (-T). */
|
||||
EXTERN int tab_align_flag;
|
||||
|
||||
/* Expand tabs in the output so the text lines up properly
|
||||
despite the characters added to the front of each line (-t). */
|
||||
EXTERN int tab_expand_flag;
|
||||
|
||||
/* In directory comparison, specify file to start with (-S).
|
||||
All file names less than this name are ignored. */
|
||||
EXTERN char *dir_start_file;
|
||||
|
||||
/* If a file is new (appears in only one dir)
|
||||
include its entire contents (-N).
|
||||
Then `patch' would create the file with appropriate contents. */
|
||||
EXTERN int entire_new_file_flag;
|
||||
|
||||
/* If a file is new (appears in only the second dir)
|
||||
include its entire contents (-P).
|
||||
Then `patch' would create the file with appropriate contents. */
|
||||
EXTERN int unidirectional_new_file_flag;
|
||||
|
||||
/* Pipe each file's output through pr (-l). */
|
||||
EXTERN int paginate_flag;
|
||||
|
||||
enum line_class {
|
||||
/* Lines taken from just the first file. */
|
||||
OLD,
|
||||
/* Lines taken from just the second file. */
|
||||
NEW,
|
||||
/* Lines common to both files. */
|
||||
UNCHANGED,
|
||||
/* A hunk containing both old and new lines (line groups only). */
|
||||
CHANGED
|
||||
};
|
||||
|
||||
/* Line group formats for old, new, unchanged, and changed groups. */
|
||||
EXTERN char *group_format[CHANGED + 1];
|
||||
|
||||
/* Line formats for old, new, and unchanged lines. */
|
||||
EXTERN char *line_format[UNCHANGED + 1];
|
||||
|
||||
/* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
|
||||
EXTERN int sdiff_help_sdiff;
|
||||
|
||||
/* Tell OUTPUT_SDIFF to show only the left version of common lines. */
|
||||
EXTERN int sdiff_left_only;
|
||||
|
||||
/* Tell OUTPUT_SDIFF to not show common lines. */
|
||||
EXTERN int sdiff_skip_common_lines;
|
||||
|
||||
/* The half line width and column 2 offset for OUTPUT_SDIFF. */
|
||||
EXTERN unsigned sdiff_half_width;
|
||||
EXTERN unsigned sdiff_column2_offset;
|
||||
|
||||
/* String containing all the command options diff received,
|
||||
with spaces between and at the beginning but none at the end.
|
||||
If there were no options given, this string is empty. */
|
||||
EXTERN char * switch_string;
|
||||
|
||||
/* Nonzero means use heuristics for better speed. */
|
||||
EXTERN int heuristic;
|
||||
|
||||
/* Name of program the user invoked (for error messages). */
|
||||
EXTERN char *program_name;
|
||||
|
||||
/* The result of comparison is an "edit script": a chain of `struct change'.
|
||||
Each `struct change' represents one place where some lines are deleted
|
||||
and some are inserted.
|
||||
|
||||
LINE0 and LINE1 are the first affected lines in the two files (origin 0).
|
||||
DELETED is the number of lines deleted here from file 0.
|
||||
INSERTED is the number of lines inserted here in file 1.
|
||||
|
||||
If DELETED is 0 then LINE0 is the number of the line before
|
||||
which the insertion was done; vice versa for INSERTED and LINE1. */
|
||||
|
||||
struct change
|
||||
{
|
||||
struct change *link; /* Previous or next edit command */
|
||||
int inserted; /* # lines of file 1 changed here. */
|
||||
int deleted; /* # lines of file 0 changed here. */
|
||||
int line0; /* Line number of 1st deleted line. */
|
||||
int line1; /* Line number of 1st inserted line. */
|
||||
char ignore; /* Flag used in context.c */
|
||||
};
|
||||
|
||||
/* Structures that describe the input files. */
|
||||
|
||||
/* Data on one input file being compared. */
|
||||
|
||||
struct file_data {
|
||||
int desc; /* File descriptor */
|
||||
char const *name; /* File name */
|
||||
struct stat stat; /* File status from fstat() */
|
||||
int dir_p; /* nonzero if file is a directory */
|
||||
|
||||
/* Buffer in which text of file is read. */
|
||||
char * buffer;
|
||||
/* Allocated size of buffer. */
|
||||
size_t bufsize;
|
||||
/* Number of valid characters now in the buffer. */
|
||||
size_t buffered_chars;
|
||||
|
||||
/* Array of pointers to lines in the file. */
|
||||
char const **linbuf;
|
||||
|
||||
/* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
|
||||
linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
|
||||
linebuf[linbuf_base ... valid_lines - 1] contain valid data.
|
||||
linebuf[linbuf_base ... alloc_lines - 1] are allocated. */
|
||||
int linbuf_base, buffered_lines, valid_lines, alloc_lines;
|
||||
|
||||
/* Pointer to end of prefix of this file to ignore when hashing. */
|
||||
char const *prefix_end;
|
||||
|
||||
/* Count of lines in the prefix.
|
||||
There are this many lines in the file before linbuf[0]. */
|
||||
int prefix_lines;
|
||||
|
||||
/* Pointer to start of suffix of this file to ignore when hashing. */
|
||||
char const *suffix_begin;
|
||||
|
||||
/* Vector, indexed by line number, containing an equivalence code for
|
||||
each line. It is this vector that is actually compared with that
|
||||
of another file to generate differences. */
|
||||
int *equivs;
|
||||
|
||||
/* Vector, like the previous one except that
|
||||
the elements for discarded lines have been squeezed out. */
|
||||
int *undiscarded;
|
||||
|
||||
/* Vector mapping virtual line numbers (not counting discarded lines)
|
||||
to real ones (counting those lines). Both are origin-0. */
|
||||
int *realindexes;
|
||||
|
||||
/* Total number of nondiscarded lines. */
|
||||
int nondiscarded_lines;
|
||||
|
||||
/* Vector, indexed by real origin-0 line number,
|
||||
containing 1 for a line that is an insertion or a deletion.
|
||||
The results of comparison are stored here. */
|
||||
char *changed_flag;
|
||||
|
||||
/* 1 if file ends in a line with no final newline. */
|
||||
int missing_newline;
|
||||
|
||||
/* 1 more than the maximum equivalence value used for this or its
|
||||
sibling file. */
|
||||
int equiv_max;
|
||||
};
|
||||
|
||||
/* Describe the two files currently being compared. */
|
||||
|
||||
EXTERN struct file_data files[2];
|
||||
|
||||
/* Stdio stream to output diffs to. */
|
||||
|
||||
EXTERN FILE *outfile;
|
||||
|
||||
/* Declare various functions. */
|
||||
|
||||
/* analyze.c */
|
||||
int diff_2_files PARAMS((struct file_data[], int));
|
||||
|
||||
/* context.c */
|
||||
void print_context_header PARAMS((struct file_data[], int));
|
||||
void print_context_script PARAMS((struct change *, int));
|
||||
|
||||
/* diff.c */
|
||||
int excluded_filename PARAMS((char const *));
|
||||
|
||||
/* dir.c */
|
||||
int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int));
|
||||
|
||||
/* ed.c */
|
||||
void print_ed_script PARAMS((struct change *));
|
||||
void pr_forward_ed_script PARAMS((struct change *));
|
||||
|
||||
/* ifdef.c */
|
||||
void print_ifdef_script PARAMS((struct change *));
|
||||
|
||||
/* io.c */
|
||||
int read_files PARAMS((struct file_data[], int));
|
||||
int sip PARAMS((struct file_data *, int));
|
||||
void slurp PARAMS((struct file_data *));
|
||||
|
||||
/* normal.c */
|
||||
void print_normal_script PARAMS((struct change *));
|
||||
|
||||
/* rcs.c */
|
||||
void print_rcs_script PARAMS((struct change *));
|
||||
|
||||
/* side.c */
|
||||
void print_sdiff_script PARAMS((struct change *));
|
||||
|
||||
/* util.c */
|
||||
VOID *xmalloc PARAMS((size_t));
|
||||
VOID *xrealloc PARAMS((VOID *, size_t));
|
||||
char *concat PARAMS((char const *, char const *, char const *));
|
||||
char *dir_file_pathname PARAMS((char const *, char const *));
|
||||
int change_letter PARAMS((int, int));
|
||||
int line_cmp PARAMS((char const *, char const *));
|
||||
int translate_line_number PARAMS((struct file_data const *, int));
|
||||
struct change *find_change PARAMS((struct change *));
|
||||
struct change *find_reverse_change PARAMS((struct change *));
|
||||
void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *));
|
||||
void begin_output PARAMS((void));
|
||||
void debug_script PARAMS((struct change *));
|
||||
void error PARAMS((char const *, char const *, char const *));
|
||||
void fatal PARAMS((char const *));
|
||||
void finish_output PARAMS((void));
|
||||
void message PARAMS((char const *, char const *, char const *));
|
||||
void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
|
||||
void output_1_line PARAMS((char const *, char const *, char const *, char const *));
|
||||
void perror_with_name PARAMS((char const *));
|
||||
void pfatal_with_name PARAMS((char const *));
|
||||
void print_1_line PARAMS((char const *, char const * const *));
|
||||
void print_message_queue PARAMS((void));
|
||||
void print_number_range PARAMS((int, struct file_data *, int, int));
|
||||
void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *))));
|
||||
void setup_output PARAMS((char const *, char const *, int));
|
||||
void translate_range PARAMS((struct file_data const *, int, int, int *, int *));
|
||||
|
||||
/* version.c */
|
||||
extern char const version_string[];
|
File diff suppressed because it is too large
Load Diff
1778
contrib/diff/diff3.c
1778
contrib/diff/diff3.c
File diff suppressed because it is too large
Load Diff
@ -1,216 +0,0 @@
|
||||
/* Read, sort and compare two directories. Used for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
/* Read the directory named by DIR and store into DIRDATA a sorted vector
|
||||
of filenames for its contents. DIR->desc == -1 means this directory is
|
||||
known to be nonexistent, so set DIRDATA to an empty vector.
|
||||
Return -1 (setting errno) if error, 0 otherwise. */
|
||||
|
||||
struct dirdata
|
||||
{
|
||||
char const **names; /* Sorted names of files in dir, 0-terminated. */
|
||||
char *data; /* Allocated storage for file names. */
|
||||
};
|
||||
|
||||
static int compare_names PARAMS((void const *, void const *));
|
||||
static int dir_sort PARAMS((struct file_data const *, struct dirdata *));
|
||||
|
||||
static int
|
||||
dir_sort (dir, dirdata)
|
||||
struct file_data const *dir;
|
||||
struct dirdata *dirdata;
|
||||
{
|
||||
register struct dirent *next;
|
||||
register int i;
|
||||
|
||||
/* Address of block containing the files that are described. */
|
||||
char const **names;
|
||||
|
||||
/* Number of files in directory. */
|
||||
size_t nnames;
|
||||
|
||||
/* Allocated and used storage for file name data. */
|
||||
char *data;
|
||||
size_t data_alloc, data_used;
|
||||
|
||||
dirdata->names = 0;
|
||||
dirdata->data = 0;
|
||||
nnames = 0;
|
||||
data = 0;
|
||||
|
||||
if (dir->desc != -1)
|
||||
{
|
||||
/* Open the directory and check for errors. */
|
||||
register DIR *reading = opendir (dir->name);
|
||||
if (!reading)
|
||||
return -1;
|
||||
|
||||
/* Initialize the table of filenames. */
|
||||
|
||||
data_alloc = max (1, (size_t) dir->stat.st_size);
|
||||
data_used = 0;
|
||||
dirdata->data = data = xmalloc (data_alloc);
|
||||
|
||||
/* Read the directory entries, and insert the subfiles
|
||||
into the `data' table. */
|
||||
|
||||
while ((errno = 0, (next = readdir (reading)) != 0))
|
||||
{
|
||||
char *d_name = next->d_name;
|
||||
size_t d_size = NAMLEN (next) + 1;
|
||||
|
||||
/* Ignore the files `.' and `..' */
|
||||
if (d_name[0] == '.'
|
||||
&& (d_name[1] == 0 || (d_name[1] == '.' && d_name[2] == 0)))
|
||||
continue;
|
||||
|
||||
if (excluded_filename (d_name))
|
||||
continue;
|
||||
|
||||
while (data_alloc < data_used + d_size)
|
||||
dirdata->data = data = xrealloc (data, data_alloc *= 2);
|
||||
memcpy (data + data_used, d_name, d_size);
|
||||
data_used += d_size;
|
||||
nnames++;
|
||||
}
|
||||
if (errno)
|
||||
{
|
||||
int e = errno;
|
||||
closedir (reading);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
#if CLOSEDIR_VOID
|
||||
closedir (reading);
|
||||
#else
|
||||
if (closedir (reading) != 0)
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Create the `names' table from the `data' table. */
|
||||
dirdata->names = names = (char const **) xmalloc (sizeof (char *)
|
||||
* (nnames + 1));
|
||||
for (i = 0; i < nnames; i++)
|
||||
{
|
||||
names[i] = data;
|
||||
data += strlen (data) + 1;
|
||||
}
|
||||
names[nnames] = 0;
|
||||
|
||||
/* Sort the table. */
|
||||
qsort (names, nnames, sizeof (char *), compare_names);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sort the files now in the table. */
|
||||
|
||||
static int
|
||||
compare_names (file1, file2)
|
||||
void const *file1, *file2;
|
||||
{
|
||||
return filename_cmp (* (char const *const *) file1,
|
||||
* (char const *const *) file2);
|
||||
}
|
||||
|
||||
/* Compare the contents of two directories named in FILEVEC[0] and FILEVEC[1].
|
||||
This is a top-level routine; it does everything necessary for diff
|
||||
on two directories.
|
||||
|
||||
FILEVEC[0].desc == -1 says directory FILEVEC[0] doesn't exist,
|
||||
but pretend it is empty. Likewise for FILEVEC[1].
|
||||
|
||||
HANDLE_FILE is a caller-provided subroutine called to handle each file.
|
||||
It gets five operands: dir and name (rel to original working dir) of file
|
||||
in dir 0, dir and name pathname of file in dir 1, and the recursion depth.
|
||||
|
||||
For a file that appears in only one of the dirs, one of the name-args
|
||||
to HANDLE_FILE is zero.
|
||||
|
||||
DEPTH is the current depth in recursion, used for skipping top-level
|
||||
files by the -S option.
|
||||
|
||||
Returns the maximum of all the values returned by HANDLE_FILE,
|
||||
or 2 if trouble is encountered in opening files. */
|
||||
|
||||
int
|
||||
diff_dirs (filevec, handle_file, depth)
|
||||
struct file_data const filevec[];
|
||||
int (*handle_file) PARAMS((char const *, char const *, char const *, char const *, int));
|
||||
int depth;
|
||||
{
|
||||
struct dirdata dirdata[2];
|
||||
int val = 0; /* Return value. */
|
||||
int i;
|
||||
|
||||
/* Get sorted contents of both dirs. */
|
||||
for (i = 0; i < 2; i++)
|
||||
if (dir_sort (&filevec[i], &dirdata[i]) != 0)
|
||||
{
|
||||
perror_with_name (filevec[i].name);
|
||||
val = 2;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
register char const * const *names0 = dirdata[0].names;
|
||||
register char const * const *names1 = dirdata[1].names;
|
||||
char const *name0 = filevec[0].name;
|
||||
char const *name1 = filevec[1].name;
|
||||
|
||||
/* If `-S name' was given, and this is the topmost level of comparison,
|
||||
ignore all file names less than the specified starting name. */
|
||||
|
||||
if (dir_start_file && depth == 0)
|
||||
{
|
||||
while (*names0 && filename_cmp (*names0, dir_start_file) < 0)
|
||||
names0++;
|
||||
while (*names1 && filename_cmp (*names1, dir_start_file) < 0)
|
||||
names1++;
|
||||
}
|
||||
|
||||
/* Loop while files remain in one or both dirs. */
|
||||
while (*names0 || *names1)
|
||||
{
|
||||
/* Compare next name in dir 0 with next name in dir 1.
|
||||
At the end of a dir,
|
||||
pretend the "next name" in that dir is very large. */
|
||||
int nameorder = (!*names0 ? 1 : !*names1 ? -1
|
||||
: filename_cmp (*names0, *names1));
|
||||
int v1 = (*handle_file) (name0, 0 < nameorder ? 0 : *names0++,
|
||||
name1, nameorder < 0 ? 0 : *names1++,
|
||||
depth + 1);
|
||||
if (v1 > val)
|
||||
val = v1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
if (dirdata[i].names)
|
||||
free (dirdata[i].names);
|
||||
if (dirdata[i].data)
|
||||
free (dirdata[i].data);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
@ -1,200 +0,0 @@
|
||||
/* Output routines for ed-script format.
|
||||
Copyright (C) 1988, 89, 91, 92, 93 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
static void print_ed_hunk PARAMS((struct change *));
|
||||
static void print_rcs_hunk PARAMS((struct change *));
|
||||
static void pr_forward_ed_hunk PARAMS((struct change *));
|
||||
|
||||
/* Print our script as ed commands. */
|
||||
|
||||
void
|
||||
print_ed_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
print_script (script, find_reverse_change, print_ed_hunk);
|
||||
}
|
||||
|
||||
/* Print a hunk of an ed diff */
|
||||
|
||||
static void
|
||||
print_ed_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int f0, l0, f1, l1;
|
||||
int deletes, inserts;
|
||||
|
||||
#if 0
|
||||
hunk = flip_script (hunk);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
debug_script (hunk);
|
||||
#endif
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
|
||||
if (!deletes && !inserts)
|
||||
return;
|
||||
|
||||
begin_output ();
|
||||
|
||||
/* Print out the line number header for this hunk */
|
||||
print_number_range (',', &files[0], f0, l0);
|
||||
fprintf (outfile, "%c\n", change_letter (inserts, deletes));
|
||||
|
||||
/* Print new/changed lines from second file, if needed */
|
||||
if (inserts)
|
||||
{
|
||||
int i;
|
||||
int inserting = 1;
|
||||
for (i = f1; i <= l1; i++)
|
||||
{
|
||||
/* Resume the insert, if we stopped. */
|
||||
if (! inserting)
|
||||
fprintf (outfile, "%da\n",
|
||||
i - f1 + translate_line_number (&files[0], f0) - 1);
|
||||
inserting = 1;
|
||||
|
||||
/* If the file's line is just a dot, it would confuse `ed'.
|
||||
So output it with a double dot, and set the flag LEADING_DOT
|
||||
so that we will output another ed-command later
|
||||
to change the double dot into a single dot. */
|
||||
|
||||
if (files[1].linbuf[i][0] == '.'
|
||||
&& files[1].linbuf[i][1] == '\n')
|
||||
{
|
||||
fprintf (outfile, "..\n");
|
||||
fprintf (outfile, ".\n");
|
||||
/* Now change that double dot to the desired single dot. */
|
||||
fprintf (outfile, "%ds/^\\.\\././\n",
|
||||
i - f1 + translate_line_number (&files[0], f0));
|
||||
inserting = 0;
|
||||
}
|
||||
else
|
||||
/* Line is not `.', so output it unmodified. */
|
||||
print_1_line ("", &files[1].linbuf[i]);
|
||||
}
|
||||
|
||||
/* End insert mode, if we are still in it. */
|
||||
if (inserting)
|
||||
fprintf (outfile, ".\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Print change script in the style of ed commands,
|
||||
but print the changes in the order they appear in the input files,
|
||||
which means that the commands are not truly useful with ed. */
|
||||
|
||||
void
|
||||
pr_forward_ed_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
print_script (script, find_change, pr_forward_ed_hunk);
|
||||
}
|
||||
|
||||
static void
|
||||
pr_forward_ed_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int i;
|
||||
int f0, l0, f1, l1;
|
||||
int deletes, inserts;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
|
||||
if (!deletes && !inserts)
|
||||
return;
|
||||
|
||||
begin_output ();
|
||||
|
||||
fprintf (outfile, "%c", change_letter (inserts, deletes));
|
||||
print_number_range (' ', files, f0, l0);
|
||||
fprintf (outfile, "\n");
|
||||
|
||||
/* If deletion only, print just the number range. */
|
||||
|
||||
if (!inserts)
|
||||
return;
|
||||
|
||||
/* For insertion (with or without deletion), print the number range
|
||||
and the lines from file 2. */
|
||||
|
||||
for (i = f1; i <= l1; i++)
|
||||
print_1_line ("", &files[1].linbuf[i]);
|
||||
|
||||
fprintf (outfile, ".\n");
|
||||
}
|
||||
|
||||
/* Print in a format somewhat like ed commands
|
||||
except that each insert command states the number of lines it inserts.
|
||||
This format is used for RCS. */
|
||||
|
||||
void
|
||||
print_rcs_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
print_script (script, find_change, print_rcs_hunk);
|
||||
}
|
||||
|
||||
/* Print a hunk of an RCS diff */
|
||||
|
||||
static void
|
||||
print_rcs_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int i;
|
||||
int f0, l0, f1, l1;
|
||||
int deletes, inserts;
|
||||
int tf0, tl0, tf1, tl1;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
|
||||
if (!deletes && !inserts)
|
||||
return;
|
||||
|
||||
begin_output ();
|
||||
|
||||
translate_range (&files[0], f0, l0, &tf0, &tl0);
|
||||
|
||||
if (deletes)
|
||||
{
|
||||
fprintf (outfile, "d");
|
||||
/* For deletion, print just the starting line number from file 0
|
||||
and the number of lines deleted. */
|
||||
fprintf (outfile, "%d %d\n",
|
||||
tf0,
|
||||
(tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
|
||||
}
|
||||
|
||||
if (inserts)
|
||||
{
|
||||
fprintf (outfile, "a");
|
||||
|
||||
/* Take last-line-number from file 0 and # lines from file 1. */
|
||||
translate_range (&files[1], f1, l1, &tf1, &tl1);
|
||||
fprintf (outfile, "%d %d\n",
|
||||
tl0,
|
||||
(tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
|
||||
|
||||
/* Print the inserted lines. */
|
||||
for (i = f1; i <= l1; i++)
|
||||
print_1_line ("", &files[1].linbuf[i]);
|
||||
}
|
||||
}
|
@ -1,428 +0,0 @@
|
||||
/* #ifdef-format output routines for GNU DIFF.
|
||||
Copyright (C) 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY. No author or distributor
|
||||
accepts responsibility to anyone for the consequences of using it
|
||||
or for whether it serves any particular purpose or works at all,
|
||||
unless he says so in writing. Refer to the GNU DIFF General Public
|
||||
License for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute
|
||||
GNU DIFF, but only under the conditions described in the
|
||||
GNU DIFF General Public License. A copy of this license is
|
||||
supposed to have been given to you along with GNU DIFF so you
|
||||
can know your rights and responsibilities. It should be in a
|
||||
file named COPYING. Among other things, the copyright notice
|
||||
and this notice must be preserved on all copies. */
|
||||
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
struct group
|
||||
{
|
||||
struct file_data const *file;
|
||||
int from, upto; /* start and limit lines for this group of lines */
|
||||
};
|
||||
|
||||
static char *format_group PARAMS((FILE *, char *, int, struct group const *));
|
||||
static char *scan_char_literal PARAMS((char *, int *));
|
||||
static char *scan_printf_spec PARAMS((char *));
|
||||
static int groups_letter_value PARAMS((struct group const *, int));
|
||||
static void format_ifdef PARAMS((char *, int, int, int, int));
|
||||
static void print_ifdef_hunk PARAMS((struct change *));
|
||||
static void print_ifdef_lines PARAMS((FILE *, char *, struct group const *));
|
||||
|
||||
static int next_line;
|
||||
|
||||
/* Print the edit-script SCRIPT as a merged #ifdef file. */
|
||||
|
||||
void
|
||||
print_ifdef_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
next_line = - files[0].prefix_lines;
|
||||
print_script (script, find_change, print_ifdef_hunk);
|
||||
if (next_line < files[0].valid_lines)
|
||||
{
|
||||
begin_output ();
|
||||
format_ifdef (group_format[UNCHANGED], next_line, files[0].valid_lines,
|
||||
next_line - files[0].valid_lines + files[1].valid_lines,
|
||||
files[1].valid_lines);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a hunk of an ifdef diff.
|
||||
This is a contiguous portion of a complete edit script,
|
||||
describing changes in consecutive lines. */
|
||||
|
||||
static void
|
||||
print_ifdef_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int first0, last0, first1, last1, deletes, inserts;
|
||||
char *format;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
|
||||
if (inserts)
|
||||
format = deletes ? group_format[CHANGED] : group_format[NEW];
|
||||
else if (deletes)
|
||||
format = group_format[OLD];
|
||||
else
|
||||
return;
|
||||
|
||||
begin_output ();
|
||||
|
||||
/* Print lines up to this change. */
|
||||
if (next_line < first0)
|
||||
format_ifdef (group_format[UNCHANGED], next_line, first0,
|
||||
next_line - first0 + first1, first1);
|
||||
|
||||
/* Print this change. */
|
||||
next_line = last0 + 1;
|
||||
format_ifdef (format, first0, next_line, first1, last1 + 1);
|
||||
}
|
||||
|
||||
/* Print a set of lines according to FORMAT.
|
||||
Lines BEG0 up to END0 are from the first file;
|
||||
lines BEG1 up to END1 are from the second file. */
|
||||
|
||||
static void
|
||||
format_ifdef (format, beg0, end0, beg1, end1)
|
||||
char *format;
|
||||
int beg0, end0, beg1, end1;
|
||||
{
|
||||
struct group groups[2];
|
||||
|
||||
groups[0].file = &files[0];
|
||||
groups[0].from = beg0;
|
||||
groups[0].upto = end0;
|
||||
groups[1].file = &files[1];
|
||||
groups[1].from = beg1;
|
||||
groups[1].upto = end1;
|
||||
format_group (outfile, format, '\0', groups);
|
||||
}
|
||||
|
||||
/* Print to file OUT a set of lines according to FORMAT.
|
||||
The format ends at the first free instance of ENDCHAR.
|
||||
Yield the address of the terminating character.
|
||||
GROUPS specifies which lines to print.
|
||||
If OUT is zero, do not actually print anything; just scan the format. */
|
||||
|
||||
static char *
|
||||
format_group (out, format, endchar, groups)
|
||||
register FILE *out;
|
||||
char *format;
|
||||
int endchar;
|
||||
struct group const *groups;
|
||||
{
|
||||
register char c;
|
||||
register char *f = format;
|
||||
|
||||
while ((c = *f) != endchar && c != 0)
|
||||
{
|
||||
f++;
|
||||
if (c == '%')
|
||||
{
|
||||
char *spec = f;
|
||||
switch ((c = *f++))
|
||||
{
|
||||
case '%':
|
||||
break;
|
||||
|
||||
case '(':
|
||||
/* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */
|
||||
{
|
||||
int i, value[2];
|
||||
FILE *thenout, *elseout;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
unsigned char f0 = f[0];
|
||||
if (ISDIGIT (f0))
|
||||
{
|
||||
value[i] = atoi (f);
|
||||
while (ISDIGIT ((unsigned char) *++f))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
value[i] = groups_letter_value (groups, f0);
|
||||
if (value[i] < 0)
|
||||
goto bad_format;
|
||||
f++;
|
||||
}
|
||||
if (*f++ != "=?"[i])
|
||||
goto bad_format;
|
||||
}
|
||||
if (value[0] == value[1])
|
||||
thenout = out, elseout = 0;
|
||||
else
|
||||
thenout = 0, elseout = out;
|
||||
f = format_group (thenout, f, ':', groups);
|
||||
if (*f)
|
||||
{
|
||||
f = format_group (elseout, f + 1, ')', groups);
|
||||
if (*f)
|
||||
f++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
/* Print lines deleted from first file. */
|
||||
print_ifdef_lines (out, line_format[OLD], &groups[0]);
|
||||
continue;
|
||||
|
||||
case '=':
|
||||
/* Print common lines. */
|
||||
print_ifdef_lines (out, line_format[UNCHANGED], &groups[0]);
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
/* Print lines inserted from second file. */
|
||||
print_ifdef_lines (out, line_format[NEW], &groups[1]);
|
||||
continue;
|
||||
|
||||
default:
|
||||
{
|
||||
int value;
|
||||
char *speclim;
|
||||
|
||||
f = scan_printf_spec (spec);
|
||||
if (!f)
|
||||
goto bad_format;
|
||||
speclim = f;
|
||||
c = *f++;
|
||||
switch (c)
|
||||
{
|
||||
case '\'':
|
||||
f = scan_char_literal (f, &value);
|
||||
if (!f)
|
||||
goto bad_format;
|
||||
break;
|
||||
|
||||
default:
|
||||
value = groups_letter_value (groups, c);
|
||||
if (value < 0)
|
||||
goto bad_format;
|
||||
break;
|
||||
}
|
||||
if (out)
|
||||
{
|
||||
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
|
||||
*speclim = 0;
|
||||
fprintf (out, spec - 1, value);
|
||||
/* Undo the temporary replacement. */
|
||||
*speclim = c;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
bad_format:
|
||||
c = '%';
|
||||
f = spec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (out)
|
||||
putc (c, out);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/* For the line group pair G, return the number corresponding to LETTER.
|
||||
Return -1 if LETTER is not a group format letter. */
|
||||
static int
|
||||
groups_letter_value (g, letter)
|
||||
struct group const *g;
|
||||
int letter;
|
||||
{
|
||||
if (ISUPPER (letter))
|
||||
{
|
||||
g++;
|
||||
letter = tolower (letter);
|
||||
}
|
||||
switch (letter)
|
||||
{
|
||||
case 'e': return translate_line_number (g->file, g->from) - 1;
|
||||
case 'f': return translate_line_number (g->file, g->from);
|
||||
case 'l': return translate_line_number (g->file, g->upto) - 1;
|
||||
case 'm': return translate_line_number (g->file, g->upto);
|
||||
case 'n': return g->upto - g->from;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print to file OUT, using FORMAT to print the line group GROUP.
|
||||
But do nothing if OUT is zero. */
|
||||
static void
|
||||
print_ifdef_lines (out, format, group)
|
||||
register FILE *out;
|
||||
char *format;
|
||||
struct group const *group;
|
||||
{
|
||||
struct file_data const *file = group->file;
|
||||
char const * const *linbuf = file->linbuf;
|
||||
int from = group->from, upto = group->upto;
|
||||
|
||||
if (!out)
|
||||
return;
|
||||
|
||||
/* If possible, use a single fwrite; it's faster. */
|
||||
if (!tab_expand_flag && format[0] == '%')
|
||||
{
|
||||
if (format[1] == 'l' && format[2] == '\n' && !format[3])
|
||||
{
|
||||
fwrite (linbuf[from], sizeof (char),
|
||||
linbuf[upto] + (linbuf[upto][-1] != '\n') - linbuf[from],
|
||||
out);
|
||||
return;
|
||||
}
|
||||
if (format[1] == 'L' && !format[2])
|
||||
{
|
||||
fwrite (linbuf[from], sizeof (char),
|
||||
linbuf[upto] - linbuf[from], out);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (; from < upto; from++)
|
||||
{
|
||||
register char c;
|
||||
register char *f = format;
|
||||
|
||||
while ((c = *f++) != 0)
|
||||
{
|
||||
if (c == '%')
|
||||
{
|
||||
char *spec = f;
|
||||
switch ((c = *f++))
|
||||
{
|
||||
case '%':
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
output_1_line (linbuf[from],
|
||||
linbuf[from + 1]
|
||||
- (linbuf[from + 1][-1] == '\n'), 0, 0);
|
||||
continue;
|
||||
|
||||
case 'L':
|
||||
output_1_line (linbuf[from], linbuf[from + 1], 0, 0);
|
||||
continue;
|
||||
|
||||
default:
|
||||
{
|
||||
int value;
|
||||
char *speclim;
|
||||
|
||||
f = scan_printf_spec (spec);
|
||||
if (!f)
|
||||
goto bad_format;
|
||||
speclim = f;
|
||||
c = *f++;
|
||||
switch (c)
|
||||
{
|
||||
case '\'':
|
||||
f = scan_char_literal (f, &value);
|
||||
if (!f)
|
||||
goto bad_format;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
value = translate_line_number (file, from);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto bad_format;
|
||||
}
|
||||
/* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
|
||||
*speclim = 0;
|
||||
fprintf (out, spec - 1, value);
|
||||
/* Undo the temporary replacement. */
|
||||
*speclim = c;
|
||||
}
|
||||
continue;
|
||||
|
||||
bad_format:
|
||||
c = '%';
|
||||
f = spec;
|
||||
break;
|
||||
}
|
||||
}
|
||||
putc (c, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Scan the character literal represented in the string LIT; LIT points just
|
||||
after the initial apostrophe. Put the literal's value into *INTPTR.
|
||||
Yield the address of the first character after the closing apostrophe,
|
||||
or zero if the literal is ill-formed. */
|
||||
static char *
|
||||
scan_char_literal (lit, intptr)
|
||||
char *lit;
|
||||
int *intptr;
|
||||
{
|
||||
register char *p = lit;
|
||||
int value, digits;
|
||||
char c = *p++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
case '\'':
|
||||
return 0;
|
||||
|
||||
case '\\':
|
||||
value = 0;
|
||||
while ((c = *p++) != '\'')
|
||||
{
|
||||
unsigned digit = c - '0';
|
||||
if (8 <= digit)
|
||||
return 0;
|
||||
value = 8 * value + digit;
|
||||
}
|
||||
digits = p - lit - 2;
|
||||
if (! (1 <= digits && digits <= 3))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
value = c;
|
||||
if (*p++ != '\'')
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
*intptr = value;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Scan optional printf-style SPEC of the form `-*[0-9]*(.[0-9]*)?[cdoxX]'.
|
||||
Return the address of the character following SPEC, or zero if failure. */
|
||||
static char *
|
||||
scan_printf_spec (spec)
|
||||
register char *spec;
|
||||
{
|
||||
register unsigned char c;
|
||||
|
||||
while ((c = *spec++) == '-')
|
||||
continue;
|
||||
while (ISDIGIT (c))
|
||||
c = *spec++;
|
||||
if (c == '.')
|
||||
while (ISDIGIT (c = *spec++))
|
||||
continue;
|
||||
switch (c)
|
||||
{
|
||||
case 'c': case 'd': case 'o': case 'x': case 'X':
|
||||
return spec;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,238 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
tranformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
@ -1,714 +0,0 @@
|
||||
/* File I/O for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
/* Rotate a value n bits to the left. */
|
||||
#define UINT_BIT (sizeof (unsigned) * CHAR_BIT)
|
||||
#define ROL(v, n) ((v) << (n) | (v) >> (UINT_BIT - (n)))
|
||||
|
||||
/* Given a hash value and a new character, return a new hash value. */
|
||||
#define HASH(h, c) ((c) + ROL (h, 7))
|
||||
|
||||
/* Guess remaining number of lines from number N of lines so far,
|
||||
size S so far, and total size T. */
|
||||
#define GUESS_LINES(n,s,t) (((t) - (s)) / ((n) < 10 ? 32 : (s) / ((n)-1)) + 5)
|
||||
|
||||
/* Type used for fast prefix comparison in find_identical_ends. */
|
||||
#ifndef word
|
||||
#define word int
|
||||
#endif
|
||||
|
||||
/* Lines are put into equivalence classes (of lines that match in line_cmp).
|
||||
Each equivalence class is represented by one of these structures,
|
||||
but only while the classes are being computed.
|
||||
Afterward, each class is represented by a number. */
|
||||
struct equivclass
|
||||
{
|
||||
int next; /* Next item in this bucket. */
|
||||
unsigned hash; /* Hash of lines in this class. */
|
||||
char const *line; /* A line that fits this class. */
|
||||
size_t length; /* That line's length, not counting its newline. */
|
||||
};
|
||||
|
||||
/* Hash-table: array of buckets, each being a chain of equivalence classes.
|
||||
buckets[-1] is reserved for incomplete lines. */
|
||||
static int *buckets;
|
||||
|
||||
/* Number of buckets in the hash table array, not counting buckets[-1]. */
|
||||
static int nbuckets;
|
||||
|
||||
/* Array in which the equivalence classes are allocated.
|
||||
The bucket-chains go through the elements in this array.
|
||||
The number of an equivalence class is its index in this array. */
|
||||
static struct equivclass *equivs;
|
||||
|
||||
/* Index of first free element in the array `equivs'. */
|
||||
static int equivs_index;
|
||||
|
||||
/* Number of elements allocated in the array `equivs'. */
|
||||
static int equivs_alloc;
|
||||
|
||||
static void find_and_hash_each_line PARAMS((struct file_data *));
|
||||
static void find_identical_ends PARAMS((struct file_data[]));
|
||||
static void prepare_text_end PARAMS((struct file_data *));
|
||||
|
||||
/* Check for binary files and compare them for exact identity. */
|
||||
|
||||
/* Return 1 if BUF contains a non text character.
|
||||
SIZE is the number of characters in BUF. */
|
||||
|
||||
#define binary_file_p(buf, size) (memchr (buf, '\0', size) != 0)
|
||||
|
||||
/* Get ready to read the current file.
|
||||
Return nonzero if SKIP_TEST is zero,
|
||||
and if it appears to be a binary file. */
|
||||
|
||||
int
|
||||
sip (current, skip_test)
|
||||
struct file_data *current;
|
||||
int skip_test;
|
||||
{
|
||||
/* If we have a nonexistent file at this stage, treat it as empty. */
|
||||
if (current->desc < 0)
|
||||
{
|
||||
/* Leave room for a sentinel. */
|
||||
current->bufsize = sizeof (word);
|
||||
current->buffer = xmalloc (current->bufsize);
|
||||
}
|
||||
else
|
||||
{
|
||||
current->bufsize = STAT_BLOCKSIZE (current->stat);
|
||||
current->buffer = xmalloc (current->bufsize);
|
||||
|
||||
if (! skip_test)
|
||||
{
|
||||
/* Check first part of file to see if it's a binary file. */
|
||||
#if HAVE_SETMODE
|
||||
int oldmode = setmode (current->desc, O_BINARY);
|
||||
#endif
|
||||
size_t n = read (current->desc, current->buffer, current->bufsize);
|
||||
if (n == -1)
|
||||
pfatal_with_name (current->name);
|
||||
current->buffered_chars = n;
|
||||
#if HAVE_SETMODE
|
||||
if (oldmode != O_BINARY)
|
||||
{
|
||||
if (lseek (current->desc, - (off_t) n, SEEK_CUR) == -1)
|
||||
pfatal_with_name (current->name);
|
||||
setmode (current->desc, oldmode);
|
||||
current->buffered_chars = 0;
|
||||
}
|
||||
#endif
|
||||
return binary_file_p (current->buffer, n);
|
||||
}
|
||||
}
|
||||
|
||||
current->buffered_chars = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Slurp the rest of the current file completely into memory. */
|
||||
|
||||
void
|
||||
slurp (current)
|
||||
struct file_data *current;
|
||||
{
|
||||
size_t cc;
|
||||
|
||||
if (current->desc < 0)
|
||||
/* The file is nonexistent. */
|
||||
;
|
||||
else if (S_ISREG (current->stat.st_mode))
|
||||
{
|
||||
/* It's a regular file; slurp in the rest all at once. */
|
||||
|
||||
/* Get the size out of the stat block.
|
||||
Allocate enough room for appended newline and sentinel. */
|
||||
cc = current->stat.st_size + 1 + sizeof (word);
|
||||
if (current->bufsize < cc)
|
||||
{
|
||||
current->bufsize = cc;
|
||||
current->buffer = xrealloc (current->buffer, cc);
|
||||
}
|
||||
|
||||
if (current->buffered_chars < current->stat.st_size)
|
||||
{
|
||||
cc = read (current->desc,
|
||||
current->buffer + current->buffered_chars,
|
||||
current->stat.st_size - current->buffered_chars);
|
||||
if (cc == -1)
|
||||
pfatal_with_name (current->name);
|
||||
current->buffered_chars += cc;
|
||||
}
|
||||
}
|
||||
/* It's not a regular file; read it, growing the buffer as needed. */
|
||||
else if (always_text_flag || current->buffered_chars != 0)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (current->buffered_chars == current->bufsize)
|
||||
{
|
||||
current->bufsize = current->bufsize * 2;
|
||||
current->buffer = xrealloc (current->buffer, current->bufsize);
|
||||
}
|
||||
cc = read (current->desc,
|
||||
current->buffer + current->buffered_chars,
|
||||
current->bufsize - current->buffered_chars);
|
||||
if (cc == 0)
|
||||
break;
|
||||
if (cc == -1)
|
||||
pfatal_with_name (current->name);
|
||||
current->buffered_chars += cc;
|
||||
}
|
||||
/* Allocate just enough room for appended newline and sentinel. */
|
||||
current->bufsize = current->buffered_chars + 1 + sizeof (word);
|
||||
current->buffer = xrealloc (current->buffer, current->bufsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split the file into lines, simultaneously computing the equivalence class for
|
||||
each line. */
|
||||
|
||||
static void
|
||||
find_and_hash_each_line (current)
|
||||
struct file_data *current;
|
||||
{
|
||||
unsigned h;
|
||||
unsigned char const *p = (unsigned char const *) current->prefix_end;
|
||||
unsigned char c;
|
||||
int i, *bucket;
|
||||
size_t length;
|
||||
|
||||
/* Cache often-used quantities in local variables to help the compiler. */
|
||||
char const **linbuf = current->linbuf;
|
||||
int alloc_lines = current->alloc_lines;
|
||||
int line = 0;
|
||||
int linbuf_base = current->linbuf_base;
|
||||
int *cureqs = (int *) xmalloc (alloc_lines * sizeof (int));
|
||||
struct equivclass *eqs = equivs;
|
||||
int eqs_index = equivs_index;
|
||||
int eqs_alloc = equivs_alloc;
|
||||
char const *suffix_begin = current->suffix_begin;
|
||||
char const *bufend = current->buffer + current->buffered_chars;
|
||||
int use_line_cmp = ignore_some_line_changes;
|
||||
|
||||
while ((char const *) p < suffix_begin)
|
||||
{
|
||||
char const *ip = (char const *) p;
|
||||
|
||||
/* Compute the equivalence class for this line. */
|
||||
|
||||
h = 0;
|
||||
|
||||
/* Hash this line until we find a newline. */
|
||||
if (ignore_case_flag)
|
||||
{
|
||||
if (ignore_all_space_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (! ISSPACE (c))
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (ISSPACE (c))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
c = *p++;
|
||||
if (!ISSPACE (c))
|
||||
break;
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
}
|
||||
h = HASH (h, ' ');
|
||||
}
|
||||
/* C is now the first non-space. */
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else
|
||||
while ((c = *p++) != '\n')
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ignore_all_space_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (! ISSPACE (c))
|
||||
h = HASH (h, c);
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (ISSPACE (c))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
c = *p++;
|
||||
if (!ISSPACE (c))
|
||||
break;
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
}
|
||||
h = HASH (h, ' ');
|
||||
}
|
||||
/* C is now the first non-space. */
|
||||
h = HASH (h, c);
|
||||
}
|
||||
else
|
||||
while ((c = *p++) != '\n')
|
||||
h = HASH (h, c);
|
||||
}
|
||||
hashing_done:;
|
||||
|
||||
bucket = &buckets[h % nbuckets];
|
||||
length = (char const *) p - ip - 1;
|
||||
|
||||
if ((char const *) p == bufend
|
||||
&& current->missing_newline
|
||||
&& ROBUST_OUTPUT_STYLE (output_style))
|
||||
{
|
||||
/* This line is incomplete. If this is significant,
|
||||
put the line into bucket[-1]. */
|
||||
if (! (ignore_space_change_flag | ignore_all_space_flag))
|
||||
bucket = &buckets[-1];
|
||||
|
||||
/* Omit the inserted newline when computing linbuf later. */
|
||||
p--;
|
||||
bufend = suffix_begin = (char const *) p;
|
||||
}
|
||||
|
||||
for (i = *bucket; ; i = eqs[i].next)
|
||||
if (!i)
|
||||
{
|
||||
/* Create a new equivalence class in this bucket. */
|
||||
i = eqs_index++;
|
||||
if (i == eqs_alloc)
|
||||
eqs = (struct equivclass *)
|
||||
xrealloc (eqs, (eqs_alloc*=2) * sizeof(*eqs));
|
||||
eqs[i].next = *bucket;
|
||||
eqs[i].hash = h;
|
||||
eqs[i].line = ip;
|
||||
eqs[i].length = length;
|
||||
*bucket = i;
|
||||
break;
|
||||
}
|
||||
else if (eqs[i].hash == h)
|
||||
{
|
||||
char const *eqline = eqs[i].line;
|
||||
|
||||
/* Reuse existing equivalence class if the lines are identical.
|
||||
This detects the common case of exact identity
|
||||
faster than complete comparison would. */
|
||||
if (eqs[i].length == length && memcmp (eqline, ip, length) == 0)
|
||||
break;
|
||||
|
||||
/* Reuse existing class if line_cmp reports the lines equal. */
|
||||
if (use_line_cmp && line_cmp (eqline, ip) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Maybe increase the size of the line table. */
|
||||
if (line == alloc_lines)
|
||||
{
|
||||
/* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */
|
||||
alloc_lines = 2 * alloc_lines - linbuf_base;
|
||||
cureqs = (int *) xrealloc (cureqs, alloc_lines * sizeof (*cureqs));
|
||||
linbuf = (char const **) xrealloc (linbuf + linbuf_base,
|
||||
(alloc_lines - linbuf_base)
|
||||
* sizeof (*linbuf))
|
||||
- linbuf_base;
|
||||
}
|
||||
linbuf[line] = ip;
|
||||
cureqs[line] = i;
|
||||
++line;
|
||||
}
|
||||
|
||||
current->buffered_lines = line;
|
||||
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
/* Record the line start for lines in the suffix that we care about.
|
||||
Record one more line start than lines,
|
||||
so that we can compute the length of any buffered line. */
|
||||
if (line == alloc_lines)
|
||||
{
|
||||
/* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */
|
||||
alloc_lines = 2 * alloc_lines - linbuf_base;
|
||||
linbuf = (char const **) xrealloc (linbuf + linbuf_base,
|
||||
(alloc_lines - linbuf_base)
|
||||
* sizeof (*linbuf))
|
||||
- linbuf_base;
|
||||
}
|
||||
linbuf[line] = (char const *) p;
|
||||
|
||||
if ((char const *) p == bufend)
|
||||
break;
|
||||
|
||||
if (context <= i && no_diff_means_no_output)
|
||||
break;
|
||||
|
||||
line++;
|
||||
|
||||
while (*p++ != '\n')
|
||||
;
|
||||
}
|
||||
|
||||
/* Done with cache in local variables. */
|
||||
current->linbuf = linbuf;
|
||||
current->valid_lines = line;
|
||||
current->alloc_lines = alloc_lines;
|
||||
current->equivs = cureqs;
|
||||
equivs = eqs;
|
||||
equivs_alloc = eqs_alloc;
|
||||
equivs_index = eqs_index;
|
||||
}
|
||||
|
||||
/* Prepare the end of the text. Make sure it's initialized.
|
||||
Make sure text ends in a newline,
|
||||
but remember that we had to add one. */
|
||||
|
||||
static void
|
||||
prepare_text_end (current)
|
||||
struct file_data *current;
|
||||
{
|
||||
size_t buffered_chars = current->buffered_chars;
|
||||
char *p = current->buffer;
|
||||
|
||||
if (buffered_chars == 0 || p[buffered_chars - 1] == '\n')
|
||||
current->missing_newline = 0;
|
||||
else
|
||||
{
|
||||
p[buffered_chars++] = '\n';
|
||||
current->buffered_chars = buffered_chars;
|
||||
current->missing_newline = 1;
|
||||
}
|
||||
|
||||
/* Don't use uninitialized storage when planting or using sentinels. */
|
||||
if (p)
|
||||
bzero (p + buffered_chars, sizeof (word));
|
||||
}
|
||||
|
||||
/* Given a vector of two file_data objects, find the identical
|
||||
prefixes and suffixes of each object. */
|
||||
|
||||
static void
|
||||
find_identical_ends (filevec)
|
||||
struct file_data filevec[];
|
||||
{
|
||||
word *w0, *w1;
|
||||
char *p0, *p1, *buffer0, *buffer1;
|
||||
char const *end0, *beg0;
|
||||
char const **linbuf0, **linbuf1;
|
||||
int i, lines;
|
||||
size_t n0, n1, tem;
|
||||
int alloc_lines0, alloc_lines1;
|
||||
int buffered_prefix, prefix_count, prefix_mask;
|
||||
|
||||
slurp (&filevec[0]);
|
||||
if (filevec[0].desc != filevec[1].desc)
|
||||
slurp (&filevec[1]);
|
||||
else
|
||||
{
|
||||
filevec[1].buffer = filevec[0].buffer;
|
||||
filevec[1].bufsize = filevec[0].bufsize;
|
||||
filevec[1].buffered_chars = filevec[0].buffered_chars;
|
||||
}
|
||||
for (i = 0; i < 2; i++)
|
||||
prepare_text_end (&filevec[i]);
|
||||
|
||||
/* Find identical prefix. */
|
||||
|
||||
p0 = buffer0 = filevec[0].buffer;
|
||||
p1 = buffer1 = filevec[1].buffer;
|
||||
|
||||
n0 = filevec[0].buffered_chars;
|
||||
n1 = filevec[1].buffered_chars;
|
||||
|
||||
if (p0 == p1)
|
||||
/* The buffers are the same; sentinels won't work. */
|
||||
p0 = p1 += n1;
|
||||
else
|
||||
{
|
||||
/* Insert end sentinels, in this case characters that are guaranteed
|
||||
to make the equality test false, and thus terminate the loop. */
|
||||
|
||||
if (n0 < n1)
|
||||
p0[n0] = ~p1[n0];
|
||||
else
|
||||
p1[n1] = ~p0[n1];
|
||||
|
||||
/* Loop until first mismatch, or to the sentinel characters. */
|
||||
|
||||
/* Compare a word at a time for speed. */
|
||||
w0 = (word *) p0;
|
||||
w1 = (word *) p1;
|
||||
while (*w0++ == *w1++)
|
||||
;
|
||||
--w0, --w1;
|
||||
|
||||
/* Do the last few bytes of comparison a byte at a time. */
|
||||
p0 = (char *) w0;
|
||||
p1 = (char *) w1;
|
||||
while (*p0++ == *p1++)
|
||||
;
|
||||
--p0, --p1;
|
||||
|
||||
/* Don't mistakenly count missing newline as part of prefix. */
|
||||
if (ROBUST_OUTPUT_STYLE (output_style)
|
||||
&& (buffer0 + n0 - filevec[0].missing_newline < p0)
|
||||
!=
|
||||
(buffer1 + n1 - filevec[1].missing_newline < p1))
|
||||
--p0, --p1;
|
||||
}
|
||||
|
||||
/* Now P0 and P1 point at the first nonmatching characters. */
|
||||
|
||||
/* Skip back to last line-beginning in the prefix,
|
||||
and then discard up to HORIZON_LINES lines from the prefix. */
|
||||
i = horizon_lines;
|
||||
while (p0 != buffer0 && (p0[-1] != '\n' || i--))
|
||||
--p0, --p1;
|
||||
|
||||
/* Record the prefix. */
|
||||
filevec[0].prefix_end = p0;
|
||||
filevec[1].prefix_end = p1;
|
||||
|
||||
/* Find identical suffix. */
|
||||
|
||||
/* P0 and P1 point beyond the last chars not yet compared. */
|
||||
p0 = buffer0 + n0;
|
||||
p1 = buffer1 + n1;
|
||||
|
||||
if (! ROBUST_OUTPUT_STYLE (output_style)
|
||||
|| filevec[0].missing_newline == filevec[1].missing_newline)
|
||||
{
|
||||
end0 = p0; /* Addr of last char in file 0. */
|
||||
|
||||
/* Get value of P0 at which we should stop scanning backward:
|
||||
this is when either P0 or P1 points just past the last char
|
||||
of the identical prefix. */
|
||||
beg0 = filevec[0].prefix_end + (n0 < n1 ? 0 : n0 - n1);
|
||||
|
||||
/* Scan back until chars don't match or we reach that point. */
|
||||
while (p0 != beg0)
|
||||
if (*--p0 != *--p1)
|
||||
{
|
||||
/* Point at the first char of the matching suffix. */
|
||||
++p0, ++p1;
|
||||
beg0 = p0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Are we at a line-beginning in both files? If not, add the rest of
|
||||
this line to the main body. Discard up to HORIZON_LINES lines from
|
||||
the identical suffix. Also, discard one extra line,
|
||||
because shift_boundaries may need it. */
|
||||
i = horizon_lines + !((buffer0 == p0 || p0[-1] == '\n')
|
||||
&&
|
||||
(buffer1 == p1 || p1[-1] == '\n'));
|
||||
while (i-- && p0 != end0)
|
||||
while (*p0++ != '\n')
|
||||
;
|
||||
|
||||
p1 += p0 - beg0;
|
||||
}
|
||||
|
||||
/* Record the suffix. */
|
||||
filevec[0].suffix_begin = p0;
|
||||
filevec[1].suffix_begin = p1;
|
||||
|
||||
/* Calculate number of lines of prefix to save.
|
||||
|
||||
prefix_count == 0 means save the whole prefix;
|
||||
we need this with for options like -D that output the whole file.
|
||||
We also need it for options like -F that output some preceding line;
|
||||
at least we will need to find the last few lines,
|
||||
but since we don't know how many, it's easiest to find them all.
|
||||
|
||||
Otherwise, prefix_count != 0. Save just prefix_count lines at start
|
||||
of the line buffer; they'll be moved to the proper location later.
|
||||
Handle 1 more line than the context says (because we count 1 too many),
|
||||
rounded up to the next power of 2 to speed index computation. */
|
||||
|
||||
if (no_diff_means_no_output && ! function_regexp_list)
|
||||
{
|
||||
for (prefix_count = 1; prefix_count < context + 1; prefix_count *= 2)
|
||||
;
|
||||
prefix_mask = prefix_count - 1;
|
||||
alloc_lines0
|
||||
= prefix_count
|
||||
+ GUESS_LINES (0, 0, p0 - filevec[0].prefix_end)
|
||||
+ context;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix_count = 0;
|
||||
prefix_mask = ~0;
|
||||
alloc_lines0 = GUESS_LINES (0, 0, n0);
|
||||
}
|
||||
|
||||
lines = 0;
|
||||
linbuf0 = (char const **) xmalloc (alloc_lines0 * sizeof (*linbuf0));
|
||||
|
||||
/* If the prefix is needed, find the prefix lines. */
|
||||
if (! (no_diff_means_no_output
|
||||
&& filevec[0].prefix_end == p0
|
||||
&& filevec[1].prefix_end == p1))
|
||||
{
|
||||
p0 = buffer0;
|
||||
end0 = filevec[0].prefix_end;
|
||||
while (p0 != end0)
|
||||
{
|
||||
int l = lines++ & prefix_mask;
|
||||
if (l == alloc_lines0)
|
||||
linbuf0 = (char const **) xrealloc (linbuf0, (alloc_lines0 *= 2)
|
||||
* sizeof(*linbuf0));
|
||||
linbuf0[l] = p0;
|
||||
while (*p0++ != '\n')
|
||||
;
|
||||
}
|
||||
}
|
||||
buffered_prefix = prefix_count && context < lines ? context : lines;
|
||||
|
||||
/* Allocate line buffer 1. */
|
||||
tem = prefix_count ? filevec[1].suffix_begin - buffer1 : n1;
|
||||
|
||||
alloc_lines1
|
||||
= (buffered_prefix
|
||||
+ GUESS_LINES (lines, filevec[1].prefix_end - buffer1, tem)
|
||||
+ context);
|
||||
linbuf1 = (char const **) xmalloc (alloc_lines1 * sizeof (*linbuf1));
|
||||
|
||||
if (buffered_prefix != lines)
|
||||
{
|
||||
/* Rotate prefix lines to proper location. */
|
||||
for (i = 0; i < buffered_prefix; i++)
|
||||
linbuf1[i] = linbuf0[(lines - context + i) & prefix_mask];
|
||||
for (i = 0; i < buffered_prefix; i++)
|
||||
linbuf0[i] = linbuf1[i];
|
||||
}
|
||||
|
||||
/* Initialize line buffer 1 from line buffer 0. */
|
||||
for (i = 0; i < buffered_prefix; i++)
|
||||
linbuf1[i] = linbuf0[i] - buffer0 + buffer1;
|
||||
|
||||
/* Record the line buffer, adjusted so that
|
||||
linbuf*[0] points at the first differing line. */
|
||||
filevec[0].linbuf = linbuf0 + buffered_prefix;
|
||||
filevec[1].linbuf = linbuf1 + buffered_prefix;
|
||||
filevec[0].linbuf_base = filevec[1].linbuf_base = - buffered_prefix;
|
||||
filevec[0].alloc_lines = alloc_lines0 - buffered_prefix;
|
||||
filevec[1].alloc_lines = alloc_lines1 - buffered_prefix;
|
||||
filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
|
||||
}
|
||||
|
||||
/* Largest primes less than some power of two, for nbuckets. Values range
|
||||
from useful to preposterous. If one of these numbers isn't prime
|
||||
after all, don't blame it on me, blame it on primes (6) . . . */
|
||||
static int const primes[] =
|
||||
{
|
||||
509,
|
||||
1021,
|
||||
2039,
|
||||
4093,
|
||||
8191,
|
||||
16381,
|
||||
32749,
|
||||
#if 32767 < INT_MAX
|
||||
65521,
|
||||
131071,
|
||||
262139,
|
||||
524287,
|
||||
1048573,
|
||||
2097143,
|
||||
4194301,
|
||||
8388593,
|
||||
16777213,
|
||||
33554393,
|
||||
67108859, /* Preposterously large . . . */
|
||||
134217689,
|
||||
268435399,
|
||||
536870909,
|
||||
1073741789,
|
||||
2147483647,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
/* Given a vector of two file_data objects, read the file associated
|
||||
with each one, and build the table of equivalence classes.
|
||||
Return 1 if either file appears to be a binary file.
|
||||
If PRETEND_BINARY is nonzero, pretend they are binary regardless. */
|
||||
|
||||
int
|
||||
read_files (filevec, pretend_binary)
|
||||
struct file_data filevec[];
|
||||
int pretend_binary;
|
||||
{
|
||||
int i;
|
||||
int skip_test = always_text_flag | pretend_binary;
|
||||
int appears_binary = pretend_binary | sip (&filevec[0], skip_test);
|
||||
|
||||
if (filevec[0].desc != filevec[1].desc)
|
||||
appears_binary |= sip (&filevec[1], skip_test | appears_binary);
|
||||
else
|
||||
{
|
||||
filevec[1].buffer = filevec[0].buffer;
|
||||
filevec[1].bufsize = filevec[0].bufsize;
|
||||
filevec[1].buffered_chars = filevec[0].buffered_chars;
|
||||
}
|
||||
if (appears_binary)
|
||||
{
|
||||
#if HAVE_SETMODE
|
||||
setmode (filevec[0].desc, O_BINARY);
|
||||
setmode (filevec[1].desc, O_BINARY);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
find_identical_ends (filevec);
|
||||
|
||||
equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1;
|
||||
equivs = (struct equivclass *) xmalloc (equivs_alloc * sizeof (struct equivclass));
|
||||
/* Equivalence class 0 is permanently safe for lines that were not
|
||||
hashed. Real equivalence classes start at 1. */
|
||||
equivs_index = 1;
|
||||
|
||||
for (i = 0; primes[i] < equivs_alloc / 3; i++)
|
||||
if (! primes[i])
|
||||
abort ();
|
||||
nbuckets = primes[i];
|
||||
|
||||
buckets = (int *) xmalloc ((nbuckets + 1) * sizeof (*buckets));
|
||||
bzero (buckets++, (nbuckets + 1) * sizeof (*buckets));
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
find_and_hash_each_line (&filevec[i]);
|
||||
|
||||
filevec[0].equiv_max = filevec[1].equiv_max = equivs_index;
|
||||
|
||||
free (equivs);
|
||||
free (buckets - 1);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/* Normal-format output routines for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
static void print_normal_hunk PARAMS((struct change *));
|
||||
|
||||
/* Print the edit-script SCRIPT as a normal diff.
|
||||
INF points to an array of descriptions of the two files. */
|
||||
|
||||
void
|
||||
print_normal_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
print_script (script, find_change, print_normal_hunk);
|
||||
}
|
||||
|
||||
/* Print a hunk of a normal diff.
|
||||
This is a contiguous portion of a complete edit script,
|
||||
describing changes in consecutive lines. */
|
||||
|
||||
static void
|
||||
print_normal_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int first0, last0, first1, last1, deletes, inserts;
|
||||
register int i;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
|
||||
if (!deletes && !inserts)
|
||||
return;
|
||||
|
||||
begin_output ();
|
||||
|
||||
/* Print out the line number header for this hunk */
|
||||
print_number_range (',', &files[0], first0, last0);
|
||||
fprintf (outfile, "%c", change_letter (inserts, deletes));
|
||||
print_number_range (',', &files[1], first1, last1);
|
||||
fprintf (outfile, "\n");
|
||||
|
||||
/* Print the lines that the first file has. */
|
||||
if (deletes)
|
||||
for (i = first0; i <= last0; i++)
|
||||
print_1_line ("<", &files[0].linbuf[i]);
|
||||
|
||||
if (inserts && deletes)
|
||||
fprintf (outfile, "---\n");
|
||||
|
||||
/* Print the lines that the second file has. */
|
||||
if (inserts)
|
||||
for (i = first1; i <= last1; i++)
|
||||
print_1_line (">", &files[1].linbuf[i]);
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
/* prepend_args.c - utilility programs for manpiulating argv[]
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "system.h"
|
||||
#include "diff.h"
|
||||
#include "prepend_args.h"
|
||||
|
||||
|
||||
/* Find the white-space-separated options specified by OPTIONS, and
|
||||
using BUF to store copies of these options, set ARGV[0], ARGV[1],
|
||||
etc. to the option copies. Return the number N of options found.
|
||||
Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0]
|
||||
etc. Backslash can be used to escape whitespace (and backslashes). */
|
||||
static int
|
||||
prepend_args (options, buf, argv)
|
||||
char const *options;
|
||||
char *buf;
|
||||
char **argv;
|
||||
{
|
||||
char const *o = options;
|
||||
char *b = buf;
|
||||
int n = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (ISSPACE ((unsigned char) *o))
|
||||
o++;
|
||||
if (!*o)
|
||||
return n;
|
||||
if (argv)
|
||||
argv[n] = b;
|
||||
n++;
|
||||
|
||||
do
|
||||
if ((*b++ = *o++) == '\\' && *o)
|
||||
b[-1] = *o++;
|
||||
while (*o && ! ISSPACE ((unsigned char) *o));
|
||||
|
||||
*b++ = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepend the whitespace-separated options in OPTIONS to the argument
|
||||
vector of a main program with argument count *PARGC and argument
|
||||
vector *PARGV. */
|
||||
void
|
||||
prepend_default_options (options, pargc, pargv)
|
||||
char const *options;
|
||||
int *pargc;
|
||||
char ***pargv;
|
||||
{
|
||||
if (options)
|
||||
{
|
||||
char *buf = xmalloc (strlen (options) + 1);
|
||||
int prepended = prepend_args (options, buf, (char **) NULL);
|
||||
int argc = *pargc;
|
||||
char * const *argv = *pargv;
|
||||
char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
|
||||
*pargc = prepended + argc;
|
||||
*pargv = pp;
|
||||
*pp++ = *argv++;
|
||||
pp += prepend_args (options, buf, pp);
|
||||
while ((*pp++ = *argv++))
|
||||
continue;
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
/* prepend_args.h - utilility programs for manpiulating argv[]
|
||||
Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
void prepend_default_options PARAMS ((char const *, int *, char ***));
|
1109
contrib/diff/sdiff.c
1109
contrib/diff/sdiff.c
File diff suppressed because it is too large
Load Diff
@ -1,284 +0,0 @@
|
||||
/* sdiff-format output routines for GNU DIFF.
|
||||
Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY. No author or distributor
|
||||
accepts responsibility to anyone for the consequences of using it
|
||||
or for whether it serves any particular purpose or works at all,
|
||||
unless he says so in writing. Refer to the GNU DIFF General Public
|
||||
License for full details.
|
||||
|
||||
Everyone is granted permission to copy, modify and redistribute
|
||||
GNU DIFF, but only under the conditions described in the
|
||||
GNU DIFF General Public License. A copy of this license is
|
||||
supposed to have been given to you along with GNU DIFF so you
|
||||
can know your rights and responsibilities. It should be in a
|
||||
file named COPYING. Among other things, the copyright notice
|
||||
and this notice must be preserved on all copies. */
|
||||
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
static unsigned print_half_line PARAMS((char const * const *, unsigned, unsigned));
|
||||
static unsigned tab_from_to PARAMS((unsigned, unsigned));
|
||||
static void print_1sdiff_line PARAMS((char const * const *, int, char const * const *));
|
||||
static void print_sdiff_common_lines PARAMS((int, int));
|
||||
static void print_sdiff_hunk PARAMS((struct change *));
|
||||
|
||||
/* Next line number to be printed in the two input files. */
|
||||
static int next0, next1;
|
||||
|
||||
/* Print the edit-script SCRIPT as a sdiff style output. */
|
||||
|
||||
void
|
||||
print_sdiff_script (script)
|
||||
struct change *script;
|
||||
{
|
||||
begin_output ();
|
||||
|
||||
next0 = next1 = - files[0].prefix_lines;
|
||||
print_script (script, find_change, print_sdiff_hunk);
|
||||
|
||||
print_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines);
|
||||
}
|
||||
|
||||
/* Tab from column FROM to column TO, where FROM <= TO. Yield TO. */
|
||||
|
||||
static unsigned
|
||||
tab_from_to (from, to)
|
||||
unsigned from, to;
|
||||
{
|
||||
FILE *out = outfile;
|
||||
unsigned tab;
|
||||
|
||||
if (! tab_expand_flag)
|
||||
for (tab = from + TAB_WIDTH - from % TAB_WIDTH; tab <= to; tab += TAB_WIDTH)
|
||||
{
|
||||
putc ('\t', out);
|
||||
from = tab;
|
||||
}
|
||||
while (from++ < to)
|
||||
putc (' ', out);
|
||||
return to;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the text for half an sdiff line. This means truncate to width
|
||||
* observing tabs, and trim a trailing newline. Returns the last column
|
||||
* written (not the number of chars).
|
||||
*/
|
||||
static unsigned
|
||||
print_half_line (line, indent, out_bound)
|
||||
char const * const *line;
|
||||
unsigned indent, out_bound;
|
||||
{
|
||||
FILE *out = outfile;
|
||||
register unsigned in_position = 0, out_position = 0;
|
||||
register char const
|
||||
*text_pointer = line[0],
|
||||
*text_limit = line[1];
|
||||
|
||||
while (text_pointer < text_limit)
|
||||
{
|
||||
register unsigned char c = *text_pointer++;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\t':
|
||||
{
|
||||
unsigned spaces = TAB_WIDTH - in_position % TAB_WIDTH;
|
||||
if (in_position == out_position)
|
||||
{
|
||||
unsigned tabstop = out_position + spaces;
|
||||
if (tab_expand_flag)
|
||||
{
|
||||
if (out_bound < tabstop)
|
||||
tabstop = out_bound;
|
||||
for (; out_position < tabstop; out_position++)
|
||||
putc (' ', out);
|
||||
}
|
||||
else
|
||||
if (tabstop < out_bound)
|
||||
{
|
||||
out_position = tabstop;
|
||||
putc (c, out);
|
||||
}
|
||||
}
|
||||
in_position += spaces;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
{
|
||||
putc (c, out);
|
||||
tab_from_to (0, indent);
|
||||
in_position = out_position = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
if (in_position != 0 && --in_position < out_bound)
|
||||
if (out_position <= in_position)
|
||||
/* Add spaces to make up for suppressed tab past out_bound. */
|
||||
for (; out_position < in_position; out_position++)
|
||||
putc (' ', out);
|
||||
else
|
||||
{
|
||||
out_position = in_position;
|
||||
putc (c, out);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
case '\v':
|
||||
control_char:
|
||||
if (in_position < out_bound)
|
||||
putc (c, out);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! ISPRINT (c))
|
||||
goto control_char;
|
||||
/* falls through */
|
||||
case ' ':
|
||||
if (in_position++ < out_bound)
|
||||
{
|
||||
out_position = in_position;
|
||||
putc (c, out);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
return out_position;
|
||||
}
|
||||
}
|
||||
|
||||
return out_position;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print side by side lines with a separator in the middle.
|
||||
* 0 parameters are taken to indicate white space text.
|
||||
* Blank lines that can easily be caught are reduced to a single newline.
|
||||
*/
|
||||
|
||||
static void
|
||||
print_1sdiff_line (left, sep, right)
|
||||
char const * const *left;
|
||||
int sep;
|
||||
char const * const *right;
|
||||
{
|
||||
FILE *out = outfile;
|
||||
unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset;
|
||||
unsigned col = 0;
|
||||
int put_newline = 0;
|
||||
|
||||
if (left)
|
||||
{
|
||||
if (left[1][-1] == '\n')
|
||||
put_newline = 1;
|
||||
col = print_half_line (left, 0, hw);
|
||||
}
|
||||
|
||||
if (sep != ' ')
|
||||
{
|
||||
col = tab_from_to (col, (hw + c2o - 1) / 2) + 1;
|
||||
if (sep == '|' && put_newline != (right[1][-1] == '\n'))
|
||||
sep = put_newline ? '/' : '\\';
|
||||
putc (sep, out);
|
||||
}
|
||||
|
||||
if (right)
|
||||
{
|
||||
if (right[1][-1] == '\n')
|
||||
put_newline = 1;
|
||||
if (**right != '\n')
|
||||
{
|
||||
col = tab_from_to (col, c2o);
|
||||
print_half_line (right, col, hw);
|
||||
}
|
||||
}
|
||||
|
||||
if (put_newline)
|
||||
putc ('\n', out);
|
||||
}
|
||||
|
||||
/* Print lines common to both files in side-by-side format. */
|
||||
static void
|
||||
print_sdiff_common_lines (limit0, limit1)
|
||||
int limit0, limit1;
|
||||
{
|
||||
int i0 = next0, i1 = next1;
|
||||
|
||||
if (! sdiff_skip_common_lines && (i0 != limit0 || i1 != limit1))
|
||||
{
|
||||
if (sdiff_help_sdiff)
|
||||
fprintf (outfile, "i%d,%d\n", limit0 - i0, limit1 - i1);
|
||||
|
||||
if (! sdiff_left_only)
|
||||
{
|
||||
while (i0 != limit0 && i1 != limit1)
|
||||
print_1sdiff_line (&files[0].linbuf[i0++], ' ', &files[1].linbuf[i1++]);
|
||||
while (i1 != limit1)
|
||||
print_1sdiff_line (0, ')', &files[1].linbuf[i1++]);
|
||||
}
|
||||
while (i0 != limit0)
|
||||
print_1sdiff_line (&files[0].linbuf[i0++], '(', 0);
|
||||
}
|
||||
|
||||
next0 = limit0;
|
||||
next1 = limit1;
|
||||
}
|
||||
|
||||
/* Print a hunk of an sdiff diff.
|
||||
This is a contiguous portion of a complete edit script,
|
||||
describing changes in consecutive lines. */
|
||||
|
||||
static void
|
||||
print_sdiff_hunk (hunk)
|
||||
struct change *hunk;
|
||||
{
|
||||
int first0, last0, first1, last1, deletes, inserts;
|
||||
register int i, j;
|
||||
|
||||
/* Determine range of line numbers involved in each file. */
|
||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
|
||||
if (!deletes && !inserts)
|
||||
return;
|
||||
|
||||
/* Print out lines up to this change. */
|
||||
print_sdiff_common_lines (first0, first1);
|
||||
|
||||
if (sdiff_help_sdiff)
|
||||
fprintf (outfile, "c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
|
||||
|
||||
/* Print ``xxx | xxx '' lines */
|
||||
if (inserts && deletes)
|
||||
{
|
||||
for (i = first0, j = first1; i <= last0 && j <= last1; ++i, ++j)
|
||||
print_1sdiff_line (&files[0].linbuf[i], '|', &files[1].linbuf[j]);
|
||||
deletes = i <= last0;
|
||||
inserts = j <= last1;
|
||||
next0 = first0 = i;
|
||||
next1 = first1 = j;
|
||||
}
|
||||
|
||||
|
||||
/* Print `` > xxx '' lines */
|
||||
if (inserts)
|
||||
{
|
||||
for (j = first1; j <= last1; ++j)
|
||||
print_1sdiff_line (0, '>', &files[1].linbuf[j]);
|
||||
next1 = j;
|
||||
}
|
||||
|
||||
/* Print ``xxx < '' lines */
|
||||
if (deletes)
|
||||
{
|
||||
for (i = first0; i <= last0; ++i)
|
||||
print_1sdiff_line (&files[0].linbuf[i], '<', 0);
|
||||
next0 = i;
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
Fri Sep 30 22:22:28 PDT 1994
|
@ -1,267 +0,0 @@
|
||||
/* System dependent declarations.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* We must define `volatile' and `const' first (the latter inside config.h),
|
||||
so that they're used consistently in all system includes. */
|
||||
#if !__STDC__
|
||||
#ifndef volatile
|
||||
#define volatile
|
||||
#endif
|
||||
#endif
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if __STDC__
|
||||
#define PARAMS(args) args
|
||||
#define VOID void
|
||||
#else
|
||||
#define PARAMS(args) ()
|
||||
#define VOID char
|
||||
#endif
|
||||
|
||||
#if STAT_MACROS_BROKEN
|
||||
#undef S_ISBLK
|
||||
#undef S_ISCHR
|
||||
#undef S_ISDIR
|
||||
#undef S_ISFIFO
|
||||
#undef S_ISREG
|
||||
#undef S_ISSOCK
|
||||
#endif
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISBLK) && defined(S_IFBLK)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR) && defined(S_IFCHR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISFIFO) && defined(S_IFFIFO)
|
||||
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#endif
|
||||
#ifndef SEEK_CUR
|
||||
#define SEEK_CUR 1
|
||||
#endif
|
||||
|
||||
#ifndef STDIN_FILENO
|
||||
#define STDIN_FILENO 0
|
||||
#endif
|
||||
#ifndef STDOUT_FILENO
|
||||
#define STDOUT_FILENO 1
|
||||
#endif
|
||||
#ifndef STDERR_FILENO
|
||||
#define STDERR_FILENO 2
|
||||
#endif
|
||||
|
||||
#if HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#if HAVE_SYS_FILE_H
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_DUP2
|
||||
#define dup2(f,t) (close (t), fcntl (f,F_DUPFD,t))
|
||||
#endif
|
||||
|
||||
#ifndef O_RDONLY
|
||||
#define O_RDONLY 0
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(stat_val) ((unsigned) (stat_val) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef STAT_BLOCKSIZE
|
||||
#if HAVE_ST_BLKSIZE
|
||||
#define STAT_BLOCKSIZE(s) (s).st_blksize
|
||||
#else
|
||||
#define STAT_BLOCKSIZE(s) (8 * 1024)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else
|
||||
# define dirent direct
|
||||
# define NAMLEN(dirent) ((dirent)->d_namlen)
|
||||
# if HAVE_SYS_NDIR_H
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if HAVE_SYS_DIR_H
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if HAVE_NDIR_H
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if HAVE_VFORK_H
|
||||
#include <vfork.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
VOID *malloc ();
|
||||
VOID *realloc ();
|
||||
#endif
|
||||
#ifndef getenv
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
#ifndef INT_MAX
|
||||
#define INT_MAX 2147483647
|
||||
#endif
|
||||
#ifndef CHAR_BIT
|
||||
#define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# ifndef bzero
|
||||
# define bzero(s, n) memset (s, 0, n)
|
||||
# endif
|
||||
#else
|
||||
# if !HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr (), *strrchr ();
|
||||
# if !HAVE_MEMCHR
|
||||
# define memcmp(s1, s2, n) bcmp (s1, s2, n)
|
||||
# define memcpy(d, s, n) bcopy (s, d, n)
|
||||
void *memchr ();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
/* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
|
||||
as an argument to <ctype.h> macros like `isspace'. */
|
||||
#if STDC_HEADERS
|
||||
#define CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
#define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
|
||||
#endif
|
||||
#ifndef ISPRINT
|
||||
#define ISPRINT(c) (CTYPE_DOMAIN (c) && isprint (c))
|
||||
#endif
|
||||
#ifndef ISSPACE
|
||||
#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c))
|
||||
#endif
|
||||
#ifndef ISUPPER
|
||||
#define ISUPPER(c) (CTYPE_DOMAIN (c) && isupper (c))
|
||||
#endif
|
||||
|
||||
#ifndef ISDIGIT
|
||||
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#if !STDC_HEADERS
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) >= (b) ? (a) : (b))
|
||||
|
||||
/* This section contains Posix-compliant defaults for macros
|
||||
that are meant to be overridden by hand in config.h as needed. */
|
||||
|
||||
#ifndef filename_cmp
|
||||
#define filename_cmp(a, b) strcmp (a, b)
|
||||
#endif
|
||||
|
||||
#ifndef filename_lastdirchar
|
||||
#define filename_lastdirchar(filename) strrchr (filename, '/')
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FORK
|
||||
#define HAVE_FORK 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETMODE
|
||||
#define HAVE_SETMODE 0
|
||||
#endif
|
||||
|
||||
#ifndef initialize_main
|
||||
#define initialize_main(argcp, argvp)
|
||||
#endif
|
||||
|
||||
/* Do struct stat *S, *T describe the same file? Answer -1 if unknown. */
|
||||
#ifndef same_file
|
||||
#define same_file(s,t) ((s)->st_ino==(t)->st_ino && (s)->st_dev==(t)->st_dev)
|
||||
#endif
|
||||
|
||||
/* Place into Q a quoted version of A suitable for `popen' or `system',
|
||||
incrementing Q and junking A.
|
||||
Do not increment Q by more than 4 * strlen (A) + 2. */
|
||||
#ifndef SYSTEM_QUOTE_ARG
|
||||
#define SYSTEM_QUOTE_ARG(q, a) \
|
||||
{ \
|
||||
*(q)++ = '\''; \
|
||||
for (; *(a); *(q)++ = *(a)++) \
|
||||
if (*(a) == '\'') \
|
||||
{ \
|
||||
*(q)++ = '\''; \
|
||||
*(q)++ = '\\'; \
|
||||
*(q)++ = '\''; \
|
||||
} \
|
||||
*(q)++ = '\''; \
|
||||
}
|
||||
#endif
|
@ -1,759 +0,0 @@
|
||||
/* Support routines for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
GNU DIFF is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU DIFF is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* $FreeBSD$ */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
#ifndef PR_PROGRAM
|
||||
#define PR_PROGRAM "/bin/pr"
|
||||
#endif
|
||||
|
||||
/* Queue up one-line messages to be printed at the end,
|
||||
when -l is specified. Each message is recorded with a `struct msg'. */
|
||||
|
||||
struct msg
|
||||
{
|
||||
struct msg *next;
|
||||
char const *format;
|
||||
char const *arg1;
|
||||
char const *arg2;
|
||||
char const *arg3;
|
||||
char const *arg4;
|
||||
};
|
||||
|
||||
/* Head of the chain of queues messages. */
|
||||
|
||||
static struct msg *msg_chain;
|
||||
|
||||
/* Tail of the chain of queues messages. */
|
||||
|
||||
static struct msg **msg_chain_end = &msg_chain;
|
||||
|
||||
/* Use when a system call returns non-zero status.
|
||||
TEXT should normally be the file name. */
|
||||
|
||||
void
|
||||
perror_with_name (text)
|
||||
char const *text;
|
||||
{
|
||||
int e = errno;
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
}
|
||||
|
||||
/* Use when a system call returns non-zero status and that is fatal. */
|
||||
|
||||
void
|
||||
pfatal_with_name (text)
|
||||
char const *text;
|
||||
{
|
||||
int e = errno;
|
||||
print_message_queue ();
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* Print an error message from the format-string FORMAT
|
||||
with args ARG1 and ARG2. */
|
||||
|
||||
void
|
||||
error (format, arg, arg1)
|
||||
char const *format, *arg, *arg1;
|
||||
{
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
fprintf (stderr, format, arg, arg1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Print an error message containing the string TEXT, then exit. */
|
||||
|
||||
void
|
||||
fatal (m)
|
||||
char const *m;
|
||||
{
|
||||
print_message_queue ();
|
||||
error ("%s", m, 0);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
/* Like printf, except if -l in effect then save the message and print later.
|
||||
This is used for things like "binary files differ" and "Only in ...". */
|
||||
|
||||
void
|
||||
message (format, arg1, arg2)
|
||||
char const *format, *arg1, *arg2;
|
||||
{
|
||||
message5 (format, arg1, arg2, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
message5 (format, arg1, arg2, arg3, arg4)
|
||||
char const *format, *arg1, *arg2, *arg3, *arg4;
|
||||
{
|
||||
if (paginate_flag)
|
||||
{
|
||||
struct msg *new = (struct msg *) xmalloc (sizeof (struct msg));
|
||||
new->format = format;
|
||||
new->arg1 = concat (arg1, "", "");
|
||||
new->arg2 = concat (arg2, "", "");
|
||||
new->arg3 = arg3 ? concat (arg3, "", "") : 0;
|
||||
new->arg4 = arg4 ? concat (arg4, "", "") : 0;
|
||||
new->next = 0;
|
||||
*msg_chain_end = new;
|
||||
msg_chain_end = &new->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sdiff_help_sdiff)
|
||||
putchar (' ');
|
||||
printf (format, arg1, arg2, arg3, arg4);
|
||||
}
|
||||
}
|
||||
|
||||
/* Output all the messages that were saved up by calls to `message'. */
|
||||
|
||||
void
|
||||
print_message_queue ()
|
||||
{
|
||||
struct msg *m;
|
||||
|
||||
for (m = msg_chain; m; m = m->next)
|
||||
printf (m->format, m->arg1, m->arg2, m->arg3, m->arg4);
|
||||
}
|
||||
|
||||
/* Call before outputting the results of comparing files NAME0 and NAME1
|
||||
to set up OUTFILE, the stdio stream for the output to go to.
|
||||
|
||||
Usually, OUTFILE is just stdout. But when -l was specified
|
||||
we fork off a `pr' and make OUTFILE a pipe to it.
|
||||
`pr' then outputs to our stdout. */
|
||||
|
||||
static char const *current_name0;
|
||||
static char const *current_name1;
|
||||
static int current_depth;
|
||||
|
||||
void
|
||||
setup_output (name0, name1, depth)
|
||||
char const *name0, *name1;
|
||||
int depth;
|
||||
{
|
||||
current_name0 = name0;
|
||||
current_name1 = name1;
|
||||
current_depth = depth;
|
||||
outfile = 0;
|
||||
}
|
||||
|
||||
#if HAVE_FORK
|
||||
static pid_t pr_pid;
|
||||
#endif
|
||||
|
||||
void
|
||||
begin_output ()
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (outfile != 0)
|
||||
return;
|
||||
|
||||
/* Construct the header of this piece of diff. */
|
||||
name = xmalloc (strlen (current_name0) + strlen (current_name1)
|
||||
+ strlen (switch_string) + 7);
|
||||
/* Posix.2 section 4.17.6.1.1 specifies this format. But there is a
|
||||
bug in the first printing (IEEE Std 1003.2-1992 p 251 l 3304):
|
||||
it says that we must print only the last component of the pathnames.
|
||||
This requirement is silly and does not match historical practice. */
|
||||
sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
|
||||
|
||||
if (paginate_flag)
|
||||
{
|
||||
/* Make OUTFILE a pipe to a subsidiary `pr'. */
|
||||
|
||||
#if HAVE_FORK
|
||||
int pipes[2];
|
||||
|
||||
if (pipe (pipes) != 0)
|
||||
pfatal_with_name ("pipe");
|
||||
|
||||
fflush (stdout);
|
||||
|
||||
pr_pid = vfork ();
|
||||
if (pr_pid < 0)
|
||||
pfatal_with_name ("vfork");
|
||||
|
||||
if (pr_pid == 0)
|
||||
{
|
||||
close (pipes[1]);
|
||||
if (pipes[0] != STDIN_FILENO)
|
||||
{
|
||||
if (dup2 (pipes[0], STDIN_FILENO) < 0)
|
||||
pfatal_with_name ("dup2");
|
||||
close (pipes[0]);
|
||||
}
|
||||
#ifdef __FreeBSD__
|
||||
execl (PR_PROGRAM, PR_PROGRAM, "-F", "-h", name, (char *)NULL);
|
||||
#else
|
||||
execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, (char *)NULL);
|
||||
#endif
|
||||
pfatal_with_name (PR_PROGRAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
close (pipes[0]);
|
||||
outfile = fdopen (pipes[1], "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name ("fdopen");
|
||||
}
|
||||
#else /* ! HAVE_FORK */
|
||||
char *command = xmalloc (4 * strlen (name) + strlen (PR_PROGRAM) + 10);
|
||||
char *p;
|
||||
char const *a = name;
|
||||
sprintf (command, "%s -f -h ", PR_PROGRAM);
|
||||
p = command + strlen (command);
|
||||
SYSTEM_QUOTE_ARG (p, a);
|
||||
*p = 0;
|
||||
outfile = popen (command, "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name (command);
|
||||
free (command);
|
||||
#endif /* ! HAVE_FORK */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/* If -l was not specified, output the diff straight to `stdout'. */
|
||||
|
||||
outfile = stdout;
|
||||
|
||||
/* If handling multiple files (because scanning a directory),
|
||||
print which files the following output is about. */
|
||||
if (current_depth > 0)
|
||||
printf ("%s\n", name);
|
||||
}
|
||||
|
||||
free (name);
|
||||
|
||||
/* A special header is needed at the beginning of context output. */
|
||||
switch (output_style)
|
||||
{
|
||||
case OUTPUT_CONTEXT:
|
||||
print_context_header (files, 0);
|
||||
break;
|
||||
|
||||
case OUTPUT_UNIFIED:
|
||||
print_context_header (files, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Call after the end of output of diffs for one file.
|
||||
Close OUTFILE and get rid of the `pr' subfork. */
|
||||
|
||||
void
|
||||
finish_output ()
|
||||
{
|
||||
if (outfile != 0 && outfile != stdout)
|
||||
{
|
||||
int wstatus;
|
||||
if (ferror (outfile))
|
||||
fatal ("write error");
|
||||
#if ! HAVE_FORK
|
||||
wstatus = pclose (outfile);
|
||||
#else /* HAVE_FORK */
|
||||
if (fclose (outfile) != 0)
|
||||
pfatal_with_name ("write error");
|
||||
if (waitpid (pr_pid, &wstatus, 0) < 0)
|
||||
pfatal_with_name ("waitpid");
|
||||
#endif /* HAVE_FORK */
|
||||
if (wstatus != 0)
|
||||
fatal ("subsidiary pr failed");
|
||||
}
|
||||
|
||||
outfile = 0;
|
||||
}
|
||||
|
||||
/* Compare two lines (typically one from each input file)
|
||||
according to the command line options.
|
||||
For efficiency, this is invoked only when the lines do not match exactly
|
||||
but an option like -i might cause us to ignore the difference.
|
||||
Return nonzero if the lines differ. */
|
||||
|
||||
int
|
||||
line_cmp (s1, s2)
|
||||
char const *s1, *s2;
|
||||
{
|
||||
register unsigned char const *t1 = (unsigned char const *) s1;
|
||||
register unsigned char const *t2 = (unsigned char const *) s2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
register unsigned char c1 = *t1++;
|
||||
register unsigned char c2 = *t2++;
|
||||
|
||||
/* Test for exact char equality first, since it's a common case. */
|
||||
if (c1 != c2)
|
||||
{
|
||||
/* Ignore horizontal white space if -b or -w is specified. */
|
||||
|
||||
if (ignore_all_space_flag)
|
||||
{
|
||||
/* For -w, just skip past any white space. */
|
||||
while (ISSPACE (c1) && c1 != '\n') c1 = *t1++;
|
||||
while (ISSPACE (c2) && c2 != '\n') c2 = *t2++;
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
{
|
||||
/* For -b, advance past any sequence of white space in line 1
|
||||
and consider it just one Space, or nothing at all
|
||||
if it is at the end of the line. */
|
||||
if (ISSPACE (c1))
|
||||
{
|
||||
while (c1 != '\n')
|
||||
{
|
||||
c1 = *t1++;
|
||||
if (! ISSPACE (c1))
|
||||
{
|
||||
--t1;
|
||||
c1 = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Likewise for line 2. */
|
||||
if (ISSPACE (c2))
|
||||
{
|
||||
while (c2 != '\n')
|
||||
{
|
||||
c2 = *t2++;
|
||||
if (! ISSPACE (c2))
|
||||
{
|
||||
--t2;
|
||||
c2 = ' ';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
/* If we went too far when doing the simple test
|
||||
for equality, go back to the first non-white-space
|
||||
character in both sides and try again. */
|
||||
if (c2 == ' ' && c1 != '\n'
|
||||
&& (unsigned char const *) s1 + 1 < t1
|
||||
&& ISSPACE(t1[-2]))
|
||||
{
|
||||
--t1;
|
||||
continue;
|
||||
}
|
||||
if (c1 == ' ' && c2 != '\n'
|
||||
&& (unsigned char const *) s2 + 1 < t2
|
||||
&& ISSPACE(t2[-2]))
|
||||
{
|
||||
--t2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lowercase all letters if -i is specified. */
|
||||
|
||||
if (ignore_case_flag)
|
||||
{
|
||||
if (ISUPPER (c1))
|
||||
c1 = tolower (c1);
|
||||
if (ISUPPER (c2))
|
||||
c2 = tolower (c2);
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
break;
|
||||
}
|
||||
if (c1 == '\n')
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* Find the consecutive changes at the start of the script START.
|
||||
Return the last link before the first gap. */
|
||||
|
||||
struct change *
|
||||
find_change (start)
|
||||
struct change *start;
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
struct change *
|
||||
find_reverse_change (start)
|
||||
struct change *start;
|
||||
{
|
||||
return start;
|
||||
}
|
||||
|
||||
/* Divide SCRIPT into pieces by calling HUNKFUN and
|
||||
print each piece with PRINTFUN.
|
||||
Both functions take one arg, an edit script.
|
||||
|
||||
HUNKFUN is called with the tail of the script
|
||||
and returns the last link that belongs together with the start
|
||||
of the tail.
|
||||
|
||||
PRINTFUN takes a subscript which belongs together (with a null
|
||||
link at the end) and prints it. */
|
||||
|
||||
void
|
||||
print_script (script, hunkfun, printfun)
|
||||
struct change *script;
|
||||
struct change * (*hunkfun) PARAMS((struct change *));
|
||||
void (*printfun) PARAMS((struct change *));
|
||||
{
|
||||
struct change *next = script;
|
||||
|
||||
while (next)
|
||||
{
|
||||
struct change *this, *end;
|
||||
|
||||
/* Find a set of changes that belong together. */
|
||||
this = next;
|
||||
end = (*hunkfun) (next);
|
||||
|
||||
/* Disconnect them from the rest of the changes,
|
||||
making them a hunk, and remember the rest for next iteration. */
|
||||
next = end->link;
|
||||
end->link = 0;
|
||||
#ifdef DEBUG
|
||||
debug_script (this);
|
||||
#endif
|
||||
|
||||
/* Print this hunk. */
|
||||
(*printfun) (this);
|
||||
|
||||
/* Reconnect the script so it will all be freed properly. */
|
||||
end->link = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Print the text of a single line LINE,
|
||||
flagging it with the characters in LINE_FLAG (which say whether
|
||||
the line is inserted, deleted, changed, etc.). */
|
||||
|
||||
void
|
||||
print_1_line (line_flag, line)
|
||||
char const *line_flag;
|
||||
char const * const *line;
|
||||
{
|
||||
char const *text = line[0], *limit = line[1]; /* Help the compiler. */
|
||||
FILE *out = outfile; /* Help the compiler some more. */
|
||||
char const *flag_format = 0;
|
||||
|
||||
/* If -T was specified, use a Tab between the line-flag and the text.
|
||||
Otherwise use a Space (as Unix diff does).
|
||||
Print neither space nor tab if line-flags are empty. */
|
||||
|
||||
if (line_flag && *line_flag)
|
||||
{
|
||||
flag_format = tab_align_flag ? "%s\t" : "%s ";
|
||||
fprintf (out, flag_format, line_flag);
|
||||
}
|
||||
|
||||
output_1_line (text, limit, flag_format, line_flag);
|
||||
|
||||
if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
|
||||
fprintf (out, "\n\\ No newline at end of file\n");
|
||||
}
|
||||
|
||||
/* Output a line from TEXT up to LIMIT. Without -t, output verbatim.
|
||||
With -t, expand white space characters to spaces, and if FLAG_FORMAT
|
||||
is nonzero, output it with argument LINE_FLAG after every
|
||||
internal carriage return, so that tab stops continue to line up. */
|
||||
|
||||
void
|
||||
output_1_line (text, limit, flag_format, line_flag)
|
||||
char const *text, *limit, *flag_format, *line_flag;
|
||||
{
|
||||
if (!tab_expand_flag)
|
||||
fwrite (text, sizeof (char), limit - text, outfile);
|
||||
else
|
||||
{
|
||||
register FILE *out = outfile;
|
||||
register unsigned char c;
|
||||
register char const *t = text;
|
||||
register unsigned column = 0;
|
||||
|
||||
while (t < limit)
|
||||
switch ((c = *t++))
|
||||
{
|
||||
case '\t':
|
||||
{
|
||||
unsigned spaces = TAB_WIDTH - column % TAB_WIDTH;
|
||||
column += spaces;
|
||||
do
|
||||
putc (' ', out);
|
||||
while (--spaces);
|
||||
}
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
putc (c, out);
|
||||
if (flag_format && t < limit && *t != '\n')
|
||||
fprintf (out, flag_format, line_flag);
|
||||
column = 0;
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
if (column == 0)
|
||||
continue;
|
||||
column--;
|
||||
putc (c, out);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ISPRINT (c))
|
||||
column++;
|
||||
putc (c, out);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
change_letter (inserts, deletes)
|
||||
int inserts, deletes;
|
||||
{
|
||||
if (!inserts)
|
||||
return 'd';
|
||||
else if (!deletes)
|
||||
return 'a';
|
||||
else
|
||||
return 'c';
|
||||
}
|
||||
|
||||
/* Translate an internal line number (an index into diff's table of lines)
|
||||
into an actual line number in the input file.
|
||||
The internal line number is LNUM. FILE points to the data on the file.
|
||||
|
||||
Internal line numbers count from 0 starting after the prefix.
|
||||
Actual line numbers count from 1 within the entire file. */
|
||||
|
||||
int
|
||||
translate_line_number (file, lnum)
|
||||
struct file_data const *file;
|
||||
int lnum;
|
||||
{
|
||||
return lnum + file->prefix_lines + 1;
|
||||
}
|
||||
|
||||
void
|
||||
translate_range (file, a, b, aptr, bptr)
|
||||
struct file_data const *file;
|
||||
int a, b;
|
||||
int *aptr, *bptr;
|
||||
{
|
||||
*aptr = translate_line_number (file, a - 1) + 1;
|
||||
*bptr = translate_line_number (file, b + 1) - 1;
|
||||
}
|
||||
|
||||
/* Print a pair of line numbers with SEPCHAR, translated for file FILE.
|
||||
If the two numbers are identical, print just one number.
|
||||
|
||||
Args A and B are internal line numbers.
|
||||
We print the translated (real) line numbers. */
|
||||
|
||||
void
|
||||
print_number_range (sepchar, file, a, b)
|
||||
int sepchar;
|
||||
struct file_data *file;
|
||||
int a, b;
|
||||
{
|
||||
int trans_a, trans_b;
|
||||
translate_range (file, a, b, &trans_a, &trans_b);
|
||||
|
||||
/* Note: we can have B < A in the case of a range of no lines.
|
||||
In this case, we should print the line number before the range,
|
||||
which is B. */
|
||||
if (trans_b > trans_a)
|
||||
fprintf (outfile, "%d%c%d", trans_a, sepchar, trans_b);
|
||||
else
|
||||
fprintf (outfile, "%d", trans_b);
|
||||
}
|
||||
|
||||
/* Look at a hunk of edit script and report the range of lines in each file
|
||||
that it applies to. HUNK is the start of the hunk, which is a chain
|
||||
of `struct change'. The first and last line numbers of file 0 are stored in
|
||||
*FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
|
||||
Note that these are internal line numbers that count from 0.
|
||||
|
||||
If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
|
||||
|
||||
Also set *DELETES nonzero if any lines of file 0 are deleted
|
||||
and set *INSERTS nonzero if any lines of file 1 are inserted.
|
||||
If only ignorable lines are inserted or deleted, both are
|
||||
set to 0. */
|
||||
|
||||
void
|
||||
analyze_hunk (hunk, first0, last0, first1, last1, deletes, inserts)
|
||||
struct change *hunk;
|
||||
int *first0, *last0, *first1, *last1;
|
||||
int *deletes, *inserts;
|
||||
{
|
||||
int l0, l1, show_from, show_to;
|
||||
int i;
|
||||
int trivial = ignore_blank_lines_flag || ignore_regexp_list;
|
||||
struct change *next;
|
||||
|
||||
show_from = show_to = 0;
|
||||
|
||||
*first0 = hunk->line0;
|
||||
*first1 = hunk->line1;
|
||||
|
||||
next = hunk;
|
||||
do
|
||||
{
|
||||
l0 = next->line0 + next->deleted - 1;
|
||||
l1 = next->line1 + next->inserted - 1;
|
||||
show_from += next->deleted;
|
||||
show_to += next->inserted;
|
||||
|
||||
for (i = next->line0; i <= l0 && trivial; i++)
|
||||
if (!ignore_blank_lines_flag || files[0].linbuf[i][0] != '\n')
|
||||
{
|
||||
struct regexp_list *r;
|
||||
char const *line = files[0].linbuf[i];
|
||||
int len = files[0].linbuf[i + 1] - line;
|
||||
|
||||
for (r = ignore_regexp_list; r; r = r->next)
|
||||
if (0 <= re_search (&r->buf, line, len, 0, len, 0))
|
||||
break; /* Found a match. Ignore this line. */
|
||||
/* If we got all the way through the regexp list without
|
||||
finding a match, then it's nontrivial. */
|
||||
if (!r)
|
||||
trivial = 0;
|
||||
}
|
||||
|
||||
for (i = next->line1; i <= l1 && trivial; i++)
|
||||
if (!ignore_blank_lines_flag || files[1].linbuf[i][0] != '\n')
|
||||
{
|
||||
struct regexp_list *r;
|
||||
char const *line = files[1].linbuf[i];
|
||||
int len = files[1].linbuf[i + 1] - line;
|
||||
|
||||
for (r = ignore_regexp_list; r; r = r->next)
|
||||
if (0 <= re_search (&r->buf, line, len, 0, len, 0))
|
||||
break; /* Found a match. Ignore this line. */
|
||||
/* If we got all the way through the regexp list without
|
||||
finding a match, then it's nontrivial. */
|
||||
if (!r)
|
||||
trivial = 0;
|
||||
}
|
||||
}
|
||||
while ((next = next->link) != 0);
|
||||
|
||||
*last0 = l0;
|
||||
*last1 = l1;
|
||||
|
||||
/* If all inserted or deleted lines are ignorable,
|
||||
tell the caller to ignore this hunk. */
|
||||
|
||||
if (trivial)
|
||||
show_from = show_to = 0;
|
||||
|
||||
*deletes = show_from;
|
||||
*inserts = show_to;
|
||||
}
|
||||
|
||||
/* malloc a block of memory, with fatal error message if we can't do it. */
|
||||
|
||||
VOID *
|
||||
xmalloc (size)
|
||||
size_t size;
|
||||
{
|
||||
register VOID *value;
|
||||
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
value = (VOID *) malloc (size);
|
||||
|
||||
if (!value)
|
||||
fatal ("memory exhausted");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* realloc a block of memory, with fatal error message if we can't do it. */
|
||||
|
||||
VOID *
|
||||
xrealloc (old, size)
|
||||
VOID *old;
|
||||
size_t size;
|
||||
{
|
||||
register VOID *value;
|
||||
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
|
||||
value = (VOID *) realloc (old, size);
|
||||
|
||||
if (!value)
|
||||
fatal ("memory exhausted");
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Concatenate three strings, returning a newly malloc'd string. */
|
||||
|
||||
char *
|
||||
concat (s1, s2, s3)
|
||||
char const *s1, *s2, *s3;
|
||||
{
|
||||
size_t len = strlen (s1) + strlen (s2) + strlen (s3);
|
||||
char *new = xmalloc (len + 1);
|
||||
sprintf (new, "%s%s%s", s1, s2, s3);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* Yield the newly malloc'd pathname
|
||||
of the file in DIR whose filename is FILE. */
|
||||
|
||||
char *
|
||||
dir_file_pathname (dir, file)
|
||||
char const *dir, *file;
|
||||
{
|
||||
char const *p = filename_lastdirchar (dir);
|
||||
return concat (dir, "/" + (p && !p[1]), file);
|
||||
}
|
||||
|
||||
void
|
||||
debug_script (sp)
|
||||
struct change *sp;
|
||||
{
|
||||
fflush (stdout);
|
||||
for (; sp; sp = sp->link)
|
||||
fprintf (stderr, "%3d %3d delete %d insert %d\n",
|
||||
sp->line0, sp->line1, sp->deleted, sp->inserted);
|
||||
fflush (stderr);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
/* Version number of GNU diff. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
char const version_string[] = "2.7";
|
@ -1,81 +0,0 @@
|
||||
/* xmalloc.c -- malloc with out of memory checking
|
||||
Copyright (C) 1990, 1991, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
#define VOID void
|
||||
#else
|
||||
#define VOID char
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
VOID *malloc ();
|
||||
VOID *realloc ();
|
||||
void free ();
|
||||
#endif
|
||||
|
||||
#if __STDC__ && defined (HAVE_VPRINTF)
|
||||
void error (int, int, char const *, ...);
|
||||
#else
|
||||
void error ();
|
||||
#endif
|
||||
|
||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||
|
||||
VOID *
|
||||
xmalloc (n)
|
||||
size_t n;
|
||||
{
|
||||
VOID *p;
|
||||
|
||||
p = malloc (n);
|
||||
if (p == 0)
|
||||
/* Must exit with 2 for `cmp'. */
|
||||
error (2, 0, "memory exhausted");
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Change the size of an allocated block of memory P to N bytes,
|
||||
with error checking.
|
||||
If P is NULL, run xmalloc.
|
||||
If N is 0, run free and return NULL. */
|
||||
|
||||
VOID *
|
||||
xrealloc (p, n)
|
||||
VOID *p;
|
||||
size_t n;
|
||||
{
|
||||
if (p == 0)
|
||||
return xmalloc (n);
|
||||
if (n == 0)
|
||||
{
|
||||
free (p);
|
||||
return 0;
|
||||
}
|
||||
p = realloc (p, n);
|
||||
if (p == 0)
|
||||
/* Must exit with 2 for `cmp'. */
|
||||
error (2, 0, "memory exhausted");
|
||||
return p;
|
||||
}
|
@ -1,16 +1,24 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/diff
|
||||
DIFFSRC=${.CURDIR}/../../../contrib/diff/src
|
||||
.PATH: ${DIFFSRC} \
|
||||
${.CURDIR}/../../../contrib/diff/lib \
|
||||
${.CURDIR}/../../../contrib/diff/man
|
||||
|
||||
PROG= diff
|
||||
SRCS= analyze.c cmpbuf.c context.c diff.c dir.c ed.c \
|
||||
ifdef.c io.c normal.c prepend_args.c side.c util.c version.c
|
||||
SRCS= analyze.c context.c diff.c dir.c ed.c ifdef.c io.c \
|
||||
normal.c side.c util.c \
|
||||
xmalloc.c strtoumax.c cmpbuf.c exitfail.c error.c quotesys.c \
|
||||
strftime.c c-stack.c basename.c exclude.c hard-locale.c \
|
||||
file-type.c posixver.c prepargs.c version-etc.c
|
||||
|
||||
# Important for ctype macros!
|
||||
CFLAGS+=-funsigned-char
|
||||
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff \
|
||||
-I${DESTDIR}/usr/include/gnu
|
||||
CFLAGS+=-I${DESTDIR}/usr/include/gnu
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/src
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/lib
|
||||
CFLAGS+=-DHAVE_CONFIG_H
|
||||
CFLAGS+=-DPR_PROGRAM=\"/usr/bin/pr\"
|
||||
|
||||
@ -19,4 +27,10 @@ SUBDIR+=doc
|
||||
DPADD= ${LIBGNUREGEX}
|
||||
LDADD= -lgnuregex
|
||||
|
||||
.for f in diff.c context.c
|
||||
${f}: ${DIFFSRC}/${f} ${.CURDIR}/${f}.diff
|
||||
patch -s -b .orig -o ${.TARGET} < ${.CURDIR}/${f}.diff ${DIFFSRC}/${f}
|
||||
CLEANFILES+= ${f}
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,508 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.TH DIFF 1 "22sep1993" "GNU Tools" "GNU Tools"
|
||||
.SH NAME
|
||||
diff \- find differences between two files
|
||||
.SH SYNOPSIS
|
||||
.B diff
|
||||
[options] from-file to-file
|
||||
.SH DESCRIPTION
|
||||
In the simplest case,
|
||||
.I diff
|
||||
compares the contents of the two files
|
||||
.I from-file
|
||||
and
|
||||
.IR to-file .
|
||||
A file name of
|
||||
.B \-
|
||||
stands for
|
||||
text read from the standard input. As a special case,
|
||||
.B "diff \- \-"
|
||||
compares a copy of standard input to itself.
|
||||
|
||||
If
|
||||
.I from-file
|
||||
is a directory and
|
||||
.I to-file
|
||||
is not,
|
||||
.I diff
|
||||
compares the file in
|
||||
.I from-file
|
||||
whose file name is that of
|
||||
.IR to-file ,
|
||||
and vice versa. The non-directory file must not be
|
||||
.BR \- .
|
||||
|
||||
If both
|
||||
.I from-file
|
||||
and
|
||||
.I to-file
|
||||
are directories,
|
||||
.I diff
|
||||
compares corresponding files in both directories, in
|
||||
alphabetical order; this comparison is not recursive unless the
|
||||
.B \-r
|
||||
or
|
||||
.B \-\-recursive
|
||||
option is given.
|
||||
.I diff
|
||||
never
|
||||
compares the actual contents of a directory as if it were a file. The
|
||||
file that is fully specified may not be standard input, because standard
|
||||
input is nameless and the notion of ``file with the same name'' does not
|
||||
apply.
|
||||
|
||||
.B diff
|
||||
options begin with
|
||||
.BR \- ,
|
||||
so normally
|
||||
.I from-file
|
||||
and
|
||||
.I to-file
|
||||
may not begin with
|
||||
.BR \- .
|
||||
However,
|
||||
.B \-\-
|
||||
as an
|
||||
argument by itself treats the remaining arguments as file names even if
|
||||
they begin with
|
||||
.BR \- .
|
||||
.SS Options
|
||||
Below is a summary of all of the options that GNU
|
||||
.I diff
|
||||
accepts.
|
||||
Most options have two equivalent names, one of which is a single letter
|
||||
preceded by
|
||||
.BR \- ,
|
||||
and the other of which is a long name preceded by
|
||||
.BR \-\- .
|
||||
Multiple single letter options (unless they take an
|
||||
argument) can be combined into a single command line word:
|
||||
.B \-ac
|
||||
is
|
||||
equivalent to
|
||||
.BR "\-a \-c" .
|
||||
Long named options can be abbreviated to
|
||||
any unique prefix of their name. Brackets
|
||||
.RB ( [
|
||||
and
|
||||
.BR ] )
|
||||
indicate that an
|
||||
option takes an optional argument.
|
||||
.TP
|
||||
.BI \- lines
|
||||
Show
|
||||
.I lines
|
||||
(an integer) lines of context. This option does not
|
||||
specify an output format by itself; it has no effect unless it is
|
||||
combined with
|
||||
.B \-c
|
||||
or
|
||||
.BR \-u .
|
||||
This option is obsolete. For proper
|
||||
operation,
|
||||
.I patch
|
||||
typically needs at least two lines of context.
|
||||
.TP
|
||||
.B \-a
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not seem to be text.
|
||||
.TP
|
||||
.B \-b
|
||||
Ignore changes in amount of white space.
|
||||
.TP
|
||||
.B \-B
|
||||
Ignore changes that just insert or delete blank lines.
|
||||
.TP
|
||||
.B \-\-brief
|
||||
Report only whether the files differ, not the details of the
|
||||
differences.
|
||||
.TP
|
||||
.B \-c
|
||||
Use the context output format.
|
||||
.TP
|
||||
.BI "\-C " lines
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-context[= lines ]
|
||||
Use the context output format, showing
|
||||
.I lines
|
||||
(an integer) lines of
|
||||
context, or three if
|
||||
.I lines
|
||||
is not given.
|
||||
For proper operation,
|
||||
.I patch
|
||||
typically needs at least two lines of
|
||||
context.
|
||||
.TP
|
||||
.BI \-\-changed\-group\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a line group containing differing lines from
|
||||
both files in if-then-else format.
|
||||
For more details on what can be specified in the
|
||||
.I format
|
||||
string, consult the info documentation of
|
||||
.I diff .
|
||||
.TP
|
||||
.B \-d
|
||||
Change the algorithm to perhaps find a smaller set of changes. This makes
|
||||
.I diff
|
||||
slower (sometimes much slower).
|
||||
.TP
|
||||
.BI "\-D " name
|
||||
Make merged if-then-else format output, conditional on the preprocessor
|
||||
macro
|
||||
.IR name .
|
||||
.TP
|
||||
.B \-e
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-ed
|
||||
Make output that is a valid
|
||||
.I ed
|
||||
script.
|
||||
.TP
|
||||
.BI \-\-exclude= pattern
|
||||
When comparing directories, ignore files and subdirectories whose basenames
|
||||
match
|
||||
.IR pattern .
|
||||
.TP
|
||||
.BI \-\-exclude\-from= file
|
||||
When comparing directories, ignore files and subdirectories whose basenames
|
||||
match any pattern contained in
|
||||
.IR file .
|
||||
.TP
|
||||
.B \-\-expand\-tabs
|
||||
Expand tabs to spaces in the output, to preserve the alignment of tabs
|
||||
in the input files.
|
||||
.TP
|
||||
.B \-f
|
||||
Make output that looks vaguely like an
|
||||
.I ed
|
||||
script but has changes
|
||||
in the order they appear in the file.
|
||||
.TP
|
||||
.BI "\-F " regexp
|
||||
In context and unified format, for each hunk of differences, show some
|
||||
of the last preceding line that matches
|
||||
.IR regexp .
|
||||
.TP
|
||||
.B \-\-forward\-ed
|
||||
Make output that looks vaguely like an
|
||||
.B ed
|
||||
script but has changes
|
||||
in the order they appear in the file.
|
||||
.TP
|
||||
.B \-h
|
||||
This option currently has no effect; it is present for Unix
|
||||
compatibility.
|
||||
.TP
|
||||
.B \-H
|
||||
Use heuristics to speed handling of large files that have numerous
|
||||
scattered small changes.
|
||||
.TP
|
||||
.BI \-\-horizon\-lines= lines
|
||||
Do not discard the last
|
||||
.I lines
|
||||
lines of the common prefix
|
||||
and the first
|
||||
.I lines
|
||||
lines of the common suffix.
|
||||
.TP
|
||||
.B \-i
|
||||
Ignore changes in case; consider upper- and lower-case letters
|
||||
equivalent.
|
||||
.TP
|
||||
.BI "\-I " regexp
|
||||
Ignore changes that just insert or delete lines that match
|
||||
.IR regexp .
|
||||
.TP
|
||||
.BI \-\-ifdef= name
|
||||
Make merged if-then-else format output, conditional on the preprocessor
|
||||
macro
|
||||
.IR name .
|
||||
.TP
|
||||
.B \-\-ignore\-all\-space
|
||||
Ignore white space when comparing lines.
|
||||
.TP
|
||||
.B \-\-ignore\-blank\-lines
|
||||
Ignore changes that just insert or delete blank lines.
|
||||
.TP
|
||||
.B \-\-ignore\-case
|
||||
Ignore changes in case; consider upper- and lower-case to be the same.
|
||||
.TP
|
||||
.BI \-\-ignore\-matching\-lines= regexp
|
||||
Ignore changes that just insert or delete lines that match
|
||||
.IR regexp .
|
||||
.TP
|
||||
.B \-\-ignore\-space\-change
|
||||
Ignore changes in amount of white space.
|
||||
.TP
|
||||
.B \-\-initial\-tab
|
||||
Output a tab rather than a space before the text of a line in normal or
|
||||
context format. This causes the alignment of tabs in the line to look
|
||||
normal.
|
||||
.TP
|
||||
.B \-l
|
||||
Pass the output through
|
||||
.I pr
|
||||
to paginate it.
|
||||
.TP
|
||||
.BI "\-L " label
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-label= label
|
||||
Use
|
||||
.I label
|
||||
instead of the file name in the context format
|
||||
and unified format
|
||||
headers.
|
||||
.TP
|
||||
.B \-\-left\-column
|
||||
Print only the left column of two common lines in side by side format.
|
||||
.TP
|
||||
.BI \-\-line\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output all input lines in in-then-else format.
|
||||
.TP
|
||||
.B \-\-minimal
|
||||
Change the algorithm to perhaps find a smaller set of changes. This
|
||||
makes
|
||||
.I diff
|
||||
slower (sometimes much slower).
|
||||
.TP
|
||||
.B \-n
|
||||
Output RCS-format diffs; like
|
||||
.B \-f
|
||||
except that each command
|
||||
specifies the number of lines affected.
|
||||
.TP
|
||||
.B \-N
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-new\-file
|
||||
In directory comparison, if a file is found in only one directory,
|
||||
treat it as present but empty in the other directory.
|
||||
.TP
|
||||
.BI \-\-new\-group\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a group of lines taken from just the second
|
||||
file in if-then-else format.
|
||||
.TP
|
||||
.BI \-\-new\-line\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a line taken from just the second file in
|
||||
if-then-else format.
|
||||
.TP
|
||||
.B \-o
|
||||
Use the old traditional output format.
|
||||
.TP
|
||||
.BI \-\-old\-group\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a group of lines taken from just the first
|
||||
file in if-then-else format.
|
||||
.TP
|
||||
.BI \-\-old\-line\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a line taken from just the first file in
|
||||
if-then-else format.
|
||||
.TP
|
||||
.B \-p
|
||||
Show which C function each change is in.
|
||||
.TP
|
||||
.B \-P
|
||||
When comparing directories, if a file appears only in the second
|
||||
directory of the two, treat it as present but empty in the other.
|
||||
.TP
|
||||
.B \-\-paginate
|
||||
Pass the output through
|
||||
.I pr
|
||||
to paginate it.
|
||||
.TP
|
||||
.B \-q
|
||||
Report only whether the files differ, not the details of the
|
||||
differences.
|
||||
.TP
|
||||
.B \-\-rcs
|
||||
Output RCS-format diffs; like
|
||||
.B \-f
|
||||
except that each command
|
||||
specifies the number of lines affected.
|
||||
.TP
|
||||
.B \-r
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-recursive
|
||||
When comparing directories, recursively compare any subdirectories
|
||||
found.
|
||||
.TP
|
||||
.B \-s
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-report\-identical\-files
|
||||
Report when two files are the same.
|
||||
.TP
|
||||
.BI "\-S " file
|
||||
When comparing directories, start with the file
|
||||
.IR file .
|
||||
This is
|
||||
used for resuming an aborted comparison.
|
||||
.TP
|
||||
.B \-\-sdiff\-merge\-assist
|
||||
Print extra information to help
|
||||
.IR sdiff .
|
||||
.I sdiff
|
||||
uses this
|
||||
option when it runs
|
||||
.IR diff .
|
||||
This option is not intended for users
|
||||
to use directly.
|
||||
.TP
|
||||
.B \-\-show\-c\-function
|
||||
Show which C function each change is in.
|
||||
.TP
|
||||
.BI \-\-show\-function\-line= regexp
|
||||
In context and unified format, for each hunk of differences, show some
|
||||
of the last preceding line that matches
|
||||
.IR regexp .
|
||||
.TP
|
||||
.B \-\-side\-by\-side
|
||||
Use the side by side output format.
|
||||
.TP
|
||||
.B \-\-speed\-large\-files
|
||||
Use heuristics to speed handling of large files that have numerous
|
||||
scattered small changes.
|
||||
.TP
|
||||
.BI \-\-starting\-file= file
|
||||
When comparing directories, start with the file
|
||||
.IR file .
|
||||
This is
|
||||
used for resuming an aborted comparison.
|
||||
.TP
|
||||
.B \-\-suppress\-common\-lines
|
||||
Do not print common lines in side by side format.
|
||||
.TP
|
||||
.B \-t
|
||||
Expand tabs to spaces in the output, to preserve the alignment of tabs
|
||||
in the input files.
|
||||
.TP
|
||||
.B \-T
|
||||
Output a tab rather than a space before the text of a line in normal or
|
||||
context format. This causes the alignment of tabs in the line to look
|
||||
normal.
|
||||
.TP
|
||||
.B \-\-text
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not appear to be text.
|
||||
.TP
|
||||
.B \-u
|
||||
Use the unified output format.
|
||||
.TP
|
||||
.BI \-\-unchanged\-group\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a group of common lines taken from both files
|
||||
in if-then-else format.
|
||||
.TP
|
||||
.BI \-\-unchanged\-line\-format= format
|
||||
Use
|
||||
.I format
|
||||
to output a line common to both files in if-then-else
|
||||
format.
|
||||
.TP
|
||||
.B \-\-unidirectional\-new\-file
|
||||
When comparing directories, if a file appears only in the second
|
||||
directory of the two, treat it as present but empty in the other.
|
||||
.TP
|
||||
.BI "\-U " lines
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-unified[= lines ]
|
||||
Use the unified output format, showing
|
||||
.I lines
|
||||
(an integer) lines of
|
||||
context, or three if
|
||||
.I lines
|
||||
is not given.
|
||||
For proper operation,
|
||||
.I patch
|
||||
typically needs at least two lines of
|
||||
context.
|
||||
.TP
|
||||
.B \-v
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-version
|
||||
Output the version number of
|
||||
.IR diff .
|
||||
.TP
|
||||
.B \-w
|
||||
Ignore horizontal white space when comparing lines.
|
||||
.TP
|
||||
.BI "\-W " columns
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-width= columns
|
||||
Use an output width of
|
||||
.I columns
|
||||
in side by side format.
|
||||
.TP
|
||||
.BI "\-x " pattern
|
||||
When comparing directories, ignore files and subdirectories whose basenames
|
||||
match
|
||||
.IR pattern .
|
||||
.TP
|
||||
.BI "\-X " file
|
||||
When comparing directories, ignore files and subdirectories whose basenames
|
||||
match any pattern contained in
|
||||
.IR file .
|
||||
.TP
|
||||
.B \-y
|
||||
Use the side by side output format.
|
||||
.SH RETURN VALUE
|
||||
.I diff
|
||||
returns 0 if the files are identical or 1 if the files differ.
|
||||
If one or both of the files cannot be opened,
|
||||
then the return value is set to 2.
|
||||
.SH ENVIRONMENT
|
||||
The environment variable
|
||||
.B DIFF_OPTIONS
|
||||
can hold a set of default
|
||||
options for
|
||||
.I diff.
|
||||
These options are interpreted first and can be overwritten by explicit command
|
||||
line parameters.
|
||||
.SH EXAMPLES
|
||||
To save to a file some changes that you have made to your local source
|
||||
tree (possibly including new files), which you would like to show to others
|
||||
(perhaps using the
|
||||
.B send-pr(1)
|
||||
program), you could type
|
||||
.sp
|
||||
diff -urN foo.orig foo >foo.diff
|
||||
.sp
|
||||
where
|
||||
.I foo.orig
|
||||
and
|
||||
.I foo
|
||||
might be directory hierarchies or single files.
|
||||
.SH SEE ALSO
|
||||
cmp(1), comm(1), diff3(1), ed(1), patch(1), pr(1), sdiff(1).
|
||||
.SH DIAGNOSTICS
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
differences were found, and 2 means trouble.
|
@ -4,6 +4,6 @@ INFO = diff
|
||||
|
||||
INFOENTRY_diff= "* DIFF: (diff). DIFF/PATCH Reference Manual."
|
||||
|
||||
SRCDIR=${.CURDIR}/../../../../contrib/diff
|
||||
SRCDIR=${.CURDIR}/../../../../contrib/diff/doc
|
||||
|
||||
.include <bsd.info.mk>
|
||||
|
@ -1,15 +1,27 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/diff
|
||||
DIFFSRC=${.CURDIR}/../../../contrib/diff/src
|
||||
.PATH: ${DIFFSRC} \
|
||||
${.CURDIR}/../../../contrib/diff/lib \
|
||||
${.CURDIR}/../../../contrib/diff/man
|
||||
|
||||
PROG= diff3
|
||||
SRCS= diff3.c version.c
|
||||
SRCS= diff3.c version-etc.c \
|
||||
xmalloc.c error.c c-stack.c exitfail.c cmpbuf.c
|
||||
|
||||
# Important for ctype macros!
|
||||
CFLAGS+=-funsigned-char
|
||||
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/src
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/lib
|
||||
CFLAGS+=-DHAVE_CONFIG_H
|
||||
CFLAGS+=-DDIFF_PROGRAM=\"/usr/bin/diff\"
|
||||
CFLAGS+=-DDEFAULT_DIFF_PROGRAM=\"/usr/bin/diff\"
|
||||
|
||||
.for f in diff3.c
|
||||
${f}: ${DIFFSRC}/${f} ${.CURDIR}/${f}.diff
|
||||
patch -s -b .orig -o ${.TARGET} < ${.CURDIR}/${f}.diff ${DIFFSRC}/${f}
|
||||
CLEANFILES+= ${f}
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,210 +0,0 @@
|
||||
.TH DIFF3 1 "22sep1993" "GNU Tools" "GNU Tools"
|
||||
.SH NAME
|
||||
diff3 \- find differences between three files
|
||||
.SH SYNOPSIS
|
||||
.B diff3
|
||||
[options] mine older yours
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I diff3
|
||||
command compares three files and outputs descriptions
|
||||
of their differences.
|
||||
|
||||
The files to compare are
|
||||
.IR mine ,
|
||||
.IR older ,
|
||||
and
|
||||
.IR yours .
|
||||
At most one of these three file names may be
|
||||
.BR \- ,
|
||||
which tells
|
||||
.I diff3
|
||||
to read the standard input for that file.
|
||||
.SS Options
|
||||
Below is a summary of all of the options that GNU
|
||||
.I diff3
|
||||
accepts. Multiple single letter options (unless they take an argument)
|
||||
can be combined into a single command line argument.
|
||||
.TP
|
||||
.B \-a
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not appear to be text.
|
||||
.TP
|
||||
.B \-A
|
||||
Incorporate all changes from
|
||||
.I older
|
||||
to
|
||||
.I yours
|
||||
into
|
||||
.IR mine ,
|
||||
surrounding all conflicts with bracket lines.
|
||||
.TP
|
||||
.B \-B
|
||||
Old behavior of -A. Shows non-conflicts.
|
||||
.TP
|
||||
.B \-e
|
||||
Generate an
|
||||
.I ed
|
||||
script that incorporates all the changes from
|
||||
.I older
|
||||
to
|
||||
.I yours
|
||||
into
|
||||
.IR mine .
|
||||
.TP
|
||||
.B \-E
|
||||
Like
|
||||
.BR \-e ,
|
||||
except bracket lines from overlapping changes' first
|
||||
and third files.
|
||||
With
|
||||
.BR \-e ,
|
||||
an overlapping change looks like this:
|
||||
.sp
|
||||
.nf
|
||||
<<<<<<< \fImine\fP
|
||||
lines from \fImine\fP
|
||||
=======
|
||||
lines from \fIyours\fP
|
||||
>>>>>>> \fIyours\fP
|
||||
.fi
|
||||
.TP
|
||||
.B \-\-ed
|
||||
Generate an
|
||||
.I ed
|
||||
script that incorporates all the changes from
|
||||
.I older
|
||||
to
|
||||
.I yours
|
||||
into
|
||||
.IR mine .
|
||||
.TP
|
||||
.B \-\-easy\-only
|
||||
Like
|
||||
.BR \-e ,
|
||||
except output only the nonoverlapping changes.
|
||||
.TP
|
||||
.B \-i
|
||||
Generate
|
||||
.B w
|
||||
and
|
||||
.B q
|
||||
commands at the end of the
|
||||
.I ed
|
||||
script for System V compatibility. This option must be combined with
|
||||
one of the
|
||||
.B \-AeExX3
|
||||
options, and may not be combined with
|
||||
.BR \-m .
|
||||
.TP
|
||||
.B \-\-initial\-tab
|
||||
Output a tab rather than two spaces before the text of a line in normal format.
|
||||
This causes the alignment of tabs in the line to look normal.
|
||||
.TP
|
||||
.BI "\-L " label
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-label= label
|
||||
Use the label
|
||||
.I label
|
||||
for the brackets output by the
|
||||
.BR \-A ,
|
||||
.B \-E
|
||||
and
|
||||
.B \-X
|
||||
options. This option may be given up to three
|
||||
times, one for each input file. The default labels are the names of
|
||||
the input files. Thus
|
||||
.B "diff3 \-L X \-L Y \-L Z \-m A B C"
|
||||
acts like
|
||||
.BR "diff3 \-m A B C ,
|
||||
except that the output looks like it came from
|
||||
files named
|
||||
.BR X ,
|
||||
.B Y
|
||||
and
|
||||
.B Z
|
||||
rather than from files
|
||||
named
|
||||
.BR A ,
|
||||
.B B
|
||||
and
|
||||
.BR C .
|
||||
.TP
|
||||
.B \-m
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-merge
|
||||
Apply the edit script to the first file and send the result to standard
|
||||
output. Unlike piping the output from
|
||||
.I diff3
|
||||
to
|
||||
.IR ed ,
|
||||
this
|
||||
works even for binary files and incomplete lines.
|
||||
.B \-A
|
||||
is assumed
|
||||
if no edit script option is specified.
|
||||
.TP
|
||||
.B \-\-overlap\-only
|
||||
Like
|
||||
.BR \-e ,
|
||||
except output only the overlapping changes.
|
||||
.TP
|
||||
.B \-\-show\-all
|
||||
Incorporate all unmerged changes from
|
||||
.I older
|
||||
to
|
||||
.I yours
|
||||
into
|
||||
.IR mine ,
|
||||
surrounding all overlapping changes with bracket lines.
|
||||
.TP
|
||||
.B \-\-show\-overlap
|
||||
Like
|
||||
.BR \-e ,
|
||||
except bracket lines from overlapping changes' first
|
||||
and third files.
|
||||
.TP
|
||||
.B \-T
|
||||
Output a tab rather than two spaces before the text of a line in normal format.
|
||||
This causes the alignment of tabs in the line to look normal.
|
||||
.TP
|
||||
.B \-\-text
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not appear to be text.
|
||||
.TP
|
||||
.B \-v
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-version
|
||||
Output the version number of
|
||||
.IR diff3 .
|
||||
.TP
|
||||
.B \-x
|
||||
Like
|
||||
.BR \-e ,
|
||||
except output only the overlapping changes.
|
||||
.TP
|
||||
.B \-X
|
||||
Like
|
||||
.BR \-E ,
|
||||
except output only the overlapping changes.
|
||||
In other words, like
|
||||
.BR \-x ,
|
||||
except bracket changes as in
|
||||
.BR \-E .
|
||||
.TP
|
||||
.B \-3
|
||||
Like
|
||||
.BR \-e ,
|
||||
except output only the nonoverlapping changes.
|
||||
.SH SEE ALSO
|
||||
cmp(1), comm(1), diff(1), ed(1), patch(1), sdiff(1).
|
||||
.SH DIAGNOSTICS
|
||||
An exit status of 0 means
|
||||
.I diff3
|
||||
was successful, 1 means some
|
||||
conflicts were found, and 2 means trouble.
|
@ -1,16 +1,28 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${.CURDIR}/../../../contrib/diff
|
||||
DIFFSRC=${.CURDIR}/../../../contrib/diff/src
|
||||
.PATH: ${DIFFSRC} \
|
||||
${.CURDIR}/../../../contrib/diff/lib \
|
||||
${.CURDIR}/../../../contrib/diff/man
|
||||
|
||||
PROG= sdiff
|
||||
SRCS= sdiff.c version.c
|
||||
SRCS= sdiff.c version-etc.c \
|
||||
error.c xmalloc.c c-stack.c basename.c strtoumax.c \
|
||||
exitfail.c
|
||||
|
||||
# Important for ctype macros!
|
||||
CFLAGS+=-funsigned-char
|
||||
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/src
|
||||
CFLAGS+=-I${.CURDIR}/../../../contrib/diff/lib
|
||||
CFLAGS+=-DHAVE_CONFIG_H
|
||||
CFLAGS+=-DDIFF_PROGRAM=\"/usr/bin/diff\"
|
||||
CFLAGS+=-DDEFAULT_EDITOR_PROGRAM=\"/usr/bin/vi\"
|
||||
CFLAGS+=-DDEFAULT_DIFF_PROGRAM=\"/usr/bin/diff\"
|
||||
|
||||
.for f in sdiff.c
|
||||
${f}: ${DIFFSRC}/${f} ${.CURDIR}/${f}.diff
|
||||
patch -s -b .orig -o ${.TARGET} < ${.CURDIR}/${f}.diff ${DIFFSRC}/${f}
|
||||
CLEANFILES+= ${f}
|
||||
.endfor
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,205 +0,0 @@
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.TH SDIFF 1 "22sep1993" "GNU Tools" "GNU Tools"
|
||||
.SH NAME
|
||||
sdiff \- find differences between two files and merge interactively
|
||||
.SH SYNOPSIS
|
||||
.B sdiff
|
||||
.B -o
|
||||
outfile [options] from-file to-file
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I sdiff
|
||||
command merges two files and interactively outputs the
|
||||
results to
|
||||
.IR outfile .
|
||||
|
||||
If
|
||||
.I from-file
|
||||
is a directory and
|
||||
.I to-file
|
||||
is not,
|
||||
.I sdiff
|
||||
compares the file in
|
||||
.I from-file
|
||||
whose file name is that of
|
||||
.IR to-file ,
|
||||
and vice versa.
|
||||
.I from-file
|
||||
and
|
||||
.I to-file
|
||||
may not both be
|
||||
directories.
|
||||
|
||||
.I sdiff
|
||||
options begin with
|
||||
.BR \- ,
|
||||
so normally
|
||||
.I from-file
|
||||
and
|
||||
.I to-file
|
||||
may not begin with
|
||||
.BR \- .
|
||||
However,
|
||||
.B \-\-
|
||||
as an
|
||||
argument by itself treats the remaining arguments as file names even if
|
||||
they begin with
|
||||
.BR \- .
|
||||
You may not use
|
||||
.B \-
|
||||
as an input file.
|
||||
|
||||
.I sdiff
|
||||
without
|
||||
.B \-o
|
||||
(or
|
||||
.BR \-\-output )
|
||||
produces a
|
||||
side-by-side difference. This usage is obsolete; use
|
||||
.B "diff \-\-side\-by\-side"
|
||||
instead.
|
||||
.SS Options
|
||||
Below is a summary of all of the options that GNU
|
||||
.I sdiff
|
||||
accepts.
|
||||
Each option has two equivalent names, one of which is a single
|
||||
letter preceded by
|
||||
.BR \- ,
|
||||
and the other of which is a long name
|
||||
preceded by
|
||||
.BR \-\- .
|
||||
Multiple single letter options (unless they take
|
||||
an argument) can be combined into a single command line argument. Long
|
||||
named options can be abbreviated to any unique prefix of their name.
|
||||
.TP
|
||||
.B \-a
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not appear to be text.
|
||||
.TP
|
||||
.B \-b
|
||||
Ignore changes in amount of white space.
|
||||
.TP
|
||||
.B \-B
|
||||
Ignore changes that just insert or delete blank lines.
|
||||
.TP
|
||||
.B \-d
|
||||
Change the algorithm to perhaps find a smaller set of changes. This
|
||||
makes
|
||||
.I sdiff
|
||||
slower (sometimes much slower).
|
||||
.TP
|
||||
.B \-H
|
||||
Use heuristics to speed handling of large files that have numerous
|
||||
scattered small changes.
|
||||
.TP
|
||||
.B \-\-expand\-tabs
|
||||
Expand tabs to spaces in the output, to preserve the alignment of tabs
|
||||
in the input files.
|
||||
.TP
|
||||
.B \-i
|
||||
Ignore changes in case; consider upper- and lower-case to be the same.
|
||||
.TP
|
||||
.BI "\-I " regexp
|
||||
Ignore changes that just insert or delete lines that match
|
||||
.IR regexp .
|
||||
.TP
|
||||
.B \-\-ignore\-all\-space
|
||||
Ignore white space when comparing lines.
|
||||
.TP
|
||||
.B \-\-ignore\-blank\-lines
|
||||
Ignore changes that just insert or delete blank lines.
|
||||
.TP
|
||||
.B \-\-ignore\-case
|
||||
Ignore changes in case; consider upper- and lower-case to be the same.
|
||||
.TP
|
||||
.BI \-\-ignore\-matching\-lines= regexp
|
||||
Ignore changes that just insert or delete lines that match
|
||||
.IR regexp .
|
||||
.TP
|
||||
.B \-\-ignore\-space\-change
|
||||
Ignore changes in amount of white space.
|
||||
.TP
|
||||
.B \-l
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-left\-column
|
||||
Print only the left column of two common lines.
|
||||
.TP
|
||||
.B \-\-minimal
|
||||
Change the algorithm to perhaps find a smaller set of changes. This
|
||||
makes
|
||||
.I sdiff
|
||||
slower (sometimes much slower).
|
||||
.TP
|
||||
.BI "\-o " file
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-output= file
|
||||
Put merged output into
|
||||
.IR file .
|
||||
This option is required for merging.
|
||||
.TP
|
||||
.B \-s
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-suppress\-common\-lines
|
||||
Do not print common lines.
|
||||
.TP
|
||||
.B \-\-speed\-large\-files
|
||||
Use heuristics to speed handling of large files that have numerous
|
||||
scattered small changes.
|
||||
.TP
|
||||
.B \-t
|
||||
Expand tabs to spaces in the output, to preserve the alignment of tabs
|
||||
in the input files.
|
||||
.TP
|
||||
.B \-\-text
|
||||
Treat all files as text and compare them line-by-line, even if they
|
||||
do not appear to be text.
|
||||
.TP
|
||||
.B \-v
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.B \-\-version
|
||||
Output the version number of
|
||||
.IR sdiff .
|
||||
.TP
|
||||
.BI "\-w " columns
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-\-width= columns
|
||||
Use an output width of
|
||||
.IR columns .
|
||||
Note that for historical reasons, this option is
|
||||
.B \-W
|
||||
in
|
||||
.IR diff ,
|
||||
.B \-w
|
||||
in
|
||||
.IR sdiff .
|
||||
.TP
|
||||
.B \-W
|
||||
Ignore horizontal white space when comparing lines.
|
||||
Note that for historical reasons, this option is
|
||||
.B \-w
|
||||
in
|
||||
.IR diff ,
|
||||
.B \-W
|
||||
in
|
||||
.IR sdiff .
|
||||
.SH SEE ALSO
|
||||
cmp(1), comm(1), diff(1), diff3(1).
|
||||
|
||||
The
|
||||
.B info
|
||||
documentation of
|
||||
.BR diff .
|
||||
.SH DIAGNOSTICS
|
||||
An exit status of 0 means no differences were found, 1 means some
|
||||
differences were found, and 2 means trouble.
|
Loading…
Reference in New Issue
Block a user