Yaffs site version 1.1
[yaffs-website] / vendor / sebastian / diff / src / Parser.php
1 <?php
2 /*
3  * This file is part of sebastian/diff.
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
27         if (!empty($lines) && $lines[\count($lines) - 1] == '') {
28             \array_pop($lines);
29         }
30
31         $lineCount = \count($lines);
32         $diffs     = array();
33         $diff      = null;
34         $collected = array();
35
36         for ($i = 0; $i < $lineCount; ++$i) {
37             if (\preg_match('(^---\\s+(?P<file>\\S+))', $lines[$i], $fromMatch) &&
38                 \preg_match('(^\\+\\+\\+\\s+(?P<file>\\S+))', $lines[$i + 1], $toMatch)) {
39                 if ($diff !== null) {
40                     $this->parseFileDiff($diff, $collected);
41
42                     $diffs[]   = $diff;
43                     $collected = array();
44                 }
45
46                 $diff = new Diff($fromMatch['file'], $toMatch['file']);
47
48                 ++$i;
49             } else {
50                 if (\preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
51                     continue;
52                 }
53
54                 $collected[] = $lines[$i];
55             }
56         }
57
58         if ($diff !== null && \count($collected)) {
59             $this->parseFileDiff($diff, $collected);
60
61             $diffs[] = $diff;
62         }
63
64         return $diffs;
65     }
66
67     /**
68      * @param Diff  $diff
69      * @param array $lines
70      */
71     private function parseFileDiff(Diff $diff, array $lines)
72     {
73         $chunks = array();
74         $chunk  = null;
75
76         foreach ($lines as $line) {
77             if (\preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
78                 $chunk = new Chunk(
79                     $match['start'],
80                     isset($match['startrange']) ? \max(1, $match['startrange']) : 1,
81                     $match['end'],
82                     isset($match['endrange']) ? \max(1, $match['endrange']) : 1
83                 );
84
85                 $chunks[]  = $chunk;
86                 $diffLines = array();
87
88                 continue;
89             }
90
91             if (\preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
92                 $type = Line::UNCHANGED;
93
94                 if ($match['type'] === '+') {
95                     $type = Line::ADDED;
96                 } elseif ($match['type'] === '-') {
97                     $type = Line::REMOVED;
98                 }
99
100                 $diffLines[] = new Line($type, $match['line']);
101
102                 if (null !== $chunk) {
103                     $chunk->setLines($diffLines);
104                 }
105             }
106         }
107
108         $diff->setChunks($chunks);
109     }
110 }