| | <?php |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | class Text_Diff_Engine_shell { |
| |
|
| | |
| | |
| | |
| | |
| | |
| | var $_diffCommand = 'diff'; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | 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(); |
| |
|
| | |
| | $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)) { |
| | |
| | return array(new Text_Diff_Op_copy($from_lines)); |
| | } |
| |
|
| | $from_line_no = 1; |
| | $to_line_no = 1; |
| | $edits = array(); |
| |
|
| | |
| | |
| | |
| | |
| | preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff, |
| | $matches, PREG_SET_ORDER); |
| |
|
| | foreach ($matches as $match) { |
| | if (!isset($match[5])) { |
| | |
| | $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]) { |
| | |
| | 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': |
| | |
| | array_push($edits, |
| | new Text_Diff_Op_delete( |
| | $this->_getLines($from_lines, $from_line_no, $match[2]))); |
| | $to_line_no++; |
| | break; |
| |
|
| | case 'c': |
| | |
| | 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': |
| | |
| | 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)) { |
| | |
| | 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; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | function _getLines(&$text_lines, &$line_no, $end = false) |
| | { |
| | if (!empty($end)) { |
| | $lines = array(); |
| | |
| | while ($line_no <= $end) { |
| | array_push($lines, array_shift($text_lines)); |
| | $line_no++; |
| | } |
| | } else { |
| | $lines = array(array_shift($text_lines)); |
| | $line_no++; |
| | } |
| |
|
| | return $lines; |
| | } |
| |
|
| | } |
| |
|