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

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

Most merges is ok. branches don't work 100%.

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