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