]> git.sur5r.net Git - cc65/blobdiff - src/da65/scanner.c
Merge pull request #334 from cacciatc/standard-versioning
[cc65] / src / da65 / scanner.c
index 9b58981df0420da48ed452a8a8b6015f3e382163..8dc8d393a77fb389fa86fa87828b56ef938a4525 100644 (file)
@@ -1,8 +1,8 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                scanner.c                                 */
+/*                                 scanner.c                                 */
 /*                                                                           */
-/*          Configuration file scanner for the da65 disassembler            */
+/*           Configuration file scanner for the da65 disassembler            */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
 
 /* Current token and attributes */
 unsigned        InfoTok;
-char                   InfoSVal [CFG_MAX_IDENT_LEN+1];
+char            InfoSVal [CFG_MAX_IDENT_LEN+1];
 long            InfoIVal;
 
 /* Error location */
-unsigned               InfoErrorLine;
-unsigned               InfoErrorCol;
+unsigned                InfoErrorLine;
+unsigned                InfoErrorCol;
 
 /* Input sources for the configuration */
-static const char*             InfoFile        = 0;
+static const char*      InfoFile        = 0;
 
 /* Other input stuff */
-static int                     C               = ' ';
-static unsigned                InputLine       = 1;
-static unsigned                InputCol        = 0;
-static FILE*                   InputFile       = 0;
+static int              C               = ' ';
+static unsigned         InputLine       = 1;
+static unsigned         InputCol        = 0;
+static FILE*            InputFile       = 0;
 
 
 
 /*****************************************************************************/
-/*                             Error handling                               */
+/*                              Error handling                               */
 /*****************************************************************************/
 
 
@@ -112,7 +112,7 @@ void InfoError (const char* Format, ...)
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -125,13 +125,13 @@ static void NextChar (void)
 
     /* Count columns */
     if (C != EOF) {
-       ++InputCol;
+        ++InputCol;
     }
 
     /* Count lines */
     if (C == '\n') {
-       ++InputLine;
-       InputCol = 0;
+        ++InputLine;
+        InputCol = 0;
     }
 }
 
@@ -141,9 +141,9 @@ static unsigned DigitVal (int C)
 /* Return the value for a numeric digit */
 {
     if (IsDigit (C)) {
-       return C - '0';
+        return C - '0';
     } else {
-       return toupper (C) - 'A' + 10;
+        return toupper (C) - 'A' + 10;
     }
 }
 
@@ -153,12 +153,12 @@ void InfoNextTok (void)
 /* Read the next token from the input stream */
 {
     unsigned I;
-
+    int      Esc;
 
 Again:
     /* Skip whitespace */
     while (IsSpace (C)) {
-       NextChar ();
+        NextChar ();
     }
 
     /* Remember the current position */
@@ -168,99 +168,110 @@ Again:
     /* Identifier? */
     if (C == '_' || IsAlpha (C)) {
 
-       /* Read the identifier */
-       I = 0;
-       while (C == '_' || IsAlNum (C)) {
-           if (I < CFG_MAX_IDENT_LEN) {
-               InfoSVal [I++] = C;
-           }
-           NextChar ();
-       }
-       InfoSVal [I] = '\0';
-       InfoTok = INFOTOK_IDENT;
-       return;
+        /* Read the identifier */
+        I = 0;
+        while (C == '_' || IsAlNum (C)) {
+            if (I < CFG_MAX_IDENT_LEN) {
+                InfoSVal [I++] = C;
+            }
+            NextChar ();
+        }
+        InfoSVal [I] = '\0';
+        InfoTok = INFOTOK_IDENT;
+        return;
     }
 
     /* Hex number? */
     if (C == '$') {
-       NextChar ();
-       if (!IsXDigit (C)) {
-           InfoError ("Hex digit expected");
-       }
-       InfoIVal = 0;
-       while (IsXDigit (C)) {
-                   InfoIVal = InfoIVal * 16 + DigitVal (C);
-           NextChar ();
-       }
-       InfoTok = INFOTOK_INTCON;
-       return;
+        NextChar ();
+        if (!IsXDigit (C)) {
+            InfoError ("Hex digit expected");
+        }
+        InfoIVal = 0;
+        while (IsXDigit (C)) {
+            InfoIVal = InfoIVal * 16 + DigitVal (C);
+            NextChar ();
+        }
+        InfoTok = INFOTOK_INTCON;
+        return;
     }
 
     /* Decimal number? */
     if (IsDigit (C)) {
-       InfoIVal = 0;
-       while (IsDigit (C)) {
-                   InfoIVal = InfoIVal * 10 + DigitVal (C);
-           NextChar ();
-       }
-       InfoTok = INFOTOK_INTCON;
-       return;
+        InfoIVal = 0;
+        while (IsDigit (C)) {
+            InfoIVal = InfoIVal * 10 + DigitVal (C);
+            NextChar ();
+        }
+        InfoTok = INFOTOK_INTCON;
+        return;
     }
 
     /* Other characters */
     switch (C) {
 
-       case '{':
-           NextChar ();
-           InfoTok = INFOTOK_LCURLY;
-           break;
+        case '{':
+            NextChar ();
+            InfoTok = INFOTOK_LCURLY;
+            break;
 
-       case '}':
-           NextChar ();
-           InfoTok = INFOTOK_RCURLY;
-           break;
+        case '}':
+            NextChar ();
+            InfoTok = INFOTOK_RCURLY;
+            break;
 
-       case ';':
-           NextChar ();
-           InfoTok = INFOTOK_SEMI;
-           break;
+        case ';':
+            NextChar ();
+            InfoTok = INFOTOK_SEMI;
+            break;
 
-       case '.':
-           NextChar ();
-           InfoTok = INFOTOK_DOT;
-           break;
+        case '.':
+            NextChar ();
+            InfoTok = INFOTOK_DOT;
+            break;
 
-       case ',':
-           NextChar ();
-           InfoTok = INFOTOK_COMMA;
-           break;
+        case ',':
+            NextChar ();
+            InfoTok = INFOTOK_COMMA;
+            break;
 
-       case '=':
-           NextChar ();
-           InfoTok = INFOTOK_EQ;
-           break;
+        case '=':
+            NextChar ();
+            InfoTok = INFOTOK_EQ;
+            break;
 
         case ':':
-           NextChar ();
-           InfoTok = INFOTOK_COLON;
-           break;
+            NextChar ();
+            InfoTok = INFOTOK_COLON;
+            break;
 
         case '\"':
-           NextChar ();
-           I = 0;
-           while (C != '\"') {
-               if (C == EOF || C == '\n') {
-                   InfoError ("Unterminated string");
-               }
-               if (I < CFG_MAX_IDENT_LEN) {
-                   InfoSVal [I++] = C;
-               }
-               NextChar ();
-           }
-                   NextChar ();
-           InfoSVal [I] = '\0';
-           InfoTok = INFOTOK_STRCON;
-           break;
+            NextChar ();
+            I = 0;
+            while (C != '\"') {
+                Esc = (C == '\\');
+                if (Esc) {
+                    NextChar ();
+                }
+                if (C == EOF || C == '\n') {
+                    InfoError ("Unterminated string");
+                }
+                if (Esc) {
+                    switch (C) {
+                        case '\"':      C = '\"';       break;
+                        case '\'':      C = '\'';       break;
+                        default:        InfoError ("Invalid escape char: %c", C);
+                    }
+                }
+                if (I < CFG_MAX_IDENT_LEN) {
+                    InfoSVal [I++] = C;
+                }
+                NextChar ();
+            }
+            NextChar ();
+            InfoSVal [I] = '\0';
+            InfoTok = INFOTOK_STRCON;
+            break;
 
         case '\'':
             NextChar ();
@@ -277,22 +288,22 @@ Again:
             break;
 
         case '#':
-           /* Comment */
-           while (C != '\n' && C != EOF) {
-               NextChar ();
-           }
-           if (C != EOF) {
-               goto Again;
-           }
-           InfoTok = INFOTOK_EOF;
-           break;
+            /* Comment */
+            while (C != '\n' && C != EOF) {
+                NextChar ();
+            }
+            if (C != EOF) {
+                goto Again;
+            }
+            InfoTok = INFOTOK_EOF;
+            break;
 
         case EOF:
-           InfoTok = INFOTOK_EOF;
-           break;
+            InfoTok = INFOTOK_EOF;
+            break;
 
-       default:
-           InfoError ("Invalid character `%c'", C);
+        default:
+            InfoError ("Invalid character `%c'", C);
 
     }
 }
@@ -303,7 +314,7 @@ void InfoConsume (unsigned T, const char* Msg)
 /* Skip a token, print an error message if not found */
 {
     if (InfoTok != T) {
-               InfoError (Msg);
+        InfoError (Msg);
     }
     InfoNextTok ();
 }
@@ -346,7 +357,7 @@ void InfoOptionalComma (void)
 /* Consume a comma if there is one */
 {
     if (InfoTok == INFOTOK_COMMA) {
-               InfoNextTok ();
+        InfoNextTok ();
     }
 }
 
@@ -356,7 +367,7 @@ void InfoOptionalAssign (void)
 /* Consume an equal sign if there is one */
 {
     if (InfoTok == INFOTOK_EQ) {
-               InfoNextTok ();
+        InfoNextTok ();
     }
 }
 
@@ -366,7 +377,7 @@ void InfoAssureInt (void)
 /* Make sure the next token is an integer */
 {
     if (InfoTok != INFOTOK_INTCON) {
-               InfoError ("Integer constant expected");
+        InfoError ("Integer constant expected");
     }
 }
 
@@ -376,7 +387,7 @@ void InfoAssureStr (void)
 /* Make sure the next token is a string constant */
 {
     if (InfoTok != INFOTOK_STRCON) {
-               InfoError ("String constant expected");
+        InfoError ("String constant expected");
     }
 }
 
@@ -386,7 +397,7 @@ void InfoAssureChar (void)
 /* Make sure the next token is a char constant */
 {
     if (InfoTok != INFOTOK_STRCON) {
-               InfoError ("Character constant expected");
+        InfoError ("Character constant expected");
     }
 }
 
@@ -396,7 +407,7 @@ void InfoAssureIdent (void)
 /* Make sure the next token is an identifier */
 {
     if (InfoTok != INFOTOK_IDENT) {
-               InfoError ("Identifier expected");
+        InfoError ("Identifier expected");
     }
 }
 
@@ -406,7 +417,7 @@ void InfoRangeCheck (long Lo, long Hi)
 /* Check the range of InfoIVal */
 {
     if (InfoIVal < Lo || InfoIVal > Hi) {
-       InfoError ("Range error");
+        InfoError ("Range error");
     }
 }
 
@@ -420,20 +431,20 @@ void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
     /* We need an identifier */
     if (InfoTok == INFOTOK_IDENT) {
 
-       /* Make it upper case */
-       I = 0;
-       while (InfoSVal [I]) {
-           InfoSVal [I] = toupper (InfoSVal [I]);
-           ++I;
-       }
-
-               /* Linear search */
-       for (I = 0; I < Size; ++I) {
-           if (strcmp (InfoSVal, Table [I].Ident) == 0) {
-               InfoTok = Table [I].Tok;
-               return;
-           }
-       }
+        /* Make it upper case */
+        I = 0;
+        while (InfoSVal [I]) {
+            InfoSVal [I] = toupper (InfoSVal [I]);
+            ++I;
+        }
+
+        /* Linear search */
+        for (I = 0; I < Size; ++I) {
+            if (strcmp (InfoSVal, Table [I].Ident) == 0) {
+                InfoTok = Table [I].Tok;
+                return;
+            }
+        }
 
     }
 
@@ -447,23 +458,23 @@ void InfoBoolToken (void)
 /* Map an identifier or integer to a boolean token */
 {
     static const IdentTok Booleans [] = {
-               {   "YES",      INFOTOK_TRUE     },
-       {   "NO",       INFOTOK_FALSE    },
+        {   "YES",      INFOTOK_TRUE     },
+        {   "NO",       INFOTOK_FALSE    },
         {   "TRUE",     INFOTOK_TRUE     },
         {   "FALSE",    INFOTOK_FALSE    },
-               {   "ON",       INFOTOK_TRUE     },
-       {   "OFF",      INFOTOK_FALSE    },
+        {   "ON",       INFOTOK_TRUE     },
+        {   "OFF",      INFOTOK_FALSE    },
     };
 
     /* If we have an identifier, map it to a boolean token */
     if (InfoTok == INFOTOK_IDENT) {
-       InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
+        InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
     } else {
-       /* We expected an integer here */
-       if (InfoTok != INFOTOK_INTCON) {
-           InfoError ("Boolean value expected");
-       }
-       InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
+        /* We expected an integer here */
+        if (InfoTok != INFOTOK_INTCON) {
+            InfoError ("Boolean value expected");
+        }
+        InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
     }
 }
 
@@ -519,10 +530,6 @@ void InfoCloseInput (void)
     /* Close the input file if we had one */
     if (InputFile) {
         (void) fclose (InputFile);
-       InputFile = 0;
+        InputFile = 0;
     }
 }
-
-
-
-