+# Things currently missing:
+#
+# - Scoping with .proc/.endproc
+# - .global is ignored
+# - .constructor/.destructor/.condes dito
+# - .ignorecase is ignored, labels are always case sensitive
+# - .include handling (difficult)
+# - The global namespace operator ::
+#
+
+
+
use strict 'vars';
use warnings;
my $BGColor = "#FFFFFF"; # Background color
my $Debug = 0; # No debugging
my $Help = 0; # Help flag
+my $HTMLDir = ""; # Directory in which to create the files
my $IndexCols = 6; # Columns in the file listing
-my $IndexTitle = "Index"; # Title of index page
-my $IndexName = "index.html"; # Name of index page
-my $IndexPage = 0; # Create an index page
+my $IndexTitle = "Index"; # Title of index page
+my $IndexName = "index.html"; # Name of index page
+my $IndexPage = 0; # Create an index page
my $LinkStyle = 0; # Default link style
-my $ReplaceExt = 0; # Replace extension instead of appending
-my $TextColor = "#000000"; # Text color
-my $Verbose = 0; # Be quiet
+my $ReplaceExt = 0; # Replace extension instead of appending
+my $TextColor = "#000000"; # Text color
+my $Verbose = 0; # Be quiet
+
+# Table used to convert the label number into names
+my @NameTab = ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K",
+ "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6",
+ "7", "8", "9");
# Generate a label and return it
sub GenLabel {
+
+ my $I;
+ my $L = "";;
+ my $Num = $LabelNum++;
+
# Generate the label
- return sprintf ("L%06X", $LabelNum++);
+ for ($I = 0; $I < 4; $I++) {
+ $L = $NameTab[$Num % 36] . $L;
+ $Num /= 36;
+ }
+ return $L;
}
# Make an output file name from an input file name
return $S;
}
+# Strip a path from a filename and return just the name
+sub StripPath {
+
+ # Filename is argument
+ my $FileName = $_[0];
+
+ # Remove a path name if we have one
+ $FileName =~ /^(.*?)([^\/]*)$/;
+ return $2;
+}
+
#-----------------------------------------------------------------------------#
-# Document header and footer #
+# Document header and footer #
# ----------------------------------------------------------------------------#
<p><br><p>
<hr size=1 noshade>
<address>
- <a href=\"http://validator.w3.org/check/referer\"><img border=0
- src=\"http://validator.w3.org/images/vh40\"
- alt=\"Valid HTML 4.0!\" height=31 width=88 align=right></a>
- $Name; generated on $Today by ca65html<br>
- <a href=\"mailto:uz\@cc65.org\">uz\@cc65.org</a>
+<a href="http://validator.w3.org/check/referer"><img border=0 src="http://validator.w3.org/images/vh40" alt="Valid HTML 4.0!" height=31 width=88 align=right></a>
+$Name; generated on $Today by ca65html<br>
+<a href=\"mailto:uz\@cc65.org\">uz\@cc65.org</a>
</address>
</body>
</html>
# Argument is file to add
my $FileName = $_[0];
- # Remove a path name if we have one
- $FileName =~ /^(.*?)([^\/]*)$/;
- my $Path = $1;
- my $Name = $2;
+ # Get just the name (remove a path if there is one)
+ my $Name = StripPath ($FileName);
# Check if we have the file already
if (exists ($Files{$Name})) {
- Gabble ("File \"$FileName\" already known");
- return;
+ Gabble ("File \"$FileName\" already known");
+ return;
}
# Check with the full pathname. If we don't find it, search in the current
# directory
if (-f $FileName && -r $FileName) {
- $Files{$Name} = $FileName;
- $FileCount++;
+ $Files{$Name} = $FileName;
+ $FileCount++;
} elsif (-f $Name && -r $Name) {
- $Files{$Name} = $Name;
- $FileCount++;
+ $Files{$Name} = $Name;
+ $FileCount++;
} else {
Abort ("$FileName not found or not readable");
}
#-----------------------------------------------------------------------------#
-# Referencing and defining labels #
+# Referencing and defining labels #
# ----------------------------------------------------------------------------#
#-----------------------------------------------------------------------------#
-# Pass 1 #
+# Pass 1 #
# ----------------------------------------------------------------------------#
my $FileName = $Files{$InName}; # Includes path if needed
open (INPUT, "<$FileName") or Abort ("Cannot open $FileName: $!");
+ # Keep the user happy
+ Gabble ("$FileName => $OutName");
+
# Read and process all lines from the file
while ($Line = <INPUT>) {
# Pass1: Read all files for the first time.
sub Pass1 () {
+ # Keep the user happy
+ Gabble ("Pass 1");
+
# Walk over the files
for my $InName (keys (%Files)) {
-
# Process one file
Process1 ($InName);
-
}
}
open (INPUT, "<$FileName") or Abort ("Cannot open $FileName: $!");
# Open the output file and print the HTML header
- open (OUTPUT, ">$OutName") or Abort ("Cannot open $OutName: $!");
+ open (OUTPUT, ">$HTMLDir$OutName") or Abort ("Cannot open $OutName: $!");
DocHeader (OUTPUT, $InName);
+ # Keep the user happy
+ Gabble ("$FileName => $OutName");
+
# The instructions that will have hyperlinks if a label is used
my $Ins = "adc|add|and|bcc|bcs|beq|bit|bmi|bne|bpl|bcv|bra|bvs|".
"cmp|cpx|cpy|dec|eor|inc|jmp|jsr|lda|ldx|ldy|ora|rol|".
$Line = $2;
# Variable to assemble HTML representation
- my $Item = $Id;
+ my $Contents = "";
+
+ # Make this import a link target
+ if (exists ($Imports{$OutName}{$Id})) {
+ $Label = $Imports{$OutName}{$1};
+ $Contents .= sprintf (" name=\"%s\"", $Label);
+ }
# If we have an export for this import, add a link to this
# export definition
if (exists ($Exports{$Id})) {
$Label = $Exports{$Id};
- $Item = sprintf ("<a href=\"%s\">%s</a>", $Label, $Item);
+ $Contents .= sprintf (" href=\"%s\"", $Label);
}
- # Make this import a link target
- if (exists ($Imports{$OutName}{$Id})) {
- $Label = $Imports{$OutName}{$1};
- $Item = sprintf ("<a name=\"%s\">%s</a>", $Label, $Item);
+ # Add the HTML stuff to the output line
+ if ($Contents ne "") {
+ $OutLine .= sprintf ("<a%s>%s</a>", $Contents, $Id);
+ } else {
+ $OutLine .= $Id;
}
- # Add the HTML stuff to the output line
- $OutLine .= $Item;
-
# Check if another identifier follows
if ($Line =~ /^(\s*),(\s*)(.*)$/) {
$OutLine .= "$1,$2";
$Line = $2;
# Variable to assemble HTML representation
- my $Item = $Id;
+ my $Contents = "";
# If we have a definition for this export in this file, add
# a link to the definition.
if (exists ($Labels{$OutName}{$1})) {
$Label = $Labels{$OutName}{$1};
- $Item = sprintf ("<a href=\"#%s\">%s</a>", $Label, $Item);
+ $Contents = sprintf (" href=\"#%s\"", $Label);
}
# If we have this identifier in the list of exports, add a
if (exists ($Exports{$Id})) {
$Label = $Exports{$Id};
# Be sure to use only the label part
- $Label =~ s/^(.*#)(.*)$/$2/;
- $Item = sprintf ("<a name=\"%s\">%s</a>", $Label, $Item);
+ $Label =~ s/^(.*#)(.*)$/$2/; # ##FIXME: Expensive
+ $Contents .= sprintf (" name=\"%s\"", $Label);
}
# Add the HTML stuff to the output line
- $OutLine .= $Item;
+ if ($Contents ne "") {
+ $OutLine .= sprintf ("<a%s>%s</a>", $Contents, $Id);
+ } else {
+ $OutLine .= $Id;
+ }
# Check if another identifier follows
if ($Line =~ /^(\s*),(\s*)(.*)$/) {
# Cleanup the remainder and add it
$OutLine .= Cleanup ($Line);
+ # Handle .include
+ } elsif ($Line =~ /^(\.include)(\s+)\"((?:[^\"]+?|\\\")+)\"(\s*)(;.*$|$)/) {
+
+ # Add the fixed stuff to the output line
+ $OutLine .= "$1$2\"";
+
+ # Get the filename into a named variable
+ my $FileName = $3;
+
+ # Remember the remainder
+ $Line = "\"$4$5";
+
+ # Get the name without a path
+ my $Name = StripPath ($FileName);
+
+ # We don't need FileName any longer as is, so clean it up
+ $FileName = Cleanup ($FileName);
+
+ # If the include file is among the list of our files, add a link,
+ # otherwise just add the name as is.
+ if (exists ($Files{$Name})) {
+ $OutLine .= sprintf ("<a href=\"%s\">%s</a>", GetOutName ($Name), $FileName);
+ } else {
+ $OutLine .= $FileName;
+ }
+
+ # Add the remainder
+ $OutLine .= Cleanup ($Line);
+
# Check for any legal instruction
} elsif ($Line =~ /^($Ins)(\s+)(.*?)(\s*)(;.*$|$)/) {
# Pass2: Read all files the second time.
sub Pass2 () {
+ # Keep the user happy
+ Gabble ("Pass 2");
+
# Walk over the files
for my $InName (keys (%Files)) {
-
# Process one file
Process2 ($InName);
-
}
}
sub CreateIndex {
# Open the index page file
- open (INDEX, ">$IndexName") or Abort ("Cannot open $IndexName: $!");
+ open (INDEX, ">$HTMLDir$IndexName") or Abort ("Cannot open $IndexName: $!");
# Print the header
print INDEX <<"EOF";
ExportIndex (INDEX);
# Print the document footer
- my $Today = localtime;
- print INDEX <<"EOF";
-<p><br><p>
-<hr size=1 noshade>
-<address>
- <a href="http://validator.w3.org/check/referer"><img border=0
- src="http://validator.w3.org/images/vh40"
- alt="Valid HTML 4.0!" height="31" width="88" align=right></a>
- $IndexName; generated on $Today by ca65html<br>
- <a href=\"mailto:uz\@cc65.org\">uz\@cc65.org</a>
-</address>
-</body>
-</html>
-EOF
+ DocFooter (INDEX, $IndexName);
# Close the index file
close (INDEX);
sub Usage {
print "Usage: ca65html [options] file ...\n";
print "Options:\n";
- print "\t--bgcolor c\tUse background color c instead of $BGColor\n";
- print "\t--help\t\tThis text\n";
- print "\t--indexcols n\tUse n columns on index page (default $IndexCols)\n";
- print "\t--indexname f\tUse name f for the index file instead of $IndexName\n";
- print "\t--indexpage\tCreate an index page\n";
- print "\t--indextitle t\tUse t as the index title instead of $IndexTitle\n";
- print "\t--linkstyle s\tUse the given link style\n";
- print "\t--replaceext\tReplace source extension instead of appending .html\n";
- print "\t--textcolor c\tUse text color c instead of $TextColor\n";
- print "\t--verbose\tBe more verbose\n";
+ print " --bgcolor color Use background color c instead of $BGColor\n";
+ print " --help This text\n";
+ print " --htmldir dir Specify directory for HTML files\n";
+ print " --indexcols n Use n columns on index page (default $IndexCols)\n";
+ print " --indexname file Use file for the index file instead of $IndexName\n";
+ print " --indexpage Create an index page\n";
+ print " --indextitle title Use title as the index title instead of $IndexTitle\n";
+ print " --linkstyle style Use the given link style\n";
+ print " --replaceext Replace source extension instead of appending .html\n";
+ print " --textcolor color Use text color c instead of $TextColor\n";
+ print " --verbose Be more verbose\n";
}
GetOptions ("bgcolor=s" => \$BGColor,
"debug!" => \$Debug,
"help" => \$Help,
+ "htmldir=s" => \$HTMLDir,
"indexcols=i" => \$IndexCols,
"indexname=s" => \$IndexName,
"indexpage" => \$IndexPage,
if ($IndexCols <= 0 || $IndexCols >= 20) {
Abort ("Invalid value for --indexcols option");
}
+if ($HTMLDir ne "" && $HTMLDir =~ /[^\/]$/) {
+ # Add a trailing path separator
+ $HTMLDir .= "/";
+}
+
+
# Print help if requested
if ($Help) {