]> git.sur5r.net Git - cc65/blobdiff - src/da65/scanner.c
add gotox, gotoy, and gotoxy
[cc65] / src / da65 / scanner.c
index 19f5dad868ab4e95040fcbdb1a8c573ecabce8af..dab5ffe98fd902ae46e9e8c1449b002730c33b9a 100644 (file)
@@ -1,15 +1,15 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                scanner.c                                 */
+/*                                 scanner.c                                 */
 /*                                                                           */
-/*          Configuration file scanner for the da65 disassembler            */
+/*           Configuration file scanner for the da65 disassembler            */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 2000-2005 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -37,9 +37,9 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
-#include <ctype.h>
 
 /* common */
+#include "chartype.h"
 #include "xsprintf.h"
 
 /* ld65 */
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
 
 /* Current token and attributes */
-unsigned        CfgTok;
-char                   CfgSVal [CFG_MAX_IDENT_LEN+1];
-long            CfgIVal;
+unsigned        InfoTok;
+char            InfoSVal [CFG_MAX_IDENT_LEN+1];
+long            InfoIVal;
 
 /* Error location */
-unsigned               CfgErrorLine;
-unsigned               CfgErrorCol;
+unsigned                InfoErrorLine;
+unsigned                InfoErrorCol;
 
 /* Input sources for the configuration */
-static const char*             CfgFile         = 0;
-static const char*      CfgBuf                 = 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                               */
 /*****************************************************************************/
 
 
 
-void CfgWarning (const char* Format, ...)
+void InfoWarning (const char* Format, ...)
 /* Print a warning message adding file name and line number of the config file */
 {
     char Buf [512];
@@ -92,12 +91,12 @@ void CfgWarning (const char* Format, ...)
     xvsprintf (Buf, sizeof (Buf), Format, ap);
     va_end (ap);
 
-    Warning ("%s(%u): %s", CfgFile, CfgErrorLine, Buf);
+    Warning ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
 }
 
 
 
-void CfgError (const char* Format, ...)
+void InfoError (const char* Format, ...)
 /* Print an error message adding file name and line number of the config file */
 {
     char Buf [512];
@@ -107,13 +106,13 @@ void CfgError (const char* Format, ...)
     xvsprintf (Buf, sizeof (Buf), Format, ap);
     va_end (ap);
 
-    Error ("%s(%u): %s", CfgFile, CfgErrorLine, Buf);
+    Error ("%s(%u): %s", InfoFile, InfoErrorLine, Buf);
 }
 
 
 
 /*****************************************************************************/
-/*                                          Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
@@ -121,28 +120,18 @@ void CfgError (const char* Format, ...)
 static void NextChar (void)
 /* Read the next character from the input file */
 {
-    if (CfgBuf) {
-       /* Read from buffer */
-       C = (unsigned char)(*CfgBuf);
-       if (C == 0) {
-           C = EOF;
-       } else {
-           ++CfgBuf;
-       }
-    } else {
-       /* Read from the file */
-       C = getc (InputFile);
-    }
+    /* Read from the file */
+    C = getc (InputFile);
 
     /* Count columns */
     if (C != EOF) {
-       ++InputCol;
+        ++InputCol;
     }
 
     /* Count lines */
     if (C == '\n') {
-       ++InputLine;
-       InputCol = 0;
+        ++InputLine;
+        InputCol = 0;
     }
 }
 
@@ -151,355 +140,377 @@ static void NextChar (void)
 static unsigned DigitVal (int C)
 /* Return the value for a numeric digit */
 {
-    if (isdigit (C)) {
-       return C - '0';
+    if (IsDigit (C)) {
+        return C - '0';
     } else {
-       return toupper (C) - 'A' + 10;
+        return toupper (C) - 'A' + 10;
     }
 }
 
 
 
-void CfgNextTok (void)
+void InfoNextTok (void)
 /* Read the next token from the input stream */
 {
     unsigned I;
-
+    int      Esc;
 
 Again:
     /* Skip whitespace */
-    while (isspace (C)) {
-       NextChar ();
+    while (IsSpace (C)) {
+        NextChar ();
     }
 
     /* Remember the current position */
-    CfgErrorLine = InputLine;
-    CfgErrorCol  = InputCol;
+    InfoErrorLine = InputLine;
+    InfoErrorCol  = InputCol;
 
     /* Identifier? */
-    if (C == '_' || isalpha (C)) {
-
-       /* Read the identifier */
-       I = 0;
-       while (C == '_' || isalnum (C)) {
-           if (I < CFG_MAX_IDENT_LEN) {
-               CfgSVal [I++] = C;
-           }
-           NextChar ();
-       }
-       CfgSVal [I] = '\0';
-       CfgTok = CFGTOK_IDENT;
-       return;
+    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;
     }
 
     /* Hex number? */
     if (C == '$') {
-       NextChar ();
-       if (!isxdigit (C)) {
-           CfgError ("Hex digit expected");
-       }
-       CfgIVal = 0;
-       while (isxdigit (C)) {
-                   CfgIVal = CfgIVal * 16 + DigitVal (C);
-           NextChar ();
-       }
-       CfgTok = CFGTOK_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)) {
-       CfgIVal = 0;
-       while (isdigit (C)) {
-                   CfgIVal = CfgIVal * 10 + DigitVal (C);
-           NextChar ();
-       }
-       CfgTok = CFGTOK_INTCON;
-       return;
+    if (IsDigit (C)) {
+        InfoIVal = 0;
+        while (IsDigit (C)) {
+            InfoIVal = InfoIVal * 10 + DigitVal (C);
+            NextChar ();
+        }
+        InfoTok = INFOTOK_INTCON;
+        return;
     }
 
     /* Other characters */
     switch (C) {
 
-       case '{':
-           NextChar ();
-           CfgTok = CFGTOK_LCURLY;
-           break;
+        case '{':
+            NextChar ();
+            InfoTok = INFOTOK_LCURLY;
+            break;
 
-       case '}':
-           NextChar ();
-           CfgTok = CFGTOK_RCURLY;
-           break;
+        case '}':
+            NextChar ();
+            InfoTok = INFOTOK_RCURLY;
+            break;
 
-       case ';':
-           NextChar ();
-           CfgTok = CFGTOK_SEMI;
-           break;
+        case ';':
+            NextChar ();
+            InfoTok = INFOTOK_SEMI;
+            break;
 
-       case '.':
-           NextChar ();
-           CfgTok = CFGTOK_DOT;
-           break;
+        case '.':
+            NextChar ();
+            InfoTok = INFOTOK_DOT;
+            break;
 
-       case ',':
-           NextChar ();
-           CfgTok = CFGTOK_COMMA;
-           break;
+        case ',':
+            NextChar ();
+            InfoTok = INFOTOK_COMMA;
+            break;
 
-       case '=':
-           NextChar ();
-           CfgTok = CFGTOK_EQ;
-           break;
+        case '=':
+            NextChar ();
+            InfoTok = INFOTOK_EQ;
+            break;
 
         case ':':
-           NextChar ();
-           CfgTok = CFGTOK_COLON;
-           break;
+            NextChar ();
+            InfoTok = INFOTOK_COLON;
+            break;
 
         case '\"':
-           NextChar ();
-           I = 0;
-           while (C != '\"') {
-               if (C == EOF || C == '\n') {
-                   CfgError ("Unterminated string");
-               }
-               if (I < CFG_MAX_IDENT_LEN) {
-                   CfgSVal [I++] = C;
-               }
-               NextChar ();
-           }
-                   NextChar ();
-           CfgSVal [I] = '\0';
-           CfgTok = CFGTOK_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 ();
+            if (C == EOF || IsControl (C)) {
+                InfoError ("Invalid character constant");
+            }
+            InfoIVal = C;
+            NextChar ();
+            if (C != '\'') {
+                InfoError ("Unterminated character constant");
+            }
+            NextChar ();
+            InfoTok = INFOTOK_CHARCON;
+            break;
 
         case '#':
-           /* Comment */
-           while (C != '\n' && C != EOF) {
-               NextChar ();
-           }
-           if (C != EOF) {
-               goto Again;
-           }
-           CfgTok = CFGTOK_EOF;
-           break;
+            /* Comment */
+            while (C != '\n' && C != EOF) {
+                NextChar ();
+            }
+            if (C != EOF) {
+                goto Again;
+            }
+            InfoTok = INFOTOK_EOF;
+            break;
 
         case EOF:
-           CfgTok = CFGTOK_EOF;
-           break;
+            InfoTok = INFOTOK_EOF;
+            break;
 
-       default:
-           CfgError ("Invalid character `%c'", C);
+        default:
+            InfoError ("Invalid character `%c'", C);
 
     }
 }
 
 
 
-void CfgConsume (unsigned T, const char* Msg)
+void InfoConsume (unsigned T, const char* Msg)
 /* Skip a token, print an error message if not found */
 {
-    if (CfgTok != T) {
-               CfgError (Msg);
+    if (InfoTok != T) {
+        InfoError (Msg);
     }
-    CfgNextTok ();
+    InfoNextTok ();
 }
 
 
 
-void CfgConsumeLCurly (void)
+void InfoConsumeLCurly (void)
 /* Consume a left curly brace */
 {
-    CfgConsume (CFGTOK_LCURLY, "`{' expected");
+    InfoConsume (INFOTOK_LCURLY, "`{' expected");
 }
 
 
 
-void CfgConsumeRCurly (void)
+void InfoConsumeRCurly (void)
 /* Consume a right curly brace */
 {
-    CfgConsume (CFGTOK_RCURLY, "`}' expected");
+    InfoConsume (INFOTOK_RCURLY, "`}' expected");
 }
 
 
 
-void CfgConsumeSemi (void)
+void InfoConsumeSemi (void)
 /* Consume a semicolon */
 {
-    CfgConsume (CFGTOK_SEMI, "`;' expected");
+    InfoConsume (INFOTOK_SEMI, "`;' expected");
 }
 
 
 
-void CfgConsumeColon (void)
+void InfoConsumeColon (void)
 /* Consume a colon */
 {
-    CfgConsume (CFGTOK_COLON, "`:' expected");
+    InfoConsume (INFOTOK_COLON, "`:' expected");
 }
 
 
 
-void CfgOptionalComma (void)
+void InfoOptionalComma (void)
 /* Consume a comma if there is one */
 {
-    if (CfgTok == CFGTOK_COMMA) {
-               CfgNextTok ();
+    if (InfoTok == INFOTOK_COMMA) {
+        InfoNextTok ();
     }
 }
 
 
 
-void CfgOptionalAssign (void)
+void InfoOptionalAssign (void)
 /* Consume an equal sign if there is one */
 {
-    if (CfgTok == CFGTOK_EQ) {
-               CfgNextTok ();
+    if (InfoTok == INFOTOK_EQ) {
+        InfoNextTok ();
     }
 }
 
 
 
-void CfgAssureInt (void)
+void InfoAssureInt (void)
 /* Make sure the next token is an integer */
 {
-    if (CfgTok != CFGTOK_INTCON) {
-               CfgError ("Integer constant expected");
+    if (InfoTok != INFOTOK_INTCON) {
+        InfoError ("Integer constant expected");
     }
 }
 
 
 
-void CfgAssureStr (void)
+void InfoAssureStr (void)
 /* Make sure the next token is a string constant */
 {
-    if (CfgTok != CFGTOK_STRCON) {
-               CfgError ("String constant expected");
+    if (InfoTok != INFOTOK_STRCON) {
+        InfoError ("String constant expected");
+    }
+}
+
+
+
+void InfoAssureChar (void)
+/* Make sure the next token is a char constant */
+{
+    if (InfoTok != INFOTOK_STRCON) {
+        InfoError ("Character constant expected");
     }
 }
 
 
 
-void CfgAssureIdent (void)
+void InfoAssureIdent (void)
 /* Make sure the next token is an identifier */
 {
-    if (CfgTok != CFGTOK_IDENT) {
-               CfgError ("Identifier expected");
+    if (InfoTok != INFOTOK_IDENT) {
+        InfoError ("Identifier expected");
     }
 }
 
 
 
-void CfgRangeCheck (long Lo, long Hi)
-/* Check the range of CfgIVal */
+void InfoRangeCheck (long Lo, long Hi)
+/* Check the range of InfoIVal */
 {
-    if (CfgIVal < Lo || CfgIVal > Hi) {
-       CfgError ("Range error");
+    if (InfoIVal < Lo || InfoIVal > Hi) {
+        InfoError ("Range error");
     }
 }
 
 
 
-void CfgSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
+void InfoSpecialToken (const IdentTok* Table, unsigned Size, const char* Name)
 /* Map an identifier to one of the special tokens in the table */
 {
     unsigned I;
 
     /* We need an identifier */
-    if (CfgTok == CFGTOK_IDENT) {
-
-       /* Make it upper case */
-       I = 0;
-       while (CfgSVal [I]) {
-           CfgSVal [I] = toupper (CfgSVal [I]);
-           ++I;
-       }
-
-               /* Linear search */
-       for (I = 0; I < Size; ++I) {
-           if (strcmp (CfgSVal, Table [I].Ident) == 0) {
-               CfgTok = Table [I].Tok;
-               return;
-           }
-       }
+    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;
+            }
+        }
 
     }
 
     /* Not found or no identifier */
-    CfgError ("%s expected", Name);
+    InfoError ("%s expected", Name);
 }
 
 
 
-void CfgBoolToken (void)
+void InfoBoolToken (void)
 /* Map an identifier or integer to a boolean token */
 {
     static const IdentTok Booleans [] = {
-               {   "YES",      CFGTOK_TRUE     },
-       {   "NO",       CFGTOK_FALSE    },
-        {   "TRUE",     CFGTOK_TRUE     },
-        {   "FALSE",    CFGTOK_FALSE    },
+        {   "YES",      INFOTOK_TRUE     },
+        {   "NO",       INFOTOK_FALSE    },
+        {   "TRUE",     INFOTOK_TRUE     },
+        {   "FALSE",    INFOTOK_FALSE    },
+        {   "ON",       INFOTOK_TRUE     },
+        {   "OFF",      INFOTOK_FALSE    },
     };
 
     /* If we have an identifier, map it to a boolean token */
-    if (CfgTok == CFGTOK_IDENT) {
-       CfgSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
+    if (InfoTok == INFOTOK_IDENT) {
+        InfoSpecialToken (Booleans, ENTRY_COUNT (Booleans), "Boolean");
     } else {
-       /* We expected an integer here */
-       if (CfgTok != CFGTOK_INTCON) {
-           CfgError ("Boolean value expected");
-       }
-       CfgTok = (CfgIVal == 0)? CFGTOK_FALSE : CFGTOK_TRUE;
+        /* We expected an integer here */
+        if (InfoTok != INFOTOK_INTCON) {
+            InfoError ("Boolean value expected");
+        }
+        InfoTok = (InfoIVal == 0)? INFOTOK_FALSE : INFOTOK_TRUE;
     }
 }
 
 
 
-void CfgSetName (const char* Name)
+void InfoSetName (const char* Name)
 /* Set a name for a config file */
 {
-    CfgFile = Name;
+    InfoFile = Name;
 }
 
 
 
-const char* CfgGetName (void)
+const char* InfoGetName (void)
 /* Get the name of the config file */
 {
-    return CfgFile? CfgFile : "";
-}
-
-
-
-void CfgSetBuf (const char* Buf)
-/* Set a memory buffer for the config */
-{
-    CfgBuf = Buf;
+    return InfoFile? InfoFile : "";
 }
 
 
 
-int CfgAvail (void)
-/* Return true if we have a configuration available */
+int InfoAvail ()
+/* Return true if we have an info file given */
 {
-    return CfgFile != 0 || CfgBuf != 0;
+    return (InfoFile != 0);
 }
 
 
 
-void CfgOpenInput (void)
-/* Open the input file if we have one */
+void InfoOpenInput (void)
+/* Open the input file */
 {
-    /* If we have a config name given, open the file, otherwise we will read
-     * from a buffer.
-     */
-    if (!CfgBuf) {
-
-       /* Open the file */
-       InputFile = fopen (CfgFile, "r");
-       if (InputFile == 0) {
-           Error ("Cannot open `%s': %s", CfgFile, strerror (errno));
-       }
-
+    /* Open the file */
+    InputFile = fopen (InfoFile, "r");
+    if (InputFile == 0) {
+        Error ("Cannot open `%s': %s", InfoFile, strerror (errno));
     }
 
     /* Initialize variables */
@@ -508,18 +519,18 @@ void CfgOpenInput (void)
     InputCol  = 0;
 
     /* Start the ball rolling ... */
-    CfgNextTok ();
+    InfoNextTok ();
 }
 
 
 
-void CfgCloseInput (void)
+void InfoCloseInput (void)
 /* Close the input file if we have one */
 {
     /* Close the input file if we had one */
     if (InputFile) {
         (void) fclose (InputFile);
-       InputFile = 0;
+        InputFile = 0;
     }
 }