[ Index ]
 

Code source de Horde 3.1.3

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/Text/ -> Diff3.php (source)

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


Généré le : Sun Feb 25 18:01:28 2007 par Balluche grâce à PHPXref 0.7