]> git.sur5r.net Git - cc65/commitdiff
New info file statement "asminc" that allows to read in a file containing
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 8 Jan 2005 20:16:57 +0000 (20:16 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 8 Jan 2005 20:16:57 +0000 (20:16 +0000)
symbol values in asm syntax.

git-svn-id: svn://svn.cc65.org/cc65/trunk@3355 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/da65/asminc.c [new file with mode: 0644]
src/da65/asminc.h [new file with mode: 0644]
src/da65/infofile.c
src/da65/make/gcc.mak
src/da65/make/watcom.mak
src/da65/scanner.c
src/da65/scanner.h

diff --git a/src/da65/asminc.c b/src/da65/asminc.c
new file mode 100644 (file)
index 0000000..b326edb
--- /dev/null
@@ -0,0 +1,225 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 asminc.c                                  */
+/*                                                                           */
+/*             Read an assembler include file containing symbols             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 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       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#include <stdio.h>
+#include <errno.h>
+
+/* common */
+#include "chartype.h"
+#include "strbuf.h"
+
+/* da65 */
+#include "asminc.h"
+#include "attrtab.h"
+#include "error.h"
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+static char* SkipWhitespace (char* L)
+/* Ignore white space in L */
+{
+    while (IsBlank (*L)) {
+        ++L;
+    }
+    return L;
+}
+
+
+
+unsigned DigitVal (unsigned char C)
+/* Return the value of the given digit */
+{
+    if (IsDigit (C)) {
+        return C - '0';
+    } else {
+        return tolower (C) - 'a' + 10;
+    }
+}
+
+
+
+void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown)
+/* Read an assembler include file */
+{
+    char        Buf[1024];
+    char*       L;
+    unsigned    Line;
+    unsigned   Len;
+    long        Val;
+    unsigned    DVal;
+    int         Sign;
+    unsigned    Base;
+    unsigned    Digits;
+    StrBuf      Ident = STATIC_STRBUF_INITIALIZER;
+
+    /* Try to open the file for reading */
+    FILE* F = fopen (Filename, "r");
+    if (F == 0) {
+        Error ("Cannot open asm include file \"%s\": %s",
+               Filename, strerror (errno));
+    }
+
+    /* Read line by line, check for NAME = VALUE lines */
+    Line = 0;
+    while ((L = fgets (Buf, sizeof (Buf), F)) != 0) {
+
+        /* One more line read */
+        ++Line;
+
+        /* Ignore leading white space */
+        while (IsBlank (*L)) {
+            ++L;
+        }
+
+       /* Remove trailing whitespace */
+       Len = strlen (L);
+       while (Len > 0 && IsSpace (L[Len-1])) {
+           --Len;
+       }
+       L[Len] = '\0';
+
+        /* If the line is empty or starts with a comment char, ignore it */
+        if (*L == '\0' || *L == CommentStart) {
+            continue;
+        }
+
+        /* Read an identifier */
+        SB_Clear (&Ident);
+        if (IsAlpha (*L) || *L == '_') {
+            SB_AppendChar (&Ident, *L++);
+            while (IsAlNum (*L) || *L == '_') {
+                SB_AppendChar (&Ident, *L++);
+            }
+            SB_Terminate (&Ident);
+        } else {
+            if (!IgnoreUnknown) {
+                Error ("%s(%u): Syntax error", Filename, Line);
+            }
+            continue;
+        }
+
+        /* Ignore white space */
+        L = SkipWhitespace (L);
+
+        /* Check for := or = */
+        if (*L == '=') {
+            ++L;
+        } else if (*L == ':' && *++L == '=') {
+            ++L;
+        } else {
+           if (!IgnoreUnknown) {
+               Error ("%s(%u): Missing `='", Filename, Line);
+           }                              
+           continue;
+       }
+
+        /* Allow white space once again */
+        L = SkipWhitespace (L);
+
+        /* A number follows. Read the sign. */
+        if (*L == '-') {
+            Sign = -1;
+            ++L;
+        } else {
+            Sign = 1;
+            if (*L == '+') {
+                ++L;
+            }
+        }
+
+        /* Determine the base of the number. Allow $ and % as prefixes for
+         * hex and binary numbers respectively.
+         */
+        if (*L == '$') {
+            Base = 16;
+            ++L;
+        } else if (*L == '%') {
+            Base = 2;
+            ++L;
+        } else {
+            Base = 10;
+        }
+
+        /* Decode the number */
+        Digits = 0;
+        Val = 0;
+        while (IsXDigit (*L) && (DVal = DigitVal (*L)) < Base) {
+            Val = (Val * Base) + DVal;
+            ++Digits;
+            ++L;
+        }
+
+        /* Must have at least one digit */
+        if (Digits == 0) {
+            if (!IgnoreUnknown) {
+                Error ("%s(%u): Error in number format", Filename, Line);
+            }
+            continue;
+        }
+
+        /* Skip whitespace again */
+        L = SkipWhitespace (L);
+
+        /* Check for a comment character or end of line */
+        if (*L != CommentStart && *L != '\0') {
+            if (!IgnoreUnknown) {
+                Error ("%s(%u): Trailing garbage", Filename, Line);
+            }
+            continue;
+        }
+
+        /* Apply the sign */
+        Val *= Sign;
+
+        /* Define the symbol */
+        AddExtLabelRange (Val, SB_GetConstBuf (&Ident), 1);
+
+    }
+
+    /* Delete the string buffer contents */
+    DoneStrBuf (&Ident);
+
+    /* Close the include file ignoring errors (we were just reading). */
+    (void) fclose (F);
+}
+
+
+
diff --git a/src/da65/asminc.h b/src/da65/asminc.h
new file mode 100644 (file)
index 0000000..7b5c553
--- /dev/null
@@ -0,0 +1,56 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                 asminc.h                                  */
+/*                                                                           */
+/*             Read an assembler include file containing symbols             */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 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       */
+/* warranty.  In no event will the authors be held liable for any damages    */
+/* arising from the use of this software.                                    */
+/*                                                                           */
+/* Permission is granted to anyone to use this software for any purpose,     */
+/* including commercial applications, and to alter it and redistribute it    */
+/* freely, subject to the following restrictions:                            */
+/*                                                                           */
+/* 1. The origin of this software must not be misrepresented; you must not   */
+/*    claim that you wrote the original software. If you use this software   */
+/*    in a product, an acknowledgment in the product documentation would be  */
+/*    appreciated but is not required.                                       */
+/* 2. Altered source versions must be plainly marked as such, and must not   */
+/*    be misrepresented as being the original software.                      */
+/* 3. This notice may not be removed or altered from any source              */
+/*    distribution.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+#ifndef ASMINC_H
+#define ASMINC_H
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void AsmInc (const char* Filename, char CommentStart, int IgnoreUnknown);
+/* Read an assembler include file */
+
+
+
+/* End of asminc.h */
+#endif
+
+
+
index 493054f4561aa8e847720864323bb3d6792df670..cf20411fd74433577a724e9aeb1e211d983889c7 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2004 Ullrich von Bassewitz                                       */
+/* (C) 2000-2005 Ullrich von Bassewitz                                       */
 /*               Römerstrasse 52                                             */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -48,6 +48,7 @@
 #include "xmalloc.h"
 
 /* da65 */
+#include "asminc.h"
 #include "attrtab.h"
 #include "error.h"
 #include "global.h"
@@ -425,10 +426,10 @@ static void LabelSection (void)
        Size = 1;
     }
     if (Value + Size > 0x10000) {
-       InfoError ("Invalid size (address out of range)");
+       InfoError ("Invalid size (address out of range)");
     }
     if (HaveLabel ((unsigned) Value)) {
-       InfoError ("Label for address $%04lX already defined", Value);
+       InfoError ("Label for address $%04lX already defined", Value);
     }
 
     /* Define the label(s) */
@@ -443,13 +444,104 @@ static void LabelSection (void)
 
 
 
+static void AsmIncSection (void)
+/* Parse a asminc section */
+{
+    static const IdentTok LabelDefs[] = {
+        {   "COMMENTSTART",     INFOTOK_COMMENTSTART    },
+               {   "FILE",             INFOTOK_FILE            },
+        {   "IGNOREUNKNOWN",    INFOTOK_IGNOREUNKNOWN   },
+    };
+
+    /* Locals - initialize to avoid gcc warnings */
+    char* Name = 0;
+    int CommentStart = EOF;
+    int IgnoreUnknown = -1;
+
+    /* Skip the token */
+    InfoNextTok ();
+
+    /* Expect the opening curly brace */
+    InfoConsumeLCurly ();
+
+    /* Look for section tokens */
+    while (InfoTok != INFOTOK_RCURLY) {
+
+       /* Convert to special token */
+               InfoSpecialToken (LabelDefs, ENTRY_COUNT (LabelDefs), "Asminc directive");
+
+       /* Look at the token */
+       switch (InfoTok) {
+
+            case INFOTOK_COMMENTSTART:
+                InfoNextTok ();
+                if (CommentStart != EOF) {
+                    InfoError ("Commentstart already given");
+                }
+                InfoAssureChar ();
+                CommentStart = (char) InfoIVal;
+                InfoNextTok ();
+                break;
+
+           case INFOTOK_FILE:
+               InfoNextTok ();
+               if (Name) {
+                   InfoError ("File name already given");
+               }
+               InfoAssureStr ();
+               if (InfoSVal[0] == '\0') {
+                   InfoError ("File name may not be empty");
+               }
+               Name = xstrdup (InfoSVal);
+               InfoNextTok ();
+               break;
+
+            case INFOTOK_IGNOREUNKNOWN:
+                InfoNextTok ();
+                if (IgnoreUnknown != -1) {
+                    InfoError ("Ignoreunknown already specified");
+                }
+                InfoBoolToken ();
+                IgnoreUnknown = (InfoTok != INFOTOK_FALSE);
+                InfoNextTok ();
+                break;
+       }
+
+       /* Directive is followed by a semicolon */
+       InfoConsumeSemi ();
+    }
+
+    /* Check for the necessary data and assume defaults */
+    if (Name == 0) {
+       InfoError ("File name is missing");
+    }
+    if (CommentStart == EOF) {
+       CommentStart = ';';
+    }
+    if (IgnoreUnknown == -1) {
+        IgnoreUnknown = 0;
+    }
+
+    /* Open the file and read the symbol definitions */
+    AsmInc (Name, CommentStart, IgnoreUnknown);
+
+    /* Delete the dynamically allocated memory for Name */
+    xfree (Name);
+
+    /* Consume the closing brace */
+    InfoConsumeRCurly ();
+}
+
+
+
 static void InfoParse (void)
 /* Parse the config file */
 {
     static const IdentTok Globals[] = {
-       {   "GLOBAL",   INFOTOK_GLOBAL  },
-       {   "RANGE",    INFOTOK_RANGE   },
-       {   "LABEL",    INFOTOK_LABEL   },
+       {   "GLOBAL",   INFOTOK_GLOBAL  },
+       {   "RANGE",    INFOTOK_RANGE   },
+       {   "LABEL",    INFOTOK_LABEL   },
+        {   "ASMINC",   INFOTOK_ASMINC  },
     };
 
     while (InfoTok != INFOTOK_EOF) {
@@ -472,6 +564,9 @@ static void InfoParse (void)
                LabelSection ();
                break;
 
+            case INFOTOK_ASMINC:
+                AsmIncSection ();
+                break;
        }
 
        /* Semicolon expected */
index 49d4991f434c1a1b44f2596479c60abf1c873225..d4ac9d77bb0e460c72f61a90c8689057137630cd 100644 (file)
@@ -10,7 +10,8 @@ CC=gcc
 EBIND=emxbind
 LDFLAGS=
 
-OBJS =         attrtab.o       \
+OBJS =         asminc.o        \
+        attrtab.o      \
        code.o          \
        data.o          \
        error.o         \
index b288cb8caeca75a64d8d296e8308aa0326dc5c54..5d500f746c873eac6652c47d6b9bfbdb11ce31fd 100644 (file)
@@ -59,7 +59,8 @@ endif
 # ------------------------------------------------------------------------------
 # All OBJ files
 
-OBJS =         attrtab.obj     \
+OBJS =         asminc.obj      \
+        attrtab.obj    \
        code.obj        \
        data.obj        \
        error.obj       \
index 6d1315fafc6940b628784ca809e3280a19d55b51..9b58981df0420da48ed452a8a8b6015f3e382163 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/* (C) 2000-2005 Ullrich von Bassewitz                                       */
 /*               Römerstrasse 52                                             */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -262,6 +262,20 @@ Again:
            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) {
@@ -368,6 +382,16 @@ void InfoAssureStr (void)
 
 
 
+void InfoAssureChar (void)
+/* Make sure the next token is a char constant */
+{
+    if (InfoTok != INFOTOK_STRCON) {
+               InfoError ("Character constant expected");
+    }
+}
+
+
+
 void InfoAssureIdent (void)
 /* Make sure the next token is an identifier */
 {
@@ -427,6 +451,8 @@ void InfoBoolToken (void)
        {   "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 */
index 4a14d0d5dbe8597e99aa8a79ff51ecd1f5392cff..5e3f6efabe928f7a501004375c21c63d852f2d63 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/* (C) 2000-2005 Ullrich von Bassewitz                                       */
 /*               Römerstrasse 52                                             */
 /*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
@@ -49,6 +49,7 @@ typedef enum token_t {
     INFOTOK_NONE,
     INFOTOK_INTCON,
     INFOTOK_STRCON,
+    INFOTOK_CHARCON,
     INFOTOK_IDENT,
     INFOTOK_LCURLY,
     INFOTOK_RCURLY,
@@ -63,6 +64,7 @@ typedef enum token_t {
     INFOTOK_GLOBAL,
     INFOTOK_RANGE,
     INFOTOK_LABEL,
+    INFOTOK_ASMINC,
 
     /* Global section */
     INFOTOK_COMMENTS,
@@ -95,6 +97,11 @@ typedef enum token_t {
     INFOTOK_ADDR,
     INFOTOK_SIZE,
 
+    /* ASMINC section */
+    INFOTOK_FILE,
+    INFOTOK_COMMENTSTART,
+    INFOTOK_IGNOREUNKNOWN,
+
     /* */
     INFOTOK_TRUE,
     INFOTOK_FALSE
@@ -104,8 +111,8 @@ typedef enum token_t {
 /* Mapping table entry, special identifier --> token */
 typedef struct IdentTok IdentTok;
 struct IdentTok {
-    const char*                Ident;          /* Identifier */
-    token_t            Tok;            /* Token for identifier */
+    const char*                Ident;          /* Identifier */
+    token_t            Tok;            /* Token for identifier */
 };
 #define ENTRY_COUNT(s)         (sizeof (s) / sizeof (s [0]))
 
@@ -113,8 +120,8 @@ struct IdentTok {
 
 /* Current token and attributes */
 #define CFG_MAX_IDENT_LEN  255
-extern unsigned                InfoTok;
-extern char                    InfoSVal [CFG_MAX_IDENT_LEN+1];
+extern unsigned                InfoTok;
+extern char                    InfoSVal[CFG_MAX_IDENT_LEN+1];
 extern long            InfoIVal;
 
 /* Error location */
@@ -165,6 +172,9 @@ void InfoAssureInt (void);
 void InfoAssureStr (void);
 /* Make sure the next token is a string constant */
 
+void InfoAssureChar (void);
+/* Make sure the next token is a char constant */
+
 void InfoAssureIdent (void);
 /* Make sure the next token is an identifier */