/** * get the gdiff as a single text string * * @param string a file name of the original content * @param string a file for the updated content * @return an ASCII string */ public static function &gdiff($original, $updated) { global $context; // read the original file $stat = Safe::stat($context['path_to_root'] . $original); if (!is_array($stat)) { return sprintf(i18n::s('Impossible to read %s.'), $original); } $text = '--- ' . $original . "\t" . str_replace(' ', ' ', Skin::build_date($stat[9])) . "\n"; $original_lines = Safe::file($context['path_to_root'] . $original); // read the updated file $stat = Safe::stat($context['path_to_root'] . $updated); if (!is_array($stat)) { return sprintf(i18n::s('Impossible to read %s.'), $updated); } $text .= '+++ ' . $updated . "\t" . str_replace(' ', ' ', Skin::build_date($stat[9])) . "\n"; $updated_lines = Safe::file($context['path_to_root'] . $updated); // compare the two sequences $sequence = Scripts::compare($original_lines, $updated_lines); // format the result according to the gdiff specification $in_chunk = TRUE; $sync = 0; $chunk_start = $old_start = $old_current = $new_start = $new_current = 0; for ($index = 0; $index < count($sequence); $index++) { list($tag, $left, $right) = $sequence[$index]; switch ($tag) { case '-': $chunk[] = '-' . $left; $sync = 0; if (!$in_chunk) { $old_start = $old_current - 3; $new_start = $new_current - 3; $in_chunk = TRUE; } $old_current++; break; case '+': $chunk[] = '+' . $right; $sync = 0; if (!$in_chunk) { $old_start = $old_current - 3; $new_start = $new_current - 3; $in_chunk = TRUE; } $new_current++; break; case '=': $chunk[] = ' ' . $left; if ($in_chunk) { if ($sync++ >= 2) { $in_chunk = FALSE; $text .= '@@ -' . ($old_start + 1) . ',' . ($old_current - $old_start + 1) . ' +' . ($new_start + 1) . ',' . ($new_current - $new_start + 1) . ' @@' . "\n"; foreach ($chunk as $line) { $text .= $line . "\n"; } unset($chunk); } } elseif (count($chunk) > 3) { array_shift($chunk); } $old_current++; $new_current++; break; } } if (is_array($chunk) && count($chunk) > 0) { $text .= '@@ -' . ($old_start + 1) . ',' . ($old_current - $old_start) . ' +' . ($new_start + 1) . ',' . ($new_current - $new_start) . ' @@' . "\n"; foreach ($chunk as $line) { $text .= $line . "\n"; } } // return the result of the whole comparison return $text; }