X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fscanner.c;h=a0ff4530497c3a5563c54fe9b6426f17f6c731e3;hb=b3496bb343a2c93284a8669da4b52cf45b3db3dd;hp=b6321780e21f346c3b5355b4fd99da84d3f681e4;hpb=ea50befaac9228edb2bab7f0bbf41881b4abc925;p=cc65 diff --git a/src/cc65/scanner.c b/src/cc65/scanner.c index b6321780e..a0ff45304 100644 --- a/src/cc65/scanner.c +++ b/src/cc65/scanner.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2003 Ullrich von Bassewitz */ +/* Römerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -81,15 +81,16 @@ static const struct Keyword { unsigned char Type; /* Token type */ } Keywords [] = { { "_Pragma", TOK_PRAGMA, TT_C }, + { "__AX__", TOK_AX, TT_C }, { "__A__", TOK_A, TT_C }, - { "__AX__", TOK_AX, TT_C }, - { "__EAX__", TOK_EAX, TT_C }, - { "__X__", TOK_X, TT_C }, - { "__Y__", TOK_Y, TT_C }, - { "__asm__", TOK_ASM, TT_C }, - { "__attribute__", TOK_ATTRIBUTE, TT_C }, - { "__far__", TOK_FAR, TT_C }, - { "__fastcall__", TOK_FASTCALL, TT_C }, + { "__EAX__", TOK_EAX, TT_C }, + { "__X__", TOK_X, TT_C }, + { "__Y__", TOK_Y, TT_C }, + { "__asm__", TOK_ASM, TT_C }, + { "__attribute__", TOK_ATTRIBUTE, TT_C }, + { "__far__", TOK_FAR, TT_C }, + { "__fastcall__", TOK_FASTCALL, TT_C }, + { "__near__", TOK_NEAR, TT_C }, { "asm", TOK_ASM, TT_EXT }, { "auto", TOK_AUTO, TT_C }, { "break", TOK_BREAK, TT_C }, @@ -111,7 +112,9 @@ static const struct Keyword { { "if", TOK_IF, TT_C }, { "int", TOK_INT, TT_C }, { "long", TOK_LONG, TT_C }, + { "near", TOK_NEAR, TT_EXT }, { "register", TOK_REGISTER, TT_C }, + { "restrict", TOK_RESTRICT, TT_C }, { "return", TOK_RETURN, TT_C }, { "short", TOK_SHORT, TT_C }, { "signed", TOK_SIGNED, TT_C }, @@ -237,23 +240,11 @@ 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. */ { - int i; - unsigned val; + int I; + unsigned Val; int C; /* Check for escape chars */ @@ -262,49 +253,71 @@ static int ParseChar (void) switch (CurC) { case 'b': C = '\b'; - break; + break; case 'f': - C = '\f'; - break; + C = '\f'; + break; case 'r': - C = '\r'; - break; + C = '\r'; + break; case 'n': - C = '\n'; - break; + C = '\n'; + break; case 't': - C = '\t'; - break; + C = '\t'; + break; + case 'v': + C = '\v'; + break; case '\"': - C = '\"'; - break; + C = '\"'; + break; case '\'': - C = '\''; - break; + C = '\''; + break; case '\\': - C = '\\'; - break; + C = '\\'; + break; case 'x': case 'X': - /* Hex character constant */ - NextChar (); - val = HexVal (CurC) << 4; - NextChar (); - C = val | HexVal (CurC); /* Do not translate */ - break; + /* Hex character constant */ + NextChar (); + Val = HexVal (CurC) << 4; + NextChar (); + C = Val | HexVal (CurC); /* Do not translate */ + break; case '0': case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': /* Octal constant */ - i = 0; - C = CurC - '0'; - while (NextC >= '0' && NextC <= '7' && i++ < 4) { + I = 0; + Val = CurC - '0'; + while (NextC >= '0' && NextC <= '7' && ++I <= 3) { NextChar (); - C = (C << 3) | (CurC - '0'); + Val = (Val << 3) | (CurC - '0'); } + C = (int) Val; + if (Val >= 256) { + Error ("Character constant out of range"); + C = ' '; + } break; default: Error ("Illegal character constant"); C = ' '; + /* Try to do error recovery, otherwise the compiler will spit + * out thousands of errors in this place and abort. + */ + if (CurC != '\'' && CurC != '\0') { + while (NextC != '\'' && NextC != '\"' && NextC != '\0') { + NextChar (); + } + } break; } } else { @@ -403,6 +416,14 @@ void NextToken (void) } CurTok = NextTok; + /* When reading the first time from the file, the line info in NextTok, + * which was copied to CurTok is invalid. Since the information from + * the token is used for error messages, we must make it valid. + */ + if (CurTok.LI == 0) { + CurTok.LI = UseLineInfo (GetCurLineInfo ()); + } + /* Remember the starting position of the next token */ NextTok.LI = UseLineInfo (GetCurLineInfo ()); @@ -419,11 +440,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 +454,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; - } - } - 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 */ + Base = 8; } - 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;