-
+ 1EFDA8C6B8B6B764827F69CDC2C94EEDC00C0F9452F0DCADA89AC0A4C188A8183D9EDBDD4AD188402AB693D18E9C45F66115577F5D8F4692D80CE82D8170DC12
mp-wp/wp-includes/Text/Diff/Engine/shell.php
(0 . 0)(1 . 164)
69530 <?php
69531 /**
69532 * Class used internally by Diff to actually compute the diffs.
69533 *
69534 * This class uses the Unix `diff` program via shell_exec to compute the
69535 * differences between the two input arrays.
69536 *
69537 * $Horde: framework/Text_Diff/Diff/Engine/shell.php,v 1.8 2008/01/04 10:07:50 jan Exp $
69538 *
69539 * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
69540 *
69541 * See the enclosed file COPYING for license information (LGPL). If you did
69542 * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
69543 *
69544 * @author Milian Wolff <mail@milianw.de>
69545 * @package Text_Diff
69546 * @since 0.3.0
69547 */
69548 class Text_Diff_Engine_shell {
69549
69550 /**
69551 * Path to the diff executable
69552 *
69553 * @var string
69554 */
69555 var $_diffCommand = 'diff';
69556
69557 /**
69558 * Returns the array of differences.
69559 *
69560 * @param array $from_lines lines of text from old file
69561 * @param array $to_lines lines of text from new file
69562 *
69563 * @return array all changes made (array with Text_Diff_Op_* objects)
69564 */
69565 function diff($from_lines, $to_lines)
69566 {
69567 array_walk($from_lines, array('Text_Diff', 'trimNewlines'));
69568 array_walk($to_lines, array('Text_Diff', 'trimNewlines'));
69569
69570 $temp_dir = Text_Diff::_getTempDir();
69571
69572 // Execute gnu diff or similar to get a standard diff file.
69573 $from_file = tempnam($temp_dir, 'Text_Diff');
69574 $to_file = tempnam($temp_dir, 'Text_Diff');
69575 $fp = fopen($from_file, 'w');
69576 fwrite($fp, implode("\n", $from_lines));
69577 fclose($fp);
69578 $fp = fopen($to_file, 'w');
69579 fwrite($fp, implode("\n", $to_lines));
69580 fclose($fp);
69581 $diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file);
69582 unlink($from_file);
69583 unlink($to_file);
69584
69585 if (is_null($diff)) {
69586 // No changes were made
69587 return array(new Text_Diff_Op_copy($from_lines));
69588 }
69589
69590 $from_line_no = 1;
69591 $to_line_no = 1;
69592 $edits = array();
69593
69594 // Get changed lines by parsing something like:
69595 // 0a1,2
69596 // 1,2c4,6
69597 // 1,5d6
69598 preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff,
69599 $matches, PREG_SET_ORDER);
69600
69601 foreach ($matches as $match) {
69602 if (!isset($match[5])) {
69603 // This paren is not set every time (see regex).
69604 $match[5] = false;
69605 }
69606
69607 if ($match[3] == 'a') {
69608 $from_line_no--;
69609 }
69610
69611 if ($match[3] == 'd') {
69612 $to_line_no--;
69613 }
69614
69615 if ($from_line_no < $match[1] || $to_line_no < $match[4]) {
69616 // copied lines
69617 assert('$match[1] - $from_line_no == $match[4] - $to_line_no');
69618 array_push($edits,
69619 new Text_Diff_Op_copy(
69620 $this->_getLines($from_lines, $from_line_no, $match[1] - 1),
69621 $this->_getLines($to_lines, $to_line_no, $match[4] - 1)));
69622 }
69623
69624 switch ($match[3]) {
69625 case 'd':
69626 // deleted lines
69627 array_push($edits,
69628 new Text_Diff_Op_delete(
69629 $this->_getLines($from_lines, $from_line_no, $match[2])));
69630 $to_line_no++;
69631 break;
69632
69633 case 'c':
69634 // changed lines
69635 array_push($edits,
69636 new Text_Diff_Op_change(
69637 $this->_getLines($from_lines, $from_line_no, $match[2]),
69638 $this->_getLines($to_lines, $to_line_no, $match[5])));
69639 break;
69640
69641 case 'a':
69642 // added lines
69643 array_push($edits,
69644 new Text_Diff_Op_add(
69645 $this->_getLines($to_lines, $to_line_no, $match[5])));
69646 $from_line_no++;
69647 break;
69648 }
69649 }
69650
69651 if (!empty($from_lines)) {
69652 // Some lines might still be pending. Add them as copied
69653 array_push($edits,
69654 new Text_Diff_Op_copy(
69655 $this->_getLines($from_lines, $from_line_no,
69656 $from_line_no + count($from_lines) - 1),
69657 $this->_getLines($to_lines, $to_line_no,
69658 $to_line_no + count($to_lines) - 1)));
69659 }
69660
69661 return $edits;
69662 }
69663
69664 /**
69665 * Get lines from either the old or new text
69666 *
69667 * @access private
69668 *
69669 * @param array &$text_lines Either $from_lines or $to_lines
69670 * @param int &$line_no Current line number
69671 * @param int $end Optional end line, when we want to chop more
69672 * than one line.
69673 *
69674 * @return array The chopped lines
69675 */
69676 function _getLines(&$text_lines, &$line_no, $end = false)
69677 {
69678 if (!empty($end)) {
69679 $lines = array();
69680 // We can shift even more
69681 while ($line_no <= $end) {
69682 array_push($lines, array_shift($text_lines));
69683 $line_no++;
69684 }
69685 } else {
69686 $lines = array(array_shift($text_lines));
69687 $line_no++;
69688 }
69689
69690 return $lines;
69691 }
69692
69693 }