mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.1.0360: using an external diff program is slow and inflexible
Problem: Using an external diff program is slow and inflexible. Solution: Include the xdiff library. (Christian Brabandt, closes #2732) Use it by default.
This commit is contained in:
14
Filelist
14
Filelist
@@ -273,6 +273,20 @@ SRC_ALL = \
|
||||
src/libvterm/t/92lp1640917.test \
|
||||
src/libvterm/t/harness.c \
|
||||
src/libvterm/t/run-test.pl \
|
||||
src/xdiff/xdiff.h \
|
||||
src/xdiff/xdiffi.c \
|
||||
src/xdiff/xdiffi.h \
|
||||
src/xdiff/xemit.c \
|
||||
src/xdiff/xemit.h \
|
||||
src/xdiff/xhistogram.c \
|
||||
src/xdiff/xinclude.h \
|
||||
src/xdiff/xmacros.h \
|
||||
src/xdiff/xpatience.c \
|
||||
src/xdiff/xprepare.c \
|
||||
src/xdiff/xprepare.h \
|
||||
src/xdiff/xtypes.h \
|
||||
src/xdiff/xutils.c \
|
||||
src/xdiff/xutils.h \
|
||||
|
||||
|
||||
# source files for Unix only
|
||||
|
@@ -39,7 +39,9 @@ The second and following arguments may also be a directory name. Vim will
|
||||
then append the file name of the first argument to the directory name to find
|
||||
the file.
|
||||
|
||||
This only works when a standard "diff" command is available. See 'diffexpr'.
|
||||
By default an internal diff library will be used. When 'diffopt' or
|
||||
'diffexpr' has been set an external "diff" command will be used. This only
|
||||
works when such a diff program is available.
|
||||
|
||||
Diffs are local to the current tab page |tab-page|. You can't see diffs with
|
||||
a window in another tab page. This does make it possible to have several
|
||||
@@ -344,8 +346,9 @@ between file1 and file2: >
|
||||
|
||||
The ">" is replaced with the value of 'shellredir'.
|
||||
|
||||
The output of "diff" must be a normal "ed" style diff. Do NOT use a context
|
||||
diff. This example explains the format that Vim expects: >
|
||||
The output of "diff" must be a normal "ed" style diff or a unified diff. Do
|
||||
NOT use a context diff. This example explains the format that Vim expects for
|
||||
the "ed" style diff: >
|
||||
|
||||
1a2
|
||||
> bbb
|
||||
|
@@ -2609,8 +2609,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
{not in Vi}
|
||||
{not available when compiled without the |+diff|
|
||||
feature}
|
||||
Expression which is evaluated to obtain an ed-style diff file from two
|
||||
versions of a file. See |diff-diffexpr|.
|
||||
Expression which is evaluated to obtain a diff file (either ed-style
|
||||
or unified-style) from two versions of a file. See |diff-diffexpr|.
|
||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||
security reasons.
|
||||
|
||||
@@ -2657,11 +2657,31 @@ A jump table for the options with a short description can be found at |Q_op|.
|
||||
foldcolumn:{n} Set the 'foldcolumn' option to {n} when
|
||||
starting diff mode. Without this 2 is used.
|
||||
|
||||
Examples: >
|
||||
internal Use the internal diff library. This is
|
||||
ignored when 'diffexpr' is set. *E960*
|
||||
When running out of memory when writing a
|
||||
buffer this item will be ignored for diffs
|
||||
involving that buffer. Set the 'verbose'
|
||||
option to see when this happens.
|
||||
|
||||
:set diffopt=filler,context:4
|
||||
indent-heuristic
|
||||
Use the indent heuristic for the internal
|
||||
diff library.
|
||||
|
||||
algorithm:{text} Use the specified diff algorithm with the
|
||||
internal diff engine. Currently supported
|
||||
algorithms are:
|
||||
myers the default algorithm
|
||||
minimal spend extra time to generate the
|
||||
smallest possible diff
|
||||
patience patience diff algorithm
|
||||
histogram histogram diff algorithm
|
||||
|
||||
Examples: >
|
||||
:set diffopt=internal,filler,context:4
|
||||
:set diffopt=
|
||||
:set diffopt=filler,foldcolumn:3
|
||||
:set diffopt=internal,filler,foldcolumn:3
|
||||
:set diffopt-=internal " do NOT use the internal diff parser
|
||||
<
|
||||
*'digraph'* *'dg'* *'nodigraph'* *'nodg'*
|
||||
'digraph' 'dg' boolean (default off)
|
||||
|
@@ -166,6 +166,25 @@ else
|
||||
ifndef CROSS_COMPILE
|
||||
CROSS_COMPILE =
|
||||
endif
|
||||
|
||||
# About the "sh.exe" condition, as explained by Ken Takata:
|
||||
#
|
||||
# If the makefile is executed with mingw32-make and sh.exe is not found in
|
||||
# $PATH, then $SHELL is set to "sh.exe" (without any path). In this case,
|
||||
# unix-like commands might not work and a dos-style path is needed.
|
||||
#
|
||||
# If the makefile is executed with mingw32-make and sh.exe IS found in $PATH,
|
||||
# then $SHELL is set with the actual path of sh.exe (e.g.
|
||||
# "C:/msys64/usr/bin/sh.exe"). In this case, unix-like commands can be used.
|
||||
#
|
||||
# If it is executed by the "make" command from cmd.exe, $SHELL is set to
|
||||
# "/bin/sh". If the "make" command is in the $PATH, other unix-like commands
|
||||
# might also work.
|
||||
#
|
||||
# If it is executed by the "make" command from a unix-like shell,
|
||||
# $SHELL is set with the unix-style path (e.g. "/bin/bash").
|
||||
# In this case, unix-like commands can be used.
|
||||
#
|
||||
ifneq (sh.exe, $(SHELL))
|
||||
DEL = rm
|
||||
MKDIR = mkdir -p
|
||||
@@ -810,6 +829,23 @@ OBJ += $(OUTDIR)/terminal.o \
|
||||
$(OUTDIR)/term_vterm.o
|
||||
endif
|
||||
|
||||
# Include xdiff
|
||||
OBJ += $(OUTDIR)/xdiffi.o \
|
||||
$(OUTDIR)/xemit.o \
|
||||
$(OUTDIR)/xprepare.o \
|
||||
$(OUTDIR)/xutils.o \
|
||||
$(OUTDIR)/xhistogram.o \
|
||||
$(OUTDIR)/xpatience.o
|
||||
|
||||
XDIFF_DEPS = \
|
||||
xdiff/xdiff.h \
|
||||
xdiff/xdiffi.h \
|
||||
xdiff/xemit.h \
|
||||
xdiff/xinclude.h \
|
||||
xdiff/xmacros.h \
|
||||
xdiff/xprepare.h \
|
||||
xdiff/xtypes.h \
|
||||
xdiff/xutils.h
|
||||
|
||||
ifdef MZSCHEME
|
||||
MZSCHEME_SUFFIX = Z
|
||||
@@ -1055,6 +1091,23 @@ $(OUTDIR)/term_unicode.o: libvterm/src/unicode.c $(TERM_DEPS)
|
||||
$(OUTDIR)/term_vterm.o: libvterm/src/vterm.c $(TERM_DEPS)
|
||||
$(CCCTERM) libvterm/src/vterm.c -o $@
|
||||
|
||||
$(OUTDIR)/xdiffi.o: xdiff/xdiffi.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xdiffi.c -o $(OUTDIR)/xdiffi.o
|
||||
|
||||
$(OUTDIR)/xemit.o: xdiff/xemit.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xemit.c -o $(OUTDIR)/xemit.o
|
||||
|
||||
$(OUTDIR)/xprepare.o: xdiff/xprepare.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xprepare.c -o $(OUTDIR)/xprepare.o
|
||||
|
||||
$(OUTDIR)/xutils.o: xdiff/xutils.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xutils.c -o $(OUTDIR)/xutils.o
|
||||
|
||||
$(OUTDIR)/xhistogram.o: xdiff/xhistogram.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xhistogram.c -o $(OUTDIR)/xhistogram.o
|
||||
|
||||
$(OUTDIR)/xpatience.o: xdiff/xpatience.c $(XDIFF_DEPS)
|
||||
$(CC) -c $(CFLAGS) xdiff/xpatience.c -o $(OUTDIR)/xpatience.o
|
||||
|
||||
pathdef.c: $(INCL)
|
||||
ifneq (sh.exe, $(SHELL))
|
||||
|
@@ -813,6 +813,24 @@ CUI_OBJ = $(OUTDIR)\iscygpty.obj
|
||||
!endif
|
||||
SUBSYSTEM_TOOLS = console
|
||||
|
||||
XDIFF_OBJ = $(OBJDIR)/xdiffi.obj \
|
||||
$(OBJDIR)/xemit.obj \
|
||||
$(OBJDIR)/xprepare.obj \
|
||||
$(OBJDIR)/xutils.obj \
|
||||
$(OBJDIR)/xhistogram.obj \
|
||||
$(OBJDIR)/xpatience.obj
|
||||
|
||||
XDIFF_DEPS = \
|
||||
xdiff/xdiff.h \
|
||||
xdiff/xdiffi.h \
|
||||
xdiff/xemit.h \
|
||||
xdiff/xinclude.h \
|
||||
xdiff/xmacros.h \
|
||||
xdiff/xprepare.h \
|
||||
xdiff/xtypes.h \
|
||||
xdiff/xutils.h
|
||||
|
||||
|
||||
!if "$(SUBSYSTEM_VER)" != ""
|
||||
SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER)
|
||||
SUBSYSTEM_TOOLS = $(SUBSYSTEM_TOOLS),$(SUBSYSTEM_VER)
|
||||
@@ -1204,12 +1222,12 @@ all: $(VIM).exe \
|
||||
tee/tee.exe \
|
||||
GvimExt/gvimext.dll
|
||||
|
||||
$(VIM).exe: $(OUTDIR) $(OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
||||
$(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \
|
||||
$(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \
|
||||
$(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \
|
||||
version.c version.h
|
||||
$(CC) $(CFLAGS_OUTDIR) version.c
|
||||
$(link) $(LINKARGS1) -out:$(VIM).exe $(OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
||||
$(link) $(LINKARGS1) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \
|
||||
$(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \
|
||||
$(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \
|
||||
$(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2)
|
||||
@@ -1304,6 +1322,7 @@ $(NEW_TESTS):
|
||||
$(MAKE) /NOLOGO -f Make_dos.mak nolog
|
||||
$(MAKE) /NOLOGO -f Make_dos.mak $@.res
|
||||
$(MAKE) /NOLOGO -f Make_dos.mak report
|
||||
cat messages
|
||||
cd ..
|
||||
|
||||
###########################################################################
|
||||
@@ -1344,6 +1363,24 @@ $(OUTDIR)/dict.obj: $(OUTDIR) dict.c $(INCL)
|
||||
|
||||
$(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL)
|
||||
|
||||
$(OUTDIR)/xdiffi.obj: $(OUTDIR) xdiff/xdiffi.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xdiffi.c
|
||||
|
||||
$(OUTDIR)/xemit.obj: $(OUTDIR) xdiff/xemit.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xemit.c
|
||||
|
||||
$(OUTDIR)/xprepare.obj: $(OUTDIR) xdiff/xprepare.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xprepare.c
|
||||
|
||||
$(OUTDIR)/xutils.obj: $(OUTDIR) xdiff/xutils.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xutils.c
|
||||
|
||||
$(OUTDIR)/xhistogram.obj: $(OUTDIR) xdiff/xhistogram.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xhistogram.c
|
||||
|
||||
$(OUTDIR)/xpatience.obj: $(OUTDIR) xdiff/xpatience.c $(XDIFF_DEPS)
|
||||
$(CC) $(CFLAGS_OUTDIR) xdiff/xpatience.c
|
||||
|
||||
$(OUTDIR)/digraph.obj: $(OUTDIR) digraph.c $(INCL)
|
||||
|
||||
$(OUTDIR)/edit.obj: $(OUTDIR) edit.c $(INCL)
|
||||
|
53
src/Makefile
53
src/Makefile
@@ -1400,6 +1400,32 @@ TERM_DEPS = \
|
||||
|
||||
TERM_SRC = libvterm/src/*.c
|
||||
|
||||
XDIFF_SRC = \
|
||||
xdiff/xdiffi.c \
|
||||
xdiff/xemit.c \
|
||||
xdiff/xprepare.c \
|
||||
xdiff/xutils.c \
|
||||
xdiff/xhistogram.c \
|
||||
xdiff/xpatience.c \
|
||||
|
||||
XDIFF_OBJS = \
|
||||
objects/xdiffi.o \
|
||||
objects/xemit.o \
|
||||
objects/xprepare.o \
|
||||
objects/xutils.o \
|
||||
objects/xhistogram.o \
|
||||
objects/xpatience.o \
|
||||
|
||||
XDIFF_INCL = \
|
||||
xdiff/xdiff.h \
|
||||
xdiff/xdiffi.h \
|
||||
xdiff/xemit.h \
|
||||
xdiff/xinclude.h \
|
||||
xdiff/xmacros.h \
|
||||
xdiff/xprepare.h \
|
||||
xdiff/xtypes.h \
|
||||
xdiff/xutils.h \
|
||||
|
||||
### Command to create dependencies based on #include "..."
|
||||
### prototype headers are ignored due to -DPROTO, system
|
||||
### headers #include <...> are ignored if we use the -MM option, as
|
||||
@@ -1611,6 +1637,7 @@ BASIC_SRC = \
|
||||
SRC = $(BASIC_SRC) \
|
||||
$(GUI_SRC) \
|
||||
$(TERM_SRC) \
|
||||
$(XDIFF_SRC) \
|
||||
$(HANGULIN_SRC) \
|
||||
$(LUA_SRC) \
|
||||
$(MZSCHEME_SRC) \
|
||||
@@ -1728,6 +1755,7 @@ OBJ_COMMON = \
|
||||
$(WORKSHOP_OBJ) \
|
||||
$(NETBEANS_OBJ) \
|
||||
$(CHANNEL_OBJ) \
|
||||
$(XDIFF_OBJS) \
|
||||
$(WSDEBUG_OBJ)
|
||||
|
||||
# The files included by tests are not in OBJ_COMMON.
|
||||
@@ -2731,7 +2759,7 @@ SHADOWDIR = shadow
|
||||
|
||||
shadow: runtime pixmaps
|
||||
$(MKDIR_P) $(SHADOWDIR)
|
||||
cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../libvterm ../vimtutor ../gvimtutor ../install-sh ../Make_all.mak .
|
||||
cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../xdiff ../libvterm ../vimtutor ../gvimtutor ../install-sh ../Make_all.mak .
|
||||
mkdir $(SHADOWDIR)/auto
|
||||
cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
|
||||
$(MKDIR_P) $(SHADOWDIR)/po
|
||||
@@ -2915,7 +2943,7 @@ objects/crypt_zip.o: crypt_zip.c
|
||||
objects/dict.o: dict.c
|
||||
$(CCC) -o $@ dict.c
|
||||
|
||||
objects/diff.o: diff.c
|
||||
objects/diff.o: diff.c $(XDIFF_INCL)
|
||||
$(CCC) -o $@ diff.c
|
||||
|
||||
objects/digraph.o: digraph.c
|
||||
@@ -3229,6 +3257,27 @@ objects/term_unicode.o: libvterm/src/unicode.c $(TERM_DEPS)
|
||||
objects/term_vterm.o: libvterm/src/vterm.c $(TERM_DEPS)
|
||||
$(CCCTERM) -o $@ libvterm/src/vterm.c
|
||||
|
||||
CCCDIFF = $(CCC_NF) $(ALL_CFLAGS)
|
||||
|
||||
objects/xdiffi.o: xdiff/xdiffi.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xdiffi.c
|
||||
|
||||
objects/xprepare.o: xdiff/xprepare.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xprepare.c
|
||||
|
||||
objects/xutils.o: xdiff/xutils.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xutils.c
|
||||
|
||||
objects/xemit.o: xdiff/xemit.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xemit.c
|
||||
|
||||
objects/xhistogram.o: xdiff/xhistogram.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xhistogram.c
|
||||
|
||||
objects/xpatience.o: xdiff/xpatience.c $(XDIFF_INCL)
|
||||
$(CCCDIFF) -o $@ xdiff/xpatience.c
|
||||
|
||||
|
||||
###############################################################################
|
||||
### MacOS X installation
|
||||
###
|
||||
|
831
src/diff.c
831
src/diff.c
File diff suppressed because it is too large
Load Diff
@@ -2433,7 +2433,9 @@ struct file_buffer
|
||||
term_T *b_term; /* When not NULL this buffer is for a terminal
|
||||
* window. */
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_DIFF
|
||||
int b_diff_failed; // internal diff failed for this buffer
|
||||
#endif
|
||||
}; /* file_buffer */
|
||||
|
||||
|
||||
|
20
src/testdir/dumps/Test_diff_01.dump
Normal file
20
src/testdir/dumps/Test_diff_01.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|0+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |7|-@19||+1#0000000#ffffff0|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |7|-@19
|
||||
| @1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_02.dump
Normal file
20
src/testdir/dumps/Test_diff_02.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1|0+0#0000000#5fd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |7|-@19||+1#0000000#ffffff0|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |7|-@19
|
||||
| @1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_03.dump
Normal file
20
src/testdir/dumps/Test_diff_03.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |1|-@19||+1#0000000#ffffff0|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |1|-@19
|
||||
| @1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|1+0#0000000#5fd7ff255@1| @32
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_04.dump
Normal file
20
src/testdir/dumps/Test_diff_04.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |1|-@19||+1#0000000#ffffff0|++0#0000e05#a8a8a8255| |+|-@1| @1|4| |l|i|n|e|s|:| |1|-@19
|
||||
| @1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#5fd7ff255@1| @32||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_05.dump
Normal file
20
src/testdir/dumps/Test_diff_05.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|4+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#5fd7ff255@1| @32||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_06.dump
Normal file
20
src/testdir/dumps/Test_diff_06.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|2+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|3+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|4+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|4+0#0000000#5fd7ff255| @33||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|5+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|6+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|7+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|8+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|9+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32||+1&&| +0#0000e05#a8a8a8255@1|1+0#0000000#ffffff0|0| @32
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|1+0#0000000#5fd7ff255@1| @32
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_07.dump
Normal file
20
src/testdir/dumps/Test_diff_07.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1>#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16||+1&&| +0#0000e05#a8a8a8255@1|#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|/+2#0000000#ff404010@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| +0&#ffd7ff255@13||+1&#ffffff0| +0#0000e05#a8a8a8255@1|i+2#0000000#ff404010|n|t| |f|i|b|(|i|n|t| |n|)| +0&#ffd7ff255@20
|
||||
| +0#0000e05#a8a8a8255@1|i+0#0000000#5fd7ff255|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@3|i|n+2&#ff404010|t| |i|;| +0&#ffd7ff255@24||+1&#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@3|i|f+2&#ff404010|(|n| |>| |2|)| +0&#ffd7ff255@21
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|f|o|r|(|i| |=| |0|;| |i| |<| |1|0|;| |i|+@1|)| @7||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@7|p+2&#ff404010|r|i|n|t|f|(|"|Y|o|u|r| |a|n|s|w|e|r| |i|s|:| |"|)+0&#ffd7ff255|;||+1&#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@7|r+2&#ff404010|e|t|u|r|n| |f|i|b|(|n|-|1|)| |+| |f|i|b|(|n|-|2|)+0&#ffd7ff255|;
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@7|p|r|i|n|t|f|(|"|%|d|\|n|"|,| |f|o@1|)|;| @6||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|}| @29||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|}| @29
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|r|e|t|u|r|n| |1|;| @21
|
||||
| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|i+2#0000000#ff404010|n|t| |f|a|c|t|(|i|n|t| |n|)| +0&#ffd7ff255@19||+1&#ffffff0| +0#0000e05#a8a8a8255@1|/+2#0000000#ff404010@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| +0&#ffd7ff255@13
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|i+0#0000000#5fd7ff255|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@3|i|f+2&#ff404010|(|n| |>| |1|)| +0&#ffd7ff255@21||+1&#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#ffd7ff255@3|i|n+2&#ff404010|t| |i|;| +0&#ffd7ff255@24
|
||||
|X+3&#ffffff0|f|i|l|e|1| @12|1|,|1| @11|T|o|p| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|T|o|p
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|i|n|t|e|r|n|a|l| @52
|
20
src/testdir/dumps/Test_diff_08.dump
Normal file
20
src/testdir/dumps/Test_diff_08.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1>#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16||+1&&| +0#0000e05#a8a8a8255@1|#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|i+0#0000000#5fd7ff255|n|t| |f|i|b|(|i|n|t| |n|)| @20
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|{+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|i|f|(|n| |>| |2|)| @21
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|{| @29
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@7|r|e|t|u|r|n| |f|i|b|(|n|-|1|)| |+| |f|i|b|(|n|-|2|)|;
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|}| @29
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|r|e|t|u|r|n| |1|;| @21
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|}+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@34
|
||||
| +0#0000e05#a8a8a8255@1|/+0#0000000#ffffff0@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| @13||+1&&| +0#0000e05#a8a8a8255@1|/+0#0000000#ffffff0@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| @13
|
||||
| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13||+1&&| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i|n|t| |i|;| @24||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i|n|t| |i|;| @24
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|f|o|r|(|i| |=| |0|;| |i| |<| |1|0|;| |i|+@1|)| @7||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|f|o|r|(|i| |=| |0|;| |i| |<| |1|0|;| |i|+@1|)| @7
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@7|p|r|i|n|t|f|(|"|Y|o|u|r| |a|n|s|w|e|r| |i|s|:| |"|)|;||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
|X+3#0000000#ffffff0|f|i|l|e|1| @12|1|,|1| @11|T|o|p| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|T|o|p
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|a|l|g|o|r|i|t|h|m|:|p|a|t|i|e|n|c|e| @42
|
20
src/testdir/dumps/Test_diff_09.dump
Normal file
20
src/testdir/dumps/Test_diff_09.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1>#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16||+1&&| +0#0000e05#a8a8a8255@1|#+0#0000000#ffffff0|i|n|c|l|u|d|e| |<|s|t|d|i|o|.|h|>| @16
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|i+0#0000000#5fd7ff255|n|t| |f|i|b|(|i|n|t| |n|)| @20
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|{+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|i|f|(|n| |>| |2|)| @21
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|{| @29
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@7|r|e|t|u|r|n| |f|i|b|(|n|-|1|)| |+| |f|i|b|(|n|-|2|)|;
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|}| @29
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|r|e|t|u|r|n| |1|;| @21
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1|}+0#0000000#5fd7ff255| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@34
|
||||
| +0#0000e05#a8a8a8255@1|/+0#0000000#ffffff0@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| @13||+1&&| +0#0000e05#a8a8a8255@1|/+0#0000000#ffffff0@1| |F|r|o|b|s| |f|o@1| |h|e|a|r|t|i|l|y| @13
|
||||
| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13||+1&&| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |f|r|o|b|n|i|t|z|(|i|n|t| |f|o@1|)| @13
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i|n|t| |i|;| @24||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|i|n|t| |i|;| @24
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|f|o|r|(|i| |=| |0|;| |i| |<| |1|0|;| |i|+@1|)| @7||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|f|o|r|(|i| |=| |0|;| |i| |<| |1|0|;| |i|+@1|)| @7
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|{| @29
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@7|p|r|i|n|t|f|(|"|Y|o|u|r| |a|n|s|w|e|r| |i|s|:| |"|)|;||+1&#ffffff0| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34
|
||||
|X+3#0000000#ffffff0|f|i|l|e|1| @12|1|,|1| @11|T|o|p| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|T|o|p
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|a|l|g|o|r|i|t|h|m|:|p|a|t|i|e|n|c|e| @42
|
20
src/testdir/dumps/Test_diff_10.dump
Normal file
20
src/testdir/dumps/Test_diff_10.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@1|d|e|f| |f|i|n|a|l|i|z|e|(|v|a|l|u|e|s|)| @12||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@1|d|e|f| |f|i|n|a|l|i|z|e|(|v|a|l|u|e|s|)| @12
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@5|v|.|p|r|e|p|a|r|e| @19
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|e|n|d| @27
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@34
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|v|.|f|i|n|a|l|i|z|e| @18||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|v|.|f|i|n|a|l|i|z|e| @18
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|e|n|d| @27||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|e|n|d| @27
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|0|-|1| @9|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|0|-|1| @9|A|l@1
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|i|n|t|e|r|n|a|l| @52
|
20
src/testdir/dumps/Test_diff_11.dump
Normal file
20
src/testdir/dumps/Test_diff_11.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1> +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@1|d|e|f| |f|i|n|a|l|i|z|e|(|v|a|l|u|e|s|)| @12||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@1|d|e|f| |f|i|n|a|l|i|z|e|(|v|a|l|u|e|s|)| @12
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@5|v|.|p|r|e|p|a|r|e| @19
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@3|e|n|d| @27
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@34
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|v|a|l|u|e|s|.|e|a|c|h| |d|o| |||v||| @12
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|v|.|f|i|n|a|l|i|z|e| @18||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|v|.|f|i|n|a|l|i|z|e| @18
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|e|n|d| @27||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@3|e|n|d| @27
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|0|-|1| @9|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|0|-|1| @9|A|l@1
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|i|n|d|e|n|t|-|h|e|u|r|i|s|t|i|c| @44
|
20
src/testdir/dumps/Test_diff_12.dump
Normal file
20
src/testdir/dumps/Test_diff_12.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
|++0#0000e05#a8a8a8255| |+|-@1| |1|0| |l|i|n|e|s|:| |1|-@19||+1#0000000#ffffff0|++0#0000e05#a8a8a8255| |+|-@1| |1|0| |l|i|n|e|s|:| |1|-@19
|
||||
| @1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_13.dump
Normal file
20
src/testdir/dumps/Test_diff_13.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@34||+1&&|-+0#0000e05#a8a8a8255| | +0#0000000#ffffff0@34
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|0|,|0|-|1| @9|A|l@1| |X+1&&|f|i|l|e|2| @12|0|,|0|-|1| @9|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_14.dump
Normal file
20
src/testdir/dumps/Test_diff_14.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1|a+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|A+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|b+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|d| @32||+1&#ffffff0| +0#0000e05#a8a8a8255@1|c+0#0000000#ffd7ff255|D|e+2&#ff404010| +0&#ffd7ff255@31
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&> @73
|
20
src/testdir/dumps/Test_diff_15.dump
Normal file
20
src/testdir/dumps/Test_diff_15.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1>i+0#0000000#ffffff0|n|t| |m|a|i|n|(|)| @24||+1&&| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |m|a|i|n|(|)| @24
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|i|f| |(|0|)| @25
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|{| @30
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@2|p|r|i|n|t|f|(|"|H|e|l@1|o|,| |W|o|r|l|d|!|"|)|;| @7||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|p|r|i|n|t|f|(|"|H|e|l@1|o|,| |W|o|r|l|d|!|"|)|;| @4
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@2|r|e|t|u|r|n| |0|;| @22||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|r|e|t|u|r|n| |0|;| @19
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|}| @30
|
||||
| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|&|v|i|m| |d|i|f@1|o|p|t|+|=|f|i|l@1|e|r| |d|i|f@1|o|p|t|+|=|i|w|h|i|t|e| @26
|
20
src/testdir/dumps/Test_diff_16.dump
Normal file
20
src/testdir/dumps/Test_diff_16.dump
Normal file
@@ -0,0 +1,20 @@
|
||||
| +0#0000e05#a8a8a8255@1>i+0#0000000#ffffff0|n|t| |m|a|i|n|(|)| @24||+1&&| +0#0000e05#a8a8a8255@1|i+0#0000000#ffffff0|n|t| |m|a|i|n|(|)| @24
|
||||
| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|{+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|i|f| |(|0|)| @25
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|{| @30
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@2|p|r|i|n|t|f|(|"|H|e|l@1|o|,| |W|o|r|l|d|!|"|)|;| @7||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|p|r|i|n|t|f|(|"|H|e|l@1|o|,| |W|o|r|l|d|!|"|)|;| @4
|
||||
| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@2|r|e|t|u|r|n| |0|;| @22||+1&&| +0#0000e05#a8a8a8255@1| +0#0000000#ffffff0@5|r|e|t|u|r|n| |0|;| @19
|
||||
| +0#0000e05#a8a8a8255@1|-+0#4040ff13#afffff255@34||+1#0000000#ffffff0| +0#0000e05#a8a8a8255@1| +0#0000000#5fd7ff255@2|}| @30
|
||||
| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33||+1&&| +0#0000e05#a8a8a8255@1|}+0#0000000#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33||+1#0000000&| +0#0000e05#a8a8a8255@1|~+0#4040ff13#ffffff0| @33
|
||||
|X+3#0000000&|f|i|l|e|1| @12|1|,|1| @11|A|l@1| |X+1&&|f|i|l|e|2| @12|1|,|1| @11|A|l@1
|
||||
|:+0&&|s|e|t| |d|i|f@1|o|p|t|+|=|i|n|t|e|r|n|a|l| @52
|
@@ -1,4 +1,6 @@
|
||||
" Tests for diff mode
|
||||
source shared.vim
|
||||
source screendump.vim
|
||||
|
||||
func Test_diff_fold_sync()
|
||||
enew!
|
||||
@@ -33,6 +35,18 @@ func Test_diff_fold_sync()
|
||||
endfunc
|
||||
|
||||
func Test_vert_split()
|
||||
set diffopt=filler
|
||||
call Common_vert_split()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
func Test_vert_split_internal()
|
||||
set diffopt=internal,filler
|
||||
call Common_vert_split()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
func Common_vert_split()
|
||||
" Disable the title to avoid xterm keeping the wrong one.
|
||||
set notitle noicon
|
||||
new
|
||||
@@ -275,10 +289,8 @@ func Test_diffoff()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_icase()
|
||||
set diffopt=icase,foldcolumn:0
|
||||
|
||||
e one
|
||||
func Common_icase_test()
|
||||
edit one
|
||||
call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve'])
|
||||
redraw
|
||||
let normattr = screenattr(1, 1)
|
||||
@@ -300,32 +312,54 @@ func Test_diffopt_icase()
|
||||
|
||||
diffoff!
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_icase()
|
||||
set diffopt=icase,foldcolumn:0
|
||||
call Common_icase_test()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_iwhite()
|
||||
set diffopt=iwhite,foldcolumn:0
|
||||
func Test_diffopt_icase_internal()
|
||||
set diffopt=icase,foldcolumn:0,internal
|
||||
call Common_icase_test()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
e one
|
||||
" Difference in trailing spaces should be ignored,
|
||||
func Common_iwhite_test()
|
||||
edit one
|
||||
" Difference in trailing spaces and amount of spaces should be ignored,
|
||||
" but not other space differences.
|
||||
call setline(1, ["One \t", 'Two', 'Three', 'Four'])
|
||||
call setline(1, ["One \t", 'Two', 'Three', 'one two', 'one two', 'Four'])
|
||||
redraw
|
||||
let normattr = screenattr(1, 1)
|
||||
diffthis
|
||||
|
||||
botright vert new two
|
||||
call setline(1, ["One\t ", "Two\t ", 'Three', ' Four'])
|
||||
call setline(1, ["One\t ", "Two\t ", 'Three', 'one two', 'onetwo', ' Four'])
|
||||
diffthis
|
||||
|
||||
redraw
|
||||
call assert_equal(normattr, screenattr(1, 1))
|
||||
call assert_equal(normattr, screenattr(2, 1))
|
||||
call assert_equal(normattr, screenattr(3, 1))
|
||||
call assert_notequal(normattr, screenattr(4, 1))
|
||||
call assert_equal(normattr, screenattr(4, 1))
|
||||
call assert_notequal(normattr, screenattr(5, 1))
|
||||
call assert_notequal(normattr, screenattr(6, 1))
|
||||
|
||||
diffoff!
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_iwhite()
|
||||
set diffopt=iwhite,foldcolumn:0
|
||||
call Common_iwhite_test()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_iwhite_internal()
|
||||
set diffopt=internal,iwhite,foldcolumn:0
|
||||
call Common_iwhite_test()
|
||||
set diffopt&
|
||||
endfunc
|
||||
|
||||
@@ -339,8 +373,13 @@ func Test_diffopt_context()
|
||||
|
||||
set diffopt=context:2
|
||||
call assert_equal('+-- 2 lines: 1', foldtextresult(1))
|
||||
set diffopt=internal,context:2
|
||||
call assert_equal('+-- 2 lines: 1', foldtextresult(1))
|
||||
|
||||
set diffopt=context:1
|
||||
call assert_equal('+-- 3 lines: 1', foldtextresult(1))
|
||||
set diffopt=internal,context:1
|
||||
call assert_equal('+-- 3 lines: 1', foldtextresult(1))
|
||||
|
||||
diffoff!
|
||||
%bwipe!
|
||||
@@ -348,7 +387,7 @@ func Test_diffopt_context()
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_horizontal()
|
||||
set diffopt=horizontal
|
||||
set diffopt=internal,horizontal
|
||||
diffsplit
|
||||
|
||||
call assert_equal(&columns, winwidth(1))
|
||||
@@ -362,7 +401,7 @@ func Test_diffopt_horizontal()
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_vertical()
|
||||
set diffopt=vertical
|
||||
set diffopt=internal,vertical
|
||||
diffsplit
|
||||
|
||||
call assert_equal(&lines - 2, winheight(1))
|
||||
@@ -376,7 +415,7 @@ func Test_diffopt_vertical()
|
||||
endfunc
|
||||
|
||||
func Test_diffopt_hiddenoff()
|
||||
set diffopt=filler,foldcolumn:0,hiddenoff
|
||||
set diffopt=internal,filler,foldcolumn:0,hiddenoff
|
||||
e! one
|
||||
call setline(1, ['Two', 'Three'])
|
||||
redraw
|
||||
@@ -399,7 +438,7 @@ func Test_diffopt_hiddenoff()
|
||||
endfunc
|
||||
|
||||
func Test_diffoff_hidden()
|
||||
set diffopt=filler,foldcolumn:0
|
||||
set diffopt=internal,filler,foldcolumn:0
|
||||
e! one
|
||||
call setline(1, ['Two', 'Three'])
|
||||
redraw
|
||||
@@ -629,3 +668,118 @@ func Test_diff_lastline()
|
||||
bwipe!
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func WriteDiffFiles(list1, list2)
|
||||
call writefile(a:list1, 'Xfile1')
|
||||
call writefile(a:list2, 'Xfile2')
|
||||
endfunc
|
||||
|
||||
" Verify a screendump with both the external and external diff.
|
||||
func VerifyBoth(buf, dumpfile, extra)
|
||||
call term_sendkeys(a:buf, ":diffupdate!\<cr>")
|
||||
" trailing : for leaving the cursor on the command line
|
||||
for cmd in [":set diffopt=filler" . a:extra . "\<cr>:", ":set diffopt+=internal\<cr>:"]
|
||||
call term_sendkeys(a:buf, cmd)
|
||||
if VerifyScreenDump(a:buf, a:dumpfile, {}, cmd =~ 'internal' ? 'internal' : 'external')
|
||||
break " don't let the next iteration overwrite the "failed" file.
|
||||
endif
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
func Test_diff_screen()
|
||||
if !CanRunVimInTerminal() || !has('menu')
|
||||
return
|
||||
endif
|
||||
" clean up already existing swap files, just in case
|
||||
call delete('.Xfile1.swp')
|
||||
call delete('.Xfile2.swp')
|
||||
|
||||
" Test 1: Add a line in beginning of file 2
|
||||
call WriteDiffFiles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
let buf = RunVimInTerminal('-d Xfile1 Xfile2', {})
|
||||
" Set autoread mode, ,so that Vim won't complain once we re-write the test
|
||||
" files
|
||||
call term_sendkeys(buf, ":set autoread\<cr>\<c-w>w:set autoread\<cr>\<c-w>w")
|
||||
|
||||
call VerifyBoth(buf, 'Test_diff_01', '')
|
||||
|
||||
" Test 2: Add a line in beginning of file 1
|
||||
call WriteDiffFiles([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
call VerifyBoth(buf, 'Test_diff_02', '')
|
||||
|
||||
" Test 3: Add a line at the end of file 2
|
||||
call WriteDiffFiles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
|
||||
call VerifyBoth(buf, 'Test_diff_03', '')
|
||||
|
||||
" Test 4: Add a line at the end of file 1
|
||||
call WriteDiffFiles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
call VerifyBoth(buf, 'Test_diff_04', '')
|
||||
|
||||
" Test 5: Add a line in the middle of file 2, remove on at the end of file 1
|
||||
call WriteDiffFiles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10])
|
||||
call VerifyBoth(buf, 'Test_diff_05', '')
|
||||
|
||||
" Test 6: Add a line in the middle of file 1, remove on at the end of file 2
|
||||
call WriteDiffFiles([1, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
|
||||
call VerifyBoth(buf, 'Test_diff_06', '')
|
||||
|
||||
" Test 7 - 9: Test normal/patience/histogram diff algorithm
|
||||
call WriteDiffFiles(['#include <stdio.h>', '', '// Frobs foo heartily', 'int frobnitz(int foo)', '{',
|
||||
\ ' int i;', ' for(i = 0; i < 10; i++)', ' {', ' printf("Your answer is: ");',
|
||||
\ ' printf("%d\n", foo);', ' }', '}', '', 'int fact(int n)', '{', ' if(n > 1)', ' {',
|
||||
\ ' return fact(n-1) * n;', ' }', ' return 1;', '}', '', 'int main(int argc, char **argv)',
|
||||
\ '{', ' frobnitz(fact(10));', '}'],
|
||||
\ ['#include <stdio.h>', '', 'int fib(int n)', '{', ' if(n > 2)', ' {',
|
||||
\ ' return fib(n-1) + fib(n-2);', ' }', ' return 1;', '}', '', '// Frobs foo heartily',
|
||||
\ 'int frobnitz(int foo)', '{', ' int i;', ' for(i = 0; i < 10; i++)', ' {',
|
||||
\ ' printf("%d\n", foo);', ' }', '}', '',
|
||||
\ 'int main(int argc, char **argv)', '{', ' frobnitz(fib(10));', '}'])
|
||||
call term_sendkeys(buf, ":diffupdate!\<cr>")
|
||||
call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_07', {})
|
||||
|
||||
call term_sendkeys(buf, ":set diffopt+=algorithm:patience\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_08', {})
|
||||
|
||||
call term_sendkeys(buf, ":set diffopt+=algorithm:histogram\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_09', {})
|
||||
|
||||
" Test 10-11: normal/indent-heuristic
|
||||
call term_sendkeys(buf, ":set diffopt&vim\<cr>")
|
||||
call WriteDiffFiles(['', ' def finalize(values)', '', ' values.each do |v|', ' v.finalize', ' end'],
|
||||
\ ['', ' def finalize(values)', '', ' values.each do |v|', ' v.prepare', ' end', '',
|
||||
\ ' values.each do |v|', ' v.finalize', ' end'])
|
||||
call term_sendkeys(buf, ":diffupdate!\<cr>")
|
||||
call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_10', {})
|
||||
|
||||
call term_sendkeys(buf, ":set diffopt+=indent-heuristic\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_11', {})
|
||||
|
||||
" Test 12: diff the same file
|
||||
call WriteDiffFiles([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
call VerifyBoth(buf, 'Test_diff_12', '')
|
||||
|
||||
" Test 13: diff an empty file
|
||||
call WriteDiffFiles([], [])
|
||||
call VerifyBoth(buf, 'Test_diff_13', '')
|
||||
|
||||
" Test 14: test diffopt+=icase
|
||||
call WriteDiffFiles(['a', 'b', 'cd'], ['A', 'b', 'cDe'])
|
||||
call VerifyBoth(buf, 'Test_diff_14', " diffopt+=filler diffopt+=icase")
|
||||
|
||||
" Test 15-16: test diffopt+=iwhite
|
||||
call WriteDiffFiles(['int main()', '{', ' printf("Hello, World!");', ' return 0;', '}'],
|
||||
\ ['int main()', '{', ' if (0)', ' {', ' printf("Hello, World!");', ' return 0;', ' }', '}'])
|
||||
call term_sendkeys(buf, ":diffupdate!\<cr>")
|
||||
call term_sendkeys(buf, ":set diffopt&vim diffopt+=filler diffopt+=iwhite\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_15', {})
|
||||
call term_sendkeys(buf, ":set diffopt+=internal\<cr>")
|
||||
call VerifyScreenDump(buf, 'Test_diff_16', {})
|
||||
|
||||
" clean up
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xfile1')
|
||||
call delete('Xfile2')
|
||||
endfunc
|
||||
|
||||
|
@@ -794,6 +794,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
360,
|
||||
/**/
|
||||
359,
|
||||
/**/
|
||||
|
504
src/xdiff/COPYING
Normal file
504
src/xdiff/COPYING
Normal file
@@ -0,0 +1,504 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
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.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
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 library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
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.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
14
src/xdiff/README.txt
Normal file
14
src/xdiff/README.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
The files in this directory come from the xdiff implementation in git.
|
||||
You can find it here: https://github.com/git/git/tree/master/xdiff
|
||||
The files were last updated 2018 September 10.
|
||||
|
||||
This is originally based on libxdiff, which can be found here:
|
||||
http://www.xmailserver.org/xdiff-lib.html
|
||||
|
||||
The git version was used because it has been maintained and improved.
|
||||
And since it's part of git it is expected to be reliable.
|
||||
|
||||
The code is distributed under the GNU LGPL license. It is included in the
|
||||
COPYING file.
|
||||
|
||||
The first work for including xdiff in Vim was done by Christian Brabandt.
|
142
src/xdiff/xdiff.h
Normal file
142
src/xdiff/xdiff.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XDIFF_H)
|
||||
#define XDIFF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
/* xpparm_t.flags */
|
||||
#define XDF_NEED_MINIMAL (1 << 0)
|
||||
|
||||
#define XDF_IGNORE_WHITESPACE (1 << 1)
|
||||
#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 2)
|
||||
#define XDF_IGNORE_WHITESPACE_AT_EOL (1 << 3)
|
||||
#define XDF_IGNORE_CR_AT_EOL (1 << 4)
|
||||
#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | \
|
||||
XDF_IGNORE_WHITESPACE_CHANGE | \
|
||||
XDF_IGNORE_WHITESPACE_AT_EOL | \
|
||||
XDF_IGNORE_CR_AT_EOL)
|
||||
|
||||
#define XDF_IGNORE_BLANK_LINES (1 << 7)
|
||||
|
||||
#define XDF_PATIENCE_DIFF (1 << 14)
|
||||
#define XDF_HISTOGRAM_DIFF (1 << 15)
|
||||
#define XDF_DIFF_ALGORITHM_MASK (XDF_PATIENCE_DIFF | XDF_HISTOGRAM_DIFF)
|
||||
#define XDF_DIFF_ALG(x) ((x) & XDF_DIFF_ALGORITHM_MASK)
|
||||
|
||||
#define XDF_INDENT_HEURISTIC (1 << 23)
|
||||
|
||||
/* xdemitconf_t.flags */
|
||||
#define XDL_EMIT_FUNCNAMES (1 << 0)
|
||||
#define XDL_EMIT_FUNCCONTEXT (1 << 2)
|
||||
|
||||
/* merge simplification levels */
|
||||
#define XDL_MERGE_MINIMAL 0
|
||||
#define XDL_MERGE_EAGER 1
|
||||
#define XDL_MERGE_ZEALOUS 2
|
||||
#define XDL_MERGE_ZEALOUS_ALNUM 3
|
||||
|
||||
/* merge favor modes */
|
||||
#define XDL_MERGE_FAVOR_OURS 1
|
||||
#define XDL_MERGE_FAVOR_THEIRS 2
|
||||
#define XDL_MERGE_FAVOR_UNION 3
|
||||
|
||||
/* merge output styles */
|
||||
#define XDL_MERGE_DIFF3 1
|
||||
|
||||
typedef struct s_mmfile {
|
||||
char *ptr;
|
||||
long size;
|
||||
} mmfile_t;
|
||||
|
||||
typedef struct s_mmbuffer {
|
||||
char *ptr;
|
||||
long size;
|
||||
} mmbuffer_t;
|
||||
|
||||
typedef struct s_xpparam {
|
||||
unsigned long flags;
|
||||
|
||||
/* See Documentation/diff-options.txt. */
|
||||
char **anchors;
|
||||
size_t anchors_nr;
|
||||
} xpparam_t;
|
||||
|
||||
typedef struct s_xdemitcb {
|
||||
void *priv;
|
||||
int (*outf)(void *, mmbuffer_t *, int);
|
||||
} xdemitcb_t;
|
||||
|
||||
typedef long (*find_func_t)(const char *line, long line_len, char *buffer, long buffer_size, void *priv);
|
||||
|
||||
typedef int (*xdl_emit_hunk_consume_func_t)(long start_a, long count_a,
|
||||
long start_b, long count_b,
|
||||
void *cb_data);
|
||||
|
||||
typedef struct s_xdemitconf {
|
||||
long ctxlen;
|
||||
long interhunkctxlen;
|
||||
unsigned long flags;
|
||||
find_func_t find_func;
|
||||
void *find_func_priv;
|
||||
xdl_emit_hunk_consume_func_t hunk_func;
|
||||
} xdemitconf_t;
|
||||
|
||||
typedef struct s_bdiffparam {
|
||||
long bsize;
|
||||
} bdiffparam_t;
|
||||
|
||||
|
||||
#define xdl_malloc(x) malloc(x)
|
||||
#define xdl_free(ptr) free(ptr)
|
||||
#define xdl_realloc(ptr,x) realloc(ptr,x)
|
||||
|
||||
void *xdl_mmfile_first(mmfile_t *mmf, long *size);
|
||||
long xdl_mmfile_size(mmfile_t *mmf);
|
||||
|
||||
int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdemitconf_t const *xecfg, xdemitcb_t *ecb);
|
||||
|
||||
typedef struct s_xmparam {
|
||||
xpparam_t xpp;
|
||||
int marker_size;
|
||||
int level;
|
||||
int favor;
|
||||
int style;
|
||||
const char *ancestor; /* label for orig */
|
||||
const char *file1; /* label for mf1 */
|
||||
const char *file2; /* label for mf2 */
|
||||
} xmparam_t;
|
||||
|
||||
#define DEFAULT_CONFLICT_MARKER_SIZE 7
|
||||
|
||||
int xdl_merge(mmfile_t *orig, mmfile_t *mf1, mmfile_t *mf2,
|
||||
xmparam_t const *xmp, mmbuffer_t *result);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* #ifdef __cplusplus */
|
||||
|
||||
#endif /* #if !defined(XDIFF_H) */
|
1043
src/xdiff/xdiffi.c
Normal file
1043
src/xdiff/xdiffi.c
Normal file
File diff suppressed because it is too large
Load Diff
64
src/xdiff/xdiffi.h
Normal file
64
src/xdiff/xdiffi.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XDIFFI_H)
|
||||
#define XDIFFI_H
|
||||
|
||||
|
||||
typedef struct s_diffdata {
|
||||
long nrec;
|
||||
unsigned long const *ha;
|
||||
long *rindex;
|
||||
char *rchg;
|
||||
} diffdata_t;
|
||||
|
||||
typedef struct s_xdalgoenv {
|
||||
long mxcost;
|
||||
long snake_cnt;
|
||||
long heur_min;
|
||||
} xdalgoenv_t;
|
||||
|
||||
typedef struct s_xdchange {
|
||||
struct s_xdchange *next;
|
||||
long i1, i2;
|
||||
long chg1, chg2;
|
||||
int ignore;
|
||||
} xdchange_t;
|
||||
|
||||
|
||||
|
||||
int xdl_recs_cmp(diffdata_t *dd1, long off1, long lim1,
|
||||
diffdata_t *dd2, long off2, long lim2,
|
||||
long *kvdf, long *kvdb, int need_min, xdalgoenv_t *xenv);
|
||||
int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *xe);
|
||||
int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags);
|
||||
int xdl_build_script(xdfenv_t *xe, xdchange_t **xscr);
|
||||
void xdl_free_script(xdchange_t *xscr);
|
||||
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg);
|
||||
int xdl_do_patience_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
int xdl_do_histogram_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *env);
|
||||
|
||||
#endif /* #if !defined(XDIFFI_H) */
|
312
src/xdiff/xemit.c
Normal file
312
src/xdiff/xemit.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xinclude.h"
|
||||
|
||||
static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
|
||||
|
||||
*rec = xdf->recs[ri]->ptr;
|
||||
|
||||
return xdf->recs[ri]->size;
|
||||
}
|
||||
|
||||
|
||||
static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
|
||||
long size, psize = strlen(pre);
|
||||
char const *rec;
|
||||
|
||||
size = xdl_get_rec(xdf, ri, &rec);
|
||||
if (xdl_emit_diffrec(rec, size, pre, psize, ecb) < 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Starting at the passed change atom, find the latest change atom to be included
|
||||
* inside the differential hunk according to the specified configuration.
|
||||
* Also advance xscr if the first changes must be discarded.
|
||||
*/
|
||||
xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg)
|
||||
{
|
||||
xdchange_t *xch, *xchp, *lxch;
|
||||
long max_common = 2 * xecfg->ctxlen + xecfg->interhunkctxlen;
|
||||
long max_ignorable = xecfg->ctxlen;
|
||||
unsigned long ignored = 0; /* number of ignored blank lines */
|
||||
|
||||
/* remove ignorable changes that are too far before other changes */
|
||||
for (xchp = *xscr; xchp && xchp->ignore; xchp = xchp->next) {
|
||||
xch = xchp->next;
|
||||
|
||||
if (xch == NULL ||
|
||||
xch->i1 - (xchp->i1 + xchp->chg1) >= max_ignorable)
|
||||
*xscr = xch;
|
||||
}
|
||||
|
||||
if (*xscr == NULL)
|
||||
return NULL;
|
||||
|
||||
lxch = *xscr;
|
||||
|
||||
for (xchp = *xscr, xch = xchp->next; xch; xchp = xch, xch = xch->next) {
|
||||
long distance = xch->i1 - (xchp->i1 + xchp->chg1);
|
||||
if (distance > max_common)
|
||||
break;
|
||||
|
||||
if (distance < max_ignorable && (!xch->ignore || lxch == xchp)) {
|
||||
lxch = xch;
|
||||
ignored = 0;
|
||||
} else if (distance < max_ignorable && xch->ignore) {
|
||||
ignored += xch->chg2;
|
||||
} else if (lxch != xchp &&
|
||||
xch->i1 + (long)ignored - (lxch->i1 + lxch->chg1) > max_common) {
|
||||
break;
|
||||
} else if (!xch->ignore) {
|
||||
lxch = xch;
|
||||
ignored = 0;
|
||||
} else {
|
||||
ignored += xch->chg2;
|
||||
}
|
||||
}
|
||||
|
||||
return lxch;
|
||||
}
|
||||
|
||||
|
||||
static long def_ff(const char *rec, long len, char *buf, long sz, void *priv UNUSED)
|
||||
{
|
||||
if (len > 0 &&
|
||||
(isalpha((unsigned char)*rec) || /* identifier? */
|
||||
*rec == '_' || /* also identifier? */
|
||||
*rec == '$')) { /* identifiers from VMS and other esoterico */
|
||||
if (len > sz)
|
||||
len = sz;
|
||||
while (0 < len && isspace((unsigned char)rec[len - 1]))
|
||||
len--;
|
||||
memcpy(buf, rec, len);
|
||||
return len;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static long match_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri,
|
||||
char *buf, long sz)
|
||||
{
|
||||
const char *rec;
|
||||
long len = xdl_get_rec(xdf, ri, &rec);
|
||||
if (!xecfg->find_func)
|
||||
return def_ff(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
return xecfg->find_func(rec, len, buf, sz, xecfg->find_func_priv);
|
||||
}
|
||||
|
||||
static int is_func_rec(xdfile_t *xdf, xdemitconf_t const *xecfg, long ri)
|
||||
{
|
||||
char dummy[1];
|
||||
return match_func_rec(xdf, xecfg, ri, dummy, sizeof(dummy)) >= 0;
|
||||
}
|
||||
|
||||
struct func_line {
|
||||
long len;
|
||||
char buf[80];
|
||||
};
|
||||
|
||||
static long get_func_line(xdfenv_t *xe, xdemitconf_t const *xecfg,
|
||||
struct func_line *func_line, long start, long limit)
|
||||
{
|
||||
long l, size, step = (start > limit) ? -1 : 1;
|
||||
char *buf, dummy[1];
|
||||
|
||||
buf = func_line ? func_line->buf : dummy;
|
||||
size = func_line ? sizeof(func_line->buf) : sizeof(dummy);
|
||||
|
||||
for (l = start; l != limit && 0 <= l && l < xe->xdf1.nrec; l += step) {
|
||||
long len = match_func_rec(&xe->xdf1, xecfg, l, buf, size);
|
||||
if (len >= 0) {
|
||||
if (func_line)
|
||||
func_line->len = len;
|
||||
return l;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int is_empty_rec(xdfile_t *xdf, long ri)
|
||||
{
|
||||
const char *rec;
|
||||
long len = xdl_get_rec(xdf, ri, &rec);
|
||||
|
||||
while (len > 0 && XDL_ISSPACE(*rec)) {
|
||||
rec++;
|
||||
len--;
|
||||
}
|
||||
return !len;
|
||||
}
|
||||
|
||||
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg) {
|
||||
long s1, s2, e1, e2, lctx;
|
||||
xdchange_t *xch, *xche;
|
||||
long funclineprev = -1;
|
||||
struct func_line func_line = { 0 };
|
||||
|
||||
for (xch = xscr; xch; xch = xche->next) {
|
||||
xche = xdl_get_hunk(&xch, xecfg);
|
||||
if (!xch)
|
||||
break;
|
||||
|
||||
s1 = XDL_MAX(xch->i1 - xecfg->ctxlen, 0);
|
||||
s2 = XDL_MAX(xch->i2 - xecfg->ctxlen, 0);
|
||||
|
||||
if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
|
||||
long fs1, i1 = xch->i1;
|
||||
|
||||
/* Appended chunk? */
|
||||
if (i1 >= xe->xdf1.nrec) {
|
||||
long i2 = xch->i2;
|
||||
|
||||
/*
|
||||
* We don't need additional context if
|
||||
* a whole function was added.
|
||||
*/
|
||||
while (i2 < xe->xdf2.nrec) {
|
||||
if (is_func_rec(&xe->xdf2, xecfg, i2))
|
||||
goto post_context_calculation;
|
||||
i2++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Otherwise get more context from the
|
||||
* pre-image.
|
||||
*/
|
||||
i1 = xe->xdf1.nrec - 1;
|
||||
}
|
||||
|
||||
fs1 = get_func_line(xe, xecfg, NULL, i1, -1);
|
||||
while (fs1 > 0 && !is_empty_rec(&xe->xdf1, fs1 - 1) &&
|
||||
!is_func_rec(&xe->xdf1, xecfg, fs1 - 1))
|
||||
fs1--;
|
||||
if (fs1 < 0)
|
||||
fs1 = 0;
|
||||
if (fs1 < s1) {
|
||||
s2 -= s1 - fs1;
|
||||
s1 = fs1;
|
||||
}
|
||||
}
|
||||
|
||||
post_context_calculation:
|
||||
lctx = xecfg->ctxlen;
|
||||
lctx = XDL_MIN(lctx, xe->xdf1.nrec - (xche->i1 + xche->chg1));
|
||||
lctx = XDL_MIN(lctx, xe->xdf2.nrec - (xche->i2 + xche->chg2));
|
||||
|
||||
e1 = xche->i1 + xche->chg1 + lctx;
|
||||
e2 = xche->i2 + xche->chg2 + lctx;
|
||||
|
||||
if (xecfg->flags & XDL_EMIT_FUNCCONTEXT) {
|
||||
long fe1 = get_func_line(xe, xecfg, NULL,
|
||||
xche->i1 + xche->chg1,
|
||||
xe->xdf1.nrec);
|
||||
while (fe1 > 0 && is_empty_rec(&xe->xdf1, fe1 - 1))
|
||||
fe1--;
|
||||
if (fe1 < 0)
|
||||
fe1 = xe->xdf1.nrec;
|
||||
if (fe1 > e1) {
|
||||
e2 += fe1 - e1;
|
||||
e1 = fe1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Overlap with next change? Then include it
|
||||
* in the current hunk and start over to find
|
||||
* its new end.
|
||||
*/
|
||||
if (xche->next) {
|
||||
long l = XDL_MIN(xche->next->i1,
|
||||
xe->xdf1.nrec - 1);
|
||||
if (l - xecfg->ctxlen <= e1 ||
|
||||
get_func_line(xe, xecfg, NULL, l, e1) < 0) {
|
||||
xche = xche->next;
|
||||
goto post_context_calculation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit current hunk header.
|
||||
*/
|
||||
|
||||
if (xecfg->flags & XDL_EMIT_FUNCNAMES) {
|
||||
get_func_line(xe, xecfg, &func_line,
|
||||
s1 - 1, funclineprev);
|
||||
funclineprev = s1 - 1;
|
||||
}
|
||||
if (xdl_emit_hunk_hdr(s1 + 1, e1 - s1, s2 + 1, e2 - s2,
|
||||
func_line.buf, func_line.len, ecb) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Emit pre-context.
|
||||
*/
|
||||
for (; s2 < xch->i2; s2++)
|
||||
if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
|
||||
return -1;
|
||||
|
||||
for (s1 = xch->i1, s2 = xch->i2;; xch = xch->next) {
|
||||
/*
|
||||
* Merge previous with current change atom.
|
||||
*/
|
||||
for (; s1 < xch->i1 && s2 < xch->i2; s1++, s2++)
|
||||
if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Removes lines from the first file.
|
||||
*/
|
||||
for (s1 = xch->i1; s1 < xch->i1 + xch->chg1; s1++)
|
||||
if (xdl_emit_record(&xe->xdf1, s1, "-", ecb) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Adds lines from the second file.
|
||||
*/
|
||||
for (s2 = xch->i2; s2 < xch->i2 + xch->chg2; s2++)
|
||||
if (xdl_emit_record(&xe->xdf2, s2, "+", ecb) < 0)
|
||||
return -1;
|
||||
|
||||
if (xch == xche)
|
||||
break;
|
||||
s1 = xch->i1 + xch->chg1;
|
||||
s2 = xch->i2 + xch->chg2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Emit post-context.
|
||||
*/
|
||||
for (s2 = xche->i2 + xche->chg2; s2 < e2; s2++)
|
||||
if (xdl_emit_record(&xe->xdf2, s2, " ", ecb) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
36
src/xdiff/xemit.h
Normal file
36
src/xdiff/xemit.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XEMIT_H)
|
||||
#define XEMIT_H
|
||||
|
||||
|
||||
typedef int (*emit_func_t)(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg);
|
||||
|
||||
xdchange_t *xdl_get_hunk(xdchange_t **xscr, xdemitconf_t const *xecfg);
|
||||
int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb,
|
||||
xdemitconf_t const *xecfg);
|
||||
|
||||
|
||||
|
||||
#endif /* #if !defined(XEMIT_H) */
|
386
src/xdiff/xhistogram.c
Normal file
386
src/xdiff/xhistogram.c
Normal file
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
* Copyright (C) 2010, Google Inc.
|
||||
* and other copyright owners as documented in JGit's IP log.
|
||||
*
|
||||
* This program and the accompanying materials are made available
|
||||
* under the terms of the Eclipse Distribution License v1.0 which
|
||||
* accompanies this distribution, is reproduced below, and is
|
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "xinclude.h"
|
||||
#include "xtypes.h"
|
||||
#include "xdiff.h"
|
||||
|
||||
#define MAX_PTR INT_MAX
|
||||
#define MAX_CNT INT_MAX
|
||||
|
||||
#define LINE_END(n) (line##n + count##n - 1)
|
||||
#define LINE_END_PTR(n) (*line##n + *count##n - 1)
|
||||
|
||||
struct histindex {
|
||||
struct record {
|
||||
unsigned int ptr, cnt;
|
||||
struct record *next;
|
||||
} **records, /* an occurrence */
|
||||
**line_map; /* map of line to record chain */
|
||||
chastore_t rcha;
|
||||
unsigned int *next_ptrs;
|
||||
unsigned int table_bits,
|
||||
records_size,
|
||||
line_map_size;
|
||||
|
||||
unsigned int max_chain_length,
|
||||
key_shift,
|
||||
ptr_shift;
|
||||
|
||||
unsigned int cnt,
|
||||
has_common;
|
||||
|
||||
xdfenv_t *env;
|
||||
xpparam_t const *xpp;
|
||||
};
|
||||
|
||||
struct region {
|
||||
unsigned int begin1, end1;
|
||||
unsigned int begin2, end2;
|
||||
};
|
||||
|
||||
#define LINE_MAP(i, a) (i->line_map[(a) - i->ptr_shift])
|
||||
|
||||
#define NEXT_PTR(index, ptr) \
|
||||
(index->next_ptrs[(ptr) - index->ptr_shift])
|
||||
|
||||
#define CNT(index, ptr) \
|
||||
((LINE_MAP(index, ptr))->cnt)
|
||||
|
||||
#define REC(env, s, l) \
|
||||
(env->xdf##s.recs[l - 1])
|
||||
|
||||
static int cmp_recs(xpparam_t const *xpp,
|
||||
xrecord_t *r1, xrecord_t *r2)
|
||||
{
|
||||
return r1->ha == r2->ha &&
|
||||
xdl_recmatch(r1->ptr, r1->size, r2->ptr, r2->size,
|
||||
xpp->flags);
|
||||
}
|
||||
|
||||
#define CMP_ENV(xpp, env, s1, l1, s2, l2) \
|
||||
(cmp_recs(xpp, REC(env, s1, l1), REC(env, s2, l2)))
|
||||
|
||||
#define CMP(i, s1, l1, s2, l2) \
|
||||
(cmp_recs(i->xpp, REC(i->env, s1, l1), REC(i->env, s2, l2)))
|
||||
|
||||
#define TABLE_HASH(index, side, line) \
|
||||
XDL_HASHLONG((REC(index->env, side, line))->ha, index->table_bits)
|
||||
|
||||
static int scanA(struct histindex *index, int line1, int count1)
|
||||
{
|
||||
int ptr, tbl_idx;
|
||||
unsigned int chain_len;
|
||||
struct record **rec_chain, *rec;
|
||||
|
||||
for (ptr = LINE_END(1); line1 <= ptr; ptr--) {
|
||||
tbl_idx = TABLE_HASH(index, 1, ptr);
|
||||
rec_chain = index->records + tbl_idx;
|
||||
rec = *rec_chain;
|
||||
|
||||
chain_len = 0;
|
||||
while (rec) {
|
||||
if (CMP(index, 1, rec->ptr, 1, ptr)) {
|
||||
/*
|
||||
* ptr is identical to another element. Insert
|
||||
* it onto the front of the existing element
|
||||
* chain.
|
||||
*/
|
||||
NEXT_PTR(index, ptr) = rec->ptr;
|
||||
rec->ptr = ptr;
|
||||
/* cap rec->cnt at MAX_CNT */
|
||||
rec->cnt = XDL_MIN(MAX_CNT, rec->cnt + 1);
|
||||
LINE_MAP(index, ptr) = rec;
|
||||
goto continue_scan;
|
||||
}
|
||||
|
||||
rec = rec->next;
|
||||
chain_len++;
|
||||
}
|
||||
|
||||
if (chain_len == index->max_chain_length)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* This is the first time we have ever seen this particular
|
||||
* element in the sequence. Construct a new chain for it.
|
||||
*/
|
||||
if (!(rec = xdl_cha_alloc(&index->rcha)))
|
||||
return -1;
|
||||
rec->ptr = ptr;
|
||||
rec->cnt = 1;
|
||||
rec->next = *rec_chain;
|
||||
*rec_chain = rec;
|
||||
LINE_MAP(index, ptr) = rec;
|
||||
|
||||
continue_scan:
|
||||
; /* no op */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int try_lcs(struct histindex *index, struct region *lcs, int b_ptr,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
unsigned int b_next = b_ptr + 1;
|
||||
struct record *rec = index->records[TABLE_HASH(index, 2, b_ptr)];
|
||||
unsigned int as, ae, bs, be, np, rc;
|
||||
int should_break;
|
||||
|
||||
for (; rec; rec = rec->next) {
|
||||
if (rec->cnt > index->cnt) {
|
||||
if (!index->has_common)
|
||||
index->has_common = CMP(index, 1, rec->ptr, 2, b_ptr);
|
||||
continue;
|
||||
}
|
||||
|
||||
as = rec->ptr;
|
||||
if (!CMP(index, 1, as, 2, b_ptr))
|
||||
continue;
|
||||
|
||||
index->has_common = 1;
|
||||
for (;;) {
|
||||
should_break = 0;
|
||||
np = NEXT_PTR(index, as);
|
||||
bs = b_ptr;
|
||||
ae = as;
|
||||
be = bs;
|
||||
rc = rec->cnt;
|
||||
|
||||
while (line1 < (int)as && line2 < (int)bs
|
||||
&& CMP(index, 1, as - 1, 2, bs - 1)) {
|
||||
as--;
|
||||
bs--;
|
||||
if (1 < rc)
|
||||
rc = XDL_MIN(rc, CNT(index, as));
|
||||
}
|
||||
while ((int)ae < LINE_END(1) && (int)be < LINE_END(2)
|
||||
&& CMP(index, 1, ae + 1, 2, be + 1)) {
|
||||
ae++;
|
||||
be++;
|
||||
if (1 < rc)
|
||||
rc = XDL_MIN(rc, CNT(index, ae));
|
||||
}
|
||||
|
||||
if (b_next <= be)
|
||||
b_next = be + 1;
|
||||
if (lcs->end1 - lcs->begin1 < ae - as || rc < index->cnt) {
|
||||
lcs->begin1 = as;
|
||||
lcs->begin2 = bs;
|
||||
lcs->end1 = ae;
|
||||
lcs->end2 = be;
|
||||
index->cnt = rc;
|
||||
}
|
||||
|
||||
if (np == 0)
|
||||
break;
|
||||
|
||||
while (np <= ae) {
|
||||
np = NEXT_PTR(index, np);
|
||||
if (np == 0) {
|
||||
should_break = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (should_break)
|
||||
break;
|
||||
|
||||
as = np;
|
||||
}
|
||||
}
|
||||
return b_next;
|
||||
}
|
||||
|
||||
static int fall_back_to_classic_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
xpparam_t xpparam;
|
||||
xpparam.flags = xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
|
||||
|
||||
return xdl_fall_back_diff(env, &xpparam,
|
||||
line1, count1, line2, count2);
|
||||
}
|
||||
|
||||
static inline void free_index(struct histindex *index)
|
||||
{
|
||||
xdl_free(index->records);
|
||||
xdl_free(index->line_map);
|
||||
xdl_free(index->next_ptrs);
|
||||
xdl_cha_free(&index->rcha);
|
||||
}
|
||||
|
||||
static int find_lcs(xpparam_t const *xpp, xdfenv_t *env,
|
||||
struct region *lcs,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
int b_ptr;
|
||||
int sz, ret = -1;
|
||||
struct histindex index;
|
||||
|
||||
memset(&index, 0, sizeof(index));
|
||||
|
||||
index.env = env;
|
||||
index.xpp = xpp;
|
||||
|
||||
index.records = NULL;
|
||||
index.line_map = NULL;
|
||||
/* in case of early xdl_cha_free() */
|
||||
index.rcha.head = NULL;
|
||||
|
||||
index.table_bits = xdl_hashbits(count1);
|
||||
sz = index.records_size = 1 << index.table_bits;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.records = (struct record **) xdl_malloc(sz)))
|
||||
goto cleanup;
|
||||
memset(index.records, 0, sz);
|
||||
|
||||
sz = index.line_map_size = count1;
|
||||
sz *= sizeof(struct record *);
|
||||
if (!(index.line_map = (struct record **) xdl_malloc(sz)))
|
||||
goto cleanup;
|
||||
memset(index.line_map, 0, sz);
|
||||
|
||||
sz = index.line_map_size;
|
||||
sz *= sizeof(unsigned int);
|
||||
if (!(index.next_ptrs = (unsigned int *) xdl_malloc(sz)))
|
||||
goto cleanup;
|
||||
memset(index.next_ptrs, 0, sz);
|
||||
|
||||
/* lines / 4 + 1 comes from xprepare.c:xdl_prepare_ctx() */
|
||||
if (xdl_cha_init(&index.rcha, sizeof(struct record), count1 / 4 + 1) < 0)
|
||||
goto cleanup;
|
||||
|
||||
index.ptr_shift = line1;
|
||||
index.max_chain_length = 64;
|
||||
|
||||
if (scanA(&index, line1, count1))
|
||||
goto cleanup;
|
||||
|
||||
index.cnt = index.max_chain_length + 1;
|
||||
|
||||
for (b_ptr = line2; b_ptr <= LINE_END(2); )
|
||||
b_ptr = try_lcs(&index, lcs, b_ptr, line1, count1, line2, count2);
|
||||
|
||||
if (index.has_common && index.max_chain_length < index.cnt)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
free_index(&index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
struct region lcs;
|
||||
int lcs_found;
|
||||
int result;
|
||||
redo:
|
||||
result = -1;
|
||||
|
||||
if (count1 <= 0 && count2 <= 0)
|
||||
return 0;
|
||||
|
||||
if (LINE_END(1) >= MAX_PTR)
|
||||
return -1;
|
||||
|
||||
if (!count1) {
|
||||
while(count2--)
|
||||
env->xdf2.rchg[line2++ - 1] = 1;
|
||||
return 0;
|
||||
} else if (!count2) {
|
||||
while(count1--)
|
||||
env->xdf1.rchg[line1++ - 1] = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&lcs, 0, sizeof(lcs));
|
||||
lcs_found = find_lcs(xpp, env, &lcs, line1, count1, line2, count2);
|
||||
if (lcs_found < 0)
|
||||
goto out;
|
||||
else if (lcs_found)
|
||||
result = fall_back_to_classic_diff(xpp, env, line1, count1, line2, count2);
|
||||
else {
|
||||
if (lcs.begin1 == 0 && lcs.begin2 == 0) {
|
||||
while (count1--)
|
||||
env->xdf1.rchg[line1++ - 1] = 1;
|
||||
while (count2--)
|
||||
env->xdf2.rchg[line2++ - 1] = 1;
|
||||
result = 0;
|
||||
} else {
|
||||
result = histogram_diff(xpp, env,
|
||||
line1, lcs.begin1 - line1,
|
||||
line2, lcs.begin2 - line2);
|
||||
if (result)
|
||||
goto out;
|
||||
/*
|
||||
* result = histogram_diff(xpp, env,
|
||||
* lcs.end1 + 1, LINE_END(1) - lcs.end1,
|
||||
* lcs.end2 + 1, LINE_END(2) - lcs.end2);
|
||||
* but let's optimize tail recursion ourself:
|
||||
*/
|
||||
count1 = LINE_END(1) - lcs.end1;
|
||||
line1 = lcs.end1 + 1;
|
||||
count2 = LINE_END(2) - lcs.end2;
|
||||
line2 = lcs.end2 + 1;
|
||||
goto redo;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
return histogram_diff(xpp, env,
|
||||
env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
|
||||
env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);
|
||||
}
|
61
src/xdiff/xinclude.h
Normal file
61
src/xdiff/xinclude.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
/* defines HAVE_ATTRIBUTE_UNUSED */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "../auto/config.h"
|
||||
#endif
|
||||
|
||||
/* Mark unused function arguments with UNUSED, so that gcc -Wunused-parameter
|
||||
* can be used to check for mistakes. */
|
||||
#ifdef HAVE_ATTRIBUTE_UNUSED
|
||||
# define UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define UNUSED
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define inline __inline
|
||||
#endif
|
||||
|
||||
#if !defined(XINCLUDE_H)
|
||||
#define XINCLUDE_H
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "xmacros.h"
|
||||
#include "xdiff.h"
|
||||
#include "xtypes.h"
|
||||
#include "xutils.h"
|
||||
#include "xprepare.h"
|
||||
#include "xdiffi.h"
|
||||
#include "xemit.h"
|
||||
|
||||
|
||||
#endif /* #if !defined(XINCLUDE_H) */
|
54
src/xdiff/xmacros.h
Normal file
54
src/xdiff/xmacros.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XMACROS_H)
|
||||
#define XMACROS_H
|
||||
|
||||
|
||||
|
||||
|
||||
#define XDL_MIN(a, b) ((a) < (b) ? (a): (b))
|
||||
#define XDL_MAX(a, b) ((a) > (b) ? (a): (b))
|
||||
#define XDL_ABS(v) ((v) >= 0 ? (v): -(v))
|
||||
#define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9')
|
||||
#define XDL_ISSPACE(c) (isspace((unsigned char)(c)))
|
||||
#define XDL_ADDBITS(v,b) ((v) + ((v) >> (b)))
|
||||
#define XDL_MASKBITS(b) ((1UL << (b)) - 1)
|
||||
#define XDL_HASHLONG(v,b) (XDL_ADDBITS((unsigned long)(v), b) & XDL_MASKBITS(b))
|
||||
#define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0)
|
||||
#define XDL_LE32_PUT(p, v) \
|
||||
do { \
|
||||
unsigned char *__p = (unsigned char *) (p); \
|
||||
*__p++ = (unsigned char) (v); \
|
||||
*__p++ = (unsigned char) ((v) >> 8); \
|
||||
*__p++ = (unsigned char) ((v) >> 16); \
|
||||
*__p = (unsigned char) ((v) >> 24); \
|
||||
} while (0)
|
||||
#define XDL_LE32_GET(p, v) \
|
||||
do { \
|
||||
unsigned char const *__p = (unsigned char const *) (p); \
|
||||
(v) = (unsigned long) __p[0] | ((unsigned long) __p[1]) << 8 | \
|
||||
((unsigned long) __p[2]) << 16 | ((unsigned long) __p[3]) << 24; \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif /* #if !defined(XMACROS_H) */
|
390
src/xdiff/xpatience.c
Normal file
390
src/xdiff/xpatience.c
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003-2016 Davide Libenzi, Johannes E. Schindelin
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
#include "xinclude.h"
|
||||
#include "xtypes.h"
|
||||
#include "xdiff.h"
|
||||
|
||||
/*
|
||||
* The basic idea of patience diff is to find lines that are unique in
|
||||
* both files. These are intuitively the ones that we want to see as
|
||||
* common lines.
|
||||
*
|
||||
* The maximal ordered sequence of such line pairs (where ordered means
|
||||
* that the order in the sequence agrees with the order of the lines in
|
||||
* both files) naturally defines an initial set of common lines.
|
||||
*
|
||||
* Now, the algorithm tries to extend the set of common lines by growing
|
||||
* the line ranges where the files have identical lines.
|
||||
*
|
||||
* Between those common lines, the patience diff algorithm is applied
|
||||
* recursively, until no unique line pairs can be found; these line ranges
|
||||
* are handled by the well-known Myers algorithm.
|
||||
*/
|
||||
|
||||
#define NON_UNIQUE ULONG_MAX
|
||||
|
||||
/*
|
||||
* This is a hash mapping from line hash to line numbers in the first and
|
||||
* second file.
|
||||
*/
|
||||
struct hashmap {
|
||||
int nr, alloc;
|
||||
struct entry {
|
||||
unsigned long hash;
|
||||
/*
|
||||
* 0 = unused entry, 1 = first line, 2 = second, etc.
|
||||
* line2 is NON_UNIQUE if the line is not unique
|
||||
* in either the first or the second file.
|
||||
*/
|
||||
unsigned long line1, line2;
|
||||
/*
|
||||
* "next" & "previous" are used for the longest common
|
||||
* sequence;
|
||||
* initially, "next" reflects only the order in file1.
|
||||
*/
|
||||
struct entry *next, *previous;
|
||||
|
||||
/*
|
||||
* If 1, this entry can serve as an anchor. See
|
||||
* Documentation/diff-options.txt for more information.
|
||||
*/
|
||||
unsigned anchor : 1;
|
||||
} *entries, *first, *last;
|
||||
/* were common records found? */
|
||||
unsigned long has_matches;
|
||||
mmfile_t *file1, *file2;
|
||||
xdfenv_t *env;
|
||||
xpparam_t const *xpp;
|
||||
};
|
||||
|
||||
static int is_anchor(xpparam_t const *xpp, const char *line)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < xpp->anchors_nr; i++) {
|
||||
if (!strncmp(line, xpp->anchors[i], strlen(xpp->anchors[i])))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The argument "pass" is 1 for the first file, 2 for the second. */
|
||||
static void insert_record(xpparam_t const *xpp, int line, struct hashmap *map,
|
||||
int pass)
|
||||
{
|
||||
xrecord_t **records = pass == 1 ?
|
||||
map->env->xdf1.recs : map->env->xdf2.recs;
|
||||
xrecord_t *record = records[line - 1], *other;
|
||||
/*
|
||||
* After xdl_prepare_env() (or more precisely, due to
|
||||
* xdl_classify_record()), the "ha" member of the records (AKA lines)
|
||||
* is _not_ the hash anymore, but a linearized version of it. In
|
||||
* other words, the "ha" member is guaranteed to start with 0 and
|
||||
* the second record's ha can only be 0 or 1, etc.
|
||||
*
|
||||
* So we multiply ha by 2 in the hope that the hashing was
|
||||
* "unique enough".
|
||||
*/
|
||||
int index = (int)((record->ha << 1) % map->alloc);
|
||||
|
||||
while (map->entries[index].line1) {
|
||||
other = map->env->xdf1.recs[map->entries[index].line1 - 1];
|
||||
if (map->entries[index].hash != record->ha ||
|
||||
!xdl_recmatch(record->ptr, record->size,
|
||||
other->ptr, other->size,
|
||||
map->xpp->flags)) {
|
||||
if (++index >= map->alloc)
|
||||
index = 0;
|
||||
continue;
|
||||
}
|
||||
if (pass == 2)
|
||||
map->has_matches = 1;
|
||||
if (pass == 1 || map->entries[index].line2)
|
||||
map->entries[index].line2 = NON_UNIQUE;
|
||||
else
|
||||
map->entries[index].line2 = line;
|
||||
return;
|
||||
}
|
||||
if (pass == 2)
|
||||
return;
|
||||
map->entries[index].line1 = line;
|
||||
map->entries[index].hash = record->ha;
|
||||
map->entries[index].anchor = is_anchor(xpp, map->env->xdf1.recs[line - 1]->ptr);
|
||||
if (!map->first)
|
||||
map->first = map->entries + index;
|
||||
if (map->last) {
|
||||
map->last->next = map->entries + index;
|
||||
map->entries[index].previous = map->last;
|
||||
}
|
||||
map->last = map->entries + index;
|
||||
map->nr++;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function has to be called for each recursion into the inter-hunk
|
||||
* parts, as previously non-unique lines can become unique when being
|
||||
* restricted to a smaller part of the files.
|
||||
*
|
||||
* It is assumed that env has been prepared using xdl_prepare().
|
||||
*/
|
||||
static int fill_hashmap(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
struct hashmap *result,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
result->file1 = file1;
|
||||
result->file2 = file2;
|
||||
result->xpp = xpp;
|
||||
result->env = env;
|
||||
|
||||
/* We know exactly how large we want the hash map */
|
||||
result->alloc = count1 * 2;
|
||||
result->entries = (struct entry *)
|
||||
xdl_malloc(result->alloc * sizeof(struct entry));
|
||||
if (!result->entries)
|
||||
return -1;
|
||||
memset(result->entries, 0, result->alloc * sizeof(struct entry));
|
||||
|
||||
/* First, fill with entries from the first file */
|
||||
while (count1--)
|
||||
insert_record(xpp, line1++, result, 1);
|
||||
|
||||
/* Then search for matches in the second file */
|
||||
while (count2--)
|
||||
insert_record(xpp, line2++, result, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the longest sequence with a smaller last element (meaning a smaller
|
||||
* line2, as we construct the sequence with entries ordered by line1).
|
||||
*/
|
||||
static int binary_search(struct entry **sequence, int longest,
|
||||
struct entry *entry)
|
||||
{
|
||||
int left = -1, right = longest;
|
||||
|
||||
while (left + 1 < right) {
|
||||
int middle = left + (right - left) / 2;
|
||||
/* by construction, no two entries can be equal */
|
||||
if (sequence[middle]->line2 > entry->line2)
|
||||
right = middle;
|
||||
else
|
||||
left = middle;
|
||||
}
|
||||
/* return the index in "sequence", _not_ the sequence length */
|
||||
return left;
|
||||
}
|
||||
|
||||
/*
|
||||
* The idea is to start with the list of common unique lines sorted by
|
||||
* the order in file1. For each of these pairs, the longest (partial)
|
||||
* sequence whose last element's line2 is smaller is determined.
|
||||
*
|
||||
* For efficiency, the sequences are kept in a list containing exactly one
|
||||
* item per sequence length: the sequence with the smallest last
|
||||
* element (in terms of line2).
|
||||
*/
|
||||
static struct entry *find_longest_common_sequence(struct hashmap *map)
|
||||
{
|
||||
struct entry **sequence = xdl_malloc(map->nr * sizeof(struct entry *));
|
||||
int longest = 0, i;
|
||||
struct entry *entry;
|
||||
|
||||
/*
|
||||
* If not -1, this entry in sequence must never be overridden.
|
||||
* Therefore, overriding entries before this has no effect, so
|
||||
* do not do that either.
|
||||
*/
|
||||
int anchor_i = -1;
|
||||
|
||||
for (entry = map->first; entry; entry = entry->next) {
|
||||
if (!entry->line2 || entry->line2 == NON_UNIQUE)
|
||||
continue;
|
||||
i = binary_search(sequence, longest, entry);
|
||||
entry->previous = i < 0 ? NULL : sequence[i];
|
||||
++i;
|
||||
if (i <= anchor_i)
|
||||
continue;
|
||||
sequence[i] = entry;
|
||||
if (entry->anchor) {
|
||||
anchor_i = i;
|
||||
longest = anchor_i + 1;
|
||||
} else if (i == longest) {
|
||||
longest++;
|
||||
}
|
||||
}
|
||||
|
||||
/* No common unique lines were found */
|
||||
if (!longest) {
|
||||
xdl_free(sequence);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Iterate starting at the last element, adjusting the "next" members */
|
||||
entry = sequence[longest - 1];
|
||||
entry->next = NULL;
|
||||
while (entry->previous) {
|
||||
entry->previous->next = entry;
|
||||
entry = entry->previous;
|
||||
}
|
||||
xdl_free(sequence);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static int match(struct hashmap *map, int line1, int line2)
|
||||
{
|
||||
xrecord_t *record1 = map->env->xdf1.recs[line1 - 1];
|
||||
xrecord_t *record2 = map->env->xdf2.recs[line2 - 1];
|
||||
return xdl_recmatch(record1->ptr, record1->size,
|
||||
record2->ptr, record2->size, map->xpp->flags);
|
||||
}
|
||||
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
static int walk_common_sequence(struct hashmap *map, struct entry *first,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
int end1 = line1 + count1, end2 = line2 + count2;
|
||||
int next1, next2;
|
||||
|
||||
for (;;) {
|
||||
/* Try to grow the line ranges of common lines */
|
||||
if (first) {
|
||||
next1 = first->line1;
|
||||
next2 = first->line2;
|
||||
while (next1 > line1 && next2 > line2 &&
|
||||
match(map, next1 - 1, next2 - 1)) {
|
||||
next1--;
|
||||
next2--;
|
||||
}
|
||||
} else {
|
||||
next1 = end1;
|
||||
next2 = end2;
|
||||
}
|
||||
while (line1 < next1 && line2 < next2 &&
|
||||
match(map, line1, line2)) {
|
||||
line1++;
|
||||
line2++;
|
||||
}
|
||||
|
||||
/* Recurse */
|
||||
if (next1 > line1 || next2 > line2) {
|
||||
struct hashmap submap;
|
||||
|
||||
memset(&submap, 0, sizeof(submap));
|
||||
if (patience_diff(map->file1, map->file2,
|
||||
map->xpp, map->env,
|
||||
line1, next1 - line1,
|
||||
line2, next2 - line2))
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!first)
|
||||
return 0;
|
||||
|
||||
while (first->next &&
|
||||
first->next->line1 == first->line1 + 1 &&
|
||||
first->next->line2 == first->line2 + 1)
|
||||
first = first->next;
|
||||
|
||||
line1 = first->line1 + 1;
|
||||
line2 = first->line2 + 1;
|
||||
|
||||
first = first->next;
|
||||
}
|
||||
}
|
||||
|
||||
static int fall_back_to_classic_diff(struct hashmap *map,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
xpparam_t xpp;
|
||||
xpp.flags = map->xpp->flags & ~XDF_DIFF_ALGORITHM_MASK;
|
||||
|
||||
return xdl_fall_back_diff(map->env, &xpp,
|
||||
line1, count1, line2, count2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively find the longest common sequence of unique lines,
|
||||
* and if none was found, ask xdl_do_diff() to do the job.
|
||||
*
|
||||
* This function assumes that env was prepared with xdl_prepare_env().
|
||||
*/
|
||||
static int patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
struct hashmap map;
|
||||
struct entry *first;
|
||||
int result = 0;
|
||||
|
||||
/* trivial case: one side is empty */
|
||||
if (!count1) {
|
||||
while(count2--)
|
||||
env->xdf2.rchg[line2++ - 1] = 1;
|
||||
return 0;
|
||||
} else if (!count2) {
|
||||
while(count1--)
|
||||
env->xdf1.rchg[line1++ - 1] = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&map, 0, sizeof(map));
|
||||
if (fill_hashmap(file1, file2, xpp, env, &map,
|
||||
line1, count1, line2, count2))
|
||||
return -1;
|
||||
|
||||
/* are there any matching lines at all? */
|
||||
if (!map.has_matches) {
|
||||
while(count1--)
|
||||
env->xdf1.rchg[line1++ - 1] = 1;
|
||||
while(count2--)
|
||||
env->xdf2.rchg[line2++ - 1] = 1;
|
||||
xdl_free(map.entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
first = find_longest_common_sequence(&map);
|
||||
if (first)
|
||||
result = walk_common_sequence(&map, first,
|
||||
line1, count1, line2, count2);
|
||||
else
|
||||
result = fall_back_to_classic_diff(&map,
|
||||
line1, count1, line2, count2);
|
||||
|
||||
xdl_free(map.entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
|
||||
xpparam_t const *xpp, xdfenv_t *env)
|
||||
{
|
||||
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
|
||||
return -1;
|
||||
|
||||
/* environment is cleaned up in xdl_diff() */
|
||||
return patience_diff(file1, file2, xpp, env,
|
||||
1, env->xdf1.nrec, 1, env->xdf2.nrec);
|
||||
}
|
483
src/xdiff/xprepare.c
Normal file
483
src/xdiff/xprepare.c
Normal file
@@ -0,0 +1,483 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "xinclude.h"
|
||||
|
||||
|
||||
#define XDL_KPDIS_RUN 4
|
||||
#define XDL_MAX_EQLIMIT 1024
|
||||
#define XDL_SIMSCAN_WINDOW 100
|
||||
#define XDL_GUESS_NLINES1 256
|
||||
#define XDL_GUESS_NLINES2 20
|
||||
|
||||
|
||||
typedef struct s_xdlclass {
|
||||
struct s_xdlclass *next;
|
||||
unsigned long ha;
|
||||
char const *line;
|
||||
long size;
|
||||
long idx;
|
||||
long len1, len2;
|
||||
} xdlclass_t;
|
||||
|
||||
typedef struct s_xdlclassifier {
|
||||
unsigned int hbits;
|
||||
long hsize;
|
||||
xdlclass_t **rchash;
|
||||
chastore_t ncha;
|
||||
xdlclass_t **rcrecs;
|
||||
long alloc;
|
||||
long count;
|
||||
long flags;
|
||||
} xdlclassifier_t;
|
||||
|
||||
|
||||
|
||||
|
||||
static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags);
|
||||
static void xdl_free_classifier(xdlclassifier_t *cf);
|
||||
static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
|
||||
unsigned int hbits, xrecord_t *rec);
|
||||
static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
|
||||
xdlclassifier_t *cf, xdfile_t *xdf);
|
||||
static void xdl_free_ctx(xdfile_t *xdf);
|
||||
static int xdl_clean_mmatch(char const *dis, long i, long s, long e);
|
||||
static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
|
||||
static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2);
|
||||
static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2);
|
||||
|
||||
|
||||
|
||||
|
||||
static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) {
|
||||
cf->flags = flags;
|
||||
|
||||
cf->hbits = xdl_hashbits((unsigned int) size);
|
||||
cf->hsize = 1 << cf->hbits;
|
||||
|
||||
if (xdl_cha_init(&cf->ncha, sizeof(xdlclass_t), size / 4 + 1) < 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
if (!(cf->rchash = (xdlclass_t **) xdl_malloc(cf->hsize * sizeof(xdlclass_t *)))) {
|
||||
|
||||
xdl_cha_free(&cf->ncha);
|
||||
return -1;
|
||||
}
|
||||
memset(cf->rchash, 0, cf->hsize * sizeof(xdlclass_t *));
|
||||
|
||||
cf->alloc = size;
|
||||
if (!(cf->rcrecs = (xdlclass_t **) xdl_malloc(cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
|
||||
xdl_free(cf->rchash);
|
||||
xdl_cha_free(&cf->ncha);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cf->count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void xdl_free_classifier(xdlclassifier_t *cf) {
|
||||
|
||||
xdl_free(cf->rcrecs);
|
||||
xdl_free(cf->rchash);
|
||||
xdl_cha_free(&cf->ncha);
|
||||
}
|
||||
|
||||
|
||||
static int xdl_classify_record(unsigned int pass, xdlclassifier_t *cf, xrecord_t **rhash,
|
||||
unsigned int hbits, xrecord_t *rec) {
|
||||
long hi;
|
||||
char const *line;
|
||||
xdlclass_t *rcrec;
|
||||
xdlclass_t **rcrecs;
|
||||
|
||||
line = rec->ptr;
|
||||
hi = (long) XDL_HASHLONG(rec->ha, cf->hbits);
|
||||
for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next)
|
||||
if (rcrec->ha == rec->ha &&
|
||||
xdl_recmatch(rcrec->line, rcrec->size,
|
||||
rec->ptr, rec->size, cf->flags))
|
||||
break;
|
||||
|
||||
if (!rcrec) {
|
||||
if (!(rcrec = xdl_cha_alloc(&cf->ncha))) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
rcrec->idx = cf->count++;
|
||||
if (cf->count > cf->alloc) {
|
||||
cf->alloc *= 2;
|
||||
if (!(rcrecs = (xdlclass_t **) xdl_realloc(cf->rcrecs, cf->alloc * sizeof(xdlclass_t *)))) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
cf->rcrecs = rcrecs;
|
||||
}
|
||||
cf->rcrecs[rcrec->idx] = rcrec;
|
||||
rcrec->line = line;
|
||||
rcrec->size = rec->size;
|
||||
rcrec->ha = rec->ha;
|
||||
rcrec->len1 = rcrec->len2 = 0;
|
||||
rcrec->next = cf->rchash[hi];
|
||||
cf->rchash[hi] = rcrec;
|
||||
}
|
||||
|
||||
(pass == 1) ? rcrec->len1++ : rcrec->len2++;
|
||||
|
||||
rec->ha = (unsigned long) rcrec->idx;
|
||||
|
||||
hi = (long) XDL_HASHLONG(rec->ha, hbits);
|
||||
rec->next = rhash[hi];
|
||||
rhash[hi] = rec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int xdl_prepare_ctx(unsigned int pass, mmfile_t *mf, long narec, xpparam_t const *xpp,
|
||||
xdlclassifier_t *cf, xdfile_t *xdf) {
|
||||
unsigned int hbits;
|
||||
long nrec, hsize, bsize;
|
||||
unsigned long hav;
|
||||
char const *blk, *cur, *top, *prev;
|
||||
xrecord_t *crec;
|
||||
xrecord_t **recs, **rrecs;
|
||||
xrecord_t **rhash;
|
||||
unsigned long *ha;
|
||||
char *rchg;
|
||||
long *rindex;
|
||||
|
||||
ha = NULL;
|
||||
rindex = NULL;
|
||||
rchg = NULL;
|
||||
rhash = NULL;
|
||||
recs = NULL;
|
||||
|
||||
if (xdl_cha_init(&xdf->rcha, sizeof(xrecord_t), narec / 4 + 1) < 0)
|
||||
goto abort;
|
||||
if (!(recs = (xrecord_t **) xdl_malloc(narec * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
|
||||
hbits = hsize = 0;
|
||||
else {
|
||||
hbits = xdl_hashbits((unsigned int) narec);
|
||||
hsize = 1 << hbits;
|
||||
if (!(rhash = (xrecord_t **) xdl_malloc(hsize * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
memset(rhash, 0, hsize * sizeof(xrecord_t *));
|
||||
}
|
||||
|
||||
nrec = 0;
|
||||
if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
|
||||
for (top = blk + bsize; cur < top; ) {
|
||||
prev = cur;
|
||||
hav = xdl_hash_record(&cur, top, xpp->flags);
|
||||
if (nrec >= narec) {
|
||||
narec *= 2;
|
||||
if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
|
||||
goto abort;
|
||||
recs = rrecs;
|
||||
}
|
||||
if (!(crec = xdl_cha_alloc(&xdf->rcha)))
|
||||
goto abort;
|
||||
crec->ptr = prev;
|
||||
crec->size = (long) (cur - prev);
|
||||
crec->ha = hav;
|
||||
recs[nrec++] = crec;
|
||||
|
||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
|
||||
xdl_classify_record(pass, cf, rhash, hbits, crec) < 0)
|
||||
goto abort;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(rchg = (char *) xdl_malloc((nrec + 2) * sizeof(char))))
|
||||
goto abort;
|
||||
memset(rchg, 0, (nrec + 2) * sizeof(char));
|
||||
|
||||
if (!(rindex = (long *) xdl_malloc((nrec + 1) * sizeof(long))))
|
||||
goto abort;
|
||||
if (!(ha = (unsigned long *) xdl_malloc((nrec + 1) * sizeof(unsigned long))))
|
||||
goto abort;
|
||||
|
||||
xdf->nrec = nrec;
|
||||
xdf->recs = recs;
|
||||
xdf->hbits = hbits;
|
||||
xdf->rhash = rhash;
|
||||
xdf->rchg = rchg + 1;
|
||||
xdf->rindex = rindex;
|
||||
xdf->nreff = 0;
|
||||
xdf->ha = ha;
|
||||
xdf->dstart = 0;
|
||||
xdf->dend = nrec - 1;
|
||||
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
xdl_free(ha);
|
||||
xdl_free(rindex);
|
||||
xdl_free(rchg);
|
||||
xdl_free(rhash);
|
||||
xdl_free(recs);
|
||||
xdl_cha_free(&xdf->rcha);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static void xdl_free_ctx(xdfile_t *xdf) {
|
||||
|
||||
xdl_free(xdf->rhash);
|
||||
xdl_free(xdf->rindex);
|
||||
xdl_free(xdf->rchg - 1);
|
||||
xdl_free(xdf->ha);
|
||||
xdl_free(xdf->recs);
|
||||
xdl_cha_free(&xdf->rcha);
|
||||
}
|
||||
|
||||
|
||||
int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *xe) {
|
||||
long enl1, enl2, sample;
|
||||
xdlclassifier_t cf;
|
||||
|
||||
memset(&cf, 0, sizeof(cf));
|
||||
|
||||
/*
|
||||
* For histogram diff, we can afford a smaller sample size and
|
||||
* thus a poorer estimate of the number of lines, as the hash
|
||||
* table (rhash) won't be filled up/grown. The number of lines
|
||||
* (nrecs) will be updated correctly anyway by
|
||||
* xdl_prepare_ctx().
|
||||
*/
|
||||
sample = (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF
|
||||
? XDL_GUESS_NLINES2 : XDL_GUESS_NLINES1);
|
||||
|
||||
enl1 = xdl_guess_lines(mf1, sample) + 1;
|
||||
enl2 = xdl_guess_lines(mf2, sample) + 1;
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF &&
|
||||
xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (xdl_prepare_ctx(1, mf1, enl1, xpp, &cf, &xe->xdf1) < 0) {
|
||||
|
||||
xdl_free_classifier(&cf);
|
||||
return -1;
|
||||
}
|
||||
if (xdl_prepare_ctx(2, mf2, enl2, xpp, &cf, &xe->xdf2) < 0) {
|
||||
|
||||
xdl_free_ctx(&xe->xdf1);
|
||||
xdl_free_classifier(&cf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((XDF_DIFF_ALG(xpp->flags) != XDF_PATIENCE_DIFF) &&
|
||||
(XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF) &&
|
||||
xdl_optimize_ctxs(&cf, &xe->xdf1, &xe->xdf2) < 0) {
|
||||
|
||||
xdl_free_ctx(&xe->xdf2);
|
||||
xdl_free_ctx(&xe->xdf1);
|
||||
xdl_free_classifier(&cf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (XDF_DIFF_ALG(xpp->flags) != XDF_HISTOGRAM_DIFF)
|
||||
xdl_free_classifier(&cf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void xdl_free_env(xdfenv_t *xe) {
|
||||
|
||||
xdl_free_ctx(&xe->xdf2);
|
||||
xdl_free_ctx(&xe->xdf1);
|
||||
}
|
||||
|
||||
|
||||
static int xdl_clean_mmatch(char const *dis, long i, long s, long e) {
|
||||
long r, rdis0, rpdis0, rdis1, rpdis1;
|
||||
|
||||
/*
|
||||
* Limits the window the is examined during the similar-lines
|
||||
* scan. The loops below stops when dis[i - r] == 1 (line that
|
||||
* has no match), but there are corner cases where the loop
|
||||
* proceed all the way to the extremities by causing huge
|
||||
* performance penalties in case of big files.
|
||||
*/
|
||||
if (i - s > XDL_SIMSCAN_WINDOW)
|
||||
s = i - XDL_SIMSCAN_WINDOW;
|
||||
if (e - i > XDL_SIMSCAN_WINDOW)
|
||||
e = i + XDL_SIMSCAN_WINDOW;
|
||||
|
||||
/*
|
||||
* Scans the lines before 'i' to find a run of lines that either
|
||||
* have no match (dis[j] == 0) or have multiple matches (dis[j] > 1).
|
||||
* Note that we always call this function with dis[i] > 1, so the
|
||||
* current line (i) is already a multimatch line.
|
||||
*/
|
||||
for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) {
|
||||
if (!dis[i - r])
|
||||
rdis0++;
|
||||
else if (dis[i - r] == 2)
|
||||
rpdis0++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If the run before the line 'i' found only multimatch lines, we
|
||||
* return 0 and hence we don't make the current line (i) discarded.
|
||||
* We want to discard multimatch lines only when they appear in the
|
||||
* middle of runs with nomatch lines (dis[j] == 0).
|
||||
*/
|
||||
if (rdis0 == 0)
|
||||
return 0;
|
||||
for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) {
|
||||
if (!dis[i + r])
|
||||
rdis1++;
|
||||
else if (dis[i + r] == 2)
|
||||
rpdis1++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If the run after the line 'i' found only multimatch lines, we
|
||||
* return 0 and hence we don't make the current line (i) discarded.
|
||||
*/
|
||||
if (rdis1 == 0)
|
||||
return 0;
|
||||
rdis1 += rdis0;
|
||||
rpdis1 += rpdis0;
|
||||
|
||||
return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to reduce the problem complexity, discard records that have no
|
||||
* matches on the other file. Also, lines that have multiple matches
|
||||
* might be potentially discarded if they happear in a run of discardable.
|
||||
*/
|
||||
static int xdl_cleanup_records(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
|
||||
long i, nm, nreff, mlim;
|
||||
xrecord_t **recs;
|
||||
xdlclass_t *rcrec;
|
||||
char *dis, *dis1, *dis2;
|
||||
|
||||
if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
memset(dis, 0, xdf1->nrec + xdf2->nrec + 2);
|
||||
dis1 = dis;
|
||||
dis2 = dis1 + xdf1->nrec + 1;
|
||||
|
||||
if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT)
|
||||
mlim = XDL_MAX_EQLIMIT;
|
||||
for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) {
|
||||
rcrec = cf->rcrecs[(*recs)->ha];
|
||||
nm = rcrec ? rcrec->len2 : 0;
|
||||
dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
|
||||
}
|
||||
|
||||
if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT)
|
||||
mlim = XDL_MAX_EQLIMIT;
|
||||
for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) {
|
||||
rcrec = cf->rcrecs[(*recs)->ha];
|
||||
nm = rcrec ? rcrec->len1 : 0;
|
||||
dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1;
|
||||
}
|
||||
|
||||
for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart];
|
||||
i <= xdf1->dend; i++, recs++) {
|
||||
if (dis1[i] == 1 ||
|
||||
(dis1[i] == 2 && !xdl_clean_mmatch(dis1, i, xdf1->dstart, xdf1->dend))) {
|
||||
xdf1->rindex[nreff] = i;
|
||||
xdf1->ha[nreff] = (*recs)->ha;
|
||||
nreff++;
|
||||
} else
|
||||
xdf1->rchg[i] = 1;
|
||||
}
|
||||
xdf1->nreff = nreff;
|
||||
|
||||
for (nreff = 0, i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart];
|
||||
i <= xdf2->dend; i++, recs++) {
|
||||
if (dis2[i] == 1 ||
|
||||
(dis2[i] == 2 && !xdl_clean_mmatch(dis2, i, xdf2->dstart, xdf2->dend))) {
|
||||
xdf2->rindex[nreff] = i;
|
||||
xdf2->ha[nreff] = (*recs)->ha;
|
||||
nreff++;
|
||||
} else
|
||||
xdf2->rchg[i] = 1;
|
||||
}
|
||||
xdf2->nreff = nreff;
|
||||
|
||||
xdl_free(dis);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Early trim initial and terminal matching records.
|
||||
*/
|
||||
static int xdl_trim_ends(xdfile_t *xdf1, xdfile_t *xdf2) {
|
||||
long i, lim;
|
||||
xrecord_t **recs1, **recs2;
|
||||
|
||||
recs1 = xdf1->recs;
|
||||
recs2 = xdf2->recs;
|
||||
for (i = 0, lim = XDL_MIN(xdf1->nrec, xdf2->nrec); i < lim;
|
||||
i++, recs1++, recs2++)
|
||||
if ((*recs1)->ha != (*recs2)->ha)
|
||||
break;
|
||||
|
||||
xdf1->dstart = xdf2->dstart = i;
|
||||
|
||||
recs1 = xdf1->recs + xdf1->nrec - 1;
|
||||
recs2 = xdf2->recs + xdf2->nrec - 1;
|
||||
for (lim -= i, i = 0; i < lim; i++, recs1--, recs2--)
|
||||
if ((*recs1)->ha != (*recs2)->ha)
|
||||
break;
|
||||
|
||||
xdf1->dend = xdf1->nrec - i - 1;
|
||||
xdf2->dend = xdf2->nrec - i - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int xdl_optimize_ctxs(xdlclassifier_t *cf, xdfile_t *xdf1, xdfile_t *xdf2) {
|
||||
|
||||
if (xdl_trim_ends(xdf1, xdf2) < 0 ||
|
||||
xdl_cleanup_records(cf, xdf1, xdf2) < 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
34
src/xdiff/xprepare.h
Normal file
34
src/xdiff/xprepare.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XPREPARE_H)
|
||||
#define XPREPARE_H
|
||||
|
||||
|
||||
|
||||
int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
|
||||
xdfenv_t *xe);
|
||||
void xdl_free_env(xdfenv_t *xe);
|
||||
|
||||
|
||||
|
||||
#endif /* #if !defined(XPREPARE_H) */
|
67
src/xdiff/xtypes.h
Normal file
67
src/xdiff/xtypes.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XTYPES_H)
|
||||
#define XTYPES_H
|
||||
|
||||
|
||||
|
||||
typedef struct s_chanode {
|
||||
struct s_chanode *next;
|
||||
long icurr;
|
||||
} chanode_t;
|
||||
|
||||
typedef struct s_chastore {
|
||||
chanode_t *head, *tail;
|
||||
long isize, nsize;
|
||||
chanode_t *ancur;
|
||||
chanode_t *sncur;
|
||||
long scurr;
|
||||
} chastore_t;
|
||||
|
||||
typedef struct s_xrecord {
|
||||
struct s_xrecord *next;
|
||||
char const *ptr;
|
||||
long size;
|
||||
unsigned long ha;
|
||||
} xrecord_t;
|
||||
|
||||
typedef struct s_xdfile {
|
||||
chastore_t rcha;
|
||||
long nrec;
|
||||
unsigned int hbits;
|
||||
xrecord_t **rhash;
|
||||
long dstart, dend;
|
||||
xrecord_t **recs;
|
||||
char *rchg;
|
||||
long *rindex;
|
||||
long nreff;
|
||||
unsigned long *ha;
|
||||
} xdfile_t;
|
||||
|
||||
typedef struct s_xdfenv {
|
||||
xdfile_t xdf1, xdf2;
|
||||
} xdfenv_t;
|
||||
|
||||
|
||||
|
||||
#endif /* #if !defined(XTYPES_H) */
|
425
src/xdiff/xutils.c
Normal file
425
src/xdiff/xutils.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include "xinclude.h"
|
||||
|
||||
|
||||
|
||||
|
||||
long xdl_bogosqrt(long n) {
|
||||
long i;
|
||||
|
||||
/*
|
||||
* Classical integer square root approximation using shifts.
|
||||
*/
|
||||
for (i = 1; n > 0; n >>= 2)
|
||||
i <<= 1;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
|
||||
xdemitcb_t *ecb) {
|
||||
int i = 2;
|
||||
mmbuffer_t mb[3];
|
||||
|
||||
mb[0].ptr = (char *) pre;
|
||||
mb[0].size = psize;
|
||||
mb[1].ptr = (char *) rec;
|
||||
mb[1].size = size;
|
||||
if (size > 0 && rec[size - 1] != '\n') {
|
||||
mb[2].ptr = (char *) "\n\\ No newline at end of file\n";
|
||||
mb[2].size = strlen(mb[2].ptr);
|
||||
i++;
|
||||
}
|
||||
if (ecb->outf(ecb->priv, mb, i) < 0) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *xdl_mmfile_first(mmfile_t *mmf, long *size)
|
||||
{
|
||||
*size = mmf->size;
|
||||
return mmf->ptr;
|
||||
}
|
||||
|
||||
|
||||
long xdl_mmfile_size(mmfile_t *mmf)
|
||||
{
|
||||
return mmf->size;
|
||||
}
|
||||
|
||||
|
||||
int xdl_cha_init(chastore_t *cha, long isize, long icount) {
|
||||
|
||||
cha->head = cha->tail = NULL;
|
||||
cha->isize = isize;
|
||||
cha->nsize = icount * isize;
|
||||
cha->ancur = cha->sncur = NULL;
|
||||
cha->scurr = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void xdl_cha_free(chastore_t *cha) {
|
||||
chanode_t *cur, *tmp;
|
||||
|
||||
for (cur = cha->head; (tmp = cur) != NULL;) {
|
||||
cur = cur->next;
|
||||
xdl_free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *xdl_cha_alloc(chastore_t *cha) {
|
||||
chanode_t *ancur;
|
||||
void *data;
|
||||
|
||||
if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
|
||||
if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
ancur->icurr = 0;
|
||||
ancur->next = NULL;
|
||||
if (cha->tail)
|
||||
cha->tail->next = ancur;
|
||||
if (!cha->head)
|
||||
cha->head = ancur;
|
||||
cha->tail = ancur;
|
||||
cha->ancur = ancur;
|
||||
}
|
||||
|
||||
data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
|
||||
ancur->icurr += cha->isize;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
long xdl_guess_lines(mmfile_t *mf, long sample) {
|
||||
long nl = 0, size, tsize = 0;
|
||||
char const *data, *cur, *top;
|
||||
|
||||
if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
|
||||
for (top = data + size; nl < sample && cur < top; ) {
|
||||
nl++;
|
||||
if (!(cur = memchr(cur, '\n', top - cur)))
|
||||
cur = top;
|
||||
else
|
||||
cur++;
|
||||
}
|
||||
tsize += (long) (cur - data);
|
||||
}
|
||||
|
||||
if (nl && tsize)
|
||||
nl = xdl_mmfile_size(mf) / (tsize / nl);
|
||||
|
||||
return nl + 1;
|
||||
}
|
||||
|
||||
int xdl_blankline(const char *line, long size, long flags)
|
||||
{
|
||||
long i;
|
||||
|
||||
if (!(flags & XDF_WHITESPACE_FLAGS))
|
||||
return (size <= 1);
|
||||
|
||||
for (i = 0; i < size && XDL_ISSPACE(line[i]); i++)
|
||||
;
|
||||
|
||||
return (i == size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Have we eaten everything on the line, except for an optional
|
||||
* CR at the very end?
|
||||
*/
|
||||
static int ends_with_optional_cr(const char *l, long s, long i)
|
||||
{
|
||||
int complete = s && l[s-1] == '\n';
|
||||
|
||||
if (complete)
|
||||
s--;
|
||||
if (s == i)
|
||||
return 1;
|
||||
/* do not ignore CR at the end of an incomplete line */
|
||||
if (complete && s == i + 1 && l[i] == '\r')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
|
||||
{
|
||||
int i1, i2;
|
||||
|
||||
if (s1 == s2 && !memcmp(l1, l2, s1))
|
||||
return 1;
|
||||
if (!(flags & XDF_WHITESPACE_FLAGS))
|
||||
return 0;
|
||||
|
||||
i1 = 0;
|
||||
i2 = 0;
|
||||
|
||||
/*
|
||||
* -w matches everything that matches with -b, and -b in turn
|
||||
* matches everything that matches with --ignore-space-at-eol,
|
||||
* which in turn matches everything that matches with --ignore-cr-at-eol.
|
||||
*
|
||||
* Each flavor of ignoring needs different logic to skip whitespaces
|
||||
* while we have both sides to compare.
|
||||
*/
|
||||
if (flags & XDF_IGNORE_WHITESPACE) {
|
||||
goto skip_ws;
|
||||
while (i1 < s1 && i2 < s2) {
|
||||
if (l1[i1++] != l2[i2++])
|
||||
return 0;
|
||||
skip_ws:
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
}
|
||||
} else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) {
|
||||
while (i1 < s1 && i2 < s2) {
|
||||
if (XDL_ISSPACE(l1[i1]) && XDL_ISSPACE(l2[i2])) {
|
||||
/* Skip matching spaces and try again */
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
continue;
|
||||
}
|
||||
if (l1[i1++] != l2[i2++])
|
||||
return 0;
|
||||
}
|
||||
} else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL) {
|
||||
while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
|
||||
i1++;
|
||||
i2++;
|
||||
}
|
||||
} else if (flags & XDF_IGNORE_CR_AT_EOL) {
|
||||
/* Find the first difference and see how the line ends */
|
||||
while (i1 < s1 && i2 < s2 && l1[i1] == l2[i2]) {
|
||||
i1++;
|
||||
i2++;
|
||||
}
|
||||
return (ends_with_optional_cr(l1, s1, i1) &&
|
||||
ends_with_optional_cr(l2, s2, i2));
|
||||
}
|
||||
|
||||
/*
|
||||
* After running out of one side, the remaining side must have
|
||||
* nothing but whitespace for the lines to match. Note that
|
||||
* ignore-whitespace-at-eol case may break out of the loop
|
||||
* while there still are characters remaining on both lines.
|
||||
*/
|
||||
if (i1 < s1) {
|
||||
while (i1 < s1 && XDL_ISSPACE(l1[i1]))
|
||||
i1++;
|
||||
if (s1 != i1)
|
||||
return 0;
|
||||
}
|
||||
if (i2 < s2) {
|
||||
while (i2 < s2 && XDL_ISSPACE(l2[i2]))
|
||||
i2++;
|
||||
return (s2 == i2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned long xdl_hash_record_with_whitespace(char const **data,
|
||||
char const *top, long flags) {
|
||||
unsigned long ha = 5381;
|
||||
char const *ptr = *data;
|
||||
int cr_at_eol_only = (flags & XDF_WHITESPACE_FLAGS) == XDF_IGNORE_CR_AT_EOL;
|
||||
|
||||
for (; ptr < top && *ptr != '\n'; ptr++) {
|
||||
if (cr_at_eol_only) {
|
||||
/* do not ignore CR at the end of an incomplete line */
|
||||
if (*ptr == '\r' &&
|
||||
(ptr + 1 < top && ptr[1] == '\n'))
|
||||
continue;
|
||||
}
|
||||
else if (XDL_ISSPACE(*ptr)) {
|
||||
const char *ptr2 = ptr;
|
||||
int at_eol;
|
||||
while (ptr + 1 < top && XDL_ISSPACE(ptr[1])
|
||||
&& ptr[1] != '\n')
|
||||
ptr++;
|
||||
at_eol = (top <= ptr + 1 || ptr[1] == '\n');
|
||||
if (flags & XDF_IGNORE_WHITESPACE)
|
||||
; /* already handled */
|
||||
else if (flags & XDF_IGNORE_WHITESPACE_CHANGE
|
||||
&& !at_eol) {
|
||||
ha += (ha << 5);
|
||||
ha ^= (unsigned long) ' ';
|
||||
}
|
||||
else if (flags & XDF_IGNORE_WHITESPACE_AT_EOL
|
||||
&& !at_eol) {
|
||||
while (ptr2 != ptr + 1) {
|
||||
ha += (ha << 5);
|
||||
ha ^= (unsigned long) *ptr2;
|
||||
ptr2++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ha += (ha << 5);
|
||||
ha ^= (unsigned long) *ptr;
|
||||
}
|
||||
*data = ptr < top ? ptr + 1: ptr;
|
||||
|
||||
return ha;
|
||||
}
|
||||
|
||||
unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
|
||||
unsigned long ha = 5381;
|
||||
char const *ptr = *data;
|
||||
|
||||
if (flags & XDF_WHITESPACE_FLAGS)
|
||||
return xdl_hash_record_with_whitespace(data, top, flags);
|
||||
|
||||
for (; ptr < top && *ptr != '\n'; ptr++) {
|
||||
ha += (ha << 5);
|
||||
ha ^= (unsigned long) *ptr;
|
||||
}
|
||||
*data = ptr < top ? ptr + 1: ptr;
|
||||
|
||||
return ha;
|
||||
}
|
||||
|
||||
unsigned int xdl_hashbits(unsigned int size) {
|
||||
unsigned int val = 1, bits = 0;
|
||||
|
||||
for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++);
|
||||
return bits ? bits: 1;
|
||||
}
|
||||
|
||||
|
||||
int xdl_num_out(char *out, long val) {
|
||||
char *ptr, *str = out;
|
||||
char buf[32];
|
||||
|
||||
ptr = buf + sizeof(buf) - 1;
|
||||
*ptr = '\0';
|
||||
if (val < 0) {
|
||||
*--ptr = '-';
|
||||
val = -val;
|
||||
}
|
||||
for (; val && ptr > buf; val /= 10)
|
||||
*--ptr = "0123456789"[val % 10];
|
||||
if (*ptr)
|
||||
for (; *ptr; ptr++, str++)
|
||||
*str = *ptr;
|
||||
else
|
||||
*str++ = '0';
|
||||
*str = '\0';
|
||||
|
||||
return str - out;
|
||||
}
|
||||
|
||||
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
|
||||
const char *func, long funclen, xdemitcb_t *ecb) {
|
||||
int nb = 0;
|
||||
mmbuffer_t mb;
|
||||
char buf[128];
|
||||
|
||||
memcpy(buf, "@@ -", 4);
|
||||
nb += 4;
|
||||
|
||||
nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1);
|
||||
|
||||
if (c1 != 1) {
|
||||
memcpy(buf + nb, ",", 1);
|
||||
nb += 1;
|
||||
|
||||
nb += xdl_num_out(buf + nb, c1);
|
||||
}
|
||||
|
||||
memcpy(buf + nb, " +", 2);
|
||||
nb += 2;
|
||||
|
||||
nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1);
|
||||
|
||||
if (c2 != 1) {
|
||||
memcpy(buf + nb, ",", 1);
|
||||
nb += 1;
|
||||
|
||||
nb += xdl_num_out(buf + nb, c2);
|
||||
}
|
||||
|
||||
memcpy(buf + nb, " @@", 3);
|
||||
nb += 3;
|
||||
if (func && funclen) {
|
||||
buf[nb++] = ' ';
|
||||
if (funclen > (long)sizeof(buf) - nb - 1)
|
||||
funclen = sizeof(buf) - nb - 1;
|
||||
memcpy(buf + nb, func, funclen);
|
||||
nb += funclen;
|
||||
}
|
||||
buf[nb++] = '\n';
|
||||
|
||||
mb.ptr = buf;
|
||||
mb.size = nb;
|
||||
if (ecb->outf(ecb->priv, &mb, 1) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
int line1, int count1, int line2, int count2)
|
||||
{
|
||||
/*
|
||||
* This probably does not work outside Git, since
|
||||
* we have a very simple mmfile structure.
|
||||
*
|
||||
* Note: ideally, we would reuse the prepared environment, but
|
||||
* the libxdiff interface does not (yet) allow for diffing only
|
||||
* ranges of lines instead of the whole files.
|
||||
*/
|
||||
mmfile_t subfile1, subfile2;
|
||||
xdfenv_t env;
|
||||
|
||||
subfile1.ptr = (char *)diff_env->xdf1.recs[line1 - 1]->ptr;
|
||||
subfile1.size = diff_env->xdf1.recs[line1 + count1 - 2]->ptr +
|
||||
diff_env->xdf1.recs[line1 + count1 - 2]->size - subfile1.ptr;
|
||||
subfile2.ptr = (char *)diff_env->xdf2.recs[line2 - 1]->ptr;
|
||||
subfile2.size = diff_env->xdf2.recs[line2 + count2 - 2]->ptr +
|
||||
diff_env->xdf2.recs[line2 + count2 - 2]->size - subfile2.ptr;
|
||||
if (xdl_do_diff(&subfile1, &subfile2, xpp, &env) < 0)
|
||||
return -1;
|
||||
|
||||
memcpy(diff_env->xdf1.rchg + line1 - 1, env.xdf1.rchg, count1);
|
||||
memcpy(diff_env->xdf2.rchg + line2 - 1, env.xdf2.rchg, count2);
|
||||
|
||||
xdl_free_env(&env);
|
||||
|
||||
return 0;
|
||||
}
|
47
src/xdiff/xutils.h
Normal file
47
src/xdiff/xutils.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* LibXDiff by Davide Libenzi ( File Differential Library )
|
||||
* Copyright (C) 2003 Davide Libenzi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Davide Libenzi <davidel@xmailserver.org>
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(XUTILS_H)
|
||||
#define XUTILS_H
|
||||
|
||||
|
||||
|
||||
long xdl_bogosqrt(long n);
|
||||
int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
|
||||
xdemitcb_t *ecb);
|
||||
int xdl_cha_init(chastore_t *cha, long isize, long icount);
|
||||
void xdl_cha_free(chastore_t *cha);
|
||||
void *xdl_cha_alloc(chastore_t *cha);
|
||||
long xdl_guess_lines(mmfile_t *mf, long sample);
|
||||
int xdl_blankline(const char *line, long size, long flags);
|
||||
int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
|
||||
unsigned long xdl_hash_record(char const **data, char const *top, long flags);
|
||||
unsigned int xdl_hashbits(unsigned int size);
|
||||
int xdl_num_out(char *out, long val);
|
||||
int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
|
||||
const char *func, long funclen, xdemitcb_t *ecb);
|
||||
int xdl_fall_back_diff(xdfenv_t *diff_env, xpparam_t const *xpp,
|
||||
int line1, int count1, int line2, int count2);
|
||||
|
||||
|
||||
|
||||
#endif /* #if !defined(XUTILS_H) */
|
Reference in New Issue
Block a user