Text_Diff
[ class tree: Text_Diff ] [ index: Text_Diff ] [ all elements ]

Source for file shell.php

Documentation is available at shell.php

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

Documentation generated on Mon, 11 Mar 2019 16:03:27 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.