Rev 171 Rev 172
1 <?php 1 <?php
2 # vim:et:ts=3:sts=3:sw=3:fdm=marker: 2 # vim:et:ts=3:sts=3:sw=3:fdm=marker:
3   3  
4 // WebSVN - Subversion repository viewing via the web using PHP 4 // WebSVN - Subversion repository viewing via the web using PHP
5 // Copyright © 2004-2006 Tim Armes, Matt Sicker 5 // Copyright © 2004-2006 Tim Armes, Matt Sicker
6 // 6 //
7 // This program is free software; you can redistribute it and/or modify 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 8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or 9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version. 10 // (at your option) any later version.
11 // 11 //
12 // This program is distributed in the hope that it will be useful, 12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details. 15 // GNU General Public License for more details.
16 // 16 //
17 // You should have received a copy of the GNU General Public License 17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software 18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // 20 //
21 // -- 21 // --
22 // 22 //
23 // diff.php 23 // diff.php
24 // 24 //
25 // Show the differences between 2 revisions of a file. 25 // Show the differences between 2 revisions of a file.
26 // 26 //
27   27  
28 require_once("include/setup.inc"); 28 require_once("include/setup.inc");
29 require_once("include/svnlook.inc"); 29 require_once("include/svnlook.inc");
30 require_once("include/utils.inc"); 30 require_once("include/utils.inc");
31 require_once("include/template.inc"); 31 require_once("include/template.inc");
32   32  
33 $context = 5; 33 $context = 5;
34   34  
35 $vars["action"] = $lang["DIFF"]; 35 $vars["action"] = $lang["DIFF"];
36 $all = (@$_REQUEST["all"] == 1)?1:0; 36 $all = (@$_REQUEST["all"] == 1)?1:0;
37   37  
38 // Make sure that we have a repository 38 // Make sure that we have a repository
39 if (!isset($rep)) 39 if (!isset($rep))
40 { 40 {
41 echo $lang["NOREP"]; 41 echo $lang["NOREP"];
42 exit; 42 exit;
43 } 43 }
44   44  
45 $svnrep = new SVNRepository($rep); 45 $svnrep = new SVNRepository($rep);
46   46  
47 // If there's no revision info, go to the lastest revision for this path 47 // If there's no revision info, go to the lastest revision for this path
48 $history = $svnrep->getLog($path, "", "", true); 48 $history = $svnrep->getLog($path, "", "", true);
49 $youngest = $history->entries[0]->rev; 49 $youngest = $history->entries[0]->rev;
50   50  
51 if (empty($rev)) 51 if (empty($rev))
52 $rev = $youngest; 52 $rev = $youngest;
53   53  
54 $history = $svnrep->getLog($path, $rev); 54 $history = $svnrep->getLog($path, $rev);
55   55  
56 if ($path{0} != "/") 56 if ($path{0} != "/")
57 $ppath = "/".$path; 57 $ppath = "/".$path;
58 else 58 else
59 $ppath = $path; 59 $ppath = $path;
60   60  
61 $prevrev = @$history->entries[1]->rev; 61 $prevrev = @$history->entries[1]->rev;
62   62  
63 $vars["repname"] = $rep->getDisplayName(); 63 $vars["repname"] = $rep->getDisplayName();
64 $vars["rev"] = $rev; 64 $vars["rev"] = $rev;
65 $vars["path"] = $ppath; 65 $vars["path"] = $ppath;
66 $vars["prevrev"] = $prevrev; 66 $vars["prevrev"] = $prevrev;
67   67  
68 $vars["rev1"] = $history->entries[0]->rev; 68 $vars["rev1"] = $history->entries[0]->rev;
69 $vars["rev2"] = $prevrev; 69 $vars["rev2"] = $prevrev;
70   70  
71 createDirLinks($rep, $ppath, $rev, $showchanged); 71 createDirLinks($rep, $ppath, $rev, $showchanged);
72   72  
73 $listing = array(); 73 $listing = array();
74   74  
75 if ($prevrev) 75 if ($prevrev)
76 { 76 {
77 $url = $config->getURL($rep, $path, "diff"); 77 $url = $config->getURL($rep, $path, "diff");
78 78
79 if (!$all) 79 if (!$all)
80 { 80 {
81 $vars["showalllink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=1\">${lang["SHOWENTIREFILE"]}</a>"; 81 $vars["showalllink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=1\">${lang["SHOWENTIREFILE"]}</a>";
82 $vars["showcompactlink"] = ""; 82 $vars["showcompactlink"] = "";
83 } 83 }
84 else 84 else
85 { 85 {
86 $vars["showcompactlink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=0\">${lang["SHOWCOMPACT"]}</a>"; 86 $vars["showcompactlink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=0\">${lang["SHOWCOMPACT"]}</a>";
87 $vars["showalllink"] = ""; 87 $vars["showalllink"] = "";
88 } 88 }
89   89  
90 // Get the contents of the two files 90 // Get the contents of the two files
91 $newtname = tempnam("temp", ""); 91 $newtname = tempnam("temp", "");
92 $new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true); 92 $new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true);
93   93  
94 $oldtname = tempnam("temp", ""); 94 $oldtname = tempnam("temp", "");
95 $old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true); 95 $old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true);
96 96
97 $ent = true; 97 $ent = true;
98 $extension = strrchr(basename($path), "."); 98 $extension = strrchr(basename($path), ".");
99 if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript)) 99 if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
100 $ent = false; 100 $ent = false;
101   101  
102 $file1cache = array(); 102 $file1cache = array();
103   103  
104 if ($all) 104 if ($all)
105 $context = 1; // Setting the context to 0 makes diff generate the wrong line numbers! 105 $context = 1; // Setting the context to 0 makes diff generate the wrong line numbers!
106   106  
107 // Open a pipe to the diff command with $context lines of context 107 // Open a pipe to the diff command with $context lines of context
108 108
109 $cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false); 109 $cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false);
110 110
111 if ($all) 111 if ($all)
112 { 112 {
113 $ofile = fopen($oldtname, "r"); 113 $ofile = fopen($oldtname, "r");
114 $nfile = fopen($newtname, "r"); 114 $nfile = fopen($newtname, "r");
115 } 115 }
116   116  
117 if ($diff = popen($cmd, "r")) 117 if ($diff = popen($cmd, "r"))
118 { 118 {
119 // Ignore the 3 header lines 119 // Ignore the 3 header lines
120 $line = fgets($diff); 120 $line = fgets($diff);
121 $line = fgets($diff); 121 $line = fgets($diff);
122   122  
123 // Get the first real line 123 // Get the first real line
124 $line = fgets($diff); 124 $line = fgets($diff);
125 125
126 $index = 0; 126 $index = 0;
127 $listing = array(); 127 $listing = array();
128 128
129 $curoline = 1; 129 $curoline = 1;
130 $curnline = 1; 130 $curnline = 1;
131 131
132 while (!feof($diff)) 132 while (!feof($diff))
133 { 133 {
134 // Get the first line of this range 134 // Get the first line of this range
135 sscanf($line, "@@ -%d", $oline); 135 sscanf($line, "@@ -%d", $oline);
136 136
137 $line = substr($line, strpos($line, "+")); 137 $line = substr($line, strpos($line, "+"));
138 sscanf($line, "+%d", $nline); 138 sscanf($line, "+%d", $nline);
139 139
140 if ($all) 140 if ($all)
141 { 141 {
142 while ($curoline < $oline || $curnline < $nline) 142 while ($curoline < $oline || $curnline < $nline)
143 { 143 {
144 $listing[$index]["rev1diffclass"] = "diff"; 144 $listing[$index]["rev1diffclass"] = "diff";
145 $listing[$index]["rev2diffclass"] = "diff"; 145 $listing[$index]["rev2diffclass"] = "diff";
146 146
147 if ($curoline < $oline) 147 if ($curoline < $oline)
148 { 148 {
149 $nl = fgets($ofile); 149 $nl = fgets($ofile);
150 150
151 if ($ent) 151 if ($ent)
152 $line = replaceEntities(rtrim($nl), $rep); 152 $line = replaceEntities(rtrim($nl), $rep);
153 else 153 else
154 $line = rtrim($nl); 154 $line = rtrim($nl);
155 155
156 $listing[$index]["rev1line"] = hardspace($line); 156 $listing[$index]["rev1line"] = hardspace($line);
157   157  
158 $curoline++; 158 $curoline++;
159 } 159 }
160 else 160 else
161 $listing[$index]["rev1line"] = "&nbsp;"; 161 $listing[$index]["rev1line"] = "&nbsp;";
162 162
163 if ($curnline < $nline) 163 if ($curnline < $nline)
164 { 164 {
165 $nl = fgets($nfile); 165 $nl = fgets($nfile);
166   166  
167 if ($ent) 167 if ($ent)
168 $line = replaceEntities(rtrim($nl), $rep); 168 $line = replaceEntities(rtrim($nl), $rep);
169 else 169 else
170 $line = rtrim($nl); 170 $line = rtrim($nl);
171 171
172 $listing[$index]["rev2line"] = hardspace($line); 172 $listing[$index]["rev2line"] = hardspace($line);
173 $curnline++; 173 $curnline++;
174 } 174 }
175 else 175 else
176 $listing[$index]["rev2line"] = "&nbsp;"; 176 $listing[$index]["rev2line"] = "&nbsp;";
177 177
178 $listing[$index]["rev1lineno"] = 0; 178 $listing[$index]["rev1lineno"] = 0;
179 $listing[$index]["rev2lineno"] = 0; 179 $listing[$index]["rev2lineno"] = 0;
180   180  
181 $index++; 181 $index++;
182 } 182 }
183 } 183 }
184 else 184 else
185 { 185 {
186 // Output the line numbers 186 // Output the line numbers
187 $listing[$index]["rev1lineno"] = "$oline"; 187 $listing[$index]["rev1lineno"] = "$oline";
188 $listing[$index]["rev2lineno"] = "$nline"; 188 $listing[$index]["rev2lineno"] = "$nline";
189 $index++; 189 $index++;
190 } 190 }
191 191
192 $fin = false; 192 $fin = false;
193 while (!feof($diff) && !$fin) 193 while (!feof($diff) && !$fin)
194 { 194 {
195 $listing[$index]["rev1lineno"] = 0; 195 $listing[$index]["rev1lineno"] = 0;
196 $listing[$index]["rev2lineno"] = 0; 196 $listing[$index]["rev2lineno"] = 0;
197   197  
198 $line = fgets($diff); 198 $line = fgets($diff);
199 if (!strncmp($line, "@@", 2)) 199 if (!strncmp($line, "@@", 2))
200 { 200 {
201 $fin = true; 201 $fin = true;
202 } 202 }
203 else 203 else
204 { 204 {
205 $mod = $line{0}; 205 $mod = $line{0};
206   206  
207 if ($ent) 207 if ($ent)
208 $line = replaceEntities(rtrim(substr($line, 1)), $rep); 208 $line = replaceEntities(rtrim(substr($line, 1)), $rep);
209 else 209 else
210 $line = rtrim(substr($line, 1)); 210 $line = rtrim(substr($line, 1));
211 211
212 $listing[$index]["rev1line"] = hardspace($line); 212 $listing[$index]["rev1line"] = hardspace($line);
213   213  
214 $text = hardspace($line); 214 $text = hardspace($line);
215 if ($text == "") $text = "&nbsp;"; 215 if ($text == "") $text = "&nbsp;";
216 216
217 switch ($mod) 217 switch ($mod)
218 { 218 {
219 case "-": 219 case "-":
220 $listing[$index]["rev1diffclass"] = "diffdeleted"; 220 $listing[$index]["rev1diffclass"] = "diffdeleted";
221 $listing[$index]["rev2diffclass"] = "diff"; 221 $listing[$index]["rev2diffclass"] = "diff";
222 222
223 $listing[$index]["rev1line"] = $text; 223 $listing[$index]["rev1line"] = $text;
224 $listing[$index]["rev2line"] = "&nbsp;"; 224 $listing[$index]["rev2line"] = "&nbsp;";
225 225
226 if ($all) 226 if ($all)
227 { 227 {
228 fgets($ofile); 228 fgets($ofile);
229 $curoline++; 229 $curoline++;
230 } 230 }
231 231
232 break; 232 break;
233   233  
234 case "+": 234 case "+":
235 235
236 // Try to mark "changed" line sensibly 236 // Try to mark "changed" line sensibly
237 if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff") 237 if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff")
238 { 238 {
239 $i = $index - 1; 239 $i = $index - 1;
240 while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff") 240 while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff")
241 $i--; 241 $i--;
242 242
243 $listing[$i]["rev1diffclass"] = "diffchanged"; 243 $listing[$i]["rev1diffclass"] = "diffchanged";
244 $listing[$i]["rev2diffclass"] = "diffchanged"; 244 $listing[$i]["rev2diffclass"] = "diffchanged";
245 $listing[$i]["rev2line"] = $text; 245 $listing[$i]["rev2line"] = $text;
246 246
247 if ($all) 247 if ($all)
248 { 248 {
249 fgets($nfile); 249 fgets($nfile);
250 $curnline++; 250 $curnline++;
251 } 251 }
252   252  
253 // Don't increment the current index count 253 // Don't increment the current index count
254 $index--; 254 $index--;
255 } 255 }
256 else 256 else
257 { 257 {
258 $listing[$index]["rev1diffclass"] = "diff"; 258 $listing[$index]["rev1diffclass"] = "diff";
259 $listing[$index]["rev2diffclass"] = "diffadded"; 259 $listing[$index]["rev2diffclass"] = "diffadded";
260 260
261 $listing[$index]["rev1line"] = "&nbsp;"; 261 $listing[$index]["rev1line"] = "&nbsp;";
262 $listing[$index]["rev2line"] = $text; 262 $listing[$index]["rev2line"] = $text;
263   263  
264 if ($all) 264 if ($all)
265 { 265 {
266 fgets($nfile); 266 fgets($nfile);
267 $curnline++; 267 $curnline++;
268 } 268 }
269 } 269 }
270 break; 270 break;
271 271
272 default: 272 default:
273 $listing[$index]["rev1diffclass"] = "diff"; 273 $listing[$index]["rev1diffclass"] = "diff";
274 $listing[$index]["rev2diffclass"] = "diff"; 274 $listing[$index]["rev2diffclass"] = "diff";
275 275
276 $listing[$index]["rev1line"] = $text; 276 $listing[$index]["rev1line"] = $text;
277 $listing[$index]["rev2line"] = $text; 277 $listing[$index]["rev2line"] = $text;
278 278
279 if ($all) 279 if ($all)
280 { 280 {
281 fgets($ofile); 281 fgets($ofile);
282 fgets($nfile); 282 fgets($nfile);
283 $curoline++; 283 $curoline++;
284 $curnline++; 284 $curnline++;
285 } 285 }
286   286  
287 break; 287 break;
288 } 288 }
289 } 289 }
290 290
291 if (!$fin) 291 if (!$fin)
292 $index++; 292 $index++;
293 } 293 }
294 } 294 }
295 295
296 // Output the rest of the files 296 // Output the rest of the files
297 if ($all) 297 if ($all)
298 { 298 {
299 while (!feof($ofile) || !feof($nfile)) 299 while (!feof($ofile) || !feof($nfile))
300 { 300 {
301 $listing[$index]["rev1diffclass"] = "diff"; 301 $listing[$index]["rev1diffclass"] = "diff";
302 $listing[$index]["rev2diffclass"] = "diff"; 302 $listing[$index]["rev2diffclass"] = "diff";
303 303
304 if ($ent) 304 if ($ent)
305 $line = replaceEntities(rtrim(fgets($ofile)), $rep); 305 $line = replaceEntities(rtrim(fgets($ofile)), $rep);
306 else 306 else
307 $line = rtrim(fgets($ofile)); 307 $line = rtrim(fgets($ofile));
308   308  
309 if (!feof($ofile)) 309 if (!feof($ofile))
310 $listing[$index]["rev1line"] = hardspace($line); 310 $listing[$index]["rev1line"] = hardspace($line);
311 else 311 else
312 $listing[$index]["rev1line"] = "&nbsp;"; 312 $listing[$index]["rev1line"] = "&nbsp;";
313 313
314 if ($ent) 314 if ($ent)
315 $line = replaceEntities(rtrim(fgets($nfile)), $rep); 315 $line = replaceEntities(rtrim(fgets($nfile)), $rep);
316 else 316 else
317 $line = rtrim(fgets($nfile)); 317 $line = rtrim(fgets($nfile));
318   318  
319 if (!feof($nfile)) 319 if (!feof($nfile))
320 $listing[$index]["rev2line"] = hardspace($line); 320 $listing[$index]["rev2line"] = hardspace($line);
321 else 321 else
322 $listing[$index]["rev2line"] = "&nbsp;"; 322 $listing[$index]["rev2line"] = "&nbsp;";
323 323
324 $listing[$index]["rev1lineno"] = 0; 324 $listing[$index]["rev1lineno"] = 0;
325 $listing[$index]["rev2lineno"] = 0; 325 $listing[$index]["rev2lineno"] = 0;
326   326  
327 $index++; 327 $index++;
328 } 328 }
329 } 329 }
330 330
331 pclose($diff); 331 pclose($diff);
332 } 332 }
333 333
334 if ($all) 334 if ($all)
335 { 335 {
336 fclose($ofile); 336 fclose($ofile);
337 fclose($nfile); 337 fclose($nfile);
338 } 338 }
339   339  
340 // Remove our temporary files 340 // Remove our temporary files
341 unlink($oldtname); 341 unlink($oldtname);
342 unlink($newtname); 342 unlink($newtname);
343 } 343 }
344 else 344 else
345 { 345 {
346 $vars["noprev"] = 1; 346 $vars["noprev"] = 1;
347 } 347 }
348   348  
349 $vars["version"] = $version; 349 $vars["version"] = $version;
350   350  
351 if (!$rep->hasReadAccess($path, false)) 351 if (!$rep->hasReadAccess($path, false))
352 $vars["noaccess"] = true; 352 $vars["noaccess"] = true;
353   353  
354 parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); 354 parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
355 parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing); 355 parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing);
356 parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); 356 parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
357 357
358 ?> 358 ?>