Add SB_GetNumber to scanstrbuf.c.
Rewrite of CharMapPragma in pragma.c Fixed bug in scanner.c: Invalid octal constants containing the numbers 8 and 9 were accepted by the compiler. Moved SignExtendChar from scanner.c to datatype.c. git-svn-id: svn://svn.cc65.org/cc65/trunk@1416 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2002 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
@@ -135,6 +135,18 @@ void TypeFree (type* T)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SignExtendChar (int C)
|
||||||
|
/* Do correct sign extension of a character */
|
||||||
|
{
|
||||||
|
if (SignedChars && (C & 0x80) != 0) {
|
||||||
|
return C | ~0xFF;
|
||||||
|
} else {
|
||||||
|
return C & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type GetDefaultChar (void)
|
type GetDefaultChar (void)
|
||||||
/* Return the default char type (signed/unsigned) depending on the settings */
|
/* Return the default char type (signed/unsigned) depending on the settings */
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998 Ullrich von Bassewitz */
|
/* (C) 1998-2002 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
@@ -180,6 +180,9 @@ type* TypeAlloc (unsigned Len);
|
|||||||
void TypeFree (type* Type);
|
void TypeFree (type* Type);
|
||||||
/* Free a type string */
|
/* Free a type string */
|
||||||
|
|
||||||
|
int SignExtendChar (int C);
|
||||||
|
/* Do correct sign extension of a character */
|
||||||
|
|
||||||
type GetDefaultChar (void);
|
type GetDefaultChar (void);
|
||||||
/* Return the default char type (signed/unsigned) depending on the settings */
|
/* Return the default char type (signed/unsigned) depending on the settings */
|
||||||
|
|
||||||
|
|||||||
@@ -186,33 +186,37 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
|||||||
static void CharMapPragma (StrBuf* B)
|
static void CharMapPragma (StrBuf* B)
|
||||||
/* Change the character map */
|
/* Change the character map */
|
||||||
{
|
{
|
||||||
unsigned Index, C;
|
long Index, C;
|
||||||
|
|
||||||
ExprDesc Val;
|
|
||||||
|
|
||||||
/* Read the character index */
|
/* Read the character index */
|
||||||
ConstIntExpr (&Val);
|
if (!SB_GetNumber (B, &Index)) {
|
||||||
if (Val.ConstVal < 1 || Val.ConstVal > 255) {
|
return;
|
||||||
|
}
|
||||||
|
if (Index < 1 || Index > 255) {
|
||||||
Error ("Character index out of range");
|
Error ("Character index out of range");
|
||||||
Index = 'A';
|
return;
|
||||||
} else {
|
|
||||||
Index = Val.ConstVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Comma follows */
|
/* Comma follows */
|
||||||
ConsumeComma ();
|
SB_SkipWhite (B);
|
||||||
|
if (SB_Get (B) != ',') {
|
||||||
|
Error ("Comma expected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SB_SkipWhite (B);
|
||||||
|
|
||||||
/* Read the character code */
|
/* Read the character code */
|
||||||
ConstIntExpr (&Val);
|
if (!SB_GetNumber (B, &C)) {
|
||||||
if (Val.ConstVal < 1 || Val.ConstVal > 255) {
|
return;
|
||||||
|
}
|
||||||
|
if (C < 1 || C > 255) {
|
||||||
Error ("Character code out of range");
|
Error ("Character code out of range");
|
||||||
C = 'A';
|
return;
|
||||||
} else {
|
|
||||||
C = Val.ConstVal;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remap the character */
|
/* Remap the character */
|
||||||
TgtTranslateSet (Index, C);
|
printf ("Translating %04lX to %04lX\n", Index, C);
|
||||||
|
TgtTranslateSet ((unsigned) Index, (unsigned char) C);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -346,9 +350,15 @@ static void ParsePragma (void)
|
|||||||
Error ("')' expected");
|
Error ("')' expected");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
SB_SkipWhite (&B);
|
||||||
|
|
||||||
|
/* Allow an optional semicolon to be compatible with the old syntax */
|
||||||
|
if (SB_Peek (&B) == ';') {
|
||||||
|
SB_Skip (&B);
|
||||||
|
SB_SkipWhite (&B);
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure nothing follows */
|
/* Make sure nothing follows */
|
||||||
SB_SkipWhite (&B);
|
|
||||||
if (SB_Peek (&B) != '\0') {
|
if (SB_Peek (&B) != '\0') {
|
||||||
Error ("Unexpected input following pragma directive");
|
Error ("Unexpected input following pragma directive");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -237,18 +237,6 @@ static void SetTok (int tok)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int SignExtendChar (int C)
|
|
||||||
/* Do correct sign extension of a character */
|
|
||||||
{
|
|
||||||
if (SignedChars && (C & 0x80) != 0) {
|
|
||||||
return C | ~0xFF;
|
|
||||||
} else {
|
|
||||||
return C & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int ParseChar (void)
|
static int ParseChar (void)
|
||||||
/* Parse a character. Converts \n into EOL, etc. */
|
/* Parse a character. Converts \n into EOL, etc. */
|
||||||
{
|
{
|
||||||
@@ -419,11 +407,12 @@ void NextToken (void)
|
|||||||
/* A number */
|
/* A number */
|
||||||
int HaveSuffix; /* True if we have a type suffix */
|
int HaveSuffix; /* True if we have a type suffix */
|
||||||
unsigned types; /* Possible types */
|
unsigned types; /* Possible types */
|
||||||
unsigned base;
|
unsigned Base;
|
||||||
|
unsigned DigitVal;
|
||||||
unsigned long k; /* Value */
|
unsigned long k; /* Value */
|
||||||
|
|
||||||
k = 0;
|
k = 0;
|
||||||
base = 10;
|
Base = 10;
|
||||||
types = IT_INT | IT_LONG | IT_ULONG;
|
types = IT_INT | IT_LONG | IT_ULONG;
|
||||||
|
|
||||||
if (CurC == '0') {
|
if (CurC == '0') {
|
||||||
@@ -432,22 +421,29 @@ void NextToken (void)
|
|||||||
/* gobble 0 and examin next char */
|
/* gobble 0 and examin next char */
|
||||||
NextChar ();
|
NextChar ();
|
||||||
if (toupper (CurC) == 'X') {
|
if (toupper (CurC) == 'X') {
|
||||||
base = 16;
|
Base = 16;
|
||||||
NextTok.Type = type_uint;
|
NextTok.Type = type_uint;
|
||||||
NextChar (); /* gobble "x" */
|
NextChar (); /* gobble "x" */
|
||||||
} else {
|
} else {
|
||||||
base = 8;
|
Base = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (1) {
|
while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
|
||||||
if (IsDigit (CurC)) {
|
k = k * Base + DigitVal;
|
||||||
k = k * base + (CurC - '0');
|
NextChar ();
|
||||||
} else if (base == 16 && IsXDigit (CurC)) {
|
|
||||||
k = (k << 4) + HexVal (CurC);
|
|
||||||
} else {
|
|
||||||
break; /* not digit */
|
|
||||||
}
|
}
|
||||||
NextChar (); /* gobble char */
|
/* Check for errorneous digits */
|
||||||
|
if (Base == 8 && IsDigit (CurC)) {
|
||||||
|
Error ("Numeric constant contains digits beyond the radix");
|
||||||
|
/* Do error recovery */
|
||||||
|
do {
|
||||||
|
NextChar ();
|
||||||
|
} while (IsDigit (CurC));
|
||||||
|
} else if (Base != 16 && IsXDigit (CurC)) {
|
||||||
|
Error ("Nondigits in number and not hexadecimal");
|
||||||
|
do {
|
||||||
|
NextChar ();
|
||||||
|
} while (IsXDigit (CurC));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a suffix */
|
/* Check for a suffix */
|
||||||
|
|||||||
@@ -35,8 +35,10 @@
|
|||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "chartype.h"
|
#include "chartype.h"
|
||||||
|
#include "tgttrans.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
|
#include "datatype.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "hexval.h"
|
#include "hexval.h"
|
||||||
#include "ident.h"
|
#include "ident.h"
|
||||||
@@ -209,3 +211,100 @@ int SB_GetString (StrBuf* B, StrBuf* S)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int SB_GetNumber (StrBuf* B, long* Val)
|
||||||
|
/* Get a number from the string buffer. Accepted formats are decimal, octal,
|
||||||
|
* hex and character constants. Numeric constants may be preceeded by a
|
||||||
|
* minus or plus sign. The function returns 1 if a number was found and
|
||||||
|
* zero otherwise.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int Sign;
|
||||||
|
char C;
|
||||||
|
unsigned Base;
|
||||||
|
unsigned DigitVal;
|
||||||
|
|
||||||
|
/* Initialize Val */
|
||||||
|
*Val = 0;
|
||||||
|
|
||||||
|
/* Check for a sign */
|
||||||
|
Sign = 1;
|
||||||
|
switch (SB_Peek (B)) {
|
||||||
|
case '-':
|
||||||
|
Sign = -1;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case '+':
|
||||||
|
SB_Skip (B);
|
||||||
|
SB_SkipWhite (B);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for the different formats */
|
||||||
|
C = SB_Peek (B);
|
||||||
|
if (IsDigit (C)) {
|
||||||
|
|
||||||
|
if (C == '0') {
|
||||||
|
/* Hex or octal */
|
||||||
|
SB_Skip (B);
|
||||||
|
if (tolower (SB_Peek (B)) == 'x') {
|
||||||
|
SB_Skip (B);
|
||||||
|
Base = 16;
|
||||||
|
if (!IsXDigit (SB_Peek (B))) {
|
||||||
|
Error ("Invalid hexadecimal number");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Base = 8;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Base = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the number */
|
||||||
|
while (IsXDigit (C = SB_Peek (B)) && (DigitVal = HexVal (C)) < Base) {
|
||||||
|
*Val = (*Val * Base) + DigitVal;
|
||||||
|
SB_Skip (B);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allow optional 'U' and 'L' modifiers */
|
||||||
|
C = SB_Peek (B);
|
||||||
|
if (C == 'u' || C == 'U') {
|
||||||
|
SB_Skip (B);
|
||||||
|
C = SB_Peek (B);
|
||||||
|
if (C == 'l' || C == 'L') {
|
||||||
|
SB_Skip (B);
|
||||||
|
}
|
||||||
|
} else if (C == 'l' || C == 'L') {
|
||||||
|
SB_Skip (B);
|
||||||
|
C = SB_Peek (B);
|
||||||
|
if (C == 'u' || C == 'U') {
|
||||||
|
SB_Skip (B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (C == '\'') {
|
||||||
|
|
||||||
|
/* Character constant */
|
||||||
|
SB_Skip (B);
|
||||||
|
*Val = SignExtendChar (TgtTranslateChar (ParseChar (B)));
|
||||||
|
if (SB_Peek (B) != '\'') {
|
||||||
|
Error ("`\'' expected");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
/* Skip the quote */
|
||||||
|
SB_Skip (B);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Invalid number */
|
||||||
|
Error ("Numeric constant expected");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success, value read is in Val */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,12 @@ int SB_GetString (StrBuf* B, StrBuf* S);
|
|||||||
* returns 1 if a string was found and 0 otherwise.
|
* returns 1 if a string was found and 0 otherwise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
int SB_GetNumber (StrBuf* B, long* Val);
|
||||||
|
/* Get a number from the string buffer. Accepted formats are decimal, octal,
|
||||||
|
* hex and character constants. Numeric constants may be preceeded by a
|
||||||
|
* minus or plus sign. The function returns 1 if a number was found and
|
||||||
|
* zero otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user