]> git.sur5r.net Git - cc65/commitdiff
Added an OPTIONAL segment attribute
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 May 2003 22:20:32 +0000 (22:20 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 22 May 2003 22:20:32 +0000 (22:20 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@2162 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ld65/config.c
src/ld65/config.h
src/ld65/scanner.h

index c10b5f7dca91a257ab29147128720a5c661f28ff..5a9c1d8d89edec483d134f2fecd1e96e401132ed 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -98,6 +98,7 @@ unsigned              SegDescCount;   /* Number of entries in list */
 #define SA_DEFINE      0x0010
 #define SA_OFFSET      0x0020
 #define SA_START       0x0040
+#define SA_OPTIONAL     0x0080
 
 
 
@@ -336,11 +337,10 @@ static SegDesc* NewSegDesc (const char* Name)
        CfgError ("Segment `%s' defined twice", Name);
     }
 
-    /* Verify that the given segment does really exist */
+    /* Search for the actual segment in the input files. The function may
+     * return NULL (no such segment), this is checked later.
+     */
     Seg = SegFind (Name);
-    if (Seg == 0) {
-               CfgWarning ("Segment `%s' does not exist", Name);
-    }
 
     /* Allocate memory */
     S = xmalloc (sizeof (SegDesc) + Len);
@@ -608,21 +608,22 @@ static void ParseSegments (void)
 /* Parse a SEGMENTS section */
 {
     static const IdentTok Attributes [] = {
-               {   "LOAD",     CFGTOK_LOAD     },
-       {   "RUN",      CFGTOK_RUN      },
-        {   "TYPE",     CFGTOK_TYPE     },
         {   "ALIGN",    CFGTOK_ALIGN    },
         {   "DEFINE",   CFGTOK_DEFINE   },
-       {   "OFFSET",   CFGTOK_OFFSET   },
-       {   "START",    CFGTOK_START    },
+               {   "LOAD",     CFGTOK_LOAD     },
+       {   "OFFSET",   CFGTOK_OFFSET   },
+        {   "OPTIONAL", CFGTOK_OPTIONAL },
+       {   "RUN",      CFGTOK_RUN      },
+       {   "START",    CFGTOK_START    },
+        {   "TYPE",     CFGTOK_TYPE     },
     };
     static const IdentTok Types [] = {
-               {   "RO",       CFGTOK_RO       },
-               {   "RW",       CFGTOK_RW       },
-               {   "BSS",      CFGTOK_BSS      },
-       {   "ZP",       CFGTOK_ZP       },
-       {   "WP",       CFGTOK_WPROT    },
-       {   "WPROT",    CFGTOK_WPROT    },
+               {   "RO",       CFGTOK_RO       },
+               {   "RW",       CFGTOK_RW       },
+               {   "BSS",      CFGTOK_BSS      },
+       {   "ZP",       CFGTOK_ZP       },
+       {   "WP",       CFGTOK_WPROT    },
+       {   "WPROT",    CFGTOK_WPROT    },
     };
 
     unsigned Count;
@@ -653,66 +654,74 @@ static void ParseSegments (void)
            /* Check which attribute was given */
            switch (AttrTok) {
 
-               case CFGTOK_LOAD:
-                   FlagAttr (&S->Attr, SA_LOAD, "LOAD");
-                   S->Load = CfgGetMemory (CfgSVal);
-                   break;
-
-               case CFGTOK_RUN:
-                   FlagAttr (&S->Attr, SA_RUN, "RUN");
-                   S->Run = CfgGetMemory (CfgSVal);
-                   break;
-
-               case CFGTOK_TYPE:
-                   FlagAttr (&S->Attr, SA_TYPE, "TYPE");
-                           CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
-                   switch (CfgTok) {
-                               case CFGTOK_RO:    S->Flags |= SF_RO;               break;
-                       case CFGTOK_RW:    /* Default */                    break;
-                       case CFGTOK_BSS:   S->Flags |= SF_BSS;              break;
-                       case CFGTOK_ZP:    S->Flags |= (SF_BSS | SF_ZP);    break;
-                       case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT);  break;
-                       default:           Internal ("Unexpected token: %d", CfgTok);
-                   }
-                   break;
-
                case CFGTOK_ALIGN:
-                   CfgAssureInt ();
-                   FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
-                   CfgRangeCheck (1, 0x10000);
-                   S->Align = BitFind (CfgIVal);
-                   if ((0x01UL << S->Align) != CfgIVal) {
-                       CfgError ("Alignment must be a power of 2");
-                   }
-                   S->Flags |= SF_ALIGN;
-                   break;
+                   CfgAssureInt ();
+                   FlagAttr (&S->Attr, SA_ALIGN, "ALIGN");
+                   CfgRangeCheck (1, 0x10000);
+                   S->Align = BitFind (CfgIVal);
+                   if ((0x01UL << S->Align) != CfgIVal) {
+                       CfgError ("Alignment must be a power of 2");
+                   }
+                   S->Flags |= SF_ALIGN;
+                   break;
 
                case CFGTOK_DEFINE:
-                   FlagAttr (&S->Attr, SA_DEFINE, "DEFINE");
-                   /* Map the token to a boolean */
+                   FlagAttr (&S->Attr, SA_DEFINE, "DEFINE");
+                   /* Map the token to a boolean */
+                   CfgBoolToken ();
+                   if (CfgTok == CFGTOK_TRUE) {
+                       S->Flags |= SF_DEFINE;
+                   }
+                   break;
+
+               case CFGTOK_LOAD:
+                   FlagAttr (&S->Attr, SA_LOAD, "LOAD");
+                   S->Load = CfgGetMemory (CfgSVal);
+                   break;
+
+               case CFGTOK_OFFSET:
+                   CfgAssureInt ();
+                   FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
+                   CfgRangeCheck (1, 0x1000000);
+                   S->Addr   = CfgIVal;
+                   S->Flags |= SF_OFFSET;
+                   break;
+
+               case CFGTOK_OPTIONAL:
+                   FlagAttr (&S->Attr, SA_OPTIONAL, "OPTIONAL");
                    CfgBoolToken ();
                    if (CfgTok == CFGTOK_TRUE) {
-                       S->Flags |= SF_DEFINE;
+                       S->Flags |= SF_OPTIONAL;
                    }
-                   break;
+                   break;
 
-               case CFGTOK_OFFSET:
-                   CfgAssureInt ();
-                   FlagAttr (&S->Attr, SA_OFFSET, "OFFSET");
-                   CfgRangeCheck (1, 0x1000000);
-                   S->Addr   = CfgIVal;
-                   S->Flags |= SF_OFFSET;
-                   break;
+               case CFGTOK_RUN:
+                   FlagAttr (&S->Attr, SA_RUN, "RUN");
+                   S->Run = CfgGetMemory (CfgSVal);
+                   break;
 
                case CFGTOK_START:
-                   CfgAssureInt ();
-                   FlagAttr (&S->Attr, SA_START, "START");
-                   CfgRangeCheck (1, 0x1000000);
-                   S->Addr   = CfgIVal;
-                   S->Flags |= SF_START;
-                   break;
-
-               default:
+                   CfgAssureInt ();
+                   FlagAttr (&S->Attr, SA_START, "START");
+                   CfgRangeCheck (1, 0x1000000);
+                   S->Addr   = CfgIVal;
+                   S->Flags |= SF_START;
+                   break;
+
+               case CFGTOK_TYPE:
+                   FlagAttr (&S->Attr, SA_TYPE, "TYPE");
+                           CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
+                   switch (CfgTok) {
+                               case CFGTOK_RO:    S->Flags |= SF_RO;               break;
+                       case CFGTOK_RW:    /* Default */                    break;
+                       case CFGTOK_BSS:   S->Flags |= SF_BSS;              break;
+                       case CFGTOK_ZP:    S->Flags |= (SF_BSS | SF_ZP);    break;
+                       case CFGTOK_WPROT: S->Flags |= (SF_RO | SF_WPROT);  break;
+                       default:           Internal ("Unexpected token: %d", CfgTok);
+                   }
+                   break;
+
+               default:
                            FAIL ("Unexpected attribute token");
 
            }
@@ -738,13 +747,13 @@ static void ParseSegments (void)
            S->Align = 0;
        }
 
-       /* If the segment is marked as BSS style, and if the segment exists 
-         * in any of the object file, check that there's no initialized data 
+       /* If the segment is marked as BSS style, and if the segment exists
+         * in any of the object file, check that there's no initialized data
          * in the segment.
         */
        if ((S->Flags & SF_BSS) != 0 && S->Seg != 0 && !IsBSSType (S->Seg)) {
            Warning ("%s(%u): Segment with type `bss' contains initialized data",
-                    CfgGetName (), CfgErrorLine);
+                    CfgGetName (), CfgErrorLine);
        }
 
         /* If the segment is marked as BSS style, it may not have separate
@@ -758,23 +767,23 @@ static void ParseSegments (void)
        /* Don't allow read/write data to be put into a readonly area */
        if ((S->Flags & SF_RO) == 0) {
                    if (S->Run->Flags & MF_RO) {
-               CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'",
-                         S->Name, S->Run->Name);
+               CfgError ("Cannot put r/w segment `%s' in r/o memory area `%s'",
+                         S->Name, S->Run->Name);
            }
        }
 
        /* Only one of ALIGN, START and OFFSET may be used */
                Count = ((S->Flags & SF_ALIGN)  != 0) +
                ((S->Flags & SF_OFFSET) != 0) +
-               ((S->Flags & SF_START)  != 0);
+               ((S->Flags & SF_START)  != 0);
        if (Count > 1) {
                    CfgError ("Only one of ALIGN, START, OFFSET may be used");
        }
 
        /* If this segment does exist in any of the object files, insert the
-        * descriptor into the list of segment descriptors. Otherwise discard
-        * it silently, because the segment pointer in the descriptor is
-        * invalid.
+        * descriptor into the list of segment descriptors. Otherwise print a
+         * warning and discard it, because the segment pointer in the
+         * descriptor is invalid.
         */
        if (S->Seg != 0) {
            /* Insert the descriptor into the list of all descriptors */
@@ -782,11 +791,15 @@ static void ParseSegments (void)
            /* Insert the segment into the memory area list */
            MemoryInsert (S->Run, S);
            if ((S->Flags & SF_LOAD_AND_RUN) != 0) {
-               /* We have a separate RUN area given */
-               MemoryInsert (S->Load, S);
+               /* We have a separate RUN area given */
+               MemoryInsert (S->Load, S);
            }
        } else {
-           /* Segment does not exist, discard the descriptor */
+            /* Print a warning if the segment is not optional */
+            if ((S->Flags & SF_OPTIONAL) == 0) {
+                CfgWarning ("Segment `%s' does not exist", S->Name);
+            }
+           /* Discard the descriptor */
            FreeSegDesc (S);
        }
 
index b5e60824551dd8825750bbd6146fcc1bb1cc8385..e2c91e3bada9b5843e298b6763152cc08229f137 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -107,14 +107,15 @@ extern unsigned           SegDescCount;   /* Number of entries in list */
 #define MF_RO          0x0004          /* Read only memory area */
 
 /* Segment flags */
-#define SF_RO          0x0001          /* Read only segment */
+#define SF_RO                  0x0001          /* Read only segment */
 #define SF_BSS                 0x0002          /* Segment is BSS style segment */
-#define SF_ZP          0x0004          /* Zeropage segment (o65 only) */
+#define SF_ZP                  0x0004          /* Zeropage segment (o65 only) */
 #define SF_WPROT       0x0008          /* Write protected segment */
 #define SF_DEFINE              0x0010          /* Define start and size */
 #define SF_ALIGN       0x0020          /* Align the segment */
 #define SF_OFFSET      0x0040          /* Segment has offset in memory */
 #define SF_START       0x0080          /* Segment has fixed start address */
+#define SF_OPTIONAL     0x0100          /* Segment is optional (must not exist) */
 #define SF_LOAD_AND_RUN        0x1000          /* LOAD and RUN given */
 #define SF_RUN_DEF             0x2000          /* RUN symbols already defined */
 #define SF_LOAD_DEF    0x4000          /* LOAD symbols already defined */
@@ -145,4 +146,4 @@ void CfgWriteTarget (void);
 
 
 
-                     
+
index d2af2af429a4c9d784728efae582d1cc73e041d8..c8c2c6a3750ad84c0dc9b6aa62128e9e1701f40d 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
+/* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
@@ -85,6 +85,7 @@ typedef enum {
     CFGTOK_RUN,
     CFGTOK_ALIGN,
     CFGTOK_OFFSET,
+    CFGTOK_OPTIONAL,
 
     CFGTOK_RO,
     CFGTOK_RW,