Allowed character code zero to be remapped with other character codes.

This commit is contained in:
Greg King
2016-06-11 06:43:19 -04:00
parent e95d07aa97
commit 573381a340
8 changed files with 71 additions and 59 deletions

View File

@@ -4,7 +4,7 @@
<title>ca65 Users Guide <title>ca65 Users Guide
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
<url url="mailto:greg.king5@verizon.net" name="Greg King"> <url url="mailto:greg.king5@verizon.net" name="Greg King">
<date>2015-11-17 <date>2016-06-11
<abstract> <abstract>
ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is ca65 is a powerful macro assembler for the 6502, 65C02, and 65816 CPUs. It is
@@ -2170,16 +2170,15 @@ Here's a list of all control commands and a description, what they do:
<sect1><tt>.CHARMAP</tt><label id=".CHARMAP"><p> <sect1><tt>.CHARMAP</tt><label id=".CHARMAP"><p>
Apply a custom mapping for characters. The command is followed by two Apply a custom mapping for characters. The command is followed by two
numbers. The first one is the index of the source character (range 1..255), numbers. The first one is the index of the source character (range 0..255);
the second one is the mapping (range 0..255). The mapping applies to all the second one is the mapping (range 0..255). The mapping applies to all
character and string constants when they generate output, and overrides a character and string constants <em/when/ they generate output; and, overrides
mapping table specified with the <tt><ref id="option-t" name="-t"></tt> a mapping table specified with the <tt><ref id="option-t" name="-t"></tt>
command line switch. command line switch.
Example: Example:
<tscreen><verb> <tscreen><verb>
.charmap $41, $61 ; Map 'A' to 'a' .charmap $41, $61 ; Map 'A' to 'a'
</verb></tscreen> </verb></tscreen>

View File

@@ -4,7 +4,7 @@
<title>cc65 Users Guide <title>cc65 Users Guide
<author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline> <author><url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
<url url="mailto:gregdk@users.sf.net" name="Greg King"> <url url="mailto:gregdk@users.sf.net" name="Greg King">
<date>2016-04-22 <date>2016-06-11
<abstract> <abstract>
cc65 is a C compiler for 6502 targets. It supports several 6502 based home cc65 is a C compiler for 6502 targets. It supports several 6502 based home
@@ -478,15 +478,15 @@ Here is a description of all the command line options:
<label id="option-W"> <label id="option-W">
<tag><tt>-W name[,name]</tt></tag> <tag><tt>-W name[,name,...]</tt></tag>
This option allows to control warnings generated by the compiler. It is This option allows to control warnings generated by the compiler. It is
followed by a comma separated list of warnings that should be enabled or followed by a comma-separated list of warnings that should be enabled or
disabled. To disable a warning, its name is prefixed by a minus sign. If disabled. To disable a warning, its name is prefixed by a minus sign. If
no such prefix exists, or the name is prefixed by a plus sign, the warning no such prefix exists, or the name is prefixed by a plus sign, the warning
is enabled. is enabled.
The following warning names are currently recognized: The following warning names currently are recognized:
<descrip> <descrip>
<tag><tt/const-comparison/</tag> <tag><tt/const-comparison/</tag>
Warn if the result of a comparison is constant. Warn if the result of a comparison is constant.
@@ -494,10 +494,13 @@ Here is a description of all the command line options:
Treat all warnings as errors. Treat all warnings as errors.
<tag><tt/no-effect/</tag> <tag><tt/no-effect/</tag>
Warn about statements that don't have an effect. Warn about statements that don't have an effect.
<tag><tt/remap-zero/</tag>
Warn about a <tt/<ref id="pragma-charmap" name="#pragma charmap()">/
that changes a character's code number from/to 0x00.
<tag><tt/struct-param/</tag> <tag><tt/struct-param/</tag>
Warn when passing structs by value. Warn when passing structs by value.
<tag><tt/unknown-pragma/</tag> <tag><tt/unknown-pragma/</tag>
Warn about known #pragmas. Warn about #pragmas that aren't recognized by cc65.
<tag><tt/unused-label/</tag> <tag><tt/unused-label/</tag>
Warn about unused labels. Warn about unused labels.
<tag><tt/unused-param/</tag> <tag><tt/unused-param/</tag>
@@ -506,11 +509,11 @@ Here is a description of all the command line options:
Warn about unused variables. Warn about unused variables.
</descrip> </descrip>
The full list of available warning names may be retrieved by using the The full list of available warning names can be retrieved by using the
option <tt><ref id="option-list-warnings" name="--list-warnings"></tt>. option <tt><ref id="option-list-warnings" name="--list-warnings"></tt>.
You may also use <tt><ref id="pragma-warn" name="#pragma&nbsp;warn"></tt> to You may use also <tt><ref id="pragma-warn" name="#pragma&nbsp;warn"></tt> to
control this setting for smaller pieces of code from within your code. control this setting, for smaller pieces of code, from within your sources.
</descrip><p> </descrip><p>
@@ -931,34 +934,38 @@ parameter with the <tt/#pragma/.
<sect1><tt>#pragma charmap (&lt;index&gt;, &lt;code&gt;)</tt><label id="pragma-charmap"><p> <sect1><tt>#pragma charmap (&lt;index&gt;, &lt;code&gt;)</tt><label id="pragma-charmap"><p>
Each literal string and each literal character in the source is translated Each literal string and each literal character in the source is translated
by use of a translation table. This translation table is preset when the by use of a translation table. That translation table is preset when the
compiler is started depending on the target system, for example to map compiler is started, depending on the target system; for example, to map
ISO-8859-1 characters into PETSCII if the target is a commodore machine. ISO-8859-1 characters into PETSCII if the target is a Commodore machine.
This pragma allows to change entries in the translation table, so the This pragma allows to change entries in the translation table, so the
translation for individual characters, or even the complete table may be translation for individual characters, or even the complete table may be
adjusted. adjusted. Both arguments are assumed to be unsigned characters with a valid
range of 0-255.
Both arguments are assumed to be unsigned characters with a valid range of Beware of some pitfalls:
1-255. <itemize>
<item>The character index is actually the code of the character in the
Beware of two pitfalls: C source; so, character mappings do always depend on the source
character set. That means that <tt/#pragma&nbsp;charmap()/ is not
<itemize> portable -- it depends on the build environment.
<item>The character index is actually the code of the character in the <item>While it is possible to use character literals as indices, the
C source, so character mappings do always depend on the source result may be somewhat unexpected, since character literals are
character set. This means that <tt/#pragma&nbsp;charmap/ is not themselves translated. For that reason, I would suggest to avoid
portable -- it depends on the build environment. character literals, and use numeric character codes instead.
<item>While it is possible to use character literals as indices, the <item>It is risky to change index <tt/0x00/, because string functions depend
result may be somewhat unexpected, since character literals are on it. If it is changed, then the <tt/'\0'/ at the end of string
itself translated. For this reason I would suggest to avoid literals will become non-zero. Functions that are used on those
character literals and use numeric character codes instead. literals won't stop at the end of them. cc65 will warn you if you do
</itemize> change that code number. You can turn off that <tt/remap-zero/ warning
if you are certain that you know what you are doing (see <tt/<ref
id="pragma-warn" name="#pragma&nbsp;warn()">/).
</itemize>
Example: Example:
<tscreen><verb> <tscreen><verb>
/* Use a space wherever an 'a' occurs in ISO-8859-1 source */ /* Use a space wherever an 'a' occurs in ISO-8859-1 source */
#pragma charmap (0x61, 0x20); #pragma charmap (0x61, 0x20);
</verb></tscreen> </verb></tscreen>
@@ -1129,7 +1136,7 @@ parameter with the <tt/#pragma/.
Switch compiler warnings on or off. "name" is the name of a warning (see the Switch compiler warnings on or off. "name" is the name of a warning (see the
<tt/<ref name="-W" id="option-W">/ compiler option for a list). The name is <tt/<ref name="-W" id="option-W">/ compiler option for a list). The name is
either followed by "pop", which restores the last pushed state, or by "on" or followed either by "pop", which restores the last pushed state, or by "on" or
"off", optionally preceeded by "push" to push the current state before "off", optionally preceeded by "push" to push the current state before
changing it. changing it.
@@ -1144,6 +1151,7 @@ parameter with the <tt/#pragma/.
#pragma warn (unused-param, pop) #pragma warn (unused-param, pop)
</verb></tscreen> </verb></tscreen>
<sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p> <sect1><tt>#pragma writable-strings ([push,] on|off)</tt><label id="pragma-writable-strings"><p>
Changes the storage location of string literals. For historical reasons, Changes the storage location of string literals. For historical reasons,

View File

@@ -618,16 +618,16 @@ static void DoCase (void)
static void DoCharMap (void) static void DoCharMap (void)
/* Allow custome character mappings */ /* Allow custom character mappings */
{ {
long Index; long Index;
long Code; long Code;
/* Read the index as numerical value */ /* Read the index as numerical value */
Index = ConstExpression (); Index = ConstExpression ();
if (Index <= 0 || Index > 255) { if (Index < 0 || Index > 255) {
/* Value out of range */ /* Value out of range */
ErrorSkip ("Range error"); ErrorSkip ("Index range error");
return; return;
} }
@@ -638,7 +638,7 @@ static void DoCharMap (void)
Code = ConstExpression (); Code = ConstExpression ();
if (Code < 0 || Code > 255) { if (Code < 0 || Code > 255) {
/* Value out of range */ /* Value out of range */
ErrorSkip ("Range error"); ErrorSkip ("Code range error");
return; return;
} }

View File

@@ -66,11 +66,12 @@ IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */
/* Warn about: */ /* Warn about: */
IntStack WarnConstComparison= INTSTACK(1); /* - constant comparison results */ IntStack WarnConstComparison= INTSTACK(1); /* - constant comparison results */
IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */ IntStack WarnNoEffect = INTSTACK(1); /* - statements without an effect */
IntStack WarnRemapZero = INTSTACK(1); /* - remapping character code zero */
IntStack WarnStructParam = INTSTACK(1); /* - structs passed by val */ IntStack WarnStructParam = INTSTACK(1); /* - structs passed by val */
IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */
IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */ IntStack WarnUnusedLabel = INTSTACK(1); /* - unused labels */
IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */ IntStack WarnUnusedParam = INTSTACK(1); /* - unused parameters */
IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */ IntStack WarnUnusedVar = INTSTACK(1); /* - unused variables */
IntStack WarnUnknownPragma = INTSTACK(1); /* - unknown #pragmas */
/* Map the name of a warning to the intstack that holds its state */ /* Map the name of a warning to the intstack that holds its state */
typedef struct WarnMapEntry WarnMapEntry; typedef struct WarnMapEntry WarnMapEntry;
@@ -79,10 +80,11 @@ struct WarnMapEntry {
const char* Name; const char* Name;
}; };
static WarnMapEntry WarnMap[] = { static WarnMapEntry WarnMap[] = {
/* Keep sorted, even if this isn't used for now */ /* Keep names sorted, even if it isn't used for now */
{ &WarningsAreErrors, "error" },
{ &WarnConstComparison, "const-comparison" }, { &WarnConstComparison, "const-comparison" },
{ &WarningsAreErrors, "error" },
{ &WarnNoEffect, "no-effect" }, { &WarnNoEffect, "no-effect" },
{ &WarnRemapZero, "remap-zero" },
{ &WarnStructParam, "struct-param" }, { &WarnStructParam, "struct-param" },
{ &WarnUnknownPragma, "unknown-pragma" }, { &WarnUnknownPragma, "unknown-pragma" },
{ &WarnUnusedLabel, "unused-label" }, { &WarnUnusedLabel, "unused-label" },

View File

@@ -65,11 +65,12 @@ extern IntStack WarningsAreErrors; /* Treat warnings as errors */
/* Warn about: */ /* Warn about: */
extern IntStack WarnConstComparison; /* - constant comparison results */ extern IntStack WarnConstComparison; /* - constant comparison results */
extern IntStack WarnNoEffect; /* - statements without an effect */ extern IntStack WarnNoEffect; /* - statements without an effect */
extern IntStack WarnRemapZero; /* - remapping character code zero */
extern IntStack WarnStructParam; /* - structs passed by val */ extern IntStack WarnStructParam; /* - structs passed by val */
extern IntStack WarnUnknownPragma; /* - unknown #pragmas */
extern IntStack WarnUnusedLabel; /* - unused labels */ extern IntStack WarnUnusedLabel; /* - unused labels */
extern IntStack WarnUnusedParam; /* - unused parameters */ extern IntStack WarnUnusedParam; /* - unused parameters */
extern IntStack WarnUnusedVar; /* - unused variables */ extern IntStack WarnUnusedVar; /* - unused variables */
extern IntStack WarnUnknownPragma; /* - unknown #pragmas */

View File

@@ -453,13 +453,14 @@ static void CharMapPragma (StrBuf* B)
return; return;
} }
if (Index < 1 || Index > 255) { if (Index < 1 || Index > 255) {
if (Index == 0) { if (Index != 0) {
/* For groepaz */
Error ("Remapping 0 is not allowed");
} else {
Error ("Character index out of range"); Error ("Character index out of range");
return;
}
/* For groepaz and Christian */
if (IS_Get (&WarnRemapZero)) {
Warning ("Remapping from 0 is dangerous with string functions");
} }
return;
} }
/* Comma follows */ /* Comma follows */
@@ -472,13 +473,14 @@ static void CharMapPragma (StrBuf* B)
return; return;
} }
if (C < 1 || C > 255) { if (C < 1 || C > 255) {
if (C == 0) { if (C != 0) {
/* For groepaz */
Error ("Remapping 0 is not allowed");
} else {
Error ("Character code out of range"); Error ("Character code out of range");
return;
}
/* For groepaz and Christian */
if (IS_Get (&WarnRemapZero)) {
Warning ("Remapping to 0 can make string functions stop unexpectedly");
} }
return;
} }
/* Remap the character */ /* Remap the character */

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2002 Ullrich von Bassewitz */ /* (C) 1998-2002, Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Roemerstrasse 52 */
/* D-70597 Stuttgart */ /* D-70794 Filderstadt */
/* EMail: uz@cc65.org */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */

View File

@@ -124,6 +124,6 @@ void TgtTranslateStrBuf (StrBuf* Buf)
void TgtTranslateSet (unsigned Index, unsigned char C) void TgtTranslateSet (unsigned Index, unsigned char C)
/* Set the translation code for the given character */ /* Set the translation code for the given character */
{ {
CHECK (Index > 0 && Index < sizeof (Tab)); CHECK (Index < sizeof (Tab));
Tab[Index] = C; Tab[Index] = C;
} }