/ASTRA_Demo_Server/udrive/www/astra/interact/includes/pear/Text/Diff3.php

https://github.com/shafiqissani/ASTRA-College-Website · PHP · 262 lines · 178 code · 39 blank · 45 comment · 37 complexity · 864e3bf79093161f7ae81533acfeda42 MD5 · raw file

  1. <?php
  2. require_once 'Text/Diff.php';
  3. /**
  4. * A class for computing three way diffs.
  5. *
  6. * $Horde: framework/Text_Diff/Diff3.php,v 1.4 2005/07/03 05:10:11 selsky Exp $
  7. *
  8. * @package Text_Diff
  9. * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
  10. */
  11. class Text_Diff3 extends Text_Diff {
  12. /**
  13. * Conflict counter.
  14. *
  15. * @var integer
  16. */
  17. var $_conflictingBlocks = 0;
  18. /**
  19. * Computes diff between 3 sequences of strings.
  20. *
  21. * @param array $orig The original lines to use.
  22. * @param array $final1 The first version to compare to.
  23. * @param array $final2 The second version to compare to.
  24. */
  25. function Text_Diff3($orig, $final1, $final2)
  26. {
  27. if (extension_loaded('xdiff')) {
  28. $engine = &new Text_Diff_Engine_xdiff();
  29. } else {
  30. $engine = &new Text_Diff_Engine_native();
  31. }
  32. $this->_edits = $this->_diff3($engine->diff($orig, $final1),
  33. $engine->diff($orig, $final2));
  34. }
  35. function mergedOutput($label1 = false, $label2 = false)
  36. {
  37. $lines = array();
  38. foreach ($this->_edits as $edit) {
  39. if ($edit->isConflict()) {
  40. /* FIXME: this should probably be moved somewhere else. */
  41. $lines = array_merge($lines,
  42. array('<<<<<<<' . ($label1 ? ' ' . $label1 : '')),
  43. $edit->final1,
  44. array("======="),
  45. $edit->final2,
  46. array('>>>>>>>' . ($label2 ? ' ' . $label2 : '')));
  47. $this->_conflictingBlocks++;
  48. } else {
  49. $lines = array_merge($lines, $edit->merged());
  50. }
  51. }
  52. return $lines;
  53. }
  54. /**
  55. * @access private
  56. */
  57. function _diff3($edits1, $edits2)
  58. {
  59. $edits = array();
  60. $bb = &new Text_Diff3_BlockBuilder();
  61. $e1 = current($edits1);
  62. $e2 = current($edits2);
  63. while ($e1 || $e2) {
  64. if ($e1 && $e2 && is_a($e1, 'Text_Diff_Op_copy') && is_a($e2, 'Text_Diff_Op_copy')) {
  65. /* We have copy blocks from both diffs. This is the (only)
  66. * time we want to emit a diff3 copy block. Flush current
  67. * diff3 diff block, if any. */
  68. if ($edit = $bb->finish()) {
  69. $edits[] = $edit;
  70. }
  71. $ncopy = min($e1->norig(), $e2->norig());
  72. assert($ncopy > 0);
  73. $edits[] = &new Text_Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
  74. if ($e1->norig() > $ncopy) {
  75. array_splice($e1->orig, 0, $ncopy);
  76. array_splice($e1->final, 0, $ncopy);
  77. } else {
  78. $e1 = next($edits1);
  79. }
  80. if ($e2->norig() > $ncopy) {
  81. array_splice($e2->orig, 0, $ncopy);
  82. array_splice($e2->final, 0, $ncopy);
  83. } else {
  84. $e2 = next($edits2);
  85. }
  86. } else {
  87. if ($e1 && $e2) {
  88. if ($e1->orig && $e2->orig) {
  89. $norig = min($e1->norig(), $e2->norig());
  90. $orig = array_splice($e1->orig, 0, $norig);
  91. array_splice($e2->orig, 0, $norig);
  92. $bb->input($orig);
  93. }
  94. if (is_a($e1, 'Text_Diff_Op_copy')) {
  95. $bb->out1(array_splice($e1->final, 0, $norig));
  96. }
  97. if (is_a($e2, 'Text_Diff_Op_copy')) {
  98. $bb->out2(array_splice($e2->final, 0, $norig));
  99. }
  100. }
  101. if ($e1 && ! $e1->orig) {
  102. $bb->out1($e1->final);
  103. $e1 = next($edits1);
  104. }
  105. if ($e2 && ! $e2->orig) {
  106. $bb->out2($e2->final);
  107. $e2 = next($edits2);
  108. }
  109. }
  110. }
  111. if ($edit = $bb->finish()) {
  112. $edits[] = $edit;
  113. }
  114. return $edits;
  115. }
  116. }
  117. /**
  118. * @package Text_Diff
  119. * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
  120. *
  121. * @access private
  122. */
  123. class Text_Diff3_Op {
  124. function Text_Diff3_Op($orig = false, $final1 = false, $final2 = false)
  125. {
  126. $this->orig = $orig ? $orig : array();
  127. $this->final1 = $final1 ? $final1 : array();
  128. $this->final2 = $final2 ? $final2 : array();
  129. }
  130. function merged()
  131. {
  132. if (!isset($this->_merged)) {
  133. if ($this->final1 === $this->final2) {
  134. $this->_merged = &$this->final1;
  135. } elseif ($this->final1 === $this->orig) {
  136. $this->_merged = &$this->final2;
  137. } elseif ($this->final2 === $this->orig) {
  138. $this->_merged = &$this->final1;
  139. } else {
  140. $this->_merged = false;
  141. }
  142. }
  143. return $this->_merged;
  144. }
  145. function isConflict()
  146. {
  147. return $this->merged() === false;
  148. }
  149. }
  150. /**
  151. * @package Text_Diff
  152. * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
  153. *
  154. * @access private
  155. */
  156. class Text_Diff3_Op_copy extends Text_Diff3_Op {
  157. function Text_Diff3_Op_Copy($lines = false)
  158. {
  159. $this->orig = $lines ? $lines : array();
  160. $this->final1 = &$this->orig;
  161. $this->final2 = &$this->orig;
  162. }
  163. function merged()
  164. {
  165. return $this->orig;
  166. }
  167. function isConflict()
  168. {
  169. return false;
  170. }
  171. }
  172. /**
  173. * @package Text_Diff
  174. * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
  175. *
  176. * @access private
  177. */
  178. class Text_Diff3_BlockBuilder {
  179. function Text_Diff3_BlockBuilder()
  180. {
  181. $this->_init();
  182. }
  183. function input($lines)
  184. {
  185. if ($lines) {
  186. $this->_append($this->orig, $lines);
  187. }
  188. }
  189. function out1($lines)
  190. {
  191. if ($lines) {
  192. $this->_append($this->final1, $lines);
  193. }
  194. }
  195. function out2($lines)
  196. {
  197. if ($lines) {
  198. $this->_append($this->final2, $lines);
  199. }
  200. }
  201. function isEmpty()
  202. {
  203. return !$this->orig && !$this->final1 && !$this->final2;
  204. }
  205. function finish()
  206. {
  207. if ($this->isEmpty()) {
  208. return false;
  209. } else {
  210. $edit = &new Text_Diff3_Op($this->orig, $this->final1, $this->final2);
  211. $this->_init();
  212. return $edit;
  213. }
  214. }
  215. function _init()
  216. {
  217. $this->orig = $this->final1 = $this->final2 = array();
  218. }
  219. function _append(&$array, $lines)
  220. {
  221. array_splice($array, sizeof($array), 0, $lines);
  222. }
  223. }