1 | <?php
|
---|
2 |
|
---|
3 | require "../Odin32DBhelpers.php3";
|
---|
4 |
|
---|
5 | /*
|
---|
6 | * Configuration:
|
---|
7 | */
|
---|
8 | $sCVSROOT = ".";
|
---|
9 | $sCVSROOT = "d:/odin32/cvs/cvsroot";
|
---|
10 |
|
---|
11 |
|
---|
12 | /**
|
---|
13 | * Quick and dirty CVS file parser.
|
---|
14 | */
|
---|
15 | class CVSFile
|
---|
16 | {
|
---|
17 | var $fOk; /* Status of contructor. */
|
---|
18 | var $sError; /* Last error message. */
|
---|
19 | var $sFullName; /* Full path of the */
|
---|
20 | var $sDir; /* CVSROOT relative directory */
|
---|
21 | var $sName; /* Workfile filename. */
|
---|
22 | var $sExt; /* Workfile extention. */
|
---|
23 | var $aasKeys; /* base keys */
|
---|
24 | var $aasDeltas; /* the text values only */
|
---|
25 | var $aaasRevs; /* all types of revision info (but the text) */
|
---|
26 |
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Constructor.
|
---|
30 | * Opens a CVS repository file, reads it into memory and closes it.
|
---|
31 | */
|
---|
32 | function CVSFile($sFilename, $fNoDeltas)
|
---|
33 | {
|
---|
34 | global $sCVSROOT;
|
---|
35 |
|
---|
36 | $timer = Odin32DBTimerStart("");
|
---|
37 |
|
---|
38 | $this->fOk = 0;
|
---|
39 | /*
|
---|
40 | * TODO: Security: Check that the path and filename is valid!
|
---|
41 | * We can't allow relative paths (ie. "..")
|
---|
42 | */
|
---|
43 | if (strlen($sFilename) < 3 || substr($sFilename, strlen($sFilename)-2) != ",v")
|
---|
44 | {
|
---|
45 | $this->sError = "filename is invalid";
|
---|
46 | return 1;
|
---|
47 | }
|
---|
48 |
|
---|
49 | /*
|
---|
50 | * Check filesize. Minimum size is 10 bytes!
|
---|
51 | */
|
---|
52 | $this->sFullname = $sCVSROOT."/".$sFilename;
|
---|
53 | $cbFile = filesize($this->sFullname);
|
---|
54 | if ($cbFile <= 10)
|
---|
55 | {
|
---|
56 | $this->sError = "too small file, " . $this->sFullname . ", ". $cbFile ."\n";
|
---|
57 | return 1;
|
---|
58 | }
|
---|
59 | if (!$fNoDeltas && $cbFile >= (2*1024*1024)) //currently max size of 2MB.
|
---|
60 | {
|
---|
61 | $this->sError = "\ntoo large file, ". $this->sFullname .", ". $cbFile ."\n";
|
---|
62 | return 1;
|
---|
63 | }
|
---|
64 |
|
---|
65 |
|
---|
66 | /*
|
---|
67 | * Seems ok. Let's, init object variables
|
---|
68 | */
|
---|
69 | $this->fOk = 0;
|
---|
70 | $this->sError = "";
|
---|
71 | $i = strrpos($sFilename, "\\");
|
---|
72 | $j = strrpos($sFilename, "/");
|
---|
73 | $i = ($i > $j) ? $i : $j;
|
---|
74 | $this->sName = substr($sFilename, $i > 0 ? $i + 1 : 0, strlen($sFilename)-2 - ($i > 0 ? $i + 1 : 0));
|
---|
75 | $this->sDir = substr($sFilename, 0, $i);
|
---|
76 | if (($i = strrpos($this->sName, '.')) > 0)
|
---|
77 | $this->sExt = substr($this->sName, $i+1);
|
---|
78 | else
|
---|
79 | $this->sExt = "";
|
---|
80 | $this->aasKeys = array();
|
---|
81 | $this->aasDeltas = array();
|
---|
82 | $this->aaasRevs = array();
|
---|
83 |
|
---|
84 |
|
---|
85 | /*
|
---|
86 | * Open the file
|
---|
87 | */
|
---|
88 | $hFile = fopen($this->sFullname, "rb");
|
---|
89 | if (!$hFile)
|
---|
90 | {
|
---|
91 | $this->sError = "\nfailed to open the file $this->sFullname\n";
|
---|
92 | fclose($hFile);
|
---|
93 | return 1;
|
---|
94 | }
|
---|
95 |
|
---|
96 |
|
---|
97 | /*
|
---|
98 | * Parse file.
|
---|
99 | */
|
---|
100 | $fAt = 0;
|
---|
101 | $fNewKey= 1;
|
---|
102 | $sKey = "";
|
---|
103 | $sRev = "";
|
---|
104 | $fDesc = 0;
|
---|
105 |
|
---|
106 | $iLine = -1;
|
---|
107 | $sLine = "";
|
---|
108 | $fStop = 0;
|
---|
109 | while (($sLine != "" || !feof($hFile)) && !$fStop)
|
---|
110 | {
|
---|
111 | /*
|
---|
112 | * Left trim.
|
---|
113 | * If empty line, get next and iterate.
|
---|
114 | */
|
---|
115 | $sLine = ltrim($sLine);
|
---|
116 | if (!$sLine || $sLine == "" || $sLine == "\n" || $sLine == "\r")
|
---|
117 | {
|
---|
118 | $iLine++;
|
---|
119 | $sLine = fgets($hFile, 0x1000);
|
---|
120 | continue;
|
---|
121 | }
|
---|
122 |
|
---|
123 | /*
|
---|
124 | * Are we looking for a new key word?
|
---|
125 | */
|
---|
126 | if ($fNewKey)
|
---|
127 | {
|
---|
128 | //$sKey = CopyWord($sLine);
|
---|
129 | $cch = strlen($sLine);
|
---|
130 | for ($i = 0; $i < $cch; $i++)
|
---|
131 | {
|
---|
132 | $c = $sLine[$i];
|
---|
133 | if (!(
|
---|
134 | ($c >= 'a' && $c <= 'z')
|
---|
135 | ||
|
---|
136 | ($c >= 'A' && $c <= 'Z')
|
---|
137 | ||
|
---|
138 | ($c >= '0' && $c <= '9')
|
---|
139 | ||
|
---|
140 | $c == '.'
|
---|
141 | ||
|
---|
142 | $c == '_'
|
---|
143 | )
|
---|
144 | )
|
---|
145 | break;
|
---|
146 | }
|
---|
147 | $sKey = substr($sLine, 0, $i);
|
---|
148 |
|
---|
149 | $sLine = ltrim(SkipWord($sLine));
|
---|
150 | if ($sKey[0] >= "0" && $sKey[0] <= "9")
|
---|
151 | /* Revision number: delta or revision info */
|
---|
152 | $sRev = $sKey;
|
---|
153 | else
|
---|
154 | $fNewKey = 0;
|
---|
155 | continue;
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | /*
|
---|
160 | * Extract value
|
---|
161 | */
|
---|
162 | $fNoSemicolon = ($sKey == "desc" || $sKey == "log" || $sKey == "desc");
|
---|
163 | if ($fAt = ($sLine[0] == "@")) //check if the value is enclosed in '@'s
|
---|
164 | $sLine = substr($sLine, 1);
|
---|
165 | $asValue = array();
|
---|
166 | $fEnd = 0;
|
---|
167 | while (!$fEnd)
|
---|
168 | {
|
---|
169 | /* get new line? */
|
---|
170 | if (!$sLine || $sLine == "" || $sLine == "\n" || $sLine == "\r")
|
---|
171 | {
|
---|
172 | if (feof($hFile))
|
---|
173 | break;
|
---|
174 | /* Get next line and remove any EOF chars */
|
---|
175 | $iLine++;
|
---|
176 | $sLine = str_replace("\x1a", "", fgets($hFile, 0x1000));
|
---|
177 | continue;
|
---|
178 | }
|
---|
179 |
|
---|
180 | //echo "debug line $iLine: $sLine";
|
---|
181 |
|
---|
182 | /*
|
---|
183 | * Look for end char (either ; or @) and copy.
|
---|
184 | * If end of value then $sLine <- rest of line.
|
---|
185 | */
|
---|
186 | $fEnd = 0;
|
---|
187 | $cchLine = strlen($sLine);
|
---|
188 | if ($fAt)
|
---|
189 | { /* terminated with @ */
|
---|
190 | //$iAt = 0;
|
---|
191 | //for ($iAt; $iAt+1 < $cchLine; $iAt++)
|
---|
192 | // if ($sLine[$iAt] == '@' && ($fEnd = ($sLine[++$iAt] != '@')))
|
---|
193 | // break;
|
---|
194 | if ($sLine[0] == '@' && $sLine[1] != '@')
|
---|
195 | $fEnd = $iAt = 1;
|
---|
196 | else
|
---|
197 | {
|
---|
198 | $iAt = 0;
|
---|
199 | while ($iAt = strpos($sLine, "@", $iAt+1))
|
---|
200 | if ($fEnd = ($sLine[++$iAt] != '@'))
|
---|
201 | break;
|
---|
202 | }
|
---|
203 |
|
---|
204 | if ($fEnd)
|
---|
205 | {
|
---|
206 | $asValue[] = str_replace("@@", "@", substr($sLine, 0, $iAt - 1));
|
---|
207 | /* if semicolon end, skip to it. ASSUMES: same line! */
|
---|
208 | if (!$fNoSemicolon && ($iAt = strpos($sLine, ";", $iAt)) >= 0)
|
---|
209 | $iAt++;
|
---|
210 | $sLine = (strlen($sLine) > $iAt && $iAt >= 0) ? substr($sLine, $iAt) : "";
|
---|
211 | }
|
---|
212 | else
|
---|
213 | {
|
---|
214 | $asValue[] = str_replace("@@", "@", $sLine);
|
---|
215 | $sLine = "";
|
---|
216 | }
|
---|
217 | }
|
---|
218 | else
|
---|
219 | { /* terminated with ';' */
|
---|
220 | $i = strpos($sLine, ';');
|
---|
221 | if ($fEnd = ($i > 0 || $sLine[0] == ';'))
|
---|
222 | {
|
---|
223 | //$asValue[] = str_replace("@@", "@", substr($sLine, 0, $i));
|
---|
224 | $asValue[] = substr($sLine, 0, $i);
|
---|
225 | $sLine = (strlen($sLine) > $i+1) ? substr($sLine, $i+1) : "";
|
---|
226 | }
|
---|
227 | else
|
---|
228 | {
|
---|
229 | //$asValue[] = str_replace("@@", "@", $sLine);
|
---|
230 | $asValue[] = $sLine;
|
---|
231 | $sLine = "";
|
---|
232 | }
|
---|
233 | }
|
---|
234 | }
|
---|
235 |
|
---|
236 |
|
---|
237 | /*
|
---|
238 | * Process the key.
|
---|
239 | */
|
---|
240 | switch ($sKey)
|
---|
241 | {
|
---|
242 | /*
|
---|
243 | * This is normally the keyword separating
|
---|
244 | * revision info from log+text info.
|
---|
245 | */
|
---|
246 | case "desc":
|
---|
247 | $fDesc = 1;
|
---|
248 | $sRev = "";
|
---|
249 | break;
|
---|
250 |
|
---|
251 | /*
|
---|
252 | * Stop after the first log entry.
|
---|
253 | */
|
---|
254 | case "log":
|
---|
255 | $fStop = $fNoDeltas;
|
---|
256 | break;
|
---|
257 |
|
---|
258 | /*
|
---|
259 | * Don'r read deltas for archives with the expand tag set
|
---|
260 | */
|
---|
261 | case "expand":
|
---|
262 | $fNoDeltas = 1;//= $asValue[0] != "";
|
---|
263 | break;
|
---|
264 | }
|
---|
265 |
|
---|
266 | /*
|
---|
267 | * Save key and value in the appopriate place.
|
---|
268 | */
|
---|
269 | if ($sRev == "")
|
---|
270 | { /* Base keys */
|
---|
271 | if (sizeof($this->aaKeys) <= 0 //sanity check! head must come first and have a value!
|
---|
272 | && ($sKey != "head" || sizeof($asValue) <= 0 || $asValue[0] == ""))
|
---|
273 | {
|
---|
274 | $this->sError = "Invalid file format.";
|
---|
275 | fclose($hFile);
|
---|
276 | return 1;
|
---|
277 | }
|
---|
278 | $this->aasKeys[$sKey] = $asValue;
|
---|
279 | }
|
---|
280 | else if ($sKey != "text")
|
---|
281 | { /* Revision information keys */
|
---|
282 | if (!isset($this->aaasRevs[$sRev]))
|
---|
283 | $this->aaasRevs[$sRev] = array($sKey => $asValue);
|
---|
284 | else
|
---|
285 | $this->aaasRevs[$sRev][$sKey] = $asValue;
|
---|
286 | }
|
---|
287 | else
|
---|
288 | { /* Delta (ie. 'text') key */
|
---|
289 | $this->aasDeltas[$sRev] = $asValue;
|
---|
290 | }
|
---|
291 |
|
---|
292 | /*
|
---|
293 | * Completed reading of this key, so next one.
|
---|
294 | */
|
---|
295 | $fNewKey = 1;
|
---|
296 |
|
---|
297 | /* debug */
|
---|
298 | //echo "debug key: $sKey value(".sizeof($asValue)."):".$asValue[0]."\n";
|
---|
299 | }
|
---|
300 |
|
---|
301 | fclose($hFile);
|
---|
302 |
|
---|
303 | /*
|
---|
304 | * Return successfully.
|
---|
305 | */
|
---|
306 | $this->fOk = 1;
|
---|
307 |
|
---|
308 | Odin32DBTimerStop($timer);
|
---|
309 | return 1;
|
---|
310 | }
|
---|
311 |
|
---|
312 |
|
---|
313 | /**
|
---|
314 | * Debug dump function.
|
---|
315 | */
|
---|
316 | function DumpInfo()
|
---|
317 | {
|
---|
318 | echo "\nDump:<br>\n";
|
---|
319 |
|
---|
320 | while (list ($sKey, $asValue) = each ($this->aasKeys))
|
---|
321 | {
|
---|
322 | echo "* key: $sKey *<br>\n";
|
---|
323 | if (sizeof((array)$asValue) > 0)
|
---|
324 | {
|
---|
325 | while (list ($key, $s) = each ($asValue))
|
---|
326 | echo $s;
|
---|
327 | echo "<br>\n";
|
---|
328 | }
|
---|
329 | }
|
---|
330 |
|
---|
331 | while (list ($sRev, $aasKeys) = each ($this->aaasRevs))
|
---|
332 | {
|
---|
333 | echo "* Revision: $sRev *<br>\n";
|
---|
334 | if (sizeof((array)$aasKeys) > 0)
|
---|
335 | {
|
---|
336 | while (list ($sKey, $asValue) = each ($aasKeys))
|
---|
337 | {
|
---|
338 | echo "* key: $sKey *<br>\n";
|
---|
339 | if (sizeof((array)$asValue) > 0)
|
---|
340 | {
|
---|
341 | while (list ($key, $s) = each ($asValue))
|
---|
342 | echo $s;
|
---|
343 | echo "<br>\n";
|
---|
344 | }
|
---|
345 | }
|
---|
346 | }
|
---|
347 | }
|
---|
348 |
|
---|
349 | if (0)
|
---|
350 | {
|
---|
351 | while (list ($sKey, $asValue) = each ($this->aasDeltas))
|
---|
352 | {
|
---|
353 | echo "* delta for revision: $sKey *<br>\n";
|
---|
354 | if (sizeof((array)$asValue) > 0)
|
---|
355 | {
|
---|
356 | while (list ($key, $s) = each ($asValue))
|
---|
357 | echo $s."<br>";
|
---|
358 | echo "\n";
|
---|
359 | }
|
---|
360 | }
|
---|
361 | }
|
---|
362 | }
|
---|
363 |
|
---|
364 |
|
---|
365 | /**
|
---|
366 | * Prints the contents of the file to stdout.
|
---|
367 | *
|
---|
368 | * Color coding is enabled. (TODO)
|
---|
369 | *
|
---|
370 | * Currently only $sRevision == head revision is supported
|
---|
371 | * @returns Success indicator (true / false)
|
---|
372 | * @param $sRevision. Revision number. defaults to head revision.
|
---|
373 | *
|
---|
374 | */
|
---|
375 | function PrintRevision($sRevision)
|
---|
376 | {
|
---|
377 | /* defaults to head revision if empty */
|
---|
378 | if ($sRevision == "") $sRevision = $this->aasKeys["head"][0];
|
---|
379 | if (!isset($this->aasDeltas[$sRevision]))
|
---|
380 | {
|
---|
381 | $this->sError = "CVSFile::PrintRevision is called with an invalid revision number. ($sRevision)";
|
---|
382 | return 0;
|
---|
383 | }
|
---|
384 | /* to-be-removed - TODO - FIXME */
|
---|
385 | if ($sRevision != $this->aasKeys["head"][0])
|
---|
386 | {
|
---|
387 | $this->sError = "CVSFile::PrintRevision is called with an invalid revision number (not head).";
|
---|
388 | return 0;
|
---|
389 | }
|
---|
390 |
|
---|
391 | /*
|
---|
392 | * Initiate the color encoder.
|
---|
393 | */
|
---|
394 | switch ($this->sExt)
|
---|
395 | {
|
---|
396 | case 'c':
|
---|
397 | case 'cpp':
|
---|
398 | case 'cxx':
|
---|
399 | case 'h':
|
---|
400 | case 'hpp':
|
---|
401 | C_ColorInit($aVariables);
|
---|
402 | break;
|
---|
403 | }
|
---|
404 |
|
---|
405 |
|
---|
406 |
|
---|
407 | /*
|
---|
408 | * Write it!
|
---|
409 | */
|
---|
410 | echo "<table><tr><td bgcolor=#020286><pre><font size=-0 face=\"System VIO, System Monospaced\" color=#02FEFE>\n";
|
---|
411 |
|
---|
412 | $fComment = 0;
|
---|
413 | $iLine = 0;
|
---|
414 | $cLines = sizeof($this->aasDeltas[$sRevision]);
|
---|
415 | //echo "<!-- debug $this->sExt -->\n";
|
---|
416 | while ($iLine < $cLines)
|
---|
417 | {
|
---|
418 | $sLine = htmlspecialchars($this->aasDeltas[$sRevision][$iLine++]);
|
---|
419 |
|
---|
420 | /*
|
---|
421 | * Preprocessing... Color coding
|
---|
422 | */
|
---|
423 | switch ($this->sExt)
|
---|
424 | {
|
---|
425 | case 'c':
|
---|
426 | case 'cpp':
|
---|
427 | case 'cxx':
|
---|
428 | case 'h':
|
---|
429 | case 'hpp':
|
---|
430 | $sLine = C_ColorEncode($sLine, $aVariables);
|
---|
431 | //echo "<a name=$iLine>";
|
---|
432 | //C_ColorEncode2($sLine, $aVariables);
|
---|
433 | //echo "</a>";
|
---|
434 | break;
|
---|
435 |
|
---|
436 | default:
|
---|
437 | echo "<a name=$iLine>$sLine</a>";
|
---|
438 |
|
---|
439 | }
|
---|
440 |
|
---|
441 | /*
|
---|
442 | * Finished processing of the line. So, write it.
|
---|
443 | */
|
---|
444 | echo "<a name=$iLine>$sLine</a>";
|
---|
445 | }
|
---|
446 |
|
---|
447 | echo "</pre></td></tr></table>\n";
|
---|
448 |
|
---|
449 | return 1;
|
---|
450 | }
|
---|
451 |
|
---|
452 |
|
---|
453 | /**
|
---|
454 | * Gets the revision number of the head revision.
|
---|
455 | * @returns head revision number
|
---|
456 | */
|
---|
457 | function getHead()
|
---|
458 | {
|
---|
459 | return $this->aasKeys["head"][0];
|
---|
460 | }
|
---|
461 |
|
---|
462 |
|
---|
463 | /**
|
---|
464 | * Gets the log string for the given revision.
|
---|
465 | * @returns Array of strings in the log text.
|
---|
466 | * @param $sRev Revision number to get log text for.
|
---|
467 | */
|
---|
468 | function getLog($sRev)
|
---|
469 | {
|
---|
470 | return @$this->aaasRevs[$sRev]["log"];
|
---|
471 | }
|
---|
472 |
|
---|
473 |
|
---|
474 | /**
|
---|
475 | * Gets the author for a revision.
|
---|
476 | * @return Author name.
|
---|
477 | * @param $sRev Revision number to get author name for.
|
---|
478 | */
|
---|
479 | function getAuthor($sRev)
|
---|
480 | {
|
---|
481 | return @$this->aaasRevs[$sRev]["author"][0];
|
---|
482 | }
|
---|
483 |
|
---|
484 | /**
|
---|
485 | * Get date+time stap on a revision.
|
---|
486 | * @returns date string for the given revision.
|
---|
487 | * @param $sRev Revision number to get date+time for.
|
---|
488 | */
|
---|
489 | function getDate($sRev)
|
---|
490 | {
|
---|
491 | return @$this->aaasRevs[$sRev]["date"][0];
|
---|
492 | }
|
---|
493 |
|
---|
494 | /**
|
---|
495 | * Get the age of the given revision.
|
---|
496 | * @returns Age string. (human readable)
|
---|
497 | * @param $sRev Revision number to get age for.
|
---|
498 | */
|
---|
499 | function getAge($sRev)
|
---|
500 | {
|
---|
501 | if (!isset($this->aaasRevs[$sRev]["date"][0]))
|
---|
502 | return "<i>error</i>";
|
---|
503 |
|
---|
504 | $sDate = $this->aaasRevs[$sRev]["date"][0];
|
---|
505 | $sCurDate = date("Y.m.d.H.i.s");
|
---|
506 | if ($sDate > $sCurDate)
|
---|
507 | {
|
---|
508 | return "0 seconds"; //fixme?
|
---|
509 | }
|
---|
510 |
|
---|
511 | /* seconds */
|
---|
512 | $i1 = substr($sCurDate, 17, 2);
|
---|
513 | $i2 = substr($sDate, 17, 2);
|
---|
514 | if ($fBorrow = ($i1 < $i2))
|
---|
515 | $i1 += 60;
|
---|
516 | $iSeconds = $i1 - $i2;
|
---|
517 |
|
---|
518 | /* minuttes */
|
---|
519 | $i1 = substr($sCurDate, 14, 2);
|
---|
520 | $i2 = substr($sDate, 14, 2);
|
---|
521 | if ($fBorrow)
|
---|
522 | $i1--;
|
---|
523 | if ($fBorrow = ($i1 < $i2))
|
---|
524 | $i1 += 60;
|
---|
525 | $iMinuttes = $i1 - $i2;
|
---|
526 |
|
---|
527 | /* hours */
|
---|
528 | $i1 = substr($sCurDate, 11, 2);
|
---|
529 | $i2 = substr($sDate, 11, 2);
|
---|
530 | if ($fBorrow)
|
---|
531 | $i1--;
|
---|
532 | if ($fBorrow = ($i1 < $i2))
|
---|
533 | $i1 += 24;
|
---|
534 | $iHours = $i1 - $i2;
|
---|
535 |
|
---|
536 | /* days */
|
---|
537 | $i1 = substr($sCurDate, 8, 2);
|
---|
538 | $i2 = substr($sDate, 8, 2);
|
---|
539 | if ($fBorrow)
|
---|
540 | $i1--;
|
---|
541 | if ($fBorrow = ($i1 < $i2))
|
---|
542 | {
|
---|
543 | $iM = substr($sCurDate, 5, 2);
|
---|
544 | $iY = substr($sCurDate, 0, 4);
|
---|
545 | if ($iM == 1 || $iM == 3 || $iM == 5 || $iM == 7 || $iM == 8 || $iM == 10 || $iM == 12)
|
---|
546 | $i1 += 31;
|
---|
547 | else if ($iM == 4 || $iM == 6 || $iM == 9 || $iM == 11)
|
---|
548 | $i1 += 30;
|
---|
549 | else if (($iY % 4) != 0 || (($iY % 100) == 0 && ($iY % 1000) != 0))
|
---|
550 | $i1 += 28;
|
---|
551 | else
|
---|
552 | $i1 += 29;
|
---|
553 | }
|
---|
554 | $iDays = $i1 - $i2;
|
---|
555 |
|
---|
556 | /* months */
|
---|
557 | $i1 = substr($sCurDate, 5, 2);
|
---|
558 | $i2 = substr($sDate, 5, 2);
|
---|
559 | if ($fBorrow)
|
---|
560 | $i1--;
|
---|
561 | if ($fBorrow = ($i1 < $i2))
|
---|
562 | $i1 += 12;
|
---|
563 | $iMonths = $i1 - $i2;
|
---|
564 |
|
---|
565 | /* years */
|
---|
566 | $i1 = substr($sCurDate, 0, 4);
|
---|
567 | $i2 = substr($sDate, 0, 4);
|
---|
568 | if ($fBorrow)
|
---|
569 | $i1--;
|
---|
570 | $iYears = $i1 - $i2;
|
---|
571 |
|
---|
572 | //printf("<!-- $sCurDate - $sDate = %04d.%02d.%02d.%02d.%02d.%02d -->\n", $iYears, $iMonths, $iDays, $iHours, $iMinuttes, $iSeconds);
|
---|
573 |
|
---|
574 | /* make output */
|
---|
575 | if ($iYears > 0)
|
---|
576 | return "$iYears year".($iYears > 1 ? "s" : "")." $iMonths month".($iMonths > 1 ? "s" : "");
|
---|
577 | if ($iMonths > 0)
|
---|
578 | return "$iMonths month".($iMonths > 1 ? "s" : "")." $iDays day".($iDays > 1 ? "s" : "");
|
---|
579 | if ($iDays > 0)
|
---|
580 | return "$iDays day".($iDays > 1 ? "s" : "")." $iHours hour".($iHours > 1 ? "s" : "");
|
---|
581 | if ($iHours > 0)
|
---|
582 | return "$iHours hour".($iHours > 1 ? "s" : "")." $iMinuttes min";
|
---|
583 | if ($iMinuttes > 0)
|
---|
584 | return "$iMinuttes min $iSeconds sec";
|
---|
585 | return "$iSeconds seconds";
|
---|
586 | }
|
---|
587 |
|
---|
588 | }
|
---|
589 |
|
---|
590 |
|
---|
591 | /**
|
---|
592 | * This function displayes the contents of an directory.
|
---|
593 | */
|
---|
594 | function ListDirectory($sDir, $iSortColumn)
|
---|
595 | {
|
---|
596 | global $sCVSROOT;
|
---|
597 |
|
---|
598 | /*
|
---|
599 | * Validate and fixup $sDir.
|
---|
600 | * Note that relative .. is not allowed!
|
---|
601 | */
|
---|
602 | $sDir = str_replace("\\", "/", $sDir);
|
---|
603 | if ($sDir == "")
|
---|
604 | $sDir = ".";
|
---|
605 | if ($sDir[0] == '/')
|
---|
606 | $sDir = substr($sDir, 1);
|
---|
607 | if ($sDir[strlen($sDir)-1] == '/')
|
---|
608 | $sDir = substr($sDir, 0, strlen($sDir) - 1);
|
---|
609 | if ((strlen($sDir) == 2 && $sDir == "..")
|
---|
610 | ||
|
---|
611 | (substr($sDir, 0, 3) == "../")
|
---|
612 | ||
|
---|
613 | (substr($sDir, strlen($sDir)-3) == "/..")
|
---|
614 | ||
|
---|
615 | (strpos($sDir, "/../") > 0)
|
---|
616 | )
|
---|
617 | {
|
---|
618 | echo "<!-- Invalid parameter: \$sDir $sDir -->\n";
|
---|
619 | echo "<i>Invalid parameter: \$sDir $sDir </i>\n";
|
---|
620 | return 87;
|
---|
621 | }
|
---|
622 |
|
---|
623 | /*
|
---|
624 | * Open the directory, read the contents into two arrays;
|
---|
625 | * one for files and one for directories. All files which
|
---|
626 | * don't end with ',v' are ignored.
|
---|
627 | */
|
---|
628 | $hDir = opendir($sCVSROOT.'/'.$sDir);
|
---|
629 | if (!$hDir)
|
---|
630 | {
|
---|
631 | echo "<!-- debug error opendir($sDir) failed -->\n";
|
---|
632 | echo "<i>debug error opendir($sDir) failed</i>\n";
|
---|
633 | return 5;
|
---|
634 | }
|
---|
635 |
|
---|
636 | $asFiles = array();
|
---|
637 | $asSubDirs = array();
|
---|
638 | while ($sEntry = readdir($hDir))
|
---|
639 | {
|
---|
640 | if (is_dir($sCVSROOT.'/'.$sDir.'/'.$sEntry))
|
---|
641 | {
|
---|
642 | if ($sEntry != '..' && $sEntry != '.')
|
---|
643 | $asSubDirs[] = $sEntry;
|
---|
644 | }
|
---|
645 | else
|
---|
646 | {
|
---|
647 | $cchEntry = strlen($sEntry);
|
---|
648 | if ($cchEntry > 2 && substr($sEntry, $cchEntry - 2, 2) == ',v')
|
---|
649 | $asFiles[$sEntry] = $sEntry;
|
---|
650 | }
|
---|
651 | }
|
---|
652 | closedir($hDir);
|
---|
653 |
|
---|
654 | /*
|
---|
655 | * Get CVS data.
|
---|
656 | */
|
---|
657 | $asRev = array();
|
---|
658 | $asAge = array();
|
---|
659 | $asAuthor = array();
|
---|
660 | $asLog = array();
|
---|
661 | for ($i = 0; list($sKey, $sFile) = each($asFiles); $i++)
|
---|
662 | {
|
---|
663 | $obj = new CVSFile($sDir.'/'.$sFile, 1);
|
---|
664 | if ($obj->fOk)
|
---|
665 | {
|
---|
666 | $asRev[$sFile] = $sRev = $obj->getHead();
|
---|
667 | $asAge[$sFile] = $obj->getAge($sRev);
|
---|
668 | $asAuthor[$sFile] = $obj->getAuthor($sRev);
|
---|
669 | $asLog[$sFile] = $obj->getLog($sRev);
|
---|
670 | }
|
---|
671 | else
|
---|
672 | $asLog[$sFile] = $obj->sError;
|
---|
673 | }
|
---|
674 |
|
---|
675 | /*
|
---|
676 | * Sort the stuff.
|
---|
677 | */
|
---|
678 | sort($asSubDirs);
|
---|
679 | switch ($iSortColumn)
|
---|
680 | {
|
---|
681 | case 0: $asSorted = $asFiles; break;
|
---|
682 | case 1: $asSorted = $asRev; break;
|
---|
683 | case 2: $asSorted = $asAge; break;
|
---|
684 | case 3: $asSorted = $asAuthor; break;
|
---|
685 | case 4: $asSorted = $asLog; break;
|
---|
686 | default: $asSorted = $asFiles; break;
|
---|
687 | }
|
---|
688 | asort($asSorted);
|
---|
689 |
|
---|
690 | /*
|
---|
691 | * Present data
|
---|
692 | */
|
---|
693 | $aColumnColors = array("#cccccc","#cccccc","#cccccc","#cccccc", "#88ff88","#cccccc","#cccccc","#cccccc","#cccccc");
|
---|
694 | echo "<table border=0 width=100% cellspacing=1 cellpadding=2>\n",
|
---|
695 | " <hr NOSHADE>\n",
|
---|
696 | " <th bgcolor=#".$aColumnColors[4+0-$iSortColumn]."><b><a href=cvs.phtml?sDir=$sDir&iSortColumn=0>Filename</a></b></th>\n",
|
---|
697 | " <th bgcolor=#".$aColumnColors[4+1-$iSortColumn]."><b><a href=cvs.phtml?sDir=$sDir&iSortColumn=1>Rev</a></b></th>\n",
|
---|
698 | " <th bgcolor=#".$aColumnColors[4+2-$iSortColumn]."><b><a href=cvs.phtml?sDir=$sDir&iSortColumn=2>Age</a></b></th>\n",
|
---|
699 | " <th bgcolor=#".$aColumnColors[4+3-$iSortColumn]."><b><a href=cvs.phtml?sDir=$sDir&iSortColumn=3>Author</a></b></th>\n",
|
---|
700 | " <th bgcolor=#".$aColumnColors[4+4-$iSortColumn]."><b><a href=cvs.phtml?sDir=$sDir&iSortColumn=4>Last Log Entry</a></b></th>\n",
|
---|
701 | " </hr>\n";
|
---|
702 | $i = 0;
|
---|
703 | /* directories */
|
---|
704 | if ($sDir != "." && $sDir != "")
|
---|
705 | {
|
---|
706 | if (($j = strrpos($sDir, '/')) > 0)
|
---|
707 | $sParentDir = substr($sDir, 0, $j - 1);
|
---|
708 | else
|
---|
709 | $sParentDir = "";
|
---|
710 | $sBgColor = ($i++ % 2) ? "" : " bgcolor=#ccccee";
|
---|
711 | echo " <tr>\n",
|
---|
712 | " <td", $sBgColor , ">",
|
---|
713 | "<font size=-1><a href=\"cvs.phtml?sDir=$sParentDir\">Parent Directory</a></font></td>\n",
|
---|
714 | " <td$sBgColor> </td>\n",
|
---|
715 | " <td$sBgColor> </td>\n",
|
---|
716 | " <td$sBgColor> </td>\n",
|
---|
717 | " <td$sBgColor> </td>\n",
|
---|
718 | " </tr>\n";
|
---|
719 | }
|
---|
720 | while (list($sKey, $sVal) = each($asSubDirs))
|
---|
721 | {
|
---|
722 | $sBgColor = ($i++ % 2) ? "" : " bgcolor=#ccccee";
|
---|
723 | echo " <tr>\n",
|
---|
724 | " <td$sBgColor><font size=-1><a href=\"cvs.phtml?sDir=$sDir/$sVal\">$sVal</a></font></td>\n",
|
---|
725 | " <td$sBgColor> </td>\n",
|
---|
726 | " <td$sBgColor> </td>\n",
|
---|
727 | " <td$sBgColor> </td>\n",
|
---|
728 | " <td$sBgColor> </td>\n",
|
---|
729 | " </tr>\n";
|
---|
730 | }
|
---|
731 |
|
---|
732 | /* files */
|
---|
733 | while (list($sKey, $sVal) = each($asSorted))
|
---|
734 | {
|
---|
735 | $sBgColor = ($i++ % 2) ? "" : " bgcolor=#ccccee";
|
---|
736 | $sRev = isset($asRev[$sKey]) ? $asRev[$sKey] : "<i> error </i>";
|
---|
737 | $sAge = isset($asAge[$sKey]) ? $asAge[$sKey] : "<i> error </i>";
|
---|
738 | $sAuthor= isset($asAuthor[$sKey])?$asAuthor[$sKey] : "<i> error </i>";
|
---|
739 | for ($sLog = "", $j = sizeof($asLog[$sKey]) - 1; $j >= 0; $j--)
|
---|
740 | {
|
---|
741 | if ($sLog == "")
|
---|
742 | {
|
---|
743 | if (trim($asLog[$sKey][$j]) != "")
|
---|
744 | $sLog = $asLog[$sKey][$j];
|
---|
745 | continue;
|
---|
746 | }
|
---|
747 | $sLog = $asLog[$sKey][$j]."<br>".$sLog;
|
---|
748 | }
|
---|
749 | echo " <tr>\n",
|
---|
750 | " <td$sBgColor><font size=-1><a href=\"cvs.phtml?sFile=$sDir/$sKey\">$sKey</a></font></td>\n",
|
---|
751 | " <td$sBgColor><font size=-1><a href=\"cvs.phtml?sFile=$sDir/$sKey?sRev=$sRev\">$sRev</a></font></td>\n",
|
---|
752 | " <td$sBgColor><font size=-1>$sAge</font></td>\n",
|
---|
753 | " <td$sBgColor><font size=-1>$sAuthor</font></td>\n",
|
---|
754 | " <td$sBgColor><font size=-1>$sLog</font></td>\n",
|
---|
755 | " </tr>\n";
|
---|
756 | }
|
---|
757 |
|
---|
758 | echo "</table>\n";
|
---|
759 |
|
---|
760 |
|
---|
761 | /*
|
---|
762 | * Debug dump.
|
---|
763 | *//*
|
---|
764 | while (list ($sKey, $sVal) = each ($asSubDirs))
|
---|
765 | echo "Dir: $sVal<br>\n";
|
---|
766 | while (list ($sKey, $sVal) = each ($asFiles))
|
---|
767 | echo "File: $sVal<br>\n";
|
---|
768 | */
|
---|
769 | }
|
---|
770 |
|
---|
771 |
|
---|
772 | /**
|
---|
773 | * Copies the first word.
|
---|
774 | * A words is: [a-zA-Z0-9_.]
|
---|
775 | *
|
---|
776 | * tested ok
|
---|
777 | * @returns Returns the word at the start of $s.
|
---|
778 | */
|
---|
779 | function CopyWord($s)
|
---|
780 | {
|
---|
781 | $cch = strlen($s);
|
---|
782 | for ($i = 0; $i < $cch; $i++)
|
---|
783 | {
|
---|
784 | $c = $s[$i];
|
---|
785 | if (!($c >= 'a' && $c <= 'z')
|
---|
786 | &&
|
---|
787 | !($c >= 'A' && $c <= 'Z')
|
---|
788 | &&
|
---|
789 | !($c >= '0' && $c <= '9')
|
---|
790 | &&
|
---|
791 | !($c == '.' || $c == '_')
|
---|
792 | )
|
---|
793 | break;
|
---|
794 | }
|
---|
795 | return substr($s, 0, $i);
|
---|
796 | }
|
---|
797 |
|
---|
798 |
|
---|
799 | /**
|
---|
800 | * Skips the first word.
|
---|
801 | * A words is: [a-zA-Z0-9_.]
|
---|
802 | *
|
---|
803 | * tested ok
|
---|
804 | * @returns $s - first word.
|
---|
805 | */
|
---|
806 | function SkipWord($s)
|
---|
807 | {
|
---|
808 | $cch = strlen($s);
|
---|
809 | for ($i = 0; $i < $cch; $i++)
|
---|
810 | {
|
---|
811 | $c = $s[$i];
|
---|
812 | if (!($c >= 'a' && $c <= 'z')
|
---|
813 | &&
|
---|
814 | !($c >= 'A' && $c <= 'Z')
|
---|
815 | &&
|
---|
816 | !($c >= '0' && $c <= '9')
|
---|
817 | &&
|
---|
818 | !($c == '.' || $c == '_')
|
---|
819 | )
|
---|
820 | break;
|
---|
821 | }
|
---|
822 | return substr($s, $i);
|
---|
823 | }
|
---|
824 |
|
---|
825 |
|
---|
826 |
|
---|
827 |
|
---|
828 | /*
|
---|
829 | * C color encoding.
|
---|
830 | */
|
---|
831 | $aC_Keywords = array(
|
---|
832 | // "auto" => 1,
|
---|
833 | "break" => 1,
|
---|
834 | "case" => 1,
|
---|
835 | "char" => 1,
|
---|
836 | "const" => 1,
|
---|
837 | "continue" => 1,
|
---|
838 | "default" => 1,
|
---|
839 | // "defined" => 1,
|
---|
840 | "do" => 1,
|
---|
841 | "double" => 1,
|
---|
842 | "else" => 1,
|
---|
843 | "enum" => 1,
|
---|
844 | "extern" => 1,
|
---|
845 | "float" => 1,
|
---|
846 | "for" => 1,
|
---|
847 | "goto" => 1,
|
---|
848 | "if" => 1,
|
---|
849 | "int" => 1,
|
---|
850 | "long" => 1,
|
---|
851 | "register" => 1,
|
---|
852 | "return" => 1,
|
---|
853 | "short" => 1,
|
---|
854 | "sizeof" => 1,
|
---|
855 | "static" => 1,
|
---|
856 | "struct" => 1,
|
---|
857 | "switch" => 1,
|
---|
858 | "typedef" => 1,
|
---|
859 | "union" => 1,
|
---|
860 | "unsigned" => 1,
|
---|
861 | "void" => 1,
|
---|
862 | "while" => 1,
|
---|
863 | "class" => 1,
|
---|
864 | "delete" => 1,
|
---|
865 | // "finally" => 1,
|
---|
866 | "friend" => 1,
|
---|
867 | "inline" => 1,
|
---|
868 | "new" => 1,
|
---|
869 | "operator" => 1,
|
---|
870 | "overload" => 1,
|
---|
871 | "private" => 1,
|
---|
872 | "protected" => 1,
|
---|
873 | "public" => 1,
|
---|
874 | "this" => 1,
|
---|
875 | "virtual" => 1,
|
---|
876 | // "bool" => 1,
|
---|
877 | // "true" => 1,
|
---|
878 | // "false" => 1,
|
---|
879 | "explicit" => 1,
|
---|
880 | "mutable" => 1,
|
---|
881 | "typename" => 1,
|
---|
882 | // "static_cast" => 1,
|
---|
883 | // "const_cast" => 1,
|
---|
884 | // "reinterpret_cast" => 1,
|
---|
885 | // "dynamic_cast" => 1,
|
---|
886 | // "using" => 1,
|
---|
887 | "typeid" => 1,
|
---|
888 | // "asm" => 1,
|
---|
889 | "catch" => 1,
|
---|
890 | "signed" => 1,
|
---|
891 | "template" => 1,
|
---|
892 | "throw" => 1,
|
---|
893 | "try" => 1,
|
---|
894 | // "namespace" => 1,
|
---|
895 | "volatile" => 1
|
---|
896 |
|
---|
897 | );
|
---|
898 |
|
---|
899 | $aC_Symbols = array(
|
---|
900 | "{" => 1,
|
---|
901 | "}" => 1,
|
---|
902 | // "[" => 1,
|
---|
903 | // "]" => 1,
|
---|
904 | // "(" => 1,
|
---|
905 | // ")" => 1,
|
---|
906 | // "." => 1,
|
---|
907 | // "," => 1,
|
---|
908 | "!" => 1,
|
---|
909 | "%" => 1,
|
---|
910 | // "&" => 1,
|
---|
911 | "&" => 1,
|
---|
912 | "*" => 1,
|
---|
913 | "-" => 1,
|
---|
914 | "=" => 1,
|
---|
915 | "+" => 1,
|
---|
916 | ":" => 1,
|
---|
917 | ";" => 1,
|
---|
918 | // "<" => 1,
|
---|
919 | "<" => 1,
|
---|
920 | // ">" => 1,
|
---|
921 | ">" => 1,
|
---|
922 | "?" => 1,
|
---|
923 | "/" => 1,
|
---|
924 | "|" => 1,
|
---|
925 | "~" => 1,
|
---|
926 | "^" => 1,
|
---|
927 | "*" => 1);
|
---|
928 |
|
---|
929 | /**
|
---|
930 | * Initiate the variable array used by the C Color encoder.
|
---|
931 | * @param $aVaraibles Variable array. (output)
|
---|
932 | */
|
---|
933 | function C_ColorInit(&$aVariables)
|
---|
934 | {
|
---|
935 | global $aC_Keywords;
|
---|
936 | global $aC_Symbols;
|
---|
937 |
|
---|
938 | $aVariables["fComment"] = 0;
|
---|
939 |
|
---|
940 | ksort($aC_Keywords);
|
---|
941 | ksort($aC_Symbols);
|
---|
942 | }
|
---|
943 |
|
---|
944 |
|
---|
945 | /**
|
---|
946 | * Encode a line of C code.
|
---|
947 | * @param $sLine Line string to encode.
|
---|
948 | * @param $aVariables Variable array.
|
---|
949 | * @returns Color encoded line string.
|
---|
950 | */
|
---|
951 | function C_ColorEncode($sLine, &$aVariables)
|
---|
952 | {
|
---|
953 | global $aC_Keywords;
|
---|
954 | global $aC_Symbols;
|
---|
955 |
|
---|
956 | $sRet = "";
|
---|
957 | $cchLine = strlen($sLine);
|
---|
958 |
|
---|
959 | /*
|
---|
960 | * If mulitline comment we'll only check if it ends at this line.
|
---|
961 | * if it doesn't we'll do nothing.
|
---|
962 | * if it does we'll skip to then end of it.
|
---|
963 | */
|
---|
964 | if ($aVariables["fComment"])
|
---|
965 | {
|
---|
966 | if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
|
---|
967 | return $sLine;
|
---|
968 | $i += 2;
|
---|
969 | $sRet = substr($sLine, 0, $i)."</font>";
|
---|
970 | $aVariables["fComment"] = 0;
|
---|
971 | }
|
---|
972 | else
|
---|
973 | $i = 0;
|
---|
974 |
|
---|
975 | /*
|
---|
976 | * Loop thru the (remainings) of the line.
|
---|
977 | */
|
---|
978 | $fFirstNonBlank = 1;
|
---|
979 | while ($i < $cchLine)
|
---|
980 | {
|
---|
981 | $ch = $sLine[$i];
|
---|
982 | /* comment check */
|
---|
983 | if ($i+1 < $cchLine && $ch == '/')
|
---|
984 | {
|
---|
985 | if ($sLine[$i+1] == '/')
|
---|
986 | { /* one-line comment */
|
---|
987 | return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
|
---|
988 | }
|
---|
989 |
|
---|
990 | if ($sLine[$i+1] == '*')
|
---|
991 | { /* Start of multiline comment */
|
---|
992 | if ($j = strpos($sLine, "*/", $i + 2))
|
---|
993 | {
|
---|
994 | $sRet .= "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
|
---|
995 | $i = $j + 2;
|
---|
996 | }
|
---|
997 | else
|
---|
998 | {
|
---|
999 | $aVariables["fComment"] = 1;
|
---|
1000 | return $sRet . "<font color=#02FE02>" . substr($sLine, $i);
|
---|
1001 | }
|
---|
1002 | continue;
|
---|
1003 | }
|
---|
1004 | }
|
---|
1005 |
|
---|
1006 | /*
|
---|
1007 | * Check for string.
|
---|
1008 | */
|
---|
1009 | if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == """)) || $sLine[$i] == "'")
|
---|
1010 | && ($i == 0 || $sLine[$i-1] != '\\'))
|
---|
1011 | { /* start of a string */
|
---|
1012 | $j = $i + 1;
|
---|
1013 | if ($fDbl)
|
---|
1014 | {
|
---|
1015 | /* if ($sLine[$i] == '"')
|
---|
1016 | while ($j < $cchLine && $sLine[$j] != '"')
|
---|
1017 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1018 | else */
|
---|
1019 | {
|
---|
1020 | while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != """))
|
---|
1021 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1022 | if ($j < $cchLine)
|
---|
1023 | $j += 5;
|
---|
1024 | }
|
---|
1025 | }
|
---|
1026 | else
|
---|
1027 | while ($j < $cchLine && $sLine[$j] != "'")
|
---|
1028 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1029 | $j++;
|
---|
1030 | $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
|
---|
1031 | $i = $j;
|
---|
1032 | continue;
|
---|
1033 | }
|
---|
1034 |
|
---|
1035 | /*
|
---|
1036 | * Check for preprocessor directive.
|
---|
1037 | */
|
---|
1038 | if ($fFirstNonBlank && $ch == "#")
|
---|
1039 | {
|
---|
1040 | $j = $i + 1;
|
---|
1041 | while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == '\t'))
|
---|
1042 | $j++;
|
---|
1043 | $j += C_WordLen($sLine, $cchLine, $j);
|
---|
1044 | $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
|
---|
1045 | $i = $j;
|
---|
1046 | $fFirstNonBlank = 0;
|
---|
1047 | continue;
|
---|
1048 | }
|
---|
1049 |
|
---|
1050 | /*
|
---|
1051 | * If non-blank, lets check if we're at the start of a word...
|
---|
1052 | */
|
---|
1053 | $fBlank = ($ch == ' ' || $ch == '\t'); //TODO more "blanks"?
|
---|
1054 | if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
|
---|
1055 | $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
|
---|
1056 |
|
---|
1057 | if ($cchWord > 0)
|
---|
1058 | {
|
---|
1059 | /*
|
---|
1060 | * Check for keyword or number.
|
---|
1061 | */
|
---|
1062 | if ($cchWord > 0 && (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9')))
|
---|
1063 | $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
1064 |
|
---|
1065 | /*
|
---|
1066 | * Skip word.
|
---|
1067 | */
|
---|
1068 | else
|
---|
1069 | $sRet .= substr($sLine, $i, $cchWord);
|
---|
1070 | $i += $cchWord;
|
---|
1071 | continue;
|
---|
1072 | }
|
---|
1073 |
|
---|
1074 |
|
---|
1075 | /*
|
---|
1076 | * Prepare for symbol check. (we'll have to check for HTML stuff like &).
|
---|
1077 | */
|
---|
1078 | $cchWord = 1;
|
---|
1079 | if ($ch == '&')
|
---|
1080 | {
|
---|
1081 | /*
|
---|
1082 | while ($cchWord < 8 && $sLine[$i+$cchWord] != ';' &&
|
---|
1083 | ( ($sLine[$i+$cchWord] >= 'a' && $sLine[$i+$cchWord] <= 'z')
|
---|
1084 | || ($sLine[$i+$cchWord] >= 'A' && $sLine[$i+$cchWord] <= 'Z')
|
---|
1085 | )
|
---|
1086 | )
|
---|
1087 | $cchWord++;
|
---|
1088 |
|
---|
1089 | if ($sLine[$i + $cchWord++] != ';')
|
---|
1090 | $cchWord = 1;
|
---|
1091 | */
|
---|
1092 | if (substr($sLine, $i, 5) == "&")
|
---|
1093 | $cchWord = 5;
|
---|
1094 | else if (substr($sLine, $i, 4) == ">" || substr($sLine, $i, 4) == "<")
|
---|
1095 | $cchWord = 4;
|
---|
1096 | }
|
---|
1097 |
|
---|
1098 | /*
|
---|
1099 | * Check for Symbol.
|
---|
1100 | */
|
---|
1101 | if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
|
---|
1102 | {
|
---|
1103 | $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
1104 | $i += $cchWord;
|
---|
1105 | continue;
|
---|
1106 | }
|
---|
1107 |
|
---|
1108 |
|
---|
1109 | /*
|
---|
1110 | * Copy char
|
---|
1111 | */
|
---|
1112 | $sRet .= $sLine[$i];
|
---|
1113 | $i++;
|
---|
1114 | }
|
---|
1115 |
|
---|
1116 | return $sRet;
|
---|
1117 | }
|
---|
1118 |
|
---|
1119 |
|
---|
1120 | /**
|
---|
1121 | * Encode a line of C code.
|
---|
1122 | * @param $sLine Line string to encode.
|
---|
1123 | * @param $aVariables Variable array.
|
---|
1124 | * @returns Color encoded line string.
|
---|
1125 | */
|
---|
1126 | function C_ColorEncode2($sLine, &$aVariables)
|
---|
1127 | {
|
---|
1128 | global $aC_Keywords;
|
---|
1129 | global $aC_Symbols;
|
---|
1130 |
|
---|
1131 | $cchLine = strlen($sLine);
|
---|
1132 |
|
---|
1133 | /*
|
---|
1134 | * If mulitline comment we'll only check if it ends at this line.
|
---|
1135 | * if it doesn't we'll do nothing.
|
---|
1136 | * if it does we'll skip to then end of it.
|
---|
1137 | */
|
---|
1138 | if ($aVariables["fComment"])
|
---|
1139 | {
|
---|
1140 | if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
|
---|
1141 | {
|
---|
1142 | echo $sLine;
|
---|
1143 | return;
|
---|
1144 | }
|
---|
1145 | $i += 2;
|
---|
1146 | echo substr($sLine, 0, $i)."</font>";
|
---|
1147 | $aVariables["fComment"] = 0;
|
---|
1148 | }
|
---|
1149 | else
|
---|
1150 | $i = 0;
|
---|
1151 |
|
---|
1152 | /*
|
---|
1153 | * Loop thru the (remainings) of the line.
|
---|
1154 | */
|
---|
1155 | $fFirstNonBlank = 1;
|
---|
1156 | while ($i < $cchLine)
|
---|
1157 | {
|
---|
1158 | $ch = $sLine[$i];
|
---|
1159 | /* comment check */
|
---|
1160 | if ($i+1 < $cchLine && $ch == '/')
|
---|
1161 | {
|
---|
1162 | if ($sLine[$i+1] == '/')
|
---|
1163 | { /* one-line comment */
|
---|
1164 | echo "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
|
---|
1165 | return;
|
---|
1166 | }
|
---|
1167 |
|
---|
1168 | if ($sLine[$i+1] == '*')
|
---|
1169 | { /* Start of multiline comment */
|
---|
1170 | if ($j = strpos($sLine, "*/", $i + 2))
|
---|
1171 | {
|
---|
1172 | echo "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
|
---|
1173 | $i = $j + 2;
|
---|
1174 | }
|
---|
1175 | else
|
---|
1176 | {
|
---|
1177 | $aVariables["fComment"] = 1;
|
---|
1178 | echo "<font color=#02FE02>" . substr($sLine, $i);
|
---|
1179 | return;
|
---|
1180 | }
|
---|
1181 | continue;
|
---|
1182 | }
|
---|
1183 | }
|
---|
1184 |
|
---|
1185 | /*
|
---|
1186 | * Check for string.
|
---|
1187 | */
|
---|
1188 | if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == """)) || $sLine[$i] == "'")
|
---|
1189 | && ($i == 0 || $sLine[$i-1] != '\\'))
|
---|
1190 | { /* start of a string */
|
---|
1191 | $j = $i + 1;
|
---|
1192 | if ($fDbl)
|
---|
1193 | {
|
---|
1194 | /* if ($sLine[$i] == '"')
|
---|
1195 | while ($j < $cchLine && $sLine[$j] != '"')
|
---|
1196 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1197 | else */
|
---|
1198 | {
|
---|
1199 | while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != """))
|
---|
1200 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1201 | if ($j < $cchLine)
|
---|
1202 | $j += 5;
|
---|
1203 | }
|
---|
1204 | }
|
---|
1205 | else
|
---|
1206 | while ($j < $cchLine && $sLine[$j] != "'")
|
---|
1207 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
1208 | $j++;
|
---|
1209 | echo "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
|
---|
1210 | $i = $j;
|
---|
1211 | continue;
|
---|
1212 | }
|
---|
1213 |
|
---|
1214 | /*
|
---|
1215 | * Check for preprocessor directive.
|
---|
1216 | */
|
---|
1217 | if ($fFirstNonBlank && $ch == "#")
|
---|
1218 | {
|
---|
1219 | $j = $i + 1;
|
---|
1220 | while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == '\t'))
|
---|
1221 | $j++;
|
---|
1222 | $j += C_WordLen($sLine, $cchLine, $j);
|
---|
1223 | echo "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
|
---|
1224 | $i = $j;
|
---|
1225 | $fFirstNonBlank = 0;
|
---|
1226 | continue;
|
---|
1227 | }
|
---|
1228 |
|
---|
1229 | /*
|
---|
1230 | * If non-blank, lets check if we're at the start of a word...
|
---|
1231 | */
|
---|
1232 | $fBlank = ($ch == ' ' || $ch == '\t'); //TODO more "blanks"?
|
---|
1233 | if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
|
---|
1234 | $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
|
---|
1235 |
|
---|
1236 | if ($cchWord > 0)
|
---|
1237 | {
|
---|
1238 | /*
|
---|
1239 | * Check for keyword or number.
|
---|
1240 | */
|
---|
1241 | if ($cchWord > 0 && (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9')))
|
---|
1242 | echo "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
1243 |
|
---|
1244 | /*
|
---|
1245 | * Skip word.
|
---|
1246 | */
|
---|
1247 | else
|
---|
1248 | echo substr($sLine, $i, $cchWord);
|
---|
1249 | $i += $cchWord;
|
---|
1250 | continue;
|
---|
1251 | }
|
---|
1252 |
|
---|
1253 |
|
---|
1254 | /*
|
---|
1255 | * Prepare for symbol check. (we'll have to check for HTML stuff like &).
|
---|
1256 | */
|
---|
1257 | $cchWord = 1;
|
---|
1258 | if ($ch == '&')
|
---|
1259 | {
|
---|
1260 | /*
|
---|
1261 | while ($cchWord < 8 && $sLine[$i+$cchWord] != ';' &&
|
---|
1262 | ( ($sLine[$i+$cchWord] >= 'a' && $sLine[$i+$cchWord] <= 'z')
|
---|
1263 | || ($sLine[$i+$cchWord] >= 'A' && $sLine[$i+$cchWord] <= 'Z')
|
---|
1264 | )
|
---|
1265 | )
|
---|
1266 | $cchWord++;
|
---|
1267 |
|
---|
1268 | if ($sLine[$i + $cchWord++] != ';')
|
---|
1269 | $cchWord = 1;
|
---|
1270 | */
|
---|
1271 | if (substr($sLine, $i, 5) == "&")
|
---|
1272 | $cchWord = 5;
|
---|
1273 | else if (substr($sLine, $i, 4) == ">" || substr($sLine, $i, 4) == "<")
|
---|
1274 | $cchWord = 4;
|
---|
1275 | }
|
---|
1276 |
|
---|
1277 | /*
|
---|
1278 | * Check for Symbol.
|
---|
1279 | */
|
---|
1280 | if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
|
---|
1281 | {
|
---|
1282 | echo "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
1283 | $i += $cchWord;
|
---|
1284 | continue;
|
---|
1285 | }
|
---|
1286 |
|
---|
1287 |
|
---|
1288 | /*
|
---|
1289 | * Copy char
|
---|
1290 | */
|
---|
1291 | echo $ch;
|
---|
1292 | $i++;
|
---|
1293 | }
|
---|
1294 |
|
---|
1295 | return;
|
---|
1296 | }
|
---|
1297 |
|
---|
1298 |
|
---|
1299 | /**
|
---|
1300 | * Calculates the lenght of the word which eventually starts at [$i].
|
---|
1301 | * @param $sLine Line.
|
---|
1302 | * @param $cchLine Line length.
|
---|
1303 | * @param $i Line index.
|
---|
1304 | * @returns Word length.
|
---|
1305 | */
|
---|
1306 | function C_WordLen($sLine, $cchLine, $i)
|
---|
1307 | {
|
---|
1308 |
|
---|
1309 | /*
|
---|
1310 | * Check that previous letter wasen't a possible
|
---|
1311 | * word part.
|
---|
1312 | */
|
---|
1313 | if ($i > 0)
|
---|
1314 | {
|
---|
1315 | $ch = $sLine[$i - 1];
|
---|
1316 | if ( ($ch >= 'a' && $ch <= 'z')
|
---|
1317 | || ($ch >= 'A' && $ch <= 'Z')
|
---|
1318 | || ($ch >= '0' && $ch <= '9')
|
---|
1319 | || ($ch == '_')
|
---|
1320 | || ($ch == '$')
|
---|
1321 | )
|
---|
1322 | return 0;
|
---|
1323 | }
|
---|
1324 |
|
---|
1325 | /*
|
---|
1326 | * Count letters in the word
|
---|
1327 | */
|
---|
1328 | $j = $i;
|
---|
1329 | $ch = $sLine[$i];
|
---|
1330 | while ($i < $cchLine &&
|
---|
1331 | ( ($ch >= 'a' && $ch <= 'z')
|
---|
1332 | || ($ch >= 'A' && $ch <= 'Z')
|
---|
1333 | || ($ch >= '0' && $ch <= '9')
|
---|
1334 | || ($ch == '_')
|
---|
1335 | || ($ch == '$')
|
---|
1336 | )
|
---|
1337 | )
|
---|
1338 | $ch = @$sLine[++$i];
|
---|
1339 | return $i - $j;
|
---|
1340 | }
|
---|
1341 |
|
---|
1342 | ?>
|
---|
1343 |
|
---|