]> git.sur5r.net Git - cc65/commitdiff
Add SB_GetNumber to scanstrbuf.c.
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Sep 2002 18:46:08 +0000 (18:46 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 30 Sep 2002 18:46:08 +0000 (18:46 +0000)
Rewrite of CharMapPragma in pragma.c
Fixed bug in scanner.c: Invalid octal constants containing the numbers 8
and 9 were accepted by the compiler.
Moved SignExtendChar from scanner.c to datatype.c.

git-svn-id: svn://svn.cc65.org/cc65/trunk@1416 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/datatype.c
src/cc65/datatype.h
src/cc65/pragma.c
src/cc65/scanner.c
src/cc65/scanstrbuf.c
src/cc65/scanstrbuf.h

index 01778b5f836fbff43504fd4979fd6326d623c141..bc3ae194f43d8399c9507b2dd03e6b49f0036062 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
+/* (C) 1998-2002 Ullrich von Bassewitz                                       */
 /*               Wacholderweg 14                                             */
 /*               D-70597 Stuttgart                                           */
 /* EMail:        uz@musoftware.de                                            */
@@ -135,6 +135,18 @@ void TypeFree (type* T)
 
 
 
+int SignExtendChar (int C)
+/* Do correct sign extension of a character */
+{
+    if (SignedChars && (C & 0x80) != 0) {
+               return C | ~0xFF;
+    } else {
+               return C & 0xFF;
+    }
+}
+
+
+
 type GetDefaultChar (void)
 /* Return the default char type (signed/unsigned) depending on the settings */
 {
index a750afff23368e3df1478de4a9fb8d0dfc69c88d..2d4ac21bb060cd27de32939c5976964ca49f25f4 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 1998-2002 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -180,6 +180,9 @@ type* TypeAlloc (unsigned Len);
 void TypeFree (type* Type);
 /* Free a type string */
 
+int SignExtendChar (int C);
+/* Do correct sign extension of a character */
+
 type GetDefaultChar (void);
 /* Return the default char type (signed/unsigned) depending on the settings */
 
index b26ef7bc81d7ea989fea8cee011f419f50beb097..f4c38491b003504e10ea1c7d3c3f3f25afc215b9 100644 (file)
@@ -175,7 +175,7 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
 
     } else {
        Error ("String literal expected");
-    }             
+    }
 
     /* Call the string buf destructor */
     DoneStrBuf (&S);
@@ -186,33 +186,37 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
 static void CharMapPragma (StrBuf* B)
 /* Change the character map */
 {
-    unsigned Index, C;
-
-    ExprDesc Val;
+    long Index, C;
 
     /* Read the character index */
-    ConstIntExpr (&Val);
-    if (Val.ConstVal < 1 || Val.ConstVal > 255) {
-       Error ("Character index out of range");
-       Index = 'A';
-    } else {
-       Index = Val.ConstVal;
+    if (!SB_GetNumber (B, &Index)) {
+        return;
+    }
+    if (Index < 1 || Index > 255) {
+       Error ("Character index out of range");
+       return;
     }
 
     /* Comma follows */
-    ConsumeComma ();
+    SB_SkipWhite (B);
+    if (SB_Get (B) != ',') {
+        Error ("Comma expected");
+        return;
+    }
+    SB_SkipWhite (B);
 
     /* Read the character code */
-    ConstIntExpr (&Val);
-    if (Val.ConstVal < 1 || Val.ConstVal > 255) {
+    if (!SB_GetNumber (B, &C)) {
+        return;
+    }
+    if (C < 1 || C > 255) {
        Error ("Character code out of range");
-       C = 'A';
-    } else {
-       C = Val.ConstVal;
+       return;
     }
 
     /* Remap the character */
-    TgtTranslateSet (Index, C);
+    printf ("Translating %04lX to %04lX\n", Index, C);
+    TgtTranslateSet ((unsigned) Index, (unsigned char) C);
 }
 
 
@@ -346,9 +350,15 @@ static void ParsePragma (void)
         Error ("')' expected");
         return;
     }
+    SB_SkipWhite (&B);
+
+    /* Allow an optional semicolon to be compatible with the old syntax */
+    if (SB_Peek (&B) == ';') {
+        SB_Skip (&B);
+        SB_SkipWhite (&B);
+    }
 
     /* Make sure nothing follows */
-    SB_SkipWhite (&B);
     if (SB_Peek (&B) != '\0') {
         Error ("Unexpected input following pragma directive");
     }
index b6321780e21f346c3b5355b4fd99da84d3f681e4..967a7fb135b5b4c6ebc8340c9e13e51ad84521f6 100644 (file)
@@ -237,18 +237,6 @@ static void SetTok (int tok)
 
 
 
-static int SignExtendChar (int C)
-/* Do correct sign extension of a character */
-{
-    if (SignedChars && (C & 0x80) != 0) {
-               return C | ~0xFF;
-    } else {
-               return C & 0xFF;
-    }
-}
-
-
-
 static int ParseChar (void)
 /* Parse a character. Converts \n into EOL, etc. */
 {
@@ -387,7 +375,7 @@ static void StringConst (void)
 
 void NextToken (void)
 /* Get next token from input stream */
-{
+{        
     ident token;
 
     /* We have to skip white space here before shifting tokens, since the
@@ -419,11 +407,12 @@ void NextToken (void)
        /* A number */
        int HaveSuffix;         /* True if we have a type suffix */
        unsigned types;         /* Possible types */
-       unsigned base;
-       unsigned long k;        /* Value */
+       unsigned Base;
+        unsigned DigitVal;
+       unsigned long k;        /* Value */
 
        k     = 0;
-       base  = 10;
+       Base  = 10;
        types = IT_INT | IT_LONG | IT_ULONG;
 
                if (CurC == '0') {
@@ -432,23 +421,30 @@ void NextToken (void)
            /* gobble 0 and examin next char */
            NextChar ();
            if (toupper (CurC) == 'X') {
-               base = 16;
-               NextTok.Type = type_uint;
+               Base = 16;
+               NextTok.Type = type_uint;
                        NextChar ();    /* gobble "x" */
            } else {
-               base = 8;
-           }
-       }
-       while (1) {
-           if (IsDigit (CurC)) {
-               k = k * base + (CurC - '0');
-           } else if (base == 16 && IsXDigit (CurC)) {
-               k = (k << 4) + HexVal (CurC);
-           } else {
-               break;          /* not digit */
+               Base = 8;
            }
-                   NextChar ();        /* gobble char */
        }
+        while (IsXDigit (CurC) && (DigitVal = HexVal (CurC)) < Base) {
+            k = k * Base + DigitVal;
+            NextChar ();
+        }
+        /* Check for errorneous digits */
+        if (Base == 8 && IsDigit (CurC)) {
+            Error ("Numeric constant contains digits beyond the radix");
+            /* Do error recovery */
+            do {
+                NextChar ();
+            } while (IsDigit (CurC));
+        } else if (Base != 16 && IsXDigit (CurC)) {
+            Error ("Nondigits in number and not hexadecimal");
+            do {
+                NextChar ();
+            } while (IsXDigit (CurC));
+        }
 
        /* Check for a suffix */
        HaveSuffix = 1;
index 82418f763d456b5852879e66df2d118a98dbba6d..39c15e4e56c13833088fc278d4c877676dc167c7 100644 (file)
 
 /* common */
 #include "chartype.h"
+#include "tgttrans.h"
 
 /* cc65 */
+#include "datatype.h"
 #include "error.h"
 #include "hexval.h"
 #include "ident.h"
@@ -209,3 +211,100 @@ 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 */
+    return 1;
+}
+
+
+
index 9bd971441590ebcdef86cc680bad8fe5de9a62bf..29002052e2468b4bee5c96af147d36e32ce3219b 100644 (file)
@@ -63,6 +63,12 @@ int SB_GetString (StrBuf* B, StrBuf* S);
  * returns 1 if a string was found and 0 otherwise.
  */
 
+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.
+ */