Created
May 13, 2017 22:35
-
-
Save BinaryMoon/d6416caad61bdb5e7ae07c729201dd0e to your computer and use it in GitHub Desktop.
do a diff between files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function PHPDiff ($old, $new) { | |
$t1 = $old; | |
$t2 = $new; | |
# build a reverse-index array using the line as key and line number as value | |
# don't store blank lines, so they won't be targets of the shortest distance | |
# search | |
foreach ($t1 as $i => $x) { | |
if ($x>'') { | |
$r1[$x][] = $i; | |
} | |
} | |
foreach ($t2 as $i => $x) { | |
if ($x>'') { | |
$r2[$x][] = $i; | |
} | |
} | |
$a1 = 0; | |
$a2 = 0; # start at beginning of each list | |
$actions = array(); | |
# walk this loop until we reach the end of one of the lists | |
while ($a1 < count($t1) && $a2 < count($t2)) { | |
# if we have a common element, save it and go to the next | |
if ($t1[$a1] == $t2[$a2]) { | |
$actions[] = 4; | |
$a1++; | |
$a2++; | |
continue; | |
} | |
# otherwise, find the shortest move (Manhattan-distance) from the | |
# current location | |
$best1 = count($t1); | |
$best2 = count($t2); | |
$s1 = $a1; | |
$s2 = $a2; | |
while(($s1 + $s2 - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2)) { | |
$d = -1; | |
foreach((array) @$r1[$t2[$s2]] as $n) { | |
if ($n >= $s1) { | |
$d = $n; | |
break; | |
} | |
} | |
if ($d >= $s1 && ($d + $s2 - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2)) { | |
$best1 = $d; | |
$best2 = $s2; | |
} | |
$d = -1; | |
foreach((array) @$r2[$t1[$s1]] as $n) { | |
if ($n >= $s2) { | |
$d = $n; | |
break; | |
} | |
} | |
if ($d >= $s2 && ($s1 + $d - $a1 - $a2) < ($best1 + $best2 - $a1 - $a2)) { | |
$best1 = $s1; | |
$best2 = $d; | |
} | |
$s1++; | |
$s2++; | |
} | |
// deleted elements | |
while ($a1 < $best1) { | |
$actions[] = 1; | |
$a1++; | |
} | |
// added elements | |
while ($a2 < $best2) { | |
$actions[] = 2; | |
$a2++; | |
} | |
} | |
# we've reached the end of one list, now walk to the end of the other | |
# deleted elements | |
while($a1 < count($t1)) { | |
$actions[] = 1; | |
$a1 ++; | |
} | |
# added elements | |
while($a2 < count($t2)) { | |
$actions[] = 2; | |
$a2 ++; | |
} | |
# and this marks our ending point | |
$actions[] = 8; | |
# now, let's follow the path we just took and report the added/deleted | |
# elements into $out. | |
$op = 0; | |
$x0 = $x1 = $y0 = $y1 = 0; | |
$changeCount = 0; | |
$out = array(); | |
foreach($actions as $act) { | |
if ($act == 1) { | |
$op |= $act; | |
$x1 ++; | |
continue; | |
} | |
if ($act==2) { | |
$op |= $act; | |
$y1 ++; | |
continue; | |
} | |
if ($op>0) { | |
$xstr = ($x1 == ($x0 + 1)) ? $x1 : ($x0 + 1) . ', ' . $x1; | |
$ystr = ($y1 == ($y0 + 1)) ? $y1 : ($y0 + 1) . ', ' . $y1; | |
$out[] = '<li>'; | |
if ($op == 1) { | |
$out[] = '<p><strong>Code deleted</strong> : lines ' . $xstr . '</p>'; | |
} | |
if ($op == 3) { | |
$out[] = '<p><strong>Code changed</strong> : lines ' . $xstr . ' → ' . $ystr . '</p>'; | |
} | |
// deleted elems | |
if ($x0 < $x1) { | |
$out[] = "<pre>"; | |
while ($x0 < $x1) { | |
if($t1[$x0] != "") { | |
$out[] = str_replace("\n", "", str_replace("<", "<", $t1[$x0])); | |
} | |
$x0++; | |
} | |
$out[] = "</pre>"; | |
} | |
if ($op == 2) { | |
//$out[] = "<p><strong>Lines added</strong> : " . $x1 . " to " . $ystr . "</p>"; | |
$out[] = "<p><strong>Lines added</strong> : " . $ystr . "</p>"; | |
} | |
if ($op == 3) { | |
$out[] = '<p>changed to : </p>'; | |
} | |
# added elems | |
if ($y0 < $y1) { | |
$out[] = "<pre>"; | |
while ($y0 < $y1) { | |
if($t2[$y0] != "") { | |
$out[] = str_replace("\n", "", str_replace("<", "<", $t2[$y0])); | |
} | |
$y0++; | |
} | |
$out[] = "</pre>"; | |
} | |
$out[] = '</li>'; | |
$changeCount ++; | |
} | |
$x1++; | |
$x0=$x1; | |
$y1++; | |
$y0=$y1; | |
$op=0; | |
} | |
$ret["changes"] = join("\n", $out); | |
$ret["changeCount"] = $changeCount; | |
return $ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment