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

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

mozilla fix.

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