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

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

corrected cvsroot.

File size: 73.8 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
13echo '<!-- cvsroot:'.$sCVSROOT.' -->';
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 printf('\n<!-- opendir('.$sCVSROOT.'/'.$sDir.'); -->\n');
1085 $hDir = opendir($sCVSROOT.'/'.$sDir);
1086 if (!$hDir)
1087 {
1088 echo "<!-- debug error opendir($sDir) failed -->\n";
1089 echo "<i>debug error opendir($sDir) failed</i>\n";
1090 return 5;
1091 }
1092
1093 $asFiles = array();
1094 $asSubDirs = array();
1095 while ($sEntry = readdir($hDir))
1096 {
1097 if (is_dir($sCVSROOT.'/'.$sDir.'/'.$sEntry))
1098 {
1099 if ($sEntry != '..' && $sEntry != '.')
1100 $asSubDirs[] = $sEntry;
1101 }
1102 else
1103 {
1104 $cchEntry = strlen($sEntry);
1105 if ($cchEntry > 2 && substr($sEntry, $cchEntry - 2, 2) == ',v')
1106 $asFiles[$sEntry] = $sEntry;
1107 }
1108 }
1109 closedir($hDir);
1110
1111 /*
1112 * Get CVS data.
1113 */
1114 $aExtIcons = array(
1115 "c" => "c.gif",
1116 "cpp" => "c.gif",
1117 "cxx" => "c.gif",
1118 "h" => "c.gif",
1119 "hpp" => "c.gif",
1120 "c" => "c.gif",
1121 /* these are caught by the isBinary test.
1122 "exe" => "binary.gif",
1123 "dll" => "binary.gif",
1124 "lib" => "binary.gif",
1125 "obj" => "binary.gif",
1126 "a" => "binary.gif",
1127 */
1128 "bmp" => "image1.gif",
1129 "gif" => "image1.gif",
1130 "ico" => "image1.gif",
1131 "jpg" => "image1.gif",
1132 "pal" => "image1.gif",
1133 "png" => "image1.gif",
1134 "asm" => "text.gif",
1135 "def" => "text.gif",
1136 "doc" => "text.gif",
1137 "inc" => "text.gif",
1138 "lib" => "text.gif",
1139 "mak" => "text.gif",
1140 "mk" => "text.gif",
1141 "txt" => "text.gif",
1142 "" => "text.gif",
1143 "bat" => "script.gif",
1144 "cmd" => "script.gif",
1145 "perl" => "script.gif",
1146 "sh" => "script.gif"
1147 );
1148 $cvstimer = Odin32DBTimerStart("Get CVS Data");
1149 $asRev = array();
1150 $asAge = array();
1151 $asAuthor = array();
1152 $asLog = array();
1153 $asIcon = array();
1154 for ($i = 0; list($sKey, $sFile) = each($asFiles); $i++)
1155 {
1156 $obj = new CVSFile($sDir.'/'.$sFile, 1);
1157 if ($obj->fOk)
1158 {
1159 $asRev[$sFile] = $sRev = $obj->getHead();
1160 $asDate[$sFile] = $obj->getDate($sRev);
1161 $asAuthor[$sFile] = $obj->getAuthor($sRev);
1162 $asTmpLog = $obj->getLog($sRev);
1163 for ($sLog = "", $j = sizeof($asTmpLog) - 1; $j >= 0; $j--)
1164 {
1165 if ($sLog == "")
1166 {
1167 if (trim($asTmpLog[$j]) != "")
1168 $sLog = $asTmpLog[$j];
1169 continue;
1170 }
1171 $sLog = $asTmpLog[$j]."<br>".$sLog;
1172 }
1173 $asLog[$sFile] = $sLog;
1174 $sLog = "";
1175 $asIcon[$sFile] = isset($aExtIcons[strtolower($obj->getWorkfileExt())])
1176 ? $aExtIcons[strtolower($obj->getWorkfileExt())] :
1177 ($obj->isBinary() ? "binary.gif" : "unknown.gif");
1178 }
1179 else
1180 $asLog[$sFile] = $obj->sError;
1181 }
1182 Odin32DBTimerStop($cvstimer);
1183
1184 /*
1185 * Write header
1186 */
1187 echo "<font size=-1>", CVSGetDirUrls(dirname($sDir)),
1188 ($sDir != "." ? " / ".substr($sDir, strrpos($sDir, "/") + 1) : ""),
1189 " /</font><p>\n";
1190
1191 /*
1192 * Sort the stuff.
1193 */
1194 sort($asSubDirs);
1195 switch ($iSortColumn)
1196 {
1197 case 0: $asSorted = $asFiles; break;
1198 case 1: $asSorted = $asRev; break;
1199 case 2: $asSorted = $asDate; break;
1200 case 3: $asSorted = $asAuthor; break;
1201 case 4: $asSorted = $asLog; break;
1202 default: $asSorted = $asFiles; break;
1203 }
1204 asort($asSorted);
1205
1206
1207 /*
1208 * Present data
1209 */
1210 $aColumnColors = array("#d0dce0","#d0dce0","#d0dce0","#d0dce0", "#d0dcff","#d0dce0","#d0dce0","#d0dce0","#d0dce0");
1211 echo "<table border=0 width=100% cellspacing=1 cellpadding=2>\n",
1212 " <tr>\n",
1213 " <th bgcolor=",$aColumnColors[4+0-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=0>Filename</a></b></font></th>\n",
1214 " <th bgcolor=",$aColumnColors[4+1-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=1>Rev</a></b></font></th>\n",
1215 " <th bgcolor=",$aColumnColors[4+2-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=2>Age</a></b></font></th>\n",
1216 " <th bgcolor=",$aColumnColors[4+3-$iSortColumn],"><font size=-1><b><a href=cvs.php?sDir=$sDir&iSortColumn=3>Author</a></b></font></th>\n",
1217 " <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",
1218 " </tr>\n";
1219 $i = 0;
1220 /* directories */
1221 if ($sDir != "." && $sDir != "")
1222 {
1223 if (($j = strrpos($sDir, "/")) > 0)
1224 $sParentDir = substr($sDir, 0, $j);
1225 else
1226 $sParentDir = ".";
1227 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1228 echo "<tr>\n",
1229 " <td", $sBgColor , ">",
1230 "<font size=-1><a href=\"cvs.php?sDir=",$sParentDir,"\"><img src=\"$sIconsUrl/back.gif\" border=0> Parent Directory</a></font></td>\n",
1231 " <td$sBgColor>&nbsp;</td>\n",
1232 " <td$sBgColor>&nbsp;</td>\n",
1233 " <td$sBgColor>&nbsp;</td>\n",
1234 " <td$sBgColor>&nbsp;</td>\n",
1235 "</tr>\n";
1236 }
1237 while (list($sKey, $sVal) = each($asSubDirs))
1238 {
1239 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1240 echo "<tr>\n",
1241 " <td$sBgColor><font size=-1><a href=\"cvs.php?sDir=$sDir/$sVal\"><img src=\"$sIconsUrl/dir.gif\" border=0> $sVal</a></font></td>\n",
1242 " <td$sBgColor>&nbsp;</td>\n",
1243 " <td$sBgColor>&nbsp;</td>\n",
1244 " <td$sBgColor>&nbsp;</td>\n",
1245 " <td$sBgColor>&nbsp;</td>\n",
1246 "</tr>\n";
1247 }
1248
1249 /* files */
1250 while (list($sKey, $sVal) = each($asSorted))
1251 {
1252 $sBgColor = ($i++ % 2) ? "" : " bgcolor=#f0f0f0";
1253 $sRev = isset($asRev[$sKey]) ? $asRev[$sKey] : "<i> error </i>";
1254 $sAge = isset($asDate[$sKey]) ? CVSGetAge($asDate[$sKey], 1) : "<i> error </i>";
1255 $sAuthor= isset($asAuthor[$sKey])?$asAuthor[$sKey] : "<i> error </i>";
1256 $sLog = isset($asLog[$sKey]) ? $asLog[$sKey] : "<i> error </i>";
1257 $sIcon = isset($asIcon[$sKey]) ? $asIcon[$sKey] : "<i> error </i>";
1258 echo "<tr>\n",
1259 " <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",
1260 " <td$sBgColor><font size=-1><a href=\"cvs.php?sFile=$sDir/$sKey&sRevision=$sRev\">$sRev</a></font></td>\n",
1261 " <td$sBgColor><font size=-1>$sAge</font></td>\n",
1262 " <td$sBgColor><font size=-1>$sAuthor</font></td>\n",
1263 " <td$sBgColor><font size=-2>$sLog</font></td>\n",
1264 "</tr>\n";
1265 }
1266
1267 echo "</table>\n";
1268 Odin32DBTimerStop($timer);
1269
1270
1271 /*
1272 * Debug dump.
1273 *//*
1274 while (list ($sKey, $sVal) = each ($asSubDirs))
1275 echo "Dir: $sVal<br>\n";
1276 while (list ($sKey, $sVal) = each ($asFiles))
1277 echo "File: $sVal<br>\n";
1278 */
1279}
1280
1281
1282/**
1283 * Copies the first word.
1284 * A words is: [a-zA-Z0-9_.]
1285 *
1286 * tested ok
1287 * @returns Returns the word at the start of $s.
1288 */
1289function CopyWord($s)
1290{
1291 $cch = strlen($s);
1292 for ($i = 0; $i < $cch; $i++)
1293 {
1294 $c = $s[$i];
1295 if (!($c >= 'a' && $c <= 'z')
1296 &&
1297 !($c >= 'A' && $c <= 'Z')
1298 &&
1299 !($c >= '0' && $c <= '9')
1300 &&
1301 !($c == '.' || $c == '_')
1302 )
1303 break;
1304 }
1305 return substr($s, 0, $i);
1306}
1307
1308
1309/**
1310 * Skips the first word.
1311 * A words is: [a-zA-Z0-9_.]
1312 *
1313 * tested ok
1314 * @returns $s - first word.
1315 */
1316function SkipWord($s)
1317{
1318 $cch = strlen($s);
1319 for ($i = 0; $i < $cch; $i++)
1320 {
1321 $c = $s[$i];
1322 if (!($c >= 'a' && $c <= 'z')
1323 &&
1324 !($c >= 'A' && $c <= 'Z')
1325 &&
1326 !($c >= '0' && $c <= '9')
1327 &&
1328 !($c == '.' || $c == '_')
1329 )
1330 break;
1331 }
1332 return substr($s, $i);
1333}
1334
1335
1336
1337
1338/*
1339 * C color encoding.
1340 */
1341$aC_Keywords = array(
1342// "auto" => 1,
1343 "break" => 1,
1344 "case" => 1,
1345 "char" => 1,
1346 "const" => 1,
1347 "continue" => 1,
1348 "default" => 1,
1349// "defined" => 1,
1350 "do" => 1,
1351 "double" => 1,
1352 "else" => 1,
1353 "enum" => 1,
1354 "extern" => 1,
1355 "float" => 1,
1356 "for" => 1,
1357 "goto" => 1,
1358 "if" => 1,
1359 "int" => 1,
1360 "long" => 1,
1361 "register" => 1,
1362 "return" => 1,
1363 "short" => 1,
1364 "sizeof" => 1,
1365 "static" => 1,
1366 "struct" => 1,
1367 "switch" => 1,
1368 "typedef" => 1,
1369 "union" => 1,
1370 "unsigned" => 1,
1371 "void" => 1,
1372 "while" => 1,
1373 "class" => 1,
1374 "delete" => 1,
1375// "finally" => 1,
1376 "friend" => 1,
1377 "inline" => 1,
1378 "new" => 1,
1379 "operator" => 1,
1380 "overload" => 1,
1381 "private" => 1,
1382 "protected" => 1,
1383 "public" => 1,
1384 "this" => 1,
1385 "virtual" => 1,
1386// "bool" => 1,
1387// "true" => 1,
1388// "false" => 1,
1389 "explicit" => 1,
1390 "mutable" => 1,
1391 "typename" => 1,
1392// "static_cast" => 1,
1393// "const_cast" => 1,
1394// "reinterpret_cast" => 1,
1395// "dynamic_cast" => 1,
1396// "using" => 1,
1397 "typeid" => 1,
1398// "asm" => 1,
1399 "catch" => 1,
1400 "signed" => 1,
1401 "template" => 1,
1402 "throw" => 1,
1403 "try" => 1,
1404// "namespace" => 1,
1405 "volatile" => 1
1406
1407 );
1408
1409$aC_Symbols = array(
1410 "{" => 1,
1411 "}" => 1,
1412// "[" => 1,
1413// "]" => 1,
1414// "(" => 1,
1415// ")" => 1,
1416// "." => 1,
1417// "," => 1,
1418 "!" => 1,
1419 "%" => 1,
1420// "&" => 1,
1421 "&amp;" => 1,
1422 "*" => 1,
1423 "-" => 1,
1424 "=" => 1,
1425 "+" => 1,
1426 ":" => 1,
1427 ";" => 1,
1428// "<" => 1,
1429 "&lt;" => 1,
1430// ">" => 1,
1431 "&gt;" => 1,
1432 "?" => 1,
1433 "/" => 1,
1434 "|" => 1,
1435 "~" => 1,
1436 "^" => 1,
1437 "*" => 1);
1438
1439/**
1440 * Initiate the variable array used by the C Color encoder.
1441 * @param $aVaraibles Variable array. (output)
1442 */
1443function C_ColorInit(&$aVariables)
1444{
1445 global $aC_Keywords;
1446 global $aC_Symbols;
1447
1448 $aVariables["fComment"] = 0;
1449
1450 ksort($aC_Keywords);
1451 ksort($aC_Symbols);
1452}
1453
1454
1455/**
1456 * Encode a line of C code.
1457 * @param $sLine Line string to encode.
1458 * @param $aVariables Variable array.
1459 * @returns Color encoded line string.
1460 */
1461function C_ColorEncode($sLine, &$aVariables)
1462{
1463 global $aC_Keywords;
1464 global $aC_Symbols;
1465
1466 $sRet = "";
1467 $cchLine = strlen($sLine);
1468
1469 /*
1470 * If mulitline comment we'll only check if it ends at this line.
1471 * if it doesn't we'll do nothing.
1472 * if it does we'll skip to then end of it.
1473 */
1474 if ($aVariables["fComment"])
1475 {
1476 if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
1477 return $sLine;
1478 $i += 2;
1479 $sRet = substr($sLine, 0, $i)."</font>";
1480 $aVariables["fComment"] = 0;
1481 }
1482 else
1483 $i = 0;
1484
1485 /*
1486 * Loop thru the (remainings) of the line.
1487 */
1488 $fFirstNonBlank = 1;
1489 while ($i < $cchLine)
1490 {
1491 $ch = $sLine[$i];
1492 /* comment check */
1493 if ($i+1 < $cchLine && $ch == '/')
1494 {
1495 if ($sLine[$i+1] == '/')
1496 { /* one-line comment */
1497 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
1498 }
1499
1500 if ($sLine[$i+1] == '*')
1501 { /* Start of multiline comment */
1502 if ($j = strpos($sLine, "*/", $i + 2))
1503 {
1504 $sRet .= "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
1505 $i = $j + 2;
1506 }
1507 else
1508 {
1509 $aVariables["fComment"] = 1;
1510 return $sRet . "<font color=#02FE02>" . substr($sLine, $i);
1511 }
1512 continue;
1513 }
1514 }
1515
1516 /*
1517 * Check for string.
1518 */
1519 if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
1520 && ($i == 0 || $sLine[$i-1] != '\\'))
1521 { /* start of a string */
1522 $j = $i + 1;
1523 if ($fDbl)
1524 {
1525 /* if ($sLine[$i] == '"')
1526 while ($j < $cchLine && $sLine[$j] != '"')
1527 $j += ($sLine[$j] == '\\') ? 2 : 1;
1528 else */
1529 {
1530 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
1531 $j += ($sLine[$j] == '\\') ? 2 : 1;
1532 if ($j < $cchLine)
1533 $j += 5;
1534 }
1535 }
1536 else
1537 while ($j < $cchLine && $sLine[$j] != "'")
1538 $j += ($sLine[$j] == '\\') ? 2 : 1;
1539 $j++;
1540 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
1541 $i = $j;
1542 continue;
1543 }
1544
1545 /*
1546 * Check for preprocessor directive.
1547 */
1548 if ($fFirstNonBlank && $ch == "#")
1549 {
1550 $j = $i + 1;
1551 while ($j < $cchLine && ($sLine[$j] == " " || $sLine[$j] == "\t"))
1552 $j++;
1553 $j += C_WordLen($sLine, $cchLine, $j);
1554 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
1555 $i = $j;
1556 $fFirstNonBlank = 0;
1557 continue;
1558 }
1559
1560 /*
1561 * If non-blank, lets check if we're at the start of a word...
1562 */
1563 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
1564 if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
1565 $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
1566
1567 if ($cchWord > 0)
1568 {
1569 /*
1570 * Check for keyword or number.
1571 */
1572 if (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9'))
1573 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
1574
1575 /*
1576 * Skip word.
1577 */
1578 else
1579 $sRet .= substr($sLine, $i, $cchWord);
1580 $i += $cchWord;
1581 continue;
1582 }
1583
1584
1585 /*
1586 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
1587 */
1588 $cchWord = 1;
1589 if ($ch == '&')
1590 {
1591 /*
1592 while ($cchWord < 8 && $sLine[$i+$cchWord] != ';' &&
1593 ( ($sLine[$i+$cchWord] >= 'a' && $sLine[$i+$cchWord] <= 'z')
1594 || ($sLine[$i+$cchWord] >= 'A' && $sLine[$i+$cchWord] <= 'Z')
1595 )
1596 )
1597 $cchWord++;
1598
1599 if ($sLine[$i + $cchWord++] != ';')
1600 $cchWord = 1;
1601 */
1602 if (substr($sLine, $i, 5) == "&amp;")
1603 $cchWord = 5;
1604 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
1605 $cchWord = 4;
1606 }
1607
1608 /*
1609 * Check for Symbol.
1610 */
1611 if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
1612 {
1613 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
1614 $i += $cchWord;
1615 continue;
1616 }
1617
1618
1619 /*
1620 * Copy char
1621 */
1622 $sRet .= $sLine[$i];
1623 $i++;
1624 }
1625
1626 return $sRet;
1627}
1628
1629
1630/**
1631 * Encode a line of C code.
1632 * @param $sLine Line string to encode.
1633 * @param $aVariables Variable array.
1634 * @returns Color encoded line string.
1635 */
1636function C_ColorEncode2($sLine, &$aVariables)
1637{
1638 global $aC_Keywords;
1639 global $aC_Symbols;
1640
1641 $cchLine = strlen($sLine);
1642
1643 /*
1644 * If mulitline comment we'll only check if it ends at this line.
1645 * if it doesn't we'll do nothing.
1646 * if it does we'll skip to then end of it.
1647 */
1648 if ($aVariables["fComment"])
1649 {
1650 if (!(($i = strpos($sLine, "*/")) || ($cchLine >= 2 && $sLine[0] == '*' && $sLine[1] == '/')))
1651 {
1652 echo $sLine;
1653 return;
1654 }
1655 $i += 2;
1656 echo substr($sLine, 0, $i)."</font>";
1657 $aVariables["fComment"] = 0;
1658 }
1659 else
1660 $i = 0;
1661
1662 /*
1663 * Loop thru the (remainings) of the line.
1664 */
1665 $fFirstNonBlank = 1;
1666 while ($i < $cchLine)
1667 {
1668 $ch = $sLine[$i];
1669 /* comment check */
1670 if ($i+1 < $cchLine && $ch == '/')
1671 {
1672 if ($sLine[$i+1] == '/')
1673 { /* one-line comment */
1674 echo "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
1675 return;
1676 }
1677
1678 if ($sLine[$i+1] == '*')
1679 { /* Start of multiline comment */
1680 if ($j = strpos($sLine, "*/", $i + 2))
1681 {
1682 echo "<font color=#02FE02>" . substr($sLine, $i, $j+2 - $i) . "</font>";
1683 $i = $j + 2;
1684 }
1685 else
1686 {
1687 $aVariables["fComment"] = 1;
1688 echo "<font color=#02FE02>" . substr($sLine, $i);
1689 return;
1690 }
1691 continue;
1692 }
1693 }
1694
1695 /*
1696 * Check for string.
1697 */
1698 if ((($fDbl = (/*$sLine[$i] == '"' ||*/ substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
1699 && ($i == 0 || $sLine[$i-1] != '\\'))
1700 { /* start of a string */
1701 $j = $i + 1;
1702 if ($fDbl)
1703 {
1704 /* if ($sLine[$i] == '"')
1705 while ($j < $cchLine && $sLine[$j] != '"')
1706 $j += ($sLine[$j] == '\\') ? 2 : 1;
1707 else */
1708 {
1709 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
1710 $j += ($sLine[$j] == '\\') ? 2 : 1;
1711 if ($j < $cchLine)
1712 $j += 5;
1713 }
1714 }
1715 else
1716 while ($j < $cchLine && $sLine[$j] != "'")
1717 $j += ($sLine[$j] == '\\') ? 2 : 1;
1718 $j++;
1719 echo "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
1720 $i = $j;
1721 continue;
1722 }
1723
1724 /*
1725 * Check for preprocessor directive.
1726 */
1727 if ($fFirstNonBlank && $ch == "#")
1728 {
1729 $j = $i + 1;
1730 while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == "\t"))
1731 $j++;
1732 $j += C_WordLen($sLine, $cchLine, $j);
1733 echo "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
1734 $i = $j;
1735 $fFirstNonBlank = 0;
1736 continue;
1737 }
1738
1739 /*
1740 * If non-blank, lets check if we're at the start of a word...
1741 */
1742 $fBlank = ($ch == ' ' || $ch == "\t"); //TODO more "blanks"?
1743 if ($fFirstNonBlank) $fFirstNonBlank = $fBlank;
1744 $cchWord = !$fBlank ? C_WordLen($sLine, $cchLine, $i) : 0;
1745
1746 if ($cchWord > 0)
1747 {
1748 /*
1749 * Check for keyword or number.
1750 */
1751 if (isset($aC_Keywords[substr($sLine, $i, $cchWord)]) || ($ch >= '0' && $ch <= '9'))
1752 echo "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
1753
1754 /*
1755 * Skip word.
1756 */
1757 else
1758 echo substr($sLine, $i, $cchWord);
1759 $i += $cchWord;
1760 continue;
1761 }
1762
1763
1764 /*
1765 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
1766 */
1767 $cchWord = 1;
1768 if ($ch == '&')
1769 {
1770 if (substr($sLine, $i, 5) == "&amp;")
1771 $cchWord = 5;
1772 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
1773 $cchWord = 4;
1774 }
1775
1776 /*
1777 * Check for Symbol.
1778 */
1779 if (isset($aC_Symbols[substr($sLine, $i, $cchWord)]))
1780 {
1781 echo "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
1782 $i += $cchWord;
1783 continue;
1784 }
1785
1786
1787 /*
1788 * Copy char
1789 */
1790 echo $ch;
1791 $i++;
1792 }
1793
1794 return;
1795}
1796
1797
1798/**
1799 * Calculates the lenght of the word which eventually starts at [$i].
1800 * @param $sLine Line.
1801 * @param $cchLine Line length.
1802 * @param $i Line index.
1803 * @returns Word length.
1804 */
1805function C_WordLen($sLine, $cchLine, $i)
1806{
1807
1808 /*
1809 * Check that previous letter wasen't a possible
1810 * word part.
1811 */
1812 if ($i > 0)
1813 {
1814 $ch = $sLine[$i - 1];
1815 if ( ($ch >= 'a' && $ch <= 'z')
1816 || ($ch >= 'A' && $ch <= 'Z')
1817 || ($ch >= '0' && $ch <= '9')
1818 || ($ch == '_')
1819 || ($ch == '$')
1820 )
1821 return 0;
1822 }
1823
1824 /*
1825 * Count letters in the word
1826 */
1827 $j = $i;
1828 $ch = $sLine[$i];
1829 while ($i < $cchLine &&
1830 ( ($ch >= 'a' && $ch <= 'z')
1831 || ($ch >= 'A' && $ch <= 'Z')
1832 || ($ch >= '0' && $ch <= '9')
1833 || ($ch == '_')
1834 || ($ch == '$')
1835 )
1836 )
1837 $ch = @$sLine[++$i];
1838 return $i - $j;
1839}
1840
1841
1842/*
1843 *
1844 */
1845
1846/*
1847 * ASM color encoding.
1848 */
1849$aASM_Keywords = array(
1850 "aaa" => 1,
1851 "aad" => 1,
1852 "aam" => 1,
1853 "aas" => 1,
1854 "adc" => 1,
1855 "add" => 1,
1856 "and" => 1,
1857 "arpl" => 1,
1858 "bound" => 1,
1859 "bsf" => 1,
1860 "bsr" => 1,
1861 "bswap" => 1,
1862 "bt" => 1,
1863 "btc" => 1,
1864 "btr" => 1,
1865 "bts" => 1,
1866 "call" => 1,
1867 "cbw" => 1,
1868 "cdq" => 1,
1869 "clc" => 1,
1870 "cld" => 1,
1871 "cli" => 1,
1872 "clts" => 1,
1873 "cmc" => 1,
1874 "cmp" => 1,
1875 "cmps" => 1,
1876 "cmpxchg" => 1,
1877 "cwd" => 1,
1878 "cwde" => 1,
1879 "daa" => 1,
1880 "das" => 1,
1881 "dec" => 1,
1882 "div" => 1,
1883 "enter" => 1,
1884 "hlt" => 1,
1885 "idiv" => 1,
1886 "imul" => 1,
1887 "in" => 1,
1888 "inc" => 1,
1889 "ins" => 1,
1890 "int" => 1,
1891 "into" => 1,
1892 "invd" => 1,
1893 "invlpg" => 1,
1894 "iret" => 1,
1895 "ja" => 1,
1896 "jae" => 1,
1897 "jb" => 1,
1898 "jbe" => 1,
1899 "jc" => 1,
1900 "jcxz" => 1,
1901 "jecxz" => 1,
1902 "je" => 1,
1903 "jg" => 1,
1904 "jge" => 1,
1905 "jl" => 1,
1906 "jle" => 1,
1907 "jna" => 1,
1908 "jnae" => 1,
1909 "jnb" => 1,
1910 "jnbe" => 1,
1911 "jnc" => 1,
1912 "jne" => 1,
1913 "jng" => 1,
1914 "jnge" => 1,
1915 "jnl" => 1,
1916 "jnle" => 1,
1917 "jno" => 1,
1918 "jnp" => 1,
1919 "jns" => 1,
1920 "jnz" => 1,
1921 "jo" => 1,
1922 "jp" => 1,
1923 "jpe" => 1,
1924 "jpo" => 1,
1925 "js" => 1,
1926 "jz" => 1,
1927 "jmp" => 1,
1928 "lahf" => 1,
1929 "lar" => 1,
1930 "lea" => 1,
1931 "leave" => 1,
1932 "lgdt" => 1,
1933 "lidt" => 1,
1934 "lldt" => 1,
1935 "lmsw" => 1,
1936 "lock" => 1,
1937 "lods" => 1,
1938 "loop" => 1,
1939 "loopz" => 1,
1940 "loopnz" => 1,
1941 "loope" => 1,
1942 "loopne" => 1,
1943 "lds" => 1,
1944 "les" => 1,
1945 "lfs" => 1,
1946 "lgs" => 1,
1947 "lss" => 1,
1948 "lsl" => 1,
1949 "ltr" => 1,
1950 "mov" => 1,
1951 "movs" => 1,
1952 "movsx" => 1,
1953 "movzx" => 1,
1954 "mul" => 1,
1955 "neg" => 1,
1956 "nop" => 1,
1957 "not" => 1,
1958 "or" => 1,
1959 "out" => 1,
1960 "outs" => 1,
1961 "pop" => 1,
1962 "popa" => 1,
1963 "popad" => 1,
1964 "popf" => 1,
1965 "popfd" => 1,
1966 "push" => 1,
1967 "pusha" => 1,
1968 "pushad" => 1,
1969 "pushf" => 1,
1970 "pushfd" => 1,
1971 "rcl" => 1,
1972 "rcr" => 1,
1973 "rep" => 1,
1974 "ret" => 1,
1975 "retf" => 1,
1976 "rol" => 1,
1977 "ror" => 1,
1978 "sahf" => 1,
1979 "sal" => 1,
1980 "sar" => 1,
1981 "sbb" => 1,
1982 "scas" => 1,
1983 "seta" => 1,
1984 "setae" => 1,
1985 "setb" => 1,
1986 "setbe" => 1,
1987 "setc" => 1,
1988 "sete" => 1,
1989 "setg" => 1,
1990 "setge" => 1,
1991 "setl" => 1,
1992 "setle" => 1,
1993 "setna" => 1,
1994 "setnae" => 1,
1995 "setnb" => 1,
1996 "setnbe" => 1,
1997 "setnc" => 1,
1998 "setne" => 1,
1999 "setng" => 1,
2000 "setnge" => 1,
2001 "setnl" => 1,
2002 "setnle" => 1,
2003 "setno" => 1,
2004 "setnp" => 1,
2005 "setns" => 1,
2006 "setnz" => 1,
2007 "seto" => 1,
2008 "setp" => 1,
2009 "setpe" => 1,
2010 "setpo" => 1,
2011 "sets" => 1,
2012 "setz" => 1,
2013 "sgdt" => 1,
2014 "shl" => 1,
2015 "shld" => 1,
2016 "shr" => 1,
2017 "shrd" => 1,
2018 "sidt" => 1,
2019 "sldt" => 1,
2020 "smsw" => 1,
2021 "stc" => 1,
2022 "std" => 1,
2023 "sti" => 1,
2024 "stos" => 1,
2025 "str" => 1,
2026 "sub" => 1,
2027 "test" => 1,
2028 "verr" => 1,
2029 "verw" => 1,
2030 "wait" => 1,
2031 "wbinvd" => 1,
2032 "xadd" => 1,
2033 "xchg" => 1,
2034 "xlatb" => 1,
2035 "xor" => 1,
2036 "fabs" => 1,
2037 "fadd" => 1,
2038 "fbld" => 1,
2039 "fbstp" => 1,
2040 "fchs" => 1,
2041 "fclex" => 1,
2042 "fcom" => 1,
2043 "fcos" => 1,
2044 "fdecstp" => 1,
2045 "fdiv" => 1,
2046 "fdivr" => 1,
2047 "ffree" => 1,
2048 "fiadd" => 1,
2049 "ficom" => 1,
2050 "fidiv" => 1,
2051 "fidivr" => 1,
2052 "fild" => 1,
2053 "fimul" => 1,
2054 "fincstp" => 1,
2055 "finit" => 1,
2056 "fist" => 1,
2057 "fisub" => 1,
2058 "fisubr" => 1,
2059 "fld" => 1,
2060 "fld1" => 1,
2061 "fldl2e" => 1,
2062 "fldl2t" => 1,
2063 "fldlg2" => 1,
2064 "fldln2" => 1,
2065 "fldpi" => 1,
2066 "fldz" => 1,
2067 "fldcw" => 1,
2068 "fldenv" => 1,
2069 "fmul" => 1,
2070 "fnop" => 1,
2071 "fpatan" => 1,
2072 "fprem" => 1,
2073 "fprem1" => 1,
2074 "fptan" => 1,
2075 "frndint" => 1,
2076 "frstor" => 1,
2077 "fsave" => 1,
2078 "fscale" => 1,
2079 "fsetpm" => 1,
2080 "fsin" => 1,
2081 "fsincos" => 1,
2082 "fsqrt" => 1,
2083 "fst" => 1,
2084 "fstcw" => 1,
2085 "fstenv" => 1,
2086 "fstsw" => 1,
2087 "fsub" => 1,
2088 "fsubr" => 1,
2089 "ftst" => 1,
2090 "fucom" => 1,
2091 "fwait" => 1,
2092 "fxam" => 1,
2093 "fxch" => 1,
2094 "fxtract" => 1,
2095 "fyl2x" => 1,
2096 "fyl2xp1" => 1,
2097 "f2xm1" => 1
2098 );
2099
2100$aASM_PPKeywords = array(
2101 ".align" => 1,
2102 ".alpha" => 1,
2103 "and" => 1,
2104 "assume" => 1,
2105 "byte" => 1,
2106 "code" => 1,
2107 ".code" => 1,
2108 "comm" => 1,
2109 "comment" => 1,
2110 ".const" => 1,
2111 ".cref" => 1,
2112 ".data" => 1,
2113 ".data?" => 1,
2114 "db" => 1,
2115 "dd" => 1,
2116 "df" => 1,
2117 "dosseg" => 1,
2118 "dq" => 1,
2119 "dt" => 1,
2120 "dw" => 1,
2121 "dword" => 1,
2122 "else" => 1,
2123 "end" => 1,
2124 "endif" => 1,
2125 "endm" => 1,
2126 "endp" => 1,
2127 "ends" => 1,
2128 "eq" => 1,
2129 "equ" => 1,
2130 ".err" => 1,
2131 ".err1" => 1,
2132 ".err2" => 1,
2133 ".errb" => 1,
2134 ".errdef" => 1,
2135 ".errdif" => 1,
2136 ".erre" => 1,
2137 ".erridn" => 1,
2138 ".errnb" => 1,
2139 ".errndef" => 1,
2140 ".errnz" => 1,
2141 "event" => 1,
2142 "exitm" => 1,
2143 "extrn" => 1,
2144 "far" => 1,
2145 ".fardata" => 1,
2146 ".fardata?" => 1,
2147 "fword" => 1,
2148 "ge" => 1,
2149 "group" => 1,
2150 "gt" => 1,
2151 "high" => 1,
2152 "if" => 1,
2153 "if1" => 1,
2154 "if2" => 1,
2155 "ifb" => 1,
2156 "ifdef" => 1,
2157 "ifdif" => 1,
2158 "ife" => 1,
2159 "ifidn" => 1,
2160 "ifnb" => 1,
2161 "ifndef" => 1,
2162 "include" => 1,
2163 "includelib" => 1,
2164 "irp" => 1,
2165 "irpc" => 1,
2166 "label" => 1,
2167 ".lall" => 1,
2168 "le" => 1,
2169 "length" => 1,
2170 ".lfcond" => 1,
2171 ".list" => 1,
2172 "local" => 1,
2173 "low" => 1,
2174 "lt" => 1,
2175 "macro" => 1,
2176 "mask" => 1,
2177 "mod" => 1,
2178 ".model" => 1,
2179 "name" => 1,
2180 "ne" => 1,
2181 "near" => 1,
2182 "not" => 1,
2183 "offset" => 1,
2184 "or" => 1,
2185 "org" => 1,
2186 "%out" => 1,
2187 "page" => 1,
2188 "proc" => 1,
2189 "ptr" => 1,
2190 "public" => 1,
2191 "purge" => 1,
2192 "qword" => 1,
2193 ".radix" => 1,
2194 "record" => 1,
2195 "rept" => 1,
2196 ".sall" => 1,
2197 "seg" => 1,
2198 "segment" => 1,
2199 ".seq" => 1,
2200 ".sfcond" => 1,
2201 "short" => 1,
2202 "size" => 1,
2203 ".stack" => 1,
2204 "struc" => 1,
2205 "subttl" => 1,
2206 "tbyte" => 1,
2207 ".tfcond" => 1,
2208 "this" => 1,
2209 "title" => 1,
2210 "type" => 1,
2211 ".type" => 1,
2212 "width" => 1,
2213 "word" => 1,
2214 ".xall" => 1,
2215 ".xcref" => 1,
2216 ".xlist" => 1,
2217 "xor" => 1
2218 );
2219
2220$aASM_Symbols = array(
2221 "{" => 1,
2222 "}" => 1,
2223 "!" => 1,
2224 "%" => 1,
2225 "&amp;" => 1,
2226 "*" => 1,
2227 "-" => 1,
2228 "=" => 1,
2229 "+" => 1,
2230 "&lt;" => 1,
2231 "&gt;" => 1,
2232 "/" => 1,
2233 "|" => 1,
2234 "~" => 1,
2235 "*" => 1);
2236
2237/**
2238 * Initiate the variable array used by the C Color encoder.
2239 * @param $aVaraibles Variable array. (output)
2240 */
2241function ASM_ColorInit(&$aVariables)
2242{
2243 global $aASM_Keywords;
2244 global $aASM_PPKeywords;
2245 global $aASM_Symbols;
2246
2247 ksort($aASM_Keywords);
2248 ksort($aASM_PPKeywords);
2249 ksort($aASM_Symbols);
2250}
2251
2252
2253/**
2254 * Encode a line of C code.
2255 * @param $sLine Line string to encode.
2256 * @param $aVariables Variable array.
2257 * @returns Color encoded line string.
2258 */
2259function ASM_ColorEncode($sLine, &$aVariables)
2260{
2261 global $aASM_Keywords;
2262 global $aASM_PPKeywords;
2263 global $aASM_Symbols;
2264
2265 $sRet = "";
2266 $cchLine = strlen($sLine);
2267 $i = 0;
2268 $fFirstNonBlank = 1;
2269
2270 /*
2271 * Loop thru the (remainings) of the line.
2272 */
2273 while ($i < $cchLine)
2274 {
2275 $ch = $sLine[$i];
2276
2277 /* comment check */
2278 if ($ch == ';')
2279 {
2280 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
2281 }
2282
2283 /*
2284 * Check for string.
2285 */
2286 if ((($fDbl = (substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
2287 && ($i == 0 || $sLine[$i-1] != '\\'))
2288 { /* start of a string */
2289
2290 $j = $i + 1;
2291 if ($fDbl)
2292 {
2293 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
2294 $j += ($sLine[$j] == '\\') ? 2 : 1;
2295 if ($j < $cchLine)
2296 $j += 5;
2297 }
2298 else
2299 while ($j < $cchLine && $sLine[$j] != "'")
2300 $j += ($sLine[$j] == '\\') ? 2 : 1;
2301 $j++;
2302 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
2303 $i = $j;
2304 $fFirstNonBlank = 0;
2305 continue;
2306 }
2307
2308 /*
2309 * If non-blank, lets check if we're at the start of a word...
2310 */
2311 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
2312 $cchWord = !$fBlank ? ASM_WordLen($sLine, $cchLine, $i) : 0;
2313
2314 if ($cchWord > 0)
2315 {
2316 $sWord = strtolower(substr($sLine, $i, $cchWord));
2317
2318 /*
2319 * Check for number.
2320 */
2321 if (($ch >= '0' && $ch <= '9'))
2322 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2323 else
2324 {
2325 if ($fFirstNonBlank)
2326 {
2327 /*
2328 * Check for asm keyword.
2329 */
2330 if (isset($aASM_Keywords[$sWord]))
2331 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2332 /*
2333 * Check for preprocessor directive.
2334 */
2335 else if (($f = isset($aASM_PPKeywords[$sWord]))
2336 ||
2337 ($i > 0 && $sLine[$i-1] == '.' && isset($aASM_PPKeywords[".".$sWord]))
2338 )
2339 {
2340 if ($f)
2341 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2342 else
2343 $sRet = substr($sRet, 0, -1) . "<font color=#CECECE>." . substr($sLine, $i, $cchWord) . "</font>";
2344 }
2345 /*
2346 * Skip word.
2347 */
2348 else
2349 $sRet .= substr($sLine, $i, $cchWord);
2350 }
2351 else
2352 {
2353 /*
2354 * Check for preprocessor directive.
2355 */
2356 if (($f = isset($aASM_PPKeywords[$sWord]))
2357 ||
2358 ($i > 0 && $sLine[$i-1] == '.' && isset($aASM_PPKeywords[".".$sWord]))
2359 )
2360 {
2361 if ($f)
2362 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2363 else
2364 $sRet = substr($sRet, 0, -1) . "<font color=#CECECE>." . substr($sLine, $i, $cchWord) . "</font>";
2365 }
2366 /*
2367 * Check for asm keyword.
2368 */
2369 else if (isset($aASM_Keywords[$sWord]))
2370 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2371 /*
2372 * Skip word.
2373 */
2374 else
2375 $sRet .= substr($sLine, $i, $cchWord);
2376 }
2377 }
2378
2379 $i += $cchWord;
2380 $fFirstNonBlank = 0;
2381 continue;
2382 }
2383
2384 /*
2385 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
2386 */
2387 $cchWord = 1;
2388 if ($ch == '&')
2389 {
2390 if (substr($sLine, $i, 5) == "&amp;")
2391 $cchWord = 5;
2392 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
2393 $cchWord = 4;
2394 }
2395
2396 /*
2397 * Check for Symbol.
2398 */
2399 if (isset($aASM_Symbols[substr($sLine, $i, $cchWord)]))
2400 {
2401 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2402 $i += $cchWord;
2403 $fFirstNonBlank = 0;
2404 continue;
2405 }
2406
2407
2408 /*
2409 * Copy char
2410 */
2411 $sRet .= $sLine[$i];
2412 $i++;
2413 if ($fFirstNonBlank && !$fBlank)
2414 $fFirstNonBlank = 0;
2415 }
2416
2417 return $sRet;
2418}
2419
2420/**
2421 * Calculates the lenght of the word which eventually starts at [$i].
2422 * @param $sLine Line.
2423 * @param $cchLine Line length.
2424 * @param $i Line index.
2425 * @returns Word length.
2426 */
2427function ASM_WordLen($sLine, $cchLine, $i)
2428{
2429
2430 /*
2431 * Check that previous letter wasen't a possible
2432 * word part.
2433 */
2434 if ($i > 0)
2435 {
2436 $ch = $sLine[$i - 1];
2437 if ( ($ch >= 'a' && $ch <= 'z')
2438 || ($ch >= 'A' && $ch <= 'Z')
2439 || ($ch >= '0' && $ch <= '9')
2440 || ($ch == '_')
2441 || ($ch == '@')
2442 || ($ch == '?')
2443 || ($ch == '$')
2444 )
2445 return 0;
2446 }
2447
2448 /*
2449 * Count letters in the word
2450 */
2451 $j = $i;
2452 $ch = $sLine[$i];
2453 while ($i < $cchLine &&
2454 ( ($ch >= 'a' && $ch <= 'z')
2455 || ($ch >= 'A' && $ch <= 'Z')
2456 || ($ch >= '0' && $ch <= '9')
2457 || ($ch == '_')
2458 || ($ch == '@')
2459 || ($ch == '?')
2460 || ($ch == '$')
2461 )
2462 )
2463 $ch = @$sLine[++$i];
2464 return $i - $j;
2465}
2466
2467
2468
2469/*
2470 *
2471 */
2472/* hardcoded
2473$aMake_Keywords = array(
2474 "\$&amp;" => 1,
2475 "\$**" => 1,
2476 "\$*" => 1,
2477 "\$." => 1,
2478 "\$:" => 1,
2479 "\$&lt;" => 1,
2480 "\$?" => 1,
2481 "\$@" => 1,
2482 "\$d" => 1);
2483*/
2484$aMake_Symbols = array(
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 "," => 1,
2498 "&lt;" => 1,
2499 "&gt;" => 1,
2500 ":" => 1,
2501 ";" => 1);
2502/**
2503 * Initiate the variable array used by the C Color encoder.
2504 * @param $aVaraibles Variable array. (output)
2505 */
2506function Make_ColorInit(&$aVariables)
2507{
2508 //global $aMake_Keywords;
2509 global $aMake_Symbols;
2510 //$aVariables = array("fInline" => 0)
2511 //ksort($aMake_Keywords);
2512 ksort($aMake_Symbols);
2513}
2514
2515
2516/**
2517 * Encode a line of C code.
2518 * @param $sLine Line string to encode.
2519 * @param $aVariables Variable array.
2520 * @returns Color encoded line string.
2521 */
2522function Make_ColorEncode($sLine, &$aVariables)
2523{
2524 global $aMake_Keywords;
2525 global $aMake_Symbols;
2526
2527 $sRet = "";
2528 $cchLine = strlen($sLine);
2529 $i = 0;
2530 $fFirstNonBlank = 1;
2531
2532 /*
2533 * Loop thru the (remainings) of the line.
2534 */
2535 while ($i < $cchLine)
2536 {
2537 $ch = $sLine[$i];
2538
2539 /* comment check */
2540 if ($ch == '#')
2541 {
2542 return $sRet . "<font color=#02FE02>" . substr($sLine, $i) . "</font>";
2543 }
2544
2545
2546 /*
2547 * Check for string.
2548 */
2549 if ((($fDbl = (substr($sLine, $i, 6) == "&quot;")) || $sLine[$i] == "'")
2550 && ($i == 0 || $sLine[$i-1] != '\\'))
2551 { /* start of a string */
2552
2553 $j = $i + 1;
2554 if ($fDbl)
2555 {
2556 while ($j < $cchLine && ($sLine[$j] != '&' || substr($sLine, $j, 6) != "&quot;"))
2557 $j += ($sLine[$j] == '\\') ? 2 : 1;
2558 if ($j < $cchLine)
2559 $j += 5;
2560 }
2561 else
2562 while ($j < $cchLine && $sLine[$j] != "'")
2563 $j += ($sLine[$j] == '\\') ? 2 : 1;
2564 $j++;
2565 $sRet .= "<font color=#FEFE02>".substr($sLine, $i, $j - $i)."</font>";
2566 $i = $j;
2567 $fFirstNonBlank = 0;
2568 continue;
2569 }
2570
2571 /*
2572 * Check for ! or % words
2573 */
2574 if (($fFirstNonBlank && ($ch == "#" || $ch == "!")))
2575 {
2576 $j = $i + 1;
2577 while ($j < $cchLine && ($sLine[$j] == ' ' || $sLine[$j] == "\t"))
2578 $j++;
2579 $j += Make_WordLen($sLine, $cchLine, $j);
2580 echo "<font color=#CECECE>" . substr($sLine, $i, $j - $i) . "</font>";
2581 $i = $j;
2582 $fFirstNonBlank = 0;
2583 continue;
2584 }
2585
2586 /*
2587 * Check for keyword
2588 */
2589 /* don't work
2590 if ($ch == "$" && $i + 1 < $cchLine)
2591 {
2592 $cch = 0;
2593 $sWord = substr($sLine, $i+1, 1);
2594 if ( $sWord == "*"
2595 || $sWord == "."
2596 || $sWord == ":"
2597 || $sWord == "?"
2598 || $sWord == "@"
2599 || $sWord == "d")
2600 $cch = 2;
2601 else if ($i + 2 < $cchLine && ($sWord = substr($sLine, $i+1, 2)) == "**")
2602 $cch = 3;
2603 else if ($i + 4 < $cchLine && ($sWord = substr($sLine, $i+1, 5)) == "&amp;")
2604 $cch = 6;
2605 else if ($i + 5 < $cchLine && ($sWord = substr($sLine, $i+1, 4)) == "&lt;")
2606 $cch = 5;
2607 if ($cch > 0)
2608 {
2609 echo "<font color=#CECECE>$" . $sWord . "</font>";
2610 $i += $cch;
2611 $fFirstNonBlank = 0;
2612 continue;
2613 }
2614 } */
2615
2616 /*
2617 * If non-blank, lets check if we're at the start of a word...
2618 */
2619 $fBlank = ($ch == " " || $ch == "\t" || $ch == "\n");
2620 $cchWord = !$fBlank ? Make_WordLen($sLine, $cchLine, $i) : 0;
2621
2622 if ($cchWord > 0)
2623 {
2624 $sWord = strtolower(substr($sLine, $i, $cchWord));
2625
2626 /*
2627 * Check for keywords.
2628 */
2629 if ($f = isset($aMake_Keywords[$sWord]))
2630 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2631
2632 /*
2633 * Check for number.
2634 */
2635 else if (($ch >= '0' && $ch <= '9'))
2636 $sRet .= "<font color=#FF0202>" . substr($sLine, $i, $cchWord) . "</font>";
2637
2638 /*
2639 * Skip word.
2640 */
2641 else
2642 $sRet .= substr($sLine, $i, $cchWord);
2643
2644 $i += $cchWord;
2645 $fFirstNonBlank = 0;
2646 continue;
2647 }
2648
2649 /*
2650 * Prepare for symbol check. (we'll have to check for HTML stuff like &amp;).
2651 */
2652 $cchWord = 1;
2653 if ($ch == '&')
2654 {
2655 if (substr($sLine, $i, 5) == "&amp;")
2656 $cchWord = 5;
2657 else if (substr($sLine, $i, 4) == "&gt;" || substr($sLine, $i, 4) == "&lt;")
2658 $cchWord = 4;
2659 }
2660
2661 /*
2662 * Check for Symbol.
2663 */
2664 if (isset($aMake_Symbols[substr($sLine, $i, $cchWord)]))
2665 {
2666 $sRet .= "<font color=#CECECE>" . substr($sLine, $i, $cchWord) . "</font>";
2667 $i += $cchWord;
2668 $fFirstNonBlank = 0;
2669 continue;
2670 }
2671
2672
2673 /*
2674 * Copy char
2675 */
2676 $sRet .= $sLine[$i];
2677 $i++;
2678 if ($fFirstNonBlank && !$fBlank)
2679 $fFirstNonBlank = 0;
2680 }
2681
2682 return $sRet;
2683}
2684
2685/**
2686 * Calculates the lenght of the word which eventually starts at [$i].
2687 * @param $sLine Line.
2688 * @param $cchLine Line length.
2689 * @param $i Line index.
2690 * @returns Word length.
2691 */
2692function Make_WordLen($sLine, $cchLine, $i)
2693{
2694
2695 /*
2696 * Check that previous letter wasen't a possible
2697 * word part.
2698 */
2699 if ($i > 0)
2700 {
2701 $ch = $sLine[$i - 1];
2702 if ( ($ch >= 'a' && $ch <= 'z')
2703 || ($ch >= 'A' && $ch <= 'Z')
2704 || ($ch >= '0' && $ch <= '9')
2705 || ($ch == '_')
2706 )
2707 return 0;
2708 }
2709
2710 /*
2711 * Count letters in the word
2712 */
2713 $j = $i;
2714 $ch = $sLine[$i];
2715 while ($i < $cchLine &&
2716 ( ($ch >= 'a' && $ch <= 'z')
2717 || ($ch >= 'A' && $ch <= 'Z')
2718 || ($ch >= '0' && $ch <= '9')
2719 || ($ch == '_')
2720 )
2721 )
2722 $ch = @$sLine[++$i];
2723 return $i - $j;
2724}
2725
2726
2727?>
2728
Note: See TracBrowser for help on using the repository browser.