/** * Generate a diff, no caching * * @param $otext String: old text, must be already segmented * @param $ntext String: new text, must be already segmented */ function generateDiffBody($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; wfProfileIn(__METHOD__); $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); $this->initDiffEngines(); if ($wgExternalDiffEngine == 'wikidiff' && function_exists('wikidiff_do_diff')) { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = htmlspecialchars($wgContLang->segmentForDiff($otext)); $ntext = htmlspecialchars($wgContLang->segmentForDiff($ntext)); wfProfileOut(__METHOD__); return $wgContLang->unsegmentForDiff(wikidiff_do_diff($otext, $ntext, 2)) . $this->debug('wikidiff1'); } if ($wgExternalDiffEngine == 'wikidiff2' && function_exists('wikidiff2_do_diff')) { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself wfProfileIn('wikidiff2_do_diff'); $text = wikidiff2_do_diff($otext, $ntext, 2); $text .= $this->debug('wikidiff2'); wfProfileOut('wikidiff2_do_diff'); wfProfileOut(__METHOD__); return $text; } if ($wgExternalDiffEngine != 'wikidiff3' && $wgExternalDiffEngine !== false) { # Diff via the shell global $wgTmpDirectory; $tempName1 = tempnam($wgTmpDirectory, 'diff_'); $tempName2 = tempnam($wgTmpDirectory, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { wfProfileOut(__METHOD__); return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { wfProfileOut(__METHOD__); return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); wfProfileIn(__METHOD__ . "-shellexec"); $difftext = wfShellExec($cmd); $difftext .= $this->debug("external {$wgExternalDiffEngine}"); wfProfileOut(__METHOD__ . "-shellexec"); unlink($tempName1); unlink($tempName2); wfProfileOut(__METHOD__); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs = new Diff($ota, $nta); $formatter = new TableDiffFormatter(); $difftext = $wgContLang->unsegmentForDiff($formatter->format($diffs)) . wfProfileOut(__METHOD__); return $difftext; }
"; dl( 'php_wikidiff.so' ); function randomString( $length, $nullOk = false, $ascii = false ) { $out = ''; for( $i = 0; $i < $length; $i++ ) $out .= chr( mt_rand( $nullOk ? 0 : 1, $ascii ? 127 : 255 ) ); return $out; } $size = 100000; $maxruns = 1000; $membase = memory_get_usage(); for( $i = 0; $i <= $maxruns; $i++ ) { $x = memory_get_usage() - $membase; printf( "%5d: up %d bytes\n", $i, $x ); $a = randomString( $size ); $b = randomString( $size ); $c = wikidiff_do_diff( $a, $b, 1 ); $a = ''; $b = ''; $c = ''; } echo "(" . (memory_get_usage() - $membase) . " used)\n";
/** * Generate a diff, no caching * $otext and $ntext must be already segmented */ function generateDiffBody($otext, $ntext) { global $wgExternalDiffEngine, $wgContLang; $fname = 'DifferenceEngine::generateDiffBody'; $otext = str_replace("\r\n", "\n", $otext); $ntext = str_replace("\r\n", "\n", $ntext); if ($wgExternalDiffEngine == 'wikidiff') { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = htmlspecialchars($wgContLang->segmentForDiff($otext)); $ntext = htmlspecialchars($wgContLang->segmentForDiff($ntext)); if (!function_exists('wikidiff_do_diff')) { dl('php_wikidiff.so'); } return $wgContLang->unsegementForDiff(wikidiff_do_diff($otext, $ntext, 2)); } if ($wgExternalDiffEngine == 'wikidiff2') { # Better external diff engine, the 2 may some day be dropped # This one does the escaping and segmenting itself if (!function_exists('wikidiff2_do_diff')) { wfProfileIn("{$fname}-dl"); @dl('php_wikidiff2.so'); wfProfileOut("{$fname}-dl"); } if (function_exists('wikidiff2_do_diff')) { wfProfileIn('wikidiff2_do_diff'); $text = wikidiff2_do_diff($otext, $ntext, 2); wfProfileOut('wikidiff2_do_diff'); return $text; } } if ($wgExternalDiffEngine !== false) { # Diff via the shell global $wgTmpDirectory; $tempName1 = tempnam($wgTmpDirectory, 'diff_'); $tempName2 = tempnam($wgTmpDirectory, 'diff_'); $tempFile1 = fopen($tempName1, "w"); if (!$tempFile1) { wfProfileOut($fname); return false; } $tempFile2 = fopen($tempName2, "w"); if (!$tempFile2) { wfProfileOut($fname); return false; } fwrite($tempFile1, $otext); fwrite($tempFile2, $ntext); fclose($tempFile1); fclose($tempFile2); $cmd = wfEscapeShellArg($wgExternalDiffEngine, $tempName1, $tempName2); wfProfileIn("{$fname}-shellexec"); $difftext = wfShellExec($cmd); wfProfileOut("{$fname}-shellexec"); unlink($tempName1); unlink($tempName2); return $difftext; } # Native PHP diff $ota = explode("\n", $wgContLang->segmentForDiff($otext)); $nta = explode("\n", $wgContLang->segmentForDiff($ntext)); $diffs =& new Diff($ota, $nta); $formatter =& new TableDiffFormatter(); return $wgContLang->unsegmentForDiff($formatter->format($diffs)); }
<?php dl("php_wikidiff.so"); $f1 = implode("\n", file("t1.txt")); $f2 = implode("\n", file("t2.txt")); # performance test for ($i = 0; $i < 100; ++$i) { $v = wikidiff_do_diff($f1, $f2, 2); }
function getDiff($otext, $ntext, $otitle, $ntitle) { global $wgUseExternalDiffEngine, $wgContLang; $out = "\n\t\t\t<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>\n\t\t\t<tr>\n\t\t\t\t<td colspan='2' width='50%' align='center' class='diff-otitle'>{$otitle}</td>\n\t\t\t\t<td colspan='2' width='50%' align='center' class='diff-ntitle'>{$ntitle}</td>\n\t\t\t</tr>\n\t\t"; $otext = $wgContLang->segmentForDiff($otext); $ntext = $wgContLang->segmentForDiff($ntext); $difftext = ''; if ($wgUseExternalDiffEngine) { # For historical reasons, external diff engine expects # input text to be HTML-escaped already $otext = str_replace("\r\n", "\n", htmlspecialchars($otext)); $ntext = str_replace("\r\n", "\n", htmlspecialchars($ntext)); if (!function_exists('wikidiff_do_diff')) { dl('php_wikidiff.so'); } $difftext = wikidiff_do_diff($otext, $ntext, 2); } else { $ota = explode("\n", str_replace("\r\n", "\n", $otext)); $nta = explode("\n", str_replace("\r\n", "\n", $ntext)); $diffs =& new Diff($ota, $nta); $formatter =& new TableDiffFormatter(); $difftext = $formatter->format($diffs); } $difftext = $wgContLang->unsegmentForDiff($difftext); $out .= $difftext . "</table>\n"; return $out; }