Text_Diff_Engine_shell

Class used internally by Diff to actually compute the diffs.

Defined (1)

The class is defined in the following location(s).

/wp-includes/Text/Diff/Engine/shell.php  
  1. class Text_Diff_Engine_shell { 
  2.  
  3. /** 
  4. * Path to the diff executable 
  5. * @var string 
  6. */ 
  7. var $_diffCommand = 'diff'; 
  8.  
  9. /** 
  10. * Returns the array of differences. 
  11. * @param array $from_lines lines of text from old file 
  12. * @param array $to_lines lines of text from new file 
  13. * @return array all changes made (array with Text_Diff_Op_* objects) 
  14. */ 
  15. function diff($from_lines, $to_lines) 
  16. array_walk($from_lines, array('Text_Diff', 'trimNewlines')); 
  17. array_walk($to_lines, array('Text_Diff', 'trimNewlines')); 
  18.  
  19. $temp_dir = Text_Diff::_getTempDir(); 
  20.  
  21. // Execute gnu diff or similar to get a standard diff file. 
  22. $from_file = tempnam($temp_dir, 'Text_Diff'); 
  23. $to_file = tempnam($temp_dir, 'Text_Diff'); 
  24. $fp = fopen($from_file, 'w'); 
  25. fwrite($fp, implode("\n", $from_lines)); 
  26. fclose($fp); 
  27. $fp = fopen($to_file, 'w'); 
  28. fwrite($fp, implode("\n", $to_lines)); 
  29. fclose($fp); 
  30. $diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file); 
  31. unlink($from_file); 
  32. unlink($to_file); 
  33.  
  34. if (is_null($diff)) { 
  35. // No changes were made 
  36. return array(new Text_Diff_Op_copy($from_lines)); 
  37.  
  38. $from_line_no = 1; 
  39. $to_line_no = 1; 
  40. $edits = array(); 
  41.  
  42. // Get changed lines by parsing something like: 
  43. // 0a1, 2 
  44. // 1, 2c4, 6 
  45. // 1, 5d6 
  46. preg_match_all('#^(\d+)(?:, (\d+))?([adc])(\d+)(?:, (\d+))?$#m', $diff,  
  47. $matches, PREG_SET_ORDER); 
  48.  
  49. foreach ($matches as $match) { 
  50. if (!isset($match[5])) { 
  51. // This paren is not set every time (see regex). 
  52. $match[5] = false; 
  53.  
  54. if ($match[3] == 'a') { 
  55. $from_line_no--; 
  56.  
  57. if ($match[3] == 'd') { 
  58. $to_line_no--; 
  59.  
  60. if ($from_line_no < $match[1] || $to_line_no < $match[4]) { 
  61. // copied lines 
  62. assert('$match[1] - $from_line_no == $match[4] - $to_line_no'); 
  63. array_push($edits,  
  64. new Text_Diff_Op_copy( 
  65. $this->_getLines($from_lines, $from_line_no, $match[1] - 1),  
  66. $this->_getLines($to_lines, $to_line_no, $match[4] - 1))); 
  67.  
  68. switch ($match[3]) { 
  69. case 'd': 
  70. // deleted lines 
  71. array_push($edits,  
  72. new Text_Diff_Op_delete( 
  73. $this->_getLines($from_lines, $from_line_no, $match[2]))); 
  74. $to_line_no++; 
  75. break; 
  76.  
  77. case 'c': 
  78. // changed lines 
  79. array_push($edits,  
  80. new Text_Diff_Op_change( 
  81. $this->_getLines($from_lines, $from_line_no, $match[2]),  
  82. $this->_getLines($to_lines, $to_line_no, $match[5]))); 
  83. break; 
  84.  
  85. case 'a': 
  86. // added lines 
  87. array_push($edits,  
  88. new Text_Diff_Op_add( 
  89. $this->_getLines($to_lines, $to_line_no, $match[5]))); 
  90. $from_line_no++; 
  91. break; 
  92.  
  93. if (!empty($from_lines)) { 
  94. // Some lines might still be pending. Add them as copied 
  95. array_push($edits,  
  96. new Text_Diff_Op_copy( 
  97. $this->_getLines($from_lines, $from_line_no,  
  98. $from_line_no + count($from_lines) - 1),  
  99. $this->_getLines($to_lines, $to_line_no,  
  100. $to_line_no + count($to_lines) - 1))); 
  101.  
  102. return $edits; 
  103.  
  104. /** 
  105. * Get lines from either the old or new text 
  106. * @access private 
  107. * @param array &$text_lines Either $from_lines or $to_lines 
  108. * @param int &$line_no Current line number 
  109. * @param int $end Optional end line, when we want to chop more 
  110. * than one line. 
  111. * @return array The chopped lines 
  112. */ 
  113. function _getLines(&$text_lines, &$line_no, $end = false) 
  114. if (!empty($end)) { 
  115. $lines = array(); 
  116. // We can shift even more 
  117. while ($line_no <= $end) { 
  118. array_push($lines, array_shift($text_lines)); 
  119. $line_no++; 
  120. } else { 
  121. $lines = array(array_shift($text_lines)); 
  122. $line_no++; 
  123.  
  124. return $lines; 
  125.