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

Last change on this file since 3968 was 3968, checked in by bird, 25 years ago

Enabled the DB pages to use the cvs pages.

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