]> git.sur5r.net Git - cc65/blobdiff - src/ca65/scanner.c
Finished implemenation of commands to delete macros. Added the new commands to
[cc65] / src / ca65 / scanner.c
index cc2bde590a91c7ddf3ac23cc46b0a7950dffded3..723978a864b492c68cac3b9eaba10cc8804999a1 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2010, Ullrich von Bassewitz                                      */
+/* (C) 1998-2011, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 
 
 
-Token Tok = TOK_NONE;                   /* Current token */
-int WS;                                        /* Flag: Whitespace before token */
-long IVal;                             /* Integer token attribute */
-StrBuf SVal = STATIC_STRBUF_INITIALIZER;/* String token attribute */
-
-FilePos        CurPos = { 0, 0, 0 };           /* Name and position in current file */
-
-
+/* Current input token incl. attributes */
+Token CurTok = STATIC_TOKEN_INITIALIZER;
 
 /* Struct to handle include files. */
 typedef struct InputFile InputFile;
 struct InputFile {
     FILE*                  F;                  /* Input file descriptor */
     FilePos        Pos;                /* Position in file */
-    Token           Tok;               /* Last token */
+    token_t         Tok;               /* Last token */
     int                    C;                  /* Last character */
     char                   Line[256];          /* The current input line */
+    int             IncSearchPath;      /* True if we've added a search path */
+    int             BinSearchPath;      /* True if we've added a search path */
     InputFile*     Next;               /* Linked list of input files */
 };
 
@@ -96,7 +92,7 @@ struct InputData {
     char*                  Text;               /* Pointer to the text data */
     const char*     Pos;               /* Pointer to current position */
     int                    Malloced;           /* Memory was malloced */
-    Token           Tok;               /* Last token */
+    token_t         Tok;               /* Last token */
     int                    C;                  /* Last character */
     InputData*     Next;               /* Linked list of input data */
 };
@@ -115,7 +111,7 @@ struct CharSourceFunctions {
 /* Input source: Either file or data */
 struct CharSource {
     CharSource*                 Next;   /* Linked list of char sources */
-    Token                       Tok;   /* Last token */
+    token_t                     Tok;   /* Last token */
     int                                C;      /* Last character */
     const CharSourceFunctions*  Func;   /* Pointer to function table */
     union {
@@ -135,7 +131,7 @@ int                   ForcedEnd     = 0;
 /* List of dot keywords with the corresponding tokens */
 struct DotKeyword {
     const char*        Key;                    /* MUST be first field */
-    Token       Tok;
+    token_t     Tok;
 } DotKeywords [] = {
     { ".A16",                  TOK_A16         },
     { ".A8",                   TOK_A8          },
@@ -170,6 +166,8 @@ struct DotKeyword {
     { ".DEF",          TOK_DEFINED     },
     { ".DEFINE",       TOK_DEFINE      },
     { ".DEFINED",      TOK_DEFINED     },
+    { ".DELMAC",        TOK_DELMAC      },
+    { ".DELMACRO",      TOK_DELMAC      },
     { ".DESTRUCTOR",   TOK_DESTRUCTOR  },
     { ".DWORD",        TOK_DWORD       },
     { ".ELSE",         TOK_ELSE        },
@@ -192,6 +190,7 @@ struct DotKeyword {
     { ".EXPORT",       TOK_EXPORT      },
     { ".EXPORTZP",     TOK_EXPORTZP    },
     { ".FARADDR",      TOK_FARADDR     },
+    { ".FATAL",         TOK_FATAL       },
     { ".FEATURE",      TOK_FEATURE     },
     { ".FILEOPT",      TOK_FILEOPT     },
     { ".FOPT",         TOK_FILEOPT     },
@@ -268,8 +267,8 @@ struct DotKeyword {
     { ".SEGMENT",      TOK_SEGMENT     },
     { ".SET",           TOK_SET         },
     { ".SETCPU",       TOK_SETCPU      },
-    { ".SHL",          TOK_SHL         },
-    { ".SHR",          TOK_SHR         },
+    { ".SHL",                  TOK_SHL         },
+    { ".SHR",                  TOK_SHR         },
     { ".SIZEOF",        TOK_SIZEOF      },
     { ".SMART",                TOK_SMART       },
     { ".SPRINTF",       TOK_SPRINTF     },
@@ -281,6 +280,8 @@ struct DotKeyword {
     { ".TAG",           TOK_TAG         },
     { ".TCOUNT",       TOK_TCOUNT      },
     { ".TIME",                 TOK_TIME        },
+    { ".UNDEF",         TOK_UNDEF       },
+    { ".UNDEFINE",      TOK_UNDEF       },
     { ".UNION",         TOK_UNION       },
     { ".VERSION",       TOK_VERSION     },
     { ".WARNING",      TOK_WARNING     },
@@ -302,7 +303,7 @@ static void UseCharSource (CharSource* S)
 /* Initialize a new input source and start to use it. */
 {
     /* Remember the current input char and token */
-    S->Tok      = Tok;
+    S->Tok      = CurTok.Tok;
     S->C        = C;
 
     /* Use the new input source */
@@ -315,7 +316,7 @@ static void UseCharSource (CharSource* S)
     /* Setup the next token so it will be skipped on the next call to
      * NextRawTok().
      */
-    Tok = TOK_SEP;
+    CurTok.Tok = TOK_SEP;
 }
 
 
@@ -329,7 +330,7 @@ static void DoneCharSource (void)
     Source->Func->Done (Source);
 
     /* Restore the old token */
-    Tok = Source->Tok;
+    CurTok.Tok = Source->Tok;
     C   = Source->C;
 
     /* Remember the last stacked input source */
@@ -347,13 +348,13 @@ static void DoneCharSource (void)
 /*****************************************************************************/
 /*                            InputFile functions                            */
 /*****************************************************************************/
-                                          
+
 
 
 static void IFMarkStart (CharSource* S)
 /* Mark the start of the next token */
 {
-    CurPos = S->V.File.Pos;
+    CurTok.Pos = S->V.File.Pos;
 }
 
 
@@ -418,6 +419,14 @@ void IFDone (CharSource* S)
      */
     CheckOpenIfs ();
 
+    /* If we've added search paths for this file, remove them */
+    if (S->V.File.IncSearchPath) {
+        PopSearchPath (IncSearchPath);
+    }
+    if (S->V.File.BinSearchPath) {
+        PopSearchPath (BinSearchPath);
+    }
+
     /* Close the input file and decrement the file count. We will ignore
      * errors here, since we were just reading from the file.
      */
@@ -441,70 +450,78 @@ int NewInputFile (const char* Name)
  * and false otherwise.
  */
 {
-    int RetCode = 0;            /* Return code. Assume an error. */
-    char* PathName = 0;
-
-    /* First try to open the file */
-    FILE* F = fopen (Name, "r");
-    if (F == 0) {
+    int         RetCode = 0;            /* Return code. Assume an error. */
+    char*       PathName = 0;
+    FILE*       F;
+    struct stat Buf;
+    StrBuf      NameBuf;                /* No need to initialize */
+    StrBuf      Path = AUTO_STRBUF_INITIALIZER;
+    unsigned    FileIdx;
+    CharSource* S;
 
-       /* Error (fatal error if this is the main file) */
-               if (FCount == 0) {
-           Fatal ("Cannot open input file `%s': %s", Name, strerror (errno));
-               }
 
+    /* If this is the main file, just try to open it. If it's an include file,
+     * search for it using the include path list.
+     */
+    if (FCount == 0) {
+        /* Main file */
+        F = fopen (Name, "r");
+        if (F == 0) {
+           Fatal ("Cannot open input file `%s': %s", Name, strerror (errno));
+        }
+    } else {
                /* We are on include level. Search for the file in the include
-        * directories.
-        */
-       PathName = FindInclude (Name, INC_STD);
+        * directories.
+        */
+       PathName = SearchFile (IncSearchPath, Name);
                if (PathName == 0 || (F = fopen (PathName, "r")) == 0) {
-           /* Not found or cannot open, print an error and bail out */
-           Error ("Cannot open include file `%s': %s", Name, strerror (errno));
+           /* Not found or cannot open, print an error and bail out */
+           Error ("Cannot open include file `%s': %s", Name, strerror (errno));
             goto ExitPoint;
-       }
+       }
 
                /* Use the path name from now on */
         Name = PathName;
     }
 
-    /* check again if we do now have an open file */
-    if (F != 0) {
-
-        StrBuf          NameBuf;
-       unsigned        FileIdx;
-        CharSource*     S;
-
-       /* Stat the file and remember the values. There a race condition here,
-         * since we cannot use fileno() (non standard identifier in standard
-         * header file), and therefore not fstat. When using stat with the
-         * file name, there's a risk that the file was deleted and recreated
-         * while it was open. Since mtime and size are only used to check
-         * if a file has changed in the debugger, we will ignore this problem
-         * here.
-         */
-       struct stat Buf;
-       if (stat (Name, &Buf) != 0) {
-           Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno));
-       }
-
-       /* Add the file to the input file table and remember the index */
-       FileIdx = AddFile (SB_InitFromString (&NameBuf, Name), Buf.st_size, Buf.st_mtime);
+    /* Stat the file and remember the values. There a race condition here,
+     * since we cannot use fileno() (non standard identifier in standard
+     * header file), and therefore not fstat. When using stat with the
+     * file name, there's a risk that the file was deleted and recreated
+     * while it was open. Since mtime and size are only used to check
+     * if a file has changed in the debugger, we will ignore this problem
+     * here.
+     */
+    if (stat (Name, &Buf) != 0) {
+        Fatal ("Cannot stat input file `%s': %s", Name, strerror (errno));
+    }
 
-               /* Create a new input source variable and initialize it */
-       S                   = xmalloc (sizeof (*S));
-        S->Func             = &IFFunc;
-       S->V.File.F         = F;
-       S->V.File.Pos.Line  = 0;
-       S->V.File.Pos.Col   = 0;
-       S->V.File.Pos.Name  = FileIdx;
-               S->V.File.Line[0]   = '\0';
+    /* Add the file to the input file table and remember the index */
+    FileIdx = AddFile (SB_InitFromString (&NameBuf, Name),
+                       (FCount == 0)? FT_MAIN : FT_INCLUDE,
+                       Buf.st_size, Buf.st_mtime);
 
-        /* Count active input files */
-               ++FCount;
+    /* Create a new input source variable and initialize it */
+    S                   = xmalloc (sizeof (*S));
+    S->Func             = &IFFunc;
+    S->V.File.F         = F;
+    S->V.File.Pos.Line  = 0;
+    S->V.File.Pos.Col   = 0;
+    S->V.File.Pos.Name  = FileIdx;
+    S->V.File.Line[0]   = '\0';
+
+    /* Push the path for this file onto the include search lists */
+    SB_CopyBuf (&Path, Name, FindName (Name) - Name);
+    SB_Terminate (&Path);
+    S->V.File.IncSearchPath = PushSearchPath (IncSearchPath, SB_GetConstBuf (&Path));
+    S->V.File.BinSearchPath = PushSearchPath (BinSearchPath, SB_GetConstBuf (&Path));
+    SB_Done (&Path);
+
+    /* Count active input files */
+    ++FCount;
 
-        /* Use this input source */
-        UseCharSource (S);
-    }
+    /* Use this input source */
+    UseCharSource (S);
 
     /* File successfully opened */
     RetCode = 1;
@@ -638,7 +655,7 @@ static void NextChar (void)
 void LocaseSVal (void)
 /* Make SVal lower case */
 {
-    SB_ToLower (&SVal);
+    SB_ToLower (&CurTok.SVal);
 }
 
 
@@ -646,7 +663,7 @@ void LocaseSVal (void)
 void UpcaseSVal (void)
 /* Make SVal upper case */
 {
-    SB_ToUpper (&SVal);
+    SB_ToUpper (&CurTok.SVal);
 }
 
 
@@ -659,7 +676,7 @@ static int CmpDotKeyword (const void* K1, const void* K2)
 
 
 
-static unsigned char FindDotKeyword (void)
+static token_t FindDotKeyword (void)
 /* Find the dot keyword in SVal. Return the corresponding token if found,
  * return TOK_NONE if not found.
  */
@@ -668,7 +685,7 @@ static unsigned char FindDotKeyword (void)
     struct DotKeyword* R;
 
     /* Initialize K */
-    K.Key = SB_GetConstBuf (&SVal);
+    K.Key = SB_GetConstBuf (&CurTok.SVal);
     K.Tok = 0;
 
     /* If we aren't in ignore case mode, we have to uppercase the keyword */
@@ -678,7 +695,7 @@ static unsigned char FindDotKeyword (void)
 
     /* Search for the keyword */
     R = bsearch (&K, DotKeywords, sizeof (DotKeywords) / sizeof (DotKeywords [0]),
-                sizeof (DotKeywords [0]), CmpDotKeyword);
+                sizeof (DotKeywords [0]), CmpDotKeyword);
     if (R != 0) {
        return R->Tok;
     } else {
@@ -697,10 +714,10 @@ static void ReadIdent (void)
 {
     /* Read the identifier */
     do {
-        SB_AppendChar (&SVal, C);
+        SB_AppendChar (&CurTok.SVal, C);
        NextChar ();
     } while (IsIdChar (C));
-    SB_Terminate (&SVal);
+    SB_Terminate (&CurTok.SVal);
 
     /* If we should ignore case, convert the identifier to upper case */
     if (IgnoreCase) {
@@ -727,7 +744,7 @@ static void ReadStringConst (int StringTerm)
        }
 
                /* Append the char to the string */
-        SB_AppendChar (&SVal, C);
+        SB_AppendChar (&CurTok.SVal, C);
 
        /* Skip the character */
        NextChar ();
@@ -737,7 +754,7 @@ static void ReadStringConst (int StringTerm)
     NextChar ();
 
     /* Terminate the string */
-    SB_Terminate (&SVal);
+    SB_Terminate (&CurTok.SVal);
 }
 
 
@@ -776,19 +793,24 @@ void NextRawTok (void)
 {
     /* If we've a forced end of assembly, don't read further */
     if (ForcedEnd) {
-       Tok = TOK_EOF;
+       CurTok.Tok = TOK_EOF;
        return;
     }
 
 Restart:
     /* Check if we have tokens from another input source */
     if (InputFromStack ()) {
-       return;
+        if (CurTok.Tok == TOK_IDENT && IsDefine (&CurTok.SVal)) {
+            /* This is a define style macro - expand it */
+            MacExpandStart ();
+            goto Restart;
+        }
+        return;
     }
 
 Again:
     /* Skip whitespace, remember if we had some */
-    if ((WS = IsBlank (C)) != 0) {
+    if ((CurTok.WS = IsBlank (C)) != 0) {
        do {
            NextChar ();
         } while (IsBlank (C));
@@ -798,7 +820,10 @@ Again:
     Source->Func->MarkStart (Source);
 
     /* Clear the string attribute */
-    SB_Clear (&SVal);
+    SB_Clear (&CurTok.SVal);
+
+    /* Generate line info for the current token */
+    GenLineInfo (LI_SLOT_ASM, &CurTok.Pos);
 
     /* Hex number or PC symbol? */
     if (C == '$') {
@@ -807,7 +832,7 @@ Again:
        /* Hex digit must follow or DollarIsPC must be enabled */
        if (!IsXDigit (C)) {
            if (DollarIsPC) {
-               Tok = TOK_PC;
+               CurTok.Tok = TOK_PC;
                return;
            } else {
                Error ("Hexadecimal digit expected");
@@ -815,18 +840,18 @@ Again:
        }
 
        /* Read the number */
-       IVal = 0;
+       CurTok.IVal = 0;
        while (IsXDigit (C)) {
-           if (IVal & 0xF0000000) {
+           if (CurTok.IVal & 0xF0000000) {
                Error ("Overflow in hexadecimal number");
-               IVal = 0;
+               CurTok.IVal = 0;
            }
-           IVal = (IVal << 4) + DigitVal (C);
+           CurTok.IVal = (CurTok.IVal << 4) + DigitVal (C);
            NextChar ();
        }
 
        /* This is an integer constant */
-       Tok = TOK_INTCON;
+       CurTok.Tok = TOK_INTCON;
        return;
     }
 
@@ -840,18 +865,18 @@ Again:
        }
 
        /* Read the number */
-       IVal = 0;
+        CurTok.IVal = 0;
        while (IsBDigit (C)) {
-           if (IVal & 0x80000000) {
-               Error ("Overflow in binary number");
-               IVal = 0;
+           if (CurTok.IVal & 0x80000000) {
+               Error ("Overflow in binary number");
+               CurTok.IVal = 0;
            }
-           IVal = (IVal << 1) + DigitVal (C);
+           CurTok.IVal = (CurTok.IVal << 1) + DigitVal (C);
            NextChar ();
        }
 
        /* This is an integer constant */
-       Tok = TOK_INTCON;
+        CurTok.Tok = TOK_INTCON;
        return;
     }
 
@@ -896,24 +921,24 @@ Again:
         }
 
         /* Convert the number using the given base */
-       IVal = 0;
+        CurTok.IVal = 0;
         for (I = 0; I < Digits; ++I) {
-                   if (IVal > Max) {
+                   if (CurTok.IVal > Max) {
                        Error ("Number out of range");
-               IVal = 0;
+                CurTok.IVal = 0;
                 break;
            }
             DVal = DigitVal (Buf[I]);
             if (DVal > Base) {
                 Error ("Invalid digits in number");
-                IVal = 0;
+                CurTok.IVal = 0;
                 break;
             }
-           IVal = (IVal * Base) + DVal;
+           CurTok.IVal = (CurTok.IVal * Base) + DVal;
         }
 
        /* This is an integer constant */
-               Tok = TOK_INTCON;
+               CurTok.Tok = TOK_INTCON;
        return;
     }
 
@@ -927,36 +952,36 @@ Again:
                if (!IsIdStart (C)) {
 
            /* Just a dot */
-           Tok = TOK_DOT;
+           CurTok.Tok = TOK_DOT;
 
        } else {
 
            /* Read the remainder of the identifier */
-            SB_AppendChar (&SVal, '.');
+            SB_AppendChar (&CurTok.SVal, '.');
            ReadIdent ();
 
            /* Dot keyword, search for it */
-           Tok = FindDotKeyword ();
-           if (Tok == TOK_NONE) {
+           CurTok.Tok = FindDotKeyword ();
+           if (CurTok.Tok == TOK_NONE) {
 
                /* Not found */
                if (!LeadingDotInIdents) {
                    /* Invalid pseudo instruction */
-                   Error ("`%m%p' is not a recognized control command", &SVal);
+                   Error ("`%m%p' is not a recognized control command", &CurTok.SVal);
                    goto Again;
                }
 
                /* An identifier with a dot. Check if it's a define style
                 * macro.
                 */
-                       if (IsDefine (&SVal)) {
+                       if (IsDefine (&CurTok.SVal)) {
                    /* This is a define style macro - expand it */
                    MacExpandStart ();
                    goto Restart;
                }
 
                /* Just an identifier with a dot */
-               Tok = TOK_IDENT;
+               CurTok.Tok = TOK_IDENT;
            }
 
        }
@@ -968,7 +993,7 @@ Again:
      */
     if (CPU == CPU_SWEET16 && C == '@') {
         NextChar ();
-        Tok = TOK_AT;
+        CurTok.Tok = TOK_AT;
         return;
     }
 
@@ -979,13 +1004,13 @@ Again:
        ReadIdent ();
 
        /* Start character alone is not enough */
-        if (SB_GetLen (&SVal) == 1) {
+        if (SB_GetLen (&CurTok.SVal) == 1) {
            Error ("Invalid cheap local symbol");
                    goto Again;
        }
 
                /* A local identifier */
-       Tok = TOK_LOCAL_IDENT;
+        CurTok.Tok = TOK_LOCAL_IDENT;
        return;
     }
 
@@ -999,45 +1024,45 @@ Again:
                /* Check for special names. Bail out if we have identified the type of
         * the token. Go on if the token is an identifier.
         */
-        if (SB_GetLen (&SVal) == 1) {
-           switch (toupper (SB_AtUnchecked (&SVal, 0))) {
+        if (SB_GetLen (&CurTok.SVal) == 1) {
+           switch (toupper (SB_AtUnchecked (&CurTok.SVal, 0))) {
 
-               case 'A':
+               case 'A':
                     if (C == ':') {
                         NextChar ();
-                        Tok = TOK_OVERRIDE_ABS;
+                        CurTok.Tok = TOK_OVERRIDE_ABS;
                     } else {
-                       Tok = TOK_A;
+                       CurTok.Tok = TOK_A;
                     }
                    return;
 
                 case 'F':
                     if (C == ':') {
                         NextChar ();
-                        Tok = TOK_OVERRIDE_FAR;
+                        CurTok.Tok = TOK_OVERRIDE_FAR;
                        return;
                     }
                    break;
 
                case 'S':
                     if (CPU == CPU_65816) {
-                        Tok = TOK_S;
+                        CurTok.Tok = TOK_S;
                         return;
                     }
                     break;
 
                case 'X':
-                   Tok = TOK_X;
+                   CurTok.Tok = TOK_X;
                    return;
 
                case 'Y':
-                   Tok = TOK_Y;
+                   CurTok.Tok = TOK_Y;
                    return;
 
                 case 'Z':
                     if (C == ':') {
                         NextChar ();
-                        Tok = TOK_OVERRIDE_ZP;
+                        CurTok.Tok = TOK_OVERRIDE_ZP;
                        return;
                     }
                     break;
@@ -1046,22 +1071,23 @@ Again:
                    break;
            }
 
-       } else if (CPU == CPU_SWEET16 && (IVal = Sweet16Reg (&SVal)) >= 0) {
+       } else if (CPU == CPU_SWEET16 &&
+                  (CurTok.IVal = Sweet16Reg (&CurTok.SVal)) >= 0) {
 
             /* A sweet16 register number in sweet16 mode */
-            Tok = TOK_REG;
+            CurTok.Tok = TOK_REG;
             return;
 
         }
 
        /* Check for define style macro */
-               if (IsDefine (&SVal)) {
+               if (IsDefine (&CurTok.SVal)) {
            /* Macro - expand it */
            MacExpandStart ();
            goto Restart;
        } else {
            /* An identifier */
-           Tok = TOK_IDENT;
+           CurTok.Tok = TOK_IDENT;
        }
        return;
     }
@@ -1072,26 +1098,28 @@ CharAgain:
 
        case '+':
            NextChar ();
-           Tok = TOK_PLUS;
+           CurTok.Tok = TOK_PLUS;
            return;
 
        case '-':
            NextChar ();
-           Tok = TOK_MINUS;
+           CurTok.Tok = TOK_MINUS;
            return;
 
        case '/':
            NextChar ();
             if (C != '*') {
-                Tok = TOK_DIV;
+                CurTok.Tok = TOK_DIV;
             } else if (CComments) {
                 /* Remember the position, then skip the '*' */
-                FilePos Pos = CurPos;
+                Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
+                GetFullLineInfo (&LineInfos, 0);
                 NextChar ();
                 do {
                     while (C !=  '*') {
                         if (C == EOF) {
-                            PError (&Pos, "Unterminated comment");
+                            LIError (&LineInfos, "Unterminated comment");
+                            DoneCollection (&LineInfos);
                             goto CharAgain;
                         }
                         NextChar ();
@@ -1099,27 +1127,28 @@ CharAgain:
                     NextChar ();
                 } while (C != '/');
                 NextChar ();
+                DoneCollection (&LineInfos);
                 goto Again;
             }
            return;
 
        case '*':
            NextChar ();
-           Tok = TOK_MUL;
+           CurTok.Tok = TOK_MUL;
            return;
 
        case '^':
            NextChar ();
-           Tok = TOK_XOR;
+           CurTok.Tok = TOK_XOR;
            return;
 
        case '&':
            NextChar ();
            if (C == '&') {
                NextChar ();
-               Tok = TOK_BOOLAND;
+               CurTok.Tok = TOK_BOOLAND;
            } else {
-               Tok = TOK_AND;
+               CurTok.Tok = TOK_AND;
            }
                    return;
 
@@ -1127,9 +1156,9 @@ CharAgain:
            NextChar ();
            if (C == '|') {
                NextChar ();
-               Tok = TOK_BOOLOR;
+               CurTok.Tok = TOK_BOOLOR;
            } else {
-               Tok = TOK_OR;
+               CurTok.Tok = TOK_OR;
            }
            return;
 
@@ -1139,41 +1168,41 @@ CharAgain:
 
                case ':':
                    NextChar ();
-                   Tok = TOK_NAMESPACE;
+                   CurTok.Tok = TOK_NAMESPACE;
                    break;
 
                case '-':
-                   IVal = 0;
+                   CurTok.IVal = 0;
                    do {
-                       --IVal;
-                       NextChar ();
+                       --CurTok.IVal;
+                       NextChar ();
                    } while (C == '-');
-                   Tok = TOK_ULABEL;
+                   CurTok.Tok = TOK_ULABEL;
                    break;
 
                case '+':
-                   IVal = 0;
+                   CurTok.IVal = 0;
                    do {
-                       ++IVal;
+                       ++CurTok.IVal;
                        NextChar ();
                    } while (C == '+');
-                   Tok = TOK_ULABEL;
+                   CurTok.Tok = TOK_ULABEL;
                    break;
 
                 case '=':
                     NextChar ();
-                    Tok = TOK_ASSIGN;
+                    CurTok.Tok = TOK_ASSIGN;
                     break;
 
                default:
-                   Tok = TOK_COLON;
+                   CurTok.Tok = TOK_COLON;
                    break;
            }
            return;
 
        case ',':
            NextChar ();
-           Tok = TOK_COMMA;
+           CurTok.Tok = TOK_COMMA;
            return;
 
        case ';':
@@ -1185,81 +1214,81 @@ CharAgain:
 
        case '#':
            NextChar ();
-           Tok = TOK_HASH;
+           CurTok.Tok = TOK_HASH;
            return;
 
        case '(':
            NextChar ();
-           Tok = TOK_LPAREN;
+           CurTok.Tok = TOK_LPAREN;
            return;
 
        case ')':
                    NextChar ();
-            Tok = TOK_RPAREN;
+            CurTok.Tok = TOK_RPAREN;
            return;
 
        case '[':
            NextChar ();
-           Tok = TOK_LBRACK;
+           CurTok.Tok = TOK_LBRACK;
            return;
 
        case ']':
            NextChar ();
-           Tok = TOK_RBRACK;
+           CurTok.Tok = TOK_RBRACK;
            return;
 
        case '{':
            NextChar ();
-           Tok = TOK_LCURLY;
+           CurTok.Tok = TOK_LCURLY;
            return;
 
        case '}':
            NextChar ();
-           Tok = TOK_RCURLY;
+           CurTok.Tok = TOK_RCURLY;
            return;
 
        case '<':
            NextChar ();
            if (C == '=') {
                NextChar ();
-               Tok = TOK_LE;
+               CurTok.Tok = TOK_LE;
            } else if (C == '<') {
                NextChar ();
-               Tok = TOK_SHL;
+               CurTok.Tok = TOK_SHL;
            } else if (C == '>') {
                NextChar ();
-               Tok = TOK_NE;
+               CurTok.Tok = TOK_NE;
            } else {
-               Tok = TOK_LT;
+               CurTok.Tok = TOK_LT;
            }
            return;
 
        case '=':
            NextChar ();
-                   Tok = TOK_EQ;
+                   CurTok.Tok = TOK_EQ;
            return;
 
        case '!':
            NextChar ();
-           Tok = TOK_BOOLNOT;
+           CurTok.Tok = TOK_BOOLNOT;
            return;
 
        case '>':
            NextChar ();
            if (C == '=') {
                NextChar ();
-               Tok = TOK_GE;
+               CurTok.Tok = TOK_GE;
                    } else if (C == '>') {
                NextChar ();
-               Tok = TOK_SHR;
+               CurTok.Tok = TOK_SHR;
            } else {
-               Tok = TOK_GT;
+               CurTok.Tok = TOK_GT;
            }
            return;
 
         case '~':
            NextChar ();
-           Tok = TOK_NOT;
+           CurTok.Tok = TOK_NOT;
            return;
 
        case '\'':
@@ -1269,11 +1298,11 @@ CharAgain:
             */
            if (LooseStringTerm) {
                ReadStringConst ('\'');
-                if (SB_GetLen (&SVal) == 1) {
-                   IVal = SB_AtUnchecked (&SVal, 0);
-                   Tok = TOK_CHARCON;
+                if (SB_GetLen (&CurTok.SVal) == 1) {
+                   CurTok.IVal = SB_AtUnchecked (&CurTok.SVal, 0);
+                   CurTok.Tok = TOK_CHARCON;
                } else {
-                   Tok = TOK_STRCON;
+                   CurTok.Tok = TOK_STRCON;
                }
            } else {
                /* Always a character constant */
@@ -1282,8 +1311,8 @@ CharAgain:
                    Error ("Illegal character constant");
                    goto CharAgain;
                }
-               IVal = C;
-               Tok = TOK_CHARCON;
+               CurTok.IVal = C;
+               CurTok.Tok = TOK_CHARCON;
                NextChar ();
                if (C != '\'') {
                     if (!MissingCharTerm) {
@@ -1297,7 +1326,7 @@ CharAgain:
 
        case '\"':
            ReadStringConst ('\"');
-           Tok = TOK_STRCON;
+           CurTok.Tok = TOK_STRCON;
            return;
 
        case '\\':
@@ -1315,7 +1344,7 @@ CharAgain:
 
         case '\n':
            NextChar ();
-           Tok = TOK_SEP;
+           CurTok.Tok = TOK_SEP;
            return;
 
         case EOF:
@@ -1325,7 +1354,7 @@ CharAgain:
                 DoneCharSource ();
                 goto Again;
             } else {
-               Tok = TOK_EOF;
+               CurTok.Tok = TOK_EOF;
             }
             return;
     }
@@ -1350,7 +1379,7 @@ int GetSubKey (const char** Keys, unsigned Count)
     unsigned I;
 
     /* Must have an identifier */
-    PRECONDITION (Tok == TOK_IDENT);
+    PRECONDITION (CurTok.Tok == TOK_IDENT);
 
     /* If we aren't in ignore case mode, we have to uppercase the identifier */
     if (!IgnoreCase) {
@@ -1359,7 +1388,7 @@ int GetSubKey (const char** Keys, unsigned Count)
 
     /* Do a linear search (a binary search is not worth the effort) */
     for (I = 0; I < Count; ++I) {
-               if (SB_CompareStr (&SVal, Keys [I]) == 0) {
+               if (SB_CompareStr (&CurTok.SVal, Keys [I]) == 0) {
            /* Found it */
            return I;
        }
@@ -1380,13 +1409,13 @@ unsigned char ParseAddrSize (void)
     unsigned char AddrSize;
 
     /* Check for an identifier */
-    if (Tok != TOK_IDENT) {
+    if (CurTok.Tok != TOK_IDENT) {
         Error ("Address size specifier expected");
         return ADDR_SIZE_DEFAULT;
     }
 
     /* Convert the attribute */
-    AddrSize = AddrSizeFromStr (SB_GetConstBuf (&SVal));
+    AddrSize = AddrSizeFromStr (SB_GetConstBuf (&CurTok.SVal));
     if (AddrSize == ADDR_SIZE_INVALID) {
         Error ("Address size specifier expected");
         AddrSize = ADDR_SIZE_DEFAULT;
@@ -1415,3 +1444,4 @@ void DoneScanner (void)
 
 
 
+