X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fscanner.c;h=b27ec62c5f7661c79f8cfc9e7ba29ba9a9686f74;hb=0807da74bd7c3ebe3e6e75129a07a810b17174b2;hp=f2649e40548cd42a58aeada6e79599c09610f810;hpb=9174f65e541b4e1008d40ff2b86db849b2086065;p=cc65 diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index f2649e405..b27ec62c5 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2008, Ullrich von Bassewitz */ +/* (C) 1998-2009, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -59,7 +59,7 @@ /* Current token and attributes */ cfgtok_t CfgTok; -char CfgSVal [CFG_MAX_IDENT_LEN+1]; +StrBuf CfgSVal = STATIC_STRBUF_INITIALIZER; unsigned long CfgIVal; /* Error location */ @@ -164,12 +164,75 @@ static unsigned DigitVal (int C) -void CfgNextTok (void) -/* Read the next token from the input stream */ +static void StrVal (void) +/* Parse a string value and expand escape sequences */ { - unsigned I; + /* Skip the starting double quotes */ + NextChar (); + + /* Read input chars */ + SB_Clear (&CfgSVal); + while (C != '\"') { + switch (C) { + + case EOF: + case '\n': + CfgError ("Unterminated string"); + break; + + case '%': + NextChar (); + switch (C) { + + case EOF: + case '\n': + case '\"': + CfgError ("Unterminated '%%' escape sequence"); + break; + + case '%': + SB_AppendChar (&CfgSVal, '%'); + NextChar (); + break; + + case 'O': + /* Replace by output file */ + if (OutputName) { + SB_AppendStr (&CfgSVal, OutputName); + } + NextChar (); + break; + + default: + CfgWarning ("Unkown escape sequence `%%%c'", C); + SB_AppendChar (&CfgSVal, '%'); + SB_AppendChar (&CfgSVal, C); + NextChar (); + break; + } + break; + + default: + SB_AppendChar (&CfgSVal, C); + NextChar (); + } + } + + /* Skip the terminating double quotes */ + NextChar (); + + /* Terminate the string */ + SB_Terminate (&CfgSVal); + + /* We've read a string value */ + CfgTok = CFGTOK_STRCON; +} + +void CfgNextTok (void) +/* Read the next token from the input stream */ +{ Again: /* Skip whitespace */ while (isspace (C)) { @@ -184,14 +247,12 @@ Again: if (C == '_' || IsAlpha (C)) { /* Read the identifier */ - I = 0; + SB_Clear (&CfgSVal); while (C == '_' || IsAlNum (C)) { - if (I < CFG_MAX_IDENT_LEN) { - CfgSVal [I++] = C; - } + SB_AppendChar (&CfgSVal, C); NextChar (); } - CfgSVal [I] = '\0'; + SB_Terminate (&CfgSVal); CfgTok = CFGTOK_IDENT; return; } @@ -291,20 +352,7 @@ Again: break; case '\"': - NextChar (); - I = 0; - while (C != '\"') { - if (C == EOF || C == '\n') { - CfgError ("Unterminated string"); - } - if (I < CFG_MAX_IDENT_LEN) { - CfgSVal [I++] = C; - } - NextChar (); - } - NextChar (); - CfgSVal [I] = '\0'; - CfgTok = CFGTOK_STRCON; + StrVal (); break; case '#': @@ -325,11 +373,11 @@ Again: case 'O': NextChar (); if (OutputName) { - strncpy (CfgSVal, OutputName, CFG_MAX_IDENT_LEN); - CfgSVal [CFG_MAX_IDENT_LEN] = '\0'; + SB_CopyStr (&CfgSVal, OutputName); } else { - CfgSVal [0] = '\0'; + SB_Clear (&CfgSVal); } + SB_Terminate (&CfgSVal); CfgTok = CFGTOK_STRCON; break; @@ -360,7 +408,7 @@ void CfgConsume (cfgtok_t T, const char* Msg) /* Skip a token, print an error message if not found */ { if (CfgTok != T) { - CfgError (Msg); + CfgError ("%s", Msg); } CfgNextTok (); } @@ -452,16 +500,12 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) if (CfgTok == CFGTOK_IDENT) { /* Make it upper case */ - I = 0; - while (CfgSVal [I]) { - CfgSVal [I] = toupper (CfgSVal [I]); - ++I; - } + SB_ToUpper (&CfgSVal); /* Linear search */ for (I = 0; I < Size; ++I) { - if (strcmp (CfgSVal, Table [I].Ident) == 0) { - CfgTok = Table [I].Tok; + if (SB_CompareStr (&CfgSVal, Table[I].Ident) == 0) { + CfgTok = Table[I].Tok; return; } }