Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmpage committed Nov 23, 2011
0 parents commit 50fbecd
Show file tree
Hide file tree
Showing 19 changed files with 3,286 additions and 0 deletions.
Binary file added Text/.DS_Store
Binary file not shown.
453 changes: 453 additions & 0 deletions Text/Diff.php

Large diffs are not rendered by default.

Binary file added Text/Diff/.DS_Store
Binary file not shown.
Binary file added Text/Diff/Engine/.DS_Store
Binary file not shown.
438 changes: 438 additions & 0 deletions Text/Diff/Engine/native.php

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions Text/Diff/Engine/shell.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php
/**
* Class used internally by Diff to actually compute the diffs.
*
* This class uses the Unix `diff` program via shell_exec to compute the
* differences between the two input arrays.
*
* $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.6.2.4 2009/01/06 15:23:41 jan Exp $
*
* Copyright 2007-2009 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you did
* not receive this file, see http://opensource.org/licenses/lgpl-license.php.
*
* @author Milian Wolff <[email protected]>
* @package Text_Diff
* @since 0.3.0
*/
class Text_Diff_Engine_shell {

/**
* Path to the diff executable
*
* @var string
*/
var $_diffCommand = 'diff';

/**
* Returns the array of differences.
*
* @param array $from_lines lines of text from old file
* @param array $to_lines lines of text from new file
*
* @return array all changes made (array with Text_Diff_Op_* objects)
*/
function diff($from_lines, $to_lines)
{
array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
array_walk($to_lines, array('Text_Diff', 'trimNewlines'));

$temp_dir = Text_Diff::_getTempDir();

// Execute gnu diff or similar to get a standard diff file.
$from_file = tempnam($temp_dir, 'Text_Diff');
$to_file = tempnam($temp_dir, 'Text_Diff');
$fp = fopen($from_file, 'w');
fwrite($fp, implode("\n", $from_lines));
fclose($fp);
$fp = fopen($to_file, 'w');
fwrite($fp, implode("\n", $to_lines));
fclose($fp);
$diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file);
unlink($from_file);
unlink($to_file);

if (is_null($diff)) {
// No changes were made
return array(new Text_Diff_Op_copy($from_lines));
}

$from_line_no = 1;
$to_line_no = 1;
$edits = array();

// Get changed lines by parsing something like:
// 0a1,2
// 1,2c4,6
// 1,5d6
preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff,
$matches, PREG_SET_ORDER);

foreach ($matches as $match) {
if (!isset($match[5])) {
// This paren is not set every time (see regex).
$match[5] = false;
}

if ($match[3] == 'a') {
$from_line_no--;
}

if ($match[3] == 'd') {
$to_line_no--;
}

if ($from_line_no < $match[1] || $to_line_no < $match[4]) {
// copied lines
assert('$match[1] - $from_line_no == $match[4] - $to_line_no');
array_push($edits,
new Text_Diff_Op_copy(
$this->_getLines($from_lines, $from_line_no, $match[1] - 1),
$this->_getLines($to_lines, $to_line_no, $match[4] - 1)));
}

switch ($match[3]) {
case 'd':
// deleted lines
array_push($edits,
new Text_Diff_Op_delete(
$this->_getLines($from_lines, $from_line_no, $match[2])));
$to_line_no++;
break;

case 'c':
// changed lines
array_push($edits,
new Text_Diff_Op_change(
$this->_getLines($from_lines, $from_line_no, $match[2]),
$this->_getLines($to_lines, $to_line_no, $match[5])));
break;

case 'a':
// added lines
array_push($edits,
new Text_Diff_Op_add(
$this->_getLines($to_lines, $to_line_no, $match[5])));
$from_line_no++;
break;
}
}

if (!empty($from_lines)) {
// Some lines might still be pending. Add them as copied
array_push($edits,
new Text_Diff_Op_copy(
$this->_getLines($from_lines, $from_line_no,
$from_line_no + count($from_lines) - 1),
$this->_getLines($to_lines, $to_line_no,
$to_line_no + count($to_lines) - 1)));
}

return $edits;
}

/**
* Get lines from either the old or new text
*
* @access private
*
* @param array &$text_lines Either $from_lines or $to_lines
* @param int &$line_no Current line number
* @param int $end Optional end line, when we want to chop more
* than one line.
*
* @return array The chopped lines
*/
function _getLines(&$text_lines, &$line_no, $end = false)
{
if (!empty($end)) {
$lines = array();
// We can shift even more
while ($line_no <= $end) {
array_push($lines, array_shift($text_lines));
$line_no++;
}
} else {
$lines = array(array_shift($text_lines));
$line_no++;
}

return $lines;
}

}
Loading

0 comments on commit 50fbecd

Please sign in to comment.