/* */
/* */
/* */
-/* (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,
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 */
/* 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);
}
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:
break;
case PR_RODATASEG:
- StringPragma (g_rodataname);
+ SegNamePragma (SEG_RODATA);
break;
case PR_SIGNEDCHARS: