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