source: trunk/tools/database/www/cvs.php3@ 6753

Last change on this file since 6753 was 6753, checked in by bird, 24 years ago

corrected cvsroot.

File size: 73.7 KB
Line 
1<?php
2
3require "Odin32DBHelpers.php3";
4
5/*
6 * Configuration:
7 */
8$sCVSROOT = "g:/cvsroot";
9$sCVSROOT = "e:/netlabs.cvs/odin";
10$sIconsUrl = "/icons";
11$sIconsUrl = "http://www.netlabs.org/icons";
12
13
14/**
15 * Quick and dirty CVS file parser.
16 */
17class CVSFile
18{
19 var $fOk; /* Status of contructor. */
20 var $sError; /* Last error message. */
21 var $sFullName; /* Full path of the */
22 var $sDir; /* CVSROOT relative directory */
23 var $sName; /* Workfile filename. */
24 var $sExt; /* Workfile extention. */
25 var $aasKeys; /* base keys */
26 var $aasDeltas; /* the text values only */
27 var $aaasRevs; /* all types of revision info (but the text) */
28
29
30 /**
31 * Constructor.
32 * Opens a CVS repository file, reads it into memory and closes it.
33 */
34 function CVSFile($sFilename, $fNoDeltas)
35 {
36 global $sCVSROOT;
37
38
39 $this->fOk = 0;
40 /*
41 * TODO: Security: Check that the path and filename is valid!
42 * We can't allow relative paths (ie. "..")
43 */
44 if (strlen($sFilename) < 3 || substr($sFilename, -2) != ",v")
45 {
46 $this->sError = "filename is invalid";
47 return 1;
48 }
49 $sFilename = str_replace("\\", "/", $sFilename);
50 if ((substr($sFilename, 0, 3) == "../")
51 ||
52 (substr($sFilename, -3) == "/..")
53 ||
54 (strpos($sFilename, "/../") > 0)
55 )
56 {
57 $this->sError = "Invalid parameter: \$sFilename $sFilename";
58 return 87;
59 }
60 if ($sFilename[0] == '/')
61 $sFilename = ".".$sFilename;
62 else if (substr($sFilename, 0, 2) != "./")
63 $sFilename = "./".$sFilename;
64
65 /*
66 * Check filesize. Minimum size is 10 bytes!
67 */
68 $this->sFullname = $sCVSROOT."/".$sFilename;
69 $cbFile = filesize($this->sFullname);
70 if ($cbFile <= 10)
71 {
72 $this->sError = "too small file, " . $this->sFullname . ", ". $cbFile ."\n";
73 return 1;
74 }
75 if (!$fNoDeltas && $cbFile >= (2*1024*1024)) //currently max size of 2MB.
76 {
77 $this->sError = "\ntoo large file, ". $this->sFullname .", ". $cbFile ."\n";
78 return 1;
79 }
80
81
82 /*
83 * Seems ok. Let's, init object variables
84 */
85 $this->fOk = 0;
86 $this->sError = "";
87 $i = strrpos($sFilename, "\\");
88 $j = strrpos($sFilename, "/");
89 $i = ($i > $j) ? $i : $j;
90 $this->sName = substr($sFilename, $i > 0 ? $i + 1 : 0, strlen($sFilename)-2 - ($i > 0 ? $i + 1 : 0));
91 $this->sDir = substr($sFilename, 0, $i);
92 if (($i = strrpos($this->sName, '.')) > 0)
93 $this->sExt = substr($this->sName, $i+1);
94 else
95 $this->sExt = "";
96 $this->aasKeys = array();
97 $this->aasDeltas = array();
98 $this->aaasRevs = array();
99
100
101 /*
102 * Open the file
103 */
104 $hFile = fopen($this->sFullname, "rb");
105 if (!$hFile)
106 {
107 $this->sError = "\nfailed to open the file $this->sFullname\n";
108 fclose($hFile);
109 return 1;
110 }
111
112 /*
113 * Parse the file.
114 */
115 $Timer = Odin32DBTimerStart("CVS Parse");
116 $this->fOk = $this->ParseFile($hFile, $fNoDeltas);
117 Odin32DBTimerStop($Timer);
118
119 fclose($hFile);
120
121 /*
122 * Return.
123 */
124
125 return 1;
126 }
127
128
129 /**
130 * Parses the file.
131 * (internal)
132 */
133 function ParseFile($hFile, $fNoDeltas)
134 {
135
136 /*
137 * Parse file.
138 */
139 $sKey = "";
140 $sRev = "";
141
142 $sLine = "";
143 $fStop = 0;
144 while (!$fStop)
145 {
146 /*
147 * Left trim.
148 * If empty line, get next and iterate.
149 */
150 $sLine = ltrim($sLine);
151 if ($sLine == "")
152 {
153 if (feof($hFile))
154 break;
155 $sLine = fgets($hFile, 0x1000);
156 continue;
157 }
158
159 /*
160 * Are we looking for a new key word?
161 */
162 if ($sKey == "")
163 {
164 $cch = strlen($sLine);
165 for ($i = 0; $i < $cch; $i++)
166 {
167 $c = $sLine[$i];
168 if (!( ($c >= 'a' && $c <= 'z')
169 || ($c >= 'A' && $c <= 'Z')
170 || ($c >= '0' && $c <= '9')
171 || $c == '.' || $c == '_'
172 )
173 )
174 break;
175 }
176 if ($sLine[0] >= "0" && $sLine[0] <= "9") // Revision number: delta or revision info
177 $sRev = substr($sLine, 0, $i);
178 else
179 $sKey = substr($sLine, 0, $i);
180 $sLine = ltrim(substr($sLine, $i));
181 continue;
182 }
183
184
185 /*
186 * Extract value
187 */
188 $fSemicolon = !($sKey == "desc" || $sKey == "log" || $sKey == "desc");
189 $asValue = array();
190 $fEnd = 0;
191 if ($sLine[0] == "@") //check if the value is enclosed in '@'s
192 {
193 $sLine = substr($sLine, 1);
194 for (;;)
195 {
196 /* get new line? */
197 if ($sLine == "")
198 {
199 if (feof($hFile))
200 break;
201 $sLine = fgets($hFile, 0x1000);
202 continue;
203 }
204
205 /*
206 * Look for end char ( @) and copy.
207 * If end of value then $sLine <- rest of line.
208 */
209 if ($sLine[0] != '@' || $sLine[1] == '@')
210 {
211 $iAt = 0;
212 while ($iAt = strpos($sLine, "@", $iAt+1))
213 if ($fEnd = ($sLine[++$iAt] != '@'))
214 {
215 $asValue[] = str_replace("@@", "@", substr($sLine, 0, $iAt - 1));
216 /* if semicolon end, skip to it. ASSUMES: same line! */
217 if ($fSemicolon && ($i = strpos($sLine, ";", $iAt)) > 0)
218 $iAt = $i + 1;
219 $sLine = substr($sLine, $iAt);
220 break;
221 }
222 if ($iAt > 0)
223 break;
224 }
225 else
226 {
227 /* if semicolon end, skip to it. ASSUMES: same line! */
228 if ($fSemicolon && ($iAt = strpos($sLine, ";", 1)) > 0)
229 $sLine = substr($sLine, $iAt+1);
230 else
231 $sLine = substr($sLine, 1);
232 break;
233 }
234
235 $asValue[] = str_replace("@@", "@", $sLine);
236 $sLine = fgets($hFile, 0x1000);
237 }
238 }
239 else
240 {
241 for (;;)
242 {
243 /* get new line? */
244 if ($sLine == "")
245 {
246 if (feof($hFile))
247 break;
248 $sLine = fgets($hFile, 0x1000);
249 continue;
250 }
251
252 /*
253 * Look for end char (either ; or @) and copy.
254 * If end of value then $sLine <- rest of line.
255 */
256 if (($i = strpos($sLine, ';')) <= 0 && $sLine[0] != ';')
257 { //terminator not found.
258 $asValue[] = $sLine;
259 $sLine = fgets($hFile, 0x1000);
260 }
261 else
262 { //terminator found
263 $asValue[] = substr($sLine, 0, $i);
264 $sLine = substr($sLine, $i+1);
265 break; // end
266 }
267 }
268 }
269
270
271 /*
272 * Process the key.
273 */
274 switch ($sKey)
275 {
276 /*
277 * This is normally the keyword separating
278 * revision info from log+text info.
279 */
280 case "desc":
281 $sRev = "";
282 break;
283
284 /*
285 * Stop after the first log entry.
286 */
287 case "log":
288 $fStop = $fNoDeltas;
289 break;
290
291 /*
292 * Reparse the value.
293 */
294 case "symbols":
295 $asValue2 = $asValue;
296 $asValue = array();
297 while (list ($sIgnore, $sVal) = each ($asValue2))
298 {
299 if (($sVal = trim($sVal)) != "")
300 {
301 if ($iColon = strpos($sVal, ":"))
302 $asValue[substr($sVal, 0, $iColon)] = substr($sVal, $iColon+1);
303 else
304 echo "\n<!-- error in symbols parsing -->\n";
305 }
306 }
307 break;
308
309 /*
310 * Don'r read deltas for archives with the expand tag set
311 */
312 case "expand":
313 $fNoDeltas = 1;//= $asValue[0] != "";
314 break;
315 }
316
317 /*
318 * Save key and value in the appopriate place.
319 */
320 if ($sRev == "")
321 { /* Base keys */
322 if (sizeof($this->aasKeys) <= 0 //sanity check! head must come first and have a value!
323 && ($sKey != "head" || sizeof($asValue) <= 0 || $asValue[0] == ""))
324 {
325 $this->sError = "Invalid file format.";
326 fclose($hFile);
327 return 0;
328 }
329 $this->aasKeys[$sKey] = $asValue;
330 }
331 else if ($sKey != "text")
332 { /* Revision information keys */
333 if (!isset($this->aaasRevs[$sRev]))
334 $this->aaasRevs[$sRev] = array($sKey => $asValue);
335 else
336 $this->aaasRevs[$sRev][$sKey] = $asValue;
337 }
338 else
339 { /* Delta (ie. 'text') key */
340 $this->aasDeltas[$sRev] = $asValue;
341 }
342
343 /*
344 * Completed reading of this key, so next one.
345 */
346 $sKey = "";
347 }
348
349 return 1;
350 }
351
352
353
354 /**
355 * Debug dump function.
356 */
357 function DumpInfo()
358 {
359 echo "\nDump:<br>\n";
360
361 while (list ($sKey, $asValue) = each ($this->aasKeys))
362 {
363 echo "* key: $sKey *<br>\n";
364 if (sizeof((array)$asValue) > 0)
365 {
366 while (list ($key, $s) = each ($asValue))
367 echo $s;
368 echo "<br>\n";
369 }
370 }
371
372 while (list ($sRev, $aasKeys) = each ($this->aaasRevs))
373 {
374 echo "* Revision: $sRev *<br>\n";
375 if (sizeof((array)$aasKeys) > 0)
376 {
377 while (list ($sKey, $asValue) = each ($aasKeys))
378 {
379 echo "* key: $sKey *<br>\n";
380 if (sizeof((array)$asValue) > 0)
381 {
382 while (list ($key, $s) = each ($asValue))
383 echo $s;
384 echo "<br>\n";
385 }
386 }
387 }
388 }
389
390 if (0)
391 {
392 while (list ($sKey, $asValue) = each ($this->aasDeltas))
393 {
394 echo "* delta for revision: $sKey *<br>\n";
395 if (sizeof((array)$asValue) > 0)
396 {
397 while (list ($key, $s) = each ($asValue))
398 echo $s."<br>";
399 echo "\n";
400 }
401 }
402 }
403 }
404
405
406 /**
407 * Prints the contents of the file to stdout.
408 *
409 * Color coding is enabled.
410 *
411 * Currently only $sRevision == head revision is supported
412 * @returns Success indicator (true / false)
413 * @param $sRevision. Revision number. defaults to head revision.
414 *
415 */
416 function PrintRevision($sRevision)
417 {
418 /* defaults to head revision if empty */
419 if ($sRevision == "") $sRevision = $this->aasKeys["head"][0];
420 if (!isset($this->aasDeltas[$sRevision]))
421 {
422 $this->sError = "CVSFile::PrintRevision is called with an invalid revision number. ($sRevision)";
423 return 0;
424 }
425
426 /*
427 * Make header
428 */
429 echo "<table><tr><td bgcolor=#f0f0f0>\n<table>";
430 //file info
431 echo "<tr><td valign=top><font size=-1>File:</font></td>\n",
432 "<td><font size=-1>", $this->getDirUrls(), " / <a href=\"cvs.php?sFile=$this->sDir/$this->sName,v\">$this->sName</a></font></td></tr>\n";
433
434 //revision info
435 echo "<tr><td valign=top><font size=-1>Revision:</font></td>\n",
436 "<td><font size=-1>$sRevision, ",
437 CVSFormatDate($this->getDate($sRevision)),
438 " (",CVSGetAge($this->getDate($sRevision), 6), ")",
439 "<br>by ", $this->getAuthor($sRevision),
440 "</font></td></tr>\n";
441
442 //branch info
443 echo "<tr><td valign=top><font size=-1>Branch:</font></td>\n",
444 "<td><font size=-1>", $this->getBranch($sRevision),
445 "</font></td></tr>\n";
446
447 //tag info
448 echo "<tr><td valign=top><font size=-1>Tags:</font></td>\n",
449 "<td><font size=-1>", $this->getTags($sRevision),
450 "</font></td></tr>\n";
451
452 //log info
453 $asLog = $this->getLog($sRevision);
454 echo "<tr><td valign=top><font size=-1>Log:</font></td>",
455 "<td><font size=-1>\n";
456 if (isset($asLog))
457 while (list($sKey, $s) = each ($asLog))
458 echo $s; //this should be <pre> but, that will need some line wrapping...
459 //echo str_replace("\n", "<br>", $s), "\n"; //this should be <pre> but, that will need some line wrapping...
460 echo "</font></td><tr>\n";
461
462 echo "</table>\n";//<hr noshade>\n";
463
464
465 /*
466 * Initiate the color encoder.
467 */
468 switch (strtolower($this->sExt))
469 {
470 case "c":
471 case "cpp":
472 case "cxx":
473 case "h":
474 case "hpp":
475 C_ColorInit($aVariables);
476 $iColorEncoder = 1;
477 break;
478
479 case "asm":
480 case "inc":
481 case "s":
482 ASM_ColorInit($aVariables);
483 $iColorEncoder = 2;
484 break;
485
486 case "mk":
487 case "mak":
488 Make_ColorInit($aVariables);
489 $iColorEncoder = 3;
490 break;
491
492 default:
493 if (strtolower($this->sName) == "makefile")
494 {
495 Make_ColorInit($aVariables);
496 $iColorEncoder = 3;
497 break;
498 }
499 $iColorEncoder = 0;
500 }
501
502
503
504 /*
505 * Write it!
506 */
507 $Timer = Odin32DBTimerStart("Write timer");
508 echo "<tr><td bgcolor=#020286><pre><font size=-0 face=\"System VIO, System Monospaced\" color=#02FEFE>";
509 if ($sRevision == $this->aasKeys["head"][0])
510 {
511 //head revision
512 for ($cLines = sizeof($this->aasDeltas[$sRevision]), $iLine = 0;
513 ($iLine < $cLines);
514 $iLine++)
515 {
516 /*
517 * Preprocessing... Color coding
518 */
519 echo "<a name=$iLine>";
520 switch ($iColorEncoder)
521 {
522 case 1:
523 echo str_replace("\t", " ", C_ColorEncode(htmlspecialchars($this->aasDeltas[$sRevision][$iLine]), $aVariables));
524 break;
525 case 2:
526 echo str_replace("\t", " ", ASM_ColorEncode(htmlspecialchars($this->aasDeltas[$sRevision][$iLine]), $aVariables));
527 break;
528 case 3:
529 echo str_replace("\t", " ", Make_ColorEncode(htmlspecialchars($this->aasDeltas[$sRevision][$iLine]), $aVariables));
530 break;
531 default:
532 echo str_replace("\t", " ", htmlspecialchars($this->aasDeltas[$sRevision][$iLine]));
533 }
534 echo "</a>";
535 }
536 }
537 else
538 {
539 //build revision
540 $sRev = $this->aasKeys["head"][0];
541 $asText = $this->aasDeltas[$sRev];
542 do
543 {
544 /*
545 * determin revision.
546 * (hope this works ok...)
547 */
548 $sPrevRev = $sRev;
549 $asBranches = $this->aaasRevs[$sRev]["branches"];
550 for ($f = 0, $i = 0; $i < sizeof($asBranches); $i++)
551 {
552 if (($sB = trim($asBranches[$i])) != "")
553 {
554 $sB2 = substr($sB, 0, strrpos($sB, ".") + 1);
555 if ($f = ($sB2 == substr($sRevision, 0, strlen($sB2))))
556 {
557 $sRev = $sB;
558 break;
559 }
560 }
561 }
562
563 if (!$f) $sRev = $this->aaasRevs[$sRev]["next"][0];
564 echo "<!-- \$sRev=$sRev -->";
565
566
567 /*
568 * Apply the delta.
569 */
570 $asOrg = $asText;
571 $asText = array();
572 $iOrg = 0;
573 $cOrg = sizeof($asOrg);
574 $iDelta = 0;
575 $cDelta = sizeof($this->aasDeltas[$sRev]);
576 $iText = 0;
577 while ($cDelta > $iDelta)
578 {
579 //get the next diff chunk
580 $iDiff = (int)substr($this->aasDeltas[$sRev][$iDelta], 1, strpos($this->aasDeltas[$sRev], " ") - 1) - 1;
581
582 //skip to it
583 while ($iDiff > $iOrg && $iOrg < $cOrg)
584 $asText[$iText++] = $asOrg[$iOrg++];
585
586 //apply it
587 $c = (int)substr($this->aasDeltas[$sRev][$iDelta],
588 (int)strpos($this->aasDeltas[$sRev][$iDelta], " ") + 1);
589 if ($this->aasDeltas[$sRev][$iDelta][0] == 'a')
590 {
591 $iDelta++;
592 while ($iDelta < $cDelta && $c-- > 0)
593 $asText[$iText++] = $this->aasDeltas[$sRev][$iDelta++];
594
595 while ($c-- > 0)
596 $asText[$iText++] = "";
597 }
598 else
599 {
600 $iDelta++;
601 $iOrg += $c;
602 }
603 }
604
605 //copy remaining
606 while ($iOrg < $cOrg)
607 $asText[$iText++] = $asOrg[$iOrg++];
608
609 } while ($sRev != "" && $sRev != $sRevision);
610
611 /*
612 * Print it
613 */
614 for ($cLines = sizeof($asText), $iLine = 0; $iLine < $cLines; $iLine++)
615 {
616 /*
617 * Preprocessing... Color coding
618 */
619 echo "<a name=$iLine>";
620 switch ($iColorEncoder)
621 {
622 case 1:
623 echo str_replace("\t", " ", C_ColorEncode(htmlspecialchars($asText[$iLine]), $aVariables));
624 break;
625 case 2:
626 echo str_replace("\t", " ", ASM_ColorEncode(htmlspecialchars($asText[$iLine]), $aVariables));
627 break;
628 case 3:
629 echo str_replace("\t", " ", Make_ColorEncode(htmlspecialchars($asText[$iLine]), $aVariables));
630 break;
631 default:
632 echo str_replace("\t", " ", htmlspecialchars($asText[$iLine]));
633 }
634 echo "</a>";
635 }
636 }
637 echo " \n", //80-columns line
638 "</pre></td></tr></table>\n";
639 Odin32DBTimerStop($Timer);
640
641 return 1;
642 }
643
644
645 /**
646 * Gets the revision number of the head revision.
647 * @returns head revision number
648 */
649 function getHead()
650 {
651 return $this->aasKeys["head"][0];
652 }
653
654
655 /**
656 * Gets the log string for the given revision.
657 * @returns Array of strings in the log text.
658 * @param $sRev Revision number to get log text for.
659 */
660 function getLog($sRev)
661 {
662 return @$this->aaasRevs[$sRev]["log"];
663 }
664
665
666 /**
667 * Gets the author for a revision.
668 * @return Author name.
669 * @param $sRev Revision number to get author name for.
670 */
671 function getAuthor($sRev)
672 {
673 return @$this->aaasRevs[$sRev]["author"][0];
674 }
675
676 /**
677 * Get date+time stap on a revision.
678 * @returns date string for the given revision.
679 * @param $sRev Revision number to get date+time for.
680 */
681 function getDate($sRev)
682 {
683 if (($sDate = @$this->aaasRevs[$sRev]["date"][0]) != ""
684 && $sDate[2] == "." //check for two digit date
685 )
686 return "19".$sDate;
687 return $sDate;
688 }
689
690 /**
691 * Get the workfile extention.
692 * @returns The workfile extention (without '.').
693 */
694 function getWorkfileExt()
695 {
696 return $this->sExt;
697 }
698
699 /**
700 * Get the workfile extention.
701 * @returns The workfile name (with extention)
702 */
703 function getWorkfileName()
704 {
705 return $this->sName;
706 }
707
708 /**
709 * Is this a binary file? We'll simply check for the expand keyword.
710 * @returns True (1) if binary, false (0) if not.
711 */
712 function isBinary()
713 {
714 return isset($this->aasKeys["expand"]);
715 }
716
717 /**
718 * Get loginfo for the given revision.
719 * @returns Array of log info for the given revision.
720 * @param $sRev Revision number to get loginfo for.
721 */
722 function getLog($sRev)
723 {
724 return @$this->aaasRevs[$sRev]["log"];
725 }
726
727 /**
728 * Get the branch name for the given revision.
729 * @return Branch name.
730 * @param $sRev Revision number to get branchname for.
731 */
732 function getBranch($sRev)
733 {
734 $aiDots = array();
735
736 for ($i = strlen($sRev) - 1; $i >= 0; $i--)
737 if ($sRev[$i] == ".")
738 $aiDots[] = $i;
739
740 if (sizeof($aiDots) == 1)
741 return "MAIN";
742
743 $sBranch = substr($sRev, 0, $aiDots[1]).".0";
744 $cchBranch = strlen($sBranch);
745 reset($this->aasKeys["symbols"]);
746 while (list($sTag, $sTagRev) = each($this->aasKeys["symbols"]))
747 {
748 $j = strrpos($sTagRev, ".");
749 //echo "<!-- $j $cchBranch ($sBranch, ".substr($sTagRev, 0, $j).")-->";
750 if ($cchBranch == $j && $sBranch == substr($sTagRev, 0, $j))
751 return $sTag;
752 }
753
754 return "";
755 }
756
757 /**
758 * Get the tag names associated with the given revision.
759 * @return comma separated list of tag names.
760 * @param $sRev Revision number to get tag names for.
761 */
762 function getTags($sRev)
763 {
764 //didn't find a search function, so we'll do a linear search.
765 //thru the symbols. Correct this when/if a array search function
766 //is found.
767 $sTags = "";
768 if (isset($this->aasKeys["symbols"]))
769 {
770 $asSymbols = $this->aasKeys["symbols"];
771 while (list($sTag, $sTagRev) = each($asSymbols))
772 if ($sTagRev == $sRev)
773 $sTags = ", $sTag";
774 }
775
776 //check for head revision
777 if ($sRev == $this->aasKeys["head"][0])
778 $sTags = ", HEAD";
779
780 return substr($sTags, 2); //remove ", "
781 }
782
783 /**
784 * Get a directory string (for this file) where every level
785 * is an URL to the page for it.
786 * @return URL directory string.
787 */
788 function getDirUrls()
789 {
790 return CVSGetDirUrls($this->sDir);
791 }
792
793 /**
794 * Get changes string for this revision.
795 * (Won't work for the head revision!)
796 * @return Changes string: "+x -y lines".
797 * @param $sRev Revision which we're to count changes for.
798 */
799 function getChanges($sRev)
800 {
801 if (!isset($this->aasDeltas[$sRev]))
802 return "<i>error</i>";
803 if ($sRev == $this->aasKeys["head"][0])
804 return "+0 -0 lines";
805 $cAdd = 0;
806 $cDelete = 0;
807
808 for ($i = 0, $c = sizeof($this->aasDeltas[$sRev]); $i < $c; $i++)
809 {
810 $sLine = $this->aasDeltas[$sRev][$i];
811 if ($sLine[0] == "d")
812 $cDelete += (int)substr($sLine, strpos($sLine, " ") + 1);
813 else if ($sLine[0] == "a")
814 {
815 $cAdd += (int)substr($sLine, strpos($sLine, " ") + 1);
816 $i += $cLines;
817 }
818 else
819 echo "<!-- hmm internal error in getChanges -->\n";
820 }
821
822 return "+$cDelete -$cAdd lines"; //note the deltas is for going the other way...
823 }
824
825 /**
826 *
827 * @return
828 */
829 function PrintAllInfo()
830 {
831
832 //file info
833 echo "<font size=-1>", $this->getDirUrls(), " / $this->sName</font><p>\n",
834 "\n";
835
836 echo "<table>\n";
837 //do we have to sort the array first? no...
838 $i = 0; //max is 256!!! (ChangeLog,v is _very_ big).
839 while ($i++ < 256 && list($sRevision, $aasRev) = each($this->aaasRevs))
840 {
841 echo "<tr><td bgcolor=#d0dce0>Rev. <a href=\"cvs.php?sFile=$this->sDir/$this->sName,v&sRevision=$sRevision\"",
842 "<a name=\"$sRevision\">$sRevision</a></a> by ",
843 $this->getAuthor($sRevision) ,"</td></tr>\n",
844 "<tr><td bgcolor=#f0f0f0>";
845
846 echo "<table>";
847 //revision date info
848 echo "<tr><td valign=top><font size=-1>Date:</font></td>\n",
849 "<td><font size=-1>",CVSFormatDate($this->getDate($sRevision)),
850 "<br>(",CVSGetAge($this->getDate($sRevision), 6), ")",
851 "</font></td></tr>\n";
852
853 //branch info
854 echo "<tr><td valign=top><font size=-1>Branch:</font></td>\n",
855 "<td><font size=-1>", $this->getBranch($sRevision),
856 "</font></td></tr>\n";
857
858 //tag info
859 echo "<tr><td valign=top><font size=-1>Tags:</font></td>\n",
860 "<td><font size=-1>", $this->getTags($sRevision),
861 "</font></td></tr>\n";
862
863 //Changes info
864 if (isset($aasRev["next"]) && ($sPrevRev = $aasRev["next"][0]) != "")
865 {
866 echo "<tr><td valign=top><font size=-1>Changes since $sPrevRev:</font></td>\n",
867 "<td><font size=-1>", $this->getChanges($sPrevRev),
868 "</font></td></tr>\n";
869 }
870
871 //log info
872 $asLog = $this->getLog($sRevision);
873 echo "<tr><td valign=top><font size=-1>Log:</font></td><td><font size=-1>\n";
874 if (isset($asLog))
875 while (list($sKey, $s) = each ($asLog))
876 echo $s; //this should be <pre> but, that will need some line wrapping...
877 //echo str_replace("\n", "<br>", $s), "\n"; //this should be <pre> but, that will need some line wrapping...
878 echo "</font></td></tr>\n";
879
880 echo "</table>\n";
881
882 echo "</td></tr>\n";
883 }
884
885 echo "</table>\n";
886 return 1;
887 }
888}
889
890
891/**
892 * Get a directory string where every level
893 * is an URL to the page for it.
894 * @return URL directory string.
895 * @param Directory string to process.
896 */
897function CVSGetDirUrls($sDir)
898{
899 if ($sDir == "")
900 $sDir = "./";
901 else if (substr($sDir, -1) != "/")
902 $sDir .= "/";
903
904 $iPrev = 2;
905 $sRet = "<a href=\"cvs.php?sDir=.\">[root]</a>";
906 while ($i = @strpos($sDir, "/", $iPrev))
907 {
908 $sRet .= " / <a href=\"cvs.php?sDir=".substr($sDir, 0, $i)."\">".
909 substr($sDir, $iPrev, $i - $iPrev)."</a>";
910 $iPrev = $i + 1;
911 }
912
913 return $sRet;
914}
915
916
917
918/**
919 * Get a understandable date string from a CVS date.
920 * @returns Date string (human readable)
921 * @param $sDate CVS date string. (as returned by getDate())
922 */
923function CVSFormatDate($sDate)
924{
925 $Time = mktime( substr($sDate,11, 2), //hour
926 substr($sDate,14, 2), //minute
927 substr($sDate,17, 2), //second
928 substr($sDate, 5, 2), //month
929 substr($sDate, 8, 2), //day
930 substr($sDate, 0, 4));//year
931 return date("D M d h:i:s Y", $Time);
932}
933
934
935/**
936 * Calculate the period between $sDate and the current date.
937 * @returns Age string. (human readable)
938 * @param $sDate CVS date string. (as returned by getDate())
939 * @param $cLevels Number of levels to be specified.
940 */
941function CVSGetAge($sDate, $cLevels)
942{
943 $sCurDate = date("Y.m.d.H.i.s");
944 if ($sDate > $sCurDate)
945 return "0 seconds"; //fixme?
946
947 /* seconds */
948 $i1 = substr($sCurDate, 17, 2);
949 $i2 = substr($sDate, 17, 2);
950 if ($fBorrow = ($i1 < $i2))
951 $i1 += 60;
952 $iSeconds = $i1 - $i2;
953
954 /* minutes */
955 $i1 = substr($sCurDate, 14, 2);
956 $i2 = substr($sDate, 14, 2);
957 if ($fBorrow)
958 $i1--;
959 if ($fBorrow = ($i1 < $i2))
960 $i1 += 60;
961 $iMinutes = $i1 - $i2;
962
963 /* hours */
964 $i1 = substr($sCurDate, 11, 2);
965 $i2 = substr($sDate, 11, 2);
966 if ($fBorrow)
967 $i1--;
968 if ($fBorrow = ($i1 < $i2))
969 $i1 += 24;
970 $iHours = $i1 - $i2;
971
972 /* days */
973 $i1 = substr($sCurDate, 8, 2);
974 $i2 = substr($sDate, 8, 2);
975 if ($fBorrow)
976 $i1--;
977 if ($fBorrow = ($i1 < $i2))
978 {
979 $iM = substr($sCurDate, 5, 2);
980 $iY = substr($sCurDate, 0, 4);
981 if ($iM == 1 || $iM == 3 || $iM == 5 || $iM == 7 || $iM == 8 || $iM == 10 || $iM == 12)
982 $i1 += 31;
983 else if ($iM == 4 || $iM == 6 || $iM == 9 || $iM == 11)
984 $i1 += 30;
985 else if (($iY % 4) != 0 || (($iY % 100) == 0 && ($iY % 1000) != 0))
986 $i1 += 28;
987 else
988 $i1 += 29;
989 }
990 $iDays = $i1 - $i2;
991
992 /* months */
993 $i1 = substr($sCurDate, 5, 2);
994 $i2 = substr($sDate, 5, 2);
995 if ($fBorrow)
996 $i1--;
997 if ($fBorrow = ($i1 < $i2))
998 $i1 += 12;
999 $iMonths = $i1 - $i2;
1000
1001 /* years */
1002 $i1 = substr($sCurDate, 0, 4);
1003 $i2 = substr($sDate, 0, 4);
1004 if ($fBorrow)
1005 $i1--;
1006 $iYears = $i1 - $i2;
1007
1008 //printf("<!-- $sCurDate - $sDate = %04d.%02d.%02d.%02d.%02d.%02d -->\n", $iYears, $iMonths, $iDays, $iHours, $iMinutes, $iSeconds);
1009
1010
1011 /* make output */
1012 $sRet = "";
1013 if ($cLevels > 0 && $iYears > 0)
1014 {
1015 $cLevels--;
1016 $sRet .= "$iYears year".($iYears > 1 ? "s" : "");
1017 }
1018 if ($cLevels > 0 && $iMonths > 0)
1019 {
1020 $cLevels--;
1021 $sRet .= " $iMonths month".($iMonths > 1 ? "s" : "");
1022 }
1023 if ($cLevels > 0 && $iDays > 0)
1024 {
1025 $cLevels--;
1026 $sRet .= " $iDays day".($iDays > 1 ? "s" : "");
1027 }
1028 if ($cLevels > 0 && $iHours > 0)
1029 {
1030 $cLevels--;
1031 $sRet .= " $iHours hour".($iHours > 1 ? "s" : "");
1032 }
1033 if ($cLevels > 0 && $iMinutes > 0)
1034 {
1035 $cLevels--;
1036 $sRet .= " $iMinutes minute".($iHours > 1 ? "s" : "");
1037 }
1038 if ($cLevels > 0)
1039 $sRet .= " $iSeconds second".($iHours > 1 ? "s" : "");
1040 return ltrim($sRet);
1041}
1042
1043
1044/**
1045 * This function displayes the contents of an directory.
1046 */
1047function ListDirectory($sDir, $iSortColumn)
1048{
1049 global $sCVSROOT;
1050 global $sIconsUrl;
1051 $timer = Odin32DBTimerStart("List Directory");
1052
1053 /*
1054 * Validate and fixup $sDir.
1055 * Note that relative .. is not allowed!
1056 */
1057 $sDir = str_replace("\\", "/", $sDir);
1058 if ($sDir == "")
1059 $sDir = ".";
1060 if ($sDir[0] == '/')
1061 $sDir = substr($sDir, 1);
1062 if (substr($sDir, -1) == '/')
1063 $sDir = substr($sDir, 0, - 1);
1064 if ((strlen($sDir) == 2 && $sDir == "..")
1065 ||
1066 (substr($sDir, 0, 3) == "../")
1067 ||
1068 (substr($sDir, -3) == "/..")
1069 ||
1070 (strpos($sDir, "/../") > 0)
1071 )
1072 {
1073 echo "<!-- Invalid parameter: \$sDir $sDir -->\n";
1074 echo "<i>Invalid parameter: \$sDir $sDir </i>\n";
1075 return 87;
1076 }
1077
1078 /*
1079 * Open the directory, read the contents into two arrays;
1080 * one for files and one for directories. All files which
1081 * don't end with ',v' are ignored.
1082 */
1083 $hDir = opendir($sCVSROOT.'/'.$sDir);
1084 if (!$hDir)
1085 {
1086 echo "<!-- debug error opendir($sDir) failed -->\n";
1087 echo "<i>debug error opendir($sDir) failed</i>\n";
1088 return 5;
1089 }
1090
1091 $asFiles = array();
1092 $asSubDirs = array();
1093 while ($sEntry = readdir($hDir))
1094 {
1095 if (is_dir($sCVSROOT.'/'.$sDir.'/'.$sEntry))
1096 {
1097 if ($sEntry != '..' && $sEntry != '.')
1098 $asSubDirs[] = $sEntry;
1099 }
1100 else
1101 {
1102 $cchEntry = strlen($sEntry);
1103 if ($cchEntry > 2 && substr($sEntry, $cchEntry - 2, 2) == ',v')
1104 $asFiles[$sEntry] = $sEntry;
1105 }
1106 }
1107 closedir($hDir);
1108
1109 /*
1110 * Get CVS data.
1111 */
1112 $aExtIcons = array(
1113 "c" => "c.gif",
1114 "cpp" => "c.gif",
1115 "cxx" => "c.gif",
1116 "h" => "c.gif",
1117 "hpp" => "c.gif",
1118 "c" => "c.gif",
1119 /* these are caught by the isBinary test.
1120 "exe" => "binary.gif",
1121 "dll" => "binary.gif",
1122 "lib" => "binary.gif",
1123 "obj" => "binary.gif",
1124 "a" => "binary.gif",
1125 */
1126 "bmp" => "image1.gif",
1127 "gif" => "image1.gif",
1128 "ico" => "image1.gif",
1129 "jpg" => "image1.gif",
1130 "pal" => "image1.gif",
1131 "png" => "image1.gif",
1132 "asm" => "text.gif",
1133 "def" => "text.gif",
1134 "doc" => "text.gif",
1135 "inc" => "text.gif",
1136 "lib" => "text.gif",
1137 "mak" => "text.gif",
1138 "mk" => "text.gif",
1139 "txt" => "text.gif",
1140 "" => "text.gif",
1141 "bat" => "script.gif",
1142 "cmd" => "script.gif",
1143 "perl" => "script.gif",
1144 "sh" => "script.gif"
1145 );
1146 $cvstimer = Odin32DBTimerStart("Get CVS Data");
1147 $asRev = array();
1148 $asAge = array();
1149 $asAuthor = array();
1150 $asLog = array();
1151 $asIcon = array();
1152 for ($i = 0; list($sKey, $sFile) = each($asFiles); $i++)
1153 {
1154 $obj = new CVSFile($sDir.'/'.$sFile, 1);
1155 if ($obj->fOk)
1156 {
1157 $asRev[$sFile] = $sRev = $obj->getHead();
1158 $asDate[$sFile] = $obj->getDate($sRev);
1159 $asAuthor[$sFile] = $obj->getAuthor($sRev);
1160 $asTmpLog = $obj->getLog($sRev);
1161 for ($sLog = "", $j = sizeof($asTmpLog) - 1; $j >= 0; $j--)
1162 {
1163 if ($sLog == "")
1164 {
1165 if (trim($asTmpLog[$j]) != "")
1166 $sLog = $asTmpLog[$j];
1167 continue;
1168 }
1169 $sLog = $asTmpLog[$j]."<br>".$sLog;
1170 }
1171 $asLog[$sFile] = $sLog;
1172 $sLog = "";
1173 $asIcon[$sFile] = isset($aExtIcons[strtolower($obj->getWorkfileExt())])
1174 ? $aExtIcons[strtolower($obj->getWorkfileExt())] :
1175 ($obj->isBinary() ? "binary.gif" : "unknown.gif");
1176 }
1177 else
1178 $asLog[$sFile] = $obj->sError;
1179 }
1180 Odin32DBTimerStop($cvstimer);
1181
1182 /*
1183 * Write header
1184 */
1185 echo "<font size=-1>", CVSGetDirUrls(dirname($sDir)),
1186 ($sDir != "." ? " / ".substr($sDir, strrpos($sDir, "/") + 1) : ""),
1187 " /</font><p>\n";
1188
1189 /*
1190 * Sort the stuff.
1191 */
1192 sort($asSubDirs);
1193 switch ($iSortColumn)
1194 {
1195 case 0: $asSorted = $asFiles; break;
1196 case 1: $asSorted = $asRev; break;
1197 case 2: $asSorted = $asDate; break;
1198 case 3: $asSorted = $asAuthor; break;
1199 case 4: $asSorted = $asLog; break;
1200 default: $asSorted = $asFiles; break;
1201 }
1202 asort($asSorted);
1203
1204
1205 /*
1206 * Present data
1207 */
1208 $aColumnColors = array("#d0dce0","#d0dce0","#d0dce0","#d0dce0", "#d0dcff","#d0dce0","#d0dce0","#d0dce0","#d0dce0");
1209 echo "<table border=0 width=100% cellspacing=1 cellpadding=2>\n",
1210 " <tr>\n",
1211 " <th bgcolor=",$aColumnColors[4+0-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=0>Filename</a></b></font></th>\n",
1212 " <th bgcolor=",$aColumnColors[4+1-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=1>Rev</a></b></font></th>\n",
1213 " <th bgcolor=",$aColumnColors[4+2-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=2>Age</a></b></font></th>\n",
1214 " <th bgcolor=",$aColumnColors[4+3-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=3>Author</a></b></font></th>\n",
1215 " <th bgcolor=",$aColumnColors[4+4-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=4>Last Log Entry</a></b></font></th>\n",
1216 " </tr>\n";
1217 $i = 0;
1218 /* directories */
1219 if ($sDir != "." && $sDir != "")
1220 {
1221 if (($j = strrpos($sDir, "/")) > 0)
1222 $sParentDir = substr($sDir, 0, $j);
1223 else
1224 $sParentDir = ".";
1225 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1226 echo "<tr>\n",
1227 " <td", $sBgColor , ">",
1228 "<font size=-1><a href=\"cvs.php?sDir=",$sParentDir,"\"><img src=\"$sIconsUrl/back.gif\" border=0> Parent Directory</a></font></td>\n",
1229 " <td$sBgColor>&nbsp;</td>\n",
1230 " <td$sBgColor>&nbsp;</td>\n",
1231 " <td$sBgColor>&nbsp;</td>\n",
1232 " <td$sBgColor>&nbsp;</td>\n",
1233 "</tr>\n";
1234 }
1235 while (list($sKey, $sVal) = each($asSubDirs))
1236 {
1237 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1238 echo "<tr>\n",
1239 " <td$sBgColor><font size=-1><a href=\"cvs.php?sDir=$sDir/$sVal\"><img src=\"$sIconsUrl/dir.gif\" border=0> $sVal</a></font></td>\n",
1240 " <td$sBgColor>&nbsp;</td>\n",
1241 " <td$sBgColor>&nbsp;</td>\n",
1242 " <td$sBgColor>&nbsp;</td>\n",
1243 " <td$sBgColor>&nbsp;</td>\n",
1244 "</tr>\n";
1245 }
1246
1247 /* files */
1248 while (list($sKey, $sVal) = each($asSorted))
1249 {
1250 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1251 $sRev = isset($asRev[$sKey]) ? $asRev[$sKey] : "<i> error </i>";
1252 $sAge = isset($asDate[$sKey]) ? CVSGetAge($asDate[$sKey], 1) : "<i> error </i>";
1253 $sAuthor= isset($asAuthor[$sKey])?$asAuthor[$sKey] : "<i> error </i>";
1254 $sLog = isset($asLog[$sKey]) ? $asLog[$sKey] : "<i> error </i>";
1255 $sIcon = isset($asIcon[$sKey]) ? $asIcon[$sKey] : "<i> error </i>";
1256 echo "<tr>\n",
1257 " <td$sBgColor><font size=-1><a href=\"cvs.php?sFile=$sDir/$sKey\"><img src=\"$sIconsUrl/$sIcon\" border=0>",substr($sKey, 0, -2),"</a></font></td>\n",
1258 " <td$sBgColor><font size=-1><a href=\"cvs.php?sFile=$sDir/$sKey&sRevision=$sRev\">$sRev</a></font></td>\n",
1259 " <td$sBgColor><font size=-1>$sAge</font></td>\n",
1260 " <td$sBgColor><font size=-1>$sAuthor</font></td>\n",
1261 " <td$sBgColor><font size=-2>$sLog</font></td>\n",
1262 "</tr>\n";
1263 }
1264
1265 echo "</table>\n";
1266 Odin32DBTimerStop($timer);
1267
1268
1269 /*
1270 * Debug dump.
1271 *//*
1272 while (list ($sKey, $sVal) = each ($asSubDirs))
1273 echo "Dir: $sVal<br>\n";
1274 while (list ($sKey, $sVal) = each ($asFiles))
1275 echo "File: $sVal<br>\n";
1276 */
1277}
1278
1279
1280/**
1281 * Copies the first word.
1282 * A words is: [a-zA-Z0-9_.]
1283 *
1284 * tested ok
1285 * @returns Returns the word at the start of $s.
1286 */
1287function CopyWord($s)
1288{
1289 $cch = strlen($s);
1290 for ($i = 0; $i < $cch; $i++)
1291 {
1292 $c = $s[$i];
1293 if (!($c >= 'a' && $c <= 'z')
1294 &&
1295 !($c >= 'A' && $c <= 'Z')
1296 &&
1297 !($c >= '0' && $c <= '9')
1298 &&
1299 !($c == '.' || $c == '_')
1300 )
1301 break;
1302 }
1303 return substr($s, 0, $i);
1304}
1305
1306
1307/**
1308 * Skips the first word.
1309 * A words is: [a-zA-Z0-9_.]
1310 *
1311 * tested ok
1312 * @returns $s - first word.
1313 */
1314function SkipWord($s)
1315{
1316 $cch = strlen($s);
1317 for ($i = 0; $i < $cch; $i++)
1318 {
1319 $c = $s[$i];
1320 if (!($c >= 'a' && $c <= 'z')
1321 &&
1322 !($c >= 'A' && $c <= 'Z')
1323 &&
1324 !($c >= '0' && $c <= '9')
1325 &&
1326 !($c == '.' || $c == '_')
1327 )
1328 break;
1329 }
1330 return substr($s, $i);
1331}
1332
1333
1334
1335
1336/*
1337 * C color encoding.
1338 */
1339$aC_Keywords = array(
1340// "auto" => 1,
1341 "break" => 1,
1342 "case" => 1,
1343 "char" => 1,
1344 "const" => 1,
1345 "continue" => 1,
1346 "default" => 1,
1347// "defined" => 1,
1348 "do" => 1,
1349 "double" => 1,
1350 "else" => 1,
1351 "enum" => 1,
1352 "extern" => 1,
1353 "float" => 1,
1354 "for" => 1,
1355 "goto" => 1,
1356 "if" => 1,
1357 "int" => 1,
1358 "long" => 1,
1359 "register" => 1,
1360 "return" => 1,
1361 "short" => 1,
1362 "sizeof" => 1,
1363 "static" => 1,
1364 "struct" => 1,
1365 "switch" => 1,
1366 "typedef" => 1,
1367 "union" => 1,
1368 "unsigned" => 1,
1369 "void" => 1,
1370 "while" => 1,
1371 "class" => 1,
1372 "delete" => 1,
1373// "finally" => 1,
1374 "friend" => 1,
1375 "inline" => 1,
1376 "new" => 1,
1377 "operator" => 1,
1378 "overload" => 1,
1379 "private" => 1,
1380 "protected" => 1,
1381 "public" => 1,
1382 "this" => 1,
1383 "virtual" => 1,
1384// "bool" => 1,
1385// "true" => 1,
1386// "false" => 1,
1387 "explicit" => 1,
1388 "mutable" => 1,
1389 "typename" => 1,
1390// "static_cast" => 1,
1391// "const_cast" => 1,
1392// "reinterpret_cast" => 1,
1393// "dynamic_cast" => 1,
1394// "using" => 1,
1395 "typeid" => 1,
1396// "asm" => 1,
1397 "catch" => 1,
1398 "signed" => 1,
1399 "template" => 1,
1400 "throw" => 1,
1401 "try" => 1,
1402// "namespace" => 1,
1403 "volatile" => 1
1404
1405 );
1406
1407$aC_Symbols = array(
1408 "{" => 1,
1409 "}" => 1,
1410// "[" => 1,
1411// "]" => 1,
1412// "(" => 1,
1413// ")" => 1,
1414// "." => 1,
1415// "," => 1,
1416 "!" => 1,
1417 "%" => 1,
1418// "&" => 1,
1419 "&amp;" => 1,
1420 "*" => 1,
1421 "-" => 1,
1422 "=" => 1,
1423 "+" => 1,
1424 ":" => 1,
1425 ";" => 1,
1426// "<" => 1,
1427 "&lt;" => 1,
1428// ">" => 1,
1429 "&gt;" => 1,
1430 "?" => 1,
1431 "/" => 1,
1432 "|" => 1,
1433 "~" => 1,
1434 "^" => 1,
1435 "*" => 1);
1436
1437/**
1438 * Initiate the variable array used by the C Color encoder.
1439 * @param $aVaraibles Variable array. (output)
1440 */
1441function C_ColorInit(&$aVariables)
1442{
1443 global $aC_Keywords;
1444 global $aC_Symbols;
1445
1446 $aVariables["fComment"] = 0;
1447
1448 ksort($aC_Keywords);
1449 ksort($aC_Symbols);
1450}
1451
1452
1453/**
1454 * Encode a line of C code.
1455 * @param $sLine Line string to encode.
1456 * @param $aVariables Variable array.
1457 * @returns Color encoded line string.
1458 */
1459function C_ColorEncode($sLine, &$aVariables)
1460{
1461 global $aC_Keywords;
1462 global $aC_Symbols;
1463
1464 $sRet = "";
1465 $cchLine = strlen($sLine);
1466
1467 /*
1468 * If mulitline comment we'll only check if it ends at this line.
1469 * if it doesn't we'll do nothing.
1470 * if it does we'll skip to then end of it.
1471 */
1472 if ($aVariables["fComment"])
1473 {
1474 if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
1475 return $sLine;
1476 $i += 2;
1477 $sRet = substr($sLine, 0, $i)."</font>";
1478 $aVariables["fComment"] = 0;
1479 }
1480 else
1481 $i = 0;
1482
1483 /*
1484 * Loop thru the (remainings) of the line.
1485 */
1486 $fFirstNonBlank = 1;
1487 while ($i < $cchLine)
1488 {
1489 $ch = $sLine[$i];
1490 /* comment check */
1491 if ($i+1 < $cchLine && $ch == '/')
1492 {
1493 if ($sLine[$i+1] == '/')
1494 { /* one-line comment */
1495 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
1496 }
1497
1498 if ($sLine[$i+1] == '*')
1499 { /* Start of multiline comment */
1500 if ($j = strpos($sLine, "*/", $i + 2))
1501 {
1502 $sRet .= "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
1503 $i = $j + 2;
1504 }
1505 else
1506 {
1507 $aVariables["fComment"] = 1;
1508 return $sRet . "<font color=#02FE02>" . substr($sLine, $i);
1509 }
1510 continue;
1511 }
1512 }
1513
1514 /*
1515 * Check for string.
1516 */
1517 if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
1518 && ($i == 0 || $sLine[$i-1] != '\\'))
1519 { /* start of a string */
1520 $j = $i + 1;
1521 if ($fDbl)
1522 {
1523 /* if ($sLine[$i] == '"')
1524 while ($j < $cchLine && $sLine[$j] != '"')
1525 $j += ($sLine[$j] == '\\') ? 2 : 1;
1526 else */
1527 {
1528 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
1529 $j += ($sLine[$j] == '\\') ? 2 : 1;
1530 if ($j < $cchLine)
1531 $j += 5;
1532 }
1533 }
1534 else
1535 while ($j < $cchLine && $sLine[$j] != "'")
1536 $j += ($sLine[$j] == '\\') ? 2 : 1;
1537 $j++;
1538 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
1539 $i = $j;
1540 continue;
1541 }
1542
1543 /*
1544 * Check for preprocessor directive.
1545 */
1546 if ($fFirstNonBlank && $ch == "#")
1547 {
1548 $j = $i + 1;
1549 while ($j < $cchLine && ($sLine[$j] == " " || $sLine[$j] == "\t"))
1550 $j++;
1551 $j += C_WordLen($sLine, $cchLine, $j);
1552 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
1553 $i = $j;
1554 $fFirstNonBlank = 0;
1555 continue;
1556 }
1557
1558 /*
1559 * If non-blank, lets check if we're at the start of a word...
1560 */
1561 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
1562 if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
1563 $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
1564
1565 if ($cchWord > 0)
1566 {
1567 /*
1568 * Check for keyword or number.
1569 */
1570 if (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9'))
1571 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
1572
1573 /*
1574 * Skip word.
1575 */
1576 else
1577 $sRet .= substr($sLine, $i, $cchWord);
1578 $i += $cchWord;
1579 continue;
1580 }
1581
1582
1583 /*
1584 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
1585 */
1586 $cchWord = 1;
1587 if ($ch == '&')
1588 {
1589 /*
1590 while ($cchWord < 8 && $sLine[$i+$cchWord] != ';' &&
1591 ( ($sLine[$i+$cchWord] >= 'a' && $sLine[$i+$cchWord] <= 'z')
1592 || ($sLine[$i+$cchWord] >= 'A' && $sLine[$i+$cchWord] <= 'Z')
1593 )
1594 )
1595 $cchWord++;
1596
1597 if ($sLine[$i + $cchWord++] != ';')
1598 $cchWord = 1;
1599 */
1600 if (substr($sLine, $i, 5) == "&amp;")
1601 $cchWord = 5;
1602 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
1603 $cchWord = 4;
1604 }
1605
1606 /*
1607 * Check for Symbol.
1608 */
1609 if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
1610 {
1611 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
1612 $i += $cchWord;
1613 continue;
1614 }
1615
1616
1617 /*
1618 * Copy char
1619 */
1620 $sRet .= $sLine[$i];
1621 $i++;
1622 }
1623
1624 return $sRet;
1625}
1626
1627
1628/**
1629 * Encode a line of C code.
1630 * @param $sLine Line string to encode.
1631 * @param $aVariables Variable array.
1632 * @returns Color encoded line string.
1633 */
1634function C_ColorEncode2($sLine, &$aVariables)
1635{
1636 global $aC_Keywords;
1637 global $aC_Symbols;
1638
1639 $cchLine = strlen($sLine);
1640
1641 /*
1642 * If mulitline comment we'll only check if it ends at this line.
1643 * if it doesn't we'll do nothing.
1644 * if it does we'll skip to then end of it.
1645 */
1646 if ($aVariables["fComment"])
1647 {
1648 if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
1649 {
1650 echo $sLine;
1651 return;
1652 }
1653 $i += 2;
1654 echo substr($sLine, 0, $i)."</font>";
1655 $aVariables["fComment"] = 0;
1656 }
1657 else
1658 $i = 0;
1659
1660 /*
1661 * Loop thru the (remainings) of the line.
1662 */
1663 $fFirstNonBlank = 1;
1664 while ($i < $cchLine)
1665 {
1666 $ch = $sLine[$i];
1667 /* comment check */
1668 if ($i+1 < $cchLine && $ch == '/')
1669 {
1670 if ($sLine[$i+1] == '/')
1671 { /* one-line comment */
1672 echo "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
1673 return;
1674 }
1675
1676 if ($sLine[$i+1] == '*')
1677 { /* Start of multiline comment */
1678 if ($j = strpos($sLine, "*/", $i + 2))
1679 {
1680 echo "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
1681 $i = $j + 2;
1682 }
1683 else
1684 {
1685 $aVariables["fComment"] = 1;
1686 echo "<font color=#02FE02>" . substr($sLine, $i);
1687 return;
1688 }
1689 continue;
1690 }
1691 }
1692
1693 /*
1694 * Check for string.
1695 */
1696 if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
1697 && ($i == 0 || $sLine[$i-1] != '\\'))
1698 { /* start of a string */
1699 $j = $i + 1;
1700 if ($fDbl)
1701 {
1702 /* if ($sLine[$i] == '"')
1703 while ($j < $cchLine && $sLine[$j] != '"')
1704 $j += ($sLine[$j] == '\\') ? 2 : 1;
1705 else */
1706 {
1707 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
1708 $j += ($sLine[$j] == '\\') ? 2 : 1;
1709 if ($j < $cchLine)
1710 $j += 5;
1711 }
1712 }
1713 else
1714 while ($j < $cchLine && $sLine[$j] != "'")
1715 $j += ($sLine[$j] == '\\') ? 2 : 1;
1716 $j++;
1717 echo "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
1718 $i = $j;
1719 continue;
1720 }
1721
1722 /*
1723 * Check for preprocessor directive.
1724 */
1725 if ($fFirstNonBlank && $ch == "#")
1726 {
1727 $j = $i + 1;
1728 while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == "\t"))
1729 $j++;
1730 $j += C_WordLen($sLine, $cchLine, $j);
1731 echo "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
1732 $i = $j;
1733 $fFirstNonBlank = 0;
1734 continue;
1735 }
1736
1737 /*
1738 * If non-blank, lets check if we're at the start of a word...
1739 */
1740 $fBlank = ($ch == ' ' || $ch == "\t"); //TODO more "blanks"?
1741 if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
1742 $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
1743
1744 if ($cchWord > 0)
1745 {
1746 /*
1747 * Check for keyword or number.
1748 */
1749 if (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9'))
1750 echo "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
1751
1752 /*
1753 * Skip word.
1754 */
1755 else
1756 echo substr($sLine, $i, $cchWord);
1757 $i += $cchWord;
1758 continue;
1759 }
1760
1761
1762 /*
1763 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
1764 */
1765 $cchWord = 1;
1766 if ($ch == '&')
1767 {
1768 if (substr($sLine, $i, 5) == "&amp;")
1769 $cchWord = 5;
1770 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
1771 $cchWord = 4;
1772 }
1773
1774 /*
1775 * Check for Symbol.
1776 */
1777 if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
1778 {
1779 echo "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
1780 $i += $cchWord;
1781 continue;
1782 }
1783
1784
1785 /*
1786 * Copy char
1787 */
1788 echo $ch;
1789 $i++;
1790 }
1791
1792 return;
1793}
1794
1795
1796/**
1797 * Calculates the lenght of the word which eventually starts at [$i].
1798 * @param $sLine Line.
1799 * @param $cchLine Line length.
1800 * @param $i Line index.
1801 * @returns Word length.
1802 */
1803function C_WordLen($sLine, $cchLine, $i)
1804{
1805
1806 /*
1807 * Check that previous letter wasen't a possible
1808 * word part.
1809 */
1810 if ($i > 0)
1811 {
1812 $ch = $sLine[$i - 1];
1813 if ( ($ch >= 'a' && $ch <= 'z')
1814 || ($ch >= 'A' && $ch <= 'Z')
1815 || ($ch >= '0' && $ch <= '9')
1816 || ($ch == '_')
1817 || ($ch == '$')
1818 )
1819 return 0;
1820 }
1821
1822 /*
1823 * Count letters in the word
1824 */
1825 $j = $i;
1826 $ch = $sLine[$i];
1827 while ($i < $cchLine &&
1828 ( ($ch >= 'a' && $ch <= 'z')
1829 || ($ch >= 'A' && $ch <= 'Z')
1830 || ($ch >= '0' && $ch <= '9')
1831 || ($ch == '_')
1832 || ($ch == '$')
1833 )
1834 )
1835 $ch = @$sLine[++$i];
1836 return $i - $j;
1837}
1838
1839
1840/*
1841 *
1842 */
1843
1844/*
1845 * ASM color encoding.
1846 */
1847$aASM_Keywords = array(
1848 "aaa" => 1,
1849 "aad" => 1,
1850 "aam" => 1,
1851 "aas" => 1,
1852 "adc" => 1,
1853 "add" => 1,
1854 "and" => 1,
1855 "arpl" => 1,
1856 "bound" => 1,
1857 "bsf" => 1,
1858 "bsr" => 1,
1859 "bswap" => 1,
1860 "bt" => 1,
1861 "btc" => 1,
1862 "btr" => 1,
1863 "bts" => 1,
1864 "call" => 1,
1865 "cbw" => 1,
1866 "cdq" => 1,
1867 "clc" => 1,
1868 "cld" => 1,
1869 "cli" => 1,
1870 "clts" => 1,
1871 "cmc" => 1,
1872 "cmp" => 1,
1873 "cmps" => 1,
1874 "cmpxchg" => 1,
1875 "cwd" => 1,
1876 "cwde" => 1,
1877 "daa" => 1,
1878 "das" => 1,
1879 "dec" => 1,
1880 "div" => 1,
1881 "enter" => 1,
1882 "hlt" => 1,
1883 "idiv" => 1,
1884 "imul" => 1,
1885 "in" => 1,
1886 "inc" => 1,
1887 "ins" => 1,
1888 "int" => 1,
1889 "into" => 1,
1890 "invd" => 1,
1891 "invlpg" => 1,
1892 "iret" => 1,
1893 "ja" => 1,
1894 "jae" => 1,
1895 "jb" => 1,
1896 "jbe" => 1,
1897 "jc" => 1,
1898 "jcxz" => 1,
1899 "jecxz" => 1,
1900 "je" => 1,
1901 "jg" => 1,
1902 "jge" => 1,
1903 "jl" => 1,
1904 "jle" => 1,
1905 "jna" => 1,
1906 "jnae" => 1,
1907 "jnb" => 1,
1908 "jnbe" => 1,
1909 "jnc" => 1,
1910 "jne" => 1,
1911 "jng" => 1,
1912 "jnge" => 1,
1913 "jnl" => 1,
1914 "jnle" => 1,
1915 "jno" => 1,
1916 "jnp" => 1,
1917 "jns" => 1,
1918 "jnz" => 1,
1919 "jo" => 1,
1920 "jp" => 1,
1921 "jpe" => 1,
1922 "jpo" => 1,
1923 "js" => 1,
1924 "jz" => 1,
1925 "jmp" => 1,
1926 "lahf" => 1,
1927 "lar" => 1,
1928 "lea" => 1,
1929 "leave" => 1,
1930 "lgdt" => 1,
1931 "lidt" => 1,
1932 "lldt" => 1,
1933 "lmsw" => 1,
1934 "lock" => 1,
1935 "lods" => 1,
1936 "loop" => 1,
1937 "loopz" => 1,
1938 "loopnz" => 1,
1939 "loope" => 1,
1940 "loopne" => 1,
1941 "lds" => 1,
1942 "les" => 1,
1943 "lfs" => 1,
1944 "lgs" => 1,
1945 "lss" => 1,
1946 "lsl" => 1,
1947 "ltr" => 1,
1948 "mov" => 1,
1949 "movs" => 1,
1950 "movsx" => 1,
1951 "movzx" => 1,
1952 "mul" => 1,
1953 "neg" => 1,
1954 "nop" => 1,
1955 "not" => 1,
1956 "or" => 1,
1957 "out" => 1,
1958 "outs" => 1,
1959 "pop" => 1,
1960 "popa" => 1,
1961 "popad" => 1,
1962 "popf" => 1,
1963 "popfd" => 1,
1964 "push" => 1,
1965 "pusha" => 1,
1966 "pushad" => 1,
1967 "pushf" => 1,
1968 "pushfd" => 1,
1969 "rcl" => 1,
1970 "rcr" => 1,
1971 "rep" => 1,
1972 "ret" => 1,
1973 "retf" => 1,
1974 "rol" => 1,
1975 "ror" => 1,
1976 "sahf" => 1,
1977 "sal" => 1,
1978 "sar" => 1,
1979 "sbb" => 1,
1980 "scas" => 1,
1981 "seta" => 1,
1982 "setae" => 1,
1983 "setb" => 1,
1984 "setbe" => 1,
1985 "setc" => 1,
1986 "sete" => 1,
1987 "setg" => 1,
1988 "setge" => 1,
1989 "setl" => 1,
1990 "setle" => 1,
1991 "setna" => 1,
1992 "setnae" => 1,
1993 "setnb" => 1,
1994 "setnbe" => 1,
1995 "setnc" => 1,
1996 "setne" => 1,
1997 "setng" => 1,
1998 "setnge" => 1,
1999 "setnl" => 1,
2000 "setnle" => 1,
2001 "setno" => 1,
2002 "setnp" => 1,
2003 "setns" => 1,
2004 "setnz" => 1,
2005 "seto" => 1,
2006 "setp" => 1,
2007 "setpe" => 1,
2008 "setpo" => 1,
2009 "sets" => 1,
2010 "setz" => 1,
2011 "sgdt" => 1,
2012 "shl" => 1,
2013 "shld" => 1,
2014 "shr" => 1,
2015 "shrd" => 1,
2016 "sidt" => 1,
2017 "sldt" => 1,
2018 "smsw" => 1,
2019 "stc" => 1,
2020 "std" => 1,
2021 "sti" => 1,
2022 "stos" => 1,
2023 "str" => 1,
2024 "sub" => 1,
2025 "test" => 1,
2026 "verr" => 1,
2027 "verw" => 1,
2028 "wait" => 1,
2029 "wbinvd" => 1,
2030 "xadd" => 1,
2031 "xchg" => 1,
2032 "xlatb" => 1,
2033 "xor" => 1,
2034 "fabs" => 1,
2035 "fadd" => 1,
2036 "fbld" => 1,
2037 "fbstp" => 1,
2038 "fchs" => 1,
2039 "fclex" => 1,
2040 "fcom" => 1,
2041 "fcos" => 1,
2042 "fdecstp" => 1,
2043 "fdiv" => 1,
2044 "fdivr" => 1,
2045 "ffree" => 1,
2046 "fiadd" => 1,
2047 "ficom" => 1,
2048 "fidiv" => 1,
2049 "fidivr" => 1,
2050 "fild" => 1,
2051 "fimul" => 1,
2052 "fincstp" => 1,
2053 "finit" => 1,
2054 "fist" => 1,
2055 "fisub" => 1,
2056 "fisubr" => 1,
2057 "fld" => 1,
2058 "fld1" => 1,
2059 "fldl2e" => 1,
2060 "fldl2t" => 1,
2061 "fldlg2" => 1,
2062 "fldln2" => 1,
2063 "fldpi" => 1,
2064 "fldz" => 1,
2065 "fldcw" => 1,
2066 "fldenv" => 1,
2067 "fmul" => 1,
2068 "fnop" => 1,
2069 "fpatan" => 1,
2070 "fprem" => 1,
2071 "fprem1" => 1,
2072 "fptan" => 1,
2073 "frndint" => 1,
2074 "frstor" => 1,
2075 "fsave" => 1,
2076 "fscale" => 1,
2077 "fsetpm" => 1,
2078 "fsin" => 1,
2079 "fsincos" => 1,
2080 "fsqrt" => 1,
2081 "fst" => 1,
2082 "fstcw" => 1,
2083 "fstenv" => 1,
2084 "fstsw" => 1,
2085 "fsub" => 1,
2086 "fsubr" => 1,
2087 "ftst" => 1,
2088 "fucom" => 1,
2089 "fwait" => 1,
2090 "fxam" => 1,
2091 "fxch" => 1,
2092 "fxtract" => 1,
2093 "fyl2x" => 1,
2094 "fyl2xp1" => 1,
2095 "f2xm1" => 1
2096 );
2097
2098$aASM_PPKeywords = array(
2099 ".align" => 1,
2100 ".alpha" => 1,
2101 "and" => 1,
2102 "assume" => 1,
2103 "byte" => 1,
2104 "code" => 1,
2105 ".code" => 1,
2106 "comm" => 1,
2107 "comment" => 1,
2108 ".const" => 1,
2109 ".cref" => 1,
2110 ".data" => 1,
2111 ".data?" => 1,
2112 "db" => 1,
2113 "dd" => 1,
2114 "df" => 1,
2115 "dosseg" => 1,
2116 "dq" => 1,
2117 "dt" => 1,
2118 "dw" => 1,
2119 "dword" => 1,
2120 "else" => 1,
2121 "end" => 1,
2122 "endif" => 1,
2123 "endm" => 1,
2124 "endp" => 1,
2125 "ends" => 1,
2126 "eq" => 1,
2127 "equ" => 1,
2128 ".err" => 1,
2129 ".err1" => 1,
2130 ".err2" => 1,
2131 ".errb" => 1,
2132 ".errdef" => 1,
2133 ".errdif" => 1,
2134 ".erre" => 1,
2135 ".erridn" => 1,
2136 ".errnb" => 1,
2137 ".errndef" => 1,
2138 ".errnz" => 1,
2139 "event" => 1,
2140 "exitm" => 1,
2141 "extrn" => 1,
2142 "far" => 1,
2143 ".fardata" => 1,
2144 ".fardata?" => 1,
2145 "fword" => 1,
2146 "ge" => 1,
2147 "group" => 1,
2148 "gt" => 1,
2149 "high" => 1,
2150 "if" => 1,
2151 "if1" => 1,
2152 "if2" => 1,
2153 "ifb" => 1,
2154 "ifdef" => 1,
2155 "ifdif" => 1,
2156 "ife" => 1,
2157 "ifidn" => 1,
2158 "ifnb" => 1,
2159 "ifndef" => 1,
2160 "include" => 1,
2161 "includelib" => 1,
2162 "irp" => 1,
2163 "irpc" => 1,
2164 "label" => 1,
2165 ".lall" => 1,
2166 "le" => 1,
2167 "length" => 1,
2168 ".lfcond" => 1,
2169 ".list" => 1,
2170 "local" => 1,
2171 "low" => 1,
2172 "lt" => 1,
2173 "macro" => 1,
2174 "mask" => 1,
2175 "mod" => 1,
2176 ".model" => 1,
2177 "name" => 1,
2178 "ne" => 1,
2179 "near" => 1,
2180 "not" => 1,
2181 "offset" => 1,
2182 "or" => 1,
2183 "org" => 1,
2184 "%out" => 1,
2185 "page" => 1,
2186 "proc" => 1,
2187 "ptr" => 1,
2188 "public" => 1,
2189 "purge" => 1,
2190 "qword" => 1,
2191 ".radix" => 1,
2192 "record" => 1,
2193 "rept" => 1,
2194 ".sall" => 1,
2195 "seg" => 1,
2196 "segment" => 1,
2197 ".seq" => 1,
2198 ".sfcond" => 1,
2199 "short" => 1,
2200 "size" => 1,
2201 ".stack" => 1,
2202 "struc" => 1,
2203 "subttl" => 1,
2204 "tbyte" => 1,
2205 ".tfcond" => 1,
2206 "this" => 1,
2207 "title" => 1,
2208 "type" => 1,
2209 ".type" => 1,
2210 "width" => 1,
2211 "word" => 1,
2212 ".xall" => 1,
2213 ".xcref" => 1,
2214 ".xlist" => 1,
2215 "xor" => 1
2216 );
2217
2218$aASM_Symbols = array(
2219 "{" => 1,
2220 "}" => 1,
2221 "!" => 1,
2222 "%" => 1,
2223 "&amp;" => 1,
2224 "*" => 1,
2225 "-" => 1,
2226 "=" => 1,
2227 "+" => 1,
2228 "&lt;" => 1,
2229 "&gt;" => 1,
2230 "/" => 1,
2231 "|" => 1,
2232 "~" => 1,
2233 "*" => 1);
2234
2235/**
2236 * Initiate the variable array used by the C Color encoder.
2237 * @param $aVaraibles Variable array. (output)
2238 */
2239function ASM_ColorInit(&$aVariables)
2240{
2241 global $aASM_Keywords;
2242 global $aASM_PPKeywords;
2243 global $aASM_Symbols;
2244
2245 ksort($aASM_Keywords);
2246 ksort($aASM_PPKeywords);
2247 ksort($aASM_Symbols);
2248}
2249
2250
2251/**
2252 * Encode a line of C code.
2253 * @param $sLine Line string to encode.
2254 * @param $aVariables Variable array.
2255 * @returns Color encoded line string.
2256 */
2257function ASM_ColorEncode($sLine, &$aVariables)
2258{
2259 global $aASM_Keywords;
2260 global $aASM_PPKeywords;
2261 global $aASM_Symbols;
2262
2263 $sRet = "";
2264 $cchLine = strlen($sLine);
2265 $i = 0;
2266 $fFirstNonBlank = 1;
2267
2268 /*
2269 * Loop thru the (remainings) of the line.
2270 */
2271 while ($i < $cchLine)
2272 {
2273 $ch = $sLine[$i];
2274
2275 /* comment check */
2276 if ($ch == ';')
2277 {
2278 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
2279 }
2280
2281 /*
2282 * Check for string.
2283 */
2284 if ((($fDbl = (substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
2285 && ($i == 0 || $sLine[$i-1] != '\\'))
2286 { /* start of a string */
2287
2288 $j = $i + 1;
2289 if ($fDbl)
2290 {
2291 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
2292 $j += ($sLine[$j] == '\\') ? 2 : 1;
2293 if ($j < $cchLine)
2294 $j += 5;
2295 }
2296 else
2297 while ($j < $cchLine && $sLine[$j] != "'")
2298 $j += ($sLine[$j] == '\\') ? 2 : 1;
2299 $j++;
2300 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
2301 $i = $j;
2302 $fFirstNonBlank = 0;
2303 continue;
2304 }
2305
2306 /*
2307 * If non-blank, lets check if we're at the start of a word...
2308 */
2309 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
2310 $cchWord = !$fBlank ? ASM_WordLen($sLine, $cchLine, $i) : 0;
2311
2312 if ($cchWord > 0)
2313 {
2314 $sWord = strtolower(substr($sLine, $i, $cchWord));
2315
2316 /*
2317 * Check for number.
2318 */
2319 if (($ch >= '0' && $ch <= '9'))
2320 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2321 else
2322 {
2323 if ($fFirstNonBlank)
2324 {
2325 /*
2326 * Check for asm keyword.
2327 */
2328 if (isset($aASM_Keywords[$sWord]))
2329 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2330 /*
2331 * Check for preprocessor directive.
2332 */
2333 else if (($f = isset($aASM_PPKeywords[$sWord]))
2334 ||
2335 ($i > 0 && $sLine[$i-1] == '.' && isset($aASM_PPKeywords[".".$sWord]))
2336 )
2337 {
2338 if ($f)
2339 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2340 else
2341 $sRet = substr($sRet, 0, -1) . "<font color=#CECECE>." . substr($sLine, $i, $cchWord) . "</font>";
2342 }
2343 /*
2344 * Skip word.
2345 */
2346 else
2347 $sRet .= substr($sLine, $i, $cchWord);
2348 }
2349 else
2350 {
2351 /*
2352 * Check for preprocessor directive.
2353 */
2354 if (($f = isset($aASM_PPKeywords[$sWord]))
2355 ||
2356 ($i > 0 && $sLine[$i-1] == '.' && isset($aASM_PPKeywords[".".$sWord]))
2357 )
2358 {
2359 if ($f)
2360 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2361 else
2362 $sRet = substr($sRet, 0, -1) . "<font color=#CECECE>." . substr($sLine, $i, $cchWord) . "</font>";
2363 }
2364 /*
2365 * Check for asm keyword.
2366 */
2367 else if (isset($aASM_Keywords[$sWord]))
2368 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2369 /*
2370 * Skip word.
2371 */
2372 else
2373 $sRet .= substr($sLine, $i, $cchWord);
2374 }
2375 }
2376
2377 $i += $cchWord;
2378 $fFirstNonBlank = 0;
2379 continue;
2380 }
2381
2382 /*
2383 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
2384 */
2385 $cchWord = 1;
2386 if ($ch == '&')
2387 {
2388 if (substr($sLine, $i, 5) == "&amp;")
2389 $cchWord = 5;
2390 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
2391 $cchWord = 4;
2392 }
2393
2394 /*
2395 * Check for Symbol.
2396 */
2397 if (isset($aASM_Symbols[substr($sLine, $i, $cchWord)]))
2398 {
2399 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2400 $i += $cchWord;
2401 $fFirstNonBlank = 0;
2402 continue;
2403 }
2404
2405
2406 /*
2407 * Copy char
2408 */
2409 $sRet .= $sLine[$i];
2410 $i++;
2411 if ($fFirstNonBlank && !$fBlank)
2412 $fFirstNonBlank = 0;
2413 }
2414
2415 return $sRet;
2416}
2417
2418/**
2419 * Calculates the lenght of the word which eventually starts at [$i].
2420 * @param $sLine Line.
2421 * @param $cchLine Line length.
2422 * @param $i Line index.
2423 * @returns Word length.
2424 */
2425function ASM_WordLen($sLine, $cchLine, $i)
2426{
2427
2428 /*
2429 * Check that previous letter wasen't a possible
2430 * word part.
2431 */
2432 if ($i > 0)
2433 {
2434 $ch = $sLine[$i - 1];
2435 if ( ($ch >= 'a' && $ch <= 'z')
2436 || ($ch >= 'A' && $ch <= 'Z')
2437 || ($ch >= '0' && $ch <= '9')
2438 || ($ch == '_')
2439 || ($ch == '@')
2440 || ($ch == '?')
2441 || ($ch == '$')
2442 )
2443 return 0;
2444 }
2445
2446 /*
2447 * Count letters in the word
2448 */
2449 $j = $i;
2450 $ch = $sLine[$i];
2451 while ($i < $cchLine &&
2452 ( ($ch >= 'a' && $ch <= 'z')
2453 || ($ch >= 'A' && $ch <= 'Z')
2454 || ($ch >= '0' && $ch <= '9')
2455 || ($ch == '_')
2456 || ($ch == '@')
2457 || ($ch == '?')
2458 || ($ch == '$')
2459 )
2460 )
2461 $ch = @$sLine[++$i];
2462 return $i - $j;
2463}
2464
2465
2466
2467/*
2468 *
2469 */
2470/* hardcoded
2471$aMake_Keywords = array(
2472 "\$&amp;" => 1,
2473 "\$**" => 1,
2474 "\$*" => 1,
2475 "\$." => 1,
2476 "\$:" => 1,
2477 "\$&lt;" => 1,
2478 "\$?" => 1,
2479 "\$@" => 1,
2480 "\$d" => 1);
2481*/
2482$aMake_Symbols = array(
2483 "@" => 1,
2484 "(" => 1,
2485 ")" => 1,
2486 "." => 1,
2487 "=" => 1,
2488 "*" => 1,
2489 "+" => 1,
2490 "-" => 1,
2491 "/" => 1,
2492 "" => 1,
2493 "[" => 1,
2494 "]" => 1,
2495 "," => 1,
2496 "&lt;" => 1,
2497 "&gt;" => 1,
2498 ":" => 1,
2499 ";" => 1);
2500/**
2501 * Initiate the variable array used by the C Color encoder.
2502 * @param $aVaraibles Variable array. (output)
2503 */
2504function Make_ColorInit(&$aVariables)
2505{
2506 //global $aMake_Keywords;
2507 global $aMake_Symbols;
2508 //$aVariables = array("fInline" => 0)
2509 //ksort($aMake_Keywords);
2510 ksort($aMake_Symbols);
2511}
2512
2513
2514/**
2515 * Encode a line of C code.
2516 * @param $sLine Line string to encode.
2517 * @param $aVariables Variable array.
2518 * @returns Color encoded line string.
2519 */
2520function Make_ColorEncode($sLine, &$aVariables)
2521{
2522 global $aMake_Keywords;
2523 global $aMake_Symbols;
2524
2525 $sRet = "";
2526 $cchLine = strlen($sLine);
2527 $i = 0;
2528 $fFirstNonBlank = 1;
2529
2530 /*
2531 * Loop thru the (remainings) of the line.
2532 */
2533 while ($i < $cchLine)
2534 {
2535 $ch = $sLine[$i];
2536
2537 /* comment check */
2538 if ($ch == '#')
2539 {
2540 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
2541 }
2542
2543
2544 /*
2545 * Check for string.
2546 */
2547 if ((($fDbl = (substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
2548 && ($i == 0 || $sLine[$i-1] != '\\'))
2549 { /* start of a string */
2550
2551 $j = $i + 1;
2552 if ($fDbl)
2553 {
2554 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
2555 $j += ($sLine[$j] == '\\') ? 2 : 1;
2556 if ($j < $cchLine)
2557 $j += 5;
2558 }
2559 else
2560 while ($j < $cchLine && $sLine[$j] != "'")
2561 $j += ($sLine[$j] == '\\') ? 2 : 1;
2562 $j++;
2563 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
2564 $i = $j;
2565 $fFirstNonBlank = 0;
2566 continue;
2567 }
2568
2569 /*
2570 * Check for ! or % words
2571 */
2572 if (($fFirstNonBlank && ($ch == "#" || $ch == "!")))
2573 {
2574 $j = $i + 1;
2575 while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == "\t"))
2576 $j++;
2577 $j += Make_WordLen($sLine, $cchLine, $j);
2578 echo "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
2579 $i = $j;
2580 $fFirstNonBlank = 0;
2581 continue;
2582 }
2583
2584 /*
2585 * Check for keyword
2586 */
2587 /* don't work
2588 if ($ch == "$" && $i + 1 < $cchLine)
2589 {
2590 $cch = 0;
2591 $sWord = substr($sLine, $i+1, 1);
2592 if ( $sWord == "*"
2593 || $sWord == "."
2594 || $sWord == ":"
2595 || $sWord == "?"
2596 || $sWord == "@"
2597 || $sWord == "d")
2598 $cch = 2;
2599 else if ($i + 2 < $cchLine && ($sWord = substr($sLine, $i+1, 2)) == "**")
2600 $cch = 3;
2601 else if ($i + 4 < $cchLine && ($sWord = substr($sLine, $i+1, 5)) == "&amp;")
2602 $cch = 6;
2603 else if ($i + 5 < $cchLine && ($sWord = substr($sLine, $i+1, 4)) == "&lt;")
2604 $cch = 5;
2605 if ($cch > 0)
2606 {
2607 echo "<font color=#CECECE>$" . $sWord . "</font>";
2608 $i += $cch;
2609 $fFirstNonBlank = 0;
2610 continue;
2611 }
2612 } */
2613
2614 /*
2615 * If non-blank, lets check if we're at the start of a word...
2616 */
2617 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
2618 $cchWord = !$fBlank ? Make_WordLen($sLine, $cchLine, $i) : 0;
2619
2620 if ($cchWord > 0)
2621 {
2622 $sWord = strtolower(substr($sLine, $i, $cchWord));
2623
2624 /*
2625 * Check for keywords.
2626 */
2627 if ($f = isset($aMake_Keywords[$sWord]))
2628 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2629
2630 /*
2631 * Check for number.
2632 */
2633 else if (($ch >= '0' && $ch <= '9'))
2634 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2635
2636 /*
2637 * Skip word.
2638 */
2639 else
2640 $sRet .= substr($sLine, $i, $cchWord);
2641
2642 $i += $cchWord;
2643 $fFirstNonBlank = 0;
2644 continue;
2645 }
2646
2647 /*
2648 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
2649 */
2650 $cchWord = 1;
2651 if ($ch == '&')
2652 {
2653 if (substr($sLine, $i, 5) == "&amp;")
2654 $cchWord = 5;
2655 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
2656 $cchWord = 4;
2657 }
2658
2659 /*
2660 * Check for Symbol.
2661 */
2662 if (isset($aMake_Symbols[substr($sLine, $i, $cchWord)]))
2663 {
2664 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2665 $i += $cchWord;
2666 $fFirstNonBlank = 0;
2667 continue;
2668 }
2669
2670
2671 /*
2672 * Copy char
2673 */
2674 $sRet .= $sLine[$i];
2675 $i++;
2676 if ($fFirstNonBlank && !$fBlank)
2677 $fFirstNonBlank = 0;
2678 }
2679
2680 return $sRet;
2681}
2682
2683/**
2684 * Calculates the lenght of the word which eventually starts at [$i].
2685 * @param $sLine Line.
2686 * @param $cchLine Line length.
2687 * @param $i Line index.
2688 * @returns Word length.
2689 */
2690function Make_WordLen($sLine, $cchLine, $i)
2691{
2692
2693 /*
2694 * Check that previous letter wasen't a possible
2695 * word part.
2696 */
2697 if ($i > 0)
2698 {
2699 $ch = $sLine[$i - 1];
2700 if ( ($ch >= 'a' && $ch <= 'z')
2701 || ($ch >= 'A' && $ch <= 'Z')
2702 || ($ch >= '0' && $ch <= '9')
2703 || ($ch == '_')
2704 )
2705 return 0;
2706 }
2707
2708 /*
2709 * Count letters in the word
2710 */
2711 $j = $i;
2712 $ch = $sLine[$i];
2713 while ($i < $cchLine &&
2714 ( ($ch >= 'a' && $ch <= 'z')
2715 || ($ch >= 'A' && $ch <= 'Z')
2716 || ($ch >= '0' && $ch <= '9')
2717 || ($ch == '_')
2718 )
2719 )
2720 $ch = @$sLine[++$i];
2721 return $i - $j;
2722}
2723
2724
2725?>
2726
Note: See TracBrowser for help on using the repository browser.