1 | <?php
|
---|
2 |
|
---|
3 |
|
---|
4 | $sCVSROOT = "d:/odin32/cvs/cvsroot";
|
---|
5 | $sCVSROOT = ".";
|
---|
6 |
|
---|
7 | /**
|
---|
8 | * Quick and dirty CVS file parser.
|
---|
9 | */
|
---|
10 | class CVSFile
|
---|
11 | {
|
---|
12 | var $fOk; /* Status of contructor. */
|
---|
13 | var $sError; /* Last error message. */
|
---|
14 | var $sFullName; /* Full path of the */
|
---|
15 | var $sDir; /* CVSROOT relative directory */
|
---|
16 | var $sName; /* Workfile filename. */
|
---|
17 | var $sExt; /* Workfile extention. */
|
---|
18 | var $aasKeys; /* base keys */
|
---|
19 | var $aasDeltas; /* the text values only */
|
---|
20 | var $aaasRevs; /* all types of revision info (but the text) */
|
---|
21 |
|
---|
22 |
|
---|
23 | /**
|
---|
24 | * Constructor.
|
---|
25 | * Opens a CVS repository file, reads it into memory and closes it.
|
---|
26 | */
|
---|
27 | function CVSFile($sFilename, $fNoDeltas)
|
---|
28 | {
|
---|
29 | global $sCVSROOT;
|
---|
30 |
|
---|
31 | $this->fOk = 0;
|
---|
32 | /*
|
---|
33 | * TODO: Security: Check that the path and filename is valid!
|
---|
34 | * We can't allow relative paths (ie. "..")
|
---|
35 | */
|
---|
36 | if (strlen($sFilename) < 3 || substr($sFilename, strlen($sFilename)-2) != ",v")
|
---|
37 | {
|
---|
38 | $this->sError = "filename is invalid";
|
---|
39 | return 1;
|
---|
40 | }
|
---|
41 |
|
---|
42 | /*
|
---|
43 | * Check filesize. Minimum size is 10 bytes!
|
---|
44 | */
|
---|
45 | $this->sFullname = $sCVSROOT."/".$sFilename;
|
---|
46 | $cbFile = filesize($this->sFullname);
|
---|
47 | if ($cbFile <= 10)
|
---|
48 | {
|
---|
49 | $this->sError = "too small file, " . $this->sFullname . ", ". $cbFile ."\n";
|
---|
50 | return 1;
|
---|
51 | }
|
---|
52 | if (!$fNoDeltas && $cbFile >= (2*1024*1024)) //currently max size of 2MB.
|
---|
53 | {
|
---|
54 | $this->sError = "\ntoo large file, ". $this->sFullname .", ". $cbFile ."\n";
|
---|
55 | return 1;
|
---|
56 | }
|
---|
57 |
|
---|
58 |
|
---|
59 | /*
|
---|
60 | * Seems ok. Let's, init object variables
|
---|
61 | */
|
---|
62 | $this->fOk = 0;
|
---|
63 | $this->sError = "";
|
---|
64 | $i = strrpos($sFilename, "\\");
|
---|
65 | $j = strrpos($sFilename, "/");
|
---|
66 | $i = ($i > $j) ? $i : $j;
|
---|
67 | $this->sName = substr($sFilename, $i > 0 ? $i + 1 : 0, strlen($sFilename)-2);
|
---|
68 | $this->sDir = substr($sFilename, 0, $i);
|
---|
69 | if (($i = strrpos($this->sName, '.')) > 0)
|
---|
70 | $this->sExt = substr($this->sName, $i+1);
|
---|
71 | else
|
---|
72 | $this->sExt = "";
|
---|
73 | $this->aasKeys = array();
|
---|
74 | $this->aasDeltas = array();
|
---|
75 | $this->aaasRevs = array();
|
---|
76 |
|
---|
77 |
|
---|
78 | /*
|
---|
79 | * Open the file
|
---|
80 | */
|
---|
81 | $hFile = fopen($this->sFullname, "rb");
|
---|
82 | if (!$hFile)
|
---|
83 | {
|
---|
84 | $this->sError = "\nfailed to open the file $this->sFullname\n";
|
---|
85 | fclose($hFile);
|
---|
86 | return 1;
|
---|
87 | }
|
---|
88 |
|
---|
89 |
|
---|
90 | /*
|
---|
91 | * Parse file.
|
---|
92 | */
|
---|
93 | $fAt = 0;
|
---|
94 | $fNewKey= 1;
|
---|
95 | $sKey = "";
|
---|
96 | $sRev = "";
|
---|
97 | $fDesc = 0;
|
---|
98 |
|
---|
99 | $iLine = -1;
|
---|
100 | $sLine = "";
|
---|
101 | $fStop = 0;
|
---|
102 | while (($sLine != "" || !feof($hFile)) && !$fStop)
|
---|
103 | {
|
---|
104 | /*
|
---|
105 | * Left trim.
|
---|
106 | * If empty line, get next and iterate.
|
---|
107 | */
|
---|
108 | $sLine = ltrim($sLine);
|
---|
109 | if (!$sLine || $sLine == "" || $sLine == "\n" || $sLine == "\r")
|
---|
110 | {
|
---|
111 | $iLine++;
|
---|
112 | $sLine = fgets($hFile, 0x1000);
|
---|
113 | continue;
|
---|
114 | }
|
---|
115 |
|
---|
116 | /*
|
---|
117 | * Are we looking for a new key word?
|
---|
118 | */
|
---|
119 | if ($fNewKey)
|
---|
120 | {
|
---|
121 | $sKey = CopyWord($sLine);
|
---|
122 | $sLine = ltrim(SkipWord($sLine));
|
---|
123 | if ($sKey[0] >= "0" && $sKey[0] <= "9")
|
---|
124 | /* Revision number: delta or revision info */
|
---|
125 | $sRev = $sKey;
|
---|
126 | else
|
---|
127 | $fNewKey = 0;
|
---|
128 | continue;
|
---|
129 | }
|
---|
130 |
|
---|
131 |
|
---|
132 | /*
|
---|
133 | * Extract value
|
---|
134 | */
|
---|
135 | $fNoSemicolon = ($sKey == "desc" || $sKey == "log" || $sKey == "desc");
|
---|
136 | if ($fAt = ($sLine[0] == "@")) //check if the value is enclosed in '@'s
|
---|
137 | $sLine = substr($sLine, 1);
|
---|
138 | $asValue = array();
|
---|
139 | $fEnd = 0;
|
---|
140 | while (!$fEnd)
|
---|
141 | {
|
---|
142 | /* get new line? */
|
---|
143 | if (!$sLine || $sLine == "" || $sLine == "\n" || $sLine == "\r")
|
---|
144 | {
|
---|
145 | if (feof($hFile))
|
---|
146 | break;
|
---|
147 | /* Get next line and remove any EOF chars */
|
---|
148 | $iLine++;
|
---|
149 | $sLine = str_replace("\x1a", "", fgets($hFile, 0x1000));
|
---|
150 | continue;
|
---|
151 | }
|
---|
152 |
|
---|
153 | //echo "debug line $iLine: $sLine";
|
---|
154 |
|
---|
155 | /*
|
---|
156 | * Look for end char (either ; or @) and copy.
|
---|
157 | * If end of value then $sLine <- rest of line.
|
---|
158 | */
|
---|
159 | $fEnd = 0;
|
---|
160 | $cchLine = strlen($sLine);
|
---|
161 | if ($fAt)
|
---|
162 | { /* terminated with @ */
|
---|
163 | $iAt = 0;
|
---|
164 | for ($iAt; $iAt+1 < $cchLine; $iAt++)
|
---|
165 | if ($sLine[$iAt] == '@' && ($fEnd = ($sLine[++$iAt] != '@')))
|
---|
166 | break;
|
---|
167 | if ($fEnd)
|
---|
168 | {
|
---|
169 | $asValue[] = str_replace("@@", "@", substr($sLine, 0, $iAt - 1));
|
---|
170 | /* if semicolon end, skip to it. ASSUMES: same line! */
|
---|
171 | if (!$fNoSemicolon && ($iAt = strpos($sLine, ";", $iAt)) >= 0)
|
---|
172 | $iAt++;
|
---|
173 | $sLine = (strlen($sLine) > $iAt && $iAt >= 0) ? substr($sLine, $iAt) : "";
|
---|
174 | }
|
---|
175 | else
|
---|
176 | {
|
---|
177 | $asValue[] = str_replace("@@", "@", $sLine);
|
---|
178 | $sLine = "";
|
---|
179 | }
|
---|
180 | }
|
---|
181 | else
|
---|
182 | { /* terminated with ';' */
|
---|
183 | $i = strpos($sLine, ';');
|
---|
184 | if ($fEnd = ($i >= 0))
|
---|
185 | {
|
---|
186 | $asValue[] = str_replace("@@", "@", substr($sLine, 0, $i));
|
---|
187 | $sLine = (strlen($sLine) > $i+1) ? substr($sLine, $i+1) : "";
|
---|
188 | }
|
---|
189 | else
|
---|
190 | {
|
---|
191 | $asValue[] = str_replace("@@", "@", $sLine);
|
---|
192 | $sLine = "";
|
---|
193 | }
|
---|
194 | }
|
---|
195 | }
|
---|
196 |
|
---|
197 |
|
---|
198 | /*
|
---|
199 | * Process the key.
|
---|
200 | */
|
---|
201 | switch ($sKey)
|
---|
202 | {
|
---|
203 | /*
|
---|
204 | * This is normally the keyword separating
|
---|
205 | * revision info from log+text info.
|
---|
206 | */
|
---|
207 | case "desc":
|
---|
208 | $fDesc = 1;
|
---|
209 | $sRev = "";
|
---|
210 | break;
|
---|
211 |
|
---|
212 | /*
|
---|
213 | * Stop after the first log entry.
|
---|
214 | */
|
---|
215 | case "log":
|
---|
216 | $fStop = $fNoDeltas;
|
---|
217 | break;
|
---|
218 |
|
---|
219 | /*
|
---|
220 | * Don'r read deltas for archives with the expand tag set
|
---|
221 | */
|
---|
222 | case "expand":
|
---|
223 | $fNoDeltas = 1;//= $asValue[0] != "";
|
---|
224 | break;
|
---|
225 | }
|
---|
226 |
|
---|
227 | /*
|
---|
228 | * Save key and value in the appopriate place.
|
---|
229 | */
|
---|
230 | if ($sRev == "")
|
---|
231 | { /* Base keys */
|
---|
232 | if (sizeof($this->aaKeys) <= 0 //sanity check! head must come first and have a value!
|
---|
233 | && ($sKey != "head" || sizeof($asValue) <= 0 || $asValue[0] == ""))
|
---|
234 | {
|
---|
235 | $this->sError = "Invalid file format.";
|
---|
236 | fclose($hFile);
|
---|
237 | return 1;
|
---|
238 | }
|
---|
239 | $this->aasKeys[$sKey] = $asValue;
|
---|
240 | }
|
---|
241 | else if ($sKey != "text")
|
---|
242 | { /* Revision information keys */
|
---|
243 | if (!isset($this->aaasRevs[$sRev]))
|
---|
244 | $this->aaasRevs[$sRev] = array($sKey => $asValue);
|
---|
245 | else
|
---|
246 | $this->aaasRevs[$sRev][$sKey] = $asValue;
|
---|
247 | }
|
---|
248 | else
|
---|
249 | { /* Delta (ie. 'text') key */
|
---|
250 | $this->aasDeltas[$sRev] = $asValue;
|
---|
251 | }
|
---|
252 |
|
---|
253 | /*
|
---|
254 | * Completed reading of this key, so next one.
|
---|
255 | */
|
---|
256 | $fNewKey = 1;
|
---|
257 |
|
---|
258 | /* debug */
|
---|
259 | //echo "debug key: $sKey value(".sizeof($asValue)."):".$asValue[0]."\n";
|
---|
260 | }
|
---|
261 |
|
---|
262 | fclose($hFile);
|
---|
263 |
|
---|
264 | /*
|
---|
265 | * Return successfully.
|
---|
266 | */
|
---|
267 | $this->fOk = 1;
|
---|
268 | return 1;
|
---|
269 | }
|
---|
270 |
|
---|
271 |
|
---|
272 | /**
|
---|
273 | * Debug dump function.
|
---|
274 | */
|
---|
275 | function DumpInfo()
|
---|
276 | {
|
---|
277 | echo "\nDump:\n";
|
---|
278 | while (list ($sKey, $asValue) = each ($this->aasKeys))
|
---|
279 | {
|
---|
280 | echo "* key: $sKey *\n";
|
---|
281 | if (sizeof((array)$asValue) > 0)
|
---|
282 | {
|
---|
283 | while (list ($key, $s) = each ($asValue))
|
---|
284 | echo $s;
|
---|
285 | echo "\n";
|
---|
286 | }
|
---|
287 | }
|
---|
288 |
|
---|
289 | while (list ($sRev, $aasKeys) = each ($this->aaasRevs))
|
---|
290 | {
|
---|
291 | echo "* Revision: $sRev *\n";
|
---|
292 | if (sizeof((array)$aasKeys) > 0)
|
---|
293 | {
|
---|
294 | while (list ($sKey, $asValue) = each ($aasKeys))
|
---|
295 | {
|
---|
296 | echo "* key: $sKey *\n";
|
---|
297 | if (sizeof((array)$asValue) > 0)
|
---|
298 | {
|
---|
299 | while (list ($key, $s) = each ($asValue))
|
---|
300 | echo $s;
|
---|
301 | echo "\n";
|
---|
302 | }
|
---|
303 | }
|
---|
304 | }
|
---|
305 | }
|
---|
306 |
|
---|
307 | while (list ($sKey, $asValue) = each ($this->aasDeltas))
|
---|
308 | {
|
---|
309 | echo "* delta for revision: $sKey *\n";
|
---|
310 | if (sizeof((array)$asValue) > 0)
|
---|
311 | {
|
---|
312 | while (list ($key, $s) = each ($asValue))
|
---|
313 | echo $s;
|
---|
314 | echo "\n";
|
---|
315 | }
|
---|
316 | }
|
---|
317 |
|
---|
318 | }
|
---|
319 |
|
---|
320 |
|
---|
321 | /**
|
---|
322 | * Prints the contents of the file to stdout.
|
---|
323 | *
|
---|
324 | * Color coding is enabled. (TODO)
|
---|
325 | *
|
---|
326 | * Currently only $sRevision == head revision is supported
|
---|
327 | * @returns Success indicator (true / false)
|
---|
328 | * @param $sRevision. Revision number. defaults to head revision.
|
---|
329 | *
|
---|
330 | */
|
---|
331 | function PrintRevision($sRevision)
|
---|
332 | {
|
---|
333 | /* defaults to head revision if empty */
|
---|
334 | if ($sRevision == "") $sRevision = $this->aasKeys["head"][0];
|
---|
335 | if (!isset($this->aasDeltas[$sRevision]))
|
---|
336 | {
|
---|
337 | $this->sError = "CVSFile::PrintRevision is called with an invalid revision number. ($sRevision)";
|
---|
338 | return 0;
|
---|
339 | }
|
---|
340 | /* to-be-removed - TODO - FIXME */
|
---|
341 | if ($sRevision != $this->aasKeys["head"][0])
|
---|
342 | {
|
---|
343 | $this->sError = "CVSFile::PrintRevision is called with an invalid revision number (not head).";
|
---|
344 | return 0;
|
---|
345 | }
|
---|
346 |
|
---|
347 | /*
|
---|
348 | * Initiate the color encoder.
|
---|
349 | */
|
---|
350 | switch ($this->sExt)
|
---|
351 | {
|
---|
352 | case 'c':
|
---|
353 | case 'cpp':
|
---|
354 | case 'cxx':
|
---|
355 | case 'h':
|
---|
356 | case 'hpp':
|
---|
357 | C_ColorInit($aVariables);
|
---|
358 | break;
|
---|
359 | }
|
---|
360 |
|
---|
361 |
|
---|
362 |
|
---|
363 | /*
|
---|
364 | * Write it!
|
---|
365 | */
|
---|
366 | echo "<table><tr><td bgcolor=\"#020286\"><pre><font size=-0 face=\"System VIO, System Monospaced\" color=\"#02FEFE\">\n";
|
---|
367 |
|
---|
368 | $fComment = 0;
|
---|
369 | $iLine = 0;
|
---|
370 | $cLines = sizeof($this->aasDeltas[$sRevision]);
|
---|
371 | //echo "<!-- debug $this->sExt -->\n";
|
---|
372 | while ($iLine < $cLines)
|
---|
373 | {
|
---|
374 | $sLine = htmlspecialchars($this->aasDeltas[$sRevision][$iLine++]);
|
---|
375 |
|
---|
376 | /*
|
---|
377 | * Preprocessing... Color coding
|
---|
378 | */
|
---|
379 | switch ($this->sExt)
|
---|
380 | {
|
---|
381 | case 'c':
|
---|
382 | case 'cpp':
|
---|
383 | case 'cxx':
|
---|
384 | case 'h':
|
---|
385 | case 'hpp':
|
---|
386 | $sLine = C_ColorEncode($sLine, $aVariables);
|
---|
387 | break;
|
---|
388 | }
|
---|
389 |
|
---|
390 | /*
|
---|
391 | * Finished processing of the line. So, write it.
|
---|
392 | */
|
---|
393 | echo "<a name=$iLine>$sLine</a>";
|
---|
394 | }
|
---|
395 |
|
---|
396 | echo "</pre></td></tr></table>\n";
|
---|
397 |
|
---|
398 | return 1;
|
---|
399 | }
|
---|
400 |
|
---|
401 |
|
---|
402 | }
|
---|
403 |
|
---|
404 |
|
---|
405 |
|
---|
406 | /**
|
---|
407 | * Copies the first word.
|
---|
408 | * A words is: [a-zA-Z0-9_.]
|
---|
409 | *
|
---|
410 | * tested ok
|
---|
411 | * @returns Returns the word at the start of $s.
|
---|
412 | */
|
---|
413 | function CopyWord($s)
|
---|
414 | {
|
---|
415 | $cch = strlen($s);
|
---|
416 | for ($i = 0; $i < $cch; $i++)
|
---|
417 | {
|
---|
418 | $c = $s[$i];
|
---|
419 | if (!($c >= 'a' && $c <= 'z')
|
---|
420 | &&
|
---|
421 | !($c >= 'A' && $c <= 'Z')
|
---|
422 | &&
|
---|
423 | !($c >= '0' && $c <= '9')
|
---|
424 | &&
|
---|
425 | !($c == '.' || $c == '_')
|
---|
426 | )
|
---|
427 | break;
|
---|
428 | }
|
---|
429 | return substr($s, 0, $i);
|
---|
430 | }
|
---|
431 |
|
---|
432 |
|
---|
433 | /**
|
---|
434 | * Skips the first word.
|
---|
435 | * A words is: [a-zA-Z0-9_.]
|
---|
436 | *
|
---|
437 | * tested ok
|
---|
438 | * @returns $s - first word.
|
---|
439 | */
|
---|
440 | function SkipWord($s)
|
---|
441 | {
|
---|
442 | $cch = strlen($s);
|
---|
443 | for ($i = 0; $i < $cch; $i++)
|
---|
444 | {
|
---|
445 | $c = $s[$i];
|
---|
446 | if (!($c >= 'a' && $c <= 'z')
|
---|
447 | &&
|
---|
448 | !($c >= 'A' && $c <= 'Z')
|
---|
449 | &&
|
---|
450 | !($c >= '0' && $c <= '9')
|
---|
451 | &&
|
---|
452 | !($c == '.' || $c == '_')
|
---|
453 | )
|
---|
454 | break;
|
---|
455 | }
|
---|
456 | return substr($s, $i);
|
---|
457 | }
|
---|
458 |
|
---|
459 |
|
---|
460 |
|
---|
461 |
|
---|
462 | /*
|
---|
463 | * C color encoding.
|
---|
464 | */
|
---|
465 | $aC_Keywords = array(
|
---|
466 | "auto" => 1,
|
---|
467 | "break" => 1,
|
---|
468 | "case" => 1,
|
---|
469 | "char" => 1,
|
---|
470 | "const" => 1,
|
---|
471 | "continue" => 1,
|
---|
472 | "default" => 1,
|
---|
473 | "defined" => 1,
|
---|
474 | "do" => 1,
|
---|
475 | "double" => 1,
|
---|
476 | "else" => 1,
|
---|
477 | "enum" => 1,
|
---|
478 | "extern" => 1,
|
---|
479 | "float" => 1,
|
---|
480 | "for" => 1,
|
---|
481 | "goto" => 1,
|
---|
482 | "if" => 1,
|
---|
483 | "int" => 1,
|
---|
484 | "long" => 1,
|
---|
485 | "register" => 1,
|
---|
486 | "return" => 1,
|
---|
487 | "short" => 1,
|
---|
488 | "sizeof" => 1,
|
---|
489 | "static" => 1,
|
---|
490 | "struct" => 1,
|
---|
491 | "switch" => 1,
|
---|
492 | "typedef" => 1,
|
---|
493 | "union" => 1,
|
---|
494 | "unsigned" => 1,
|
---|
495 | "void" => 1,
|
---|
496 | "while" => 1,
|
---|
497 | "class" => 1,
|
---|
498 | "delete" => 1,
|
---|
499 | "finally" => 1,
|
---|
500 | "friend" => 1,
|
---|
501 | "inline" => 1,
|
---|
502 | "new" => 1,
|
---|
503 | "operator" => 1,
|
---|
504 | "overload" => 1,
|
---|
505 | "private" => 1,
|
---|
506 | "protected" => 1,
|
---|
507 | "public" => 1,
|
---|
508 | "this" => 1,
|
---|
509 | "virtual" => 1,
|
---|
510 | "bool" => 1,
|
---|
511 | "true" => 1,
|
---|
512 | "false" => 1,
|
---|
513 | "explicit" => 1,
|
---|
514 | "mutable" => 1,
|
---|
515 | "typename" => 1,
|
---|
516 | "static_cast" => 1,
|
---|
517 | "const_cast" => 1,
|
---|
518 | "reinterpret_cast" => 1,
|
---|
519 | "dynamic_cast" => 1,
|
---|
520 | "using" => 1,
|
---|
521 | "typeid" => 1,
|
---|
522 | "asm" => 1,
|
---|
523 | "catch" => 1,
|
---|
524 | "signed" => 1,
|
---|
525 | "template" => 1,
|
---|
526 | "throw" => 1,
|
---|
527 | "try" => 1,
|
---|
528 | "volatile" => 1,
|
---|
529 | "namespace" => 1);
|
---|
530 |
|
---|
531 | $aC_Symbols = array(
|
---|
532 | "{" => 1,
|
---|
533 | "}" => 1,
|
---|
534 | // "[" => 1,
|
---|
535 | // "]" => 1,
|
---|
536 | // "(" => 1,
|
---|
537 | // ")" => 1,
|
---|
538 | // "." => 1,
|
---|
539 | // "," => 1,
|
---|
540 | "!" => 1,
|
---|
541 | "%" => 1,
|
---|
542 | "&" => 1,
|
---|
543 | "&" => 1,
|
---|
544 | "*" => 1,
|
---|
545 | "-" => 1,
|
---|
546 | "=" => 1,
|
---|
547 | "+" => 1,
|
---|
548 | ":" => 1,
|
---|
549 | ";" => 1,
|
---|
550 | "<" => 1,
|
---|
551 | "<" => 1,
|
---|
552 | ">" => 1,
|
---|
553 | ">" => 1,
|
---|
554 | "?" => 1,
|
---|
555 | "/" => 1,
|
---|
556 | "|" => 1,
|
---|
557 | "~" => 1,
|
---|
558 | "^" => 1,
|
---|
559 | "*" => 1);
|
---|
560 |
|
---|
561 | /**
|
---|
562 | * Initiate the variable array used by the C Color encoder.
|
---|
563 | * @param $aVaraibles Variable array. (output)
|
---|
564 | */
|
---|
565 | function C_ColorInit(&$aVariables)
|
---|
566 | {
|
---|
567 | $aVariables["fComment"] = 0;
|
---|
568 | }
|
---|
569 |
|
---|
570 |
|
---|
571 | /**
|
---|
572 | * Encode a line of C code.
|
---|
573 | * @param $sLine Line string to encode.
|
---|
574 | * @param $aVariables Variable array.
|
---|
575 | * @returns Color encoded line string.
|
---|
576 | */
|
---|
577 | function C_ColorEncode($sLine, &$aVariables)
|
---|
578 | {
|
---|
579 | global $aC_Keywords;
|
---|
580 | global $aC_Symbols;
|
---|
581 |
|
---|
582 | $sRet = "";
|
---|
583 | $cchLine = strlen($sLine);
|
---|
584 |
|
---|
585 | /*
|
---|
586 | * If mulitline comment we'll only check if it ends at this line.
|
---|
587 | * if it doesn't we'll do nothing.
|
---|
588 | * if it does we'll skip to then end of it.
|
---|
589 | */
|
---|
590 | if ($aVariables["fComment"])
|
---|
591 | {
|
---|
592 | if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
|
---|
593 | return $sLine;
|
---|
594 | $i += 2;
|
---|
595 | $sRet = substr($sLine, 0, $i)."</font>";
|
---|
596 | $aVariables["fComment"] = 0;
|
---|
597 | }
|
---|
598 | else
|
---|
599 | $i = 0;
|
---|
600 |
|
---|
601 | /*
|
---|
602 | * Loop thru the (remainings) of the line.
|
---|
603 | */
|
---|
604 | $fFirstNonBlank = 1;
|
---|
605 | while ($i < $cchLine)
|
---|
606 | {
|
---|
607 | /* comment check */
|
---|
608 | if ($i+1 < $cchLine && $sLine[$i] == '/')
|
---|
609 | {
|
---|
610 | if ($sLine[$i+1] == '/')
|
---|
611 | { /* one-line comment */
|
---|
612 | return $sRet . "<font color=\"#02FE02\">" . substr($sLine, $i) . "</font>";
|
---|
613 | }
|
---|
614 |
|
---|
615 | if ($sLine[$i+1] == '*')
|
---|
616 | { /* Start of multiline comment */
|
---|
617 | if ($j = strpos($sLine, "*/", $i + 2))
|
---|
618 | {
|
---|
619 | $sRet = $sRet . "<font color=\"#02FE02\">" . substr($sLine, $i, $j+2 - $i) . "</font>";
|
---|
620 | $i = $j + 2;
|
---|
621 | }
|
---|
622 | else
|
---|
623 | {
|
---|
624 | $aVariables["fComment"] = 1;
|
---|
625 | return $sRet . "<font color=\"#02FE02\">" . substr($sLine, $i);
|
---|
626 | }
|
---|
627 | continue;
|
---|
628 | }
|
---|
629 | }
|
---|
630 |
|
---|
631 |
|
---|
632 | /*
|
---|
633 | * Check for string.
|
---|
634 | */
|
---|
635 | if ((($fDbl = ($sLine[$i] == '"' || substr($sLine, $i, 6) == """)) || $sLine[$i] == "'")
|
---|
636 | && ($i == 0 || $sLine[$i-1] != '\\'))
|
---|
637 | { /* start of a string */
|
---|
638 | $j = $i + 1;
|
---|
639 | if ($fDbl)
|
---|
640 | {
|
---|
641 | if ($sLine[$i] == '"')
|
---|
642 | while ($j < $cchLine && $sLine[$j] != '"')
|
---|
643 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
644 | else
|
---|
645 | {
|
---|
646 | while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != """))
|
---|
647 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
648 | if ($j < $cchLine)
|
---|
649 | $j += 5;
|
---|
650 | }
|
---|
651 | }
|
---|
652 | else
|
---|
653 | while ($j < $cchLine && $sLine[$j] != "'")
|
---|
654 | $j += ($sLine[$j] == '\\') ? 2 : 1;
|
---|
655 | $j++;
|
---|
656 | $sRet .= "<font color=\"#FEFE02\">".substr($sLine, $i, $j - $i)."</font>";
|
---|
657 | $i = $j;
|
---|
658 | continue;
|
---|
659 | }
|
---|
660 |
|
---|
661 |
|
---|
662 | /*
|
---|
663 | * Check for preprocessor directive.
|
---|
664 | */
|
---|
665 | if ($fFirstNonBlank && $sLine[$i] == "#")
|
---|
666 | {
|
---|
667 | $j = $i + 1;
|
---|
668 | while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == '\t'))
|
---|
669 | $j++;
|
---|
670 | $j += C_WordLen($sLine, $cchLine, $j);
|
---|
671 | $sRet .= "<font color=\"#CECECE\">" . substr($sLine, $i, $j - $i) . "</font>";
|
---|
672 | $i = $j;
|
---|
673 | $fFirstNonBlank = 0;
|
---|
674 | continue;
|
---|
675 | }
|
---|
676 |
|
---|
677 | /*
|
---|
678 | * If non-blank, lets check if we're at the start of a word...
|
---|
679 | */
|
---|
680 | $fBlank = ($sLine[$i] == ' ' || $sLine[$i] == '\t'); //TODO more "blanks"?
|
---|
681 | if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
|
---|
682 | $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
|
---|
683 |
|
---|
684 | if ($cchWord > 0)
|
---|
685 | {
|
---|
686 | /*
|
---|
687 | * Check for keyword.
|
---|
688 | */
|
---|
689 | if ($cchWord > 0 && isset($aC_Keywords[substr($sLine, $i, $cchWord)]))
|
---|
690 | $sRet .= "<font color=\"#FF0202\">" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
691 |
|
---|
692 | /*
|
---|
693 | * Check for number
|
---|
694 | */
|
---|
695 | else if ($sLine[$i] >= '0' && $sLine[$i] <= '9')
|
---|
696 | $sRet .= "<font color=\"#FE0202\">" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
697 |
|
---|
698 | /*
|
---|
699 | * Skip word.
|
---|
700 | */
|
---|
701 | else
|
---|
702 | $sRet .= substr($sLine, $i, $cchWord);
|
---|
703 | $i += $cchWord;
|
---|
704 | continue;
|
---|
705 | }
|
---|
706 |
|
---|
707 |
|
---|
708 | /*
|
---|
709 | * Prepare for symbol check. (we'll have to check for HTML stuff like &).
|
---|
710 | */
|
---|
711 | $cchWord = 1;
|
---|
712 | if ($sLine[$i] == '&')
|
---|
713 | {
|
---|
714 | while ($cchWord < 8 && $sLine[$i+$cchWord] != ';' &&
|
---|
715 | ( ($sLine[$i+$cchWord] >= 'a' && $sLine[$i+$cchWord] <= 'z')
|
---|
716 | || ($sLine[$i+$cchWord] >= 'A' && $sLine[$i+$cchWord] <= 'Z')
|
---|
717 | )
|
---|
718 | )
|
---|
719 | $cchWord++;
|
---|
720 | if ($sLine[$i + $cchWord++] != ';')
|
---|
721 | $cchWord = 1;
|
---|
722 | }
|
---|
723 |
|
---|
724 | /*
|
---|
725 | * Check for Symbol.
|
---|
726 | */
|
---|
727 | if (isset($aC_Symbols[substr($sLine, $i, 1)]))
|
---|
728 | {
|
---|
729 | $sRet .= "<font color=\"#CECECE\">" . substr($sLine, $i, $cchWord) . "</font>";
|
---|
730 | $i += $cchWord;
|
---|
731 | continue;
|
---|
732 | }
|
---|
733 |
|
---|
734 |
|
---|
735 | /*
|
---|
736 | * Copy char
|
---|
737 | */
|
---|
738 | $sRet = $sRet.$sLine[$i];
|
---|
739 | $i++;
|
---|
740 | }
|
---|
741 |
|
---|
742 | return $sRet;
|
---|
743 | }
|
---|
744 |
|
---|
745 |
|
---|
746 |
|
---|
747 | /**
|
---|
748 | * Calculates the lenght of the word which eventually starts at [$i].
|
---|
749 | * @param $sLine Line.
|
---|
750 | * @param $cchLine Line length.
|
---|
751 | * @param $i Line index.
|
---|
752 | * @returns Word length.
|
---|
753 | */
|
---|
754 | function C_WordLen($sLine, $cchLine, $i)
|
---|
755 | {
|
---|
756 |
|
---|
757 | /*
|
---|
758 | * Check that previous letter wasen't a possible
|
---|
759 | * word part.
|
---|
760 | */
|
---|
761 | if ($i > 0 &&
|
---|
762 | (
|
---|
763 | ($sLine[$i-1] >= 'a' && $sLine[$i-1] <= 'z')
|
---|
764 | || ($sLine[$i-1] >= 'A' && $sLine[$i-1] <= 'Z')
|
---|
765 | || ($sLine[$i-1] >= '0' && $sLine[$i-1] <= '9')
|
---|
766 | || ($sLine[$i-1] == '_')
|
---|
767 | || ($sLine[$i-1] == '$')
|
---|
768 | )
|
---|
769 | )
|
---|
770 | return 0;
|
---|
771 |
|
---|
772 | /*
|
---|
773 | * Count letters in the word
|
---|
774 | */
|
---|
775 | $cch = 0;
|
---|
776 | $cchLine = strlen($sLine);
|
---|
777 | while ($i < $cchLine &&
|
---|
778 | (
|
---|
779 | ($sLine[$i] >= 'a' && $sLine[$i] <= 'z')
|
---|
780 | || ($sLine[$i] >= 'A' && $sLine[$i] <= 'Z')
|
---|
781 | || ($sLine[$i] >= '0' && $sLine[$i] <= '9')
|
---|
782 | || ($sLine[$i] == '_')
|
---|
783 | || ($sLine[$i] == '$')
|
---|
784 | )
|
---|
785 | )
|
---|
786 | {
|
---|
787 | $i++;
|
---|
788 | $cch++;
|
---|
789 | }
|
---|
790 | return $cch;
|
---|
791 | }
|
---|
792 |
|
---|
793 | ?>
|
---|
794 |
|
---|