updates for the updater and the diff engine.

- this update also includes an important change for including the diff engine, since we may need to include an updated engine before updating. This basically means that for a future update (B4 to another version) requires copying the new diff files first... the new include method should prevent this needed handwork for later versions then.


git-svn-id: file:///svn/phpbb/trunk@6695 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Meik Sievertsen 2006-11-29 15:51:54 +00:00
parent d417d53c0a
commit 7ed41c4de1
4 changed files with 129 additions and 32 deletions

View file

@ -15,10 +15,6 @@ if (!defined('IN_PHPBB'))
exit; exit;
} }
// Include renderer and engine
include_once($phpbb_root_path . 'includes/diff/engine.' . $phpEx);
include_once($phpbb_root_path . 'includes/diff/renderer.' . $phpEx);
/** /**
* Code from pear.php.net, Text_Diff-0.2.1 (beta) package * Code from pear.php.net, Text_Diff-0.2.1 (beta) package
* http://pear.php.net/package/Text_Diff/ * http://pear.php.net/package/Text_Diff/
@ -46,14 +42,10 @@ class diff
* @param array $from_lines An array of strings. Typically these are lines from a file. * @param array $from_lines An array of strings. Typically these are lines from a file.
* @param array $to_lines An array of strings. * @param array $to_lines An array of strings.
*/ */
function diff(&$from_content, &$to_content) function diff(&$from_content, &$to_content, $preserve_cr = true)
{ {
$diff_engine = &new diff_engine(); $diff_engine = &new diff_engine();
$this->_edits = $diff_engine->diff($from_content, $to_content, $preserve_cr);
$from_content = preg_replace('#[\n\r]+#', "\n", $from_content);
$to_content = preg_replace('#[\n\r]+#', "\n", $to_content);
$this->_edits = call_user_func_array(array($diff_engine, 'diff'), array(explode("\n", $from_content), explode("\n", $to_content)));
} }
/** /**
@ -252,7 +244,7 @@ class mapped_diff extends diff
* compared when computing the diff. * compared when computing the diff.
* @param array $mapped_to_lines This array should have the same number of elements as $to_lines. * @param array $mapped_to_lines This array should have the same number of elements as $to_lines.
*/ */
function mapped_diff($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) function mapped_diff(&$from_lines, &$to_lines, &$mapped_from_lines, &$mapped_to_lines)
{ {
if (sizeof($from_lines) != sizeof($mapped_from_lines) || sizeof($to_lines) != sizeof($mapped_to_lines)) if (sizeof($from_lines) != sizeof($mapped_from_lines) || sizeof($to_lines) != sizeof($mapped_to_lines))
{ {
@ -418,10 +410,16 @@ class diff3 extends diff
* @param array $final1 The first version to compare to. * @param array $final1 The first version to compare to.
* @param array $final2 The second version to compare to. * @param array $final2 The second version to compare to.
*/ */
function diff3($orig, $final1, $final2) function diff3(&$orig, &$final1, &$final2)
{ {
$engine = new diff_engine(); $diff_engine = &new diff_engine();
$this->_edits = $this->_diff3($engine->diff($orig, $final1), $engine->diff($orig, $final2));
$diff_1 = $diff_engine->diff($orig, $final1);
$diff_2 = $diff_engine->diff($orig, $final2);
unset($engine);
$this->_edits = $this->_diff3($diff_1, $diff_2);
} }
/** /**
@ -546,7 +544,7 @@ class diff3 extends diff
/** /**
* @access private * @access private
*/ */
function _diff3($edits1, $edits2) function _diff3(&$edits1, &$edits2)
{ {
$edits = array(); $edits = array();
$bb = &new diff3_block_builder(); $bb = &new diff3_block_builder();

View file

@ -47,11 +47,32 @@ if (!defined('IN_PHPBB'))
*/ */
class diff_engine class diff_engine
{ {
function diff($from_lines, $to_lines) function diff(&$from_lines, &$to_lines, $preserve_cr = true)
{ {
// Remove empty lines... // Remove empty lines...
// array_walk($from_lines, array('diff', 'trim_newlines')); // If preserve_cr is true, we basically only change \r\n and bare \r to \n to get the same carriage returns for both files
// array_walk($to_lines, array('diff', 'trim_newlines')); // If it is false, we try to only use \n once per line and ommit all empty lines to be able to get a proper data diff
if (is_array($from_lines))
{
$from_lines = implode("\n", $from_lines);
}
if (is_array($to_lines))
{
$to_lines = implode("\n", $to_lines);
}
if ($preserve_cr)
{
$from_lines = explode("\n", str_replace("\r", "\n", str_replace("\r\n", "\n", $from_lines)));
$to_lines = explode("\n", str_replace("\r", "\n", str_replace("\r\n", "\n", $to_lines)));
}
else
{
$from_lines = explode("\n", preg_replace('#[\n\r]+#', "\n", $from_lines));
$to_lines = explode("\n", preg_replace('#[\n\r]+#', "\n", $to_lines));
}
$n_from = sizeof($from_lines); $n_from = sizeof($from_lines);
$n_to = sizeof($to_lines); $n_to = sizeof($to_lines);

View file

@ -98,15 +98,20 @@ class diff_renderer
if (is_a($diff, 'diff3')) if (is_a($diff, 'diff3'))
{ {
$diff3 = &$diff; $diff3 = &$diff;
$diff = &new diff($diff3->get_original(), $diff3->merged_output());
$diff_1 = $diff3->get_original();
$diff_2 = $diff3->merged_output();
unset($diff3); unset($diff3);
$diff = &new diff($diff_1, $diff_2);
} }
$nlead = $this->_leading_context_lines; $nlead = $this->_leading_context_lines;
$ntrail = $this->_trailing_context_lines; $ntrail = $this->_trailing_context_lines;
$output = $this->_start_diff(); $output = $this->_start_diff();
$diffs = $diff->get_diff(); $diffs = &$diff->get_diff();
foreach ($diffs as $i => $edit) foreach ($diffs as $i => $edit)
{ {
@ -440,7 +445,11 @@ class diff_renderer_inline extends diff_renderer
// We want to split on word boundaries, but we need to preserve whitespace as well. // We want to split on word boundaries, but we need to preserve whitespace as well.
// Therefore we split on words, but include all blocks of whitespace in the wordlist. // Therefore we split on words, but include all blocks of whitespace in the wordlist.
$diff = &new diff($this->_split_on_words($text1, $nl), $this->_split_on_words($text2, $nl)); $splitted_text_1 = $this->_split_on_words($text1, $nl);
$splitted_text_2 = $this->_split_on_words($text2, $nl);
$diff = &new diff($splitted_text_1, $splitted_text_2);
unset($splitted_text_1, $splitted_text_2);
// Get the diff in inline format. // Get the diff in inline format.
$renderer = &new diff_renderer_inline(array_merge($this->get_params(), array('split_level' => 'words'))); $renderer = &new diff_renderer_inline(array_merge($this->get_params(), array('split_level' => 'words')));

View file

@ -94,7 +94,10 @@ class install_update extends module
$auth->acl($user->data); $auth->acl($user->data);
$user->setup('install'); $user->setup('install');
// Include renderer and engine
include_once($phpbb_root_path . 'includes/diff/diff.' . $phpEx); include_once($phpbb_root_path . 'includes/diff/diff.' . $phpEx);
include_once($phpbb_root_path . 'includes/diff/engine.' . $phpEx);
include_once($phpbb_root_path . 'includes/diff/renderer.' . $phpEx);
// Check for user session // Check for user session
if (!$user->data['is_registered']) if (!$user->data['is_registered'])
@ -574,22 +577,41 @@ class install_update extends module
break; break;
case 'modified': case 'modified':
$diff = &new diff3(file($this->old_location . $original_filename), file($phpbb_root_path . $file_struct['filename']), file($this->new_location . $original_filename));
$tmp = array(
'file1' => file_get_contents($this->old_location . $original_filename),
'file2' => file_get_contents($phpbb_root_path . $file_struct['filename']),
'file3' => file_get_contents($this->new_location . $original_filename),
);
$diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']);
$contents = implode("\n", $diff->merged_output()); $contents = implode("\n", $diff->merged_output());
unset($tmp, $diff);
if ($update_mode == 'download') if ($update_mode == 'download')
{ {
$compress->add_data($contents, $file_struct['filename']); $compress->add_data($contents, $file_struct['filename']);
} }
else else
{ {
// @todo add option to specify if a backup file should be created?
$transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak');
$transfer->write_file($file_struct['filename'], $contents); $transfer->write_file($file_struct['filename'], $contents);
} }
break; break;
case 'conflict': case 'conflict':
$diff = &new diff3(file($this->old_location . $original_filename), file($phpbb_root_path . $file_struct['filename']), file($this->new_location . $original_filename));
$tmp = array(
'file1' => file_get_contents($this->old_location . $original_filename),
'file2' => file_get_contents($phpbb_root_path . $file_struct['filename']),
'file3' => file_get_contents($this->new_location . $original_filename),
);
$diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']);
unset($tmp);
if ($conflicts[$file_struct['filename']] == 1) if ($conflicts[$file_struct['filename']] == 1)
{ {
@ -601,9 +623,12 @@ class install_update extends module
} }
else else
{ {
unset($diff);
break; break;
} }
unset($diff);
if ($update_mode == 'download') if ($update_mode == 'download')
{ {
$compress->add_data($contents, $file_struct['filename']); $compress->add_data($contents, $file_struct['filename']);
@ -716,7 +741,15 @@ class install_update extends module
switch ($status) switch ($status)
{ {
case 'conflict': case 'conflict':
$diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $file), file($this->new_location . $original_file)); $tmp = array(
'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
'file3' => file_get_contents($this->new_location . $original_file),
);
$diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']);
unset($tmp);
$template->assign_vars(array( $template->assign_vars(array(
'S_DIFF_CONFLICT_FILE' => true, 'S_DIFF_CONFLICT_FILE' => true,
@ -725,16 +758,39 @@ class install_update extends module
break; break;
case 'modified': case 'modified':
$diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $original_file), file($this->new_location . $file)); $tmp = array(
'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $original_file),
'file3' => file_get_contents($this->new_location . $file),
);
$diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']);
unset($tmp);
break; break;
case 'not_modified': case 'not_modified':
case 'new_conflict': case 'new_conflict':
$diff = &new diff(file($phpbb_root_path . $file), file($this->new_location . $original_file)); $tmp = array(
'file1' => file_get_contents($phpbb_root_path . $file),
'file2' => file_get_contents($this->new_location . $original_file),
);
$diff = &new diff($tmp['file1'], $tmp['file2']);
unset($tmp);
break; break;
case 'new': case 'new':
$diff = &new diff(array(), file($this->new_location . $original_file)); $tmp = array(
'file1' => array(),
'file2' => file_get_contents($this->new_location . $original_file),
);
$diff = &new diff($tmp['file1'], $tmp['file2']);
unset($tmp);
$template->assign_var('S_DIFF_NEW_FILE', true); $template->assign_var('S_DIFF_NEW_FILE', true);
$diff_mode = 'inline'; $diff_mode = 'inline';
$this->page_title = 'VIEWING_FILE_CONTENTS'; $this->page_title = 'VIEWING_FILE_CONTENTS';
@ -762,6 +818,8 @@ class install_update extends module
'S_DIFF_MODE_OPTIONS' => $diff_mode_options, 'S_DIFF_MODE_OPTIONS' => $diff_mode_options,
'S_SHOW_DIFF' => true, 'S_SHOW_DIFF' => true,
)); ));
unset($diff, $renderer);
} }
/** /**
@ -868,7 +926,7 @@ class install_update extends module
); );
// We need to diff the contents here to make sure the file is really the one we expect // We need to diff the contents here to make sure the file is really the one we expect
$diff = &new diff($tmp['file1'], $tmp['file2']); $diff = &new diff($tmp['file1'], $tmp['file2'], false);
$empty = $diff->is_empty(); $empty = $diff->is_empty();
unset($tmp, $diff); unset($tmp, $diff);
@ -897,7 +955,7 @@ class install_update extends module
); );
// We need to diff the contents here to make sure the file is really the one we expect // We need to diff the contents here to make sure the file is really the one we expect
$diff = &new diff($tmp['file1'], $tmp['file2']); $diff = &new diff($tmp['file1'], $tmp['file2'], false);
$empty_1 = $diff->is_empty(); $empty_1 = $diff->is_empty();
unset($tmp, $diff); unset($tmp, $diff);
@ -908,7 +966,7 @@ class install_update extends module
); );
// We need to diff the contents here to make sure the file is really the one we expect // We need to diff the contents here to make sure the file is really the one we expect
$diff = &new diff($tmp['file1'], $tmp['file2']); $diff = &new diff($tmp['file1'], $tmp['file2'], false);
$empty_2 = $diff->is_empty(); $empty_2 = $diff->is_empty();
unset($tmp, $diff); unset($tmp, $diff);
@ -938,12 +996,23 @@ class install_update extends module
} }
// if the file is modified we try to make sure a merge succeed // if the file is modified we try to make sure a merge succeed
$diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $file), file($this->new_location . $original_file)); $tmp = array(
'file1' => file_get_contents($this->old_location . $original_file),
'file2' => file_get_contents($phpbb_root_path . $file),
'file3' => file_get_contents($this->new_location . $original_file),
);
$diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3'], false);
unset($tmp);
if ($diff->merged_output(false, false, false, true)) if ($diff->merged_output(false, false, false, true))
{ {
$update_ary['conflicts'] = $diff->_conflicting_blocks; $update_ary['conflicts'] = $diff->_conflicting_blocks;
$update_list['conflict'][] = $update_ary; $update_list['conflict'][] = $update_ary;
unset($diff);
return; return;
} }
@ -953,7 +1022,7 @@ class install_update extends module
); );
// now compare the merged output with the original file to see if the modified file is up to date // now compare the merged output with the original file to see if the modified file is up to date
$diff = &new diff($tmp['file1'], $tmp['file2']); $diff = &new diff($tmp['file1'], $tmp['file2'], false);
$empty = $diff->is_empty(); $empty = $diff->is_empty();
if ($empty) if ($empty)