inital commit
This commit is contained in:
444
webroot/forum/inc/3rdparty/diff/Diff/Engine/Native.php
vendored
Normal file
444
webroot/forum/inc/3rdparty/diff/Diff/Engine/Native.php
vendored
Normal file
@@ -0,0 +1,444 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Horde_Text_Diff to actually compute the diffs.
|
||||
*
|
||||
* This class is implemented using native PHP code.
|
||||
*
|
||||
* The algorithm used here is mostly lifted from the perl module
|
||||
* Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
|
||||
* http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
|
||||
*
|
||||
* More ideas are taken from: http://www.ics.uci.edu/~eppstein/161/960229.html
|
||||
*
|
||||
* Some ideas (and a bit of code) are taken from analyze.c, of GNU
|
||||
* diffutils-2.7, which can be found at:
|
||||
* ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
|
||||
*
|
||||
* Some ideas (subdivision by NCHUNKS > 2, and some optimizations) are from
|
||||
* Geoffrey T. Dairiki <dairiki@dairiki.org>. The original PHP version of this
|
||||
* code was written by him, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file LICENSE for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Engine_Native
|
||||
{
|
||||
public function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
|
||||
$n_from = count($from_lines);
|
||||
$n_to = count($to_lines);
|
||||
|
||||
$this->xchanged = $this->ychanged = array();
|
||||
$this->xv = $this->yv = array();
|
||||
$this->xind = $this->yind = array();
|
||||
unset($this->seq);
|
||||
unset($this->in_seq);
|
||||
unset($this->lcs);
|
||||
|
||||
// Skip leading common lines.
|
||||
for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
|
||||
if ($from_lines[$skip] !== $to_lines[$skip]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
|
||||
}
|
||||
|
||||
// Skip trailing common lines.
|
||||
$xi = $n_from; $yi = $n_to;
|
||||
for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
|
||||
if ($from_lines[$xi] !== $to_lines[$yi]) {
|
||||
break;
|
||||
}
|
||||
$this->xchanged[$xi] = $this->ychanged[$yi] = false;
|
||||
}
|
||||
|
||||
// Ignore lines which do not exist in both files.
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$xhash[$from_lines[$xi]] = 1;
|
||||
}
|
||||
for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
|
||||
$line = $to_lines[$yi];
|
||||
if (($this->ychanged[$yi] = empty($xhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$yhash[$line] = 1;
|
||||
$this->yv[] = $line;
|
||||
$this->yind[] = $yi;
|
||||
}
|
||||
for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
|
||||
$line = $from_lines[$xi];
|
||||
if (($this->xchanged[$xi] = empty($yhash[$line]))) {
|
||||
continue;
|
||||
}
|
||||
$this->xv[] = $line;
|
||||
$this->xind[] = $xi;
|
||||
}
|
||||
|
||||
// Find the LCS.
|
||||
$this->_compareseq(0, count($this->xv), 0, count($this->yv));
|
||||
|
||||
// Merge edits when possible.
|
||||
$this->_shiftBoundaries($from_lines, $this->xchanged, $this->ychanged);
|
||||
$this->_shiftBoundaries($to_lines, $this->ychanged, $this->xchanged);
|
||||
|
||||
// Compute the edit operations.
|
||||
$edits = array();
|
||||
$xi = $yi = 0;
|
||||
while ($xi < $n_from || $yi < $n_to) {
|
||||
assert($yi < $n_to || $this->xchanged[$xi]);
|
||||
assert($xi < $n_from || $this->ychanged[$yi]);
|
||||
|
||||
// Skip matching "snake".
|
||||
$copy = array();
|
||||
while ($xi < $n_from && $yi < $n_to
|
||||
&& !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
|
||||
$copy[] = $from_lines[$xi++];
|
||||
++$yi;
|
||||
}
|
||||
if ($copy) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Copy($copy);
|
||||
}
|
||||
|
||||
// Find deletes & adds.
|
||||
$delete = array();
|
||||
while ($xi < $n_from && $this->xchanged[$xi]) {
|
||||
$delete[] = $from_lines[$xi++];
|
||||
}
|
||||
|
||||
$add = array();
|
||||
while ($yi < $n_to && $this->ychanged[$yi]) {
|
||||
$add[] = $to_lines[$yi++];
|
||||
}
|
||||
|
||||
if ($delete && $add) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Change($delete, $add);
|
||||
} elseif ($delete) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Delete($delete);
|
||||
} elseif ($add) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Add($add);
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides the Largest Common Subsequence (LCS) of the sequences (XOFF,
|
||||
* XLIM) and (YOFF, YLIM) into NCHUNKS approximately equally sized
|
||||
* segments.
|
||||
*
|
||||
* Returns (LCS, PTS). LCS is the length of the LCS. PTS is an array of
|
||||
* NCHUNKS+1 (X, Y) indexes giving the diving points between sub
|
||||
* sequences. The first sub-sequence is contained in (X0, X1), (Y0, Y1),
|
||||
* the second in (X1, X2), (Y1, Y2) and so on. Note that (X0, Y0) ==
|
||||
* (XOFF, YOFF) and (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
|
||||
*
|
||||
* This public function assumes that the first lines of the specified portions of
|
||||
* the two files do not match, and likewise that the last lines do not
|
||||
* match. The caller must trim matching lines from the beginning and end
|
||||
* of the portions it is going to specify.
|
||||
*/
|
||||
protected function _diag ($xoff, $xlim, $yoff, $ylim, $nchunks)
|
||||
{
|
||||
$flip = false;
|
||||
|
||||
if ($xlim - $xoff > $ylim - $yoff) {
|
||||
/* Things seems faster (I'm not sure I understand why) when the
|
||||
* shortest sequence is in X. */
|
||||
$flip = true;
|
||||
list ($xoff, $xlim, $yoff, $ylim)
|
||||
= array($yoff, $ylim, $xoff, $xlim);
|
||||
}
|
||||
|
||||
if ($flip) {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->xv[$i]][] = $i;
|
||||
}
|
||||
} else {
|
||||
for ($i = $ylim - 1; $i >= $yoff; $i--) {
|
||||
$ymatches[$this->yv[$i]][] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
$this->lcs = 0;
|
||||
$this->seq[0]= $yoff - 1;
|
||||
$this->in_seq = array();
|
||||
$ymids[0] = array();
|
||||
|
||||
$numer = $xlim - $xoff + $nchunks - 1;
|
||||
$x = $xoff;
|
||||
for ($chunk = 0; $chunk < $nchunks; $chunk++) {
|
||||
if ($chunk > 0) {
|
||||
for ($i = 0; $i <= $this->lcs; $i++) {
|
||||
$ymids[$i][$chunk - 1] = $this->seq[$i];
|
||||
}
|
||||
}
|
||||
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $chunk) / $nchunks);
|
||||
for (; $x < $x1; $x++) {
|
||||
$line = $flip ? $this->yv[$x] : $this->xv[$x];
|
||||
if (empty($ymatches[$line])) {
|
||||
continue;
|
||||
}
|
||||
$matches = $ymatches[$line];
|
||||
reset($matches);
|
||||
while (($y = current($matches)) !== false) {
|
||||
if (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
break;
|
||||
}
|
||||
next($matches);
|
||||
}
|
||||
while (($y = current($matches)) !== false) {
|
||||
if ($y > $this->seq[$k - 1]) {
|
||||
assert($y <= $this->seq[$k]);
|
||||
/* Optimization: this is a common case: next match is
|
||||
* just replacing previous match. */
|
||||
$this->in_seq[$this->seq[$k]] = false;
|
||||
$this->seq[$k] = $y;
|
||||
$this->in_seq[$y] = 1;
|
||||
} elseif (empty($this->in_seq[$y])) {
|
||||
$k = $this->_lcsPos($y);
|
||||
assert($k > 0);
|
||||
$ymids[$k] = $ymids[$k - 1];
|
||||
}
|
||||
next($matches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
|
||||
$ymid = $ymids[$this->lcs];
|
||||
for ($n = 0; $n < $nchunks - 1; $n++) {
|
||||
$x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
|
||||
$y1 = $ymid[$n] + 1;
|
||||
$seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
|
||||
}
|
||||
$seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
|
||||
|
||||
return array($this->lcs, $seps);
|
||||
}
|
||||
|
||||
protected function _lcsPos($ypos)
|
||||
{
|
||||
$end = $this->lcs;
|
||||
if ($end == 0 || $ypos > $this->seq[$end]) {
|
||||
$this->seq[++$this->lcs] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $this->lcs;
|
||||
}
|
||||
|
||||
$beg = 1;
|
||||
while ($beg < $end) {
|
||||
$mid = (int)(($beg + $end) / 2);
|
||||
if ($ypos > $this->seq[$mid]) {
|
||||
$beg = $mid + 1;
|
||||
} else {
|
||||
$end = $mid;
|
||||
}
|
||||
}
|
||||
|
||||
assert($ypos != $this->seq[$end]);
|
||||
|
||||
$this->in_seq[$this->seq[$end]] = false;
|
||||
$this->seq[$end] = $ypos;
|
||||
$this->in_seq[$ypos] = 1;
|
||||
return $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds LCS of two sequences.
|
||||
*
|
||||
* The results are recorded in the vectors $this->{x,y}changed[], by
|
||||
* storing a 1 in the element for each line that is an insertion or
|
||||
* deletion (ie. is not in the LCS).
|
||||
*
|
||||
* The subsequence of file 0 is (XOFF, XLIM) and likewise for file 1.
|
||||
*
|
||||
* Note that XLIM, YLIM are exclusive bounds. All line numbers are
|
||||
* origin-0 and discarded lines are not counted.
|
||||
*/
|
||||
protected function _compareseq ($xoff, $xlim, $yoff, $ylim)
|
||||
{
|
||||
/* Slide down the bottom initial diagonal. */
|
||||
while ($xoff < $xlim && $yoff < $ylim
|
||||
&& $this->xv[$xoff] == $this->yv[$yoff]) {
|
||||
++$xoff;
|
||||
++$yoff;
|
||||
}
|
||||
|
||||
/* Slide up the top initial diagonal. */
|
||||
while ($xlim > $xoff && $ylim > $yoff
|
||||
&& $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
|
||||
--$xlim;
|
||||
--$ylim;
|
||||
}
|
||||
|
||||
if ($xoff == $xlim || $yoff == $ylim) {
|
||||
$lcs = 0;
|
||||
} else {
|
||||
/* This is ad hoc but seems to work well. $nchunks =
|
||||
* sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5); $nchunks =
|
||||
* max(2,min(8,(int)$nchunks)); */
|
||||
$nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
|
||||
list($lcs, $seps)
|
||||
= $this->_diag($xoff, $xlim, $yoff, $ylim, $nchunks);
|
||||
}
|
||||
|
||||
if ($lcs == 0) {
|
||||
/* X and Y sequences have no common subsequence: mark all
|
||||
* changed. */
|
||||
while ($yoff < $ylim) {
|
||||
$this->ychanged[$this->yind[$yoff++]] = 1;
|
||||
}
|
||||
while ($xoff < $xlim) {
|
||||
$this->xchanged[$this->xind[$xoff++]] = 1;
|
||||
}
|
||||
} else {
|
||||
/* Use the partitions to split this problem into subproblems. */
|
||||
reset($seps);
|
||||
$pt1 = $seps[0];
|
||||
while ($pt2 = next($seps)) {
|
||||
$this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
|
||||
$pt1 = $pt2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts inserts/deletes of identical lines to join changes as much as
|
||||
* possible.
|
||||
*
|
||||
* We do something when a run of changed lines include a line at one end
|
||||
* and has an excluded, identical line at the other. We are free to
|
||||
* choose which identical line is included. `compareseq' usually chooses
|
||||
* the one at the beginning, but usually it is cleaner to consider the
|
||||
* following identical line to be the "change".
|
||||
*
|
||||
* This is extracted verbatim from analyze.c (GNU diffutils-2.7).
|
||||
*/
|
||||
protected function _shiftBoundaries($lines, &$changed, $other_changed)
|
||||
{
|
||||
$i = 0;
|
||||
$j = 0;
|
||||
|
||||
assert(count($lines) == count($changed));
|
||||
$len = count($lines);
|
||||
$other_len = count($other_changed);
|
||||
|
||||
while (1) {
|
||||
/* Scan forward to find the beginning of another run of
|
||||
* changes. Also keep track of the corresponding point in the
|
||||
* other file.
|
||||
*
|
||||
* Throughout this code, $i and $j are adjusted together so that
|
||||
* the first $i elements of $changed and the first $j elements of
|
||||
* $other_changed both contain the same number of zeros (unchanged
|
||||
* lines).
|
||||
*
|
||||
* Furthermore, $j is always kept so that $j == $other_len or
|
||||
* $other_changed[$j] == false. */
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $len && ! $changed[$i]) {
|
||||
assert($j < $other_len && ! $other_changed[$j]);
|
||||
$i++; $j++;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($i == $len) {
|
||||
break;
|
||||
}
|
||||
|
||||
$start = $i;
|
||||
|
||||
/* Find the end of this run of changes. */
|
||||
while (++$i < $len && $changed[$i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
/* Record the length of this run of changes, so that we can
|
||||
* later determine whether the run has grown. */
|
||||
$runlength = $i - $start;
|
||||
|
||||
/* Move the changed region back, so long as the previous
|
||||
* unchanged line matches the last changed one. This merges
|
||||
* with previous changed regions. */
|
||||
while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = false;
|
||||
while ($start > 0 && $changed[$start - 1]) {
|
||||
$start--;
|
||||
}
|
||||
assert($j > 0);
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert($j >= 0 && !$other_changed[$j]);
|
||||
}
|
||||
|
||||
/* Set CORRESPONDING to the end of the changed run, at the
|
||||
* last point where it corresponds to a changed run in the
|
||||
* other file. CORRESPONDING == LEN means no such point has
|
||||
* been found. */
|
||||
$corresponding = $j < $other_len ? $i : $len;
|
||||
|
||||
/* Move the changed region forward, so long as the first
|
||||
* changed line matches the following unchanged one. This
|
||||
* merges with following changed regions. Do this second, so
|
||||
* that if there are no merges, the changed region is moved
|
||||
* forward as far as possible. */
|
||||
while ($i < $len && $lines[$start] == $lines[$i]) {
|
||||
$changed[$start++] = false;
|
||||
$changed[$i++] = 1;
|
||||
while ($i < $len && $changed[$i]) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
assert($j < $other_len && ! $other_changed[$j]);
|
||||
$j++;
|
||||
if ($j < $other_len && $other_changed[$j]) {
|
||||
$corresponding = $i;
|
||||
while ($j < $other_len && $other_changed[$j]) {
|
||||
$j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ($runlength != $i - $start);
|
||||
|
||||
/* If possible, move the fully-merged run of changes back to a
|
||||
* corresponding run in the other file. */
|
||||
while ($corresponding < $i) {
|
||||
$changed[--$start] = 1;
|
||||
$changed[--$i] = 0;
|
||||
assert($j > 0);
|
||||
while ($other_changed[--$j]) {
|
||||
continue;
|
||||
}
|
||||
assert($j >= 0 && !$other_changed[$j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
165
webroot/forum/inc/3rdparty/diff/Diff/Engine/Shell.php
vendored
Normal file
165
webroot/forum/inc/3rdparty/diff/Diff/Engine/Shell.php
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the Unix `diff` program via shell_exec to compute the
|
||||
* differences between the two input arrays.
|
||||
*
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Milian Wolff <mail@milianw.de>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Engine_Shell
|
||||
{
|
||||
/**
|
||||
* Path to the diff executable
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_diffCommand = 'diff';
|
||||
|
||||
/**
|
||||
* Returns the array of differences.
|
||||
*
|
||||
* @param array $from_lines lines of text from old file
|
||||
* @param array $to_lines lines of text from new file
|
||||
*
|
||||
* @return array all changes made (array with Horde_Text_Diff_Op_* objects)
|
||||
*/
|
||||
public function diff($from_lines, $to_lines)
|
||||
{
|
||||
array_walk($from_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
|
||||
// Execute gnu diff or similar to get a standard diff file.
|
||||
$from_file = Horde_Util::getTempFile('Horde_Text_Diff');
|
||||
$to_file = Horde_Util::getTempFile('Horde_Text_Diff');
|
||||
$fp = fopen($from_file, 'w');
|
||||
fwrite($fp, implode("\n", $from_lines));
|
||||
fclose($fp);
|
||||
$fp = fopen($to_file, 'w');
|
||||
fwrite($fp, implode("\n", $to_lines));
|
||||
fclose($fp);
|
||||
$diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file);
|
||||
unlink($from_file);
|
||||
unlink($to_file);
|
||||
|
||||
if (is_null($diff)) {
|
||||
// No changes were made
|
||||
return array(new Horde_Text_Diff_Op_Copy($from_lines));
|
||||
}
|
||||
|
||||
$from_line_no = 1;
|
||||
$to_line_no = 1;
|
||||
$edits = array();
|
||||
|
||||
// Get changed lines by parsing something like:
|
||||
// 0a1,2
|
||||
// 1,2c4,6
|
||||
// 1,5d6
|
||||
preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff,
|
||||
$matches, PREG_SET_ORDER);
|
||||
|
||||
foreach ($matches as $match) {
|
||||
if (!isset($match[5])) {
|
||||
// This paren is not set every time (see regex).
|
||||
$match[5] = false;
|
||||
}
|
||||
|
||||
if ($match[3] == 'a') {
|
||||
$from_line_no--;
|
||||
}
|
||||
|
||||
if ($match[3] == 'd') {
|
||||
$to_line_no--;
|
||||
}
|
||||
|
||||
if ($from_line_no < $match[1] || $to_line_no < $match[4]) {
|
||||
// copied lines
|
||||
assert($match[1] - $from_line_no == $match[4] - $to_line_no);
|
||||
$edits[] =
|
||||
new Horde_Text_Diff_Op_Copy(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[1] - 1),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[4] - 1));
|
||||
}
|
||||
|
||||
switch ($match[3]) {
|
||||
case 'd':
|
||||
// deleted lines
|
||||
$edits[] =
|
||||
new Horde_Text_Diff_Op_Delete(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2]));
|
||||
$to_line_no++;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
// changed lines
|
||||
$edits[] =
|
||||
new Horde_Text_Diff_Op_Change(
|
||||
$this->_getLines($from_lines, $from_line_no, $match[2]),
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5]));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
// added lines
|
||||
$edits[] =
|
||||
new Horde_Text_Diff_Op_Add(
|
||||
$this->_getLines($to_lines, $to_line_no, $match[5]));
|
||||
$from_line_no++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($from_lines)) {
|
||||
// Some lines might still be pending. Add them as copied
|
||||
$edits[] =
|
||||
new Horde_Text_Diff_Op_Copy(
|
||||
$this->_getLines($from_lines, $from_line_no,
|
||||
$from_line_no + count($from_lines) - 1),
|
||||
$this->_getLines($to_lines, $to_line_no,
|
||||
$to_line_no + count($to_lines) - 1));
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get lines from either the old or new text
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param array &$text_lines Either $from_lines or $to_lines
|
||||
* @param int &$line_no Current line number
|
||||
* @param int $end Optional end line, when we want to chop more
|
||||
* than one line.
|
||||
*
|
||||
* @return array The chopped lines
|
||||
*/
|
||||
protected function _getLines(&$text_lines, &$line_no, $end = false)
|
||||
{
|
||||
if (!empty($end)) {
|
||||
$lines = array();
|
||||
// We can shift even more
|
||||
while ($line_no <= $end) {
|
||||
$lines[] = array_shift($text_lines);
|
||||
$line_no++;
|
||||
}
|
||||
} else {
|
||||
$lines = array(array_shift($text_lines));
|
||||
$line_no++;
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
}
|
||||
254
webroot/forum/inc/3rdparty/diff/Diff/Engine/String.php
vendored
Normal file
254
webroot/forum/inc/3rdparty/diff/Diff/Engine/String.php
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
/**
|
||||
* Parses unified or context diffs output from eg. the diff utility.
|
||||
*
|
||||
* Example:
|
||||
* <code>
|
||||
* $patch = file_get_contents('example.patch');
|
||||
* $diff = new Horde_Text_Diff('string', array($patch));
|
||||
* $renderer = new Horde_Text_Diff_Renderer_inline();
|
||||
* echo $renderer->render($diff);
|
||||
* </code>
|
||||
*
|
||||
* Copyright 2005 Örjan Persson <o@42mm.org>
|
||||
* Copyright 2005-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Örjan Persson <o@42mm.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Engine_String
|
||||
{
|
||||
/**
|
||||
* Parses a unified or context diff.
|
||||
*
|
||||
* First param contains the whole diff and the second can be used to force
|
||||
* a specific diff type. If the second parameter is 'autodetect', the
|
||||
* diff will be examined to find out which type of diff this is.
|
||||
*
|
||||
* @param string $diff The diff content.
|
||||
* @param string $mode The diff mode of the content in $diff. One of
|
||||
* 'context', 'unified', or 'autodetect'.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
* @throws Horde_Text_Diff_Exception
|
||||
*/
|
||||
public function diff($diff, $mode = 'autodetect')
|
||||
{
|
||||
// Detect line breaks.
|
||||
$lnbr = "\n";
|
||||
if (strpos($diff, "\r\n") !== false) {
|
||||
$lnbr = "\r\n";
|
||||
} elseif (strpos($diff, "\r") !== false) {
|
||||
$lnbr = "\r";
|
||||
}
|
||||
|
||||
// Make sure we have a line break at the EOF.
|
||||
if (substr($diff, -strlen($lnbr)) != $lnbr) {
|
||||
$diff .= $lnbr;
|
||||
}
|
||||
|
||||
if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') {
|
||||
throw new Horde_Text_Diff_Exception('Type of diff is unsupported');
|
||||
}
|
||||
|
||||
if ($mode == 'autodetect') {
|
||||
$context = strpos($diff, '***');
|
||||
$unified = strpos($diff, '---');
|
||||
if ($context === $unified) {
|
||||
throw new Horde_Text_Diff_Exception('Type of diff could not be detected');
|
||||
} elseif ($context === false || $unified === false) {
|
||||
$mode = $context !== false ? 'context' : 'unified';
|
||||
} else {
|
||||
$mode = $context < $unified ? 'context' : 'unified';
|
||||
}
|
||||
}
|
||||
|
||||
// Split by new line and remove the diff header, if there is one.
|
||||
$diff = explode($lnbr, $diff);
|
||||
if (($mode == 'context' && strpos($diff[0], '***') === 0) ||
|
||||
($mode == 'unified' && strpos($diff[0], '---') === 0)) {
|
||||
array_shift($diff);
|
||||
array_shift($diff);
|
||||
}
|
||||
|
||||
if ($mode == 'context') {
|
||||
return $this->parseContextDiff($diff);
|
||||
} else {
|
||||
return $this->parseUnifiedDiff($diff);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the unified diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
public function parseUnifiedDiff($diff)
|
||||
{
|
||||
$edits = array();
|
||||
$end = count($diff) - 1;
|
||||
for ($i = 0; $i < $end;) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case ' ':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == ' ');
|
||||
$edits[] = new Horde_Text_Diff_Op_Copy($diff1);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
// get all new lines
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = new Horde_Text_Diff_Op_Add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
// get changed or removed lines
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 1);
|
||||
} while (++$i < $end && substr($diff[$i], 0, 1) == '-');
|
||||
|
||||
while ($i < $end && substr($diff[$i], 0, 1) == '+') {
|
||||
$diff2[] = substr($diff[$i++], 1);
|
||||
}
|
||||
if (count($diff2) == 0) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Delete($diff1);
|
||||
} else {
|
||||
$edits[] = new Horde_Text_Diff_Op_Change($diff1, $diff2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an array containing the context diff.
|
||||
*
|
||||
* @param array $diff Array of lines.
|
||||
*
|
||||
* @return array List of all diff operations.
|
||||
*/
|
||||
public function parseContextDiff(&$diff)
|
||||
{
|
||||
$edits = array();
|
||||
$i = $max_i = $j = $max_j = 0;
|
||||
$end = count($diff) - 1;
|
||||
while ($i < $end && $j < $end) {
|
||||
while ($i >= $max_i && $j >= $max_j) {
|
||||
// Find the boundaries of the diff output of the two files
|
||||
for ($i = $j;
|
||||
$i < $end && substr($diff[$i], 0, 3) == '***';
|
||||
$i++);
|
||||
for ($max_i = $i;
|
||||
$max_i < $end && substr($diff[$max_i], 0, 3) != '---';
|
||||
$max_i++);
|
||||
for ($j = $max_i;
|
||||
$j < $end && substr($diff[$j], 0, 3) == '---';
|
||||
$j++);
|
||||
for ($max_j = $j;
|
||||
$max_j < $end && substr($diff[$max_j], 0, 3) != '***';
|
||||
$max_j++);
|
||||
}
|
||||
|
||||
// find what hasn't been changed
|
||||
$array = array();
|
||||
while ($i < $max_i &&
|
||||
$j < $max_j &&
|
||||
strcmp($diff[$i], $diff[$j]) == 0) {
|
||||
$array[] = substr($diff[$i], 2);
|
||||
$i++;
|
||||
$j++;
|
||||
}
|
||||
|
||||
while ($i < $max_i && ($max_j-$j) <= 1) {
|
||||
if ($diff[$i] != '' && substr($diff[$i], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$i++], 2);
|
||||
}
|
||||
|
||||
while ($j < $max_j && ($max_i-$i) <= 1) {
|
||||
if ($diff[$j] != '' && substr($diff[$j], 0, 1) != ' ') {
|
||||
break;
|
||||
}
|
||||
$array[] = substr($diff[$j++], 2);
|
||||
}
|
||||
if (count($array) > 0) {
|
||||
$edits[] = new Horde_Text_Diff_Op_Copy($array);
|
||||
}
|
||||
|
||||
if ($i < $max_i) {
|
||||
$diff1 = array();
|
||||
switch (substr($diff[$i], 0, 1)) {
|
||||
case '!':
|
||||
$diff2 = array();
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
if ($j < $max_j && substr($diff[$j], 0, 1) == '!') {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
}
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '!');
|
||||
$edits[] = new Horde_Text_Diff_Op_Change($diff1, $diff2);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '+');
|
||||
$edits[] = new Horde_Text_Diff_Op_Add($diff1);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff1[] = substr($diff[$i], 2);
|
||||
} while (++$i < $max_i && substr($diff[$i], 0, 1) == '-');
|
||||
$edits[] = new Horde_Text_Diff_Op_Delete($diff1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($j < $max_j) {
|
||||
$diff2 = array();
|
||||
switch (substr($diff[$j], 0, 1)) {
|
||||
case '+':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '+');
|
||||
$edits[] = new Horde_Text_Diff_Op_Add($diff2);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
do {
|
||||
$diff2[] = substr($diff[$j++], 2);
|
||||
} while ($j < $max_j && substr($diff[$j], 0, 1) == '-');
|
||||
$edits[] = new Horde_Text_Diff_Op_Delete($diff2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
}
|
||||
74
webroot/forum/inc/3rdparty/diff/Diff/Engine/Xdiff.php
vendored
Normal file
74
webroot/forum/inc/3rdparty/diff/Diff/Engine/Xdiff.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Class used internally by Diff to actually compute the diffs.
|
||||
*
|
||||
* This class uses the xdiff PECL package (http://pecl.php.net/package/xdiff)
|
||||
* to compute the differences between the two input arrays.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Jon Parise <jon@horde.org>
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Engine_Xdiff
|
||||
{
|
||||
/**
|
||||
*/
|
||||
public function diff($from_lines, $to_lines)
|
||||
{
|
||||
if (!extension_loaded('xdiff')) {
|
||||
throw new Horde_Text_Diff_Exception('The xdiff extension is required for this diff engine');
|
||||
}
|
||||
|
||||
array_walk($from_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
array_walk($to_lines, array('Horde_Text_Diff', 'trimNewlines'));
|
||||
|
||||
/* Convert the two input arrays into strings for xdiff processing. */
|
||||
$from_string = implode("\n", $from_lines);
|
||||
$to_string = implode("\n", $to_lines);
|
||||
|
||||
/* Diff the two strings and convert the result to an array. */
|
||||
$diff = xdiff_string_diff($from_string, $to_string, count($to_lines));
|
||||
$diff = explode("\n", $diff);
|
||||
|
||||
/* Walk through the diff one line at a time. We build the $edits
|
||||
* array of diff operations by reading the first character of the
|
||||
* xdiff output (which is in the "unified diff" format).
|
||||
*
|
||||
* Note that we don't have enough information to detect "changed"
|
||||
* lines using this approach, so we can't add Horde_Text_Diff_Op_Changed
|
||||
* instances to the $edits array. The result is still perfectly
|
||||
* valid, albeit a little less descriptive and efficient. */
|
||||
$edits = array();
|
||||
foreach ($diff as $line) {
|
||||
if (!strlen($line)) {
|
||||
continue;
|
||||
}
|
||||
switch ($line[0]) {
|
||||
case ' ':
|
||||
$edits[] = new Horde_Text_Diff_Op_Copy(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '+':
|
||||
$edits[] = new Horde_Text_Diff_Op_Add(array(substr($line, 1)));
|
||||
break;
|
||||
|
||||
case '-':
|
||||
$edits[] = new Horde_Text_Diff_Op_Delete(array(substr($line, 1)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
}
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/Engine/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/Engine/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
24
webroot/forum/inc/3rdparty/diff/Diff/Exception.php
vendored
Normal file
24
webroot/forum/inc/3rdparty/diff/Diff/Exception.php
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Exception handler for the Text_Diff package.
|
||||
*
|
||||
* Copyright 2011-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you
|
||||
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Jan Schneider <jan@horde.org>
|
||||
* @category Horde
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Exception extends Horde_Exception_Wrapped
|
||||
{
|
||||
}
|
||||
68
webroot/forum/inc/3rdparty/diff/Diff/Mapped.php
vendored
Normal file
68
webroot/forum/inc/3rdparty/diff/Diff/Mapped.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @category Horde
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/**
|
||||
* This can be used to compute things like case-insensitve diffs, or diffs
|
||||
* which ignore changes in white-space.
|
||||
*
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* @category Horde
|
||||
* @copyright 2007-2017 Horde LLC
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL-2.1
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Mapped extends Horde_Text_Diff
|
||||
{
|
||||
/**
|
||||
* Computes a diff between sequences of strings.
|
||||
*
|
||||
* @param string $engine Name of the diffing engine to use. 'auto' will
|
||||
* automatically select the best.
|
||||
* @param array $params Parameters to pass to the diffing engine:
|
||||
* - Two arrays, each containing the lines from a
|
||||
* file.
|
||||
* - Two arrays with the same size as the first
|
||||
* parameters. The elements are what is actually
|
||||
* compared when computing the diff.
|
||||
*/
|
||||
public function __construct($engine, $params)
|
||||
{
|
||||
list($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) = $params;
|
||||
assert(count($from_lines) == count($mapped_from_lines));
|
||||
assert(count($to_lines) == count($mapped_to_lines));
|
||||
|
||||
parent::__construct($engine, array($mapped_from_lines, $mapped_to_lines));
|
||||
|
||||
$xi = $yi = 0;
|
||||
for ($i = 0; $i < count($this->_edits); $i++) {
|
||||
$orig = &$this->_edits[$i]->orig;
|
||||
if (is_array($orig)) {
|
||||
$orig = array_slice($from_lines, $xi, count($orig));
|
||||
$xi += count($orig);
|
||||
}
|
||||
|
||||
$final = &$this->_edits[$i]->final;
|
||||
if (is_array($final)) {
|
||||
$final = array_slice($to_lines, $yi, count($final));
|
||||
$yi += count($final);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Add.php
vendored
Normal file
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Add.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Op_Add extends Horde_Text_Diff_Op_Base
|
||||
{
|
||||
public function __construct($lines)
|
||||
{
|
||||
$this->final = $lines;
|
||||
$this->orig = false;
|
||||
}
|
||||
|
||||
public function reverse()
|
||||
{
|
||||
return new Horde_Text_Diff_Op_Delete($this->final);
|
||||
}
|
||||
}
|
||||
38
webroot/forum/inc/3rdparty/diff/Diff/Op/Base.php
vendored
Normal file
38
webroot/forum/inc/3rdparty/diff/Diff/Op/Base.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
abstract class Horde_Text_Diff_Op_Base
|
||||
{
|
||||
public $orig;
|
||||
public $final;
|
||||
|
||||
abstract public function reverse();
|
||||
|
||||
public function norig()
|
||||
{
|
||||
return $this->orig ? count($this->orig) : 0;
|
||||
}
|
||||
|
||||
public function nfinal()
|
||||
{
|
||||
return $this->final ? count($this->final) : 0;
|
||||
}
|
||||
}
|
||||
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Change.php
vendored
Normal file
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Change.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Op_Change extends Horde_Text_Diff_Op_Base
|
||||
{
|
||||
public function __construct($orig, $final)
|
||||
{
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
public function reverse()
|
||||
{
|
||||
return new Horde_Text_Diff_Op_Change($this->final, $this->orig);
|
||||
}
|
||||
}
|
||||
37
webroot/forum/inc/3rdparty/diff/Diff/Op/Copy.php
vendored
Normal file
37
webroot/forum/inc/3rdparty/diff/Diff/Op/Copy.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
/**
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Op_Copy extends Horde_Text_Diff_Op_Base
|
||||
{
|
||||
public function __construct($orig, $final = false)
|
||||
{
|
||||
if (!is_array($final)) {
|
||||
$final = $orig;
|
||||
}
|
||||
$this->orig = $orig;
|
||||
$this->final = $final;
|
||||
}
|
||||
|
||||
public function reverse()
|
||||
{
|
||||
return new Horde_Text_Diff_Op_Copy($this->final, $this->orig);
|
||||
}
|
||||
}
|
||||
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Delete.php
vendored
Normal file
34
webroot/forum/inc/3rdparty/diff/Diff/Op/Delete.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* The original PHP version of this code was written by Geoffrey T. Dairiki
|
||||
* <dairiki@dairiki.org>, and is used/adapted with his permission.
|
||||
*
|
||||
* Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Op_Delete extends Horde_Text_Diff_Op_Base
|
||||
{
|
||||
public function __construct($lines)
|
||||
{
|
||||
$this->orig = $lines;
|
||||
$this->final = false;
|
||||
}
|
||||
|
||||
public function reverse()
|
||||
{
|
||||
return new Horde_Text_Diff_Op_Add($this->orig);
|
||||
}
|
||||
}
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/Op/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/Op/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
241
webroot/forum/inc/3rdparty/diff/Diff/Renderer.php
vendored
Normal file
241
webroot/forum/inc/3rdparty/diff/Diff/Renderer.php
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
<?php
|
||||
/**
|
||||
* A class to render Diffs in different formats.
|
||||
*
|
||||
* This class renders the diff in classic diff format. It is intended that
|
||||
* this class be customized via inheritance, to obtain fancier outputs.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Renderer
|
||||
{
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*
|
||||
* This should be left at zero for this class, but subclasses may want to
|
||||
* set this to other values.
|
||||
*/
|
||||
protected $_leading_context_lines = 0;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*
|
||||
* This should be left at zero for this class, but subclasses may want to
|
||||
* set this to other values.
|
||||
*/
|
||||
protected $_trailing_context_lines = 0;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($params = array())
|
||||
{
|
||||
foreach ($params as $param => $value) {
|
||||
$v = '_' . $param;
|
||||
if (isset($this->$v)) {
|
||||
$this->$v = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any renderer parameters.
|
||||
*
|
||||
* @return array All parameters of this renderer object.
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
$params = array();
|
||||
foreach (get_object_vars($this) as $k => $v) {
|
||||
if ($k[0] == '_') {
|
||||
$params[substr($k, 1)] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a diff.
|
||||
*
|
||||
* @param Horde_Text_Diff $diff A Horde_Text_Diff object.
|
||||
*
|
||||
* @return string The formatted output.
|
||||
*/
|
||||
public function render($diff)
|
||||
{
|
||||
$xi = $yi = 1;
|
||||
$block = false;
|
||||
$context = array();
|
||||
|
||||
$nlead = $this->_leading_context_lines;
|
||||
$ntrail = $this->_trailing_context_lines;
|
||||
|
||||
$output = $this->_startDiff();
|
||||
|
||||
$diffs = $diff->getDiff();
|
||||
foreach ($diffs as $i => $edit) {
|
||||
/* If these are unchanged (copied) lines, and we want to keep
|
||||
* leading or trailing context lines, extract them from the copy
|
||||
* block. */
|
||||
if ($edit instanceof Horde_Text_Diff_Op_Copy) {
|
||||
/* Do we have any diff blocks yet? */
|
||||
if (is_array($block)) {
|
||||
/* How many lines to keep as context from the copy
|
||||
* block. */
|
||||
$keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
|
||||
if (count($edit->orig) <= $keep) {
|
||||
/* We have less lines in the block than we want for
|
||||
* context => keep the whole block. */
|
||||
$block[] = $edit;
|
||||
} else {
|
||||
if ($ntrail) {
|
||||
/* Create a new block with as many lines as we need
|
||||
* for the trailing context. */
|
||||
$context = array_slice($edit->orig, 0, $ntrail);
|
||||
$block[] = new Horde_Text_Diff_Op_Copy($context);
|
||||
}
|
||||
/* @todo */
|
||||
$output .= $this->_block($x0, $ntrail + $xi - $x0,
|
||||
$y0, $ntrail + $yi - $y0,
|
||||
$block);
|
||||
$block = false;
|
||||
}
|
||||
}
|
||||
/* Keep the copy block as the context for the next block. */
|
||||
$context = $edit->orig;
|
||||
} else {
|
||||
/* Don't we have any diff blocks yet? */
|
||||
if (!is_array($block)) {
|
||||
/* Extract context lines from the preceding copy block. */
|
||||
$context = array_slice($context, count($context) - $nlead);
|
||||
$x0 = $xi - count($context);
|
||||
$y0 = $yi - count($context);
|
||||
$block = array();
|
||||
if ($context) {
|
||||
$block[] = new Horde_Text_Diff_Op_Copy($context);
|
||||
}
|
||||
}
|
||||
$block[] = $edit;
|
||||
}
|
||||
|
||||
if ($edit->orig) {
|
||||
$xi += count($edit->orig);
|
||||
}
|
||||
if ($edit->final) {
|
||||
$yi += count($edit->final);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($block)) {
|
||||
$output .= $this->_block($x0, $xi - $x0,
|
||||
$y0, $yi - $y0,
|
||||
$block);
|
||||
}
|
||||
|
||||
return $output . $this->_endDiff();
|
||||
}
|
||||
|
||||
protected function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
|
||||
{
|
||||
$output = $this->_startBlock($this->_blockHeader($xbeg, $xlen, $ybeg, $ylen));
|
||||
|
||||
foreach ($edits as $edit) {
|
||||
switch (get_class($edit)) {
|
||||
case 'Horde_Text_Diff_Op_Copy':
|
||||
$output .= $this->_context($edit->orig);
|
||||
break;
|
||||
|
||||
case 'Horde_Text_Diff_Op_Add':
|
||||
$output .= $this->_added($edit->final);
|
||||
break;
|
||||
|
||||
case 'Horde_Text_Diff_Op_Delete':
|
||||
$output .= $this->_deleted($edit->orig);
|
||||
break;
|
||||
|
||||
case 'Horde_Text_Diff_Op_Change':
|
||||
$output .= $this->_changed($edit->orig, $edit->final);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $output . $this->_endBlock();
|
||||
}
|
||||
|
||||
protected function _startDiff()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function _endDiff()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
if ($xlen > 1) {
|
||||
$xbeg .= ',' . ($xbeg + $xlen - 1);
|
||||
}
|
||||
if ($ylen > 1) {
|
||||
$ybeg .= ',' . ($ybeg + $ylen - 1);
|
||||
}
|
||||
|
||||
// this matches the GNU Diff behaviour
|
||||
if ($xlen && !$ylen) {
|
||||
$ybeg--;
|
||||
} elseif (!$xlen) {
|
||||
$xbeg--;
|
||||
}
|
||||
|
||||
return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
|
||||
}
|
||||
|
||||
protected function _startBlock($header)
|
||||
{
|
||||
return $header . "\n";
|
||||
}
|
||||
|
||||
protected function _endBlock()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function _lines($lines, $prefix = ' ')
|
||||
{
|
||||
return $prefix . implode("\n$prefix", $lines) . "\n";
|
||||
}
|
||||
|
||||
protected function _context($lines)
|
||||
{
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
protected function _added($lines)
|
||||
{
|
||||
return $this->_lines($lines, '> ');
|
||||
}
|
||||
|
||||
protected function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '< ');
|
||||
}
|
||||
|
||||
protected function _changed($orig, $final)
|
||||
{
|
||||
return $this->_deleted($orig) . "---\n" . $this->_added($final);
|
||||
}
|
||||
}
|
||||
75
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Context.php
vendored
Normal file
75
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Context.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* "Context" diff renderer.
|
||||
*
|
||||
* This class renders the diff in classic "context diff" format.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Renderer_Context extends Horde_Text_Diff_Renderer
|
||||
{
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*/
|
||||
protected $_leading_context_lines = 4;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*/
|
||||
protected $_trailing_context_lines = 4;
|
||||
|
||||
protected $_second_block = '';
|
||||
|
||||
protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
if ($xlen != 1) {
|
||||
$xbeg .= ',' . $xlen;
|
||||
}
|
||||
if ($ylen != 1) {
|
||||
$ybeg .= ',' . $ylen;
|
||||
}
|
||||
$this->_second_block = "--- $ybeg ----\n";
|
||||
return "***************\n*** $xbeg ****";
|
||||
}
|
||||
|
||||
protected function _endBlock()
|
||||
{
|
||||
return $this->_second_block;
|
||||
}
|
||||
|
||||
protected function _context($lines)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($lines, ' ');
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
protected function _added($lines)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($lines, '+ ');
|
||||
return '';
|
||||
}
|
||||
|
||||
protected function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '- ');
|
||||
}
|
||||
|
||||
protected function _changed($orig, $final)
|
||||
{
|
||||
$this->_second_block .= $this->_lines($final, '! ');
|
||||
return $this->_lines($orig, '! ');
|
||||
}
|
||||
|
||||
}
|
||||
200
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Inline.php
vendored
Normal file
200
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Inline.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* "Inline" diff renderer.
|
||||
*
|
||||
* This class renders diffs in the Wiki-style "inline" format.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Renderer_Inline extends Horde_Text_Diff_Renderer
|
||||
{
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_leading_context_lines = 10000;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_trailing_context_lines = 10000;
|
||||
|
||||
/**
|
||||
* Prefix for inserted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_ins_prefix = '<ins>';
|
||||
|
||||
/**
|
||||
* Suffix for inserted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_ins_suffix = '</ins>';
|
||||
|
||||
/**
|
||||
* Prefix for deleted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_del_prefix = '<del>';
|
||||
|
||||
/**
|
||||
* Suffix for deleted text.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_del_suffix = '</del>';
|
||||
|
||||
/**
|
||||
* Header for each change block.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_block_header = '';
|
||||
|
||||
/**
|
||||
* Whether to split down to character-level.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_split_characters = false;
|
||||
|
||||
/**
|
||||
* What are we currently splitting on? Used to recurse to show word-level
|
||||
* or character-level changes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_split_level = 'lines';
|
||||
|
||||
protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
return $this->_block_header;
|
||||
}
|
||||
|
||||
protected function _startBlock($header)
|
||||
{
|
||||
return $header;
|
||||
}
|
||||
|
||||
protected function _lines($lines, $prefix = ' ', $encode = true)
|
||||
{
|
||||
if ($encode) {
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
}
|
||||
|
||||
if ($this->_split_level == 'lines') {
|
||||
return implode("\n", $lines) . "\n";
|
||||
} else {
|
||||
return implode('', $lines);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _added($lines)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_ins_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_ins_suffix;
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
protected function _deleted($lines, $words = false)
|
||||
{
|
||||
array_walk($lines, array(&$this, '_encode'));
|
||||
$lines[0] = $this->_del_prefix . $lines[0];
|
||||
$lines[count($lines) - 1] .= $this->_del_suffix;
|
||||
return $this->_lines($lines, ' ', false);
|
||||
}
|
||||
|
||||
protected function _changed($orig, $final)
|
||||
{
|
||||
/* If we've already split on characters, just display. */
|
||||
if ($this->_split_level == 'characters') {
|
||||
return $this->_deleted($orig)
|
||||
. $this->_added($final);
|
||||
}
|
||||
|
||||
/* If we've already split on words, just display. */
|
||||
if ($this->_split_level == 'words') {
|
||||
$prefix = '';
|
||||
while ($orig[0] !== false && $final[0] !== false &&
|
||||
substr($orig[0], 0, 1) == ' ' &&
|
||||
substr($final[0], 0, 1) == ' ') {
|
||||
$prefix .= substr($orig[0], 0, 1);
|
||||
$orig[0] = substr($orig[0], 1);
|
||||
$final[0] = substr($final[0], 1);
|
||||
}
|
||||
return $prefix . $this->_deleted($orig) . $this->_added($final);
|
||||
}
|
||||
|
||||
$text1 = implode("\n", $orig);
|
||||
$text2 = implode("\n", $final);
|
||||
|
||||
/* Non-printing newline marker. */
|
||||
$nl = "\0";
|
||||
|
||||
if ($this->_split_characters) {
|
||||
$diff = new Horde_Text_Diff('native',
|
||||
array(preg_split('//u', str_replace("\n", $nl, $text1)),
|
||||
preg_split('//u', str_replace("\n", $nl, $text2))));
|
||||
} else {
|
||||
/* We want to split on word boundaries, but we need to preserve
|
||||
* whitespace as well. Therefore we split on words, but include
|
||||
* all blocks of whitespace in the wordlist. */
|
||||
$diff = new Horde_Text_Diff('native',
|
||||
array($this->_splitOnWords($text1, $nl),
|
||||
$this->_splitOnWords($text2, $nl)));
|
||||
}
|
||||
|
||||
/* Get the diff in inline format. */
|
||||
$renderer = new Horde_Text_Diff_Renderer_inline
|
||||
(array_merge($this->getParams(),
|
||||
array('split_level' => $this->_split_characters ? 'characters' : 'words')));
|
||||
|
||||
/* Run the diff and get the output. */
|
||||
return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
|
||||
}
|
||||
|
||||
protected function _splitOnWords($string, $newlineEscape = "\n")
|
||||
{
|
||||
// Ignore \0; otherwise the while loop will never finish.
|
||||
$string = str_replace("\0", '', $string);
|
||||
|
||||
$words = array();
|
||||
$length = strlen($string);
|
||||
$pos = 0;
|
||||
|
||||
while ($pos < $length) {
|
||||
// Eat a word with any preceding whitespace.
|
||||
$spaces = strspn(substr($string, $pos), " \n");
|
||||
$nextpos = strcspn(substr($string, $pos + $spaces), " \n");
|
||||
$words[] = str_replace("\n", $newlineEscape, substr($string, $pos, $spaces + $nextpos));
|
||||
$pos += $spaces + $nextpos;
|
||||
}
|
||||
|
||||
return $words;
|
||||
}
|
||||
|
||||
protected function _encode(&$string)
|
||||
{
|
||||
$string = htmlspecialchars($string);
|
||||
}
|
||||
}
|
||||
64
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Unified.php
vendored
Normal file
64
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Unified.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* "Unified" diff renderer.
|
||||
*
|
||||
* This class renders the diff in classic "unified diff" format.
|
||||
*
|
||||
* Copyright 2004-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Ciprian Popovici
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Renderer_Unified extends Horde_Text_Diff_Renderer
|
||||
{
|
||||
/**
|
||||
* Number of leading context "lines" to preserve.
|
||||
*/
|
||||
protected $_leading_context_lines = 4;
|
||||
|
||||
/**
|
||||
* Number of trailing context "lines" to preserve.
|
||||
*/
|
||||
protected $_trailing_context_lines = 4;
|
||||
|
||||
protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
if ($xlen != 1) {
|
||||
$xbeg .= ',' . $xlen;
|
||||
}
|
||||
if ($ylen != 1) {
|
||||
$ybeg .= ',' . $ylen;
|
||||
}
|
||||
return "@@ -$xbeg +$ybeg @@";
|
||||
}
|
||||
|
||||
protected function _context($lines)
|
||||
{
|
||||
return $this->_lines($lines, ' ');
|
||||
}
|
||||
|
||||
protected function _added($lines)
|
||||
{
|
||||
return $this->_lines($lines, '+');
|
||||
}
|
||||
|
||||
protected function _deleted($lines)
|
||||
{
|
||||
return $this->_lines($lines, '-');
|
||||
}
|
||||
|
||||
protected function _changed($orig, $final)
|
||||
{
|
||||
return $this->_deleted($orig) . $this->_added($final);
|
||||
}
|
||||
}
|
||||
74
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Unified/Colored.php
vendored
Normal file
74
webroot/forum/inc/3rdparty/diff/Diff/Renderer/Unified/Colored.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Jan Schneider <jan@horde.org>
|
||||
* @category Horde
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
/**
|
||||
* "Unified" diff renderer with output coloring.
|
||||
*
|
||||
* @author Jan Schneider <jan@horde.org>
|
||||
* @category Horde
|
||||
* @copyright 2017 Horde LLC
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL
|
||||
* @package Text_Diff
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_Renderer_Unified_Colored
|
||||
extends Horde_Text_Diff_Renderer_Unified
|
||||
{
|
||||
/**
|
||||
* CLI handler.
|
||||
*
|
||||
* Contrary to the name, it supports color highlighting for HTML too.
|
||||
*
|
||||
* @var Horde_Cli
|
||||
*/
|
||||
protected $_cli;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct($params = array())
|
||||
{
|
||||
if (!isset($params['cli'])) {
|
||||
throw new BadMethodCallException('CLI handler is missing');
|
||||
}
|
||||
parent::__construct($params);
|
||||
$this->_cli = $params['cli'];
|
||||
}
|
||||
|
||||
protected function _blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
{
|
||||
return $this->_cli->color(
|
||||
'lightmagenta', parent::_blockHeader($xbeg, $xlen, $ybeg, $ylen)
|
||||
);
|
||||
}
|
||||
|
||||
protected function _added($lines)
|
||||
{
|
||||
return $this->_cli->color(
|
||||
'lightgreen', parent::_added($lines)
|
||||
);
|
||||
}
|
||||
|
||||
protected function _deleted($lines)
|
||||
{
|
||||
return $this->_cli->color(
|
||||
'lightred', parent::_deleted($lines)
|
||||
);
|
||||
}
|
||||
}
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/Renderer/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/Renderer/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
778
webroot/forum/inc/3rdparty/diff/Diff/String.php
vendored
Normal file
778
webroot/forum/inc/3rdparty/diff/Diff/String.php
vendored
Normal file
@@ -0,0 +1,778 @@
|
||||
<?php
|
||||
/**
|
||||
* The Horde_String:: class provides static methods for charset and locale
|
||||
* safe string manipulation.
|
||||
*
|
||||
* Copyright 2003-2012 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you
|
||||
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @author Jan Schneider <jan@horde.org>
|
||||
* @category Horde
|
||||
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
|
||||
* @package Util
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_String
|
||||
{
|
||||
/**
|
||||
* lower() cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $_lowers = array();
|
||||
|
||||
/**
|
||||
* upper() cache.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static protected $_uppers = array();
|
||||
|
||||
/**
|
||||
* Converts a string from one charset to another.
|
||||
*
|
||||
* Uses the iconv or the mbstring extensions.
|
||||
* The original string is returned if conversion failed or none
|
||||
* of the extensions were available.
|
||||
*
|
||||
* @param mixed $input The data to be converted. If $input is an an
|
||||
* array, the array's values get converted
|
||||
* recursively.
|
||||
* @param string $from The string's current charset.
|
||||
* @param string $to The charset to convert the string to.
|
||||
* @param boolean $force Force conversion?
|
||||
*
|
||||
* @return mixed The converted input data.
|
||||
*/
|
||||
static public function convertCharset($input, $from, $to, $force = false)
|
||||
{
|
||||
/* Don't bother converting numbers. */
|
||||
if (is_numeric($input)) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
/* If the from and to character sets are identical, return now. */
|
||||
if (!$force && $from == $to) {
|
||||
return $input;
|
||||
}
|
||||
$from = self::lower($from);
|
||||
$to = self::lower($to);
|
||||
if (!$force && $from == $to) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
if (is_array($input)) {
|
||||
$tmp = array();
|
||||
reset($input);
|
||||
while (list($key, $val) = each($input)) {
|
||||
$tmp[self::_convertCharset($key, $from, $to)] = self::convertCharset($val, $from, $to, $force);
|
||||
}
|
||||
return $tmp;
|
||||
}
|
||||
|
||||
if (is_object($input)) {
|
||||
// PEAR_Error/Exception objects are almost guaranteed to contain
|
||||
// recursion, which will cause a segfault in PHP. We should never
|
||||
// reach this line, but add a check.
|
||||
if (($input instanceof Exception) ||
|
||||
($input instanceof PEAR_Error)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$input = Horde_Util::cloneObject($input);
|
||||
$vars = get_object_vars($input);
|
||||
while (list($key, $val) = each($vars)) {
|
||||
$input->$key = self::convertCharset($val, $from, $to, $force);
|
||||
}
|
||||
return $input;
|
||||
}
|
||||
|
||||
if (!is_string($input)) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
return self::_convertCharset($input, $from, $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function used to do charset conversion.
|
||||
*
|
||||
* @param string $input See self::convertCharset().
|
||||
* @param string $from See self::convertCharset().
|
||||
* @param string $to See self::convertCharset().
|
||||
*
|
||||
* @return string The converted string.
|
||||
*/
|
||||
static protected function _convertCharset($input, $from, $to)
|
||||
{
|
||||
/* Use utf8_[en|de]code() if possible and if the string isn't too
|
||||
* large (less than 16 MB = 16 * 1024 * 1024 = 16777216 bytes) - these
|
||||
* functions use more memory. */
|
||||
if (Horde_Util::extensionExists('xml') &&
|
||||
((strlen($input) < 16777216) ||
|
||||
!Horde_Util::extensionExists('iconv') ||
|
||||
!Horde_Util::extensionExists('mbstring'))) {
|
||||
if (($to == 'utf-8') &&
|
||||
in_array($from, array('iso-8859-1', 'us-ascii', 'utf-8'))) {
|
||||
return utf8_encode($input);
|
||||
}
|
||||
|
||||
if (($from == 'utf-8') &&
|
||||
in_array($to, array('iso-8859-1', 'us-ascii', 'utf-8'))) {
|
||||
return utf8_decode($input);
|
||||
}
|
||||
}
|
||||
|
||||
/* Try UTF7-IMAP conversions. */
|
||||
if (($from == 'utf7-imap') || ($to == 'utf7-imap')) {
|
||||
try {
|
||||
if ($from == 'utf7-imap') {
|
||||
return self::convertCharset(Horde_Imap_Client_Utf7imap::Utf7ImapToUtf8($input), 'UTF-8', $to);
|
||||
} else {
|
||||
if ($from == 'utf-8') {
|
||||
$conv = $input;
|
||||
} else {
|
||||
$conv = self::convertCharset($input, $from, 'UTF-8');
|
||||
}
|
||||
return Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($conv);
|
||||
}
|
||||
} catch (Horde_Imap_Client_Exception $e) {
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try iconv with transliteration. */
|
||||
if (Horde_Util::extensionExists('iconv')) {
|
||||
unset($php_errormsg);
|
||||
ini_set('track_errors', 1);
|
||||
$out = @iconv($from, $to . '//TRANSLIT', $input);
|
||||
$errmsg = isset($php_errormsg);
|
||||
ini_restore('track_errors');
|
||||
if (!$errmsg) {
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try mbstring. */
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
$out = @mb_convert_encoding($input, $to, self::_mbstringCharset($from));
|
||||
if (!empty($out)) {
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a string lowercase.
|
||||
*
|
||||
* @param string $string The string to be converted.
|
||||
* @param boolean $locale If true the string will be converted based on
|
||||
* a given charset, locale independent else.
|
||||
* @param string $charset If $locale is true, the charset to use when
|
||||
* converting.
|
||||
*
|
||||
* @return string The string with lowercase characters.
|
||||
*/
|
||||
static public function lower($string, $locale = false, $charset = null)
|
||||
{
|
||||
if ($locale) {
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
if (is_null($charset)) {
|
||||
throw new InvalidArgumentException('$charset argument must not be null');
|
||||
}
|
||||
$ret = @mb_strtolower($string, self::_mbstringCharset($charset));
|
||||
if (!empty($ret)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
return strtolower($string);
|
||||
}
|
||||
|
||||
if (!isset(self::$_lowers[$string])) {
|
||||
$language = setlocale(LC_CTYPE, 0);
|
||||
setlocale(LC_CTYPE, 'C');
|
||||
self::$_lowers[$string] = strtolower($string);
|
||||
setlocale(LC_CTYPE, $language);
|
||||
}
|
||||
|
||||
return self::$_lowers[$string];
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a string uppercase.
|
||||
*
|
||||
* @param string $string The string to be converted.
|
||||
* @param boolean $locale If true the string will be converted based on a
|
||||
* given charset, locale independent else.
|
||||
* @param string $charset If $locale is true, the charset to use when
|
||||
* converting. If not provided the current charset.
|
||||
*
|
||||
* @return string The string with uppercase characters.
|
||||
*/
|
||||
static public function upper($string, $locale = false, $charset = null)
|
||||
{
|
||||
if ($locale) {
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
if (is_null($charset)) {
|
||||
throw new InvalidArgumentException('$charset argument must not be null');
|
||||
}
|
||||
$ret = @mb_strtoupper($string, self::_mbstringCharset($charset));
|
||||
if (!empty($ret)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
return strtoupper($string);
|
||||
}
|
||||
|
||||
if (!isset(self::$_uppers[$string])) {
|
||||
$language = setlocale(LC_CTYPE, 0);
|
||||
setlocale(LC_CTYPE, 'C');
|
||||
self::$_uppers[$string] = strtoupper($string);
|
||||
setlocale(LC_CTYPE, $language);
|
||||
}
|
||||
|
||||
return self::$_uppers[$string];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with the first letter capitalized if it is
|
||||
* alphabetic.
|
||||
*
|
||||
* @param string $string The string to be capitalized.
|
||||
* @param boolean $locale If true the string will be converted based on a
|
||||
* given charset, locale independent else.
|
||||
* @param string $charset The charset to use, defaults to current charset.
|
||||
*
|
||||
* @return string The capitalized string.
|
||||
*/
|
||||
static public function ucfirst($string, $locale = false, $charset = null)
|
||||
{
|
||||
if ($locale) {
|
||||
if (is_null($charset)) {
|
||||
throw new InvalidArgumentException('$charset argument must not be null');
|
||||
}
|
||||
$first = self::substr($string, 0, 1, $charset);
|
||||
if (self::isAlpha($first, $charset)) {
|
||||
$string = self::upper($first, true, $charset) . self::substr($string, 1, null, $charset);
|
||||
}
|
||||
} else {
|
||||
$string = self::upper(substr($string, 0, 1), false) . substr($string, 1);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string with the first letter of each word capitalized if it is
|
||||
* alphabetic.
|
||||
*
|
||||
* Sentences are splitted into words at whitestrings.
|
||||
*
|
||||
* @param string $string The string to be capitalized.
|
||||
* @param boolean $locale If true the string will be converted based on a
|
||||
* given charset, locale independent else.
|
||||
* @param string $charset The charset to use, defaults to current charset.
|
||||
*
|
||||
* @return string The capitalized string.
|
||||
*/
|
||||
static public function ucwords($string, $locale = false, $charset = null)
|
||||
{
|
||||
$words = preg_split('/(\s+)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
for ($i = 0, $c = count($words); $i < $c; $i += 2) {
|
||||
$words[$i] = self::ucfirst($words[$i], $locale, $charset);
|
||||
}
|
||||
return implode('', $words);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns part of a string.
|
||||
*
|
||||
* @param string $string The string to be converted.
|
||||
* @param integer $start The part's start position, zero based.
|
||||
* @param integer $length The part's length.
|
||||
* @param string $charset The charset to use when calculating the part's
|
||||
* position and length, defaults to current
|
||||
* charset.
|
||||
*
|
||||
* @return string The string's part.
|
||||
*/
|
||||
static public function substr($string, $start, $length = null,
|
||||
$charset = 'UTF-8')
|
||||
{
|
||||
if (is_null($length)) {
|
||||
$length = self::length($string, $charset) - $start;
|
||||
}
|
||||
|
||||
if ($length == 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/* Try mbstring. */
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
$ret = @mb_substr($string, $start, $length, self::_mbstringCharset($charset));
|
||||
|
||||
/* mb_substr() returns empty string on failure. */
|
||||
if (strlen($ret)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Try iconv. */
|
||||
if (Horde_Util::extensionExists('iconv')) {
|
||||
$ret = @iconv_substr($string, $start, $length, $charset);
|
||||
|
||||
/* iconv_substr() returns false on failure. */
|
||||
if ($ret !== false) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
return substr($string, $start, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the character (not byte) length of a string.
|
||||
*
|
||||
* @param string $string The string to return the length of.
|
||||
* @param string $charset The charset to use when calculating the string's
|
||||
* length.
|
||||
*
|
||||
* @return integer The string's length.
|
||||
*/
|
||||
static public function length($string, $charset = 'UTF-8')
|
||||
{
|
||||
$charset = self::lower($charset);
|
||||
|
||||
if ($charset == 'utf-8' || $charset == 'utf8') {
|
||||
return strlen(utf8_decode($string));
|
||||
}
|
||||
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
$ret = @mb_strlen($string, self::_mbstringCharset($charset));
|
||||
if (!empty($ret)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric position of the first occurrence of $needle
|
||||
* in the $haystack string.
|
||||
*
|
||||
* @param string $haystack The string to search through.
|
||||
* @param string $needle The string to search for.
|
||||
* @param integer $offset Allows to specify which character in haystack
|
||||
* to start searching.
|
||||
* @param string $charset The charset to use when searching for the
|
||||
* $needle string.
|
||||
*
|
||||
* @return integer The position of first occurrence.
|
||||
*/
|
||||
static public function pos($haystack, $needle, $offset = 0,
|
||||
$charset = 'UTF-8')
|
||||
{
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
$track_errors = ini_set('track_errors', 1);
|
||||
$ret = @mb_strpos($haystack, $needle, $offset, self::_mbstringCharset($charset));
|
||||
ini_set('track_errors', $track_errors);
|
||||
if (!isset($php_errormsg)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
return strpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the numeric position of the last occurrence of $needle
|
||||
* in the $haystack string.
|
||||
*
|
||||
* @param string $haystack The string to search through.
|
||||
* @param string $needle The string to search for.
|
||||
* @param integer $offset Allows to specify which character in haystack
|
||||
* to start searching.
|
||||
* @param string $charset The charset to use when searching for the
|
||||
* $needle string.
|
||||
*
|
||||
* @return integer The position of first occurrence.
|
||||
*/
|
||||
static public function rpos($haystack, $needle, $offset = 0,
|
||||
$charset = 'UTF-8')
|
||||
{
|
||||
if (Horde_Util::extensionExists('mbstring')) {
|
||||
$track_errors = ini_set('track_errors', 1);
|
||||
$ret = @mb_strrpos($haystack, $needle, $offset, self::_mbstringCharset($charset));
|
||||
ini_set('track_errors', $track_errors);
|
||||
if (!isset($php_errormsg)) {
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
|
||||
return strrpos($haystack, $needle, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string padded to a certain length with another string.
|
||||
* This method behaves exactly like str_pad() but is multibyte safe.
|
||||
*
|
||||
* @param string $input The string to be padded.
|
||||
* @param integer $length The length of the resulting string.
|
||||
* @param string $pad The string to pad the input string with. Must
|
||||
* be in the same charset like the input string.
|
||||
* @param const $type The padding type. One of STR_PAD_LEFT,
|
||||
* STR_PAD_RIGHT, or STR_PAD_BOTH.
|
||||
* @param string $charset The charset of the input and the padding
|
||||
* strings.
|
||||
*
|
||||
* @return string The padded string.
|
||||
*/
|
||||
static public function pad($input, $length, $pad = ' ',
|
||||
$type = STR_PAD_RIGHT, $charset = 'UTF-8')
|
||||
{
|
||||
$mb_length = self::length($input, $charset);
|
||||
$sb_length = strlen($input);
|
||||
$pad_length = self::length($pad, $charset);
|
||||
|
||||
/* Return if we already have the length. */
|
||||
if ($mb_length >= $length) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
/* Shortcut for single byte strings. */
|
||||
if ($mb_length == $sb_length && $pad_length == strlen($pad)) {
|
||||
return str_pad($input, $length, $pad, $type);
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case STR_PAD_LEFT:
|
||||
$left = $length - $mb_length;
|
||||
$output = self::substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) . $input;
|
||||
break;
|
||||
|
||||
case STR_PAD_BOTH:
|
||||
$left = floor(($length - $mb_length) / 2);
|
||||
$right = ceil(($length - $mb_length) / 2);
|
||||
$output = self::substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) .
|
||||
$input .
|
||||
self::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset);
|
||||
break;
|
||||
|
||||
case STR_PAD_RIGHT:
|
||||
$right = $length - $mb_length;
|
||||
$output = $input . self::substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset);
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the text of a message.
|
||||
*
|
||||
* @param string $string String containing the text to wrap.
|
||||
* @param integer $width Wrap the string at this number of
|
||||
* characters.
|
||||
* @param string $break Character(s) to use when breaking lines.
|
||||
* @param boolean $cut Whether to cut inside words if a line
|
||||
* can't be wrapped.
|
||||
* @param boolean $line_folding Whether to apply line folding rules per
|
||||
* RFC 822 or similar. The correct break
|
||||
* characters including leading whitespace
|
||||
* have to be specified too.
|
||||
*
|
||||
* @return string String containing the wrapped text.
|
||||
*/
|
||||
static public function wordwrap($string, $width = 75, $break = "\n",
|
||||
$cut = false, $line_folding = false)
|
||||
{
|
||||
$wrapped = '';
|
||||
|
||||
while (self::length($string, 'UTF-8') > $width) {
|
||||
$line = self::substr($string, 0, $width, 'UTF-8');
|
||||
$string = self::substr($string, self::length($line, 'UTF-8'), null, 'UTF-8');
|
||||
|
||||
// Make sure we didn't cut a word, unless we want hard breaks
|
||||
// anyway.
|
||||
if (!$cut && preg_match('/^(.+?)((\s|\r?\n).*)/us', $string, $match)) {
|
||||
$line .= $match[1];
|
||||
$string = $match[2];
|
||||
}
|
||||
|
||||
// Wrap at existing line breaks.
|
||||
if (preg_match('/^(.*?)(\r?\n)(.*)$/su', $line, $match)) {
|
||||
$wrapped .= $match[1] . $match[2];
|
||||
$string = $match[3] . $string;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Wrap at the last colon or semicolon followed by a whitespace if
|
||||
// doing line folding.
|
||||
if ($line_folding &&
|
||||
preg_match('/^(.*?)(;|:)(\s+.*)$/u', $line, $match)) {
|
||||
$wrapped .= $match[1] . $match[2] . $break;
|
||||
$string = $match[3] . $string;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Wrap at the last whitespace of $line.
|
||||
$sub = $line_folding
|
||||
? '(.+[^\s])'
|
||||
: '(.*)';
|
||||
|
||||
if (preg_match('/^' . $sub . '(\s+)(.*)$/u', $line, $match)) {
|
||||
$wrapped .= $match[1] . $break;
|
||||
$string = ($line_folding ? $match[2] : '') . $match[3] . $string;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hard wrap if necessary.
|
||||
if ($cut) {
|
||||
$wrapped .= $line . $break;
|
||||
continue;
|
||||
}
|
||||
|
||||
$wrapped .= $line;
|
||||
}
|
||||
|
||||
return $wrapped . $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the text of a message.
|
||||
*
|
||||
* @param string $text String containing the text to wrap.
|
||||
* @param integer $length Wrap $text at this number of characters.
|
||||
* @param string $break_char Character(s) to use when breaking lines.
|
||||
* @param boolean $quote Ignore lines that are wrapped with the '>'
|
||||
* character (RFC 2646)? If true, we don't
|
||||
* remove any padding whitespace at the end of
|
||||
* the string.
|
||||
*
|
||||
* @return string String containing the wrapped text.
|
||||
*/
|
||||
static public function wrap($text, $length = 80, $break_char = "\n",
|
||||
$quote = false)
|
||||
{
|
||||
$paragraphs = array();
|
||||
|
||||
foreach (preg_split('/\r?\n/', $text) as $input) {
|
||||
if ($quote && (strpos($input, '>') === 0)) {
|
||||
$line = $input;
|
||||
} else {
|
||||
/* We need to handle the Usenet-style signature line
|
||||
* separately; since the space after the two dashes is
|
||||
* REQUIRED, we don't want to trim the line. */
|
||||
if ($input != '-- ') {
|
||||
$input = rtrim($input);
|
||||
}
|
||||
$line = self::wordwrap($input, $length, $break_char);
|
||||
}
|
||||
|
||||
$paragraphs[] = $line;
|
||||
}
|
||||
|
||||
return implode($break_char, $paragraphs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a truncated string, suitable for notifications.
|
||||
*
|
||||
* @param string $text The original string.
|
||||
* @param integer $length The maximum length.
|
||||
*
|
||||
* @return string The truncated string, if longer than $length.
|
||||
*/
|
||||
static public function truncate($text, $length = 100)
|
||||
{
|
||||
return (self::length($text) > $length)
|
||||
? rtrim(self::substr($text, 0, $length - 3)) . '...'
|
||||
: $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an abbreviated string, with characters in the middle of the
|
||||
* excessively long string replaced by '...'.
|
||||
*
|
||||
* @param string $text The original string.
|
||||
* @param integer $length The length at which to abbreviate.
|
||||
*
|
||||
* @return string The abbreviated string, if longer than $length.
|
||||
*/
|
||||
static public function abbreviate($text, $length = 20)
|
||||
{
|
||||
return (self::length($text) > $length)
|
||||
? rtrim(self::substr($text, 0, round(($length - 3) / 2))) . '...' . ltrim(self::substr($text, (($length - 3) / 2) * -1))
|
||||
: $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the common leading part of two strings.
|
||||
*
|
||||
* @param string $str1 A string.
|
||||
* @param string $str2 Another string.
|
||||
*
|
||||
* @return string The start of $str1 and $str2 that is identical in both.
|
||||
*/
|
||||
static public function common($str1, $str2)
|
||||
{
|
||||
for ($result = '', $i = 0;
|
||||
isset($str1[$i]) && isset($str2[$i]) && $str1[$i] == $str2[$i];
|
||||
$i++) {
|
||||
$result .= $str1[$i];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the every character in the parameter is an alphabetic
|
||||
* character.
|
||||
*
|
||||
* @param string $string The string to test.
|
||||
* @param string $charset The charset to use when testing the string.
|
||||
*
|
||||
* @return boolean True if the parameter was alphabetic only.
|
||||
*/
|
||||
static public function isAlpha($string, $charset)
|
||||
{
|
||||
if (!Horde_Util::extensionExists('mbstring')) {
|
||||
return ctype_alpha($string);
|
||||
}
|
||||
|
||||
$charset = self::_mbstringCharset($charset);
|
||||
$old_charset = mb_regex_encoding();
|
||||
|
||||
if ($charset != $old_charset) {
|
||||
@mb_regex_encoding($charset);
|
||||
}
|
||||
$alpha = !@mb_ereg_match('[^[:alpha:]]', $string);
|
||||
if ($charset != $old_charset) {
|
||||
@mb_regex_encoding($old_charset);
|
||||
}
|
||||
|
||||
return $alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if ever character in the parameter is a lowercase letter in
|
||||
* the current locale.
|
||||
*
|
||||
* @param string $string The string to test.
|
||||
* @param string $charset The charset to use when testing the string.
|
||||
*
|
||||
* @return boolean True if the parameter was lowercase.
|
||||
*/
|
||||
static public function isLower($string, $charset)
|
||||
{
|
||||
return ((self::lower($string, true, $charset) === $string) &&
|
||||
self::isAlpha($string, $charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if every character in the parameter is an uppercase letter
|
||||
* in the current locale.
|
||||
*
|
||||
* @param string $string The string to test.
|
||||
* @param string $charset The charset to use when testing the string.
|
||||
*
|
||||
* @return boolean True if the parameter was uppercase.
|
||||
*/
|
||||
static public function isUpper($string, $charset)
|
||||
{
|
||||
return ((self::upper($string, true, $charset) === $string) &&
|
||||
self::isAlpha($string, $charset));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a multibyte safe regex match search on the text provided.
|
||||
*
|
||||
* @param string $text The text to search.
|
||||
* @param array $regex The regular expressions to use, without perl
|
||||
* regex delimiters (e.g. '/' or '|').
|
||||
* @param string $charset The character set of the text.
|
||||
*
|
||||
* @return array The matches array from the first regex that matches.
|
||||
*/
|
||||
static public function regexMatch($text, $regex, $charset = null)
|
||||
{
|
||||
if (!empty($charset)) {
|
||||
$regex = self::convertCharset($regex, $charset, 'utf-8');
|
||||
$text = self::convertCharset($text, $charset, 'utf-8');
|
||||
}
|
||||
|
||||
$matches = array();
|
||||
foreach ($regex as $val) {
|
||||
if (preg_match('/' . $val . '/u', $text, $matches)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($charset)) {
|
||||
$matches = self::convertCharset($matches, 'utf-8', $charset);
|
||||
}
|
||||
|
||||
return $matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if a string is valid UTF-8.
|
||||
*
|
||||
* @since 1.1.0
|
||||
*
|
||||
* @param string $text The text to check.
|
||||
*
|
||||
* @return boolean True if valid UTF-8.
|
||||
*/
|
||||
static public function validUtf8($text)
|
||||
{
|
||||
/* Regex from:
|
||||
* http://stackoverflow.com/questions/1523460/ensuring-valid-utf-8-in-php
|
||||
*/
|
||||
return preg_match('/^(?:
|
||||
[\x09\x0A\x0D\x20-\x7E] # ASCII
|
||||
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
|
||||
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
|
||||
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
|
||||
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
|
||||
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
|
||||
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
|
||||
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
|
||||
)*$/xs', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround charsets that don't work with mbstring functions.
|
||||
*
|
||||
* @param string $charset The original charset.
|
||||
*
|
||||
* @return string The charset to use with mbstring functions.
|
||||
*/
|
||||
static protected function _mbstringCharset($charset)
|
||||
{
|
||||
/* mbstring functions do not handle the 'ks_c_5601-1987' &
|
||||
* 'ks_c_5601-1989' charsets. However, these charsets are used, for
|
||||
* example, by various versions of Outlook to send Korean characters.
|
||||
* Use UHC (CP949) encoding instead. See, e.g.,
|
||||
* http://lists.w3.org/Archives/Public/ietf-charsets/2001AprJun/0030.html */
|
||||
if ($charset == 'UTF-8' || $charset == 'utf-8') {
|
||||
return $charset;
|
||||
}
|
||||
if (in_array(self::lower($charset), array('ks_c_5601-1987', 'ks_c_5601-1989'))) {
|
||||
$charset = 'UHC';
|
||||
}
|
||||
|
||||
return $charset;
|
||||
}
|
||||
|
||||
}
|
||||
150
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay.php
vendored
Normal file
150
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay.php
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
/**
|
||||
* A class for computing three way merges.
|
||||
*
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_ThreeWay
|
||||
{
|
||||
/**
|
||||
* Array of changes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_edits;
|
||||
|
||||
/**
|
||||
* Conflict counter.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $_conflictingBlocks = 0;
|
||||
|
||||
/**
|
||||
* Computes diff between 3 sequences of strings.
|
||||
*
|
||||
* @param array $orig The original lines to use.
|
||||
* @param array $final1 The first version to compare to.
|
||||
* @param array $final2 The second version to compare to.
|
||||
*/
|
||||
public function __construct($orig, $final1, $final2)
|
||||
{
|
||||
if (extension_loaded('xdiff')) {
|
||||
$engine = new Horde_Text_Diff_Engine_Xdiff();
|
||||
} else {
|
||||
$engine = new Horde_Text_Diff_Engine_Native();
|
||||
}
|
||||
|
||||
$this->_edits = $this->_diff3($engine->diff($orig, $final1),
|
||||
$engine->diff($orig, $final2));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public function mergedOutput($label1 = false, $label2 = false)
|
||||
{
|
||||
$lines = array();
|
||||
foreach ($this->_edits as $edit) {
|
||||
if ($edit->isConflict()) {
|
||||
/* FIXME: this should probably be moved somewhere else. */
|
||||
$lines = array_merge($lines,
|
||||
array('<<<<<<<' . ($label1 ? ' ' . $label1 : '')),
|
||||
$edit->final1,
|
||||
array("======="),
|
||||
$edit->final2,
|
||||
array('>>>>>>>' . ($label2 ? ' ' . $label2 : '')));
|
||||
$this->_conflictingBlocks++;
|
||||
} else {
|
||||
$lines = array_merge($lines, $edit->merged());
|
||||
}
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
protected function _diff3($edits1, $edits2)
|
||||
{
|
||||
$edits = array();
|
||||
$bb = new Horde_Text_Diff_ThreeWay_BlockBuilder();
|
||||
|
||||
$e1 = current($edits1);
|
||||
$e2 = current($edits2);
|
||||
while ($e1 || $e2) {
|
||||
if ($e1 && $e2 &&
|
||||
$e1 instanceof Horde_Text_Diff_Op_Copy &&
|
||||
$e2 instanceof Horde_Text_Diff_Op_Copy) {
|
||||
/* We have copy blocks from both diffs. This is the (only)
|
||||
* time we want to emit a diff3 copy block. Flush current
|
||||
* diff3 diff block, if any. */
|
||||
if ($edit = $bb->finish()) {
|
||||
$edits[] = $edit;
|
||||
}
|
||||
|
||||
$ncopy = min($e1->norig(), $e2->norig());
|
||||
assert($ncopy > 0);
|
||||
$edits[] = new Horde_Text_Diff_ThreeWay_Op_Copy(array_slice($e1->orig, 0, $ncopy));
|
||||
|
||||
if ($e1->norig() > $ncopy) {
|
||||
array_splice($e1->orig, 0, $ncopy);
|
||||
array_splice($e1->final, 0, $ncopy);
|
||||
} else {
|
||||
$e1 = next($edits1);
|
||||
}
|
||||
|
||||
if ($e2->norig() > $ncopy) {
|
||||
array_splice($e2->orig, 0, $ncopy);
|
||||
array_splice($e2->final, 0, $ncopy);
|
||||
} else {
|
||||
$e2 = next($edits2);
|
||||
}
|
||||
} else {
|
||||
if ($e1 && $e2) {
|
||||
if ($e1->orig && $e2->orig) {
|
||||
$norig = min($e1->norig(), $e2->norig());
|
||||
$orig = array_splice($e1->orig, 0, $norig);
|
||||
array_splice($e2->orig, 0, $norig);
|
||||
$bb->input($orig);
|
||||
}
|
||||
|
||||
if ($e1 instanceof Horde_Text_Diff_Op_Copy) {
|
||||
$bb->out1(array_splice($e1->final, 0, $norig));
|
||||
}
|
||||
|
||||
if ($e2 instanceof Horde_Text_Diff_Op_Copy) {
|
||||
$bb->out2(array_splice($e2->final, 0, $norig));
|
||||
}
|
||||
}
|
||||
|
||||
if ($e1 && ! $e1->orig) {
|
||||
$bb->out1($e1->final);
|
||||
$e1 = next($edits1);
|
||||
}
|
||||
if ($e2 && ! $e2->orig) {
|
||||
$bb->out2($e2->final);
|
||||
$e2 = next($edits2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($edit = $bb->finish()) {
|
||||
$edits[] = $edit;
|
||||
}
|
||||
|
||||
return $edits;
|
||||
}
|
||||
}
|
||||
71
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/BlockBuilder.php
vendored
Normal file
71
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/BlockBuilder.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_ThreeWay_BlockBuilder
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->_init();
|
||||
}
|
||||
|
||||
public function input($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->orig, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
public function out1($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->final1, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
public function out2($lines)
|
||||
{
|
||||
if ($lines) {
|
||||
$this->_append($this->final2, $lines);
|
||||
}
|
||||
}
|
||||
|
||||
public function isEmpty()
|
||||
{
|
||||
return !$this->orig && !$this->final1 && !$this->final2;
|
||||
}
|
||||
|
||||
public function finish()
|
||||
{
|
||||
if ($this->isEmpty()) {
|
||||
return false;
|
||||
} else {
|
||||
$edit = new Horde_Text_Diff_ThreeWay_Op_Base($this->orig, $this->final1, $this->final2);
|
||||
$this->_init();
|
||||
return $edit;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _init()
|
||||
{
|
||||
$this->orig = $this->final1 = $this->final2 = array();
|
||||
}
|
||||
|
||||
protected function _append(&$array, $lines)
|
||||
{
|
||||
array_splice($array, sizeof($array), 0, $lines);
|
||||
}
|
||||
}
|
||||
48
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/Base.php
vendored
Normal file
48
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/Base.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_ThreeWay_Op_Base
|
||||
{
|
||||
public function __construct($orig = false, $final1 = false, $final2 = false)
|
||||
{
|
||||
$this->orig = $orig ? $orig : array();
|
||||
$this->final1 = $final1 ? $final1 : array();
|
||||
$this->final2 = $final2 ? $final2 : array();
|
||||
}
|
||||
|
||||
public function merged()
|
||||
{
|
||||
if (!isset($this->_merged)) {
|
||||
if ($this->final1 === $this->final2) {
|
||||
$this->_merged = &$this->final1;
|
||||
} elseif ($this->final1 === $this->orig) {
|
||||
$this->_merged = &$this->final2;
|
||||
} elseif ($this->final2 === $this->orig) {
|
||||
$this->_merged = &$this->final1;
|
||||
} else {
|
||||
$this->_merged = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_merged;
|
||||
}
|
||||
|
||||
public function isConflict()
|
||||
{
|
||||
return $this->merged() === false;
|
||||
}
|
||||
}
|
||||
36
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/Copy.php
vendored
Normal file
36
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/Copy.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2007-2017 Horde LLC (http://www.horde.org/)
|
||||
*
|
||||
* See the enclosed file COPYING for license information (LGPL). If you did
|
||||
* not receive this file, see http://www.horde.org/licenses/lgpl21.
|
||||
*
|
||||
* @package Text_Diff
|
||||
* @author Geoffrey T. Dairiki <dairiki@dairiki.org>
|
||||
*/
|
||||
|
||||
// Disallow direct access to this file for security reasons
|
||||
if(!defined("IN_MYBB"))
|
||||
{
|
||||
die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
|
||||
}
|
||||
|
||||
class Horde_Text_Diff_ThreeWay_Op_Copy extends Horde_Text_Diff_ThreeWay_Op_Base
|
||||
{
|
||||
public function __construct($lines = false)
|
||||
{
|
||||
$this->orig = $lines ? $lines : array();
|
||||
$this->final1 = &$this->orig;
|
||||
$this->final2 = &$this->orig;
|
||||
}
|
||||
|
||||
public function merged()
|
||||
{
|
||||
return $this->orig;
|
||||
}
|
||||
|
||||
public function isConflict()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/Op/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/ThreeWay/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
8
webroot/forum/inc/3rdparty/diff/Diff/index.html
vendored
Normal file
8
webroot/forum/inc/3rdparty/diff/Diff/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user