gluon-web-remote

Web remote Administration for big size of gluon routers
git clone git://archive.git.mtrnord.blog/MTRNord/gluon-web-remote.git
Log | Files | Refs | README

Diff.php (8500B)


      1 <?php
      2 /**
      3  * PHPUnit
      4  *
      5  * Copyright (c) 2001-2014, Sebastian Bergmann <sebastian@phpunit.de>.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  *   * Redistributions of source code must retain the above copyright
     13  *     notice, this list of conditions and the following disclaimer.
     14  *
     15  *   * Redistributions in binary form must reproduce the above copyright
     16  *     notice, this list of conditions and the following disclaimer in
     17  *     the documentation and/or other materials provided with the
     18  *     distribution.
     19  *
     20  *   * Neither the name of Sebastian Bergmann nor the names of his
     21  *     contributors may be used to endorse or promote products derived
     22  *     from this software without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  *
     37  * @package    PHPUnit
     38  * @subpackage Util
     39  * @author     Sebastian Bergmann <sebastian@phpunit.de>
     40  * @author     Kore Nordmann <mail@kore-nordmann.de>
     41  * @copyright  2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
     42  * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     43  * @link       http://www.phpunit.de/
     44  * @since      File available since Release 3.4.0
     45  */
     46 
     47 /**
     48  * Diff implementation.
     49  *
     50  * @package    PHPUnit
     51  * @subpackage Util
     52  * @author     Sebastian Bergmann <sebastian@phpunit.de>
     53  * @author     Kore Nordmann <mail@kore-nordmann.de>
     54  * @copyright  2001-2014 Sebastian Bergmann <sebastian@phpunit.de>
     55  * @license    http://www.opensource.org/licenses/BSD-3-Clause  The BSD 3-Clause License
     56  * @link       http://www.phpunit.de/
     57  * @since      Class available since Release 3.4.0
     58  */
     59 class PHPUnit_Util_Diff
     60 {
     61     /**
     62      * Returns the diff between two arrays or strings as string.
     63      *
     64      * @param  array|string $from
     65      * @param  array|string $to
     66      * @return string
     67      */
     68     public static function diff($from, $to)
     69     {
     70         $buffer= "--- Expected\n+++ Actual\n";
     71         $diff  = self::diffToArray($from,$to);
     72 
     73         $inOld = FALSE;
     74         $i     = 0;
     75         $old   = array();
     76 
     77         foreach ($diff as $line) {
     78             if ($line[1] ===  0 /* OLD */) {
     79                 if ($inOld === FALSE) {
     80                     $inOld = $i;
     81                 }
     82             }
     83 
     84             else if ($inOld !== FALSE) {
     85                 if (($i - $inOld) > 5) {
     86                     $old[$inOld] = $i - 1;
     87                 }
     88 
     89                 $inOld = FALSE;
     90             }
     91 
     92             ++$i;
     93         }
     94 
     95         $start = isset($old[0]) ? $old[0] : 0;
     96         $end   = count($diff);
     97         $i     = 0;
     98 
     99         if ($tmp = array_search($end, $old)) {
    100             $end = $tmp;
    101         }
    102 
    103         $newChunk = TRUE;
    104 
    105         for ($i = $start; $i < $end; $i++) {
    106             if (isset($old[$i])) {
    107                 $buffer  .= "\n";
    108                 $newChunk = TRUE;
    109                 $i        = $old[$i];
    110             }
    111 
    112             if ($newChunk) {
    113                 $buffer  .= "@@ @@\n";
    114                 $newChunk = FALSE;
    115             }
    116 
    117             if ($diff[$i][1] === 1 /* ADDED */) {
    118                 $buffer .= '+' . $diff[$i][0] . "\n";
    119             }
    120 
    121             else if ($diff[$i][1] === 2 /* REMOVED */) {
    122                 $buffer .= '-' . $diff[$i][0] . "\n";
    123             }
    124 
    125             else {
    126                 $buffer .= ' ' . $diff[$i][0] . "\n";
    127             }
    128         }
    129 
    130         return $buffer;
    131     }
    132 
    133     /**
    134      * Returns the diff between two arrays or strings as array.
    135      *
    136      * every array-entry contains two elements:
    137      *   - [0] => string $token
    138      *   - [1] => 2|1|0
    139      *
    140      * - 2: REMOVED: $token was removed from $from
    141      * - 1: ADDED: $token was added to $from
    142      * - 0: OLD: $token is not changed in $to
    143      *
    144      * @param  array|string $from
    145      * @param  array|string $to
    146      * @return array
    147      */
    148     public static function diffToArray($from, $to)
    149     {
    150         preg_match_all('(\r\n|\r|\n)', $from, $fromMatches);
    151         preg_match_all('(\r\n|\r|\n)', $to, $toMatches);
    152 
    153         if (is_string($from)) {
    154             $from = preg_split('(\r\n|\r|\n)', $from);
    155         }
    156 
    157         if (is_string($to)) {
    158             $to = preg_split('(\r\n|\r|\n)', $to);
    159         }
    160 
    161         $start      = array();
    162         $end        = array();
    163         $fromLength = count($from);
    164         $toLength   = count($to);
    165         $length     = min($fromLength, $toLength);
    166 
    167         for ($i = 0; $i < $length; ++$i) {
    168             if ($from[$i] === $to[$i]) {
    169                 $start[] = $from[$i];
    170                 unset($from[$i], $to[$i]);
    171             } else {
    172                 break;
    173             }
    174         }
    175 
    176         $length -= $i;
    177 
    178         for ($i = 1; $i < $length; ++$i) {
    179             if ($from[$fromLength - $i] === $to[$toLength - $i]) {
    180                 array_unshift($end, $from[$fromLength - $i]);
    181                 unset($from[$fromLength - $i], $to[$toLength - $i]);
    182             } else {
    183                 break;
    184             }
    185         }
    186 
    187         $common = self::longestCommonSubsequence(
    188           array_values($from), array_values($to)
    189         );
    190 
    191         $diff = array();
    192         $line = 0;
    193 
    194         if (isset($fromMatches[0]) && $toMatches[0] &&
    195             count($fromMatches[0]) === count($toMatches[0]) &&
    196             $fromMatches[0] !== $toMatches[0]) {
    197             $diff[] = array(
    198               '#Warning: Strings contain different line endings!', 0
    199             );
    200         }
    201 
    202         foreach ($start as $token) {
    203             $diff[] = array($token, 0 /* OLD */);
    204         }
    205 
    206         reset($from);
    207         reset($to);
    208 
    209         foreach ($common as $token) {
    210             while ((($fromToken = reset($from)) !== $token)) {
    211                 $diff[] = array(array_shift($from), 2 /* REMOVED */);
    212             }
    213 
    214             while ((($toToken = reset($to)) !== $token)) {
    215                 $diff[] = array(array_shift($to), 1 /* ADDED */);
    216             }
    217 
    218             $diff[] = array($token, 0 /* OLD */);
    219 
    220             array_shift($from);
    221             array_shift($to);
    222         }
    223 
    224         while (($token = array_shift($from)) !== NULL) {
    225             $diff[] = array($token, 2 /* REMOVED */);
    226         }
    227 
    228         while (($token = array_shift($to)) !== NULL) {
    229             $diff[] = array($token, 1 /* ADDED */);
    230         }
    231 
    232         foreach ($end as $token) {
    233             $diff[] = array($token, 0 /* OLD */);
    234         }
    235 
    236         return $diff;
    237     }
    238 
    239     /**
    240      * Calculates the longest common subsequence of two arrays.
    241      *
    242      * @param  array $from
    243      * @param  array $to
    244      * @return array
    245      */
    246     protected static function longestCommonSubsequence(array $from, array $to)
    247     {
    248         $common     = array();
    249         $matrix     = array();
    250         $fromLength = count($from);
    251         $toLength   = count($to);
    252 
    253         for ($i = 0; $i <= $fromLength; ++$i) {
    254             $matrix[$i][0] = 0;
    255         }
    256 
    257         for ($j = 0; $j <= $toLength; ++$j) {
    258             $matrix[0][$j] = 0;
    259         }
    260 
    261         for ($i = 1; $i <= $fromLength; ++$i) {
    262             for ($j = 1; $j <= $toLength; ++$j) {
    263                 $matrix[$i][$j] = max(
    264                   $matrix[$i-1][$j],
    265                   $matrix[$i][$j-1],
    266                   $from[$i-1] === $to[$j-1] ? $matrix[$i-1][$j-1] + 1 : 0
    267                 );
    268             }
    269         }
    270 
    271         $i = $fromLength;
    272         $j = $toLength;
    273 
    274         while ($i > 0 && $j > 0) {
    275             if ($from[$i-1] === $to[$j-1]) {
    276                 array_unshift($common, $from[$i-1]);
    277                 --$i;
    278                 --$j;
    279             }
    280 
    281             else if ($matrix[$i][$j-1] > $matrix[$i-1][$j]) {
    282                 --$j;
    283             }
    284 
    285             else {
    286                 --$i;
    287             }
    288         }
    289 
    290         return $common;
    291     }
    292 }