Text_Diff
[ class tree: Text_Diff ] [ index: Text_Diff ] [ all elements ]

Source for file string.php

Documentation is available at string.php

  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 Text_Diff('string', array($patch));
  9.  * $renderer = new Text_Diff_Renderer_inline();
  10.  * echo $renderer->render($diff);
  11.  * </code>
  12.  *
  13.  * $Horde: framework/Text_Diff/Diff/Engine/string.php,v 1.7 2008/01/04 10:07:50 jan Exp $
  14.  *
  15.  * Copyright 2005-2008 The Horde Project (http://www.horde.org/)
  16.  *
  17.  * See the enclosed file COPYING for license information (LGPL). If you did
  18.  * not receive this file, see http://opensource.org/licenses/lgpl-license.php.
  19.  *
  20.  * @author
  21.  * @package Text_Diff
  22.  * @since   0.2.0
  23.  */
  24.  
  25.     /**
  26.      * Parses a unified or context diff.
  27.      *
  28.      * First param contains the whole diff and the second can be used to force
  29.      * a specific diff type. If the second parameter is 'autodetect', the
  30.      * diff will be examined to find out which type of diff this is.
  31.      *
  32.      * @param string $diff  The diff content.
  33.      * @param string $mode  The diff mode of the content in $diff. One of
  34.      *                       'context', 'unified', or 'autodetect'.
  35.      *
  36.      * @return array  List of all diff operations.
  37.      */
  38.     function diff($diff$mode 'autodetect')
  39.     {
  40.         if ($mode != 'autodetect' && $mode != 'context' && $mode != 'unified'{
  41.             return PEAR::raiseError('Type of diff is unsupported');
  42.         }
  43.  
  44.         if ($mode == 'autodetect'{
  45.             $context strpos($diff'***');
  46.             $unified strpos($diff'---');
  47.             if ($context === $unified{
  48.                 return PEAR::raiseError('Type of diff could not be detected');
  49.             elseif ($context === false || $context === false{
  50.                 $mode $context !== false ? 'context' 'unified';
  51.             else {
  52.                 $mode $context $unified 'context' 'unified';
  53.             }
  54.         }
  55.  
  56.         // split by new line and remove the diff header
  57.         $diff explode("\n"$diff);
  58.         array_shift($diff);
  59.         array_shift($diff);
  60.  
  61.         if ($mode == 'context'{
  62.             return $this->parseContextDiff($diff);
  63.         else {
  64.             return $this->parseUnifiedDiff($diff);
  65.         }
  66.     }
  67.  
  68.     /**
  69.      * Parses an array containing the unified diff.
  70.      *
  71.      * @param array $diff  Array of lines.
  72.      *
  73.      * @return array  List of all diff operations.
  74.      */
  75.     function parseUnifiedDiff($diff)
  76.     {
  77.         $edits = array();
  78.         $end count($diff- 1;
  79.         for ($i = 0; $i $end;{
  80.             $diff1 = array();
  81.             switch (substr($diff[$i]01)) {
  82.             case ' ':
  83.                 do {
  84.                     $diff1[substr($diff[$i]1);
  85.                 while (++$i $end && substr($diff[$i]01== ' ');
  86.                 $edits[&new Text_Diff_Op_copy($diff1);
  87.                 break;
  88.  
  89.             case '+':
  90.                 // get all new lines
  91.                 do {
  92.                     $diff1[substr($diff[$i]1);
  93.                 while (++$i $end && substr($diff[$i]01== '+');
  94.                 $edits[&new Text_Diff_Op_add($diff1);
  95.                 break;
  96.  
  97.             case '-':
  98.                 // get changed or removed lines
  99.                 $diff2 = array();
  100.                 do {
  101.                     $diff1[substr($diff[$i]1);
  102.                 while (++$i $end && substr($diff[$i]01== '-');
  103.  
  104.                 while ($i $end && substr($diff[$i]01== '+'{
  105.                     $diff2[substr($diff[$i++]1);
  106.                 }
  107.                 if (count($diff2== 0{
  108.                     $edits[&new Text_Diff_Op_delete($diff1);
  109.                 else {
  110.                     $edits[&new Text_Diff_Op_change($diff1$diff2);
  111.                 }
  112.                 break;
  113.  
  114.             default:
  115.                 $i++;
  116.                 break;
  117.             }
  118.         }
  119.  
  120.         return $edits;
  121.     }
  122.  
  123.     /**
  124.      * Parses an array containing the context diff.
  125.      *
  126.      * @param array $diff  Array of lines.
  127.      *
  128.      * @return array  List of all diff operations.
  129.      */
  130.     function parseContextDiff(&$diff)
  131.     {
  132.         $edits = array();
  133.         $i $max_i $j $max_j = 0;
  134.         $end count($diff- 1;
  135.         while ($i $end && $j $end{
  136.             while ($i >= $max_i && $j >= $max_j{
  137.                 // Find the boundaries of the diff output of the two files
  138.                 for ($i $j;
  139.                      $i $end && substr($diff[$i]03== '***';
  140.                      $i++);
  141.                 for ($max_i $i;
  142.                      $max_i $end && substr($diff[$max_i]03!= '---';
  143.                      $max_i++);
  144.                 for ($j $max_i;
  145.                      $j $end && substr($diff[$j]03== '---';
  146.                      $j++);
  147.                 for ($max_j $j;
  148.                      $max_j $end && substr($diff[$max_j]03!= '***';
  149.                      $max_j++);
  150.             }
  151.  
  152.             // find what hasn't been changed
  153.             $array = array();
  154.             while ($i $max_i &&
  155.                    $j $max_j &&
  156.                    strcmp($diff[$i]$diff[$j]== 0{
  157.                 $array[substr($diff[$i]2);
  158.                 $i++;
  159.                 $j++;
  160.             }
  161.  
  162.             while ($i $max_i && ($max_j-$j<= 1{
  163.                 if ($diff[$i!= '' && substr($diff[$i]01!= ' '{
  164.                     break;
  165.                 }
  166.                 $array[substr($diff[$i++]2);
  167.             }
  168.  
  169.             while ($j $max_j && ($max_i-$i<= 1{
  170.                 if ($diff[$j!= '' && substr($diff[$j]01!= ' '{
  171.                     break;
  172.                 }
  173.                 $array[substr($diff[$j++]2);
  174.             }
  175.             if (count($array> 0{
  176.                 $edits[&new Text_Diff_Op_copy($array);
  177.             }
  178.  
  179.             if ($i $max_i{
  180.                 $diff1 = array();
  181.                 switch (substr($diff[$i]01)) {
  182.                 case '!':
  183.                     $diff2 = array();
  184.                     do {
  185.                         $diff1[substr($diff[$i]2);
  186.                         if ($j $max_j && substr($diff[$j]01== '!'{
  187.                             $diff2[substr($diff[$j++]2);
  188.                         }
  189.                     while (++$i $max_i && substr($diff[$i]01== '!');
  190.                     $edits[&new Text_Diff_Op_change($diff1$diff2);
  191.                     break;
  192.  
  193.                 case '+':
  194.                     do {
  195.                         $diff1[substr($diff[$i]2);
  196.                     while (++$i $max_i && substr($diff[$i]01== '+');
  197.                     $edits[&new Text_Diff_Op_add($diff1);
  198.                     break;
  199.  
  200.                 case '-':
  201.                     do {
  202.                         $diff1[substr($diff[$i]2);
  203.                     while (++$i $max_i && substr($diff[$i]01== '-');
  204.                     $edits[&new Text_Diff_Op_delete($diff1);
  205.                     break;
  206.                 }
  207.             }
  208.  
  209.             if ($j $max_j{
  210.                 $diff2 = array();
  211.                 switch (substr($diff[$j]01)) {
  212.                 case '+':
  213.                     do {
  214.                         $diff2[substr($diff[$j++]2);
  215.                     while ($j $max_j && substr($diff[$j]01== '+');
  216.                     $edits[&new Text_Diff_Op_add($diff2);
  217.                     break;
  218.  
  219.                 case '-':
  220.                     do {
  221.                         $diff2[substr($diff[$j++]2);
  222.                     while ($j $max_j && substr($diff[$j]01== '-');
  223.                     $edits[&new Text_Diff_Op_delete($diff2);
  224.                     break;
  225.                 }
  226.             }
  227.         }
  228.  
  229.         return $edits;
  230.     }
  231.  
  232. }

Documentation generated on Mon, 11 Mar 2019 15:14:33 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.