2 /*=====================================================================*\
3 || ###################################################################
4 || # ViewSVN [#]version[#]
5 || # Copyright ©2002-[#]year[#] Blue Static
7 || # This program is free software; you can redistribute it and/or modify
8 || # it under the terms of the GNU General Public License as published by
9 || # the Free Software Foundation; version [#]gpl[#] of the License.
11 || # This program is distributed in the hope that it will be useful, but
12 || # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 || # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 || # You should have received a copy of the GNU General Public License along
17 || # with this program; if not, write to the Free Software Foundation, Inc.,
18 || # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 || ###################################################################
20 \*=====================================================================*/
25 * This class parses a diff file from a unified diff file and turns it
26 * into a HTML-prettied output
29 * @copyright Copyright (c)2002 - [#]year[#], Blue Static
37 * Raw unified diff text
43 * The current index (file)
49 * The array index of where capturing of diff data starts
52 private $captureStart = 0;
55 * Current hunk that is being processed
61 * The lines on which hunks start
64 private $hunkLines = array('old' => array('line' => 0, 'count' => 0), 'new' => array('line' => 0, 'count' => 0));
67 * The parsed diff output
70 private $diff = array();
72 // ###################################################################
76 * @param string Raw unified diff output
78 public function __construct($raw)
83 // ###################################################################
85 * This function initiates the parsing process and returns the output
86 * in hunks, line-by-line
88 * @return array Array of outputted hunked information
90 public function fetch()
92 for ($i = 0; $i < sizeof($this->raw
); $i++
)
94 $line = $this->raw
[$i];
96 if (preg_match('/^Index: (.*)/', $line, $index))
98 $this->_processFile(array_slice($this->raw
, $this->captureStart
, $i - $this->captureStart
));
99 $this->captureStart
= $i;
100 $this->index
= $index[1];
103 $this->_processFile(array_slice($this->raw
, $this->captureStart
));
108 // ###################################################################
110 * Processes a file part of a diff
112 * @param array An array of lines that make up a file chunk
114 private function _processFile($lines)
116 preg_match_all('/[\-\+]{3}\s+(.*)\s+\(revision ([0-9]*)\)/', $lines[2] . "\n" . $lines[3], $revs);
117 $this->diff
[$this->index
]['revision']['low'] = $revs[2][0];
118 $this->diff
[$this->index
]['revision']['high'] = $revs[2][1];
123 for ($i = 4; $i < sizeof($lines); $i++
)
127 if (preg_match('/^@@ \-([0-9]*),([0-9]*) \+([0-9]*),([0-9]*) @@/', $line, $hunkHead))
129 $this->hunkLines
= array('old' => array('line' => $hunkHead[1], 'count' => $hunkHead[2]), 'new' => array('line' => $hunkHead[3], 'count' => $hunkHead[4]));
130 $this->_processHunk(array_slice($lines, $captureStart, $i - $captureStart));
134 else if (preg_match('#^__*_$#', $line))
136 $this->_processHunk(array_slice($lines, $captureStart, $i - $captureStart));
137 $this->_processProperties(array_slice($lines, $i));
141 $this->_processHunk(array_slice($lines, $captureStart));
144 // ###################################################################
146 * This processes an individual hunk of a file
148 * @param array Array of lines
150 private function _processHunk($lines)
153 for ($i = 1; $i < sizeof($lines); $i++
)
157 if (preg_match('/^([\+\- ])(.*)/', $line, $matches))
159 $action = $matches[1];
160 $content = $matches[2];
165 $this->diff
[$this->index
]['lines'][$this->hunkId
][] = array(
168 'oldlineno' => ++
$this->hunkLines
['old']['line'],
169 'newlineno' => ++
$this->hunkLines
['new']['line']
175 else if ($action == '+')
177 // potential line delta
178 if (sizeof($delstack) > 0)
180 $lastline = array_shift($delstack);
182 if ($delta = @$this->_fetchDiffExtent($lastline['line'], $content))
184 if (strlen($lastline['line']) > ($delta['start'] - $delta['end']))
186 $end = strlen($lastline['line']) +
$delta['end'];
187 $change = '{@-' . '-}' . substr($lastline['line'], $delta['start'], $end - $delta['start']) . '{/@-' . '-}';
188 $this->diff
[$this->index
]['lines'][$this->hunkId
][$lastline['index']]['line'] = substr($lastline['line'], 0, $delta['start']) . $change . substr($lastline['line'], $end);
191 if (strlen($content) > $delta['start'] - $delta['end'])
193 $end = strlen($content) +
$delta['end'];
194 $change = '{@+' . '+}' . substr($content, $delta['start'], $end - $delta['start']) . '{/@+' . '+}';
195 $content = substr($content, 0, $delta['start']) . $change . substr($content, $end);
200 $this->diff
[$this->index
]['lines'][$this->hunkId
][] = array(
204 'newlineno' => ++
$this->hunkLines
['new']['line']
208 else if ($action == '-')
210 $this->diff
[$this->index
]['lines'][$this->hunkId
][] = $temp = array(
213 'oldlineno' => ++
$this->hunkLines
['old']['line'],
217 $temp['index'] = sizeof($this->diff
[$this->index
]['lines'][$this->hunkId
]) - 1;
218 array_push($delstack, $temp);
224 // ###################################################################
226 * Processes properties
228 * @param array Lines of properties
230 private function _processProperties($lines)
235 for ($i = 1; $i < sizeof($lines); $i++
)
238 if (preg_match('#Name: (.*?)$#', $line, $matches))
240 $curprop = $matches[1];
241 BSRegister
::Debug("prop: $curprop");
245 if (preg_match('#^\s+?\+(.*)#', $line, $matches))
248 $this->diff
[$this->index
]['props'][$curprop]['add'] .= $matches[1];
250 else if (preg_match('#^\s+?\-(.*)#', $line, $matches))
253 $this->diff
[$this->index
]['props'][$curprop]['del'] .= $matches[1];
255 else if (!preg_match('#^\s+[\+\- ](.*)#', $line) AND trim($line) != '')
257 $this->diff
[$this->index
]['props'][$curprop][$mode] .= "\n" . $line;
263 // ###################################################################
265 * Returns the amount of change that occured between two lines
267 * @param string Old line
268 * @param string New line
270 * @return array Difference of positions
272 private function _fetchDiffExtent($old, $new)
275 $min = min(strlen($old), strlen($new));
277 while ($start < $min AND $old[$start] == $new[$start])
283 $min = $min - $start;
285 while (-$end <= $min AND $old[strlen($old) +
$end] == $new[strlen($new) +
$end])
290 return array('start' => $start, 'end' => $end +
1);
294 /*=====================================================================*\
295 || ###################################################################
298 || ###################################################################
299 \*=====================================================================*/