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