1
0
mirror of https://github.com/cc65/cc65.git synced 2025-02-09 17:33:00 +00:00

Patch for ca65html by Greg King:

The "ca65html.sgml" patch:
1) Removes text that says that the colorize option is non-standard.
2) Corrects the information about what is put on the index page.

The "ca65html" patch:
1) Looks for "?" and "@" at the front of cheap local labels.
2) Handles label assignment statements.
3) Parses many more ca65 dot-directives.
4) Handles every official op-code mnemonic that ca65 knows.
5) Recognizes both upper- and lower-case directives and mnemonics.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3810 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2008-02-20 17:27:19 +00:00
parent 94f3a578a5
commit f1ea61581f
2 changed files with 204 additions and 132 deletions

View File

@ -3,10 +3,10 @@
<article> <article>
<title>ca65html Users Guide <title>ca65html Users Guide
<author>Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org"> <author>Ullrich von Bassewitz, <htmlurl url="mailto:uz@cc65.org" name="uz@cc65.org">
<date>2003-10-16 <date>2007-10-2
<abstract> <abstract>
ca65html is an assembler source to HTML converter. It is very useful if you ca65html is an assembly-source-to-HTML converter. It is very useful if you
want to publish your assembler sources in the web. want to publish your assembler sources in the web.
</abstract> </abstract>
@ -17,11 +17,11 @@ want to publish your assembler sources in the web.
<sect>Overview<p> <sect>Overview<p>
ca65html converts assembler source files written for use with the <tt/<htmlurl ca65html converts assembly source files written for use with the <tt/<url
url="ca65.html" name="ca65">/ crossassembler into HTML. It is a standalone url="ca65.html" name="ca65">/ crossassembler into HTML. It is a standalone
tool written in Perl, and as such it does not understand the structure of tool written in PERL; and as such, it does not understand the structure of
assembler sources in the same depth as ca65 does, so it may fail in very rare assembler sources in the same depth as ca65 does, so it may fail in very rare
cases. In all other cases it generates very nice output. cases. In all other cases, it generates very nice output.
<sect>Usage<p> <sect>Usage<p>
@ -36,7 +36,7 @@ The HTML converter accepts the following options:
Usage: ca65html [options] file ... Usage: ca65html [options] file ...
Options: Options:
--bgcolor c Use background color c instead of #FFFFFF --bgcolor c Use background color c instead of #FFFFFF
--colorize Colorize the output (generates non standard HTML) --colorize Add color highlights to the output
--commentcolor c Use color c for comments instead of #B22222 --commentcolor c Use color c for comments instead of #B22222
--crefs Generate references to the C source file(s) --crefs Generate references to the C source file(s)
--ctrlcolor c Use color c for directives instead of #228B22 --ctrlcolor c Use color c for directives instead of #228B22
@ -67,28 +67,23 @@ Here is a description of all the command line options:
<tag><tt>--bgcolor c</tt></tag> <tag><tt>--bgcolor c</tt></tag>
Set the background color. The argument c must be a valid HTML color, usually Set the background color. The argument c must be a valid HTML color, usually
given as RGB triplet in the form <tt/#rrggbb/, where r, g and b are the given as RGB triplet in the form <tt/#rrggbb/, where r, g, and b are the
respective red, green and blue parts as two digit hex values. The default is respective red, green, and blue parts as two-digit hex values. The default is
<tt/#FFFFFF/ (white). This color is used in the <tt/&lt;body&gt;/ tag of the <tt/#FFFFFF/ (white). That color is used in the <tt/&lt;body&gt;/ of the
generated HTML output. generated HTML output.
<tag><tt>--colorize</tt></tag> <tag><tt>--colorize</tt></tag>
Colorize the output. The converter outputs processor instructions, assembler Colorize the output. The converter outputs processor instructions, assembler
control commands and comments in different colors. control commands, and comments in different colors.
While this make the output look very nice, it generates invalid HTML,
because using colors in a <tt/&lt;pre&gt;/ environment is not allowed.
However, most browsers display it well, and it is used by several other
tools, so it's up to you.
<tag><tt>--commentcolor c</tt></tag> <tag><tt>--commentcolor c</tt></tag>
Set the color used for comments. The argument c must be a valid HTML color, Set the color used for comments. The argument c must be a valid HTML color,
usually given as RGB triplet in the form <tt/#rrggbb/, where r, g and b are usually given as RGB triplet in the form <tt/#rrggbb/, where r, g, and b are
the respective red, green and blue parts as two digit hex values. The the respective red, green, and blue parts as two-digit hex values. The
default is <tt/#B22222/ (red). default is <tt/#B22222/ (red).
Note that this option has no effect if <tt/--colorize/ is not also given. Note that this option has no effect if <tt/--colorize/ is not also given.
@ -109,7 +104,7 @@ Here is a description of all the command line options:
Set the color used for assembler control commands. The argument c must be a Set the color used for assembler control commands. The argument c must be a
valid HTML color, usually given as RGB triplet in the form <tt/#rrggbb/, valid HTML color, usually given as RGB triplet in the form <tt/#rrggbb/,
where r, g and b are the respective red, green and blue parts as two digit where r, g, and b are the respective red, green, and blue parts as two-digit
hex values. The default is <tt/#228B22/ (green). hex values. The default is <tt/#228B22/ (green).
Note that this option has no effect if <tt/--colorize/ is not also given. Note that this option has no effect if <tt/--colorize/ is not also given.
@ -146,7 +141,7 @@ Here is a description of all the command line options:
<tag><tt>--indexpage</tt></tag> <tag><tt>--indexpage</tt></tag>
Causes the converter to generate an index page listing all label names and Causes the converter to generate an index page listing file names, and all
exports found in the converted files. exports found in the converted files.
@ -160,7 +155,7 @@ Here is a description of all the command line options:
Set the color used for processor instructions. The argument c must be a Set the color used for processor instructions. The argument c must be a
valid HTML color, usually given as RGB triplet in the form <tt/#rrggbb/, valid HTML color, usually given as RGB triplet in the form <tt/#rrggbb/,
where r, g and b are the respective red, green and blue parts as two digit where r, g, and b are the respective red, green, and blue parts as two-digit
hex values. The default is <tt/#A020F0/ (purple). hex values. The default is <tt/#A020F0/ (purple).
Note that this option has no effect if <tt/--colorize/ is not also given. Note that this option has no effect if <tt/--colorize/ is not also given.
@ -197,17 +192,17 @@ Here is a description of all the command line options:
<tag><tt>--textcolor c</tt></tag> <tag><tt>--textcolor c</tt></tag>
Set the color for normal text. The argument c must be a valid HTML color, Set the color for normal text. The argument c must be a valid HTML color,
usually given as RGB triplet in the form <tt/#rrggbb/, where r, g and b are usually given as RGB triplet in the form <tt/#rrggbb/, where r, g, and b are
the respective red, green and blue parts as two digit hex values. The the respective red, green, and blue parts as two-digit hex values. The
default is <tt/#000000/ (black). This color is used in the <tt/&lt;body&gt;/ default is <tt/#000000/ (black). This color is used in the <tt/&lt;body&gt;/
tag of the generated HTML output. of the generated HTML output.
<tag><tt>--verbose</tt></tag> <tag><tt>--verbose</tt></tag>
Increase the converter verbosity. Without this option, ca65html is quiet Increase the converter verbosity. Without this option, ca65html is quiet
when working. If you have a slow machine and lots of files to convert, you when working. If you have a slow machine and lots of files to convert, you
may like a little bit more progress information. might like a little bit more progress information.
</descrip> </descrip>
<p> <p>
@ -233,26 +228,22 @@ cases.
Since ca65html does not really parse the input, but does most of its work Since ca65html does not really parse the input, but does most of its work
applying text patterns, it doesn't know anything about scoping and advanced applying text patterns, it doesn't know anything about scoping and advanced
features of the assembler. This means that it may miss a label may choose the features of the assembler. This means that it might miss a label. And, it
wrong color for an item in rare cases. Since it's just a tool for displaying might choose the wrong color for an item, in rare cases. Because it's just a
sources in a nice form, I think that's ok. Anyway, if you find a conversion tool for displaying sources in a nice form, I think that's OK. Anyway, if you
problem, you can send me a short piece of example input code. If possible, I find a conversion problem, you can send me a short piece of example input code.
will fix it. If possible, I will fix it.
<sect1>Colorization<p> <sect1>Colorization<p>
While having colors in the output looks really nice, it has two drawbacks: While having colors in the output looks really nice, it has one drawback:
<enum> <enum>
<item>The output is not standard compliant HTML, because <tt/&lt;font&gt;/ <item>Because lots of <tt/&lt;span&gt;/ tags are created in the output,
tags are use in a <tt/&lt;pre&gt;/ environment. This works with all browsers the size of the output file literally will explode. It seems to be the price
I've tested, but it may not work with the one you're using. that you have to pay for color.
<item>Since lots of <tt/&lt;font&gt;/ tags are created in the output, the size
of the output file will literally explode. This seems to be the price, you
have to pay for color...
</enum> </enum>
@ -268,7 +259,7 @@ name="uz@cc65.org">).
<sect>Copyright<p> <sect>Copyright<p>
ca65html is (C) Copyright 2000-2003 Ullrich von Bassewitz. For its use the ca65html is (c) Copyright 2000-2007 Ullrich von Bassewitz. For its use, the
following conditions apply: following conditions apply:
This software is provided 'as-is', without any expressed or implied This software is provided 'as-is', without any expressed or implied

View File

@ -1,7 +1,7 @@
#!/usr/bin/perl #!/usr/bin/perl
############################################################################### ###############################################################################
# # # #
# main.c # # ca65html #
# # # #
# Convert a ca65 source into HTML # # Convert a ca65 source into HTML #
# # # #
@ -36,10 +36,10 @@
# Things currently missing: # Things currently missing:
# #
# - Scoping with .proc/.endproc # - Scoping with .proc/.endproc, .scope/.endscope, .enum/.endenum,
# .struct/.endstruct, .union/endunion, .repeat/.endrep, .local
# - .global is ignored # - .global is ignored
# - .constructor/.destructor/.condes dito # - .case is ignored, labels are always case-sensitive
# - .ignorecase is ignored, labels are always case sensitive
# - .include handling (difficult) # - .include handling (difficult)
# - The global namespace operator :: # - The global namespace operator ::
# #
@ -92,10 +92,7 @@ my $TextColor = "#000000"; # Text color
my $Verbose = 0; # Be quiet my $Verbose = 0; # Be quiet
# Table used to convert the label number into names # Table used to convert the label number into names
my @NameTab = ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", my @NameTab = ('A' .. 'Z', '0' .. '9');
"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");
@ -147,7 +144,7 @@ sub GetOutName {
} }
} }
# Remove illegal characters from a string # Translate some HTML characters into harmless names.
sub Cleanup { sub Cleanup {
my $S = shift (@_); my $S = shift (@_);
$S =~ s/&/&amp;/g; $S =~ s/&/&amp;/g;
@ -246,15 +243,13 @@ sub DocFooter {
my $Today = localtime; my $Today = localtime;
# Print # Print
print $OUT "<div id=\"bottom\">\n"; print $OUT "<div id=\"bottom\"><address>\n";
print $OUT "<address>\n"; print $OUT "<a href=\"http://validator.w3.org/check?uri=referer\">\n";
print $OUT "<a href=\"http://validator.w3.org/check?uri=referer\"><img src=\"http://www.w3.org/Icons/valid-xhtml10-blue\" alt=\"Valid XHTML 1.0 Strict\" height=\"31\" width=\"88\" /></a>"; print $OUT "<img src=\"http://www.w3.org/Icons/valid-xhtml10-blue\" alt=\"Valid XHTML 1.0 Strict\" height=\"31\" width=\"88\" /></a><br>\n";
print $OUT "$Name; generated on $Today by ca65html<br>\n"; print $OUT "$Name; generated on $Today by ca65html<br>\n";
print $OUT "<a href=\"mailto:uz&#64;cc65.org\">uz&#64;cc65.org</a>\n"; print $OUT "<a href=\"mailto:uz&#64;cc65.org\">uz&#64;cc65.org</a>\n";
print $OUT "</address>\n"; print $OUT "</address></div>\n";
print $OUT "</div>\n"; print $OUT "</body></html>\n";
print $OUT "</body>\n";
print $OUT "</html>\n";
} }
@ -424,15 +419,15 @@ sub Process1 {
chomp ($Line); chomp ($Line);
# Check for a label # Check for a label
if ($Line =~ /^\s*(\@?)([_a-zA-Z]\w*)(:(?!=)|\s*:?=)/) { if ($Line =~ /^\s*(([\@?]?)[_a-zA-Z]\w*)\s*(?::=?|=)/) {
# Is this a local label? # Is this a local label?
if ($1 eq "\@") { if ($2 ne "") {
# Use the prefix # Use the prefix
$Id = "$CheapPrefix$1$2"; $Id = "$CheapPrefix$1";
} else { } else {
# Use as is # Use as is
$Id = $2; $Id = $1;
# Remember the id as new cheap local prefix # Remember the id as new cheap local prefix
$CheapPrefix = $Id; $CheapPrefix = $Id;
} }
@ -441,32 +436,43 @@ sub Process1 {
$Labels{$OutName}{$Id} = GenLabel(); $Labels{$OutName}{$Id} = GenLabel();
# Check for an import statement # Check for an import statement
} elsif ($Line =~ /^\s*(\.import|\.importzp)\s+(.*?)(\s*)(;.*$|$)/) { } elsif ($Line =~ /^\s*\.(?:(?:force)?import|importzp)\s+(.*?)\s*(?:;.*)?$/i) {
# Split into a list of identifiers # Split into a list of identifiers
my @Ids = split (/\s*,\s*/, $2); my @Ids = split (/\s*(?::\s*[A-Za-z]+\s*)?,\s*/, $1);
# Remove an address-size specifier, from the last identifier,
# if there is one.
$Ids[$#Ids] =~ s/\s*:\s*[A-Za-z]+//;
for $Id (@Ids) { for $Id (@Ids) {
$Imports{$OutName}{$Id} = GenLabel(); $Imports{$OutName}{$Id} = GenLabel();
} }
# Check for an export statement # Check for an export statement
} elsif ($Line =~ /^\s*(\.export|\.exportzp)\s+(.*?)(\s*)(;.*$|$)/) { } elsif ($Line =~ /^\s*\.export(?:zp)?\s+(.*?)\s*(?:;.*)?$/i) {
# Split into a list of identifiers # Split into a list of identifiers
my @Ids = split (/\s*,\s*/, $2); my @Ids = split (/\s*(?::\s*[A-Za-z]+\s*)?,\s*/, $1);
# Remove an address-size specifier, from the last identifier,
# if there is one.
$Ids[$#Ids] =~ s/\s*:\s*[A-Za-z]+//;
for $Id (@Ids) { for $Id (@Ids) {
$Exports{$Id} = sprintf ("%s#%s", $OutName, GenLabel()); $Exports{$Id} = sprintf ("%s#%s", $OutName, GenLabel());
} }
# Check for an actor statement.
} elsif ($Line =~ /^\s*\.(?:(?:(?:con|de)struc|interrup)tor|condes)\s+([_a-z]\w*)/i) {
$Exports{$1} = sprintf ("%s#%s", $OutName, GenLabel());
# Check for a .proc statement # Check for a .proc statement
} elsif ($Line =~ /^\s*\.proc\s+([_a-zA-Z]\w*)?.*$/) { } elsif ($Line =~ /^\s*\.proc\s+([_a-z]\w*)/i) {
# Do we have an id?
$Id = $1;
if ($Id ne "") {
$Labels{$OutName}{$Id} = GenLabel();
}
# Remember the ID as the new cheap-local prefix.
$CheapPrefix = $1;
$Labels{$OutName}{$1} = GenLabel();
} }
} }
@ -507,7 +513,6 @@ sub Process2 {
my $OutLine; my $OutLine;
my $Id; my $Id;
my $Label; my $Label;
my $Operand;
my $Comment; my $Comment;
my $Trailer; my $Trailer;
@ -532,25 +537,25 @@ sub Process2 {
# Keep the user happy # Keep the user happy
Gabble ("$FileName => $OutName"); Gabble ("$FileName => $OutName");
# The instructions that will have hyperlinks if a label is used # The instructions that will have hyperlinks if a label is used.
my $LabelIns = "adc|add|and|asl|bcc|bcs|beq|bit|bmi|bne|bpl|bra|bvc|bvs|". # And, they will be highlighted when color is used.
"cmp|cpx|cpy|dec|eor|inc|jmp|jsr|lda|ldx|ldy|lsr|ora|rol|". my $LabelIns = "adc|add|and|asl|bb[rs][0-7]|b[cv][cs]|beq|bge|bit|blt|".
"ror|sbc|sta|stx|sty|stz|sub|"; "bmi|bne|bpl|br[akl]|bsr|cmp|cop|cp[axy]|dec|eor|inc|jml|".
"jmp|jsl|jsr|ld[axy]|lsr|mvn|mvp|ora|pe[air]|rep|".
"[rs]mb[0-7]|rol|ror|sbc|sep|st[012axyz]|sub|tai|tam|tdd|".
"ti[ain]|tma|trb|tsb|tst";
# The instructions that will have hyperlinks if a label is used # Instructions that have only the implied-addressing mode -- therefore,
my $AllIns = "adc|add|and|asl|bcc|bcs|beq|bge|bit|blt|bmi|bne|bpl|bvc|". # no hyperlinking. They will be highlighted only, when color is used.
"bra|brk|brl|bvs|clc|cld|cli|clv|cmp|cop|cpa|cpx|cpy|dea|". my $OtherIns = "cl[acdivxy]|csh|csl|de[axy]|in[axy]|nop|ph[abdkpxy]|".
"dec|dex|dey|eor|ina|inc|inx|iny|jml|jmp|jsl|jsr|lda|ldx|". "pl[abdpxy]|rt[ils]|sax|say|se[cdit]|stp|swa|sxy|ta[dsxy]|".
"ldy|lsr|mvn|mvp|nop|ora|pea|pei|per|pha|phb|phd|phk|php|". "tam[0-7]|tcd|tcs|tda|tdc|tma[0-7]|ts[acx]|tx[asy]|tya|tyx|".
"phx|phy|pla|plb|pld|plp|plx|ply|rep|rol|ror|rti|rtl|rts|".
"sbc|sec|sed|sei|sep|sta|stx|sty|stz|sub|swa|tad|tax|tay|".
"tcd|tcs|tda|tdc|trb|tsa|tsb|tsc|tsx|txa|txs|txy|tya|tyx|".
"wai|xba|xce"; "wai|xba|xce";
# Read the input file, replacing references by hyperlinks and mark # Read the input file, replacing references with hyperlinks; and, mark
# labels as link targets. # labels as link targets.
my $LineNo = 0; my $LineNo = 0;
while ($Line = <INPUT>) { LINE: while ($Line = <INPUT>) {
# Count input lines # Count input lines
$LineNo++; $LineNo++;
@ -594,16 +599,16 @@ sub Process2 {
$Trailer = $& . ColorizeComment (Cleanup ($Comment)); $Trailer = $& . ColorizeComment (Cleanup ($Comment));
# Check for a label at the start of the line. If we have one, process # Check for a label at the start of the line. If we have one, process
# it and remove it from the line # it, and remove it from the line.
if ($Line =~ s/^\s*?(\@?)([_a-zA-Z]\w*)(:(?!=)|\s*:?=)//) { if ($Line =~ s/^\s*?(([\@?]?)[_a-zA-Z]\w*)(\s*(?::=?|=))//) {
# Is this a local label? # Is this a local label?
if ($1 eq "\@") { if ($2 ne "") {
# Use the prefix # Use the prefix
$Id = "$CheapPrefix$1$2"; $Id = "$CheapPrefix$1";
} else { } else {
# Use as is # Use as is
$Id = $2; $Id = $1;
# Remember the id as new cheap local prefix # Remember the id as new cheap local prefix
$CheapPrefix = $Id; $CheapPrefix = $Id;
} }
@ -612,7 +617,26 @@ sub Process2 {
$Label = $Labels{$OutName}{$Id}; $Label = $Labels{$OutName}{$Id};
# Print the label with a tag # Print the label with a tag
$OutLine .= sprintf ("<a name=\"%s\">%s%s</a>%s", $Label, $1, $2, $3); $OutLine .= "<a name=\"$Label\">$1</a>$3";
# Is the name explicitly assigned a value?
if ($3 =~ /=$/) {
# Print all identifiers if there are any.
while ($Line =~ s/^([^_a-zA-Z]*?)(([\@?]?)[_a-zA-Z]\w*)//) {
# Add the non-label stuff.
$OutLine .= Cleanup ($1);
# Use the prefix if the label is local.
# Get the reference to that label if we find it.
$OutLine .= RefLabel ($OutName, ($3 ne "") ? "$CheapPrefix$2" : $2, $2);
}
# Add a remainder if there is one.
$OutLine .= Cleanup ($Line);
# The line is complete; print it.
next LINE;
}
} }
# Print any leading whitespace and remove it, so we don't have to # Print any leading whitespace and remove it, so we don't have to
@ -622,7 +646,7 @@ sub Process2 {
} }
# Handle the import statements # Handle the import statements
if ($Line =~ s/^(\.import|\.importzp)\s+//) { if ($Line =~ s/^\.(?:(?:force)?import|importzp)\s+//i) {
# Print any fixed stuff from the line and remove it # Print any fixed stuff from the line and remove it
$OutLine .= $&; $OutLine .= $&;
@ -657,7 +681,7 @@ sub Process2 {
} }
# Check if another identifier follows # Check if another identifier follows
if ($Line =~ s/^\s*,\s*//) { if ($Line =~ s/^\s*(?::\s*[A-Za-z]+\s*)?,\s*//) {
$OutLine .= $&; $OutLine .= $&;
} else { } else {
last; last;
@ -668,9 +692,9 @@ sub Process2 {
$OutLine .= Cleanup ($Line); $OutLine .= Cleanup ($Line);
# Handle export statements # Handle export statements
} elsif ($Line =~ s/^(\.export|\.exportzp)\s+//) { } elsif ($Line =~ s/^\.export(?:zp)?\s+//i) {
# Print the command the and white space # Print the command and the whitespace.
$OutLine .= $&; $OutLine .= $&;
# Print all identifiers if there are any # Print all identifiers if there are any
@ -706,7 +730,7 @@ sub Process2 {
} }
# Check if another identifier follows # Check if another identifier follows
if ($Line =~ s/^\s*,\s*//) { if ($Line =~ s/^\s*(?::\s*[A-Za-z]+\s*)?,\s*//) {
$OutLine .= $&; $OutLine .= $&;
} else { } else {
last; last;
@ -716,37 +740,62 @@ sub Process2 {
# Add an remainder if there is one # Add an remainder if there is one
$OutLine .= Cleanup ($Line); $OutLine .= Cleanup ($Line);
# Check for .addr and .word # Handle actor statements.
} elsif ($Line =~ s/^(\.addr|\.word)\s+//) { } elsif ($Line =~ s/^(\.(?:(?:(?:con|de)struc|interrup)tor|condes)\s+)([_a-z]\w*)//i) {
# Print the command and the whitespace.
$OutLine .= $1;
# Remember the identifier.
$Id = $2;
# Variable to assemble HTML representation
my $Contents = "";
# If we have a definition for this actor, in this file,
# then add a link to that definition.
if (exists ($Labels{$OutName}{$Id})) {
$Contents = sprintf (" href=\"#%s\"", $Labels{$OutName}{$Id});
}
# Get the target, for linking from imports in other files.
$Label = $Exports{$Id};
# Be sure to use only the label part.
$Label =~ s/^.*#//;
# Add the HTML stuff and the remainder of the actor
# to the output line.
$OutLine .= sprintf ("<a name=\"%s\"%s>%s</a>%s", $Label,
$Contents, $Id, Cleanup ($Line));
# Check for .faraddr, .addr, .dword, .word, .dbyt, .byt, .byte, .res,
# .elseif, .if, .align, and .org.
} elsif ($Line =~ s/^\.(?:(?:far)?addr|d?word|d?byte?|res|(?:else)?if|align|org)\s+//i) {
# Print the command and the white space # Print the command and the white space
$OutLine .= $&; $OutLine .= $&;
# Print all identifiers if there are any # Print all identifiers if there are any
while ($Line =~ /^([^_a-zA-Z]*)([_a-zA-Z]\w*)(.*)$/) { while ($Line =~ s/^([^_a-zA-Z]*?)(([\@?]?)[_a-zA-Z]\w*)//) {
# Add the non label stuff # Add the non label stuff
$OutLine .= Cleanup ($1); $OutLine .= Cleanup ($1);
# If the identifier is a known label, add a link # Use the prefix if the label is local.
if (exists ($Labels{$OutName}{$2})) { # Get the reference to that label if we find it.
$Label = $Labels{$OutName}{$2}; $OutLine .= RefLabel ($OutName, ($3 ne "") ? "$CheapPrefix$2" : $2, $2);
$OutLine .= sprintf ("<a href=\"#%s\">%s</a>", $Label, $2);
} else {
$OutLine .= $2;
}
# Proceed with the remainder of the line
$Line = $3;
} }
# Add an remainder if there is one # Add an remainder if there is one
$OutLine .= Cleanup ($Line); $OutLine .= Cleanup ($Line);
# Handle .proc # Handle .proc
} elsif ($Line =~ /^(\.proc)(\s+)([_a-zA-Z]\w*)?(.*)$/) { } elsif ($Line =~ /^(\.proc)(\s+)([_a-z]\w*)?(.*)$/i) {
# Do we have an identifier? # Do we have an identifier?
if ($3 ne "") { if ($3 ne "") {
# Remember the ID as the new cheap-local prefix.
$CheapPrefix = $3;
# Get the label for the id # Get the label for the id
$Label = $Labels{$OutName}{$3}; $Label = $Labels{$OutName}{$3};
@ -755,16 +804,16 @@ sub Process2 {
} else { } else {
# Print the label # Print a line that has invalid syntax (its operand isn't
$OutLine .= "$1$2$3"; # a correctly formed name).
$OutLine .= "$1$2";
} }
# Add the remainder # Add the remainder
$OutLine .= Cleanup ($4); $OutLine .= Cleanup ($4);
# Handle .include # Handle .include
} elsif ($Line =~ /^(\.include)(\s+)\"((?:[^\"]+?|\\\")+)(\".*)$/) { } elsif ($Line =~ /^(\.include)(\s*)\"((?:[^\"]+?|\\\")+)(\".*)$/i) {
# Add the fixed stuff to the output line # Add the fixed stuff to the output line
$OutLine .= "$1$2&quot;"; $OutLine .= "$1$2&quot;";
@ -860,37 +909,72 @@ sub Process2 {
# Add the remainder # Add the remainder
$OutLine .= Cleanup ($Line); $OutLine .= Cleanup ($Line);
# Check for .ifdef, .ifndef, .ifref, and .ifnref.
} elsif ($Line =~ s/^(\.ifn?[dr]ef\s+)(([\@?]?)[_a-z]\w*)?//i) {
# Print the command and the whitespace.
$OutLine .= $1;
if ($2 ne "") {
# Use the prefix if the label is local.
# Get the reference to that label if we find it.
$OutLine .= RefLabel ($OutName, ($3 ne "") ? "$CheapPrefix$2" : $2, $2);
}
# Add a remainder if there is one.
$OutLine .= Cleanup ($Line);
# Check for assertions.
} elsif ($Line =~ s/^(\.assert\s+)(.+?)(,\s*(?:error|warning)\s*(?:,.*)?)$/$2/i) {
# Print the command and the whitespace.
$OutLine .= $1;
$Comment = $3;
# Print all identifiers if there are any.
while ($Line =~ s/^([^_a-zA-Z]*?)(([\@?]?)[_a-zA-Z]\w*)//) {
# Add the non-label stuff.
$OutLine .= Cleanup ($1);
# Use the prefix if the label is local.
# Get the reference to that label if we find it.
$OutLine .= RefLabel ($OutName, ($3 ne "") ? "$CheapPrefix$2" : $2, $2);
}
# Add a remainder if there is one.
$OutLine .= Cleanup ($Line . $Comment);
# Check for instructions with labels # Check for instructions with labels
} elsif ($Line =~ /^($LabelIns)\b(\s+)(.*)$/) { } elsif ($Line =~ s/^($LabelIns)\b(\s*)//io) {
# Print the instruction and white space # Print the instruction and white space
$OutLine .= ColorizeKeyword ($1) . $2; $OutLine .= ColorizeKeyword ($1) . $2;
# Remember the remaining parts # Print all identifiers if there are any.
$Operand = $3; while ($Line =~ s/^([^_a-zA-Z]*?)(([\@?]?)[_a-zA-Z]\w*)//) {
# Check for the first identifier in the operand and replace it # Add the non-label stuff.
# by a hyperlink $OutLine .= Cleanup ($1);
if ($Operand =~ /^([^_a-zA-Z]*?)(\@?)([_a-zA-Z]\w*)(.*)$/) {
# Is this a local label? # Is this a local label?
if ($2 eq "\@") { if ($3 ne "") {
# Use the prefix # Use the prefix
$Id = "$CheapPrefix$2$3"; $Id = "$CheapPrefix$2";
} else { } else {
# Use as is # Use as is
$Id = $3; $Id = $2;
} }
# Get the reference to this label if we find it # Get the reference to this label if we find it
$Operand = Cleanup($1) . RefLabel($OutName, $Id, $2 . $3) . Cleanup($4); $OutLine .= RefLabel ($OutName, $Id, $2);
} }
# Reassemble and print the line # Reassemble and print the line
$OutLine .= $Operand; $OutLine .= Cleanup ($Line);
# Check for all other instructions # Check for all other instructions
} elsif ($Line =~ /^($AllIns)\b(.*)$/) { } elsif ($Line =~ /^($OtherIns)\b(.*)$/io) {
# Colorize and print # Colorize and print
$OutLine .= ColorizeKeyword ($1) . Cleanup ($2); $OutLine .= ColorizeKeyword ($1) . Cleanup ($2);
@ -902,14 +986,12 @@ sub Process2 {
} }
} continue {
# Colorize all keywords # Colorize all keywords
$OutLine =~ s/(?<![\w;])\.[_a-zA-Z]\w*/ColorizeCtrl ($&)/ge; $OutLine =~ s/(?<![\w;])\.[_a-zA-Z]\w*/ColorizeCtrl ($&)/ge;
# Add the trailer # Print the result with the trailer.
$OutLine .= $Trailer; print OUTPUT "$OutLine$Trailer\n";
# Print the result
print OUTPUT "$OutLine\n";
} }
# Print the HTML footer # Print the HTML footer
@ -1046,7 +1128,7 @@ sub Usage {
print "Usage: ca65html [options] file ...\n"; print "Usage: ca65html [options] file ...\n";
print "Options:\n"; print "Options:\n";
print " --bgcolor c Use background color c instead of $BGColor\n"; print " --bgcolor c Use background color c instead of $BGColor\n";
print " --colorize Colorize the output (generates non standard HTML)\n"; print " --colorize Add color highlights to the output\n";
print " --commentcolor c Use color c for comments instead of $CommentColor\n"; print " --commentcolor c Use color c for comments instead of $CommentColor\n";
print " --crefs Generate references to the C source file(s)\n"; print " --crefs Generate references to the C source file(s)\n";
print " --ctrlcolor c Use color c for directives instead of $CtrlColor\n"; print " --ctrlcolor c Use color c for directives instead of $CtrlColor\n";
@ -1129,4 +1211,3 @@ if ($IndexPage) {
# Done # Done
exit 0; exit 0;