[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/diff/ -> renderer.php (source)

   1  <?php
   2  /** 
   3  *
   4  * @package phpBB3
   5  * @version $Id: renderer.php,v 1.1 2006/08/22 21:29:45 acydburn Exp $
   6  * @copyright (c) 2006 phpBB Group 
   7  * @license http://opensource.org/licenses/gpl-license.php GNU Public License 
   8  *
   9  */
  10  
  11  /**
  12  */
  13  if (!defined('IN_PHPBB'))
  14  {
  15      exit;
  16  }
  17  
  18  /**
  19  * Code from pear.php.net, Text_Diff-0.2.1 (beta) package
  20  * http://pear.php.net/package/Text_Diff/
  21  *
  22  * Modified by Acyd Burn to meet our coding standards
  23  * and being able to integrate into phpBB
  24  */
  25  
  26  /**
  27  * A class to render Diffs in different formats.
  28  *
  29  * This class renders the diff in classic diff format. It is intended that
  30  * this class be customized via inheritance, to obtain fancier outputs.
  31  *
  32  * @package phpBB3
  33  */
  34  class diff_renderer
  35  {
  36      /**
  37      * Number of leading context "lines" to preserve.
  38      *
  39      * This should be left at zero for this class, but subclasses may want to
  40      * set this to other values.
  41      */
  42      var $_leading_context_lines = 0;
  43  
  44      /**
  45      * Number of trailing context "lines" to preserve.
  46      *
  47      * This should be left at zero for this class, but subclasses may want to
  48      * set this to other values.
  49      */
  50      var $_trailing_context_lines = 0;
  51  
  52      /**
  53      * Constructor.
  54      */
  55  	function diff_renderer($params = array())
  56      {
  57          foreach ($params as $param => $value)
  58          {
  59              $v = '_' . $param;
  60              if (isset($this->$v))
  61              {
  62                  $this->$v = $value;
  63              }
  64          }
  65      }
  66  
  67      /**
  68      * Get any renderer parameters.
  69      *
  70      * @return array  All parameters of this renderer object.
  71      */
  72  	function get_params()
  73      {
  74          $params = array();
  75          foreach (get_object_vars($this) as $k => $v)
  76          {
  77              if ($k[0] == '_')
  78              {
  79                  $params[substr($k, 1)] = $v;
  80              }
  81          }
  82  
  83          return $params;
  84      }
  85  
  86      /**
  87      * Renders a diff.
  88      *
  89      * @param diff $diff A diff object.
  90      *
  91      * @return string  The formatted output.
  92      */
  93  	function render(&$diff)
  94      {
  95          $xi = $yi = 1;
  96          $block = false;
  97          $context = array();
  98  
  99          // Create a new diff object if it is a 3-way diff
 100          if (is_a($diff, 'diff3'))
 101          {
 102              $diff3 = &$diff;
 103              $diff = &new diff($diff3->get_original(), $diff3->merged_output());
 104              unset($diff3);
 105          }
 106  
 107          $nlead = $this->_leading_context_lines;
 108          $ntrail = $this->_trailing_context_lines;
 109  
 110          $output = $this->_start_diff();
 111          $diffs = $diff->get_diff();
 112  
 113          foreach ($diffs as $i => $edit)
 114          {
 115              if (is_a($edit, 'diff_op_copy'))
 116              {
 117                  if (is_array($block))
 118                  {
 119                      $keep = ($i == sizeof($diffs) - 1) ? $ntrail : $nlead + $ntrail;
 120                      if (sizeof($edit->orig) <= $keep)
 121                      {
 122                          $block[] = $edit;
 123                      }
 124                      else
 125                      {
 126                          if ($ntrail)
 127                          {
 128                              $context = array_slice($edit->orig, 0, $ntrail);
 129                              $block[] = &new diff_op_copy($context);
 130                          }
 131  
 132                          $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
 133                          $block = false;
 134                      }
 135                  }
 136                  $context = $edit->orig;
 137              }
 138              else
 139              {
 140                  if (!is_array($block))
 141                  {
 142                      $context = array_slice($context, sizeof($context) - $nlead);
 143                      $x0 = $xi - sizeof($context);
 144                      $y0 = $yi - sizeof($context);
 145                      $block = array();
 146  
 147                      if ($context)
 148                      {
 149                          $block[] = &new diff_op_copy($context);
 150                      }
 151                  }
 152                  $block[] = $edit;
 153              }
 154  
 155              $xi += ($edit->orig) ? sizeof($edit->orig) : 0;
 156              $yi += ($edit->final) ? sizeof($edit->final) : 0;
 157          }
 158  
 159          if (is_array($block))
 160          {
 161              $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
 162          }
 163  
 164          return $output . $this->_end_diff();
 165      }
 166  
 167  	function _block($xbeg, $xlen, $ybeg, $ylen, &$edits)
 168      {
 169          $output = $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
 170  
 171          foreach ($edits as $edit)
 172          {
 173              switch (get_class($edit))
 174              {
 175                  case 'diff_op_copy':
 176                      $output .= $this->_context($edit->orig);
 177                  break;
 178  
 179                  case 'diff_op_add':
 180                      $output .= $this->_added($edit->final);
 181                  break;
 182  
 183                  case 'diff_op_delete':
 184                      $output .= $this->_deleted($edit->orig);
 185                  break;
 186  
 187                  case 'diff_op_change':
 188                      $output .= $this->_changed($edit->orig, $edit->final);
 189                  break;
 190              }
 191          }
 192  
 193          return $output . $this->_end_block();
 194      }
 195  
 196  	function _start_diff()
 197      {
 198          return '';
 199      }
 200  
 201  	function _end_diff()
 202      {
 203          return '';
 204      }
 205  
 206  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 207      {
 208          if ($xlen > 1)
 209          {
 210              $xbeg .= ',' . ($xbeg + $xlen - 1);
 211          }
 212  
 213          if ($ylen > 1)
 214          {
 215              $ybeg .= ',' . ($ybeg + $ylen - 1);
 216          }
 217  
 218          return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
 219      }
 220  
 221  	function _start_block($header)
 222      {
 223          return $header . "\n";
 224      }
 225  
 226  	function _end_block()
 227      {
 228          return '';
 229      }
 230  
 231  	function _lines($lines, $prefix = ' ')
 232      {
 233          return $prefix . implode("\n$prefix", $lines) . "\n";
 234      }
 235  
 236  	function _context($lines)
 237      {
 238          return $this->_lines($lines, '  ');
 239      }
 240  
 241  	function _added($lines)
 242      {
 243          return $this->_lines($lines, '> ');
 244      }
 245  
 246  	function _deleted($lines)
 247      {
 248          return $this->_lines($lines, '< ');
 249      }
 250  
 251  	function _changed($orig, $final)
 252      {
 253          return $this->_deleted($orig) . "---\n" . $this->_added($final);
 254      }
 255  
 256      /**
 257      * Our function to get the diff
 258      */
 259  	function get_diff_content($diff)
 260      {
 261          return $this->render($diff);
 262      }
 263  }
 264  
 265  /**
 266  * Renders a unified diff
 267  * @package phpBB3
 268  */
 269  class diff_renderer_unified extends diff_renderer 
 270  {
 271      var $_leading_context_lines = 4;
 272      var $_trailing_context_lines = 4;
 273  
 274      /**
 275      * Our function to get the diff
 276      */
 277  	function get_diff_content($diff)
 278      {
 279          return nl2br($this->render($diff));
 280      }
 281  
 282  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 283      {
 284          if ($xlen != 1) 
 285          {
 286              $xbeg .= ',' . $xlen;
 287          }
 288  
 289          if ($ylen != 1) 
 290          {
 291              $ybeg .= ',' . $ylen;
 292          }
 293          return '<div class="diff"><big class="info">@@ -' . $xbeg . ' +' . $ybeg . ' @@</big></div>';
 294      }
 295  
 296  	function _context($lines)
 297      {
 298          return '<pre class="diff context">' . htmlspecialchars($this->_lines($lines, ' ')) . '</pre>';
 299      }
 300      
 301  	function _added($lines)
 302      {
 303          return '<pre class="diff added">' . htmlspecialchars($this->_lines($lines, '+')) . '</pre>';
 304      }
 305  
 306  	function _deleted($lines)
 307      {
 308          return '<pre class="diff removed">' . htmlspecialchars($this->_lines($lines, '-')) . '</pre>';
 309      }
 310  
 311  	function _changed($orig, $final)
 312      {
 313          return $this->_deleted($orig) . $this->_added($final);
 314      }
 315  
 316  	function _start_diff()
 317      {
 318          $start = '<div class="file">';
 319  
 320          return $start;
 321      }
 322  
 323  	function _end_diff()
 324      {
 325          return '</div>';
 326      }
 327  
 328  	function _end_block()
 329      {
 330          return '';
 331      }
 332  }
 333  
 334  /**
 335  * "Inline" diff renderer.
 336  *
 337  * This class renders diffs in the Wiki-style "inline" format.
 338  *
 339  * @author  Ciprian Popovici
 340  * @package phpBB3
 341  */
 342  class diff_renderer_inline extends diff_renderer
 343  {
 344      var $_leading_context_lines = 10000;
 345      var $_trailing_context_lines = 10000;
 346  
 347      // Prefix and suffix for inserted text
 348      var $_ins_prefix = '<span class="ins">';
 349      var $_ins_suffix = '</span>';
 350  
 351      // Prefix and suffix for deleted text
 352      var $_del_prefix = '<span class="del">';
 353      var $_del_suffix = '</span>';
 354  
 355      var $_block_head = '';
 356  
 357      // What are we currently splitting on? Used to recurse to show word-level
 358      var $_split_level = 'lines';
 359  
 360      /**
 361      * Our function to get the diff
 362      */
 363  	function get_diff_content($diff)
 364      {
 365          return '<pre>' . nl2br($this->render($diff)) . '</pre>';
 366      }
 367  
 368  	function _start_diff()
 369      {
 370          return '';
 371      }
 372  
 373  	function _end_diff()
 374      {
 375          return '';
 376      }
 377  
 378  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 379      {
 380          return $this->_block_head;
 381      }
 382  
 383  	function _start_block($header)
 384      {
 385          return $header;
 386      }
 387  
 388  	function _lines($lines, $prefix = ' ', $encode = true)
 389      {
 390          if ($encode)
 391          {
 392              array_walk($lines, array(&$this, '_encode'));
 393          }
 394  
 395          if ($this->_split_level == 'words')
 396          {
 397              return implode('', $lines);
 398          }
 399          else
 400          {
 401              return implode("\n", $lines) . "\n";
 402          }
 403      }
 404  
 405  	function _added($lines)
 406      {
 407          array_walk($lines, array(&$this, '_encode'));
 408          $lines[0] = $this->_ins_prefix . $lines[0];
 409          $lines[sizeof($lines) - 1] .= $this->_ins_suffix;
 410          return $this->_lines($lines, ' ', false);
 411      }
 412  
 413  	function _deleted($lines, $words = false)
 414      {
 415          array_walk($lines, array(&$this, '_encode'));
 416          $lines[0] = $this->_del_prefix . $lines[0];
 417          $lines[sizeof($lines) - 1] .= $this->_del_suffix;
 418          return $this->_lines($lines, ' ', false);
 419      }
 420  
 421  	function _changed($orig, $final)
 422      {
 423          // If we've already split on words, don't try to do so again - just display.
 424          if ($this->_split_level == 'words')
 425          {
 426              $prefix = '';
 427              while ($orig[0] !== false && $final[0] !== false && substr($orig[0], 0, 1) == ' ' && substr($final[0], 0, 1) == ' ')
 428              {
 429                  $prefix .= substr($orig[0], 0, 1);
 430                  $orig[0] = substr($orig[0], 1);
 431                  $final[0] = substr($final[0], 1);
 432              }
 433  
 434              return $prefix . $this->_deleted($orig) . $this->_added($final);
 435          }
 436  
 437          $text1 = implode("\n", $orig);
 438          $text2 = implode("\n", $final);
 439  
 440          // Non-printing newline marker.
 441          $nl = "\0";
 442  
 443          // We want to split on word boundaries, but we need to preserve whitespace as well.
 444          // Therefore we split on words, but include all blocks of whitespace in the wordlist.
 445          $diff = &new diff($this->_split_on_words($text1, $nl), $this->_split_on_words($text2, $nl));
 446  
 447          // Get the diff in inline format.
 448          $renderer = &new diff_renderer_inline(array_merge($this->get_params(), array('split_level' => 'words')));
 449  
 450          // Run the diff and get the output.
 451          return str_replace($nl, "\n", $renderer->render($diff)) . "\n";
 452      }
 453  
 454  	function _split_on_words($string, $newline_escape = "\n")
 455      {
 456          // Ignore \0; otherwise the while loop will never finish.
 457          $string = str_replace("\0", '', $string);
 458          
 459          $words = array();
 460          $length = strlen($string);
 461          $pos = 0;
 462  
 463          $tab_there = true;
 464          while ($pos < $length)
 465          {
 466              // Check for tabs... do not include them
 467              if ($tab_there && substr($string, $pos, 1) === "\t")
 468              {
 469                  $words[] = "\t";
 470                  $pos++;
 471  
 472                  continue;
 473              }
 474              else
 475              {
 476                  $tab_there = false;
 477              }
 478  
 479              // Eat a word with any preceding whitespace.
 480              $spaces = strspn(substr($string, $pos), " \n");
 481              $nextpos = strcspn(substr($string, $pos + $spaces), " \n");
 482              $words[] = str_replace("\n", $newline_escape, substr($string, $pos, $spaces + $nextpos));
 483              $pos += $spaces + $nextpos;
 484          }
 485  
 486          return $words;
 487      }
 488  
 489  	function _encode(&$string)
 490      {
 491          $string = htmlspecialchars($string);
 492      }
 493  }
 494  
 495  /**
 496  * "raw" diff renderer.
 497  * This class could be used to output a raw unified patch file
 498  *
 499  * @package phpBB3
 500  */
 501  class diff_renderer_raw extends diff_renderer 
 502  {
 503      var $_leading_context_lines = 4;
 504      var $_trailing_context_lines = 4;
 505  
 506      /**
 507      * Our function to get the diff
 508      */
 509  	function get_diff_content($diff)
 510      {
 511          return '<textarea style="height: 400px;" class="full">' . htmlspecialchars($this->render($diff)) . '</textarea>';
 512      }
 513  
 514  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 515      {
 516          if ($xlen != 1) 
 517          {
 518              $xbeg .= ',' . $xlen;
 519          }
 520  
 521          if ($ylen != 1) 
 522          {
 523              $ybeg .= ',' . $ylen;
 524          }
 525          return '@@ -' . $xbeg . ' +' . $ybeg . ' @@';
 526      }
 527  
 528  	function _context($lines)
 529      {
 530          return $this->_lines($lines, ' ');
 531      }
 532      
 533  	function _added($lines)
 534      {
 535          return $this->_lines($lines, '+');
 536      }
 537  
 538  	function _deleted($lines)
 539      {
 540          return $this->_lines($lines, '-');
 541      }
 542  
 543  	function _changed($orig, $final)
 544      {
 545          return $this->_deleted($orig) . $this->_added($final);
 546      }
 547  }
 548  
 549  /**
 550  * "chora (Horde)" diff renderer - similar style.
 551  * This renderer class is a modified human_readable function from the Horde Framework.
 552  *
 553  * @package phpBB3
 554  */
 555  class diff_renderer_side_by_side extends diff_renderer 
 556  {
 557      var $_leading_context_lines = 3;
 558      var $_trailing_context_lines = 3;
 559  
 560      var $lines = array();
 561  
 562      // Hold the left and right columns of lines for change blocks.
 563      var $cols;
 564      var $state;
 565  
 566      var $data = false;
 567  
 568      /**
 569      * Our function to get the diff
 570      */
 571  	function get_diff_content($diff)
 572      {
 573          global $user;
 574  
 575          $output = '';
 576          $output .= '<table cellspacing="0" class="hrdiff">
 577  <caption>
 578      <span class="unmodified">&nbsp;</span> ' . $user->lang['LINE_UNMODIFIED'] . '
 579      <span class="added">&nbsp;</span> ' . $user->lang['LINE_ADDED'] . '
 580      <span class="modified">&nbsp;</span> ' . $user->lang['LINE_MODIFIED'] . '
 581      <span class="removed">&nbsp;</span> ' . $user->lang['LINE_REMOVED'] . '
 582  </caption>
 583  <tbody>
 584  ';
 585  
 586          $this->render($diff);
 587  
 588          // Is the diff empty?
 589          if (!sizeof($this->lines))
 590          {
 591              $output .= '<tr><th colspan="2">' . $user->lang['NO_VISIBLE_CHANGES'] . '</th></tr>';
 592          }
 593          else
 594          {
 595              // Iterate through every header block of changes
 596              foreach ($this->lines as $header)
 597              {
 598                  $output .= '<tr><th>Line ' . $header['oldline'] . '</th><th>' . $user->lang['LINE'] . ' ' . $header['newline'] . '</th></tr>';
 599  
 600                  // Each header block consists of a number of changes (add, remove, change).
 601                  $current_context = '';
 602  
 603                  foreach ($header['contents'] as $change)
 604                  {
 605                      if (!empty($current_context) && $change['type'] != 'empty')
 606                      {
 607                          $line = $current_context;
 608                          $current_context = '';
 609  
 610                          $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td>
 611                              <td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td></tr>';
 612                      }
 613  
 614                      switch ($change['type'])
 615                      {
 616                          case 'add':
 617                              $line = '';
 618  
 619                              foreach ($change['lines'] as $_line)
 620                              {
 621                                  $line .= htmlspecialchars($_line) . '<br />';
 622                              }
 623  
 624                              $output .= '<tr><td class="added_empty">&nbsp;</td><td class="added"><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td></tr>';
 625                          break;
 626  
 627                          case 'remove':
 628                              $line = '';
 629  
 630                              foreach ($change['lines'] as $_line)
 631                              {
 632                                  $line .= htmlspecialchars($_line) . '<br />';
 633                              }
 634  
 635                              $output .= '<tr><td class="removed"><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td><td class="removed_empty">&nbsp;</td></tr>';
 636                          break;
 637  
 638                          case 'empty':
 639                              $current_context .= htmlspecialchars($change['line']) . '<br />';
 640                          break;
 641  
 642                          case 'change':
 643                              // Pop the old/new stacks one by one, until both are empty. 
 644                              $oldsize = sizeof($change['old']);
 645                              $newsize = sizeof($change['new']);
 646                              $left = $right = '';
 647  
 648                              for ($row = 0, $row_max = max($oldsize, $newsize); $row < $row_max; ++$row)
 649                              {
 650                                  $left .= isset($change['old'][$row]) ? htmlspecialchars($change['old'][$row]) : '';
 651                                  $left .= '<br />';
 652                                  $right .= isset($change['new'][$row]) ? htmlspecialchars($change['new'][$row]) : '';
 653                                  $right .= '<br />';
 654                              }
 655  
 656                              $output .= '<tr>';
 657  
 658                              if (!empty($left))
 659                              {
 660                                  $output .= '<td class="modified"><pre>' . $left . '</pre></td>';
 661                              }
 662                              else if ($row < $oldsize)
 663                              {
 664                                  $output .= '<td class="modified">&nbsp;</td>';
 665                              }
 666                              else
 667                              {
 668                                  $output .= '<td class="unmodified">&nbsp;</td>';
 669                              }
 670  
 671                              if (!empty($right))
 672                              {
 673                                  $output .= '<td class="modified"><pre>' . $right . '</pre></td>';
 674                              }
 675                              else if ($row < $newsize)
 676                              {
 677                                  $output .= '<td class="modified">&nbsp;</td>';
 678                              }
 679                              else
 680                              {
 681                                  $output .= '<td class="unmodified">&nbsp;</td>';
 682                              }
 683  
 684                              $output .= '</tr>';
 685                          break;
 686                      }
 687                  }
 688  
 689                  if (!empty($current_context))
 690                  {
 691                      $line = $current_context;
 692                      $current_context = '';
 693  
 694                      $output .= '<tr class="unmodified"><td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td>';
 695                      $output .= '<td><pre>' . ((strlen($line)) ? $line : '&nbsp;') . '</pre></td></tr>';
 696                  }
 697              }
 698          }
 699  
 700          $output .= '</tbody></table>';
 701  
 702          return $output;
 703      }
 704  
 705  	function _start_diff()
 706      {
 707          $this->lines = array();
 708  
 709          $this->data = false;
 710          $this->cols = array(array(), array());
 711          $this->state = 'empty';
 712  
 713          return '';
 714      }
 715  
 716  	function _end_diff()
 717      {
 718          // Just flush any remaining entries in the columns stack.
 719          switch ($this->state)
 720          {
 721              case 'add':
 722                  $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]);
 723              break;
 724  
 725              case 'remove':
 726                  // We have some removal lines pending in our stack, so flush them.
 727                  $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]);
 728              break;
 729  
 730              case 'change':
 731                  // We have both remove and addition lines, so this is a change block.
 732                  $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]);
 733              break;
 734          }
 735  
 736          if ($this->data !== false)
 737          {
 738              $this->lines[] = $this->data;
 739          }
 740  
 741          return '';
 742      }
 743  
 744  	function _block_header($xbeg, $xlen, $ybeg, $ylen)
 745      {
 746          // Push any previous header information to the return stack.
 747          if ($this->data !== false)
 748          {
 749              $this->lines[] = $this->data;
 750          }
 751  
 752          $this->data = array('type' => 'header', 'oldline' => $xbeg, 'newline' => $ybeg, 'contents' => array());
 753          $this->state = 'dump';
 754      }
 755  
 756  	function _added($lines)
 757      {
 758          array_walk($lines, array(&$this, '_perform_add'));
 759      }
 760  
 761  	function _perform_add($line)
 762      {
 763          if ($this->state == 'empty')
 764          {
 765              return '';
 766          }
 767  
 768          // This is just an addition line.
 769          if ($this->state == 'dump' || $this->state == 'add')
 770          {
 771              // Start adding to the addition stack.
 772              $this->cols[0][] = $line;
 773              $this->state = 'add';
 774          }
 775          else
 776          {
 777              // This is inside a change block, so start accumulating lines.
 778              $this->state = 'change';
 779              $this->cols[1][] = $line;
 780          }
 781      }
 782  
 783  	function _deleted($lines)
 784      {
 785          array_walk($lines, array(&$this, '_perform_delete'));
 786      }
 787  
 788  	function _perform_delete($line)
 789      {
 790          // This is a removal line.
 791          $this->state = 'remove';
 792          $this->cols[0][] = $line;
 793      }
 794  
 795  	function _context($lines)
 796      {
 797          array_walk($lines, array(&$this, '_perform_context'));
 798      }
 799  
 800  	function _perform_context($line)
 801      {
 802          // An empty block with no action.
 803          switch ($this->state)
 804          {
 805              case 'add':
 806                  $this->data['contents'][] = array('type' => 'add', 'lines' => $this->cols[0]);
 807              break;
 808  
 809              case 'remove':
 810                  // We have some removal lines pending in our stack, so flush them.
 811                  $this->data['contents'][] = array('type' => 'remove', 'lines' => $this->cols[0]);
 812              break;
 813  
 814              case 'change':
 815                  // We have both remove and addition lines, so this is a change block.
 816                  $this->data['contents'][] = array('type' => 'change', 'old' => $this->cols[0], 'new' => $this->cols[1]);
 817              break;
 818          }
 819  
 820          $this->cols = array(array(), array());
 821          $this->data['contents'][] = array('type' => 'empty', 'line' => $line);
 822          $this->state = 'dump';
 823      }
 824  
 825  	function _changed($orig, $final)
 826      {
 827          return $this->_deleted($orig) . $this->_added($final);
 828      }
 829  
 830  }
 831  
 832  ?>


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6