1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-25 13:29:41 +00:00

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:
cuz 2002-09-30 18:46:08 +00:00
parent 2df5db1f04
commit d92676ef60
6 changed files with 178 additions and 52 deletions

View File

@ -6,7 +6,7 @@
/* */
/* */
/* */
/* (C) 1998-2000 Ullrich von Bassewitz */
/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* 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)
/* Return the default char type (signed/unsigned) depending on the settings */
{

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -180,6 +180,9 @@ type* TypeAlloc (unsigned Len);
void TypeFree (type* Type);
/* Free a type string */
int SignExtendChar (int C);
/* Do correct sign extension of a character */
type GetDefaultChar (void);
/* Return the default char type (signed/unsigned) depending on the settings */

View File

@ -175,7 +175,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
} else {
Error ("String literal expected");
}
}
/* Call the string buf destructor */
DoneStrBuf (&S);
@ -186,33 +186,37 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
static void CharMapPragma (StrBuf* B)
/* Change the character map */
{
unsigned Index, C;
ExprDesc Val;
long Index, C;
/* Read the character index */
ConstIntExpr (&Val);
if (Val.ConstVal < 1 || Val.ConstVal > 255) {
Error ("Character index out of range");
Index = 'A';
} else {
Index = Val.ConstVal;
if (!SB_GetNumber (B, &Index)) {
return;
}
if (Index < 1 || Index > 255) {
Error ("Character index out of range");
return;
}
/* Comma follows */
ConsumeComma ();
SB_SkipWhite (B);
if (SB_Get (B) != ',') {
Error ("Comma expected");
return;
}
SB_SkipWhite (B);
/* Read the character code */
ConstIntExpr (&Val);
if (Val.ConstVal < 1 || Val.ConstVal > 255) {
if (!SB_GetNumber (B, &C)) {
return;
}
if (C < 1 || C > 255) {
Error ("Character code out of range");
C = 'A';
} else {
C = Val.ConstVal;
return;
}
/* 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");
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 */
SB_SkipWhite (&B);
if (SB_Peek (&B) != '\0') {
Error ("Unexpected input following pragma directive");
}

View File

@ -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)
/* Parse a character. Converts \n into EOL, etc. */
{
@ -387,7 +375,7 @@ static void StringConst (void)
void NextToken (void)
/* Get next token from input stream */
{
{
ident token;
/* We have to skip white space here before shifting tokens, since the
@ -419,11 +407,12 @@ void NextToken (void)
/* A number */
int HaveSuffix; /* True if we have a type suffix */
unsigned types; /* Possible types */
unsigned base;
unsigned long k; /* Value */
unsigned Base;
unsigned DigitVal;
unsigned long k; /* Value */
k = 0;
base = 10;
Base = 10;
types = IT_INT | IT_LONG | IT_ULONG;
if (CurC == '0') {
@ -432,23 +421,30 @@ void NextToken (void)
/* gobble 0 and examin next char */
NextChar ();
if (toupper (CurC) == 'X') {
base = 16;
NextTok.Type = type_uint;
Base = 16;
NextTok.Type = type_uint;
NextChar (); /* gobble "x" */
} else {
base = 8;
Base = 8;
}
}
while (1) {
if (IsDigit (CurC)) {
k = k * base + (CurC - '0');
} else if (base == 16 && IsXDigit (CurC)) {
k = (k << 4) + HexVal (CurC);
} else {
break; /* not digit */
}
NextChar (); /* gobble char */
}
while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
k = k * Base + DigitVal;
NextChar ();
}
/* 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 */
HaveSuffix = 1;

View File

@ -35,8 +35,10 @@
/* common */
#include "chartype.h"
#include "tgttrans.h"
/* cc65 */
#include "datatype.h"
#include "error.h"
#include "hexval.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;
}

View File

@ -63,6 +63,12 @@ int SB_GetString (StrBuf* B, StrBuf* S);
* 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.
*/