]> git.sur5r.net Git - cc65/blobdiff - src/ca65/nexttok.c
Renamed variables for better readability.
[cc65] / src / ca65 / nexttok.c
index 44888b5ca98eb4101a2d00f2588b77c7530862c0..dab0697f94d5902c6272ed1908ed0040a25013ab 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2007 Ullrich von Bassewitz                                       */
-/*               Roemerstrasse 52                                            */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2000-2011, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -42,6 +42,7 @@
 #include "strbuf.h"
 
 /* ca65 */
+#include "condasm.h"
 #include "error.h"
 #include "expr.h"
 #include "global.h"
@@ -73,7 +74,7 @@ static int LookAtStrCon (void)
  * true.
  */
 {
-    if (Tok != TOK_STRCON) {
+    if (CurTok.Tok != TOK_STRCON) {
         Error ("String constant expected");
         SkipUntilSep ();
         return 0;
@@ -102,14 +103,14 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
     TokList* List = NewTokList ();
 
     /* Determine if the list is enclosed in curly braces. */
-    Token Term = GetTokListTerm (TOK_RPAREN);
+    token_t Term = GetTokListTerm (TOK_RPAREN);
 
     /* Read the token list */
     unsigned Current = 0;
-    while (Tok != Term) {
+    while (CurTok.Tok != Term) {
 
        /* Check for end of line or end of input */
-       if (TokIsSep (Tok)) {
+       if (TokIsSep (CurTok.Tok)) {
            Error ("Unexpected end of line");
            return List;
        }
@@ -142,10 +143,7 @@ static TokList* CollectTokens (unsigned Start, unsigned Count)
 static void FuncConcat (void)
 /* Handle the .CONCAT function */
 {
-    char       Buf[MAX_STR_LEN+1];
-    char*      B;
-    unsigned   Length;
-    unsigned   L;
+    StrBuf      Buf = STATIC_STRBUF_INITIALIZER;
 
     /* Skip it */
     NextTok ();
@@ -154,35 +152,22 @@ static void FuncConcat (void)
     ConsumeLParen ();
 
     /* Concatenate any number of strings */
-    B = Buf;
-    B[0] = '\0';
-    Length = 0;
     while (1) {
 
        /* Next token must be a string */
         if (!LookAtStrCon ()) {
+            SB_Done (&Buf);
            return;
        }
 
-       /* Get the length of the string const and check total length */
-       L = strlen (SVal);
-       if (Length + L > MAX_STR_LEN) {
-           Error ("String is too long");
-           /* Try to recover */
-           SkipUntilSep ();
-           return;
-       }
-
-       /* Add the new string */
-       memcpy (B, SVal, L);
-       Length += L;
-       B      += L;
+        /* Append the string */
+        SB_Append (&Buf, &CurTok.SVal);
 
        /* Skip the string token */
        NextTok ();
 
        /* Comma means another argument */
-       if (Tok == TOK_COMMA) {
+       if (CurTok.Tok == TOK_COMMA) {
            NextTok ();
        } else {
            /* Done */
@@ -190,18 +175,19 @@ static void FuncConcat (void)
        }
     }
 
-    /* Terminate the string */
-    *B = '\0';
-
     /* We expect a closing parenthesis, but will not skip it but replace it
      * by the string token just created.
      */
-    if (Tok != TOK_RPAREN) {
+    if (CurTok.Tok != TOK_RPAREN) {
        Error ("`)' expected");
     } else {
-       Tok = TOK_STRCON;
-       strcpy (SVal, Buf);
+       CurTok.Tok = TOK_STRCON;
+       SB_Copy (&CurTok.SVal, &Buf);
+        SB_Terminate (&CurTok.SVal);
     }
+
+    /* Free the string buffer */
+    SB_Done (&Buf);
 }
 
 
@@ -218,9 +204,8 @@ static void NoIdent (void)
 static void FuncIdent (void)
 /* Handle the .IDENT function */
 {
-    char      Buf[sizeof(SVal)];
-    Token     Id;
-    unsigned  Len;
+    StrBuf    Buf = STATIC_STRBUF_INITIALIZER;
+    token_t   Id;
     unsigned  I;
 
     /* Skip it */
@@ -237,49 +222,46 @@ static void FuncIdent (void)
     /* Check that the string contains a valid identifier. While doing so,
      * determine if it is a cheap local, or global one.
      */
-    Len = strlen (SVal);
-    if (Len == 0) {
-        NoIdent ();
-        return;
-    }
-    I = 0;
-    if (SVal[0] == LocalStart) {
-        if (Len < 2) {
-            NoIdent ();
-            return;
-        }
-        I = 1;
+    SB_Reset (&CurTok.SVal);
+
+    /* Check for a cheap local symbol */
+    if (SB_Peek (&CurTok.SVal) == LocalStart) {
+        SB_Skip (&CurTok.SVal);
         Id = TOK_LOCAL_IDENT;
     } else {
         Id = TOK_IDENT;
     }
-    if (!IsIdStart (SVal[I])) {
+
+    /* Next character must be a valid identifier start */
+    if (!IsIdStart (SB_Get (&CurTok.SVal))) {
         NoIdent ();
         return;
     }
-    while (I < Len) {
-        if (!IsIdChar (SVal[I])) {
+    for (I = SB_GetIndex (&CurTok.SVal); I < SB_GetLen (&CurTok.SVal); ++I) {
+        if (!IsIdChar (SB_AtUnchecked (&CurTok.SVal, I))) {
             NoIdent ();
             return;
         }
-        ++I;
     }
     if (IgnoreCase) {
         UpcaseSVal ();
     }
 
     /* If anything is ok, save and skip the string. Check that the next token
-     * is a right paren, in which case SVal is untouched. Replace the token by
-     * a identifier token.
+     * is a right paren, then replace the token by an identifier token.
      */
-    memcpy (Buf, SVal, Len+1);
+    SB_Copy (&Buf, &CurTok.SVal);
     NextTok ();
-    if (Tok != TOK_RPAREN) {
+    if (CurTok.Tok != TOK_RPAREN) {
        Error ("`)' expected");
     } else {
-        Tok = Id;
-        memcpy (SVal, Buf, Len+1);
+        CurTok.Tok = Id;
+        SB_Copy (&CurTok.SVal, &Buf);
+        SB_Terminate (&CurTok.SVal);
     }
+
+    /* Free buffer memory */
+    SB_Done (&Buf);
 }
 
 
@@ -299,7 +281,7 @@ static void FuncLeft (void)
     /* Count argument. Correct negative counts to zero. */
     Count = ConstExpression ();
     if (Count < 0) {
-       Count = 1;
+       Count = 0;
     }
     ConsumeComma ();
 
@@ -443,11 +425,11 @@ static void InvalidFormatString (void)
 static void FuncSPrintF (void)
 /* Handle the .SPRINTF function */
 {
-    char        Format[sizeof (SVal)];              /* User given format */
-    const char* F = Format;                         /* User format pointer */
-    StrBuf      R = AUTO_STRBUF_INITIALIZER;        /* Result string */
-    StrBuf      F1 = AUTO_STRBUF_INITIALIZER;       /* One format spec from F */
-    StrBuf      R1 = AUTO_STRBUF_INITIALIZER;       /* One result */
+    StrBuf      Format = STATIC_STRBUF_INITIALIZER; /* User supplied format */
+    StrBuf      R = STATIC_STRBUF_INITIALIZER;      /* Result string */
+    StrBuf      F1 = STATIC_STRBUF_INITIALIZER;     /* One format spec from F */
+    StrBuf      R1 = STATIC_STRBUF_INITIALIZER;     /* One result */
+    char        C;
     int         Done;
     long        IVal;                               /* Integer value */
 
@@ -463,30 +445,31 @@ static void FuncSPrintF (void)
     if (!LookAtStrCon ()) {
         return;
     }
-    strcpy (Format, SVal);
+    SB_Copy (&Format, &CurTok.SVal);
     NextTok ();
 
     /* Walk over the format string, generating the function result in R */
     while (1) {
 
         /* Get the next char from the format string and check for EOS */
-        if (*F == '\0') {
+        if (SB_Peek (&Format) == '\0') {
             break;
         }
 
         /* Check for a format specifier */
-        if (*F != '%') {
+        if (SB_Peek (&Format) != '%') {
             /* No format specifier, just copy */
-            SB_AppendChar (&R, *F++);
+            SB_AppendChar (&R, SB_Get (&Format));
             continue;
         }
-        if (*++F == '%') {
+        SB_Skip (&Format);
+        if (SB_Peek (&Format) == '%') {
             /* %% */
             SB_AppendChar (&R, '%');
-            ++F;
+            SB_Skip (&Format);
             continue;
         }
-        if (*F == '\0') {
+        if (SB_Peek (&Format) == '\0') {
             InvalidFormatString ();
             break;
         }
@@ -505,32 +488,32 @@ static void FuncSPrintF (void)
 
         /* Check for flags */
         Done = 0;
-        while (*F != '\0' && !Done) {
-            switch (*F) {
+        while ((C = SB_Peek (&Format)) != '\0' && !Done) {
+            switch (C) {
                 case '-': /* FALLTHROUGH */
                 case '+': /* FALLTHROUGH */
                 case ' ': /* FALLTHROUGH */
                 case '#': /* FALLTHROUGH */
-                case '0': SB_AppendChar (&F1, *F++);    break;
-                default:  Done = 1;                     break;
+                case '0': SB_AppendChar (&F1, SB_Get (&Format));  break;
+                default:  Done = 1;                               break;
             }
         }
 
         /* We do only support a numerical width field */
-        while (IsDigit (*F)) {
-            SB_AppendChar (&F1, *F++);
+        while (IsDigit (SB_Peek (&Format))) {
+            SB_AppendChar (&F1, SB_Get (&Format));
         }
 
         /* Precision - only positive numerical fields supported */
-        if (*F == '.') {
-            SB_AppendChar (&F1, *F++);
-            while (IsDigit (*F)) {
-                SB_AppendChar (&F1, *F++);
+        if (SB_Peek (&Format) == '.') {
+            SB_AppendChar (&F1, SB_Get (&Format));
+            while (IsDigit (SB_Peek (&Format))) {
+                SB_AppendChar (&F1, SB_Get (&Format));
             }
         }
 
         /* Length modifiers aren't supported, so read the conversion specs */
-        switch (*F) {
+        switch (SB_Peek (&Format)) {
 
             case 'd':
             case 'i':
@@ -542,7 +525,7 @@ static void FuncSPrintF (void)
                  * calling xsprintf later. Terminate the format string.
                  */
                 SB_AppendChar (&F1, 'l');
-                SB_AppendChar (&F1, *F++);
+                SB_AppendChar (&F1, SB_Get (&Format));
                 SB_Terminate (&F1);
 
                 /* The argument must be a constant expression */
@@ -558,17 +541,17 @@ static void FuncSPrintF (void)
 
             case 's':
                 /* Add the format spec and terminate the format */
-                SB_AppendChar (&F1, *F++);
+                SB_AppendChar (&F1, SB_Get (&Format));
                 SB_Terminate (&F1);
 
                 /* The argument must be a string constant */
                 if (!LookAtStrCon ()) {
                     /* Make it one */
-                    strcpy (SVal, "**undefined**");
+                    SB_CopyStr (&CurTok.SVal, "**undefined**");
                 }
 
                 /* Format this argument according to the spec */
-                SB_Printf (&R1, SB_GetConstBuf (&F1), SVal);
+                SB_Printf (&R1, SB_GetConstBuf (&F1), SB_GetConstBuf (&CurTok.SVal));
 
                 /* Skip the string constant */
                 NextTok ();
@@ -580,7 +563,7 @@ static void FuncSPrintF (void)
 
             case 'c':
                 /* Add the format spec and terminate the format */
-                SB_AppendChar (&F1, *F++);
+                SB_AppendChar (&F1, SB_Get (&Format));
                 SB_Terminate (&F1);
 
                 /* The argument must be a constant expression */
@@ -604,39 +587,32 @@ static void FuncSPrintF (void)
 
             default:
                 Error ("Invalid format string");
-                if (*F) {
-                    /* Don't skip beyond end of string */
-                    ++F;
-                }
+                SB_Skip (&Format);
                 break;
         }
 
     }
 
-    /* The length of the final result may not exceed the size of a string */
-    if (SB_GetLen (&R) >= sizeof (SVal)) {
-        Error ("Resulting string is too long");
-        SB_Cut (&R, sizeof (SVal) - 1);
-    }
-
     /* Terminate the result string */
     SB_Terminate (&R);
 
     /* We expect a closing parenthesis, but will not skip it but replace it
      * by the string token just created.
      */
-    if (Tok != TOK_RPAREN) {
+    if (CurTok.Tok != TOK_RPAREN) {
        Error ("`)' expected");
     } else {
-       Tok = TOK_STRCON;
-       memcpy (SVal, SB_GetConstBuf (&R), SB_GetLen (&R) + 1);
+       CurTok.Tok = TOK_STRCON;
+        SB_Copy (&CurTok.SVal, &R);
+        SB_Terminate (&CurTok.SVal);
     }
 
 
     /* Delete the string buffers */
-    DoneStrBuf (&R);
-    DoneStrBuf (&F1);
-    DoneStrBuf (&R1);
+    SB_Done (&Format);
+    SB_Done (&R);
+    SB_Done (&F1);
+    SB_Done (&R1);
 }
 
 
@@ -644,7 +620,7 @@ static void FuncSPrintF (void)
 static void FuncString (void)
 /* Handle the .STRING function */
 {
-    char Buf[MAX_STR_LEN+1];
+    StrBuf Buf = STATIC_STRBUF_INITIALIZER;
 
     /* Skip it */
     NextTok ();
@@ -653,25 +629,29 @@ static void FuncString (void)
     ConsumeLParen ();
 
     /* Accept identifiers or numeric expressions */
-    if (Tok == TOK_IDENT || Tok == TOK_LOCAL_IDENT) {
+    if (CurTok.Tok == TOK_IDENT || CurTok.Tok == TOK_LOCAL_IDENT) {
        /* Save the identifier, then skip it */
-       strcpy (Buf, SVal);
+               SB_Copy (&Buf, &CurTok.SVal);
        NextTok ();
     } else {
        /* Numeric expression */
        long Val = ConstExpression ();
-       sprintf (Buf, "%ld", Val);
+               SB_Printf (&Buf, "%ld", Val);
     }
 
     /* We expect a closing parenthesis, but will not skip it but replace it
      * by the string token just created.
      */
-    if (Tok != TOK_RPAREN) {
+    if (CurTok.Tok != TOK_RPAREN) {
        Error ("`)' expected");
     } else {
-       Tok = TOK_STRCON;
-       strcpy (SVal, Buf);
+       CurTok.Tok = TOK_STRCON;
+       SB_Copy (&CurTok.SVal, &Buf);
+        SB_Terminate (&CurTok.SVal);
     }
+
+    /* Free string memory */
+    SB_Done (&Buf);
 }
 
 
@@ -682,11 +662,13 @@ void NextTok (void)
     /* Get the next raw token */
     NextRawTok ();
 
-    /* In raw mode, pass the token unchanged */
-    if (RawMode == 0) {
+    /* In raw mode, or when output is suppressed via conditional assembly,
+     * pass the token unchanged.
+     */
+    if (RawMode == 0 && IfCond) {
 
        /* Execute token handling functions */
-       switch (Tok) {
+       switch (CurTok.Tok) {
 
            case TOK_CONCAT:
                FuncConcat ();
@@ -726,13 +708,13 @@ void NextTok (void)
 
 
 
-void Consume (Token Expected, const char* ErrMsg)
+void Consume (token_t Expected, const char* ErrMsg)
 /* Consume Expected, print an error if we don't find it */
 {
-    if (Tok == Expected) {
+    if (CurTok.Tok == Expected) {
        NextTok ();
     } else {
-       Error (ErrMsg);
+               Error ("%s", ErrMsg);
     }
 }
 
@@ -745,7 +727,7 @@ void ConsumeSep (void)
     ExpectSep ();
 
     /* If we are at end of line, skip it */
-    if (Tok == TOK_SEP) {
+    if (CurTok.Tok == TOK_SEP) {
        NextTok ();
     }
 }
@@ -779,7 +761,7 @@ void ConsumeComma (void)
 void SkipUntilSep (void)
 /* Skip tokens until we reach a line separator or end of file */
 {
-    while (!TokIsSep (Tok)) {
+    while (!TokIsSep (CurTok.Tok)) {
        NextTok ();
     }
 }
@@ -791,7 +773,7 @@ void ExpectSep (void)
  * not skip the line separator.
  */
 {
-    if (!TokIsSep (Tok)) {
+    if (!TokIsSep (CurTok.Tok)) {
                ErrorSkip ("Unexpected trailing garbage characters");
     }
 }