]> git.sur5r.net Git - cc65/blobdiff - src/cc65/scanstrbuf.c
Add dummy return value to avoid a wcc warning
[cc65] / src / cc65 / scanstrbuf.c
index 82418f763d456b5852879e66df2d118a98dbba6d..bb86c2e35f598bfb87d2fb4e4a8e5e6a73b59da5 100644 (file)
 
 /* common */
 #include "chartype.h"
+#include "tgttrans.h"
 
 /* cc65 */
+#include "datatype.h"
 #include "error.h"
 #include "hexval.h"
 #include "ident.h"
 
 
 
-static char ParseChar (StrBuf* B)
+static int ParseChar (StrBuf* B)
 /* Parse a character. Converts \n into EOL, etc. */
 {
-    unsigned I;
+    unsigned I;       
+    unsigned Val;
     int C;
 
     /* Check for escape chars */
     if ((C = SB_Get (B)) == '\\') {
-       switch (SB_Get (B)) {
+               switch (SB_Peek (B)) {
+                   case '?':
+               C = '?';
+                SB_Skip (B);
+               break;
+           case 'a':
+               C = '\a';
+                SB_Skip (B);
+               break;
            case 'b':
                C = '\b';
+                SB_Skip (B);
                break;
            case 'f':
                C = '\f';
+                SB_Skip (B);
                break;
            case 'r':
                C = '\r';
+                SB_Skip (B);
                break;
            case 'n':
                C = '\n';
+                SB_Skip (B);
                break;
            case 't':
                C = '\t';
+                SB_Skip (B);
+               break;
+           case 'v':
+               C = '\v';
+                SB_Skip (B);
                break;
            case '\"':
                C = '\"';
+                SB_Skip (B);
                break;
            case '\'':
                C = '\'';
+                SB_Skip (B);
                break;
            case '\\':
                C = '\\';
+                SB_Skip (B);
                break;
            case 'x':
            case 'X':
                /* Hex character constant */
+                SB_Skip (B);
                        C = HexVal (SB_Get (B)) << 4;
                        C |= HexVal (SB_Get (B));
-               break;
+               break;
            case '0':
-               /* Octal constant */
-                C = 0;
-                goto Octal;
            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
                 /* Octal constant */
-                C = 1;
-Octal:          I = 0;
-                       while (SB_Peek (B) >= '0' && SB_Peek (B) <= '7' && I++ < 4) {
-                    C = (C << 3) | (SB_Get (B) - '0');
-               }
+                I = 0;
+                Val = SB_Get (B) - '0';
+                       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");
-               C = ' ';
-               break;
+               Error ("Illegal character constant 0x%02X", SB_Get (B));
+               C = ' ';
+               break;
        }
     }
 
@@ -114,12 +146,8 @@ Octal:          I = 0;
 
 
 
-
-
-
-
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
@@ -209,3 +237,101 @@ int SB_GetString (StrBuf* B, StrBuf* S)
 
 
 
+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.
+ */
+{
+    int      Sign;
+    char     C;
+    unsigned Base;
+    unsigned DigitVal;
+
+    /* Initialize Val */
+    *Val = 0;
+
+    /* Check for a sign */
+    Sign = 1;
+    switch (SB_Peek (B)) {
+        case '-':
+            Sign = -1;
+            /* FALLTHROUGH */
+        case '+':
+            SB_Skip (B);
+            SB_SkipWhite (B);
+            break;
+    }
+
+    /* Check for the different formats */
+    C = SB_Peek (B);
+    if (IsDigit (C)) {
+
+        if (C == '0') {
+            /* Hex or octal */
+            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;
+            }
+        } else {
+            Base = 10;
+        }
+
+        /* 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 */
+        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') {
+            SB_Skip (B);
+            C = SB_Peek (B);
+            if (C == 'u' || C == 'U') {
+                SB_Skip (B);
+            }
+        }
+
+    } else if (C == '\'') {
+
+        /* 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);
+        }
+
+    } else {
+
+        /* Invalid number */
+        Error ("Numeric constant expected");
+        return 0;
+
+    }
+
+    /* Success, value read is in Val */
+    *Val *= Sign;
+    return 1;
+}
+
+
+