<?php// WebSVN - Subversion repository viewing via the web using PHP// Copyright (C) 2004-2006 Tim Armes//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//// --//// diff_inc.php//// Diff to filesif (!defined('USE_AUTOLOADER')) {@include_once 'Horde/String.php';@include_once 'Horde/Text/Diff.php';@include_once 'Horde/Text/Diff/Mapped.php';@include_once 'Horde/Text/Diff/Engine/Native.php';@include_once 'Horde/Text/Diff/Op/Base.php';@include_once 'Horde/Text/Diff/Op/Copy.php';@include_once 'Horde/Text/Diff/Op/Delete.php';@include_once 'Horde/Text/Diff/Op/Add.php';@include_once 'Horde/Text/Diff/Op/Change.php';@include_once 'Horde/Text/Diff/Renderer.php';@include_once 'Horde/Text/Diff/Renderer/Unified.php';}include_once 'include/diff_util.php';$arrayBased = false;$fileBased = false;class ListingHelper {var $_listing = array();var $_index = 0;var $_blockStart = false;function _add($text1, $lineno1, $class1, $text2, $lineno2, $class2) {$listing = &$this->_listing;$index = &$this->_index;$listvar = &$listing[$index];$listvar['rev1diffclass'] = $class1;$listvar['rev2diffclass'] = $class2;$listvar['rev1line'] = $text1;$listvar['rev2line'] = $text2;$listvar['rev1lineno'] = $lineno1;$listvar['rev2lineno'] = $lineno2;$listvar['startblock'] = $this->_blockStart;$this->_blockStart = false;$index++;}function addDeletedLine($text, $lineno) {$this->_add($text, $lineno, 'diffdeleted', ' ', '-', 'diffempty');}function addAddedLine($text, $lineno) {$this->_add(' ', '-', 'diffempty', $text, $lineno, 'diffadded');}function addChangedLine($text1, $lineno1, $text2, $lineno2) {$this->_add($text1, $lineno1, 'diffchanged', $text2, $lineno2, 'diffchanged');}// note that $text1 do not need to be equal $text2 if $ignoreWhitespace is truefunction addLine($text1, $lineno1, $text2, $lineno2) {$this->_add($text1, $lineno1, 'diff', $text2, $lineno2, 'diff');}function startNewBlock() {$this->_blockStart = true;}function getListing() {return $this->_listing;}}function nextLine(&$obj) {global $arrayBased, $fileBased;if ($arrayBased) return array_shift($obj);if ($fileBased) return fgets($obj);return '';}function endOfFile(&$obj) {global $arrayBased, $fileBased;if ($arrayBased) return count($obj) == 0;if ($fileBased) return feof($obj);return true;}function getWrappedLineFromFile($file, $is_highlighted) {$line = fgets($file);if ($line === false) return false;$line = toOutputEncoding($line);if (!$is_highlighted) {$line = escape($line);}$line = rtrim($line, "\n\r");if (strip_tags($line) === '') $line = ' ';return wrapInCodeTagIfNecessary($line);}function diff_result($all, $highlighted, $newtname, $oldtname, $obj, $ignoreWhitespace) {$ofile = fopen($oldtname, 'r');$nfile = fopen($newtname, 'r');// Get the first real line$line = nextLine($obj);$index = 0;$listingHelper = new ListingHelper();$curoline = 1;$curnline = 1;$sensibleLineChanges = new SensibleLineChanges(new LineDiff($ignoreWhitespace));while (!endOfFile($obj)) {// Get the first line of this range$oline = 0;sscanf($line, '@@ -%d', $oline);$line = substr($line, strpos($line, '+'));$nline = 0;sscanf($line, '+%d', $nline);while ($curoline < $oline || $curnline < $nline) {if ($curoline < $oline) {$text1 = getWrappedLineFromFile($ofile, $highlighted);$tmpoline = $curoline;$curoline++;} else {$tmpoline = '?';$text1 = ' ';}if ($curnline < $nline) {$text2 = getWrappedLineFromFile($nfile, $highlighted);$tmpnline = $curnline;$curnline++;} else {$tmpnline = '?';$text2 = ' ';}if ($all) {$listingHelper->addLine($text1, $tmpoline, $text2, $tmpnline);}}if (!$all && $line !== false) {$listingHelper->startNewBlock();}$fin = false;while (!endOfFile($obj) && !$fin) {$line = nextLine($obj);if ($line === false || $line === '' || strncmp($line, '@@', 2) == 0) {$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted);$fin = true;} else {$mod = $line[0];$line = substr($line, 1);switch ($mod) {case '-':$text = getWrappedLineFromFile($ofile, $highlighted);$sensibleLineChanges->addDeletedLine($line, $text, $curoline);$curoline++;break;case '+':$text = getWrappedLineFromFile($nfile, $highlighted);$sensibleLineChanges->addAddedLine($line, $text, $curnline);$curnline++;break;default:$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted);$text1 = getWrappedLineFromFile($ofile, $highlighted);$text2 = getWrappedLineFromFile($nfile, $highlighted);$listingHelper->addLine($text1, $curoline, $text2, $curnline);$curoline++;$curnline++;break;}}if (!$fin) {$index++;}}}$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted);// Output the rest of the filesif ($all) {while (!feof($ofile) || !feof($nfile)) {$noneof = false;$text1 = getWrappedLineFromFile($ofile, $highlighted);if ($text1 !== false) {$tmpoline = $curoline;$curoline++;$noneof = true;} else {$tmpoline = '-';$text1 = ' ';}$text2 = getWrappedLineFromFile($nfile, $highlighted);if ($text2 !== false) {$tmpnline = $curnline;$curnline++;$noneof = true;} else {$tmpnline = '-';$text2 = ' ';}if ($noneof) {$listingHelper->addLine($text1, $tmpoline, $text2, $tmpnline);}}}fclose($ofile);fclose($nfile);return $listingHelper->getListing();}function command_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) {global $config, $lang, $arrayBased, $fileBased;$context = 5;if ($all) {// Setting the context to 0 makes diff generate the wrong line numbers!$context = 1;}if ($ignoreWhitespace) {$whitespaceFlag = ' -w';} else {$whitespaceFlag = '';}// Open a pipe to the diff command with $context lines of context:$cmd = $config->diff.$whitespaceFlag.' -U '.$context.' "'.$oldtname.'" "'.$newtname.'"';$diff = runCommand($cmd, true);// Ignore the 3 header lines:$line = array_shift($diff);$line = array_shift($diff);$arrayBased = true;$fileBased = false;if ($highlighted) {$listing = diff_result($all, $highlighted, $newhlname, $oldhlname, $diff, $ignoreWhitespace);} else {$listing = diff_result($all, $highlighted, $newtname, $oldtname, $diff, $ignoreWhitespace);}return $listing;}function inline_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) {global $arrayBased, $fileBased;$context = 5;if ($all) {// Setting the context to 0 makes diff generate the wrong line numbers!$context = 1;}// modify error reporting level to suppress deprecated/strict warning "Assigning the return value of new by reference"$bckLevel = error_reporting();$removeLevel = E_DEPRECATED;$modLevel = $bckLevel & (~$removeLevel);error_reporting($modLevel);// Create the diff class$fromLines = file($oldtname);$toLines = file($newtname);if (!$ignoreWhitespace) {$diff = new Horde_Text_Diff('Native', array($fromLines, $toLines));} else {$whitespaces = array(' ', "\t", "\n", "\r");$mappedFromLines = array();foreach ($fromLines as $k => $line) {$line = rtrim($line, "\n\r");$fromLines[$k] = $line;$mappedFromLines[] = str_replace($whitespaces, array(), $line);}$mappedToLines = array();foreach ($toLines as $k => $line) {$line = rtrim($line, "\n\r");$toLines[$k] = $line;$mappedToLines[] = str_replace($whitespaces, array(), $line);}$diff = new Horde_Text_Diff_Mapped('Native', array($fromLines, $toLines, $mappedFromLines, $mappedToLines));}$renderer = new Horde_Text_Diff_Renderer_Unified(array('leading_context_lines' => $context, 'trailing_context_lines' => $context));$rendered = explode("\n", $renderer->render($diff));// restore previous error reporting levelerror_reporting($bckLevel);$arrayBased = true;$fileBased = false;if ($highlighted) {$listing = diff_result($all, $highlighted, $newhlname, $oldhlname, $rendered, $ignoreWhitespace);} else {$listing = diff_result($all, $highlighted, $newtname, $oldtname, $rendered, $ignoreWhitespace);}return $listing;}function do_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) {if ((!$ignoreWhitespace ? class_exists('Horde_Text_Diff') : class_exists('Horde_Text_Diff_Mapped'))&& class_exists('Horde_Text_Diff_Renderer_Unified')) {return inline_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname);} else {return command_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname);}}