annotate vendor/sebastian/diff/src/Parser.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2 /*
Chris@0 3 * This file is part of the Diff package.
Chris@0 4 *
Chris@0 5 * (c) Sebastian Bergmann <sebastian@phpunit.de>
Chris@0 6 *
Chris@0 7 * For the full copyright and license information, please view the LICENSE
Chris@0 8 * file that was distributed with this source code.
Chris@0 9 */
Chris@0 10
Chris@0 11 namespace SebastianBergmann\Diff;
Chris@0 12
Chris@0 13 /**
Chris@0 14 * Unified diff parser.
Chris@0 15 */
Chris@0 16 class Parser
Chris@0 17 {
Chris@0 18 /**
Chris@0 19 * @param string $string
Chris@0 20 *
Chris@0 21 * @return Diff[]
Chris@0 22 */
Chris@0 23 public function parse($string)
Chris@0 24 {
Chris@0 25 $lines = preg_split('(\r\n|\r|\n)', $string);
Chris@0 26 $lineCount = count($lines);
Chris@0 27 $diffs = array();
Chris@0 28 $diff = null;
Chris@0 29 $collected = array();
Chris@0 30
Chris@0 31 for ($i = 0; $i < $lineCount; ++$i) {
Chris@0 32 if (preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
Chris@0 33 preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
Chris@0 34 if ($diff !== null) {
Chris@0 35 $this->parseFileDiff($diff, $collected);
Chris@0 36 $diffs[] = $diff;
Chris@0 37 $collected = array();
Chris@0 38 }
Chris@0 39
Chris@0 40 $diff = new Diff($fromMatch['file'], $toMatch['file']);
Chris@0 41 ++$i;
Chris@0 42 } else {
Chris@0 43 if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
Chris@0 44 continue;
Chris@0 45 }
Chris@0 46 $collected[] = $lines[$i];
Chris@0 47 }
Chris@0 48 }
Chris@0 49
Chris@0 50 if (count($collected) && ($diff !== null)) {
Chris@0 51 $this->parseFileDiff($diff, $collected);
Chris@0 52 $diffs[] = $diff;
Chris@0 53 }
Chris@0 54
Chris@0 55 return $diffs;
Chris@0 56 }
Chris@0 57
Chris@0 58 /**
Chris@0 59 * @param Diff $diff
Chris@0 60 * @param array $lines
Chris@0 61 */
Chris@0 62 private function parseFileDiff(Diff $diff, array $lines)
Chris@0 63 {
Chris@0 64 $chunks = array();
Chris@0 65
Chris@0 66 foreach ($lines as $line) {
Chris@0 67 if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
Chris@0 68 $chunk = new Chunk(
Chris@0 69 $match['start'],
Chris@0 70 isset($match['startrange']) ? max(1, $match['startrange']) : 1,
Chris@0 71 $match['end'],
Chris@0 72 isset($match['endrange']) ? max(1, $match['endrange']) : 1
Chris@0 73 );
Chris@0 74
Chris@0 75 $chunks[] = $chunk;
Chris@0 76 $diffLines = array();
Chris@0 77 continue;
Chris@0 78 }
Chris@0 79
Chris@0 80 if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
Chris@0 81 $type = Line::UNCHANGED;
Chris@0 82
Chris@0 83 if ($match['type'] == '+') {
Chris@0 84 $type = Line::ADDED;
Chris@0 85 } elseif ($match['type'] == '-') {
Chris@0 86 $type = Line::REMOVED;
Chris@0 87 }
Chris@0 88
Chris@0 89 $diffLines[] = new Line($type, $match['line']);
Chris@0 90
Chris@0 91 if (isset($chunk)) {
Chris@0 92 $chunk->setLines($diffLines);
Chris@0 93 }
Chris@0 94 }
Chris@0 95 }
Chris@0 96
Chris@0 97 $diff->setChunks($chunks);
Chris@0 98 }
Chris@0 99 }