[ Index ]

PHP Cross Reference of MyBB 1.6.7

title

Body

[close]

/inc/3rdparty/diff/ -> Diff3.php (source)

   1  <?php
   2  /**
   3   * A class for computing three way diffs.
   4   *
   5   * $Horde: framework/Text_Diff/Diff3.php,v 1.2.10.6 2008/01/04 10:37:26 jan Exp $
   6   *
   7   * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
   8   *
   9   * See the enclosed file COPYING for license information (LGPL). If you did
  10   * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
  11   *
  12   * @package Text_Diff
  13   * @since   0.3.0
  14   */
  15   
  16  // Disallow direct access to this file for security reasons
  17  if(!defined("IN_MYBB"))
  18  {
  19      die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
  20  }
  21  
  22  /** Text_Diff */
  23  require_once  MYBB_ROOT.'inc/3rdparty/diff/Diff.php';
  24  
  25  /**
  26   * A class for computing three way diffs.
  27   *
  28   * @package Text_Diff
  29   * @author  Geoffrey T. Dairiki <dairiki@dairiki.org>
  30   */
  31  class Text_Diff3 extends Text_Diff {
  32  
  33      /**
  34       * Conflict counter.
  35       *
  36       * @var integer
  37       */
  38      var $_conflictingBlocks = 0;
  39  
  40      /**
  41       * Computes diff between 3 sequences of strings.
  42       *
  43       * @param array $orig    The original lines to use.
  44       * @param array $final1  The first version to compare to.
  45       * @param array $final2  The second version to compare to.
  46       */
  47      function Text_Diff3($orig, $final1, $final2)
  48      {
  49          if (extension_loaded('xdiff')) {
  50              $engine = new Text_Diff_Engine_xdiff();
  51          } else {
  52              $engine = new Text_Diff_Engine_native();
  53          }
  54  
  55          $this->_edits = $this->_diff3($engine->diff($orig, $final1),
  56                                        $engine->diff($orig, $final2));
  57      }
  58  
  59      /**
  60       */
  61      function mergedOutput($label1 = false, $label2 = false)
  62      {
  63          $lines = array();
  64          foreach ($this->_edits as $edit) {
  65              if ($edit->isConflict()) {
  66                  /* FIXME: this should probably be moved somewhere else. */
  67                  $lines = array_merge($lines,
  68                                       array('<<<<<<<' . ($label1 ? ' ' . $label1 : '')),
  69                                       $edit->final1,
  70                                       array("======="),
  71                                       $edit->final2,
  72                                       array('>>>>>>>' . ($label2 ? ' ' . $label2 : '')));
  73                  $this->_conflictingBlocks++;
  74              } else {
  75                  $lines = array_merge($lines, $edit->merged());
  76              }
  77          }
  78  
  79          return $lines;
  80      }
  81  
  82      /**
  83       * @access private
  84       */
  85      function _diff3($edits1, $edits2)
  86      {
  87          $edits = array();
  88          $bb = new Text_Diff3_BlockBuilder();
  89  
  90          $e1 = current($edits1);
  91          $e2 = current($edits2);
  92          while ($e1 || $e2) {
  93              if ($e1 && $e2 && is_a($e1, 'Text_Diff_Op_copy') && is_a($e2, 'Text_Diff_Op_copy')) {
  94                  /* We have copy blocks from both diffs. This is the (only)
  95                   * time we want to emit a diff3 copy block.  Flush current
  96                   * diff3 diff block, if any. */
  97                  if ($edit = $bb->finish()) {
  98                      $edits[] = $edit;
  99                  }
 100  
 101                  $ncopy = min($e1->norig(), $e2->norig());
 102                  assert($ncopy > 0);
 103                  $edits[] = new Text_Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
 104  
 105                  if ($e1->norig() > $ncopy) {
 106                      array_splice($e1->orig, 0, $ncopy);
 107                      array_splice($e1->final, 0, $ncopy);
 108                  } else {
 109                      $e1 = next($edits1);
 110                  }
 111  
 112                  if ($e2->norig() > $ncopy) {
 113                      array_splice($e2->orig, 0, $ncopy);
 114                      array_splice($e2->final, 0, $ncopy);
 115                  } else {
 116                      $e2 = next($edits2);
 117                  }
 118              } else {
 119                  if ($e1 && $e2) {
 120                      if ($e1->orig && $e2->orig) {
 121                          $norig = min($e1->norig(), $e2->norig());
 122                          $orig = array_splice($e1->orig, 0, $norig);
 123                          array_splice($e2->orig, 0, $norig);
 124                          $bb->input($orig);
 125                      }
 126  
 127                      if (is_a($e1, 'Text_Diff_Op_copy')) {
 128                          $bb->out1(array_splice($e1->final, 0, $norig));
 129                      }
 130  
 131                      if (is_a($e2, 'Text_Diff_Op_copy')) {
 132                          $bb->out2(array_splice($e2->final, 0, $norig));
 133                      }
 134                  }
 135  
 136                  if ($e1 && ! $e1->orig) {
 137                      $bb->out1($e1->final);
 138                      $e1 = next($edits1);
 139                  }
 140                  if ($e2 && ! $e2->orig) {
 141                      $bb->out2($e2->final);
 142                      $e2 = next($edits2);
 143                  }
 144              }
 145          }
 146  
 147          if ($edit = $bb->finish()) {
 148              $edits[] = $edit;
 149          }
 150  
 151          return $edits;
 152      }
 153  
 154  }
 155  
 156  /**
 157   * @package Text_Diff
 158   * @author  Geoffrey T. Dairiki <dairiki@dairiki.org>
 159   *
 160   * @access private
 161   */
 162  class Text_Diff3_Op {
 163  
 164      function Text_Diff3_Op($orig = false, $final1 = false, $final2 = false)
 165      {
 166          $this->orig = $orig ? $orig : array();
 167          $this->final1 = $final1 ? $final1 : array();
 168          $this->final2 = $final2 ? $final2 : array();
 169      }
 170  
 171      function merged()
 172      {
 173          if (!isset($this->_merged)) {
 174              if ($this->final1 === $this->final2) {
 175                  $this->_merged = &$this->final1;
 176              } elseif ($this->final1 === $this->orig) {
 177                  $this->_merged = &$this->final2;
 178              } elseif ($this->final2 === $this->orig) {
 179                  $this->_merged = &$this->final1;
 180              } else {
 181                  $this->_merged = false;
 182              }
 183          }
 184  
 185          return $this->_merged;
 186      }
 187  
 188      function isConflict()
 189      {
 190          return $this->merged() === false;
 191      }
 192  
 193  }
 194  
 195  /**
 196   * @package Text_Diff
 197   * @author  Geoffrey T. Dairiki <dairiki@dairiki.org>
 198   *
 199   * @access private
 200   */
 201  class Text_Diff3_Op_copy extends Text_Diff3_Op {
 202  
 203      function Text_Diff3_Op_Copy($lines = false)
 204      {
 205          $this->orig = $lines ? $lines : array();
 206          $this->final1 = &$this->orig;
 207          $this->final2 = &$this->orig;
 208      }
 209  
 210      function merged()
 211      {
 212          return $this->orig;
 213      }
 214  
 215      function isConflict()
 216      {
 217          return false;
 218      }
 219  
 220  }
 221  
 222  /**
 223   * @package Text_Diff
 224   * @author  Geoffrey T. Dairiki <dairiki@dairiki.org>
 225   *
 226   * @access private
 227   */
 228  class Text_Diff3_BlockBuilder {
 229  
 230      function Text_Diff3_BlockBuilder()
 231      {
 232          $this->_init();
 233      }
 234  
 235      function input($lines)
 236      {
 237          if ($lines) {
 238              $this->_append($this->orig, $lines);
 239          }
 240      }
 241  
 242      function out1($lines)
 243      {
 244          if ($lines) {
 245              $this->_append($this->final1, $lines);
 246          }
 247      }
 248  
 249      function out2($lines)
 250      {
 251          if ($lines) {
 252              $this->_append($this->final2, $lines);
 253          }
 254      }
 255  
 256      function isEmpty()
 257      {
 258          return !$this->orig && !$this->final1 && !$this->final2;
 259      }
 260  
 261      function finish()
 262      {
 263          if ($this->isEmpty()) {
 264              return false;
 265          } else {
 266              $edit = new Text_Diff3_Op($this->orig, $this->final1, $this->final2);
 267              $this->_init();
 268              return $edit;
 269          }
 270      }
 271  
 272      function _init()
 273      {
 274          $this->orig = $this->final1 = $this->final2 = array();
 275      }
 276  
 277      function _append(&$array, $lines)
 278      {
 279          array_splice($array, sizeof($array), 0, $lines);
 280      }
 281  
 282  }


Generated: Sat Mar 31 17:55:03 2012 Cross-referenced by PHPXref 0.7.1