<?php// This PHP script generates clickable HTML documentation files for amforth// project. Script should be run once (offline) when new versions of sorces are// available. It creates new subdirectory with HTML documentation tree.//// Configuration file is GenerateHTML.cfg//// (c)miho 2007 / http://www.mlab.cz// **********************************************************************// History// **********************************************************************// 0.00 work wersion// **********************************************************************// Definitions/parameters// **********************************************************************define ('INCLUDE_PATTERN', "/^ *\.include +\"(\S+)\"/i");define ('LABEL_PREFIX', "(VE_|XT_|PFA)");define ('LABEL_PATTERN', "/^ *(".LABEL_PREFIX."\S+):/i");define ('WORD_PATTERN', "/((?:\\n *;.*)*)\\n *VE_Q:[^\\n]*\\n? *.db +[^,]* *, *(\S[^\\n|;]+)/im"); // Q is used instead of Worddefine ('ASMFILES', "CodeAsm/");// **********************************************************************// Generic Funcions// **********************************************************************function MyReadFile($FileName, &$FileContent)// Reads file, returns file as a single string{// Read file$FileContent=@file($FileName);// Test if file contains any contentif ($FileContent==FALSE){unset($FileContent);return "No Data in File $FileName";}// Remove CR or LF or CR/LFforeach($FileContent as $Key => $Line){$FileContent[$Key]=rtrim($Line);}// No errorreturn "";}function MyReadFileString($FileName, &$FileContent)// Reads file and returns its content as a single string{// No Error$Error="";// Read file$Error=MyReadFile($FileName, &$FileContent);// Convert to a single stringif ($Error=="") $FileContent=implode("\n",$FileContent);// Finishedreturn $Error;}function MyWriteFile($FileName, $FileContent)// Creates and writes file{// Create Output File$File=@fopen($FileName,"w");if ($File==FALSE){return "Unable Write File ".$FileName;}// Write contentfwrite($File,$FileContent);fclose($File);// No Errorreturn "";}function FileName2HTML($FileName)// Converts FileName to FileName of HTML file{// Remove path$FileName=basename($FileName);// Change suffix$FileName=preg_replace("/\.asm$/i",".html",$FileName);// Finished#print $FileName;return $FileName;}function Label2Link($Link, $href, $title, &$LabelList)// Converts Label to Link// If label not found returns original text// IN $Link - label to find// IN $Word - word to show (on mouse)// IN $LabelList - list of all labels (Label, FileName, LineNumber){// Find label in $LabelListforeach($LabelList as $Value){if ($Link===$Value["Label"]){#$LabelListItem=$Value /////////////////////////////print "Found ".$Value["Label"]."\n";}}$FileName=$Value["FileName"]."#".$Link;// Create link$Link="<a href=\"".$FileName."\" title=\" ".$Word."\">".$Link.'</a>';return $Link;}// **********************************************************************// Function for processing// **********************************************************************function SourceAsm($SourceDir, $FileName, &$SourceAsmFiles, &$LabelList )// Process ASM source file, recurse all includes// Stores file names and labels into two arrays// IN $SourceDir - base directory (not printed)// IN $FileName - file to process// OUT $SourceAsmFiles - list of all processed files (Filename)// OUT $LabelList - list of all labels (Label, FileName, LineNumber){// Startprint "Read Asm: $FileName\n";// Read file$Error=MyReadFile($SourceDir.$FileName, $FileContent);if ($Error!=""){print $Error."\n";return 1;}// Remember filename$SourceAsmFiles[]=$FileName;// Filter source file line by line - find labelsforeach($FileContent as $Key => $Value){// Find label definitionsif (preg_match(LABEL_PATTERN,$Value,$Matches)){print " label @line ".($Key+1)." ".$Matches[1]."\n";$LabelList[]=array("Label"=>$Matches[1],"FileName"=>$FileName,"LineNumber"=>($Key+1));}}// Filter source file line by line - find includesforeach($FileContent as $Key => $Value){// Find .include "filename" linesif (preg_match(INCLUDE_PATTERN,$Value,$Matches)){print " include @line ".($Key+1)." --> ".$Matches[1]."\n";// Remember links$Includes[]=$Matches[1];}}// Print delimiterprint "\n";// Recurse includesif ($Includes){foreach($Includes as $Value){$Dir=dirname($FileName)."/";if ($Dir=="./"){$Dir="";}SourceAsm($SourceDir, $Dir.$Value, $SourceAsmFiles, $LabelList);}unset($Includes);}// Endreturn 0;}function PrintSourceAsm(&$SourceAsmFiles)// Prints all procesed ASM files{print "Asm Source File List\n";foreach($SourceAsmFiles as $Key => $Value){print " ".$Value."\n";}print "\n";}function PrintLabels(&$LabelList)// Prints all found labels{print "Label List\n";foreach($LabelList as $Key => $Value){print " ".$Value["Label"]." ".$Value["FileName"]." ".$Value["LineNumber"]."\n";}print "\n";}function CreateWordList($SourceDir, &$LabelList, &$WordList)// Goes through LabelList and looks for word definitions// IN $LabelList - Found labels// OUT $WordList - Word List (ShortLabel, Word, Comment, Label, FileName){print "Word List\n";if ($LabelList)foreach ($LabelList as $Value){// Take all VE definitionsif (stristr(substr($Value["Label"],0,3),"VE_")){// Prepare Label without VE_$ShortLabel=substr($Value["Label"],3);// Prepare search pattern$Pattern=str_replace("Q",$ShortLabel,WORD_PATTERN);#print "Pattern: ".$Pattern." ".$Value["FileName"]."\n";// Read source file$FileName=$SourceDir.$Value["FileName"];$Error=MyReadFileString($FileName, $FileContent);if ($Error!=""){print " ".$Error."\n";return 1;}$FileContent="\n".$FileContent;// Find labelif (preg_match($Pattern,$FileContent,$Matches)){// Coments - remove semiculomn$Comment = rtrim(preg_replace("/\\n; ?(.*)/","$1\n",$Matches[1]));// Convert .db parameters into string$Word="";#$Word=$Matches[2]." : ";foreach(explode(",",$Matches[2]) as $Val){// String elementpreg_match("/^ *\"([^\"]*)(\" *)/",$Val,$Tmp);#print "S:".$Tmp[1]."\n";if ($Tmp[1]!=""){$Word.=$Tmp[1];}// Hexa numberpreg_match("/\\$([0-9A-F]+)/i",$Val,$Tmp);#print "H:".$Tmp[1]."\n";if ($Tmp[1]!=""){$Number=hexdec($Tmp[1]);if ($Number!=0)$Word.=chr($Number);}// Decimal numberpreg_match("/^([0-9]+)/i",$Val,$Tmp);#print "D:".$Tmp[1]."\n";if ($Tmp[1]!=""){$Number=$Tmp[1];if ($Number!=0)$Word.=chr($Number);}}// Store label into array$WordList[]=array("Word"=>$Word, "ShortLabel"=>$ShortLabel, "Comment"=>$Comment,"Label"=>$Value["Label"] , "FileName"=>$Value["FileName"]);print " ".$Word." = ".$ShortLabel."\n";if($Comment) print " ".preg_replace("/\\n/","\n ",$Comment)."\n";}// Sort Wordsarray_multisort($WordList);// Clean Upunset($FileContent);}}print "\n";}function GenerateWordList($TemplateDir, $DestinationDir, &$LabelList, &$WordList)// Creates HTML pages with Word List// IN $TemplateDir - template directory (file WordList.*.html)// IN $LabelList - list of labels (Label, FileName, LineNumber)// IN $WordList - list of words (ShortLabel, Word, Comment, Label, FileName)// OUT WordList.*.html - create HTML pages (file WordList.*.html){// Find all templatesprint "Word List in HTML\n";foreach (glob($TemplateDir."WordList.*.html") as $FileName){// Process template fileprint " Temlate $FileName\n";// Read template file$Error=MyReadFileString($FileName, $FileContent);if ($Error!=""){print " ".$Error."\n";return 1;}// Find <<WordList>>if (!preg_match("/( *)(<<WordList>>)/i",$FileContent,$Matches)){print " Missing <<WordList>> in template file\n";unset($FileContent);return -1;}$Indent=$Matches[1];// Create HTML code - table header$WordListHTML[]="<table>";$WordListHTML[]=" <tr>";$WordListHTML[]=" <th>Word</th>";$WordListHTML[]=" <th>Label</th>";$WordListHTML[]=" <th>Definition</th>";$WordListHTML[]=" </tr>";// Create HTML code - table linesforeach($WordList as $Key => $Value){// Prepare (just for readibility)$Word=$Value["Word"];$Link="<a href=\"".ASMFILES.FileName2HTML($Value["FileName"])."#".$Value["ShortLabel"]."\" title=\"".$Value["Label"]."\">".$Value["ShortLabel"]."</a>";$Comment=$Value["Comment"];// Generate HTML$WordListHTML[]=" <tr>";$WordListHTML[]=" <td>".htmlspecialchars($Word)."</td>";$WordListHTML[]=" <td>".$Link."</td>";$WordListHTML[]=" <td>".htmlspecialchars($Comment)."</td>";$WordListHTML[]=" </tr>";}// Create HTML code - table end$WordListHTML[]="</table>";// Indent and Concatenate linesforeach($WordListHTML as $Key => $Value){$WordListHTML[$Key]=$Indent.preg_replace("/\n/","<br>",$Value);}$WordListHTML=implode("\n",$WordListHTML);// Put it into HTML template$FileContent=str_ireplace("<<WordList>>", $WordListHTML, $FileContent);#print $FileContent;// Create Output File$Error=MyWriteFile($DestinationDir.basename($FileName), $FileContent);if ($Error!=""){print " ".$Error."\n";return -1;}// Clear memoryunset($FileContent);unset($WordListHTML);}// Delimiterprint "\n";}function GenerateAsmFiles($TemplateDir, $SourceDir, &$SourceAsmFiles, $DestinationDir)// Cretaes HTML files from all processed ASM files// IN//{// Infoprint "Copy ASM Files\n";// Destination directory exists$DestinationDir.=ASMFILES;if (!is_dir($DestinationDir)){if (!@mkdir($DestinationDir)){print " Unable Create Dir ".$DestinationDir."\n";return -1;}}// Read template$Error=MyReadFileString($TemplateDir."FileAsm.en.html", $Template);if ($Error!=""){print " ".$Error."\n";return -1;}// Copy all source filesforeach($SourceAsmFiles as $Key => $FileName){print " ".$FileName."\n";// Read ASM file$Error=MyReadFileString($SourceDir.$FileName, $FileContent);if ($Error!=""){print " ".$Error."\n";return 1;}// Prepare HTML$FileContent=htmlspecialchars($FileContent);$FileContent="<pre>\n".$FileContent."\n</pre>";// Use Template$TemplateWork=$Template;$TemplateWork=str_ireplace("<<FileName>>", $FileName, $TemplateWork);$TemplateWork=str_ireplace("<<FileContent>>", $FileContent, $TemplateWork);// Write ASM file in HTML$Error=MyWriteFile($DestinationDir.FileName2HTML($FileName), $TemplateWork);if ($Error!=""){print " ".$Error."\n";return -1;}}// Delimiterprint "\n";}// **********************************************************************// Main Block// **********************************************************************// This file contains configurations for this scriptrequire_once("GenerateHTML.cfg");// Global Like Variables//$SourceAsmFiles - All processed ASM files (filenames)//$LabelList - All label definitions (Label, FileName, LineNumber)//$WordList - Word List (ShortLabel, Word, Comment, Label, FileName)// Process all ASM files from the root levelSourceAsm($CFG_SourceDir, $CFG_SourceAsm, $SourceAsmFiles, $LabelList);PrintSourceAsm($SourceAsmFiles);PrintLabels($LabelList);// Destilate Labels and WordsCreateWordList($CFG_SourceDir, $LabelList, $WordList);// Create HTML WordListGenerateWordList($CFG_TemplateDir, $CFG_DestinationDir, $LabelList, $WordList);// Copy ASM files and convert them into HTMLGenerateAsmFiles($CFG_TemplateDir, $CFG_SourceDir, $SourceAsmFiles, $CFG_DestinationDir);// Zpracování readme autora + verze// Dodělat kontroly vstupní CFG parametrů (existence souborů a adresářů)// Osetreni chyb - die(1) zpusobi chybu (v shellu a da se tak poznat, ze to nedopadlo)// Zpracování templejtů do samostatného podprogramu (vyřešit indent...)// tím se vyřeší i en/cs verze Asm souboru// Generovat log do souboru místo printu (zvážit) oddělit chyby a varování// Vyčistit cílový adresář// Process all FORTH files// Problém s rekurzí (potenciální nekonečno)// Chtělo by to do stránek vkládat info o verzi a (c)?>