[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-includes/Text/Diff/Engine/ -> shell.php (source)

   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  }


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7