X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fld65%2Fscanner.c;h=b27ec62c5f7661c79f8cfc9e7ba29ba9a9686f74;hb=0807da74bd7c3ebe3e6e75129a07a810b17174b2;hp=5576a32d3c425008a571ec3c3a4ae4b81958e3ae;hpb=8559581d9f2be04e4865aaafe8758d907e657cff;p=cc65 diff --git a/src/ld65/scanner.c b/src/ld65/scanner.c index 5576a32d3..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 */ @@ -41,6 +41,7 @@ /* common */ #include "chartype.h" +#include "strbuf.h" #include "xsprintf.h" /* ld65 */ @@ -58,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 */ @@ -86,14 +87,15 @@ static FILE* InputFile = 0; void CfgWarning (const char* Format, ...) /* Print a warning message adding file name and line number of the config file */ { - char Buf [512]; + StrBuf Buf = STATIC_STRBUF_INITIALIZER; va_list ap; va_start (ap, Format); - xvsprintf (Buf, sizeof (Buf), Format, ap); + SB_VPrintf (&Buf, Format, ap); va_end (ap); - Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf); + Warning ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); + SB_Done (&Buf); } @@ -101,14 +103,15 @@ void CfgWarning (const char* Format, ...) void CfgError (const char* Format, ...) /* Print an error message adding file name and line number of the config file */ { - char Buf [512]; + StrBuf Buf = STATIC_STRBUF_INITIALIZER; va_list ap; va_start (ap, Format); - xvsprintf (Buf, sizeof (Buf), Format, ap); + SB_VPrintf (&Buf, Format, ap); va_end (ap); - Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, Buf); + Error ("%s(%u): %s", CfgGetName(), CfgErrorLine, SB_GetConstBuf (&Buf)); + SB_Done (&Buf); } @@ -161,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)) { @@ -181,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; } @@ -197,7 +261,7 @@ Again: if (C == '$') { NextChar (); if (!isxdigit (C)) { - Error ("%s(%u): Hex digit expected", CfgGetName(), InputLine); + CfgError ("Hex digit expected"); } CfgIVal = 0; while (isxdigit (C)) { @@ -222,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; @@ -258,20 +352,7 @@ Again: break; case '\"': - NextChar (); - I = 0; - while (C != '\"') { - if (C == EOF || C == '\n') { - Error ("%s(%u): Unterminated string", CfgName, InputLine); - } - if (I < CFG_MAX_IDENT_LEN) { - CfgSVal [I++] = C; - } - NextChar (); - } - NextChar (); - CfgSVal [I] = '\0'; - CfgTok = CFGTOK_STRCON; + StrVal (); break; case '#': @@ -292,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; @@ -316,7 +397,7 @@ Again: break; default: - Error ("%s(%u): Invalid character `%c'", CfgGetName(), InputLine, C); + CfgError ("Invalid character `%c'", C); } } @@ -327,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 (); } @@ -419,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; } } @@ -436,7 +513,7 @@ void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name) } /* Not found or no identifier */ - Error ("%s(%u): %s expected", CfgGetName(), InputLine, Name); + CfgError ("%s expected", Name); }