]> git.sur5r.net Git - cc65/blobdiff - src/cc65/pragma.c
Working
[cc65] / src / cc65 / pragma.c
index 907ced7e9a0c3da44daeaab0e56d662332d67255..ce1a8a4ba2be30de09d13a6b27a4f8723f930045 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 1998-2001 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 #include <stdlib.h>
-#include <ctype.h>
+#include <string.h>
 
-#include "global.h"
+/* cc65 */
+#include "codegen.h"
 #include "error.h"
-#include "io.h"
+#include "expr.h"
+#include "global.h"
 #include "litpool.h"
-#include "symtab.h"
-#include "preproc.h"
 #include "scanner.h"
-#include "codegen.h"
-#include "expr.h"
+#include "segments.h"
+#include "symtab.h"
 #include "pragma.h"
 
 
 
 /*****************************************************************************/
-/*                                  data                                    */
+/*                                  data                                    */
 /*****************************************************************************/
 
 
 
 /* Tokens for the #pragmas */
-enum {
+typedef enum {
     PR_BSSSEG,
+    PR_CHECKSTACK,
     PR_CODESEG,
     PR_DATASEG,
     PR_REGVARADDR,
@@ -66,30 +67,101 @@ enum {
     PR_STATICLOCALS,
     PR_ZPSYM,
     PR_ILLEGAL
+} pragma_t;
+
+/* Pragma table */
+static const struct Pragma {
+    const char*        Key;            /* Keyword */
+    pragma_t   Tok;            /* Token */
+} Pragmas[] = {
+    {  "bssseg",       PR_BSSSEG       },
+    {  "checkstack",   PR_CHECKSTACK   },
+    {   "codeseg",     PR_CODESEG      },
+    {   "dataseg",     PR_DATASEG      },
+    {   "regvaraddr",  PR_REGVARADDR   },
+    {   "rodataseg",   PR_RODATASEG    },
+    {  "signedchars",  PR_SIGNEDCHARS  },
+    {  "staticlocals", PR_STATICLOCALS },
+    {   "zpsym",               PR_ZPSYM        },
 };
 
+/* Number of pragmas */
+#define PRAGMA_COUNT   (sizeof(Pragmas) / sizeof(Pragmas[0]))
+
 
 
 /*****************************************************************************/
-/*                                  code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
 
+static int CmpKey (const void* Key, const void* Elem)
+/* Compare function for bsearch */
+{
+    return strcmp ((const char*) Key, ((const struct Pragma*) Elem)->Key);
+}
+
+
+
+static pragma_t FindPragma (const char* Key)
+/* Find a pragma and return the token. Return PR_ILLEGAL if the keyword is
+ * not a valid pragma.
+ */
+{
+    struct Pragma* P;
+    P = bsearch (Key, Pragmas, PRAGMA_COUNT, sizeof (Pragmas[0]), CmpKey);
+    return P? P->Tok : PR_ILLEGAL;
+}
+
+
+
 static void StringPragma (void (*Func) (const char*))
 /* Handle a pragma that expects a string parameter */
 {
-    if (curtok != TOK_SCONST) {
-       Error (ERR_STRLIT_EXPECTED);
+    if (CurTok.Tok != TOK_SCONST) {
+       Error ("String literal expected");
     } else {
        /* Get the string */
-       const char* Name = GetLiteral (curval);
+       const char* Name = GetLiteral (CurTok.IVal);
 
                /* Call the given function with the string argument */
        Func (Name);
 
        /* Reset the string pointer, removing the string from the pool */
-       ResetLiteralOffs (curval);
+       ResetLiteralPoolOffs (CurTok.IVal);
+    }
+
+    /* Skip the string (or error) token */
+    NextToken ();
+}
+
+
+
+static void SegNamePragma (segment_t Seg)
+/* Handle a pragma that expects a segment name parameter */
+{
+    if (CurTok.Tok != TOK_SCONST) {
+       Error ("String literal expected");
+    } else {
+       /* Get the segment name */
+       const char* Name = GetLiteral (CurTok.IVal);
+
+       /* Check if the name is valid */
+       if (ValidSegName (Name)) {
+
+                   /* Set the new name */
+           g_segname (Seg, Name);
+
+       } else {
+
+           /* Segment name is invalid */
+           Error ("Illegal segment name: `%s'", Name);
+
+       }
+
+       /* Reset the string pointer, removing the string from the pool */
+       ResetLiteralPoolOffs (CurTok.IVal);
     }
 
     /* Skip the string (or error) token */
@@ -102,11 +174,11 @@ static void FlagPragma (unsigned char* Flag)
 /* Handle a pragma that expects a boolean paramater */
 {
     /* Read a constant expression */
-    struct expent val;
+    ExprDesc val;
     constexpr (&val);
 
     /* Store the value into the flag parameter */
-    *Flag = (val.e_const != 0);
+    *Flag = (val.ConstVal != 0);
 }
 
 
@@ -114,57 +186,51 @@ static void FlagPragma (unsigned char* Flag)
 void DoPragma (void)
 /* Handle pragmas */
 {
-    static const struct tok_elt Pragmas [] = {
-       {       "bssseg",       PR_BSSSEG       },
-               {       "codeseg",      PR_CODESEG      },
-       {       "dataseg",      PR_DATASEG      },
-               {       "regvaraddr",   PR_REGVARADDR   },
-       {       "rodataseg",    PR_RODATASEG    },
-       {       "signedchars",  PR_SIGNEDCHARS  },
-       {       "staticlocals", PR_STATICLOCALS },
-       {       "zpsym",        PR_ZPSYM        },
-       {       0,              PR_ILLEGAL      },
-    };
-
-    int Pragma;
+    pragma_t Pragma;
 
     /* Skip the token itself */
     NextToken ();
 
     /* Identifier must follow */
-    if (curtok != TOK_IDENT) {
-       Error (ERR_IDENT_EXPECTED);
+    if (CurTok.Tok != TOK_IDENT) {
+       Error ("Identifier expected");
        return;
     }
 
+    /* Search for the name, then skip the identifier */
+    Pragma = FindPragma (CurTok.Ident);
+    NextToken ();
+
     /* Do we know this pragma? */
-    Pragma = searchtok (CurTok.Ident, Pragmas);
     if (Pragma == PR_ILLEGAL) {
-       /* According to the ANSI standard, we're not allowed to generate errors
-        * for unknown pragmas, however, we're allowed to warn - and we will
-        * do so. Otherwise one typo may give you hours of bug hunting...
-        */
-       Warning (WARN_UNKNOWN_PRAGMA);
-       return;
+               /* According to the ANSI standard, we're not allowed to generate errors
+                * for unknown pragmas, however, we're allowed to warn - and we will
+                * do so. Otherwise one typo may give you hours of bug hunting...
+                */
+               Warning ("Unknown #pragma `%s'", CurTok.Ident);
+               return;
     }
 
-    /* Skip the identifier and check for an open paren */
-    NextToken ();
+    /* Check for an open paren */
     ConsumeLParen ();
 
     /* Switch for the different pragmas */
     switch (Pragma) {
 
        case PR_BSSSEG:
-           StringPragma (g_bssname);
+           SegNamePragma (SEG_BSS);
+           break;
+
+       case PR_CHECKSTACK:
+           FlagPragma (&CheckStack);
            break;
 
        case PR_CODESEG:
-           StringPragma (g_codename);
+           SegNamePragma (SEG_CODE);
            break;
 
        case PR_DATASEG:
-           StringPragma (g_dataname);
+           SegNamePragma (SEG_DATA);
            break;
 
        case PR_REGVARADDR:
@@ -172,7 +238,7 @@ void DoPragma (void)
            break;
 
        case PR_RODATASEG:
-           StringPragma (g_rodataname);
+           SegNamePragma (SEG_RODATA);
            break;
 
        case PR_SIGNEDCHARS:
@@ -180,7 +246,7 @@ void DoPragma (void)
            break;
 
        case PR_STATICLOCALS:
-           FlagPragma (&LocalsAreStatic);
+           FlagPragma (&StaticLocals);
            break;
 
        case PR_ZPSYM: