X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fscanner.c;h=b27ec62c5f7661c79f8cfc9e7ba29ba9a9686f74;hb=0807da74bd7c3ebe3e6e75129a07a810b17174b2;hp=8767c368c04076d60818e55d481ce5f6e283f19b;hpb=a456e503e477fdf860f63c6f52c642ab5a4a0e16;p=cc65 diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 8767c368c..b27ec62c5 100644 --- a/src/ld65/scanner.c +++ b/src/ld65/scanner.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2000 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* (C) 1998-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -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 */ @@ -95,7 +95,7 @@ void CfgWarning (const char* Format, ...) va_end (ap); Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); - DoneStrBuf (&Buf); + SB_Done (&Buf); } @@ -111,7 +111,7 @@ void CfgError (const char* Format, ...) va_end (ap); Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); - DoneStrBuf (&Buf); + SB_Done (&Buf); } @@ -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; } @@ -225,6 +286,36 @@ Again: /* Other characters */ switch (C) { + case '-': + NextChar (); + CfgTok = CFGTOK_MINUS; + break; + + case '+': + NextChar (); + CfgTok = CFGTOK_PLUS; + break; + + case '*': + NextChar (); + CfgTok = CFGTOK_MUL; + break; + + case '/': + NextChar (); + CfgTok = CFGTOK_DIV; + break; + + case '(': + NextChar (); + CfgTok = CFGTOK_LPAR; + break; + + case ')': + NextChar (); + CfgTok = CFGTOK_RPAR; + break; + case '{': NextChar (); CfgTok = CFGTOK_LCURLY; @@ -261,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 '#': @@ -295,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; @@ -330,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 (); } @@ -422,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; } }