/* Check for escape chars */
if ((C = SB_Get (B)) == '\\') {
- switch (SB_Peek (B)) {
- case '?':
- C = '?';
+ switch (SB_Peek (B)) {
+ case '?':
+ C = '?';
SB_Skip (B);
- break;
- case 'a':
- C = '\a';
+ break;
+ case 'a':
+ C = '\a';
SB_Skip (B);
- break;
- case 'b':
- C = '\b';
+ break;
+ case 'b':
+ C = '\b';
SB_Skip (B);
- break;
- case 'f':
- C = '\f';
+ break;
+ case 'f':
+ C = '\f';
SB_Skip (B);
- break;
- case 'r':
- C = '\r';
+ break;
+ case 'r':
+ C = '\r';
SB_Skip (B);
- break;
- case 'n':
- C = '\n';
+ break;
+ case 'n':
+ C = '\n';
SB_Skip (B);
- break;
- case 't':
- C = '\t';
+ break;
+ case 't':
+ C = '\t';
SB_Skip (B);
- break;
- case 'v':
- C = '\v';
+ break;
+ case 'v':
+ C = '\v';
SB_Skip (B);
- break;
- case '\"':
- C = '\"';
+ break;
+ case '\"':
+ C = '\"';
SB_Skip (B);
- break;
- case '\'':
- C = '\'';
+ break;
+ case '\'':
+ C = '\'';
SB_Skip (B);
- break;
- case '\\':
- C = '\\';
+ break;
+ case '\\':
+ C = '\\';
SB_Skip (B);
- break;
- case 'x':
- case 'X':
- /* Hex character constant */
+ break;
+ case 'x':
+ case 'X':
+ /* Hex character constant */
SB_Skip (B);
- C = HexVal (SB_Get (B)) << 4;
- C |= HexVal (SB_Get (B));
- break;
- case '0':
- case '1':
+ C = HexVal (SB_Get (B)) << 4;
+ C |= HexVal (SB_Get (B));
+ break;
+ case '0':
+ case '1':
case '2':
case '3':
case '4':
/* Octal constant */
I = 0;
Val = SB_Get (B) - '0';
- while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && ++I <= 3) {
+ while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && ++I <= 3) {
Val = (Val << 3) | (SB_Get (B) - '0');
- }
+ }
C = (int) Val;
if (Val > 256) {
Error ("Character constant out of range");
C = ' ';
}
- break;
- default:
- Error ("Illegal character constant 0x%02X", SB_Get (B));
- C = ' ';
- break;
- }
+ break;
+ default:
+ Error ("Illegal character constant 0x%02X", SB_Get (B));
+ C = ' ';
+ break;
+ }
}
/* Return the character */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-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';
- return 1;
+ } while (IsIdent (C) || IsDigit (C) ||
+ (C != '\0' && strchr (SpecialChars, C) != 0));
+ SB_Terminate (Ident);
+ return 1;
} else {
- return 0;
+ return 0;
}
}
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 */
- SB_Init (S);
+ /* Clear S */
+ SB_Clear (S);
+
+ /* A string starts with quote marks */
if (SB_Peek (B) == '\"') {
/* String follows, be sure to concatenate strings */
/* 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;
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') {
- SB_Skip (B);
- C = SB_Peek (B);
- if (C == 'l' || C == 'L') {
- SB_Skip (B);
- }
- } else if (C == 'l' || C == 'L') {
+ 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 */
*Val *= Sign;
return 1;
}
-
-
-