├── .github
└── workflows
│ ├── build.ps1
│ ├── install.ps1
│ ├── package.ps1
│ ├── test.ps1
│ └── windows.yml
├── .gitignore
├── .travis.yml
├── CREDITS
├── LICENSE
├── README.API
├── config.m4
├── config.w32
├── package.xml
├── php_xdiff.h
├── tests
├── 001.phpt
├── 002.phpt
├── 003.phpt
├── 004.phpt
├── 005.phpt
├── 006.phpt
├── 007.phpt
├── 008.phpt
├── 009.phpt
├── 010.phpt
├── 011.phpt
├── 012.phpt
├── 013.phpt
├── 014.phpt
├── 015.phpt
├── 016.phpt
├── 017.phpt
├── 018.phpt
├── 019.phpt
├── 020.phpt
├── 021.phpt
├── 022.phpt
├── 023.phpt
├── 024.phpt
├── 025.phpt
├── 026.phpt
├── 027.phpt
├── 028.phpt
├── 029.phpt
├── 030.phpt
├── 031.phpt
├── 032.phpt
├── 033.phpt
├── 034.phpt
├── 035.phpt
├── bug81552.phpt
├── context1.patch
├── context5.patch
├── error-bpatch.phpt
├── error-patch.phpt
├── error-patch2.phpt
├── file.1
├── file.2
├── file.bdiff
├── file.rabdiff
├── file_test.diff
├── logo.bdiff
├── logo.rabdiff
├── lorem1.txt
├── lorem2.txt
├── merge1.h
├── merge2.h
├── merge3.h
├── merge4.h
├── php.png
└── zend.png
├── xdiff.c
├── xdiff.stub.php
└── xdiff_arginfo.h
/.github/workflows/build.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [Parameter(Mandatory)] $arch
3 | )
4 |
5 | $ErrorActionPreference = "Stop"
6 |
7 | Set-Location ..
8 |
9 | $develdir = (Get-Item "php-devel").FullName
10 | $phpdir = (Get-Item "php").FullName
11 | $Env:PATH = "$develdir;$phpdir;$Env:PATH"
12 |
13 | Set-Location "pecl-text-xdiff"
14 |
15 | $task = New-Item "..\task.bat" -Force
16 | Add-Content $task "call phpize 2>&1"
17 | Add-Content $task "call configure --with-prefix=$phpdir --with-extra-includes=deps\include --with-extra-libs=deps\lib --enable-debug-pack --with-xdiff"
18 | Add-Content $task "nmake 2>&1"
19 | Add-Content $task "exit %errorlevel%"
20 | & "..\php-sdk\phpsdk-vc15-$arch.bat" -t $task
21 | if (-not $?) {
22 | throw "build failed with errorlevel $LastExitCode"
23 | }
24 |
--------------------------------------------------------------------------------
/.github/workflows/install.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [Parameter(Mandatory)] $version,
3 | [Parameter(Mandatory)] $ts,
4 | [Parameter(Mandatory)] $arch,
5 | [Parameter(Mandatory)] $libxdiff
6 | )
7 |
8 | $ErrorActionPreference = "Stop"
9 |
10 | if ($ts -eq "ts") {
11 | $tspart = ""
12 | } else {
13 | $tspart = "-nts";
14 | }
15 |
16 | $releases = Invoke-WebRequest "https://windows.php.net/downloads/releases/releases.json" | ConvertFrom-Json
17 | $phpversion = $releases.$version.version
18 |
19 | Set-Location ..
20 |
21 | # SDK
22 |
23 | $file = "php-sdk-2.2.0.zip"
24 | Invoke-WebRequest "https://github.com/microsoft/php-sdk-binary-tools/archive/$file" -OutFile $file
25 | Expand-Archive $file -DestinationPath .
26 | Move-Item "php-sdk-binary-tools-php-sdk-2.2.0" -Destination "php-sdk"
27 |
28 | # PHP binaries
29 |
30 | $file = "php-$phpversion$tspart-Win32-vc15-$arch.zip"
31 | Invoke-WebRequest "https://windows.php.net/downloads/releases/$file" -OutFile $file
32 | Expand-Archive $file -DestinationPath "php"
33 |
34 | # PHP devel pack
35 |
36 | $file = "php-devel-pack-$phpversion$tspart-Win32-vc15-$arch.zip"
37 | Invoke-WebRequest "https://windows.php.net/downloads/releases/$file" -OutFile $file
38 | Expand-Archive $file -DestinationPath .
39 | Move-Item "php-$phpversion-devel-vc15-$arch" -Destination "php-devel"
40 |
41 | # libxdiff
42 |
43 | $file = "libxdiff-$libxdiff-vc15-$arch.zip"
44 | Invoke-WebRequest "https://windows.php.net/downloads/pecl/deps/$file" -OutFile $file
45 | Expand-Archive $file -DestinationPath "deps"
46 | Move-Item "deps\COPYING" "deps\COPYING.LIBXDIFF"
47 |
--------------------------------------------------------------------------------
/.github/workflows/package.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [Parameter(Mandatory)] $ts,
3 | [Parameter(Mandatory)] $arch
4 | )
5 |
6 | $ErrorActionPreference = "Stop"
7 |
8 | if ($arch -eq "x86") {
9 | $builddir = "."
10 | } else {
11 | $builddir = "x64"
12 | }
13 | $builddir += "\Release"
14 | if ($ts -eq "ts") {
15 | $builddir += "_TS"
16 | }
17 |
18 | $dir = New-Item "windows_package" -ItemType "directory"
19 | Copy-Item "..\deps\COPYING.LIBXDIFF" -Destination $dir
20 | Copy-Item "CREDITS" -Destination $dir
21 | Copy-Item "LICENSE" -Destination $dir
22 | Copy-Item "README.API" -Destination $dir
23 | Copy-Item "$builddir\php_xdiff.dll" -Destination $dir
24 | Copy-Item "$builddir\php_xdiff.pdb" -Destination $dir
25 |
--------------------------------------------------------------------------------
/.github/workflows/test.ps1:
--------------------------------------------------------------------------------
1 | param (
2 | [Parameter(Mandatory)] $arch
3 | )
4 |
5 | $ErrorActionPreference = "Stop"
6 |
7 | Set-Location ..
8 |
9 | $develdir = (Get-Item "php-devel").FullName
10 | $phpdir = (Get-Item "php").FullName
11 | $Env:PATH = "$develdir;$phpdir;$Env:PATH"
12 |
13 | Set-Location "pecl-text-xdiff"
14 |
15 | $task = New-Item "..\task.bat" -Force
16 | Add-Content $task 'nmake test TESTS="--show-diff tests" 2>&1'
17 | Add-Content $task "exit %errorlevel%"
18 | & "..\php-sdk\phpsdk-vc15-$arch.bat" -t $task
19 | if (-not $?) {
20 | throw "build failed with errorlevel $LastExitCode"
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/windows.yml:
--------------------------------------------------------------------------------
1 | name: Windows build
2 | on: [push]
3 | jobs:
4 | build:
5 | strategy:
6 | matrix:
7 | version: [7.4, 7.3]
8 | ts: [nts, ts]
9 | arch: [x64, x86]
10 | runs-on: windows-2016
11 | steps:
12 | - name: Set git to use LF
13 | run: |
14 | git config --global core.autocrlf false
15 | git config --global core.eol lf
16 | - name: Checkout
17 | uses: actions/checkout@v2
18 | - name: Install
19 | run: ./.github/workflows/install.ps1 -version ${{matrix.version}} -ts ${{matrix.ts}} -arch ${{matrix.arch}} -libxdiff 0.23
20 | - name: Build
21 | run: ./.github/workflows/build.ps1 -arch ${{matrix.arch}}
22 | - name: Package
23 | run: ./.github/workflows/package.ps1 -ts ${{matrix.ts}} -arch ${{matrix.arch}}
24 | - name: Test
25 | run: ./.github/workflows/test.ps1 -arch ${{matrix.arch}}
26 | - name: Upload
27 | uses: actions/upload-artifact@v2
28 | with:
29 | name: php_xdiff-dev-${{matrix.version}}-${{matrix.ts}}-vc15-${{matrix.arch}}
30 | path: windows_package
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .deps
2 | *.lo
3 | *.la
4 | *.dep
5 | .libs
6 | Makefile
7 | Makefile.fragments
8 | Makefile.global
9 | Makefile.objects
10 | acinclude.m4
11 | aclocal.m4
12 | autom4te.cache/
13 | build/
14 | config.guess
15 | config.h
16 | config.h.in
17 | config.h.in~
18 | config.log
19 | config.nice
20 | config.status
21 | config.sub
22 | configure
23 | configure.in
24 | configure.ac
25 | install-sh
26 | libtool
27 | ltmain.sh
28 | ltmain.sh.backup
29 | missing
30 | mkinstalldirs
31 | run-tests.php
32 | tmp-php.ini
33 | modules
34 | libxdiff*
35 | xdiff-*.tgz
36 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | php:
3 | - nightly
4 | sudo: true
5 | env:
6 | - REPORT_EXIT_STATUS=1 NO_INTERACTION=1
7 | before_install:
8 | - sudo add-apt-repository ppa:curse-sds/ppa -y
9 | - sudo apt-get update -q
10 | - sudo apt-get install libxdiff-dev libxdiff0
11 | install:
12 | - phpize
13 | - EXTRA_LDFLAGS="-precious-files-regex .libs/xdiff.gcno" LDFLAGS="-lgcov" CFLAGS="-Wall -fno-strict-aliasing -coverage -O0" ./configure
14 | - make all
15 | script:
16 | - TEST_PHP_EXECUTABLE=$(which php) php -n
17 | -d open_basedir= -d output_buffering=0 -d memory_limit=-1
18 | run-tests.php -n
19 | -d extension_dir=modules -d extension=xdiff.so --show-diff
20 | tests
21 | - gcov --object-directory .libs *.c
22 | - bash <(curl -s https://codecov.io/bash)
23 |
--------------------------------------------------------------------------------
/CREDITS:
--------------------------------------------------------------------------------
1 | xdiff php extension
2 | Marcin Gibula
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | --------------------------------------------------------------------
2 | The PHP License, version 3.01
3 | Copyright (c) 1999 - 2015 The PHP Group. All rights reserved.
4 | --------------------------------------------------------------------
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, is permitted provided that the following conditions
8 | are met:
9 |
10 | 1. Redistributions of source code must retain the above copyright
11 | notice, this list of conditions and the following disclaimer.
12 |
13 | 2. Redistributions in binary form must reproduce the above copyright
14 | notice, this list of conditions and the following disclaimer in
15 | the documentation and/or other materials provided with the
16 | distribution.
17 |
18 | 3. The name "PHP" must not be used to endorse or promote products
19 | derived from this software without prior written permission. For
20 | written permission, please contact group@php.net.
21 |
22 | 4. Products derived from this software may not be called "PHP", nor
23 | may "PHP" appear in their name, without prior written permission
24 | from group@php.net. You may indicate that your software works in
25 | conjunction with PHP by saying "Foo for PHP" instead of calling
26 | it "PHP Foo" or "phpfoo"
27 |
28 | 5. The PHP Group may publish revised and/or new versions of the
29 | license from time to time. Each version will be given a
30 | distinguishing version number.
31 | Once covered code has been published under a particular version
32 | of the license, you may always continue to use it under the terms
33 | of that version. You may also choose to use such covered code
34 | under the terms of any subsequent version of the license
35 | published by the PHP Group. No one other than the PHP Group has
36 | the right to modify the terms applicable to covered code created
37 | under this License.
38 |
39 | 6. Redistributions of any form whatsoever must retain the following
40 | acknowledgment:
41 | "This product includes PHP software, freely available from
42 | ".
43 |
44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55 | OF THE POSSIBILITY OF SUCH DAMAGE.
56 |
57 | --------------------------------------------------------------------
58 |
59 | This software consists of voluntary contributions made by many
60 | individuals on behalf of the PHP Group.
61 |
62 | The PHP Group can be contacted via Email at group@php.net.
63 |
64 | For more information on the PHP Group and the PHP project,
65 | please see .
66 |
67 | PHP includes the Zend Engine, freely available at
68 | .
69 |
--------------------------------------------------------------------------------
/README.API:
--------------------------------------------------------------------------------
1 | This extension requires libxdiff (http://www.xmailserver.org/xdiff-lib.html).
2 |
3 | API:
4 |
5 | * mixed xdiff_string_diff(string str1, string str2, [int context, [bool minimal]])
6 |
7 | Makes unified diff of strings str1 and str2. 'context' indicates how many
8 | lines of context you want to include in diff result. Set 'minimal' to true if
9 | you want to minimalize size of diff (can take a long time). Returns string
10 | with result or false if an internal error happened.
11 |
12 | * bool xdiff_file_diff(string file1, string file2, string dest, [int context, [bool minimal]])
13 |
14 | Makes unified diff of files file1 and file2 and stores result in file dest.
15 | 'context' indicates how many lines of context you want to include in diff
16 | result. Set 'minimal' to true if you want to minimalize size of diff (can take
17 | a long time).
18 |
19 | * mixed xdiff_string_diff_binary(string str1, string str2)
20 |
21 | Makes binary diff of strings str1 and str2. Returns string with result or
22 | false if an internal error happened.
23 |
24 | * bool xdiff_file_diff_binary(string file1, string file2, string dest)
25 |
26 | Makes binary diff of files file1 and file2 and stores result in file dest.
27 | Returns string with result or false if an internal error happened.
28 |
29 | * string xdiff_string_patch(string file, string patch [, int flags, [string error]])
30 |
31 | Patches string 'file' with unified patch in 'patch' and returns a patched string.
32 | 'flags' can be one of:
33 | XDIFF_PATCH_NORMAL - normal patch (default)
34 | XDIFF_PATCH_REVERSE - reverse patch
35 |
36 | If 'error' is passed then error is stored inside this variable (it is passed by reference).
37 |
38 | * mixed xdiff_file_patch(string file, string patch, string dest [, int flags])
39 |
40 | Patches file 'file' with unified patch in file 'patch'.
41 | 'flags' can be one of:
42 | XDIFF_PATCH_NORMAL - normal patch (default)
43 | XDIFF_PATCH_REVERSE - reverse patch
44 |
45 | Returns false if an internal error happened, string with rejected chunks of
46 | patch or true if patch was applied successfully.
47 |
48 | * string xdiff_string_patch_binary(string str, string patch)
49 |
50 | Patches string 'str' with binary patch 'patch'.
51 | Returns patched string or false if an internal error happened.
52 |
53 | * bool xdiff_file_patch_binary(string file, string patch, string dest)
54 |
55 | Patches file 'file' with binary patch in file 'patch' and stores result in file 'dest'.
56 | Returns true if file was patched successfully, false otherwise.
57 |
58 | * string xdiff_string_merge3(string str1, string str2, string str3 [, string error])
59 |
60 | Merges strings 'str1', 'str2' and 'str3' into one. Returns merged string or
61 | false if an internal error happened. If 'error' is passed then error is
62 | stored inside this variable (it is passed by reference).
63 |
64 | * mixed xdiff_file_merge3(string file1, string file2, string file3, string dest)
65 |
66 | Merges files 'file1', 'file2' and 'file3' into one and stores result in file
67 | 'dest'. Returns true if merge was successful, string with rejected chunks if
68 | it was not or false if an internal error happened.
69 |
70 |
71 | vim:tw=78:et:
72 |
--------------------------------------------------------------------------------
/config.m4:
--------------------------------------------------------------------------------
1 | dnl $Id$
2 | dnl config.m4 for extension xdiff
3 |
4 | PHP_ARG_WITH(xdiff, for xdiff support,
5 | [ --with-xdiff Include xdiff support])
6 |
7 |
8 | if test "$PHP_XDIFF" != "no"; then
9 |
10 | SEARCH_PATH="/usr/local /usr" # you might want to change this
11 | SEARCH_FOR="/include/xdiff.h" # you most likely want to change this
12 | if test -r $PHP_XDIFF/; then # path given as parameter
13 | XDIFF_DIR=$PHP_XDIFF
14 | else # search default path list
15 | AC_MSG_CHECKING([for xdiff files in default path])
16 | for i in $SEARCH_PATH ; do
17 | if test -r $i/$SEARCH_FOR; then
18 | XDIFF_DIR=$i
19 | AC_MSG_RESULT(found in $i)
20 | fi
21 | done
22 | fi
23 |
24 | if test -z "$XDIFF_DIR"; then
25 | AC_MSG_RESULT([not found])
26 | AC_MSG_ERROR([Please reinstall the libxdiff distribution])
27 | fi
28 |
29 | PHP_ADD_INCLUDE($XDIFF_DIR/include)
30 |
31 | EXTRA_LIBS="-lm"
32 | AC_CHECK_LIB(dl, dlopen, [
33 | EXTRA_LIBS="$EXTRA_LIBS -ldl"
34 | ])
35 |
36 | LIBNAME=xdiff
37 | LIBSYMBOL=xdl_diff
38 |
39 | PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL,
40 | [
41 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $XDIFF_DIR/lib, XDIFF_SHARED_LIBADD)
42 | AC_DEFINE(HAVE_XDIFFLIB,1, [ libxdiff ])
43 | ],[
44 | AC_MSG_ERROR([wrong xdiff lib version or lib not found])
45 | ],[
46 | -L$XDIFF_DIR/lib $EXTRA_LIBS
47 | ])
48 | PHP_SUBST(XDIFF_SHARED_LIBADD)
49 |
50 | dnl check for if XDL_PATCH_IGNOREBSPACE is available
51 | old_CPPFLAGS=$CPPFLAGS
52 | CPPFLAGS=-I$XDIFF_DIR/include
53 | AC_MSG_CHECKING(if XDL_PATCH_IGNOREBSPACE is defined)
54 | AC_TRY_COMPILE([
55 | #include ],[
56 | int i = XDL_PATCH_IGNOREBSPACE;
57 | ], AC_MSG_RESULT(yes) , AC_MSG_ERROR(your libxdiff version is too old) )
58 | CPPFLAGS=$old_CPPFLAGS
59 |
60 | dnl check for xdl_rabdiff function
61 | PHP_CHECK_LIBRARY(xdiff,xdl_set_allocator, [ ], AC_MSG_ERROR([your libxdiff version is too old]))
62 |
63 | dnl check for xdl_rabdiff function
64 | PHP_CHECK_LIBRARY(xdiff,xdl_rabdiff, [ ], AC_MSG_ERROR([your libxdiff version is too old]))
65 |
66 | PHP_NEW_EXTENSION(xdiff, xdiff.c, $ext_shared)
67 | fi
68 |
--------------------------------------------------------------------------------
/config.w32:
--------------------------------------------------------------------------------
1 | // $Id$
2 | // vim:ft=javascript
3 |
4 | ARG_WITH("xdiff", "libxdiff support", "no");
5 |
6 | if (PHP_XDIFF != "no") {
7 | if (CHECK_LIB("xdiff.lib;xdiff_a.lib", "xdiff", PHP_XDIFF + ";..\\libxdiff-*") &&
8 | CHECK_HEADER_ADD_INCLUDE("xdiff.h", "CFLAGS_XDIFF", PHP_XDIFF + ";..\\libxdiff-*\\xdiff")) {
9 | EXTENSION("xdiff", "xdiff.c");
10 | } else {
11 | WARNING("did not find xdiff includes/libs");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | xdiff
7 | pecl.php.net
8 | File differences/patches.
9 | This extension creates and applies patches to both text and binary files.
10 |
11 |
12 | Marcin Gibula
13 | mg
14 | mg@iceni.pl
15 | yes
16 |
17 |
18 | Sean DuBois
19 | SeanDer
20 | sean@siobud.com
21 | yes
22 |
23 |
24 | Remi Collet
25 | remi
26 | remi@php.net
27 | yes
28 |
29 | 2022-05-24
30 |
31 | 2.1.1
32 | 2.1.0
33 |
34 |
35 | stable
36 | stable
37 |
38 | PHP License
39 |
40 | - Fixed bug #81552 xdiff_string_bpatch() and others missing (Kevin Israel)
41 | - Fixed bug #77826 xdiff_string_bpatch wrong return value on error (SATO Kentaro)
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | 7.0.0
117 |
118 |
119 | 1.10
120 |
121 |
122 |
123 | xdiff
124 |
125 |
126 |
127 |
128 |
129 | 2021-05-18
130 |
131 | 2.1.0
132 | 2.1.0
133 |
134 |
135 | stable
136 | stable
137 |
138 | PHP License
139 |
140 | - PHP 8 support
141 | - Drop PHP 5 support
142 |
143 |
144 |
145 |
146 | 2.0.1
147 | 2.0
148 |
149 |
150 | stable
151 | beta
152 |
153 | 2016-05-17
154 | PHP License
155 | Update License to PHP 3.1
156 |
157 |
158 |
159 | 2.0.0
160 | 2.0
161 |
162 |
163 | stable
164 | beta
165 |
166 | 2015-11-23
167 | PHP License
168 | PHP 7 Release.
169 |
170 |
171 |
172 | 1.5.1
173 | 1.5
174 |
175 |
176 | beta
177 | beta
178 |
179 | 2009-10-18
180 | PHP License
181 | Fix for #16566.
182 |
183 |
184 |
185 | 1.5.0
186 | 1.5
187 |
188 |
189 | beta
190 | beta
191 |
192 | 2009-10-18
193 | PHP License
194 | New functions added. Memory optimizations. Better handling of out of memory situations.
195 |
196 |
197 |
198 | 1.4.1
199 | 1.4
200 |
201 |
202 | stable
203 | stable
204 |
205 | 2008-07-01
206 | PHP License
207 | Fixes for #7215, #7422 and #8227.
208 |
209 |
210 |
211 | 1.4
212 | 1.4
213 |
214 |
215 | stable
216 | stable
217 |
218 | 2005-11-14
219 | PHP License
220 | Fixed bug #5064.
221 |
222 |
223 |
224 | 1.3
225 | 1.3
226 |
227 |
228 | stable
229 | stable
230 |
231 | 2005-05-09
232 | PHP License
233 | Fix compile error.
234 |
235 |
236 |
237 | 1.2
238 | 1.2
239 |
240 |
241 | stable
242 | stable
243 |
244 | 2004-11-09
245 | PHP License
246 | Fix libxdiff 0.9 crash. Force last parameters of xdiff_string_patch and xdiff_string_merge3 to be passed by reference.
247 |
248 |
249 |
250 | 1.1
251 | 1.1
252 |
253 |
254 | stable
255 | stable
256 |
257 | 2004-03-21
258 | PHP License
259 | Fix FreeBSD build.
260 |
261 |
262 |
263 | 1.0
264 | 1.0
265 |
266 |
267 | stable
268 | stable
269 |
270 | 2004-02-09
271 | PHP License
272 | Add support to memory_limit (libxdiff >= 0.6 required).
273 |
274 |
275 |
276 | 0.3
277 | 0.3
278 |
279 |
280 | alpha
281 | alpha
282 |
283 | 2004-01-10
284 | PHP License
285 | Win32 build fixes.
286 |
287 |
288 |
289 | 0.2
290 | 0.2
291 |
292 |
293 | alpha
294 | alpha
295 |
296 | 2004-01-08
297 | PHP License
298 | Initial release.
299 |
300 |
301 |
302 |
--------------------------------------------------------------------------------
/php_xdiff.h:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | Copyright (c) The PHP Group |
4 | +----------------------------------------------------------------------+
5 | | This source file is subject to version 3.1 of the PHP license, |
6 | | that is bundled with this package in the file LICENSE, and is |
7 | | available at through the world-wide-web at |
8 | | http://www.php.net/license/3_1.txt. |
9 | | If you did not receive a copy of the PHP license and are unable to |
10 | | obtain it through the world-wide-web, please send a note to |
11 | | license@php.net so we can mail you a copy immediately. |
12 | +----------------------------------------------------------------------+
13 | | Author: Marcin Gibula |
14 | +----------------------------------------------------------------------+
15 |
16 | $Id$
17 | */
18 |
19 | #ifndef PHP_XDIFF_H
20 | #define PHP_XDIFF_H
21 |
22 | extern zend_module_entry xdiff_module_entry;
23 | #define phpext_xdiff_ptr &xdiff_module_entry
24 |
25 | #define PHP_XDIFF_VERSION "2.1.1"
26 |
27 | #ifdef PHP_WIN32
28 | #define PHP_XDIFF_API __declspec(dllexport)
29 | #else
30 | #define PHP_XDIFF_API
31 | #endif
32 |
33 | #ifdef ZTS
34 | #include "TSRM.h"
35 | #endif
36 |
37 | PHP_MINIT_FUNCTION(xdiff);
38 | PHP_MINFO_FUNCTION(xdiff);
39 |
40 | #endif /* PHP_XDIFF_H */
41 |
42 |
43 | /*
44 | * Local variables:
45 | * tab-width: 4
46 | * c-basic-offset: 4
47 | * indent-tabs-mode: t
48 | * End:
49 | */
50 |
--------------------------------------------------------------------------------
/tests/001.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Check for xdiff presence
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
9 | --EXPECT--
10 | xdiff extension is available
11 |
--------------------------------------------------------------------------------
/tests/002.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_diff()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
11 | --EXPECT--
12 | @@ -3,3 +3,3 @@
13 | echo $a;
14 | -$b = 320;
15 | +$b = 420;
16 | echo $b;
17 |
18 |
--------------------------------------------------------------------------------
/tests/003.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_diff()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
11 | --EXPECT--
12 | @@ -3,3 +3,3 @@
13 | echo $a;
14 | -$b = 320;
15 | +$b = 420;
16 | echo $b;
17 |
18 |
--------------------------------------------------------------------------------
/tests/004.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_diff_binary()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/005.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_diff_binary()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/006.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | int(0)
15 |
--------------------------------------------------------------------------------
/tests/007.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | int(0)
15 |
--------------------------------------------------------------------------------
/tests/008.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch_binary()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/009.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch_binary()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/010.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_merge3()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
14 | --EXPECT--
15 | 0
16 |
--------------------------------------------------------------------------------
/tests/011.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_merge3()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/012.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_rabdiff()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/013.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_rabdiff()
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/014.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch_binary() with rabdiff patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/015.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch_binary() with rabdiff patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/016.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_diff_binary() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/017.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_diff_binary() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/018.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_rabdiff() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/019.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_rabdiff() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/020.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch_binary() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/021.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch_binary() with binary data and rabdiff patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/022.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch_binary() with binary data
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/023.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch_binary() with binary data and rabdiff patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/024.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_diff() with context = 1
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
12 | --EXPECT--
13 | 0
14 |
--------------------------------------------------------------------------------
/tests/025.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_diff() with context = 5
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
12 | --EXPECT--
13 | 0
14 |
--------------------------------------------------------------------------------
/tests/026.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_diff() with context = 1
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
11 | --EXPECT--
12 | 0
13 |
--------------------------------------------------------------------------------
/tests/027.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_diff() with context = 5
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
11 | --EXPECT--
12 | 0
13 |
--------------------------------------------------------------------------------
/tests/028.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() with context1.patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/029.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() with context5.patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/030.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() with context1.patch and reverse patching
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/031.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() with context5.patch and reverse patching
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/032.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch() and context1.patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/033.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch() and context5.patch
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/034.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch() and context1.patch and reverse patching
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/035.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_file_patch() and context5.patch and reverse patching
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | 0
15 |
--------------------------------------------------------------------------------
/tests/bug81552.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | Bug #81552: xdiff_string_bpatch() and others missing
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
18 | --EXPECT--
19 | string(44) "The quick brown fox jumps over the lazy cog."
20 | int(0)
21 |
--------------------------------------------------------------------------------
/tests/context1.patch:
--------------------------------------------------------------------------------
1 | @@ -9,6 +9,2 @@
2 |
3 | - * Aenean porta lectus ut diam.
4 | - * Vestibulum volutpat sollicitudin lorem.
5 | - * Morbi at tortor vel pede scelerisque eleifend.
6 | -
7 | * Mauris sed dolor sed est aliquam lobortis.
8 |
--------------------------------------------------------------------------------
/tests/context5.patch:
--------------------------------------------------------------------------------
1 | @@ -5,14 +5,10 @@
2 | * Curabitur a lorem ut tellus fermentum molestie.
3 | * Etiam eleifend sollicitudin neque.
4 | * Etiam quis justo in felis gravida rutrum.
5 | * Aenean ultrices diam id mi.
6 |
7 | - * Aenean porta lectus ut diam.
8 | - * Vestibulum volutpat sollicitudin lorem.
9 | - * Morbi at tortor vel pede scelerisque eleifend.
10 | -
11 | * Mauris sed dolor sed est aliquam lobortis.
12 | * Donec vestibulum nulla a augue.
13 | * Aliquam viverra sollicitudin nisl.
14 | * Nam vitae massa venenatis orci consequat fringilla.
15 |
16 |
--------------------------------------------------------------------------------
/tests/error-bpatch.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_bpatch() error
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
12 | --EXPECT--
13 | bool(false)
14 |
--------------------------------------------------------------------------------
/tests/error-patch.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() error
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
12 | --EXPECT--
13 | bool(false)
14 |
--------------------------------------------------------------------------------
/tests/error-patch2.phpt:
--------------------------------------------------------------------------------
1 | --TEST--
2 | xdiff_string_patch() rejection
3 | --SKIPIF--
4 |
5 | --FILE--
6 |
13 | --EXPECT--
14 | bool(true)
15 | bool(true)
16 |
--------------------------------------------------------------------------------
/tests/file.1:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/tests/file.2:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/tests/file.bdiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/file.bdiff
--------------------------------------------------------------------------------
/tests/file.rabdiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/file.rabdiff
--------------------------------------------------------------------------------
/tests/file_test.diff:
--------------------------------------------------------------------------------
1 | @@ -3,3 +3,3 @@
2 | echo $a;
3 | -$b = 320;
4 | +$b = 420;
5 | echo $b;
6 |
--------------------------------------------------------------------------------
/tests/logo.bdiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/logo.bdiff
--------------------------------------------------------------------------------
/tests/logo.rabdiff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/logo.rabdiff
--------------------------------------------------------------------------------
/tests/lorem1.txt:
--------------------------------------------------------------------------------
1 | * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
2 | * Curabitur fermentum rhoncus leo.
3 | * Phasellus pretium nibh nec neque.
4 | * In porta lectus nec ligula.
5 | * Curabitur a lorem ut tellus fermentum molestie.
6 | * Etiam eleifend sollicitudin neque.
7 | * Etiam quis justo in felis gravida rutrum.
8 | * Aenean ultrices diam id mi.
9 |
10 | * Aenean porta lectus ut diam.
11 | * Vestibulum volutpat sollicitudin lorem.
12 | * Morbi at tortor vel pede scelerisque eleifend.
13 |
14 | * Mauris sed dolor sed est aliquam lobortis.
15 | * Donec vestibulum nulla a augue.
16 | * Aliquam viverra sollicitudin nisl.
17 | * Nam vitae massa venenatis orci consequat fringilla.
18 |
19 | * Nullam sollicitudin dignissim sem.
20 | * Aenean sed tellus id felis rhoncus eleifend.
21 | * Vivamus vulputate turpis eu tortor.
22 | * Sed vulputate sollicitudin dui.
23 | * Proin porta nibh ac orci.
24 |
--------------------------------------------------------------------------------
/tests/lorem2.txt:
--------------------------------------------------------------------------------
1 | * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
2 | * Curabitur fermentum rhoncus leo.
3 | * Phasellus pretium nibh nec neque.
4 | * In porta lectus nec ligula.
5 | * Curabitur a lorem ut tellus fermentum molestie.
6 | * Etiam eleifend sollicitudin neque.
7 | * Etiam quis justo in felis gravida rutrum.
8 | * Aenean ultrices diam id mi.
9 |
10 | * Mauris sed dolor sed est aliquam lobortis.
11 | * Donec vestibulum nulla a augue.
12 | * Aliquam viverra sollicitudin nisl.
13 | * Nam vitae massa venenatis orci consequat fringilla.
14 |
15 | * Nullam sollicitudin dignissim sem.
16 | * Aenean sed tellus id felis rhoncus eleifend.
17 | * Vivamus vulputate turpis eu tortor.
18 | * Sed vulputate sollicitudin dui.
19 | * Proin porta nibh ac orci.
20 |
--------------------------------------------------------------------------------
/tests/merge1.h:
--------------------------------------------------------------------------------
1 | #ifndef PHP_XDIFF_H
2 | #define PHP_XDIFF_H
3 |
4 | extern zend_module_entry xdiff_module_entry;
5 | #define phpext_xdiff_ptr &diff_module_entry
6 |
7 | #ifdef PHP_WIN32
8 | #define PHP_XDIFF_API __declspec(dllexport)
9 | #else
10 | #define PHP_XDIFF_API
11 | #endif
12 |
13 | #ifdef ZTS
14 | #include "TSRM.h"
15 | #endif
16 |
17 | PHP_MINIT_FUNCTION(xdiff);
18 | PHP_MINFO_FUNCTION(xdiff);
19 |
20 | PHP_FUNCTION(xdiff_file_diff);
21 | PHP_FUNCTION(xdiff_file_diff_binary);
22 | PHP_FUNCTION(xdiff_file_patch);
23 | PHP_FUNCTION(xdiff_file_patch_binary);
24 | PHP_FUNCTION(xdiff_file_merge3);
25 |
26 | PHP_FUNCTION(xdiff_string_diff);
27 | PHP_FUNCTION(xdiff_string_diff_binary);
28 | PHP_FUNCTION(xdiff_string_patch);
29 | PHP_FUNCTION(xdiff_string_patch_binary);
30 | PHP_FUNCTION(xdiff_string_merge3);
31 |
32 | #endif /* PHP_XDIFF_H */
33 |
34 |
35 | /*
36 | * Local variables:
37 | * tab-width: 4
38 | * c-basic-offset: 4
39 | * indent-tabs-mode: t
40 | * End:
41 | */
42 |
--------------------------------------------------------------------------------
/tests/merge2.h:
--------------------------------------------------------------------------------
1 | #ifndef PHP_XDIFF_H
2 | #define PHP_XDIFF_H
3 |
4 | #foo
5 | #define phpext_xdiff_ptr &diff_module_entry
6 |
7 | #ifdef PHP_WIN32
8 | #define PHP_XDIFF_API __declspec(dllexport)
9 | #else
10 | #define PHP_XDIFF_API
11 | #endif
12 |
13 | #ifdef ZTS
14 | #include "TSRM.h"
15 | #endif
16 |
17 | PHP_MINIT_FUNCTION(xdiff);
18 | PHP_MINFO_FUNCTION(xdiff);
19 |
20 | PHP_FUNCTION(xdiff_file_diff);
21 | PHP_FUNCTION(xdiff_file_diff_binary);
22 | PHP_FUNCTION(xdiff_file_patch);
23 | PHP_FUNCTION(xdiff_file_patch_binary);
24 | PHP_FUNCTION(xdiff_file_merge3);
25 |
26 | PHP_FUNCTION(xdiff_string_diff);
27 | PHP_FUNCTION(xdiff_string_diff_binary);
28 | PHP_FUNCTION(xdiff_string_patch);
29 | PHP_FUNCTION(xdiff_string_patch_binary);
30 | PHP_FUNCTION(xdiff_string_merge3);
31 |
32 | #endif /* PHP_XDIFF_H */
33 |
34 |
35 | /*
36 | * Local variables:
37 | * tab-width: 4
38 | * c-basic-offset: 4
39 | * indent-tabs-mode: t
40 | * End:
41 | */
42 |
--------------------------------------------------------------------------------
/tests/merge3.h:
--------------------------------------------------------------------------------
1 | #ifndef PHP_XDIFF_H
2 | #define PHP_XDIFF_H
3 |
4 | extern zend_module_entry xdiff_module_entry;
5 | #define phpext_xdiff_ptr &diff_module_entry
6 |
7 | #ifdef PHP_WIN32
8 | #define PHP_XDIFF_API __declspec(dllexport)
9 | #else
10 | #define PHP_XDIFF_API
11 | #endif
12 |
13 | #ifdef ZTS
14 | #include "TSRM.h"
15 | #endif
16 |
17 | PHP_MINIT_FUNCTION(foo);
18 | PHP_MINFO_FUNCTION(foo);
19 |
20 | PHP_FUNCTION(xdiff_string_diff);
21 | PHP_FUNCTION(xdiff_string_diff_binary);
22 | PHP_FUNCTION(xdiff_string_patch);
23 | PHP_FUNCTION(xdiff_string_patch_binary);
24 | PHP_FUNCTION(xdiff_string_merge3);
25 |
26 | #endif /* PHP_XDIFF_H */
27 |
28 |
29 | /*
30 | * Local variables:
31 | * tab-width: 4
32 | * c-basic-offset: 4
33 | * indent-tabs-mode: t
34 | * End:
35 | */
36 |
--------------------------------------------------------------------------------
/tests/merge4.h:
--------------------------------------------------------------------------------
1 | #ifndef PHP_XDIFF_H
2 | #define PHP_XDIFF_H
3 |
4 | #foo
5 | #define phpext_xdiff_ptr &diff_module_entry
6 |
7 | #ifdef PHP_WIN32
8 | #define PHP_XDIFF_API __declspec(dllexport)
9 | #else
10 | #define PHP_XDIFF_API
11 | #endif
12 |
13 | #ifdef ZTS
14 | #include "TSRM.h"
15 | #endif
16 |
17 | PHP_MINIT_FUNCTION(foo);
18 | PHP_MINFO_FUNCTION(foo);
19 |
20 | PHP_FUNCTION(xdiff_string_diff);
21 | PHP_FUNCTION(xdiff_string_diff_binary);
22 | PHP_FUNCTION(xdiff_string_patch);
23 | PHP_FUNCTION(xdiff_string_patch_binary);
24 | PHP_FUNCTION(xdiff_string_merge3);
25 |
26 | #endif /* PHP_XDIFF_H */
27 |
28 |
29 | /*
30 | * Local variables:
31 | * tab-width: 4
32 | * c-basic-offset: 4
33 | * indent-tabs-mode: t
34 | * End:
35 | */
36 |
--------------------------------------------------------------------------------
/tests/php.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/php.png
--------------------------------------------------------------------------------
/tests/zend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/php/pecl-text-xdiff/21857dbe38d052ff0313e7a97086afa8a2398a12/tests/zend.png
--------------------------------------------------------------------------------
/xdiff.c:
--------------------------------------------------------------------------------
1 | /*
2 | +----------------------------------------------------------------------+
3 | | Copyright (c) The PHP Group |
4 | +----------------------------------------------------------------------+
5 | | This source file is subject to version 3.1 of the PHP license, |
6 | | that is bundled with this package in the file LICENSE, and is |
7 | | available at through the world-wide-web at |
8 | | http://www.php.net/license/3_1.txt. |
9 | | If you did not receive a copy of the PHP license and are unable to |
10 | | obtain it through the world-wide-web, please send a note to |
11 | | license@php.net so we can mail you a copy immediately. |
12 | +----------------------------------------------------------------------+
13 | | Author: Marcin Gibula |
14 | +----------------------------------------------------------------------+
15 |
16 | $Id$
17 | */
18 |
19 | #ifdef HAVE_CONFIG_H
20 | #include "config.h"
21 | #endif
22 |
23 | #include "php.h"
24 | #include "php_ini.h"
25 | #include "ext/standard/info.h"
26 | #include "php_xdiff.h"
27 |
28 | #ifndef ZEND_ARG_INFO_WITH_DEFAULT_VALUE
29 | #define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
30 | ZEND_ARG_INFO(pass_by_ref, name)
31 | #endif
32 | #if PHP_VERSION_ID < 70200
33 | #undef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX
34 | #define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
35 | static const zend_internal_arg_info name[] = { \
36 | { (const char*)(zend_uintptr_t)(required_num_args), ( #class_name ), 0, return_reference, allow_null, 0 },
37 | #endif
38 |
39 | #ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX
40 | #define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
41 | ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null)
42 | #endif
43 |
44 | #ifndef ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE
45 | #define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
46 | ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null)
47 | #endif
48 |
49 | #include "xdiff_arginfo.h"
50 |
51 | #ifdef PHP_WIN32
52 | /* libxdiff is compiled with /Zp1 */
53 | # pragma pack(push, 1)
54 | #endif
55 | #include
56 | #ifdef PHP_WIN32
57 | # pragma pack(pop)
58 | #endif
59 |
60 | /* Not exported by header file */
61 | extern char libxdiff_version[];
62 |
63 | struct string_buffer {
64 | char *ptr;
65 | unsigned long size;
66 | };
67 |
68 | static int load_mm_file(const char *filepath, mmfile_t *dest);
69 | static int load_into_mm_file(const char *buffer, unsigned long size, mmfile_t *dest);
70 | static int append_string(void *ptr, mmbuffer_t *buffer, int array_size);
71 | static int append_stream(void *ptr, mmbuffer_t *buffer, int array_size);
72 | static int init_string(struct string_buffer *string);
73 | static void free_string(struct string_buffer *string);
74 |
75 | static int make_diff(char *filepath1, char *filepath2, xdemitcb_t *output, int context, int minimal);
76 | static int make_diff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output, int context, int minimal);
77 | static int make_bdiff(char *filepath1, char *filepath2, xdemitcb_t *output);
78 | static int make_bdiff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output);
79 | static int make_patch(char *file_path, char *patch_path, xdemitcb_t *output, xdemitcb_t *error, int flags);
80 | static int make_patch_str(char *file, int size1, char *patch, int size2, xdemitcb_t *output, xdemitcb_t *error, int flags);
81 | static int make_bpatch(char *file_path, char *patch_path, xdemitcb_t *output);
82 | static int make_bpatch_str(char *file, int size1, char *patch, int size2, xdemitcb_t *output);
83 | static int make_merge3(char *filepath1, char *filepath2, char *filepath3, xdemitcb_t *output, xdemitcb_t *error);
84 | static int make_merge3_str(char *content1, int size1, char *content2, int size2, char *content3, int size3, xdemitcb_t *output, xdemitcb_t *error);
85 | static int make_rabdiff(char *filepath1, char *filepath2, xdemitcb_t *output);
86 | static int make_rabdiff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output);
87 |
88 | static void *xdiff_malloc(void *foo, unsigned int size)
89 | {
90 | return emalloc(size);
91 | }
92 |
93 | static void xdiff_free(void *foo, void *ptr)
94 | {
95 | if (ptr) {
96 | efree(ptr);
97 | }
98 | }
99 |
100 | static void *xdiff_realloc(void *foo, void *ptr, unsigned int nsize)
101 | {
102 | return erealloc(ptr, nsize);
103 | }
104 |
105 | static memallocator_t allocator = { NULL, xdiff_malloc, xdiff_free, xdiff_realloc };
106 |
107 | /* {{{ xdiff_module_entry
108 | */
109 | zend_module_entry xdiff_module_entry = {
110 | #if ZEND_MODULE_API_NO >= 20010901
111 | STANDARD_MODULE_HEADER,
112 | #endif
113 | "xdiff",
114 | ext_functions,
115 | PHP_MINIT(xdiff),
116 | NULL,
117 | NULL,
118 | NULL,
119 | PHP_MINFO(xdiff),
120 | #if ZEND_MODULE_API_NO >= 20010901
121 | PHP_XDIFF_VERSION,
122 | #endif
123 | STANDARD_MODULE_PROPERTIES
124 | };
125 | /* }}} */
126 |
127 | #ifdef COMPILE_DL_XDIFF
128 | ZEND_GET_MODULE(xdiff)
129 | #endif
130 |
131 | /* {{{ PHP_MINIT_FUNCTION
132 | */
133 | PHP_MINIT_FUNCTION(xdiff)
134 | {
135 | xdl_set_allocator(&allocator);
136 |
137 | REGISTER_LONG_CONSTANT("XDIFF_PATCH_NORMAL", XDL_PATCH_NORMAL, CONST_CS | CONST_PERSISTENT);
138 | REGISTER_LONG_CONSTANT("XDIFF_PATCH_REVERSE", XDL_PATCH_REVERSE, CONST_CS | CONST_PERSISTENT);
139 | REGISTER_LONG_CONSTANT("XDIFF_PATCH_IGNORESPACE", XDL_PATCH_IGNOREBSPACE, CONST_CS | CONST_PERSISTENT);
140 |
141 | return SUCCESS;
142 | }
143 | /* }}} */
144 |
145 | /* {{{ PHP_MINFO_FUNCTION
146 | */
147 | PHP_MINFO_FUNCTION(xdiff)
148 | {
149 | php_info_print_table_start();
150 | php_info_print_table_header(2, "xdiff support", "enabled");
151 | php_info_print_table_row(2, "extension version", PHP_XDIFF_VERSION);
152 | php_info_print_table_row(2, "libxdiff version", libxdiff_version);
153 | php_info_print_table_end();
154 | }
155 | /* }}} */
156 |
157 | /* {{{ proto mixed xdiff_string_diff(string str1, string str2, [int context, [bool minimal]])
158 | */
159 | PHP_FUNCTION(xdiff_string_diff)
160 | {
161 | zend_string *str1, *str2;
162 | int retval;
163 | zend_bool minimal = 0;
164 | zend_long context = 3;
165 | xdemitcb_t output;
166 | struct string_buffer string;
167 |
168 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|lb", &str1, &str2, &context, &minimal) == FAILURE) {
169 | RETURN_FALSE;
170 | }
171 |
172 | RETVAL_FALSE;
173 |
174 | retval = init_string(&string);
175 | if (!retval)
176 | goto out;
177 |
178 | output.priv= &string;
179 | output.outf = append_string;
180 |
181 | make_diff_str(str1->val, str1->len, str2->val, str2->len, &output, context, minimal);
182 | RETVAL_STRINGL(string.ptr, string.size);
183 | free_string(&string);
184 | out:
185 | return;
186 | }
187 | /* }}} */
188 |
189 | /* {{{ proto bool xdiff_file_diff(string file1, string file2, string dest, [int context, [bool minimal]])
190 | */
191 | PHP_FUNCTION(xdiff_file_diff)
192 | {
193 | zend_string *filepath1, *filepath2, *dest;
194 | int retval;
195 | zend_bool minimal = 0;
196 | zend_long context = 3;
197 | xdemitcb_t output;
198 | php_stream *output_stream;
199 |
200 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS|lb", &filepath1, &filepath2, &dest, &context, &minimal) == FAILURE) {
201 | RETURN_FALSE;
202 | }
203 |
204 | RETVAL_FALSE;
205 |
206 | output_stream = php_stream_open_wrapper(dest->val, "wb", REPORT_ERRORS, NULL);
207 | if (!output_stream)
208 | goto out;
209 |
210 | output.priv = output_stream;
211 | output.outf = append_stream;
212 |
213 | retval = make_diff(filepath1->val, filepath2->val, &output, context, minimal);
214 | if (!retval)
215 | goto out_stream_close;
216 |
217 | RETVAL_TRUE;
218 |
219 | out_stream_close:
220 | php_stream_close(output_stream);
221 | out:
222 | return;
223 | }
224 | /* }}} */
225 |
226 | /* {{{ proto mixed xdiff_string_diff_binary(string str1, string str2)
227 | */
228 | PHP_FUNCTION(xdiff_string_bdiff)
229 | {
230 | zend_string *str1, *str2;
231 | int retval;
232 | xdemitcb_t output;
233 | struct string_buffer string;
234 |
235 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &str1, &str2) == FAILURE) {
236 | RETURN_FALSE;
237 | }
238 |
239 | RETVAL_FALSE;
240 |
241 | retval = init_string(&string);
242 | if (!retval)
243 | goto out;
244 |
245 | output.priv= &string;
246 | output.outf = append_string;
247 |
248 | make_bdiff_str(str1->val, str1->len, str2->val, str2->len, &output);
249 | RETVAL_STRINGL(string.ptr, string.size);
250 | free_string(&string);
251 |
252 | out:
253 | return;
254 | }
255 | /* }}} */
256 |
257 | /* {{{ proto bool xdiff_file_diff_binary(string file1, string file2, string dest)
258 | */
259 | PHP_FUNCTION(xdiff_file_bdiff)
260 | {
261 | zend_string *filepath1, *filepath2, *result;
262 | int retval;
263 | xdemitcb_t output;
264 | php_stream *output_stream;
265 |
266 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS", &filepath1, &filepath2, &result) == FAILURE) {
267 | RETURN_FALSE;
268 | }
269 |
270 | RETVAL_FALSE;
271 |
272 | output_stream = php_stream_open_wrapper(result->val, "wb", REPORT_ERRORS, NULL);
273 | if (!output_stream)
274 | goto out;
275 |
276 | output.priv = output_stream;
277 | output.outf = append_stream;
278 |
279 | retval = make_bdiff(filepath1->val, filepath2->val, &output);
280 | if (!retval)
281 | goto out_stream_close;
282 |
283 | RETVAL_TRUE;
284 |
285 | out_stream_close:
286 | php_stream_close(output_stream);
287 | out:
288 | return;
289 | }
290 | /* }}} */
291 |
292 | /* {{{ proto mixed xdiff_string_rabdiff(string str1, string str2)
293 | */
294 | PHP_FUNCTION(xdiff_string_rabdiff)
295 | {
296 | zend_string *str1, *str2;
297 | int retval;
298 | xdemitcb_t output;
299 | struct string_buffer string;
300 |
301 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &str1, &str2) == FAILURE) {
302 | RETURN_FALSE;
303 | }
304 |
305 | RETVAL_FALSE;
306 |
307 | retval = init_string(&string);
308 | if (!retval)
309 | goto out;
310 |
311 | output.priv= &string;
312 | output.outf = append_string;
313 |
314 | make_rabdiff_str(str1->val, str1->len, str2->val, str2->len, &output);
315 | RETVAL_STRINGL(string.ptr, string.size);
316 | free_string(&string);
317 |
318 | out:
319 | return;
320 | }
321 | /* }}} */
322 |
323 | /* {{{ proto bool xdiff_file_rabdiff(string file1, string file2, string dest)
324 | */
325 | PHP_FUNCTION(xdiff_file_rabdiff)
326 | {
327 | zend_string *filepath1, *filepath2, *result;
328 | int retval;
329 | xdemitcb_t output;
330 | php_stream *output_stream;
331 |
332 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS", &filepath1, &filepath2, &result) == FAILURE) {
333 | RETURN_FALSE;
334 | }
335 |
336 | RETVAL_FALSE;
337 |
338 | output_stream = php_stream_open_wrapper(result->val, "wb", REPORT_ERRORS, NULL);
339 | if (!output_stream)
340 | goto out;
341 |
342 | output.priv = output_stream;
343 | output.outf = append_stream;
344 |
345 | retval = make_rabdiff(filepath1->val, filepath2->val, &output);
346 | if (!retval)
347 | goto out_stream_close;
348 |
349 | RETVAL_TRUE;
350 |
351 | out_stream_close:
352 | php_stream_close(output_stream);
353 | out:
354 | return;
355 | }
356 | /* }}} */
357 |
358 | /* {{{ proto bool xdiff_file_bdiff_size(string file1, string file2, string dest)
359 | */
360 | PHP_FUNCTION(xdiff_file_bdiff_size)
361 | {
362 | zend_string *filepath;
363 | int retval;
364 | long result;
365 | mmfile_t file;
366 |
367 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &filepath) == FAILURE) {
368 | RETURN_FALSE;
369 | }
370 |
371 | RETVAL_FALSE;
372 |
373 | retval = load_mm_file(filepath->val, &file);
374 | if (!retval)
375 | goto out;
376 |
377 | result = xdl_bdiff_tgsize(&file);
378 | if (result < 0)
379 | goto out_free_mmfile;
380 |
381 | RETVAL_LONG(result);
382 |
383 | out_free_mmfile:
384 | xdl_free_mmfile(&file);
385 | out:
386 | return;
387 | }
388 | /* }}} */
389 |
390 | /* {{{ proto bool xdiff_string_bdiff_size(string file1, string file2, string dest)
391 | */
392 | PHP_FUNCTION(xdiff_string_bdiff_size)
393 | {
394 | zend_string *patch;
395 | int retval;
396 | long result;
397 | mmfile_t file;
398 |
399 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &patch) == FAILURE) {
400 | RETURN_FALSE;
401 | }
402 |
403 | RETVAL_FALSE;
404 |
405 | retval = load_into_mm_file(patch->val, patch->len, &file);
406 | if (!retval)
407 | goto out;
408 |
409 | result = xdl_bdiff_tgsize(&file);
410 | if (result < 0)
411 | goto out_free_mmfile;
412 |
413 | RETVAL_LONG(result);
414 |
415 | out_free_mmfile:
416 | xdl_free_mmfile(&file);
417 | out:
418 | return;
419 | }
420 | /* }}} */
421 |
422 | /* {{{ proto mixed xdiff_file_patch(string file, string patch, string dest [, int flags])
423 | */
424 | PHP_FUNCTION(xdiff_file_patch)
425 | {
426 | php_stream *output_stream;
427 | zend_string *src_path, *patch_path, *dest_path;
428 | int retval;
429 | zend_long flags = XDL_PATCH_NORMAL; /* DIFF_PATCH_NORMAL */
430 | xdemitcb_t output, error_output;
431 | struct string_buffer error_string;
432 |
433 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS|l", &src_path, &patch_path, &dest_path, &flags) == FAILURE) {
434 | RETURN_FALSE;
435 | }
436 |
437 | RETVAL_FALSE;
438 |
439 | output_stream = php_stream_open_wrapper(dest_path->val, "wb", REPORT_ERRORS, NULL);
440 | if (!output_stream)
441 | goto out;
442 |
443 | output.outf = append_stream;
444 | output.priv = output_stream;
445 |
446 | retval = init_string(&error_string);
447 | if (!retval)
448 | goto out_stream_close;
449 |
450 | error_output.priv= &error_string;
451 | error_output.outf = append_string;
452 |
453 | retval = make_patch(src_path->val, patch_path->val, &output, &error_output, flags);
454 | if (!retval)
455 | goto out_free_string;
456 |
457 | if (error_string.size > 0) {
458 | RETVAL_STRINGL(error_string.ptr, error_string.size);
459 | } else {
460 | RETVAL_TRUE;
461 | }
462 |
463 | out_free_string:
464 | free_string(&error_string);
465 | out_stream_close:
466 | php_stream_close(output_stream);
467 | out:
468 | return;
469 | }
470 | /* }}} */
471 |
472 | /* {{{ proto string xdiff_string_patch(string file, string patch [, int flags, [string error]])
473 | */
474 | PHP_FUNCTION(xdiff_string_patch)
475 | {
476 | zval *error_ref = NULL;
477 | zend_string *src, *patch;
478 | int retval;
479 | zend_long flags = XDL_PATCH_NORMAL; /* DIFF_PATCH_NORMAL */
480 | xdemitcb_t output, error_output;
481 | struct string_buffer output_string, error_string;
482 |
483 | if (zend_parse_parameters_ex(0, ZEND_NUM_ARGS(), "SS|lz", &src, &patch, &flags, &error_ref) == FAILURE) {
484 | RETURN_FALSE;
485 | }
486 |
487 | RETVAL_FALSE;
488 |
489 | retval = init_string(&output_string);
490 | if (!retval)
491 | goto out;
492 |
493 | output.priv = &output_string;
494 | output.outf = append_string;
495 |
496 | retval = init_string(&error_string);
497 | if (!retval)
498 | goto out_free_output_string;
499 |
500 | error_output.priv= &error_string;
501 | error_output.outf = append_string;
502 |
503 | retval = make_patch_str(src->val, src->len, patch->val, patch->len, &output, &error_output, flags);
504 | if (!retval)
505 | goto out_free_error_string;
506 |
507 | if (error_string.size > 0 && error_ref) {
508 | ZVAL_DEREF(error_ref);
509 | ZVAL_STRINGL(error_ref, error_string.ptr, error_string.size);
510 | }
511 |
512 | if (output_string.size > 0) {
513 | RETVAL_STRINGL(output_string.ptr, output_string.size);
514 | } else {
515 | RETVAL_EMPTY_STRING();
516 | }
517 |
518 | out_free_error_string:
519 | free_string(&error_string);
520 | out_free_output_string:
521 | free_string(&output_string);
522 | out:
523 | return;
524 | }
525 | /* }}} */
526 |
527 | /* {{{ proto bool xdiff_file_patch_binary(string file, string patch, string dest)
528 | */
529 | PHP_FUNCTION(xdiff_file_bpatch)
530 | {
531 | php_stream *output_stream;
532 | zend_string *src_path, *patch_path, *dest_path;
533 | int retval;
534 | xdemitcb_t output;
535 |
536 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS", &src_path, &patch_path, &dest_path) == FAILURE) {
537 | RETURN_FALSE;
538 | }
539 |
540 | RETVAL_FALSE;
541 |
542 | output_stream = php_stream_open_wrapper(dest_path->val, "wb", REPORT_ERRORS, NULL);
543 | if (!output_stream)
544 | goto out;
545 |
546 | output.outf = append_stream;
547 | output.priv = output_stream;
548 |
549 | retval = make_bpatch(src_path->val, patch_path->val, &output);
550 | php_stream_close(output_stream);
551 |
552 | if (retval == 0)
553 | RETVAL_TRUE;
554 |
555 | out:
556 | return;
557 | }
558 | /* }}} */
559 |
560 | /* {{{ proto string xdiff_string_patch_binary(string str, string patch)
561 | */
562 | PHP_FUNCTION(xdiff_string_bpatch)
563 | {
564 | zend_string *src, *patch;
565 | int retval;
566 | xdemitcb_t output;
567 | struct string_buffer output_string;
568 |
569 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &src, &patch) == FAILURE) {
570 | RETURN_FALSE;
571 | }
572 |
573 | RETVAL_FALSE;
574 |
575 | retval = init_string(&output_string);
576 | if (!retval)
577 | goto out;
578 |
579 | output.priv = &output_string;
580 | output.outf = append_string;
581 |
582 | retval = make_bpatch_str(src->val, src->len, patch->val, patch->len, &output);
583 | if (!retval)
584 | goto out_free_string;
585 |
586 | RETVAL_STRINGL(output_string.ptr, output_string.size);
587 |
588 | out_free_string:
589 | free_string(&output_string);
590 | out:
591 | return;
592 | }
593 | /* }}} */
594 |
595 | /* {{{ proto mixed xdiff_file_merge3(string file1, string file2, string file3, string dest)
596 | */
597 | PHP_FUNCTION(xdiff_file_merge3)
598 | {
599 | zend_string *file1, *file2, *file3, *dest;
600 | php_stream *output_stream;
601 | struct string_buffer string;
602 | xdemitcb_t output, error_output;
603 | int retval;
604 |
605 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSSS", &file1, &file2, &file3, &dest) == FAILURE) {
606 | RETURN_FALSE;
607 | }
608 |
609 | RETVAL_FALSE;
610 |
611 | output_stream = php_stream_open_wrapper(dest->val, "wb", REPORT_ERRORS, NULL);
612 | if (!output_stream)
613 | goto out;
614 |
615 | output.priv = output_stream;
616 | output.outf = append_stream;
617 |
618 | retval = init_string(&string);
619 | if (!retval)
620 | goto out_stream_close;
621 |
622 | error_output.priv = &string;
623 | error_output.outf = append_string;
624 |
625 | retval = make_merge3(file1->val, file2->val, file3->val, &output, &error_output);
626 | if (!retval)
627 | goto out_free_string;
628 |
629 | if (string.size > 0) {
630 | RETVAL_STRINGL(string.ptr, string.size);
631 | } else {
632 | RETVAL_TRUE;
633 | }
634 |
635 | out_free_string:
636 | free_string(&string);
637 | out_stream_close:
638 | php_stream_close(output_stream);
639 | out:
640 | return;
641 | }
642 | /* }}} */
643 |
644 | /* {{{ proto string xdiff_string_merge3(string str1, string str2, string str3 [, string error])
645 | */
646 | PHP_FUNCTION(xdiff_string_merge3)
647 | {
648 | zval *error_ref = NULL;
649 | zend_string *file1, *file2, *file3;
650 | struct string_buffer output_string, error_string;
651 | xdemitcb_t output, error_output;
652 | int retval;
653 |
654 | if (zend_parse_parameters_ex(0, ZEND_NUM_ARGS(), "SSS|z", &file1, &file2, &file3, &error_ref) == FAILURE) {
655 | RETURN_FALSE;
656 | }
657 |
658 | RETVAL_FALSE;
659 |
660 | retval = init_string(&output_string);
661 | if (!retval)
662 | goto out;
663 |
664 | output.priv = &output_string;
665 | output.outf = append_string;
666 |
667 | retval = init_string(&error_string);
668 | if (!retval)
669 | goto out_free_output_string;
670 |
671 | error_output.priv = &error_string;
672 | error_output.outf = append_string;
673 |
674 | retval = make_merge3_str(file1->val, file1->len, file2->val, file2->len, file3->val, file3->len, &output, &error_output);
675 | if (!retval)
676 | goto out_free_error_string;
677 |
678 | if (error_string.size > 0 && error_ref) {
679 | ZVAL_DEREF(error_ref);
680 | ZVAL_STRINGL(error_ref, error_string.ptr, error_string.size);
681 | }
682 |
683 | if (output_string.size > 0) {
684 | RETVAL_STRINGL(output_string.ptr, output_string.size);
685 | } else {
686 | RETVAL_TRUE;
687 | }
688 |
689 | out_free_error_string:
690 | free_string(&error_string);
691 | out_free_output_string:
692 | free_string(&output_string);
693 | out:
694 | return;
695 | }
696 | /* }}} */
697 |
698 | static int load_mm_file(const char *filepath, mmfile_t *dest)
699 | {
700 | int retval;
701 | off_t filesize;
702 | void *ptr;
703 | php_stream *src;
704 | php_stream_statbuf stat;
705 |
706 | src = php_stream_open_wrapper((char *) filepath, "rb", REPORT_ERRORS, NULL);
707 | if (!src)
708 | goto out;
709 |
710 | retval = php_stream_stat(src, &stat);
711 | if (retval < 0)
712 | goto out_stream_close;
713 |
714 | filesize = stat.sb.st_size;
715 |
716 | retval = xdl_init_mmfile(dest, filesize, XDL_MMF_ATOMIC);
717 | if (retval < 0)
718 | goto out_stream_close;
719 |
720 | ptr = xdl_mmfile_writeallocate(dest, (long) filesize);
721 | if (!ptr)
722 | goto out_free_mmfile;
723 |
724 | php_stream_read(src, ptr, filesize);
725 | php_stream_close(src);
726 |
727 | return 1;
728 |
729 | out_free_mmfile:
730 | xdl_free_mmfile(dest);
731 | out_stream_close:
732 | php_stream_close(src);
733 | out:
734 | return 0;
735 | }
736 |
737 | static int load_into_mm_file(const char *buffer, unsigned long size, mmfile_t *dest)
738 | {
739 | int retval;
740 | void *ptr;
741 |
742 | retval = xdl_init_mmfile(dest, size, XDL_MMF_ATOMIC);
743 | if (retval < 0)
744 | goto out;
745 |
746 | ptr = xdl_mmfile_writeallocate(dest, (long) size);
747 | if (!ptr)
748 | goto out_free_mmfile;
749 |
750 | memcpy(ptr, buffer, size);
751 | return 1;
752 |
753 | out_free_mmfile:
754 | xdl_free_mmfile(dest);
755 | out:
756 | return 0;
757 | }
758 |
759 | static int append_string(void *ptr, mmbuffer_t *buffer, int array_size)
760 | {
761 | struct string_buffer *string = ptr;
762 | void *new_ptr;
763 | unsigned int i;
764 |
765 | for (i = 0; i < array_size; i++) {
766 | new_ptr = erealloc(string->ptr, string->size + buffer[i].size + 1);
767 | if (!new_ptr) {
768 | efree(string->ptr);
769 | return -1;
770 | }
771 |
772 | string->ptr = new_ptr;
773 | memcpy(string->ptr + string->size, buffer[i].ptr, buffer[i].size);
774 | string->size += buffer[i].size;
775 | }
776 | if (array_size) {
777 | string->ptr[string->size] = '\0';
778 | }
779 |
780 | return 0;
781 | }
782 |
783 | static int append_stream(void *ptr, mmbuffer_t *buffer, int array_size)
784 | {
785 | php_stream *stream = ptr;
786 | unsigned int i;
787 |
788 | for (i = 0; i < array_size; i++) {
789 | php_stream_write(stream, buffer[i].ptr, buffer[i].size);
790 | }
791 |
792 | return 1;
793 | }
794 |
795 | static int init_string(struct string_buffer *string)
796 | {
797 | string->ptr = emalloc(1);
798 | if (!string->ptr)
799 | return 0;
800 |
801 | string->size = 0;
802 | memset(string->ptr, 0, 1);
803 |
804 | return 1;
805 | }
806 |
807 | static void free_string(struct string_buffer *string)
808 | {
809 | if (string->ptr)
810 | efree(string->ptr);
811 | }
812 |
813 | static int make_diff(char *filepath1, char *filepath2, xdemitcb_t *output, int context, int minimal)
814 | {
815 | mmfile_t file1, file2;
816 | xpparam_t params;
817 | xdemitconf_t conf;
818 | int retval, result = 0;
819 |
820 | retval = load_mm_file(filepath1, &file1);
821 | if (!retval)
822 | goto out;
823 |
824 | retval = load_mm_file(filepath2, &file2);
825 | if (!retval)
826 | goto out_free_mmfile;
827 |
828 | params.flags = (minimal) ? XDF_NEED_MINIMAL : 0;
829 | conf.ctxlen = abs(context);
830 |
831 | retval = xdl_diff(&file1, &file2, ¶ms, &conf, output);
832 | if (retval < 0)
833 | goto out_free_mmfile2;
834 |
835 | result = 1;
836 |
837 | out_free_mmfile2:
838 | xdl_free_mmfile(&file2);
839 | out_free_mmfile:
840 | xdl_free_mmfile(&file1);
841 | out:
842 | return result;
843 | }
844 |
845 | static int make_diff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output, int context, int minimal)
846 | {
847 | mmfile_t file1, file2;
848 | xpparam_t params;
849 | xdemitconf_t conf;
850 | int retval, result = 0;
851 |
852 | retval = load_into_mm_file(str1, size1, &file1);
853 | if (!retval)
854 | goto out;
855 |
856 | retval = load_into_mm_file(str2, size2, &file2);
857 | if (!retval)
858 | goto out_free_mmfile;
859 |
860 | params.flags = (minimal) ? XDF_NEED_MINIMAL : 0;
861 | conf.ctxlen = abs(context);
862 |
863 | retval = xdl_diff(&file1, &file2, ¶ms, &conf, output);
864 | if (retval < 0)
865 | goto out_free_mmfile2;
866 |
867 | result = 1;
868 |
869 | out_free_mmfile2:
870 | xdl_free_mmfile(&file2);
871 | out_free_mmfile:
872 | xdl_free_mmfile(&file1);
873 | out:
874 | return result;
875 | }
876 |
877 | static int make_bdiff(char *filepath1, char *filepath2, xdemitcb_t *output)
878 | {
879 | mmfile_t file1, file2;
880 | bdiffparam_t params;
881 | int retval, result = 0;
882 |
883 | retval = load_mm_file(filepath1, &file1);
884 | if (!retval)
885 | goto out;
886 |
887 | retval = load_mm_file(filepath2, &file2);
888 | if (!retval)
889 | goto out_free_mmfile;
890 |
891 | params.bsize = 16;
892 |
893 | retval = xdl_bdiff(&file1, &file2, ¶ms, output);
894 | if (retval < 0)
895 | goto out_free_mmfile2;
896 |
897 | result = 1;
898 |
899 | out_free_mmfile2:
900 | xdl_free_mmfile(&file2);
901 | out_free_mmfile:
902 | xdl_free_mmfile(&file1);
903 | out:
904 | return result;
905 | }
906 |
907 | static int make_bdiff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output)
908 | {
909 | mmfile_t file1, file2;
910 | bdiffparam_t params;
911 | int retval, result = 0;
912 |
913 | retval = load_into_mm_file(str1, size1, &file1);
914 | if (!retval)
915 | goto out;
916 |
917 | retval = load_into_mm_file(str2, size2, &file2);
918 | if (!retval)
919 | goto out_free_mmfile;
920 |
921 | params.bsize = 16;
922 |
923 | retval = xdl_bdiff(&file1, &file2, ¶ms, output);
924 | if (retval < 0)
925 | goto out_free_mmfile2;
926 |
927 | result = 1;
928 |
929 | out_free_mmfile2:
930 | xdl_free_mmfile(&file2);
931 | out_free_mmfile:
932 | xdl_free_mmfile(&file1);
933 | out:
934 | return result;
935 | }
936 |
937 | static int make_rabdiff(char *filepath1, char *filepath2, xdemitcb_t *output)
938 | {
939 | mmfile_t file1, file2;
940 | int retval, result = 0;
941 |
942 | retval = load_mm_file(filepath1, &file1);
943 | if (!retval)
944 | goto out;
945 |
946 | retval = load_mm_file(filepath2, &file2);
947 | if (!retval)
948 | goto out_free_mmfile;
949 |
950 | retval = xdl_rabdiff(&file1, &file2, output);
951 | if (retval < 0)
952 | goto out_free_mmfile2;
953 |
954 | result = 1;
955 |
956 | out_free_mmfile2:
957 | xdl_free_mmfile(&file2);
958 | out_free_mmfile:
959 | xdl_free_mmfile(&file1);
960 | out:
961 | return result;
962 | }
963 |
964 | static int make_rabdiff_str(char *str1, int size1, char *str2, int size2, xdemitcb_t *output)
965 | {
966 | mmfile_t file1, file2;
967 | int retval, result = 0;
968 |
969 | retval = load_into_mm_file(str1, size1, &file1);
970 | if (!retval)
971 | goto out;
972 |
973 | retval = load_into_mm_file(str2, size2, &file2);
974 | if (!retval)
975 | goto out_free_mmfile;
976 |
977 | retval = xdl_rabdiff(&file1, &file2, output);
978 | if (retval < 0)
979 | goto out_free_mmfile2;
980 |
981 | result = 1;
982 |
983 | out_free_mmfile2:
984 | xdl_free_mmfile(&file2);
985 | out_free_mmfile:
986 | xdl_free_mmfile(&file1);
987 | out:
988 | return result;
989 | }
990 |
991 | static int make_patch(char *file_path, char *patch_path, xdemitcb_t *output, xdemitcb_t *error, int flags)
992 | {
993 | mmfile_t file, patch;
994 | int retval, result = 0;
995 |
996 | retval = load_mm_file(file_path, &file);
997 | if (!retval)
998 | goto out;
999 |
1000 | retval = load_mm_file(patch_path, &patch);
1001 | if (!retval)
1002 | goto out_free_mmfile;
1003 |
1004 | retval = xdl_patch(&file, &patch, flags, output, error);
1005 | if (retval < 0)
1006 | goto out_free_mmfile2;
1007 |
1008 | result = 1;
1009 |
1010 | out_free_mmfile2:
1011 | xdl_free_mmfile(&patch);
1012 | out_free_mmfile:
1013 | xdl_free_mmfile(&file);
1014 | out:
1015 | return result;
1016 | }
1017 |
1018 | static int make_patch_str(char *file, int size1, char *patch, int size2, xdemitcb_t *output, xdemitcb_t *error, int flags)
1019 | {
1020 | mmfile_t file_mm, patch_mm;
1021 | int retval, result = 0;
1022 |
1023 | retval = load_into_mm_file(file, size1, &file_mm);
1024 | if (!retval)
1025 | goto out;
1026 |
1027 | retval = load_into_mm_file(patch, size2, &patch_mm);
1028 | if (!retval)
1029 | goto out_free_mmfile;
1030 |
1031 | retval = xdl_patch(&file_mm, &patch_mm, flags, output, error);
1032 | if (retval < 0)
1033 | goto out_free_mmfile2;
1034 |
1035 | result = 1;
1036 |
1037 | out_free_mmfile2:
1038 | xdl_free_mmfile(&patch_mm);
1039 | out_free_mmfile:
1040 | xdl_free_mmfile(&file_mm);
1041 | out:
1042 | return result;
1043 | }
1044 |
1045 | static int make_bpatch(char *file_path, char *patch_path, xdemitcb_t *output)
1046 | {
1047 | mmfile_t file_mm, patch_mm;
1048 | int retval, result = 0;
1049 |
1050 | retval = load_mm_file(file_path, &file_mm);
1051 | if (!retval)
1052 | goto out;
1053 |
1054 | retval = load_mm_file(patch_path, &patch_mm);
1055 | if (!retval)
1056 | goto out_free_mmfile;
1057 |
1058 | retval = xdl_bpatch(&file_mm, &patch_mm, output);
1059 | if (retval < 0)
1060 | goto out_free_mmfile2;
1061 |
1062 | result = 1;
1063 |
1064 | out_free_mmfile2:
1065 | xdl_free_mmfile(&patch_mm);
1066 | out_free_mmfile:
1067 | xdl_free_mmfile(&file_mm);
1068 | out:
1069 | return result;
1070 | }
1071 |
1072 | static int make_bpatch_str(char *file, int size1, char *patch, int size2, xdemitcb_t *output)
1073 | {
1074 | mmfile_t file_mm, patch_mm;
1075 | int retval, result = 0;
1076 |
1077 | retval = load_into_mm_file(file, size1, &file_mm);
1078 | if (!retval)
1079 | goto out;
1080 |
1081 | retval = load_into_mm_file(patch, size2, &patch_mm);
1082 | if (!retval)
1083 | goto out_free_mmfile;
1084 |
1085 | retval = xdl_bpatch(&file_mm, &patch_mm, output);
1086 | if (retval < 0)
1087 | goto out_free_mmfile2;
1088 |
1089 | result = 1;
1090 |
1091 | out_free_mmfile2:
1092 | xdl_free_mmfile(&patch_mm);
1093 | out_free_mmfile:
1094 | xdl_free_mmfile(&file_mm);
1095 | out:
1096 | return result;
1097 | }
1098 |
1099 | static int make_merge3(char *filepath1, char *filepath2, char *filepath3, xdemitcb_t *output, xdemitcb_t *error)
1100 | {
1101 | mmfile_t file1, file2, file3;
1102 | int retval, result = 0;
1103 |
1104 | retval = load_mm_file(filepath1, &file1);
1105 | if (!retval)
1106 | goto out;
1107 |
1108 | retval = load_mm_file(filepath2, &file2);
1109 | if (!retval)
1110 | goto out_free_mmfile;
1111 |
1112 | retval = load_mm_file(filepath3, &file3);
1113 | if (!retval)
1114 | goto out_free_mmfile2;
1115 |
1116 | retval = xdl_merge3(&file1, &file2, &file3, output, error);
1117 | if (retval < 0)
1118 | goto out_free_mmfile3;
1119 |
1120 | result = 1;
1121 |
1122 | out_free_mmfile3:
1123 | xdl_free_mmfile(&file3);
1124 | out_free_mmfile2:
1125 | xdl_free_mmfile(&file2);
1126 | out_free_mmfile:
1127 | xdl_free_mmfile(&file1);
1128 | out:
1129 | return result;
1130 | }
1131 |
1132 | static int make_merge3_str(char *content1, int size1, char *content2, int size2, char *content3, int size3, xdemitcb_t *output, xdemitcb_t *error)
1133 | {
1134 | mmfile_t file1, file2, file3;
1135 | int retval, result = 0;
1136 |
1137 | retval = load_into_mm_file(content1, size1, &file1);
1138 | if (!retval)
1139 | goto out;
1140 |
1141 | retval = load_into_mm_file(content2, size2, &file2);
1142 | if (!retval)
1143 | goto out_free_mmfile;
1144 |
1145 | retval = load_into_mm_file(content3, size3, &file3);
1146 | if (!retval)
1147 | goto out_free_mmfile2;
1148 |
1149 | retval = xdl_merge3(&file1, &file2, &file3, output, error);
1150 | if (retval < 0)
1151 | goto out_free_mmfile3;
1152 |
1153 | result = 1;
1154 |
1155 | out_free_mmfile3:
1156 | xdl_free_mmfile(&file3);
1157 | out_free_mmfile2:
1158 | xdl_free_mmfile(&file2);
1159 | out_free_mmfile:
1160 | xdl_free_mmfile(&file1);
1161 | out:
1162 | return result;
1163 | }
1164 |
1165 | /*
1166 | * Local variables:
1167 | * tab-width: 4
1168 | * c-basic-offset: 4
1169 | * End:
1170 | * vim600: noet sw=4 ts=4 fdm=marker
1171 | * vim<600: noet sw=4 ts=4
1172 | */
1173 |
--------------------------------------------------------------------------------
/xdiff.stub.php:
--------------------------------------------------------------------------------
1 |