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

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

More complete than ever... But not quite finished.
PHP4 is 8+ timer faster than PHP3!!!

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