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

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

Branches are working better now..
Although they're listed in reverse order.
Another feature is that CVS keywords are expanded on checkout - this is not
implemented yet.

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