b2evolution PHP Cross Reference Blogging Systems

Source: /inc/_ext/phpsvnclient/ext/Diff/Diff/Engine/shell.php - 167 lines - 5356 bytes - Summary - Text - Print

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

title

Description

title

Description

title

Description

title

title

Body