X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fsebastian%2Fdiff%2Fsrc%2FDiffer.php;fp=vendor%2Fsebastian%2Fdiff%2Fsrc%2FDiffer.php;h=116c99c4be97301819caca4eae33542811172c08;hp=4960111ed7a791f62a70a71a2e2db5ec427fef75;hb=eba34333e3c89f208d2f72fa91351ad019a71583;hpb=a2bd1bf0c2c1f1a17d188f4dc0726a45494cefae diff --git a/vendor/sebastian/diff/src/Differ.php b/vendor/sebastian/diff/src/Differ.php index 4960111ed..116c99c4b 100644 --- a/vendor/sebastian/diff/src/Differ.php +++ b/vendor/sebastian/diff/src/Differ.php @@ -1,6 +1,6 @@ * @@ -31,6 +31,7 @@ class Differ /** * @param string $header + * @param bool $showNonDiffLines */ public function __construct($header = "--- Original\n+++ New\n", $showNonDiffLines = true) { @@ -49,23 +50,52 @@ class Differ */ public function diff($from, $to, LongestCommonSubsequence $lcs = null) { - if (!is_array($from) && !is_string($from)) { - $from = (string) $from; + $from = $this->validateDiffInput($from); + $to = $this->validateDiffInput($to); + $diff = $this->diffToArray($from, $to, $lcs); + $old = $this->checkIfDiffInOld($diff); + $start = isset($old[0]) ? $old[0] : 0; + $end = \count($diff); + + if ($tmp = \array_search($end, $old)) { + $end = $tmp; } - if (!is_array($to) && !is_string($to)) { - $to = (string) $to; + return $this->getBuffer($diff, $old, $start, $end); + } + + /** + * Casts variable to string if it is not a string or array. + * + * @param mixed $input + * + * @return string + */ + private function validateDiffInput($input) + { + if (!\is_array($input) && !\is_string($input)) { + return (string) $input; } - $buffer = $this->header; - $diff = $this->diffToArray($from, $to, $lcs); + return $input; + } + /** + * Takes input of the diff array and returns the old array. + * Iterates through diff line by line, + * + * @param array $diff + * + * @return array + */ + private function checkIfDiffInOld(array $diff) + { $inOld = false; $i = 0; $old = array(); foreach ($diff as $line) { - if ($line[1] === 0 /* OLD */) { + if ($line[1] === 0 /* OLD */) { if ($inOld === false) { $inOld = $i; } @@ -80,46 +110,85 @@ class Differ ++$i; } - $start = isset($old[0]) ? $old[0] : 0; - $end = count($diff); + return $old; + } - if ($tmp = array_search($end, $old)) { - $end = $tmp; - } + /** + * Generates buffer in string format, returning the patch. + * + * @param array $diff + * @param array $old + * @param int $start + * @param int $end + * + * @return string + */ + private function getBuffer(array $diff, array $old, $start, $end) + { + $buffer = $this->header; - $newChunk = true; + if (!isset($old[$start])) { + $buffer = $this->getDiffBufferElementNew($diff, $buffer, $start); + ++$start; + } for ($i = $start; $i < $end; $i++) { if (isset($old[$i])) { - $buffer .= "\n"; - $newChunk = true; - $i = $old[$i]; + $i = $old[$i]; + $buffer = $this->getDiffBufferElementNew($diff, $buffer, $i); + } else { + $buffer = $this->getDiffBufferElement($diff, $buffer, $i); } + } - if ($newChunk) { - if ($this->showNonDiffLines === true) { - $buffer .= "@@ @@\n"; - } - $newChunk = false; - } + return $buffer; + } - if ($diff[$i][1] === 1 /* ADDED */) { - $buffer .= '+' . $diff[$i][0] . "\n"; - } elseif ($diff[$i][1] === 2 /* REMOVED */) { - $buffer .= '-' . $diff[$i][0] . "\n"; - } elseif ($this->showNonDiffLines === true) { - $buffer .= ' ' . $diff[$i][0] . "\n"; - } + /** + * Gets individual buffer element. + * + * @param array $diff + * @param string $buffer + * @param int $diffIndex + * + * @return string + */ + private function getDiffBufferElement(array $diff, $buffer, $diffIndex) + { + if ($diff[$diffIndex][1] === 1 /* ADDED */) { + $buffer .= '+' . $diff[$diffIndex][0] . "\n"; + } elseif ($diff[$diffIndex][1] === 2 /* REMOVED */) { + $buffer .= '-' . $diff[$diffIndex][0] . "\n"; + } elseif ($this->showNonDiffLines === true) { + $buffer .= ' ' . $diff[$diffIndex][0] . "\n"; } return $buffer; } + /** + * Gets individual buffer element with opening. + * + * @param array $diff + * @param string $buffer + * @param int $diffIndex + * + * @return string + */ + private function getDiffBufferElementNew(array $diff, $buffer, $diffIndex) + { + if ($this->showNonDiffLines === true) { + $buffer .= "@@ @@\n"; + } + + return $this->getDiffBufferElement($diff, $buffer, $diffIndex); + } + /** * Returns the diff between two arrays or strings as array. * * Each array element contains two elements: - * - [0] => string $token + * - [0] => mixed $token * - [1] => 2|1|0 * * - 2: REMOVED: $token was removed from $from @@ -134,55 +203,37 @@ class Differ */ public function diffToArray($from, $to, LongestCommonSubsequence $lcs = null) { - preg_match_all('(\r\n|\r|\n)', $from, $fromMatches); - preg_match_all('(\r\n|\r|\n)', $to, $toMatches); - - if (is_string($from)) { - $from = preg_split('(\r\n|\r|\n)', $from); + if (\is_string($from)) { + $fromMatches = $this->getNewLineMatches($from); + $from = $this->splitStringByLines($from); + } elseif (\is_array($from)) { + $fromMatches = array(); + } else { + throw new \InvalidArgumentException('"from" must be an array or string.'); } - if (is_string($to)) { - $to = preg_split('(\r\n|\r|\n)', $to); + if (\is_string($to)) { + $toMatches = $this->getNewLineMatches($to); + $to = $this->splitStringByLines($to); + } elseif (\is_array($to)) { + $toMatches = array(); + } else { + throw new \InvalidArgumentException('"to" must be an array or string.'); } - $start = array(); - $end = array(); - $fromLength = count($from); - $toLength = count($to); - $length = min($fromLength, $toLength); - - for ($i = 0; $i < $length; ++$i) { - if ($from[$i] === $to[$i]) { - $start[] = $from[$i]; - unset($from[$i], $to[$i]); - } else { - break; - } - } - - $length -= $i; - - for ($i = 1; $i < $length; ++$i) { - if ($from[$fromLength - $i] === $to[$toLength - $i]) { - array_unshift($end, $from[$fromLength - $i]); - unset($from[$fromLength - $i], $to[$toLength - $i]); - } else { - break; - } - } + list($from, $to, $start, $end) = self::getArrayDiffParted($from, $to); if ($lcs === null) { $lcs = $this->selectLcsImplementation($from, $to); } - $common = $lcs->calculate(array_values($from), array_values($to)); + $common = $lcs->calculate(\array_values($from), \array_values($to)); $diff = array(); - if (isset($fromMatches[0]) && $toMatches[0] && - count($fromMatches[0]) === count($toMatches[0]) && - $fromMatches[0] !== $toMatches[0]) { + if ($this->detectUnmatchedLineEndings($fromMatches, $toMatches)) { $diff[] = array( - '#Warning: Strings contain different line endings!', 0 + '#Warning: Strings contain different line endings!', + 0 ); } @@ -190,29 +241,29 @@ class Differ $diff[] = array($token, 0 /* OLD */); } - reset($from); - reset($to); + \reset($from); + \reset($to); foreach ($common as $token) { - while ((($fromToken = reset($from)) !== $token)) { - $diff[] = array(array_shift($from), 2 /* REMOVED */); + while (($fromToken = \reset($from)) !== $token) { + $diff[] = array(\array_shift($from), 2 /* REMOVED */); } - while ((($toToken = reset($to)) !== $token)) { - $diff[] = array(array_shift($to), 1 /* ADDED */); + while (($toToken = \reset($to)) !== $token) { + $diff[] = array(\array_shift($to), 1 /* ADDED */); } $diff[] = array($token, 0 /* OLD */); - array_shift($from); - array_shift($to); + \array_shift($from); + \array_shift($to); } - while (($token = array_shift($from)) !== null) { + while (($token = \array_shift($from)) !== null) { $diff[] = array($token, 2 /* REMOVED */); } - while (($token = array_shift($to)) !== null) { + while (($token = \array_shift($to)) !== null) { $diff[] = array($token, 1 /* ADDED */); } @@ -223,6 +274,32 @@ class Differ return $diff; } + /** + * Get new strings denoting new lines from a given string. + * + * @param string $string + * + * @return array + */ + private function getNewLineMatches($string) + { + \preg_match_all('(\r\n|\r|\n)', $string, $stringMatches); + + return $stringMatches; + } + + /** + * Checks if input is string, if so it will split it line-by-line. + * + * @param string $input + * + * @return array + */ + private function splitStringByLines($input) + { + return \preg_split('(\r\n|\r|\n)', $input); + } + /** * @param array $from * @param array $to @@ -250,12 +327,73 @@ class Differ * @param array $from * @param array $to * - * @return int + * @return int|float */ private function calculateEstimatedFootprint(array $from, array $to) { - $itemSize = PHP_INT_SIZE == 4 ? 76 : 144; + $itemSize = PHP_INT_SIZE === 4 ? 76 : 144; + + return $itemSize * \pow(\min(\count($from), \count($to)), 2); + } + + /** + * Returns true if line ends don't match on fromMatches and toMatches. + * + * @param array $fromMatches + * @param array $toMatches + * + * @return bool + */ + private function detectUnmatchedLineEndings(array $fromMatches, array $toMatches) + { + return isset($fromMatches[0], $toMatches[0]) && + \count($fromMatches[0]) === \count($toMatches[0]) && + $fromMatches[0] !== $toMatches[0]; + } + + /** + * @param array $from + * @param array $to + * + * @return array + */ + private static function getArrayDiffParted(array &$from, array &$to) + { + $start = array(); + $end = array(); + + \reset($to); + + foreach ($from as $k => $v) { + $toK = \key($to); + + if ($toK === $k && $v === $to[$k]) { + $start[$k] = $v; + + unset($from[$k], $to[$k]); + } else { + break; + } + } + + \end($from); + \end($to); + + do { + $fromK = \key($from); + $toK = \key($to); + + if (null === $fromK || null === $toK || \current($from) !== \current($to)) { + break; + } + + \prev($from); + \prev($to); + + $end = array($fromK => $from[$fromK]) + $end; + unset($from[$fromK], $to[$toK]); + } while (true); - return $itemSize * pow(min(count($from), count($to)), 2); + return array($from, $to, $start, $end); } }