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.5.2.5 2008/09/10 08:31:58 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 || $unified === 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, if there is one.
  57.         $diff explode("\n"$diff);
  58.         if (($mode == 'context' && strpos($diff[0]'***'=== 0||
  59.             ($mode == 'unified' && strpos($diff[0]'---'=== 0)) {
  60.             array_shift($diff);
  61.             array_shift($diff);
  62.         }
  63.  
  64.         if ($mode == 'context'{
  65.             return $this->parseContextDiff($diff);
  66.         else {
  67.             return $this->parseUnifiedDiff($diff);
  68.         }
  69.     }
  70.  
  71.     /**
  72.      * Parses an array containing the unified diff.
  73.      *
  74.      * @param array $diff  Array of lines.
  75.      *
  76.      * @return array  List of all diff operations.
  77.      */
  78.     function parseUnifiedDiff($diff)
  79.     {
  80.         $edits = array();
  81.         $end count($diff- 1;
  82.         for ($i = 0; $i $end;{
  83.             $diff1 = array();
  84.             switch (substr($diff[$i]01)) {
  85.             case ' ':
  86.                 do {
  87.                     $diff1[substr($diff[$i]1);
  88.                 while (++$i $end && substr($diff[$i]01== ' ');
  89.                 $edits[= new Text_Diff_Op_copy($diff1);
  90.                 break;
  91.  
  92.             case '+':
  93.                 // get all new lines
  94.                 do {
  95.                     $diff1[substr($diff[$i]1);
  96.                 while (++$i $end && substr($diff[$i]01== '+');
  97.                 $edits[= new Text_Diff_Op_add($diff1);
  98.                 break;
  99.  
  100.             case '-':
  101.                 // get changed or removed lines
  102.                 $diff2 = array();
  103.                 do {
  104.                     $diff1[substr($diff[$i]1);
  105.                 while (++$i $end && substr($diff[$i]01== '-');
  106.  
  107.                 while ($i $end && substr($diff[$i]01== '+'{
  108.                     $diff2[substr($diff[$i++]1);
  109.                 }
  110.                 if (count($diff2== 0{
  111.                     $edits[= new Text_Diff_Op_delete($diff1);
  112.                 else {
  113.                     $edits[= new Text_Diff_Op_change($diff1$diff2);
  114.                 }
  115.                 break;
  116.  
  117.             default:
  118.                 $i++;
  119.                 break;
  120.             }
  121.         }
  122.  
  123.         return $edits;
  124.     }
  125.  
  126.     /**
  127.      * Parses an array containing the context diff.
  128.      *
  129.      * @param array $diff  Array of lines.
  130.      *
  131.      * @return array  List of all diff operations.
  132.      */
  133.     function parseContextDiff(&$diff)
  134.     {
  135.         $edits = array();
  136.         $i $max_i $j $max_j = 0;
  137.         $end count($diff- 1;
  138.         while ($i $end && $j $end{
  139.             while ($i >= $max_i && $j >= $max_j{
  140.                 // Find the boundaries of the diff output of the two files
  141.                 for ($i $j;
  142.                      $i $end && substr($diff[$i]03== '***';
  143.                      $i++);
  144.                 for ($max_i $i;
  145.                      $max_i $end && substr($diff[$max_i]03!= '---';
  146.                      $max_i++);
  147.                 for ($j $max_i;
  148.                      $j $end && substr($diff[$j]03== '---';
  149.                      $j++);
  150.                 for ($max_j $j;
  151.                      $max_j $end && substr($diff[$max_j]03!= '***';
  152.                      $max_j++);
  153.             }
  154.  
  155.             // find what hasn't been changed
  156.             $array = array();
  157.             while ($i $max_i &&
  158.                    $j $max_j &&
  159.                    strcmp($diff[$i]$diff[$j]== 0{
  160.                 $array[substr($diff[$i]2);
  161.                 $i++;
  162.                 $j++;
  163.             }
  164.  
  165.             while ($i $max_i && ($max_j-$j<= 1{
  166.                 if ($diff[$i!= '' && substr($diff[$i]01!= ' '{
  167.                     break;
  168.                 }
  169.                 $array[substr($diff[$i++]2);
  170.             }
  171.  
  172.             while ($j $max_j && ($max_i-$i<= 1{
  173.                 if ($diff[$j!= '' && substr($diff[$j]01!= ' '{
  174.                     break;
  175.                 }
  176.                 $array[substr($diff[$j++]2);
  177.             }
  178.             if (count($array> 0{
  179.                 $edits[= new Text_Diff_Op_copy($array);
  180.             }
  181.  
  182.             if ($i $max_i{
  183.                 $diff1 = array();
  184.                 switch (substr($diff[$i]01)) {
  185.                 case '!':
  186.                     $diff2 = array();
  187.                     do {
  188.                         $diff1[substr($diff[$i]2);
  189.                         if ($j $max_j && substr($diff[$j]01== '!'{
  190.                             $diff2[substr($diff[$j++]2);
  191.                         }
  192.                     while (++$i $max_i && substr($diff[$i]01== '!');
  193.                     $edits[= new Text_Diff_Op_change($diff1$diff2);
  194.                     break;
  195.  
  196.                 case '+':
  197.                     do {
  198.                         $diff1[substr($diff[$i]2);
  199.                     while (++$i $max_i && substr($diff[$i]01== '+');
  200.                     $edits[= new Text_Diff_Op_add($diff1);
  201.                     break;
  202.  
  203.                 case '-':
  204.                     do {
  205.                         $diff1[substr($diff[$i]2);
  206.                     while (++$i $max_i && substr($diff[$i]01== '-');
  207.                     $edits[= new Text_Diff_Op_delete($diff1);
  208.                     break;
  209.                 }
  210.             }
  211.  
  212.             if ($j $max_j{
  213.                 $diff2 = array();
  214.                 switch (substr($diff[$j]01)) {
  215.                 case '+':
  216.                     do {
  217.                         $diff2[substr($diff[$j++]2);
  218.                     while ($j $max_j && substr($diff[$j]01== '+');
  219.                     $edits[= new Text_Diff_Op_add($diff2);
  220.                     break;
  221.  
  222.                 case '-':
  223.                     do {
  224.                         $diff2[substr($diff[$j++]2);
  225.                     while ($j $max_j && substr($diff[$j]01== '-');
  226.                     $edits[= new Text_Diff_Op_delete($diff2);
  227.                     break;
  228.                 }
  229.             }
  230.         }
  231.  
  232.         return $edits;
  233.     }
  234.  
  235. }

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