diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2013-08-12 09:28:15 +0200 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2013-08-12 09:28:15 +0200 |
commit | 08aa4418c30cfc18ccc69a0f0f9cb9e17be6c196 (patch) | |
tree | 577a29fb579188d16003a209ce2a2e9c5b0aa2bd /includes/diff | |
parent | cacc939b34e315b85e2d72997811eb6677996cc1 (diff) |
Update to MediaWiki 1.21.1
Diffstat (limited to 'includes/diff')
-rw-r--r-- | includes/diff/DairikiDiff.php | 79 | ||||
-rw-r--r-- | includes/diff/DifferenceEngine.php | 191 | ||||
-rw-r--r-- | includes/diff/WikiDiff3.php | 5 |
3 files changed, 197 insertions, 78 deletions
diff --git a/includes/diff/DairikiDiff.php b/includes/diff/DairikiDiff.php index 72eb5d3c..94ffc066 100644 --- a/includes/diff/DairikiDiff.php +++ b/includes/diff/DairikiDiff.php @@ -5,6 +5,21 @@ * Copyright © 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> * You may copy this code freely under the conditions of the GPL. * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * * @file * @ingroup DifferenceEngine * @defgroup DifferenceEngine DifferenceEngine @@ -28,14 +43,14 @@ class _DiffOp { * @return int */ function norig() { - return $this->orig ? sizeof( $this->orig ) : 0; + return $this->orig ? count( $this->orig ) : 0; } /** * @return int */ function nclosing() { - return $this->closing ? sizeof( $this->closing ) : 0; + return $this->closing ? count( $this->closing ) : 0; } } @@ -152,7 +167,7 @@ class _DiffOp_Change extends _DiffOp { */ class _DiffEngine { - const MAX_XREF_LENGTH = 10000; + const MAX_XREF_LENGTH = 10000; protected $xchanged, $ychanged; @@ -179,8 +194,8 @@ class _DiffEngine { $this->_shift_boundaries( $to_lines, $this->ychanged, $this->xchanged ); // Compute the edit operations. - $n_from = sizeof( $from_lines ); - $n_to = sizeof( $to_lines ); + $n_from = count( $from_lines ); + $n_to = count( $to_lines ); $edits = array(); $xi = $yi = 0; @@ -206,7 +221,7 @@ class _DiffEngine { } $add = array(); - while ( $yi < $n_to && $this->ychanged[$yi] ) { + while ( $yi < $n_to && $this->ychanged[$yi] ) { $add[] = $to_lines[$yi++]; } @@ -239,8 +254,8 @@ class _DiffEngine { unset( $wikidiff3 ); } else { // old diff - $n_from = sizeof( $from_lines ); - $n_to = sizeof( $to_lines ); + $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(); @@ -288,7 +303,7 @@ class _DiffEngine { } // Find the LCS. - $this->_compareseq( 0, sizeof( $this->xv ), 0, sizeof( $this->yv ) ); + $this->_compareseq( 0, count( $this->xv ), 0, count( $this->yv ) ); } wfProfileOut( __METHOD__ ); } @@ -311,7 +326,7 @@ class _DiffEngine { * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally * sized segments. * - * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an + * 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 @@ -476,8 +491,7 @@ class _DiffEngine { // $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 ); + list ( $lcs, $seps ) = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks ); } if ( $lcs == 0 ) { @@ -518,9 +532,9 @@ class _DiffEngine { $i = 0; $j = 0; - assert( 'sizeof($lines) == sizeof($changed)' ); - $len = sizeof( $lines ); - $other_len = sizeof( $other_changed ); + assert( 'count($lines) == count($changed)' ); + $len = count( $lines ); + $other_len = count( $other_changed ); while ( 1 ) { /* @@ -698,7 +712,7 @@ class Diff { $lcs = 0; foreach ( $this->edits as $edit ) { if ( $edit->type == 'copy' ) { - $lcs += sizeof( $edit->orig ); + $lcs += count( $edit->orig ); } } return $lcs; @@ -717,7 +731,7 @@ class Diff { foreach ( $this->edits as $edit ) { if ( $edit->orig ) { - array_splice( $lines, sizeof( $lines ), 0, $edit->orig ); + array_splice( $lines, count( $lines ), 0, $edit->orig ); } } return $lines; @@ -736,7 +750,7 @@ class Diff { foreach ( $this->edits as $edit ) { if ( $edit->closing ) { - array_splice( $lines, sizeof( $lines ), 0, $edit->closing ); + array_splice( $lines, count( $lines ), 0, $edit->closing ); } } return $lines; @@ -766,7 +780,6 @@ class Diff { trigger_error( "Reversed closing doesn't match", E_USER_ERROR ); } - $prevtype = 'none'; foreach ( $this->edits as $edit ) { if ( $prevtype == $edit->type ) { @@ -814,23 +827,23 @@ class MappedDiff extends Diff { $mapped_from_lines, $mapped_to_lines ) { wfProfileIn( __METHOD__ ); - assert( 'sizeof( $from_lines ) == sizeof( $mapped_from_lines )' ); - assert( 'sizeof( $to_lines ) == sizeof( $mapped_to_lines )' ); + assert( 'count( $from_lines ) == count( $mapped_from_lines )' ); + assert( 'count( $to_lines ) == count( $mapped_to_lines )' ); parent::__construct( $mapped_from_lines, $mapped_to_lines ); $xi = $yi = 0; - for ( $i = 0; $i < sizeof( $this->edits ); $i++ ) { + for ( $i = 0; $i < count( $this->edits ); $i++ ) { $orig = &$this->edits[$i]->orig; if ( is_array( $orig ) ) { - $orig = array_slice( $from_lines, $xi, sizeof( $orig ) ); - $xi += sizeof( $orig ); + $orig = array_slice( $from_lines, $xi, count( $orig ) ); + $xi += count( $orig ); } $closing = &$this->edits[$i]->closing; if ( is_array( $closing ) ) { - $closing = array_slice( $to_lines, $yi, sizeof( $closing ) ); - $yi += sizeof( $closing ); + $closing = array_slice( $to_lines, $yi, count( $closing ) ); + $yi += count( $closing ); } } wfProfileOut( __METHOD__ ); @@ -885,7 +898,7 @@ class DiffFormatter { foreach ( $diff->edits as $edit ) { if ( $edit->type == 'copy' ) { if ( is_array( $block ) ) { - if ( sizeof( $edit->orig ) <= $nlead + $ntrail ) { + if ( count( $edit->orig ) <= $nlead + $ntrail ) { $block[] = $edit; } else { if ( $ntrail ) { @@ -901,9 +914,9 @@ class DiffFormatter { $context = $edit->orig; } else { if ( !is_array( $block ) ) { - $context = array_slice( $context, sizeof( $context ) - $nlead ); - $x0 = $xi - sizeof( $context ); - $y0 = $yi - sizeof( $context ); + $context = array_slice( $context, count( $context ) - $nlead ); + $x0 = $xi - count( $context ); + $y0 = $yi - count( $context ); $block = array(); if ( $context ) { $block[] = new _DiffOp_Copy( $context ); @@ -913,10 +926,10 @@ class DiffFormatter { } if ( $edit->orig ) { - $xi += sizeof( $edit->orig ); + $xi += count( $edit->orig ); } if ( $edit->closing ) { - $yi += sizeof( $edit->closing ); + $yi += count( $edit->closing ); } } @@ -1350,7 +1363,7 @@ class TableDiffFormatter extends DiffFormatter { */ function _block_header( $xbeg, $xlen, $ybeg, $ylen ) { $r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" . - '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n"; + '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n"; return $r; } diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php index c7156fb2..0f3c77ff 100644 --- a/includes/diff/DifferenceEngine.php +++ b/includes/diff/DifferenceEngine.php @@ -38,7 +38,10 @@ class DifferenceEngine extends ContextSource { * @private */ var $mOldid, $mNewid; - var $mOldtext, $mNewtext; + /** + * @var Content + */ + var $mOldContent, $mNewContent; protected $mDiffLang; /** @@ -77,7 +80,7 @@ class DifferenceEngine extends ContextSource { * Constructor * @param $context IContextSource context to use, anything else will be ignored * @param $old Integer old ID we want to show and diff with. - * @param $new String either 'prev' or 'next'. + * @param string $new either 'prev' or 'next'. * @param $rcid Integer ??? FIXME (default 0) * @param $refreshCache boolean If set, refreshes the diff cache * @param $unhide boolean If set, allow viewing deleted revs @@ -149,7 +152,7 @@ class DifferenceEngine extends ContextSource { function deletedLink( $id ) { if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) { $dbr = wfGetDB( DB_SLAVE ); - $row = $dbr->selectRow('archive', '*', + $row = $dbr->selectRow( 'archive', '*', array( 'ar_rev_id' => $id ), __METHOD__ ); if ( $row ) { @@ -224,6 +227,10 @@ class DifferenceEngine extends ContextSource { # we'll use the application/x-external-editor interface to call # an external diff tool like kompare, kdiff3, etc. if ( ExternalEdit::useExternalEngine( $this->getContext(), 'diff' ) ) { + //TODO: come up with a good solution for non-text content here. + // at least, the content format needs to be passed to the client somehow. + // Currently, action=raw will just fail for non-text content. + $urls = array( 'File' => array( 'Extension' => 'wiki', 'URL' => # This should be mOldPage, but it may not be set, see below. @@ -260,6 +267,8 @@ class DifferenceEngine extends ContextSource { $deleted = $suppressed = false; $allowed = $this->mNewRev->userCan( Revision::DELETED_TEXT, $user ); + $revisionTools = array(); + # mOldRev is false if the difference engine is called with a "vague" query for # a diff between a version V and its previous version V' AND the version V # is the first version of that article. In that case, V' does not exist. @@ -287,12 +296,14 @@ class DifferenceEngine extends ContextSource { if ( $samePage && $this->mNewPage->quickUserCan( 'edit', $user ) ) { if ( $this->mNewRev->isCurrent() && $this->mNewPage->userCan( 'rollback', $user ) ) { - $out->preventClickjacking(); - $rollback = '   ' . Linker::generateRollback( $this->mNewRev, $this->getContext() ); + $rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext() ); + if ( $rollbackLink ) { + $out->preventClickjacking(); + $rollback = '   ' . $rollbackLink; + } } if ( !$this->mOldRev->isDeleted( Revision::DELETED_TEXT ) && !$this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ) { - $undoLink = ' ' . $this->msg( 'parentheses' )->rawParams( - Html::element( 'a', array( + $undoLink = Html::element( 'a', array( 'href' => $this->mNewPage->getLocalUrl( array( 'action' => 'edit', 'undoafter' => $this->mOldid, @@ -300,7 +311,8 @@ class DifferenceEngine extends ContextSource { 'title' => Linker::titleAttrib( 'undo' ) ), $this->msg( 'editundo' )->text() - ) )->escaped(); + ); + $revisionTools[] = $undoLink; } } @@ -366,7 +378,15 @@ class DifferenceEngine extends ContextSource { # Handle RevisionDelete links... $rdel = $this->revisionDeleteLink( $this->mNewRev ); - $newRevisionHeader = $this->getRevisionHeader( $this->mNewRev, 'complete' ) . $undoLink; + + # Allow extensions to define their own revision tools + wfRunHooks( 'DiffRevisionTools', array( $this->mNewRev, &$revisionTools ) ); + $formattedRevisionTools = array(); + // Put each one in parentheses (poor man's button) + foreach ( $revisionTools as $tool ) { + $formattedRevisionTools[] = $this->msg( 'parentheses' )->rawParams( $tool )->escaped(); + } + $newRevisionHeader = $this->getRevisionHeader( $this->mNewRev, 'complete' ) . ' ' . implode( ' ', $formattedRevisionTools ); $newHeader = '<div id="mw-diff-ntitle1"><strong>' . $newRevisionHeader . '</strong></div>' . '<div id="mw-diff-ntitle2">' . Linker::revUserTools( $this->mNewRev, !$this->unhide ) . @@ -417,8 +437,8 @@ class DifferenceEngine extends ContextSource { /** * Get a link to mark the change as patrolled, or '' if there's either no * revision to patrol or the user is not allowed to to it. - * Side effect: this method will call OutputPage::preventClickjacking() - * when a link is builded. + * Side effect: When the patrol link is build, this method will call + * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax. * * @return String */ @@ -459,6 +479,8 @@ class DifferenceEngine extends ContextSource { // Build the link if ( $rcid ) { $this->getOutput()->preventClickjacking(); + $this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' ); + $token = $this->getUser()->getEditToken( $rcid ); $this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown( $this->mNewPage, @@ -510,19 +532,23 @@ class DifferenceEngine extends ContextSource { $out->setRevisionTimestamp( $this->mNewRev->getTimestamp() ); $out->setArticleFlag( true ); + // NOTE: only needed for B/C: custom rendering of JS/CSS via hook if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) { // Stolen from Article::view --AG 2007-10-11 // Give hooks a chance to customise the output // @TODO: standardize this crap into one function - if ( wfRunHooks( 'ShowRawCssJs', array( $this->mNewtext, $this->mNewPage, $out ) ) ) { - // Wrap the whole lot in a <pre> and don't parse - $m = array(); - preg_match( '!\.(css|js)$!u', $this->mNewPage->getText(), $m ); - $out->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" ); - $out->addHTML( htmlspecialchars( $this->mNewtext ) ); - $out->addHTML( "\n</pre>\n" ); + if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->mNewContent, $this->mNewPage, $out ) ) ) { + // NOTE: deprecated hook, B/C only + // use the content object's own rendering + $cnt = $this->mNewRev->getContent(); + $po = $cnt ? $cnt->getParserOutput( $this->mNewRev->getTitle(), $this->mNewRev->getId() ) : null; + $txt = $po ? $po->getText() : ''; + $out->addHTML( $txt ); } - } elseif ( !wfRunHooks( 'ArticleViewCustom', array( $this->mNewtext, $this->mNewPage, $out ) ) ) { + } elseif( !wfRunHooks( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) { + // Handled by extension + } elseif( !ContentHandler::runLegacyHooks( 'ArticleViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) { + // NOTE: deprecated hook, B/C only // Handled by extension } else { // Normal page @@ -536,16 +562,21 @@ class DifferenceEngine extends ContextSource { $wikiPage = WikiPage::factory( $this->mNewPage ); } - $parserOptions = $wikiPage->makeParserOptions( $this->getContext() ); + $parserOutput = $this->getParserOutput( $wikiPage, $this->mNewRev ); - if ( !$this->mNewRev->isCurrent() ) { - $parserOptions->setEditSection( false ); - } + # Also try to load it as a redirect + $rt = $this->mNewContent ? $this->mNewContent->getRedirectTarget() : null; - $parserOutput = $wikiPage->getParserOutput( $parserOptions, $this->mNewid ); + if ( $rt ) { + $article = Article::newFromTitle( $this->mNewPage, $this->getContext() ); + $out->addHTML( $article->viewRedirect( $rt ) ); - # WikiPage::getParserOutput() should not return false, but just in case - if( $parserOutput ) { + # WikiPage::getParserOutput() should not return false, but just in case + if ( $parserOutput ) { + # Show categories etc. + $out->addParserOutputNoText( $parserOutput ); + } + } else if ( $parserOutput ) { $out->addParserOutput( $parserOutput ); } } @@ -556,6 +587,17 @@ class DifferenceEngine extends ContextSource { wfProfileOut( __METHOD__ ); } + protected function getParserOutput( WikiPage $page, Revision $rev ) { + $parserOptions = $page->makeParserOptions( $this->getContext() ); + + if ( !$rev->isCurrent() || !$rev->getTitle()->quickUserCan( "edit" ) ) { + $parserOptions->setEditSection( false ); + } + + $parserOutput = $page->getParserOutput( $parserOptions, $rev->getId() ); + return $parserOutput; + } + /** * Get the diff text, send it to the OutputPage object * Returns false if the diff could not be generated, otherwise returns true @@ -584,9 +626,9 @@ class DifferenceEngine extends ContextSource { /** * Get complete diff table, including header * - * @param $otitle Title: old title - * @param $ntitle Title: new title - * @param $notice String: HTML between diff header and body + * @param string|bool $otitle Header for old text or false + * @param string|bool $ntitle Header for new text or false + * @param string $notice HTML between diff header and body * @return mixed */ function getDiff( $otitle, $ntitle, $notice = '' ) { @@ -652,7 +694,7 @@ class DifferenceEngine extends ContextSource { return false; } - $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext ); + $difftext = $this->generateContentDiffBody( $this->mOldContent, $this->mNewContent ); // Save to cache for 7 days if ( !wfRunHooks( 'AbortDiffCache', array( &$this ) ) ) { @@ -690,13 +732,64 @@ class DifferenceEngine extends ContextSource { } /** + * Generate a diff, no caching. + * + * This implementation uses generateTextDiffBody() to generate a diff based on the default + * serialization of the given Content objects. This will fail if $old or $new are not + * instances of TextContent. + * + * Subclasses may override this to provide a different rendering for the diff, + * perhaps taking advantage of the content's native form. This is required for all content + * models that are not text based. + * + * @param $old Content: old content + * @param $new Content: new content + * + * @return bool|string + * @since 1.21 + * @throws MWException if $old or $new are not instances of TextContent. + */ + function generateContentDiffBody( Content $old, Content $new ) { + if ( !( $old instanceof TextContent ) ) { + throw new MWException( "Diff not implemented for " . get_class( $old ) . "; " + . "override generateContentDiffBody to fix this." ); + } + + if ( !( $new instanceof TextContent ) ) { + throw new MWException( "Diff not implemented for " . get_class( $new ) . "; " + . "override generateContentDiffBody to fix this." ); + } + + $otext = $old->serialize(); + $ntext = $new->serialize(); + + return $this->generateTextDiffBody( $otext, $ntext ); + } + + /** * Generate a diff, no caching * - * @param $otext String: old text, must be already segmented - * @param $ntext String: new text, must be already segmented + * @param string $otext old text, must be already segmented + * @param string $ntext new text, must be already segmented * @return bool|string + * @deprecated since 1.21, use generateContentDiffBody() instead! */ function generateDiffBody( $otext, $ntext ) { + ContentHandler::deprecated( __METHOD__, "1.21" ); + + return $this->generateTextDiffBody( $otext, $ntext ); + } + + /** + * Generate a diff, no caching + * + * @todo move this to TextDifferenceEngine, make DifferenceEngine abstract. At some point. + * + * @param string $otext old text, must be already segmented + * @param string $ntext new text, must be already segmented + * @return bool|string + */ + function generateTextDiffBody( $otext, $ntext ) { global $wgExternalDiffEngine, $wgContLang; wfProfileIn( __METHOD__ ); @@ -804,7 +897,6 @@ class DifferenceEngine extends ContextSource { return $this->msg( 'lineno' )->numParams( $matches[1] )->escaped(); } - /** * If there are revisions between the ones being compared, return a note saying so. * @return string @@ -855,11 +947,11 @@ class DifferenceEngine extends ContextSource { * Get a header for a specified revision. * * @param $rev Revision - * @param $complete String: 'complete' to get the header wrapped depending + * @param string $complete 'complete' to get the header wrapped depending * the visibility of the revision and a link to edit the page. * @return String HTML fragment */ - private function getRevisionHeader( Revision $rev, $complete = '' ) { + protected function getRevisionHeader( Revision $rev, $complete = '' ) { $lang = $this->getLanguage(); $user = $this->getUser(); $revtimestamp = $rev->getTimestamp(); @@ -951,10 +1043,25 @@ class DifferenceEngine extends ContextSource { /** * Use specified text instead of loading from the database + * @deprecated since 1.21, use setContent() instead. */ function setText( $oldText, $newText ) { - $this->mOldtext = $oldText; - $this->mNewtext = $newText; + ContentHandler::deprecated( __METHOD__, "1.21" ); + + $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() ); + $newContent = ContentHandler::makeContent( $newText, $this->getTitle() ); + + $this->setContent( $oldContent, $newContent ); + } + + /** + * Use specified text instead of loading from the database + * @since 1.21 + */ + function setContent( Content $oldContent, Content $newContent ) { + $this->mOldContent = $oldContent; + $this->mNewContent = $newContent; + $this->mTextLoaded = 2; $this->mRevisionsLoaded = true; } @@ -1082,14 +1189,14 @@ class DifferenceEngine extends ContextSource { return false; } if ( $this->mOldRev ) { - $this->mOldtext = $this->mOldRev->getText( Revision::FOR_THIS_USER ); - if ( $this->mOldtext === false ) { + $this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER, $this->getUser() ); + if ( $this->mOldContent === null ) { return false; } } if ( $this->mNewRev ) { - $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER ); - if ( $this->mNewtext === false ) { + $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() ); + if ( $this->mNewContent === null ) { return false; } } @@ -1110,7 +1217,7 @@ class DifferenceEngine extends ContextSource { if ( !$this->loadRevisionData() ) { return false; } - $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER ); + $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() ); return true; } } diff --git a/includes/diff/WikiDiff3.php b/includes/diff/WikiDiff3.php index 66727445..ea6f6e5d 100644 --- a/includes/diff/WikiDiff3.php +++ b/includes/diff/WikiDiff3.php @@ -29,7 +29,7 @@ * (http://citeseer.ist.psu.edu/myers86ond.html) with range compression (see Wu et al.'s * "An O(NP) Sequence Comparison Algorithm"). * - * This implementation supports an upper bound on the excution time. + * This implementation supports an upper bound on the execution time. * * Complexity: O((M + N)D) worst case time, O(M + N + D^2) expected time, O(M + N) space * @@ -64,7 +64,7 @@ class WikiDiff3 { public function diff( /*array*/ $from, /*array*/ $to ) { // remember initial lengths - $m = sizeof( $from ); + $m = count( $from ); $n = count( $to ); $this->heuristicUsed = false; @@ -490,7 +490,6 @@ class WikiDiff3 { $temp = array( 0, 0, 0 ); - $max_progress = array_fill( 0, ceil( max( $forward_end_diag - $forward_start_diag, $backward_end_diag - $backward_start_diag ) / 2 ), $temp ); $num_progress = 0; // the 1st entry is current, it is initialized |