annotate core/lib/Drupal/Component/Diff/Diff.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 1fec387a4317
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Component\Diff;
Chris@0 4
Chris@0 5 use Drupal\Component\Diff\Engine\DiffEngine;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * Class representing a 'diff' between two sequences of strings.
Chris@0 9 * @todo document
Chris@0 10 * @subpackage DifferenceEngine
Chris@0 11 *
Chris@0 12 * Copied from https://www.drupal.org/project/diff which was based PHP diff
Chris@0 13 * engine for phpwiki. (Taken from phpwiki-1.3.3) The original code in phpwiki
Chris@0 14 * was copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> and
Chris@0 15 * licensed under GPL.
Chris@0 16 */
Chris@0 17 class Diff {
Chris@0 18
Chris@0 19 /**
Chris@0 20 * The list of differences as an array of diff operations.
Chris@0 21 *
Chris@0 22 * @var \Drupal\Component\Diff\Engine\DiffOp[]
Chris@0 23 */
Chris@0 24 protected $edits;
Chris@0 25
Chris@0 26 /**
Chris@0 27 * Constructor.
Chris@0 28 * Computes diff between sequences of strings.
Chris@0 29 *
Chris@0 30 * @param array $from_lines
Chris@0 31 * An array of strings.
Chris@0 32 * (Typically these are lines from a file.)
Chris@0 33 * @param array $to_lines
Chris@0 34 * An array of strings.
Chris@0 35 */
Chris@0 36 public function __construct($from_lines, $to_lines) {
Chris@0 37 $eng = new DiffEngine();
Chris@0 38 $this->edits = $eng->diff($from_lines, $to_lines);
Chris@0 39 //$this->_check($from_lines, $to_lines);
Chris@0 40 }
Chris@0 41
Chris@0 42 /**
Chris@0 43 * Compute reversed Diff.
Chris@0 44 *
Chris@0 45 * SYNOPSIS:
Chris@0 46 *
Chris@0 47 * $diff = new Diff($lines1, $lines2);
Chris@0 48 * $rev = $diff->reverse();
Chris@0 49 * @return object
Chris@0 50 * A Diff object representing the inverse of the original diff.
Chris@0 51 */
Chris@0 52 public function reverse() {
Chris@0 53 $rev = $this;
Chris@0 54 $rev->edits = [];
Chris@0 55 foreach ($this->edits as $edit) {
Chris@0 56 $rev->edits[] = $edit->reverse();
Chris@0 57 }
Chris@0 58 return $rev;
Chris@0 59 }
Chris@0 60
Chris@0 61 /**
Chris@0 62 * Check for empty diff.
Chris@0 63 *
Chris@0 64 * @return bool True iff two sequences were identical.
Chris@0 65 */
Chris@0 66 public function isEmpty() {
Chris@0 67 foreach ($this->edits as $edit) {
Chris@0 68 if ($edit->type != 'copy') {
Chris@0 69 return FALSE;
Chris@0 70 }
Chris@0 71 }
Chris@0 72 return TRUE;
Chris@0 73 }
Chris@0 74
Chris@0 75 /**
Chris@0 76 * Compute the length of the Longest Common Subsequence (LCS).
Chris@0 77 *
Chris@0 78 * This is mostly for diagnostic purposed.
Chris@0 79 *
Chris@0 80 * @return int The length of the LCS.
Chris@0 81 */
Chris@0 82 public function lcs() {
Chris@0 83 $lcs = 0;
Chris@0 84 foreach ($this->edits as $edit) {
Chris@0 85 if ($edit->type == 'copy') {
Chris@0 86 $lcs += sizeof($edit->orig);
Chris@0 87 }
Chris@0 88 }
Chris@0 89 return $lcs;
Chris@0 90 }
Chris@0 91
Chris@0 92 /**
Chris@0 93 * Gets the original set of lines.
Chris@0 94 *
Chris@0 95 * This reconstructs the $from_lines parameter passed to the
Chris@0 96 * constructor.
Chris@0 97 *
Chris@0 98 * @return array The original sequence of strings.
Chris@0 99 */
Chris@0 100 public function orig() {
Chris@0 101 $lines = [];
Chris@0 102
Chris@0 103 foreach ($this->edits as $edit) {
Chris@0 104 if ($edit->orig) {
Chris@0 105 array_splice($lines, sizeof($lines), 0, $edit->orig);
Chris@0 106 }
Chris@0 107 }
Chris@0 108 return $lines;
Chris@0 109 }
Chris@0 110
Chris@0 111 /**
Chris@0 112 * Gets the closing set of lines.
Chris@0 113 *
Chris@0 114 * This reconstructs the $to_lines parameter passed to the
Chris@0 115 * constructor.
Chris@0 116 *
Chris@0 117 * @return array The sequence of strings.
Chris@0 118 */
Chris@0 119 public function closing() {
Chris@0 120 $lines = [];
Chris@0 121
Chris@0 122 foreach ($this->edits as $edit) {
Chris@0 123 if ($edit->closing) {
Chris@0 124 array_splice($lines, sizeof($lines), 0, $edit->closing);
Chris@0 125 }
Chris@0 126 }
Chris@0 127 return $lines;
Chris@0 128 }
Chris@0 129
Chris@0 130 /**
Chris@0 131 * Check a Diff for validity.
Chris@0 132 *
Chris@0 133 * This is here only for debugging purposes.
Chris@0 134 */
Chris@0 135 public function check($from_lines, $to_lines) {
Chris@0 136 if (serialize($from_lines) != serialize($this->orig())) {
Chris@0 137 trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
Chris@0 138 }
Chris@0 139 if (serialize($to_lines) != serialize($this->closing())) {
Chris@0 140 trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
Chris@0 141 }
Chris@0 142
Chris@0 143 $rev = $this->reverse();
Chris@0 144 if (serialize($to_lines) != serialize($rev->orig())) {
Chris@0 145 trigger_error("Reversed original doesn't match", E_USER_ERROR);
Chris@0 146 }
Chris@0 147 if (serialize($from_lines) != serialize($rev->closing())) {
Chris@0 148 trigger_error("Reversed closing doesn't match", E_USER_ERROR);
Chris@0 149 }
Chris@0 150
Chris@0 151 $prevtype = 'none';
Chris@0 152 foreach ($this->edits as $edit) {
Chris@0 153 if ( $prevtype == $edit->type ) {
Chris@0 154 trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
Chris@0 155 }
Chris@0 156 $prevtype = $edit->type;
Chris@0 157 }
Chris@0 158
Chris@0 159 $lcs = $this->lcs();
Chris@0 160 trigger_error('Diff okay: LCS = ' . $lcs, E_USER_NOTICE);
Chris@0 161 }
Chris@0 162
Chris@0 163 /**
Chris@0 164 * Gets the list of differences as an array of diff operations.
Chris@0 165 *
Chris@0 166 * @return \Drupal\Component\Diff\Engine\DiffOp[]
Chris@0 167 * The list of differences as an array of diff operations.
Chris@0 168 */
Chris@0 169 public function getEdits() {
Chris@0 170 return $this->edits;
Chris@0 171 }
Chris@0 172
Chris@0 173 }