[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/3rdparty/diff/Diff/Engine/ -> String.php (source)

   1  <?php
   2  /**
   3   * Parses unified or context diffs output from eg. the diff utility.
   4   *
   5   * Example:
   6   * <code>
   7   * $patch = file_get_contents('example.patch');
   8   * $diff = new Horde_Text_Diff('string', array($patch));
   9   * $renderer = new Horde_Text_Diff_Renderer_inline();
  10   * echo $renderer->render($diff);
  11   * </code>
  12   *
  13   * Copyright 2005 Örjan Persson <o@42mm.org>
  14   * Copyright 2005-2011 Horde LLC (http://www.horde.org/)
  15   *
  16   * See the enclosed file COPYING for license information (LGPL). If you did
  17   * not receive this file, see http://www.horde.org/licenses/lgpl21.
  18   *
  19   * @author  Örjan Persson <o@42mm.org>
  20   * @package Text_Diff
  21   */
  22  
  23  // Disallow direct access to this file for security reasons
  24  if(!defined("IN_MYBB"))
  25  {
  26      die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
  27  }
  28  
  29  class Horde_Text_Diff_Engine_String
  30  {
  31      /**
  32       * Parses a unified or context diff.
  33       *
  34       * First param contains the whole diff and the second can be used to force
  35       * a specific diff type. If the second parameter is 'autodetect', the
  36       * diff will be examined to find out which type of diff this is.
  37       *
  38       * @param string $diff  The diff content.
  39       * @param string $mode  The diff mode of the content in $diff. One of
  40       *                      'context', 'unified', or 'autodetect'.
  41       *
  42       * @return array  List of all diff operations.
  43       * @throws Horde_Text_Diff_Exception
  44       */
  45      public function diff($diff, $mode = 'autodetect')
  46      {
  47          // Detect line breaks.
  48          $lnbr = "\n";
  49          if (strpos($diff, "\r\n") !== false) {
  50              $lnbr = "\r\n";
  51          } elseif (strpos($diff, "\r") !== false) {
  52              $lnbr = "\r";
  53          }
  54  
  55          // Make sure we have a line break at the EOF.
  56          if (substr($diff, -strlen($lnbr)) != $lnbr) {
  57              $diff .= $lnbr;
  58          }
  59  
  60          if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified') {
  61              throw new Horde_Text_Diff_Exception('Type of diff is unsupported');
  62          }
  63  
  64          if ($mode == 'autodetect') {
  65              $context = strpos($diff, '***');
  66              $unified = strpos($diff, '---');
  67              if ($context === $unified) {
  68                  throw new Horde_Text_Diff_Exception('Type of diff could not be detected');
  69              } elseif ($context === false || $unified === false) {
  70                  $mode = $context !== false ? 'context' : 'unified';
  71              } else {
  72                  $mode = $context < $unified ? 'context' : 'unified';
  73              }
  74          }
  75  
  76          // Split by new line and remove the diff header, if there is one.
  77          $diff = explode($lnbr, $diff);
  78          if (($mode == 'context' && strpos($diff[0], '***') === 0) ||
  79              ($mode == 'unified' && strpos($diff[0], '---') === 0)) {
  80              array_shift($diff);
  81              array_shift($diff);
  82          }
  83  
  84          if ($mode == 'context') {
  85              return $this->parseContextDiff($diff);
  86          } else {
  87              return $this->parseUnifiedDiff($diff);
  88          }
  89      }
  90  
  91      /**
  92       * Parses an array containing the unified diff.
  93       *
  94       * @param array $diff  Array of lines.
  95       *
  96       * @return array  List of all diff operations.
  97       */
  98      public function parseUnifiedDiff($diff)
  99      {
 100          $edits = array();
 101          $end = count($diff) - 1;
 102          for ($i = 0; $i < $end;) {
 103              $diff1 = array();
 104              switch (substr($diff[$i], 0, 1)) {
 105              case ' ':
 106                  do {
 107                      $diff1[] = substr($diff[$i], 1);
 108                  } while (++$i < $end && substr($diff[$i], 0, 1) == ' ');
 109                  $edits[] = new Horde_Text_Diff_Op_Copy($diff1);
 110                  break;
 111  
 112              case '+':
 113                  // get all new lines
 114                  do {
 115                      $diff1[] = substr($diff[$i], 1);
 116                  } while (++$i < $end && substr($diff[$i], 0, 1) == '+');
 117                  $edits[] = new Horde_Text_Diff_Op_Add($diff1);
 118                  break;
 119  
 120              case '-':
 121                  // get changed or removed lines
 122                  $diff2 = array();
 123                  do {
 124                      $diff1[] = substr($diff[$i], 1);
 125                  } while (++$i < $end && substr($diff[$i], 0, 1) == '-');
 126  
 127                  while ($i < $end && substr($diff[$i], 0, 1) == '+') {
 128                      $diff2[] = substr($diff[$i++], 1);
 129                  }
 130                  if (count($diff2) == 0) {
 131                      $edits[] = new Horde_Text_Diff_Op_Delete($diff1);
 132                  } else {
 133                      $edits[] = new Horde_Text_Diff_Op_Change($diff1, $diff2);
 134                  }
 135                  break;
 136  
 137              default:
 138                  $i++;
 139                  break;
 140              }
 141          }
 142  
 143          return $edits;
 144      }
 145  
 146      /**
 147       * Parses an array containing the context diff.
 148       *
 149       * @param array $diff  Array of lines.
 150       *
 151       * @return array  List of all diff operations.
 152       */
 153      public function parseContextDiff(&$diff)
 154      {
 155          $edits = array();
 156          $i = $max_i = $j = $max_j = 0;
 157          $end = count($diff) - 1;
 158          while ($i < $end && $j < $end) {
 159              while ($i >= $max_i && $j >= $max_j) {
 160                  // Find the boundaries of the diff output of the two files
 161                  for ($i = $j;
 162                       $i < $end && substr($diff[$i], 0, 3) == '***';
 163                       $i++);
 164                  for ($max_i = $i;
 165                       $max_i < $end && substr($diff[$max_i], 0, 3) != '---';
 166                       $max_i++);
 167                  for ($j = $max_i;
 168                       $j < $end && substr($diff[$j], 0, 3) == '---';
 169                       $j++);
 170                  for ($max_j = $j;
 171                       $max_j < $end && substr($diff[$max_j], 0, 3) != '***';
 172                       $max_j++);
 173              }
 174  
 175              // find what hasn't been changed
 176              $array = array();
 177              while ($i < $max_i &&
 178                     $j < $max_j &&
 179                     strcmp($diff[$i], $diff[$j]) == 0) {
 180                  $array[] = substr($diff[$i], 2);
 181                  $i++;
 182                  $j++;
 183              }
 184  
 185              while ($i < $max_i && ($max_j-$j) <= 1) {
 186                  if ($diff[$i] != '' && substr($diff[$i], 0, 1) != ' ') {
 187                      break;
 188                  }
 189                  $array[] = substr($diff[$i++], 2);
 190              }
 191  
 192              while ($j < $max_j && ($max_i-$i) <= 1) {
 193                  if ($diff[$j] != '' && substr($diff[$j], 0, 1) != ' ') {
 194                      break;
 195                  }
 196                  $array[] = substr($diff[$j++], 2);
 197              }
 198              if (count($array) > 0) {
 199                  $edits[] = new Horde_Text_Diff_Op_Copy($array);
 200              }
 201  
 202              if ($i < $max_i) {
 203                  $diff1 = array();
 204                  switch (substr($diff[$i], 0, 1)) {
 205                  case '!':
 206                      $diff2 = array();
 207                      do {
 208                          $diff1[] = substr($diff[$i], 2);
 209                          if ($j < $max_j && substr($diff[$j], 0, 1) == '!') {
 210                              $diff2[] = substr($diff[$j++], 2);
 211                          }
 212                      } while (++$i < $max_i && substr($diff[$i], 0, 1) == '!');
 213                      $edits[] = new Horde_Text_Diff_Op_Change($diff1, $diff2);
 214                      break;
 215  
 216                  case '+':
 217                      do {
 218                          $diff1[] = substr($diff[$i], 2);
 219                      } while (++$i < $max_i && substr($diff[$i], 0, 1) == '+');
 220                      $edits[] = new Horde_Text_Diff_Op_Add($diff1);
 221                      break;
 222  
 223                  case '-':
 224                      do {
 225                          $diff1[] = substr($diff[$i], 2);
 226                      } while (++$i < $max_i && substr($diff[$i], 0, 1) == '-');
 227                      $edits[] = new Horde_Text_Diff_Op_Delete($diff1);
 228                      break;
 229                  }
 230              }
 231  
 232              if ($j < $max_j) {
 233                  $diff2 = array();
 234                  switch (substr($diff[$j], 0, 1)) {
 235                  case '+':
 236                      do {
 237                          $diff2[] = substr($diff[$j++], 2);
 238                      } while ($j < $max_j && substr($diff[$j], 0, 1) == '+');
 239                      $edits[] = new Horde_Text_Diff_Op_Add($diff2);
 240                      break;
 241  
 242                  case '-':
 243                      do {
 244                          $diff2[] = substr($diff[$j++], 2);
 245                      } while ($j < $max_j && substr($diff[$j], 0, 1) == '-');
 246                      $edits[] = new Horde_Text_Diff_Op_Delete($diff2);
 247                      break;
 248                  }
 249              }
 250          }
 251  
 252          return $edits;
 253      }
 254  }


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1