[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Class used internally by Diff to actually compute the diffs. 4 * 5 * This class uses the Unix `diff` program via shell_exec to compute the 6 * differences between the two input arrays. 7 * 8 * Copyright 2007-2010 The Horde Project (http://www.horde.org/) 9 * 10 * See the enclosed file COPYING for license information (LGPL). If you did 11 * not receive this file, see http://opensource.org/licenses/lgpl-license.php. 12 * 13 * @author Milian Wolff <mail@milianw.de> 14 * @package Text_Diff 15 * @since 0.3.0 16 */ 17 class Text_Diff_Engine_shell { 18 19 /** 20 * Path to the diff executable 21 * 22 * @var string 23 */ 24 var $_diffCommand = 'diff'; 25 26 /** 27 * Returns the array of differences. 28 * 29 * @param array $from_lines lines of text from old file 30 * @param array $to_lines lines of text from new file 31 * 32 * @return array all changes made (array with Text_Diff_Op_* objects) 33 */ 34 function diff($from_lines, $to_lines) 35 { 36 array_walk($from_lines, array('Text_Diff', 'trimNewlines')); 37 array_walk($to_lines, array('Text_Diff', 'trimNewlines')); 38 39 $temp_dir = Text_Diff::_getTempDir(); 40 41 // Execute gnu diff or similar to get a standard diff file. 42 $from_file = tempnam($temp_dir, 'Text_Diff'); 43 $to_file = tempnam($temp_dir, 'Text_Diff'); 44 $fp = fopen($from_file, 'w'); 45 fwrite($fp, implode("\n", $from_lines)); 46 fclose($fp); 47 $fp = fopen($to_file, 'w'); 48 fwrite($fp, implode("\n", $to_lines)); 49 fclose($fp); 50 $diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file); 51 unlink($from_file); 52 unlink($to_file); 53 54 if (is_null($diff)) { 55 // No changes were made 56 return array(new Text_Diff_Op_copy($from_lines)); 57 } 58 59 $from_line_no = 1; 60 $to_line_no = 1; 61 $edits = array(); 62 63 // Get changed lines by parsing something like: 64 // 0a1,2 65 // 1,2c4,6 66 // 1,5d6 67 preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff, 68 $matches, PREG_SET_ORDER); 69 70 foreach ($matches as $match) { 71 if (!isset($match[5])) { 72 // This paren is not set every time (see regex). 73 $match[5] = false; 74 } 75 76 if ($match[3] == 'a') { 77 $from_line_no--; 78 } 79 80 if ($match[3] == 'd') { 81 $to_line_no--; 82 } 83 84 if ($from_line_no < $match[1] || $to_line_no < $match[4]) { 85 // copied lines 86 assert($match[1] - $from_line_no == $match[4] - $to_line_no); 87 array_push($edits, 88 new Text_Diff_Op_copy( 89 $this->_getLines($from_lines, $from_line_no, $match[1] - 1), 90 $this->_getLines($to_lines, $to_line_no, $match[4] - 1))); 91 } 92 93 switch ($match[3]) { 94 case 'd': 95 // deleted lines 96 array_push($edits, 97 new Text_Diff_Op_delete( 98 $this->_getLines($from_lines, $from_line_no, $match[2]))); 99 $to_line_no++; 100 break; 101 102 case 'c': 103 // changed lines 104 array_push($edits, 105 new Text_Diff_Op_change( 106 $this->_getLines($from_lines, $from_line_no, $match[2]), 107 $this->_getLines($to_lines, $to_line_no, $match[5]))); 108 break; 109 110 case 'a': 111 // added lines 112 array_push($edits, 113 new Text_Diff_Op_add( 114 $this->_getLines($to_lines, $to_line_no, $match[5]))); 115 $from_line_no++; 116 break; 117 } 118 } 119 120 if (!empty($from_lines)) { 121 // Some lines might still be pending. Add them as copied 122 array_push($edits, 123 new Text_Diff_Op_copy( 124 $this->_getLines($from_lines, $from_line_no, 125 $from_line_no + count($from_lines) - 1), 126 $this->_getLines($to_lines, $to_line_no, 127 $to_line_no + count($to_lines) - 1))); 128 } 129 130 return $edits; 131 } 132 133 /** 134 * Get lines from either the old or new text 135 * 136 * @access private 137 * 138 * @param array $text_lines Either $from_lines or $to_lines (passed by reference). 139 * @param int $line_no Current line number (passed by reference). 140 * @param int $end Optional end line, when we want to chop more 141 * than one line. 142 * 143 * @return array The chopped lines 144 */ 145 function _getLines(&$text_lines, &$line_no, $end = false) 146 { 147 if (!empty($end)) { 148 $lines = array(); 149 // We can shift even more 150 while ($line_no <= $end) { 151 array_push($lines, array_shift($text_lines)); 152 $line_no++; 153 } 154 } else { 155 $lines = array(array_shift($text_lines)); 156 $line_no++; 157 } 158 159 return $lines; 160 } 161 162 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Nov 21 01:00:03 2024 | Cross-referenced by PHPXref 0.7.1 |