Rev Author Line No. Line
541 miho 1 <?php
2 // This PHP script generates clickable HTML documentation files for amforth
3 // project. Script should be run once (offline) when new versions of sorces are
543 miho 4 // available. It creates new subdirectory with HTML documentation tree.
541 miho 5 //
6 // Configuration file is GenerateHTML.cfg
7 //
8 // (c)miho 2007 / http://www.mlab.cz
9  
10 // **********************************************************************
11 // History
12 // **********************************************************************
13 // 0.00 work wersion
14  
15  
16 // **********************************************************************
17 // Definitions/parameters
18 // **********************************************************************
19  
20  
21 define ('INCLUDE_PATTERN', "/^ *\.include +\"(\S+)\"/i");
22 define ('LABEL_PREFIX', "(VE_|XT_|PFA)");
23 define ('LABEL_PATTERN', "/^ *(".LABEL_PREFIX."\S+):/i");
24 define ('WORD_PATTERN', "/((?:\\n *;.*)*)\\n *VE_Q:[^\\n]*\\n? *.db +[^,]* *, *(\S[^\\n|;]+)/im"); // Q is used instead of Word
25 define ('ASMFILES', "CodeAsm/");
26  
27  
28 // **********************************************************************
29 // Generic Funcions
30 // **********************************************************************
31  
32  
33 function MyReadFile($FileName, &$FileContent)
34 // Reads file, returns file as a single string
35 {
36 // Read file
37 $FileContent=@file($FileName);
38  
39 // Test if file contains any content
40 if ($FileContent==FALSE)
41 {
42 unset($FileContent);
43 return "No Data in File $FileName";
44 }
45  
46 // Remove CR or LF or CR/LF
47 foreach($FileContent as $Key => $Line)
48 {
49 $FileContent[$Key]=rtrim($Line);
50 }
51  
52 // No error
53 return "";
54 }
55  
56  
57 function MyReadFileString($FileName, &$FileContent)
58 // Reads file and returns its content as a single string
59 {
60 // No Error
61 $Error="";
62  
63 // Read file
64 $Error=MyReadFile($FileName, &$FileContent);
65  
66 // Convert to a single string
67 if ($Error=="") $FileContent=implode("\n",$FileContent);
68  
69 // Finished
70 return $Error;
71 }
72  
73  
74 function MyWriteFile($FileName, $FileContent)
75 // Creates and writes file
76 {
77 // Create Output File
78 $File=@fopen($FileName,"w");
79 if ($File==FALSE)
80 {
81 return "Unable Write File ".$FileName;
82 }
83  
84 // Write content
85 fwrite($File,$FileContent);
86 fclose($File);
87  
88 // No Error
89 return "";
90 }
91  
92  
93 function FileName2HTML($FileName)
94 // Converts FileName to FileName of HTML file
95 {
96 // Remove path
97 $FileName=basename($FileName);
98 // Change suffix
99 $FileName=preg_replace("/\.asm$/i",".html",$FileName);
100 // Finished
101 #print $FileName;
102 return $FileName;
103 }
104  
105  
106 function Label2Link($Link, $href, $title, &$LabelList)
107 // Converts Label to Link
108 // If label not found returns original text
109 // IN $Link - label to find
110 // IN $Word - word to show (on mouse)
111 // IN $LabelList - list of all labels (Label, FileName, LineNumber)
112 {
113 // Find label in $LabelList
114 foreach($LabelList as $Value)
115 {
116 if ($Link===$Value["Label"])
117 {
118 #$LabelListItem=$Value /////////////////////////////
119 print "Found ".$Value["Label"]."\n";
120 }
121 }
122  
123 $FileName=$Value["FileName"]."#".$Link;
124  
125 // Create link
126 $Link="<a href=\"".$FileName."\" title=\" ".$Word."\">".$Link.'</a>';
127  
128 return $Link;
129 }
130  
131  
132 // **********************************************************************
133 // Function for processing
134 // **********************************************************************
135  
136  
137 function SourceAsm($SourceDir, $FileName, &$SourceAsmFiles, &$LabelList )
138 // Process ASM source file, recurse all includes
139 // Stores file names and labels into two arrays
140 // IN $SourceDir - base directory (not printed)
141 // IN $FileName - file to process
142 // OUT $SourceAsmFiles - list of all processed files (Filename)
143 // OUT $LabelList - list of all labels (Label, FileName, LineNumber)
144 {
145  
146 // Start
147 print "Read Asm: $FileName\n";
148  
149 // Read file
150 $Error=MyReadFile($SourceDir.$FileName, $FileContent);
151 if ($Error!="")
152 {
153 print $Error."\n";
154 return 1;
155 }
156  
157 // Remember filename
158 $SourceAsmFiles[]=$FileName;
159  
160 // Filter source file line by line - find labels
161 foreach($FileContent as $Key => $Value)
162 {
163 // Find label definitions
164 if (preg_match(LABEL_PATTERN,$Value,$Matches))
165 {
166 print " label @line ".($Key+1)." ".$Matches[1]."\n";
167 $LabelList[]=array("Label"=>$Matches[1],"FileName"=>$FileName,"LineNumber"=>($Key+1));
168 }
169 }
170  
171 // Filter source file line by line - find includes
172 foreach($FileContent as $Key => $Value)
173 {
174 // Find .include "filename" lines
175 if (preg_match(INCLUDE_PATTERN,$Value,$Matches))
176 {
177 print " include @line ".($Key+1)." --> ".$Matches[1]."\n";
178 // Remember links
179 $Includes[]=$Matches[1];
180 }
181 }
182  
183 // Print delimiter
184 print "\n";
185  
186 // Recurse includes
187 if ($Includes)
188 {
189 foreach($Includes as $Value)
190 {
191 $Dir=dirname($FileName)."/";
192 if ($Dir=="./")
193 {
194 $Dir="";
195 }
196 SourceAsm($SourceDir, $Dir.$Value, $SourceAsmFiles, $LabelList);
197 }
198 unset($Includes);
199 }
200  
201 // End
202 return 0;
203 }
204  
205  
206 function PrintSourceAsm(&$SourceAsmFiles)
207 // Prints all procesed ASM files
208 {
209 print "Asm Source File List\n";
210 foreach($SourceAsmFiles as $Key => $Value)
211 {
212 print " ".$Value."\n";
213 }
214 print "\n";
215 }
216  
217  
218 function PrintLabels(&$LabelList)
219 // Prints all found labels
220 {
221 print "Label List\n";
222 foreach($LabelList as $Key => $Value)
223 {
224 print " ".$Value["Label"]." ".$Value["FileName"]." ".$Value["LineNumber"]."\n";
225 }
226 print "\n";
227 }
228  
229  
230 function CreateWordList($SourceDir, &$LabelList, &$WordList)
231 // Goes through LabelList and looks for word definitions
232 // IN $LabelList - Found labels
233 // OUT $WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
234 {
235  
236 print "Word List\n";
237  
238 if ($LabelList)
239 foreach ($LabelList as $Value)
240 {
241 // Take all VE definitions
242 if (stristr(substr($Value["Label"],0,3),"VE_"))
243 {
244 // Prepare Label without VE_
245 $ShortLabel=substr($Value["Label"],3);
246  
247 // Prepare search pattern
248 $Pattern=str_replace("Q",$ShortLabel,WORD_PATTERN);
249 #print "Pattern: ".$Pattern." ".$Value["FileName"]."\n";
250  
251 // Read source file
252 $FileName=$SourceDir.$Value["FileName"];
543 miho 253 $Error=MyReadFileString($FileName, $FileContent);
541 miho 254 if ($Error!="")
255 {
256 print " ".$Error."\n";
257 return 1;
258 }
259 $FileContent="\n".$FileContent;
260  
261 // Find label
262 if (preg_match($Pattern,$FileContent,$Matches))
263 {
264 // Coments - remove semiculomn
265 $Comment = rtrim(preg_replace("/\\n; ?(.*)/","$1\n",$Matches[1]));
266  
267 // Convert .db parameters into string
268 $Word="";
269 #$Word=$Matches[2]." : ";
270  
271 foreach(explode(",",$Matches[2]) as $Val)
272 {
273 // String element
274 preg_match("/^ *\"([^\"]*)(\" *)/",$Val,$Tmp);
275 #print "S:".$Tmp[1]."\n";
276 if ($Tmp[1]!="")
277 {
278 $Word.=$Tmp[1];
279 }
280  
281 // Hexa number
282 preg_match("/\\$([0-9A-F]+)/i",$Val,$Tmp);
283 #print "H:".$Tmp[1]."\n";
284 if ($Tmp[1]!="")
285 {
286 $Number=hexdec($Tmp[1]);
287 if ($Number!=0)
288 $Word.=chr($Number);
289 }
290  
291 // Decimal number
292 preg_match("/^([0-9]+)/i",$Val,$Tmp);
293 #print "D:".$Tmp[1]."\n";
294 if ($Tmp[1]!="")
295 {
296 $Number=$Tmp[1];
297 if ($Number!=0)
298 $Word.=chr($Number);
299 }
300  
301 }
302  
303 // Store label into array
304 $WordList[]=array("Word"=>$Word, "ShortLabel"=>$ShortLabel, "Comment"=>$Comment,
305 "Label"=>$Value["Label"] , "FileName"=>$Value["FileName"]
306 );
307 print " ".$Word." = ".$ShortLabel."\n";
308 if($Comment) print " ".preg_replace("/\\n/","\n ",$Comment)."\n";
309 }
310  
311 // Sort Words
312 array_multisort($WordList);
313  
314 // Clean Up
315 unset($FileContent);
316 }
317 }
318 print "\n";
319 }
320  
321  
322 function GenerateWordList($TemplateDir, $DestinationDir, &$LabelList, &$WordList)
323 // Creates HTML pages with Word List
324 // IN $TemplateDir - template directory (file WordList.*.html)
325 // IN $LabelList - list of labels (Label, FileName, LineNumber)
326 // IN $WordList - list of words (ShortLabel, Word, Comment, Label, FileName)
327 // OUT WordList.*.html - create HTML pages (file WordList.*.html)
328 {
329 // Find all templates
330 print "Word List in HTML\n";
331 foreach (glob($TemplateDir."WordList.*.html") as $FileName)
332 {
333 // Process template file
334 print " Temlate $FileName\n";
335  
336 // Read template file
337 $Error=MyReadFileString($FileName, $FileContent);
338 if ($Error!="")
339 {
340 print " ".$Error."\n";
341 return 1;
342 }
343  
344 // Find <<WordList>>
345 if (!preg_match("/( *)(<<WordList>>)/i",$FileContent,$Matches))
346 {
347 print " Missing <<WordList>> in template file\n";
348 unset($FileContent);
349 return -1;
350 }
351 $Indent=$Matches[1];
352  
353 // Create HTML code - table header
354 $WordListHTML[]="<table>";
355 $WordListHTML[]=" <tr>";
356 $WordListHTML[]=" <th>Word</th>";
357 $WordListHTML[]=" <th>Label</th>";
358 $WordListHTML[]=" <th>Definition</th>";
543 miho 359 $WordListHTML[]=" </tr>";
541 miho 360  
361 // Create HTML code - table lines
362 foreach($WordList as $Key => $Value)
363 {
364 // Prepare (just for readibility)
365 $Word=$Value["Word"];
366 $Link="<a href=\"".ASMFILES.FileName2HTML($Value["FileName"])."#".$Value["ShortLabel"].
367 "\" title=\"".$Value["Label"]."\">".$Value["ShortLabel"]."</a>";
368 $Comment=$Value["Comment"];
369 // Generate HTML
370 $WordListHTML[]=" <tr>";
371 $WordListHTML[]=" <td>".htmlspecialchars($Word)."</td>";
372 $WordListHTML[]=" <td>".$Link."</td>";
373 $WordListHTML[]=" <td>".htmlspecialchars($Comment)."</td>";
374 $WordListHTML[]=" </tr>";
375 }
376 // Create HTML code - table end
377 $WordListHTML[]="</table>";
378  
379 // Indent and Concatenate lines
380 foreach($WordListHTML as $Key => $Value)
381 {
382 $WordListHTML[$Key]=$Indent.preg_replace("/\n/","<br>",$Value);
383 }
384 $WordListHTML=implode("\n",$WordListHTML);
385  
386 // Put it into HTML template
387 $FileContent=str_ireplace("<<WordList>>", $WordListHTML, $FileContent);
388 #print $FileContent;
389  
390 // Create Output File
391 $Error=MyWriteFile($DestinationDir.basename($FileName), $FileContent);
392 if ($Error!="")
393 {
394 print " ".$Error."\n";
395 return -1;
396 }
397  
398 // Clear memory
399 unset($FileContent);
400 unset($WordListHTML);
401 }
402  
403 // Delimiter
404 print "\n";
405 }
406  
407  
408 function GenerateAsmFiles($TemplateDir, $SourceDir, &$SourceAsmFiles, $DestinationDir)
409 // Cretaes HTML files from all processed ASM files
410 // IN
411 //
412 {
413 // Info
414 print "Copy ASM Files\n";
415  
416 // Destination directory exists
417 $DestinationDir.=ASMFILES;
418 if (!is_dir($DestinationDir))
419 {
420 if (!@mkdir($DestinationDir))
421 {
422 print " Unable Create Dir ".$DestinationDir."\n";
423 return -1;
424 }
425 }
426  
427 // Read template
428 $Error=MyReadFileString($TemplateDir."FileAsm.en.html", $Template);
429 if ($Error!="")
430 {
431 print " ".$Error."\n";
432 return -1;
433 }
434  
435 // Copy all source files
436 foreach($SourceAsmFiles as $Key => $FileName)
437 {
438 print " ".$FileName."\n";
439  
440 // Read ASM file
441 $Error=MyReadFileString($SourceDir.$FileName, $FileContent);
442 if ($Error!="")
443 {
444 print " ".$Error."\n";
445 return 1;
446 }
447  
448 // Prepare HTML
449 $FileContent=htmlspecialchars($FileContent);
450 $FileContent="<pre>\n".$FileContent."\n</pre>";
451  
452 // Use Template
453 $TemplateWork=$Template;
454 $TemplateWork=str_ireplace("<<FileName>>", $FileName, $TemplateWork);
455 $TemplateWork=str_ireplace("<<FileContent>>", $FileContent, $TemplateWork);
456  
457 // Write ASM file in HTML
458 $Error=MyWriteFile($DestinationDir.FileName2HTML($FileName), $TemplateWork);
459 if ($Error!="")
460 {
461 print " ".$Error."\n";
462 return -1;
463 }
464 }
465  
466 // Delimiter
467 print "\n";
468 }
469  
470  
471 // **********************************************************************
472 // Main Block
473 // **********************************************************************
474  
475  
476 // This file contains configurations for this script
477 require_once("GenerateHTML.cfg");
478  
479  
480 // Global Like Variables
481 //$SourceAsmFiles - All processed ASM files (filenames)
482 //$LabelList - All label definitions (Label, FileName, LineNumber)
483 //$WordList - Word List (ShortLabel, Word, Comment, Label, FileName)
484  
485  
486 // Process all ASM files from the root level
487 SourceAsm($CFG_SourceDir, $CFG_SourceAsm, $SourceAsmFiles, $LabelList);
488 PrintSourceAsm($SourceAsmFiles);
489 PrintLabels($LabelList);
490  
491 // Destilate Labels and Words
492 CreateWordList($CFG_SourceDir, $LabelList, $WordList);
493  
494 // Create HTML WordList
495 GenerateWordList($CFG_TemplateDir, $CFG_DestinationDir, $LabelList, $WordList);
496  
497 // Copy ASM files and convert them into HTML
498 GenerateAsmFiles($CFG_TemplateDir, $CFG_SourceDir, $SourceAsmFiles, $CFG_DestinationDir);
499  
500  
501 // Zpracování readme autora + verze
543 miho 502 // Dodělat kontroly vstupní CFG parametrů (existence souborů a adresářů)
503 // Osetreni chyb - die(1) zpusobi chybu (v shellu a da se tak poznat, ze to nedopadlo)
541 miho 504  
505 // Zpracování templejtů do samostatného podprogramu (vyřešit indent...)
506 // tím se vyřeší i en/cs verze Asm souboru
507  
508 // Generovat log do souboru místo printu (zvážit) oddělit chyby a varování
509 // Vyčistit cílový adresář
510 // Process all FORTH files
511 // Problém s rekurzí (potenciální nekonečno)
543 miho 512 // Chtělo by to do stránek vkládat info o verzi a (c)
541 miho 513 ?>