X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fscanstrbuf.c;h=f55f52a6454d791172b6d6f68a8a3b1c6b588ff6;hb=112ae0e3db511ddd92e769c11328646ebe2a6240;hp=bb86c2e35f598bfb87d2fb4e4a8e5e6a73b59da5;hpb=f2a74164a29bcf52023d5b13f3fc8ec07ee824c0;p=cc65 diff --git a/src/cc65/scanstrbuf.c b/src/cc65/scanstrbuf.c index bb86c2e35..f55f52a64 100644 --- a/src/cc65/scanstrbuf.c +++ b/src/cc65/scanstrbuf.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2002 Ullrich von Bassewitz */ -/* Wacholderweg 14 */ -/* D-70597 Stuttgart */ -/* EMail: uz@cc65.org */ +/* (C) 2002-2009, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -55,7 +55,7 @@ static int ParseChar (StrBuf* B) /* Parse a character. Converts \n into EOL, etc. */ { - unsigned I; + unsigned I; unsigned Val; int C; @@ -162,23 +162,32 @@ void SB_SkipWhite (StrBuf* B) -int SB_GetSym (StrBuf* B, char* S) -/* Get a symbol from the string buffer. S must be able to hold MAX_IDENTLEN - * characters. Returns 1 if a symbol was found and 0 otherwise. +int SB_GetSym (StrBuf* B, StrBuf* Ident, const char* SpecialChars) +/* Get a symbol from the string buffer. If SpecialChars is not NULL, it + * points to a string that contains characters allowed within the string in + * addition to letters, digits and the underline. Note: The identifier must + * still begin with a letter. + * Returns 1 if a symbol was found and 0 otherwise but doesn't output any + * errors. */ { + /* Handle a NULL argument for SpecialChars transparently */ + if (SpecialChars == 0) { + SpecialChars = ""; + } + + /* Clear Ident */ + SB_Clear (Ident); + if (IsIdent (SB_Peek (B))) { - unsigned I = 0; char C = SB_Peek (B); do { - if (I < MAX_IDENTLEN) { - ++I; - *S++ = C; - } + SB_AppendChar (Ident, C); SB_Skip (B); C = SB_Peek (B); - } while (IsIdent (C) || IsDigit (C)); - *S = '\0'; + } while (IsIdent (C) || IsDigit (C) || + (C != '\0' && strchr (SpecialChars, C) != 0)); + SB_Terminate (Ident); return 1; } else { return 0; @@ -188,15 +197,17 @@ int SB_GetSym (StrBuf* B, char* S) int SB_GetString (StrBuf* B, StrBuf* S) -/* Get a string from the string buffer. S will be initialized by the function - * and will return the correctly terminated string on return. The function - * returns 1 if a string was found and 0 otherwise. +/* Get a string from the string buffer. Returns 1 if a string was found and 0 + * otherwise. Errors are only output in case of invalid strings (missing end + * of string). */ { char C; - /* Initialize S */ - *S = AUTO_STRBUF_INITIALIZER; + /* Clear S */ + SB_Clear (S); + + /* A string starts with quote marks */ if (SB_Peek (B) == '\"') { /* String follows, be sure to concatenate strings */ @@ -241,7 +252,7 @@ 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. + * zero otherwise. Errors are only output for invalid numbers. */ { int Sign; @@ -249,83 +260,86 @@ int SB_GetNumber (StrBuf* B, long* Val) unsigned Base; unsigned DigitVal; + /* Initialize Val */ *Val = 0; - /* Check for a sign */ + /* Handle character constants */ + if (SB_Peek (B) == '\'') { + + /* 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); + return 1; + } + } + + /* Check for a sign. A sign must be followed by a digit, otherwise it's + * not a number + */ Sign = 1; switch (SB_Peek (B)) { case '-': Sign = -1; /* FALLTHROUGH */ case '+': + if (!IsDigit (SB_LookAt (B, SB_GetIndex (B) + 1))) { + return 0; + } SB_Skip (B); - SB_SkipWhite (B); break; } - /* Check for the different formats */ + /* We must have a digit now, otherwise its not a number */ C = SB_Peek (B); - if (IsDigit (C)) { + if (!IsDigit (C)) { + return 0; + } - if (C == '0') { - /* Hex or octal */ + /* Determine the base */ + if (C == '0') { + /* Hex or octal */ + SB_Skip (B); + if (tolower (SB_Peek (B)) == 'x') { 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; + Base = 16; + if (!IsXDigit (SB_Peek (B))) { + Error ("Invalid hexadecimal number"); + return 0; } } else { - Base = 10; + 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); - } + /* 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 */ + /* Allow optional 'U' and 'L' modifiers */ + C = SB_Peek (B); + if (C == 'u' || C == 'U') { + SB_Skip (B); C = SB_Peek (B); - if (C == 'u' || C == 'U') { + if (C == 'l' || C == 'L') { 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 */ + } else if (C == 'l' || C == 'L') { SB_Skip (B); - *Val = SignExtendChar (TgtTranslateChar (ParseChar (B))); - if (SB_Peek (B) != '\'') { - Error ("`\'' expected"); - return 0; - } else { - /* Skip the quote */ + C = SB_Peek (B); + if (C == 'u' || C == 'U') { SB_Skip (B); } - - } else { - - /* Invalid number */ - Error ("Numeric constant expected"); - return 0; - } /* Success, value read is in Val */