]> git.sur5r.net Git - cc65/commitdiff
Working on the condes feature
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 20 Nov 2000 15:22:57 +0000 (15:22 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Mon, 20 Nov 2000 15:22:57 +0000 (15:22 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@451 b7a2c559-68d2-44c3-8de9-860c34a00d81

37 files changed:
src/ar65/objfile.c
src/ca65/dbginfo.c
src/ca65/expr.c
src/ca65/filetab.c
src/ca65/nexttok.c
src/ca65/options.c
src/ca65/pseudo.c
src/ca65/repeat.c
src/ca65/scanner.c
src/ca65/scanner.h
src/ca65/symtab.c
src/ca65/symtab.h
src/cc65/asmline.c
src/cc65/declattr.c
src/cc65/pragma.c
src/cc65/symentry.c
src/common/cddefs.h [new file with mode: 0644]
src/common/coll.c
src/common/coll.h
src/common/objdefs.h
src/common/symdefs.h
src/common/target.c
src/da65/config.c
src/ld65/condes.c [new file with mode: 0644]
src/ld65/condes.h [new file with mode: 0644]
src/ld65/config.c
src/ld65/exports.c
src/ld65/exports.h
src/ld65/fileio.c
src/ld65/initfunc.c [deleted file]
src/ld65/initfunc.h [deleted file]
src/ld65/main.c
src/ld65/make/gcc.mak
src/ld65/scanner.c
src/ld65/scanner.h
src/od65/dump.c
src/od65/fileio.c

index 1f5bd8abec176c674e9becc506d1697a62460261..6fb40f9af7082e6becaeae85fa828d458a5dad5f 100644 (file)
@@ -286,6 +286,3 @@ void ObjExtract (const char* Name)
 
 
 
-
-
-
index 33362aca3682a7cf403b79e2db9486646ea100ac..90b25c21843d9eab0d67782b2a4d847cb0c4ce20 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* ca65 */
 #include "error.h"
 #include "expr.h"
index 4ada4317a24870ec14e01b22ffb2611e2f928374..3e09dee13d91f2876348925fce6ba551becd51b6 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "check.h"
 #include "exprdefs.h"
index 8448d44df9a3146b54a99f9e929d828e54c5e461..4e1d28c448a663c1d4ebb37e90751f0f63febb41 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "check.h"
 #include "hashstr.h"
index f460cdc91f6c4df57dd2974a1ff3ede6e7f8dbe6..5de8b9cb69b474cb5c83c145bebf2ae4577572bf 100644 (file)
 
 
 #include <stdio.h>
+#include <string.h>
 
 /* common */
 #include "check.h"
-                  
+
 /* ca65 */
 #include "error.h"
 #include "expr.h"
index ed1bd2405c96794aac3064bb5ade4b7101eb6fe9..31e37421e22cfd65d86d3ee6b70e06c22adabb84 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "optdefs.h"
 #include "xmalloc.h"
index 9373ec01b73d22de41be384c99c065afa12b1da9..cbc23b721bff36809d30f557eca749265c6090e9 100644 (file)
@@ -41,6 +41,7 @@
 
 /* common */
 #include "bitops.h"
+#include "cddefs.h"
 #include "check.h"
 #include "symdefs.h"
 #include "tgttrans.h"
@@ -173,6 +174,32 @@ static long IntArg (long Min, long Max)
 
 
 
+static void ConDes (const char* Name, unsigned Type)
+/* Parse remaining line for constructor/destructor of the remaining type */
+{
+    long Prio;
+
+    /* Optional constructor priority */
+    if (Tok == TOK_COMMA) {
+       /* Priority value follows */
+       NextTok ();
+       Prio = ConstExpression ();
+       if (Prio < CD_PRIO_MIN || Prio > CD_PRIO_MAX) {
+           /* Value out of range */
+           Error (ERR_RANGE);
+           return;
+       }
+    } else {
+       /* Use the default priority value */
+       Prio = CD_PRIO_DEF;
+    }
+
+    /* Define the symbol */
+    SymConDes (Name, Type, (unsigned) Prio);
+}
+
+
+
 /*****************************************************************************/
 /*                            Handler functions                             */
 /*****************************************************************************/
@@ -320,7 +347,7 @@ static void DoByte (void)
            NextTok ();
            /* Do smart handling of dangling comma */
            if (Tok == TOK_SEP) {
-               Error (ERR_UNEXPECTED_EOL);
+               Error (ERR_UNEXPECTED_EOL);
                break;
            }
        }
@@ -346,6 +373,76 @@ static void DoCode (void)
 
 
 
+static void DoConDes (void)
+/* Export a symbol as constructor/destructor */
+{
+    static const char* Keys[] = {
+               "CONSTRUCTOR",
+       "DESTRUCTOR",
+    };
+    char Name [sizeof (SVal)];
+    long Type;
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+       ErrorSkip (ERR_IDENT_EXPECTED);
+       return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Type follows. May be encoded as identifier or numerical */
+    ConsumeComma ();
+    if (Tok == TOK_IDENT) {
+
+       /* Map the following keyword to a number, then skip it */
+       Type = GetSubKey (Keys, sizeof (Keys) / sizeof (Keys [0]));
+       NextTok ();
+
+       /* Check if we got a valid keyword */
+       if (Type < 0) {
+           Error (ERR_SYNTAX);
+           SkipUntilSep ();
+           return;
+       }
+
+    } else {
+
+       /* Read the type as numerical value */
+               Type = ConstExpression ();
+       if (Type < CD_TYPE_MIN || Type > CD_TYPE_MAX) {
+           /* Value out of range */
+           Error (ERR_RANGE);
+           return;
+       }
+
+    }
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, (unsigned) Type);
+}
+
+
+
+static void DoConstructor (void)
+/* Export a symbol as constructor */
+{
+    char Name [sizeof (SVal)];
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+       ErrorSkip (ERR_IDENT_EXPECTED);
+       return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, CD_TYPE_CON);
+}
+
+
+
 static void DoData (void)
 /* Switch to the data segment */
 {
@@ -422,6 +519,25 @@ static void DoDefine (void)
 
 
 
+static void DoDestructor (void)
+/* Export a symbol as destructor */
+{
+    char Name [sizeof (SVal)];
+
+    /* Symbol name follows */
+    if (Tok != TOK_IDENT) {
+       ErrorSkip (ERR_IDENT_EXPECTED);
+       return;
+    }
+    strcpy (Name, SVal);
+    NextTok ();
+
+    /* Parse the remainder of the line and export the symbol */
+    ConDes (Name, CD_TYPE_DES);
+}
+
+
+
 static void DoDWord (void)
 /* Define dwords */
 {
@@ -736,41 +852,6 @@ static void DoInclude (void)
 
 
 
-static void DoInitializer (void)
-/* Export a symbol as initializer */
-{
-    char Name [sizeof (SVal)];
-    long Val;
-
-    /* Symbol name follows */
-    if (Tok != TOK_IDENT) {
-       ErrorSkip (ERR_IDENT_EXPECTED);
-       return;
-    }
-    strcpy (Name, SVal);
-    NextTok ();
-
-    /* Optional initializer value */
-    if (Tok == TOK_COMMA) {
-       /* Initializer value follows */
-       NextTok ();
-       Val = ConstExpression ();
-       if (Val < EXP_INIT_MIN || Val > EXP_INIT_MAX) {
-           /* Value out of range */
-           Error (ERR_RANGE);
-           return;
-       }
-    } else {
-       /* Use the default initializer value */
-       Val = EXP_INIT_DEF;
-    }
-
-    /* Define the symbol */
-    SymInitializer (Name, (unsigned) Val);
-}
-
-
-
 static void DoInvalid (void)
 /* Handle a token that is invalid here, since it should have been handled on
  * a much lower level of the expression hierarchy. Getting this sort of token
@@ -1171,7 +1252,9 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoCase          },
     { ccNone,          DoCode          },
     { ccNone,          DoUnexpected,   },      /* .CONCAT */
+    { ccNone,          DoConDes        },
     { ccNone,          DoUnexpected    },      /* .CONST */
+    { ccNone,          DoConstructor   },
     { ccNone,          DoUnexpected    },      /* .CPU */
     { ccNone,          DoData          },
     { ccNone,          DoDbg,          },
@@ -1179,6 +1262,7 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoDebugInfo     },
     { ccNone,          DoDefine        },
     { ccNone,          DoUnexpected    },      /* .DEFINED */
+    { ccNone,          DoDestructor    },
     { ccNone,          DoDWord         },
     { ccKeepToken,     DoConditionals  },      /* .ELSE */
     { ccKeepToken,     DoConditionals  },      /* .ELSEIF */
@@ -1215,7 +1299,6 @@ static CtrlDesc CtrlCmdTab [] = {
     { ccNone,          DoImportZP      },
     { ccNone,          DoIncBin        },
     { ccNone,          DoInclude       },
-    { ccNone,          DoInitializer   },
     { ccNone,          DoInvalid       },      /* .LEFT */
     { ccNone,          DoLineCont      },
     { ccNone,          DoList          },
index b442c165f0a57e609abe0bf57984699db643ee4a..d2a0de67ad69def5a1114b61f148b10a8c1f68a0 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* common */
 #include "xmalloc.h"
 
@@ -106,7 +108,7 @@ static void RepeatTokenCheck (TokList* L)
 /* Called each time a token from a repeat token list is set. Is used to check
  * for and replace identifiers that are the repeat counter.
  */
-{                
+{
     if (Tok == TOK_IDENT && L->Data != 0 && strcmp (SVal, L->Data) == 0) {
        /* Must replace by the repeat counter */
        Tok  = TOK_INTCON;
index b14a974d6f4b8a9a407430246a1fecd1145fb963..7fb2fe97c13e8e5c90a4726d7a4172ff83760f23 100644 (file)
@@ -133,7 +133,9 @@ struct DotKeyword {
     { "CASE",                  TOK_CASE        },
     { "CODE",          TOK_CODE        },
     { "CONCAT",                TOK_CONCAT      },
+    { "CONDES",                TOK_CONDES      },
     { "CONST",                 TOK_CONST       },
+    { "CONSTRUCTOR",   TOK_CONSTRUCTOR },
     { "CPU",           TOK_CPU         },
     { "DATA",                  TOK_DATA        },
     { "DBG",           TOK_DBG         },
@@ -142,6 +144,7 @@ struct DotKeyword {
     { "DEF",                   TOK_DEFINED     },
     { "DEFINE",                TOK_DEFINE      },
     { "DEFINED",       TOK_DEFINED     },
+    { "DESTRUCTOR",    TOK_DESTRUCTOR  },
     { "DWORD",                 TOK_DWORD       },
     { "ELSE",                  TOK_ELSE        },
     { "ELSEIF",                TOK_ELSEIF      },
@@ -182,7 +185,6 @@ struct DotKeyword {
     { "IMPORTZP",      TOK_IMPORTZP    },
     { "INCBIN",                TOK_INCBIN      },
     { "INCLUDE",       TOK_INCLUDE     },
-    { "INITIALIZER",   TOK_INITIALIZER },
     { "LEFT",          TOK_LEFT        },
     { "LINECONT",      TOK_LINECONT    },
     { "LIST",          TOK_LIST        },
index 0849eb52903b25542e955f8c69c8c24bc5156d37..f6fddc58810a36454fbd97592e8914ca7c9af63a 100644 (file)
@@ -120,8 +120,10 @@ enum Token {
     TOK_BYTE,
     TOK_CASE,
     TOK_CODE,
-    TOK_CONCAT,
+    TOK_CONCAT,            
+    TOK_CONDES,
     TOK_CONST,
+    TOK_CONSTRUCTOR,
     TOK_CPU,
     TOK_DATA,
     TOK_DBG,
@@ -129,6 +131,7 @@ enum Token {
     TOK_DEBUGINFO,
     TOK_DEFINE,
     TOK_DEFINED,
+    TOK_DESTRUCTOR,
     TOK_DWORD,
     TOK_ELSE,
     TOK_ELSEIF,
@@ -165,7 +168,6 @@ enum Token {
     TOK_IMPORTZP,
     TOK_INCBIN,
     TOK_INCLUDE,
-    TOK_INITIALIZER,
     TOK_LEFT,
     TOK_LINECONT,
     TOK_LIST,
index 8c2af867145b1a282c7de5e3cb68bee7fb826ac5..76055f92715df2b02148bc568311290eca3735a1 100644 (file)
@@ -36,6 +36,7 @@
 #include <string.h>
 
 /* common */
+#include "cddefs.h"
 #include "check.h"
 #include "hashstr.h"
 #include "symdefs.h"
@@ -63,9 +64,8 @@
 #define SF_EXPORT              0x0004          /* Export this symbol */
 #define SF_IMPORT      0x0008          /* Import this symbol */
 #define SF_GLOBAL      0x0010          /* Global symbol */
-#define SF_INITIALIZER 0x0020          /* Exported initializer */
-#define SF_ZP                  0x0040          /* Declared as zeropage symbol */
-#define SF_ABS         0x0080          /* Declared as absolute symbol */
+#define SF_ZP                  0x0020          /* Declared as zeropage symbol */
+#define SF_ABS         0x0040          /* Declared as absolute symbol */
 #define SF_INDEXED     0x0800          /* Index is valid */
 #define SF_CONST       0x1000          /* The symbol has a constant value */
 #define SF_MULTDEF             0x2000          /* Multiply defined symbol */
@@ -97,15 +97,16 @@ struct SymEntry {
        long                Val;        /* Value (if CONST set) */
        SymEntry*           Sym;        /* Symbol (if trampoline entry) */
     } V;
-    unsigned char          InitVal;    /* Initializer value */
+    unsigned char                  ConDesPrio[CD_TYPE_COUNT];  /* ConDes priorities... */
+                                       /* ...actually value+1 (used as flag) */
     char                           Name [1];   /* Dynamic allocation */
 };
 
 
 
 /* Definitions for the hash table */
-#define MAIN_HASHTAB_SIZE      213
-#define SUB_HASHTAB_SIZE       53
+#define MAIN_HASHTAB_SIZE      213
+#define SUB_HASHTAB_SIZE       53
 typedef struct SymTable SymTable;
 struct SymTable {
     unsigned                   TableSlots;     /* Number of hash table slots */
@@ -140,7 +141,7 @@ static unsigned             ExportCount = 0;/* Counter for export symbols */
 
 static int IsLocal (const char* Name)
 /* Return true if Name is the name of a local symbol */
-{             
+{
     return (*Name == LocalStart);
 }
 
@@ -166,7 +167,7 @@ static SymEntry* NewSymEntry (const char* Name)
     S->Pos     = CurPos;
     S->Flags   = 0;
     S->V.Expr  = 0;
-    S->InitVal = 0;
+    memset (S->ConDesPrio, 0, sizeof (S->ConDesPrio));
     memcpy (S->Name, Name, Len+1);
 
     /* Insert it into the list of all entries */
@@ -579,15 +580,16 @@ void SymGlobal (const char* Name, int ZP)
 
 
 
-void SymInitializer (const char* Name, unsigned InitVal)
-/* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols.
+void SymConDes (const char* Name, unsigned Type, unsigned Prio)
+/* Mark the given symbol as a module constructor/destructor. This will also
+ * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 {
     SymEntry* S;
 
-    /* Check the InitVal parameter */
-    CHECK (InitVal >= EXP_INIT_MIN && InitVal <= EXP_INIT_MAX);
+    /* Check the parameters */
+    CHECK (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+    CHECK (Prio >= CD_PRIO_MIN && Prio <= CD_PRIO_MAX);
 
     /* Don't accept local symbols */
     if (IsLocal (Name)) {
@@ -613,18 +615,18 @@ void SymInitializer (const char* Name, unsigned InitVal)
        Error (ERR_SYM_REDECL_MISMATCH);
     }
 
-    /* If the symbol was already declared as an initializer, check if the new
-     * initializer value is the same as the old one.
+    /* If the symbol was already declared as a condes, check if the new
+     * priority value is the same as the old one.
      */
-    if (S->Flags & SF_INITIALIZER) {
-       if (S->InitVal != InitVal) {
+    if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
+       if (S->ConDesPrio[Type] != Prio) {
            Error (ERR_SYM_REDECL_MISMATCH);
        }
     }
-    S->InitVal = InitVal;
+    S->ConDesPrio[Type] = Prio;
 
     /* Set the symbol data */
-    S->Flags |= SF_EXPORT | SF_INITIALIZER | SF_REFERENCED;
+    S->Flags |= SF_EXPORT | SF_REFERENCED;
 }
 
 
@@ -1064,6 +1066,7 @@ void WriteExports (void)
 /* Write the exports list to the object file */
 {
     SymEntry* S;
+    unsigned Type;
 
     /* Tell the object file module that we're about to start the exports */
     ObjStartExports ();
@@ -1086,14 +1089,26 @@ void WriteExports (void)
            /* Add zeropage/abs bits */
            ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
 
-           /* Add the initializer bits */
-           if (S->Flags & SF_INITIALIZER) {
-               ExprMask |= S->InitVal;
+           /* Count the number of ConDes types */
+           for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+               if (S->ConDesPrio[Type] != CD_PRIO_NONE) {
+                   INC_EXP_CONDES_COUNT (ExprMask);
+               }
            }
 
            /* Write the type */
            ObjWrite8 (ExprMask);
 
+           /* Write any ConDes declarations */
+           if (GET_EXP_CONDES_COUNT (ExprMask) > 0) {
+               for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+                   unsigned char Prio = S->ConDesPrio[Type];
+                   if (Prio != CD_PRIO_NONE) {
+                       ObjWrite8 (CD_BUILD (Type, Prio));
+                   }
+               }
+           }
+
            /* Write the name */
                    ObjWriteStr (S->Name);
 
@@ -1158,11 +1173,6 @@ void WriteDbgSyms (void)
                /* Add zeropage/abs bits */
                ExprMask |= (S->Flags & SF_ZP)? EXP_ZP : EXP_ABS;
 
-               /* Add the initializer bits */
-               if (S->Flags & SF_INITIALIZER) {
-                   ExprMask |= S->InitVal;
-               }
-
                /* Write the type */
                ObjWrite8 (ExprMask);
 
index 959bc3a0c692742ef574a1f04098148ec827f1b0..f25b2e09e34d8995e82be943c17840cc84d840eb 100644 (file)
@@ -86,9 +86,9 @@ void SymGlobal (const char* Name, int ZP);
  * either imported or exported.
  */
 
-void SymInitializer (const char* Name, unsigned InitVal);
-/* Mark the given symbol as an initializer. This will also mark the symbol as
- * an export. Initializers may never be zero page symbols.
+void SymConDes (const char* Name, unsigned Type, unsigned Prio);
+/* Mark the given symbol as a module constructor/destructor. This will also
+ * mark the symbol as an export. Initializers may never be zero page symbols.
  */
 
 int SymIsConst (SymEntry* Sym);
index db8c168125521d09b4906dda22750610940a0647..7303a82e3e3d54c813048aafcbfed4549c278005 100644 (file)
 
 
 #include <stdio.h>
-
-#include "../common/xmalloc.h"
-#include "../common/xsprintf.h"
-
+#include <string.h>
+         
+/* common */
+#include "xmalloc.h"
+#include "xsprintf.h"
+         
+/* cc65 */
 #include "error.h"
 #include "asmline.h"
 
index b06c36aed3dfc5b460af0093483661bef1f84f2c..9dbc710959e63d3cf17ed28a7cab424eca6994f9 100644 (file)
@@ -33,6 +33,8 @@
 
 
 
+#include <string.h>
+
 /* cc65 */
 #include "error.h"
 #include "scanner.h"
@@ -125,7 +127,7 @@ void ParseAttribute (const Declaration* D, DeclAttr* A)
 /* Parse an additional __attribute__ modifier */
 {
     ident    AttrName;
-    attrib_t AttrType;              
+    attrib_t AttrType;
 
     /* Initialize the attribute description with "no attribute" */
     A->AttrType = atNone;
index f4020cf3b64e8b2636f4c6af707d3e8d760828d7..c68009c02ec43de4a531606e0389dcb7bf092d57 100644 (file)
 
 
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
-
+                  
+/* cc65 */
 #include "codegen.h"
 #include "error.h"
 #include "expr.h"
index 03223fc97ac57d0402b793dcb617ae200866e8c3..35ed800b4d0c5c20bc0882ba6509793d76e1a287 100644 (file)
 
 
 
-#include "../common/xmalloc.h"
-
+#include <string.h>
+                  
+/* common */
+#include "xmalloc.h"
+         
+/* cc65 */
 #include "symentry.h"
 
 
@@ -43,7 +47,7 @@
 /*                                  Code                                    */
 /*****************************************************************************/
 
-
+         
 
 SymEntry* NewSymEntry (const char* Name, unsigned Flags)
 /* Create a new symbol table with the given name */
diff --git a/src/common/cddefs.h b/src/common/cddefs.h
new file mode 100644 (file)
index 0000000..5d87179
--- /dev/null
@@ -0,0 +1,80 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                cddefs.h                                  */
+/*                                                                           */
+/*             Definitions for module constructor/destructors               */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000     Ullrich von Bassewitz                                        */
+/*              Wacholderweg 14                                              */
+/*              D-70597 Stuttgart                                            */
+/* EMail:       uz@musoftware.de                                             */
+/*                                                                           */
+/*                                                                           */
+/* 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 CDDEFS_H
+#define CDDEFS_H
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* ConDes types. Count is only 7 because we want to encode 0..count in 3 bits */
+#define        CD_TYPE_COUNT   7               /* Number of table types */
+#define CD_TYPE_MIN            0               /* Minimum numeric type value */
+#define CD_TYPE_MAX            6               /* Maximum numeric type value */
+
+/* ConDes priorities, zero is no valid priority and used to mark an empty
+ * (missing) decl for this type throughout the code.
+ */
+#define CD_PRIO_NONE   0               /* No priority (no decl) */
+#define CD_PRIO_MIN            1               /* Lowest priority */
+#define CD_PRIO_DEF    7               /* Default priority */
+#define CD_PRIO_MAX    32              /* Highest priority */
+
+/* Predefined types */
+#define CD_TYPE_CON    0               /* Constructor */
+#define CD_TYPE_DES    1               /* Destructor */
+
+/* When part of an export in an object file, type and priority are encoded in
+ * one byte. In this case, the following macros access the fields:
+ */
+#define CD_GET_TYPE(v)                 (((v) >> 5) & 0x07)
+#define CD_GET_PRIO(v)         (((v) & 0x1F) + 1)
+
+/* Macro to build the byte value: */
+#define CD_BUILD(type,prio)            ((((type) & 0x07) << 5) | (((prio) - 1) & 0x1F))
+
+
+
+/* End of cddefs.h */
+
+#endif
+
+
+
index 8ce56a8c71eacf703e00ea64090f7eaaff7fee1a..d6929f7071ffc44522ea4fa3e666ee2c13936ef3 100644 (file)
@@ -225,14 +225,64 @@ void CollReplace (Collection* C, void* Item, unsigned Index)
 
 
 
-void CollSort (Collection* C, int (*Compare) (const void*, const void*))
-/* Sort the collection using the given compare function.
- * BEWARE: The function uses qsort internally, so the Compare function does
- * actually get pointers to the object pointers, not just object pointers!
+static void QuickSort (Collection* C, int Lo, int Hi,
+                      int (*Compare) (void*, const void*, const void*),
+                      void* Data)
+/* Internal recursive sort function. */
+{
+    /* Get a pointer to the items */
+    void** Items = C->Items;
+
+    /* Quicksort */
+    while (Hi > Lo) {
+       int I = Lo + 1;
+       int J = Hi;
+       while (I <= J) {
+           while (I <= J && Compare (Data, Items[Lo], Items[I]) >= 0) {
+               ++I;
+           }
+           while (I <= J && Compare (Data, Items[Lo], Items[J]) < 0) {
+               --J;
+           }
+           if (I <= J) {
+               /* Swap I and J */
+               void* Tmp = Items[I];
+               Items[I]  = Items[J];
+               Items[J]  = Tmp;
+               ++I;
+               --J;
+           }
+       }
+       if (J != Lo) {
+           /* Swap J and Lo */
+           void* Tmp = Items[J];
+           Items[J]  = Items[Lo];
+           Items[Lo] = Tmp;
+       }
+       if (J > (Hi + Lo) / 2) {
+           QuickSort (C, J + 1, Hi, Compare, Data);
+           Hi = J - 1;
+       } else {
+           QuickSort (C, Lo, J - 1, Compare, Data);
+           Lo = J + 1;
+       }
+    }
+}
+
+
+
+void CollSort (Collection* C,
+              int (*Compare) (void*, const void*, const void*),
+              void* Data)
+/* Sort the collection using the given compare function. The data pointer is
+ * passed as *first* element to the compare function, it's not used by the
+ * sort function itself. The other two pointer passed to the Compare function
+ * are pointers to objects.
  */
 {
-    /* Use qsort */
-    qsort (C->Items, C->Count, sizeof (void*), Compare);
+    if (C->Count > 1) {
+       QuickSort (C, 0, C->Count-1, Compare, Data);
+    }
 }
 
 
index 144442f6549240fcb11737a68f1773a11f549d64..ba1d4f6013f6ed6c8fb12e9721051fbd298f8139 100644 (file)
@@ -113,10 +113,13 @@ void CollReplace (Collection* C, void* Item, unsigned Index);
  * just the pointer will et replaced.
  */
 
-void CollSort (Collection* C, int (*Compare) (const void*, const void*));
-/* Sort the collection using the given compare function.
- * BEWARE: The function uses qsort internally, so the Compare function does
- * actually get pointers to the object pointers, not just object pointers!
+void CollSort (Collection* C,
+              int (*Compare) (void*, const void*, const void*),
+              void* Data);
+/* Sort the collection using the given compare function. The data pointer is
+ * passed as *first* element to the compare function, it's not used by the
+ * sort function itself. The other two pointer passed to the Compare function
+ * are pointers to objects.
  */
 
 
index 8ea626deb71f25e960aa4197f8d4a9ba6fa6e517..7678f4763a40628ebb6e257da969a678b53946f8 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Defines for magic and version */
 #define OBJ_MAGIC      0x616E7A55
-#define OBJ_VERSION    0x0007
+#define OBJ_VERSION    0x0008
 
 /* Size of an object file header */
 #define        OBJ_HDR_SIZE    56
index f4e192bf5f79144120d5de84db357357d97d2dbc..bf5ebe2844c4e825ce7a1b3463937330b562ddc1 100644 (file)
 
 /* Export size */
 #define EXP_ABS                0x00            /* Export as normal value */
-#define EXP_ZP                 0x20            /* Export as zero page value */
-#define EXP_MASK_SIZE  0x20            /* Size mask */
+#define EXP_ZP                 0x08            /* Export as zero page value */
+#define EXP_MASK_SIZE  0x08            /* Size mask */
 
 #define IS_EXP_ABS(x)          (((x) & EXP_MASK_SIZE) == EXP_ABS)
 #define IS_EXP_ZP(x)   (((x) & EXP_MASK_SIZE) == EXP_ZP)
 
 /* Export value type */
 #define EXP_CONST      0x00            /* Mask bit for const values */
-#define EXP_EXPR       0x40            /* Mask bit for expr values */
-#define EXP_MASK_VAL   0x40            /* Value mask */
+#define EXP_EXPR       0x10            /* Mask bit for expr values */
+#define EXP_MASK_VAL   0x10            /* Value mask */
 
 #define IS_EXP_CONST(x)        (((x) & EXP_MASK_VAL) == EXP_CONST)
 #define IS_EXP_EXPR(x)         (((x) & EXP_MASK_VAL) == EXP_EXPR)
 
-/* Export initializer flag */
-#define EXP_INIT_MIN   0x01            /* Minimum value */
-#define EXP_INIT_MAX   0x1F            /* Maximum value */
-#define EXP_INIT_DEF   0x18            /* Default value */
-#define EXP_MASK_INIT  0x1F            /* Initializer value mask */
+/* Number of module constructor/destructor declarations for an export */
+#define EXP_CONDES_MASK        0x07
 
-#define IS_EXP_INIT(x)         (((x) & EXP_MASK_INIT) != 0)
-#define GET_EXP_INIT_VAL(x)    ((x) & EXP_MASK_INIT)
+#define IS_EXP_CONDES(x)       (((x) & EXP_CONDES_MASK) != 0)
+#define GET_EXP_CONDES_COUNT(x)        ((x) & EXP_CONDES_MASK)
+#define INC_EXP_CONDES_COUNT(x) ((x)++)
 
 
 
index 74864d243e8f57852aafca6bca0afec9fc7cb2d0..3a5fc217174c5b850cef06564b896a2b0103a8fc 100644 (file)
@@ -34,6 +34,7 @@
 
 
 #include <stdlib.h>
+#include <string.h>
 #include <ctype.h>
 
 #include "target.h"
index d76aa6993b04748336ba6842f583916b179fd44e..275ba7d5012c73c9eb460f2aa754596d4920493b 100644 (file)
@@ -34,6 +34,7 @@
 
 
 #include <stdio.h>
+#include <string.h>
 #if defined(_MSC_VER)
 /* Microsoft compiler */
 #  include <io.h>
diff --git a/src/ld65/condes.c b/src/ld65/condes.c
new file mode 100644 (file)
index 0000000..7c9e7f7
--- /dev/null
@@ -0,0 +1,188 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                condes.h                                  */
+/*                                                                           */
+/*                  Module constructor/destructor support                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
+/*                                                                           */
+/*                                                                           */
+/* 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.                                                          */
+/*                                                                           */
+/*****************************************************************************/
+
+
+
+/* common */
+#include "check.h"
+#include "coll.h"
+#include "xmalloc.h"
+
+/* ld65 */
+#include "exports.h"
+#include "segments.h"
+#include "condes.h"
+
+
+
+/*****************************************************************************/
+/*                                          Data                                    */
+/*****************************************************************************/
+
+
+
+/* Struct describing one condes type */
+typedef struct ConDesDesc ConDesDesc;
+struct ConDesDesc {
+    Collection         ExpList;        /* List of exported symbols */
+    char*              Label;          /* Name of table label */
+    char*              SegName;        /* Name of segment the table is in */
+    unsigned char      Enable;         /* Table enabled */
+};
+
+/* Array for all types */
+static ConDesDesc ConDes[CD_TYPE_COUNT] = {
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+    { STATIC_COLLECTION_INITIALIZER, 0, 0, 0 },
+};
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void ConDesAddExport (struct Export* E)
+/* Add the given export to the list of constructors/destructor */
+{
+    unsigned Type;
+
+    /* Insert the export into all tables for which declarations exist */
+    for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+       unsigned Prio = E->ConDes[Type];
+       if (Prio != CD_PRIO_NONE) {
+                   CollAppend (&ConDes[Type].ExpList, E);
+       }
+    }
+}
+
+
+
+void ConDesSetSegName (unsigned Type, const char* SegName)
+/* Set the segment name where the table should go */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && SegName != 0);
+
+    /* Setting the segment name twice is bad */
+    CHECK (ConDes[Type].SegName == 0);
+
+    /* Set the name */
+    ConDes[Type].SegName = xstrdup (SegName);
+}
+
+
+
+void ConDesSetLabel (unsigned Type, const char* Name)
+/* Set the label for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX && Name != 0);
+
+    /* Setting the label twice is bad */
+    CHECK (ConDes[Type].Label == 0);
+
+    /* Set the name */
+    ConDes[Type].Label = xstrdup (Name);
+}
+
+
+
+const char* ConDesGetSegName (unsigned Type)
+/* Return the segment name for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+
+    /* Return the name */
+    return ConDes[Type].SegName;
+}
+
+
+
+const char* ConDesGetLabel (unsigned Type)
+/* Return the label for the given ConDes type */
+{
+    /* Check the parameters */
+    PRECONDITION (Type >= CD_TYPE_MIN && Type <= CD_TYPE_MAX);
+
+    /* Return the name */
+    return ConDes[Type].Label;
+}
+
+
+
+int ConDesHasSegName (unsigned Type)
+/* Return true if a segment name is already defined for this ConDes type */
+{
+    return (ConDesGetSegName(Type) != 0);
+}
+
+
+
+int ConDesHasLabel (unsigned Type)
+/* Return true if a label is already defined for this ConDes type */
+{
+    return (ConDesGetLabel(Type) != 0);
+}
+
+
+
+void ConDesCreate (void)
+/* Create the condes tables if requested */
+{
+}
+
+
+
+void ConDesDump (void)
+/* Dump ConDes data to stdout for debugging */
+{
+    unsigned Type;
+    for (Type = 0; Type < CD_TYPE_COUNT; ++Type) {
+               Collection* ExpList = &ConDes[Type].ExpList;
+       printf ("CONDES(%u): %u symbols\n", Type, CollCount (ExpList));
+    }
+}
+
+
+
+
+
diff --git a/src/ld65/condes.h b/src/ld65/condes.h
new file mode 100644 (file)
index 0000000..72d295a
--- /dev/null
@@ -0,0 +1,92 @@
+/*****************************************************************************/
+/*                                                                           */
+/*                                condes.h                                  */
+/*                                                                           */
+/*                  Module constructor/destructor support                   */
+/*                                                                           */
+/*                                                                           */
+/*                                                                           */
+/* (C) 2000      Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
+/*                                                                           */
+/*                                                                           */
+/* 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 CONDES_H
+#define CONDES_H
+
+
+
+/*****************************************************************************/
+/*                                Forwards                                  */
+/*****************************************************************************/
+
+
+
+struct Export;
+
+
+
+/*****************************************************************************/
+/*                                          Code                                    */
+/*****************************************************************************/
+
+
+
+void ConDesAddExport (struct Export* E);
+/* Add the given export to the list of constructors/destructor */
+
+void ConDesSetSegName (unsigned Type, const char* SegName);
+/* Set the segment name where the table should go */
+
+void ConDesSetLabel (unsigned Type, const char* Name);
+/* Set the label for the given ConDes type */
+
+const char* ConDesGetSegName (unsigned Type);
+/* Return the segment name for the given ConDes type */
+
+const char* ConDesGetLabel (unsigned Type);
+/* Return the label for the given ConDes type */
+
+int ConDesHasSegName (unsigned Type);
+/* Return true if a segment name is already defined for this ConDes type */
+
+int ConDesHasLabel (unsigned Type);
+/* Return true if a label is already defined for this ConDes type */
+
+void ConDesCreate (void);
+/* Create the condes tables if requested */
+
+void ConDesDump (void);
+/* Dump ConDes data to stdout for debugging */
+
+
+
+/* End of condes.h */
+
+#endif
+
+
+
+
index d3f63765481721f47aa51eb15f56b540719b4156..314fc235c10c7370f2a981c81830b8292df205c8 100644 (file)
 #include "check.h"
 #include "bitops.h"
 #include "xmalloc.h"
-         
+
 /* ld65 */
-#include "error.h"
-#include "global.h"
 #include "bin.h"
-#include "o65.h"
 #include "binfmt.h"
+#include "condes.h"
+#include "error.h"
 #include "exports.h"
+#include "global.h"
+#include "o65.h"
 #include "scanner.h"
 #include "config.h"
 
@@ -115,6 +116,141 @@ static unsigned O65Attr   = 0;
 
 
 
+/*****************************************************************************/
+/*                                Forwards                                  */
+/*****************************************************************************/
+
+
+
+static File* NewFile (const char* Name);
+/* Create a new file descriptor and insert it into the list */
+
+
+
+/*****************************************************************************/
+/*                             List management                              */
+/*****************************************************************************/
+
+
+
+static File* FindFile (const char* Name)
+/* Find a file with a given name. */
+{
+    File* F = FileList;
+    while (F) {
+       if (strcmp (F->Name, Name) == 0) {
+           return F;
+       }
+       F = F->Next;
+    }
+    return 0;
+}
+
+
+
+static File* GetFile (const char* Name)
+/* Get a file entry with the given name. Create a new one if needed. */
+{
+    File* F = FindFile (Name);
+    if (F == 0) {
+       /* Create a new one */
+       F = NewFile (Name);
+    }
+    return F;
+}
+
+
+
+static void FileInsert (File* F, Memory* M)
+/* Insert the memory area into the files list */
+{
+    M->F = F;
+    if (F->MemList == 0) {
+       /* First entry */
+       F->MemList = M;
+    } else {
+       F->MemLast->FNext = M;
+    }
+    F->MemLast = M;
+}
+
+
+
+static Memory* CfgFindMemory (const char* Name)
+/* Find the memory are with the given name. Return NULL if not found */
+{
+    Memory* M = MemoryList;
+    while (M) {
+               if (strcmp (M->Name, Name) == 0) {
+                   return M;
+               }
+               M = M->Next;
+    }
+    return 0;
+}
+
+
+
+static Memory* CfgGetMemory (const char* Name)
+/* Find the memory are with the given name. Print an error on an invalid name */
+{
+    Memory* M = CfgFindMemory (Name);
+    if (M == 0) {
+       CfgError ("Invalid memory area `%s'", Name);
+    }
+    return M;
+}
+
+
+
+static SegDesc* CfgFindSegDesc (const char* Name)
+/* Find the segment descriptor with the given name, return NULL if not found. */
+{
+    SegDesc* S = SegDescList;
+    while (S) {
+       if (strcmp (S->Name, Name) == 0) {
+           /* Found */
+           return S;
+               }
+       S = S->Next;
+    }
+
+    /* Not found */
+    return 0;
+}
+
+
+
+static void SegDescInsert (SegDesc* S)
+/* Insert a segment descriptor into the list of segment descriptors */
+{
+    /* Insert the struct into the list */
+    S->Next = SegDescList;
+    SegDescList = S;
+    ++SegDescCount;
+}
+
+
+
+static void MemoryInsert (Memory* M, SegDesc* S)
+/* Insert the segment descriptor into the memory area list */
+{
+    /* Create a new node for the entry */
+    MemListNode* N = xmalloc (sizeof (MemListNode));
+    N->Seg  = S;
+    N->Next = 0;
+
+    if (M->SegLast == 0) {
+               /* First entry */
+               M->SegList = N;
+    } else {
+       M->SegLast->Next = N;
+    }
+    M->SegLast = N;
+}
+
+
+
 /*****************************************************************************/
 /*                        Constructors/Destructors                          */
 /*****************************************************************************/
@@ -156,13 +292,9 @@ static Memory* NewMemory (const char* Name)
     unsigned Len = strlen (Name);
 
     /* Check for duplicate names */
-    Memory* M =        MemoryList;
-    while (M) {
-       if (strcmp (M->Name, Name) == 0) {
-                   CfgError ("Memory area `%s' defined twice", Name);
-           break;
-               }
-       M = M->Next;
+    Memory* M =        CfgFindMemory (Name);
+    if (M) {
+       CfgError ("Memory area `%s' defined twice", Name);
     }
 
     /* Allocate memory */
@@ -208,13 +340,9 @@ static SegDesc* NewSegDesc (const char* Name)
     unsigned Len = strlen (Name);
 
     /* Check for duplicate names */
-    SegDesc* S = SegDescList;
-    while (S) {
-       if (strcmp (S->Name, Name) == 0) {
-                   CfgError ("Segment `%s' defined twice", Name);
-           break;
-               }
-       S = S->Next;
+    SegDesc* S = CfgFindSegDesc (Name);
+    if (S) {
+       CfgError ("Segment `%s' defined twice", Name);
     }
 
     /* Verify that the given segment does really exist */
@@ -278,49 +406,6 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name)
 
 
 
-static File* FindFile (const char* Name)
-/* Find a file with a given name. */
-{
-    File* F = FileList;
-    while (F) {
-       if (strcmp (F->Name, Name) == 0) {
-           return F;
-       }
-       F = F->Next;
-    }
-    return 0;
-}
-
-
-
-static File* GetFile (const char* Name)
-/* Get a file entry with the given name. Create a new one if needed. */
-{
-    File* F = FindFile (Name);
-    if (F == 0) {
-       /* Create a new one */
-       F = NewFile (Name);
-    }
-    return F;
-}
-
-
-
-static void FileInsert (File* F, Memory* M)
-/* Insert the memory area into the files list */
-{
-    M->F = F;
-    if (F->MemList == 0) {
-       /* First entry */
-       F->MemList = M;
-    } else {
-       F->MemLast->FNext = M;
-    }
-    F->MemLast = M;
-}
-
-
-
 static void ParseMemory (void)
 /* Parse a MEMORY section */
 {
@@ -351,7 +436,7 @@ static void ParseMemory (void)
        while (CfgTok == CFGTOK_IDENT) {
 
            /* Map the identifier to a token */
-           unsigned AttrTok;
+           cfgtok_t AttrTok;
            CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
            AttrTok = CfgTok;
 
@@ -477,7 +562,7 @@ static void ParseFiles (void)
        while (CfgTok == CFGTOK_IDENT) {
 
            /* Map the identifier to a token */
-           unsigned AttrTok;
+           cfgtok_t AttrTok;
            CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
            AttrTok = CfgTok;
 
@@ -528,63 +613,6 @@ static void ParseFiles (void)
 
 
 
-static Memory* CfgFindMemory (const char* Name)
-/* Find the memory are with the given name. Return NULL if not found */
-{
-    Memory* M = MemoryList;
-    while (M) {
-               if (strcmp (M->Name, Name) == 0) {
-                   return M;
-               }
-               M = M->Next;
-    }
-    return 0;
-}
-
-
-
-static Memory* CfgGetMemory (const char* Name)
-/* Find the memory are with the given name. Print an error on an invalid name */
-{
-    Memory* M = CfgFindMemory (Name);
-    if (M == 0) {
-       CfgError ("Invalid memory area `%s'", Name);
-    }
-    return M;
-}
-
-
-
-static void SegDescInsert (SegDesc* S)
-/* Insert a segment descriptor into the list of segment descriptors */
-{
-    /* Insert the struct into the list */
-    S->Next = SegDescList;
-    SegDescList = S;
-    ++SegDescCount;
-}
-
-
-
-static void MemoryInsert (Memory* M, SegDesc* S)
-/* Insert the segment descriptor into the memory area list */
-{
-    /* Create a new node for the entry */
-    MemListNode* N = xmalloc (sizeof (MemListNode));
-    N->Seg  = S;
-    N->Next = 0;
-
-    if (M->SegLast == 0) {
-               /* First entry */
-               M->SegList = N;
-    } else {
-       M->SegLast->Next = N;
-    }
-    M->SegLast = N;
-}
-
-
-
 static void ParseSegments (void)
 /* Parse a SEGMENTS section */
 {
@@ -623,7 +651,7 @@ static void ParseSegments (void)
        while (CfgTok == CFGTOK_IDENT) {
 
            /* Map the identifier to a token */
-           unsigned AttrTok;
+           cfgtok_t AttrTok;
            CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
            AttrTok = CfgTok;
 
@@ -649,9 +677,11 @@ static void ParseSegments (void)
                            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;
 
@@ -788,7 +818,7 @@ static void ParseO65 (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        /* Map the identifier to a token */
-       unsigned AttrTok;
+       cfgtok_t AttrTok;
                CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
        AttrTok = CfgTok;
 
@@ -843,7 +873,7 @@ static void ParseO65 (void)
                        break;
 
                    default:
-                       Error ("Unexpected type token");
+                       CfgError ("Unexpected type token");
                }
                break;
 
@@ -863,7 +893,7 @@ static void ParseO65 (void)
                        break;
 
                    default:
-                       Error ("Unexpected OS token");
+                       CfgError ("Unexpected OS token");
                }
                break;
 
@@ -892,7 +922,7 @@ static void ParseFormats (void)
     while (CfgTok == CFGTOK_IDENT) {
 
        /* Map the identifier to a token */
-       unsigned FormatTok;
+       cfgtok_t FormatTok;
                CfgSpecialToken (Formats, ENTRY_COUNT (Formats), "Format");
        FormatTok = CfgTok;
 
@@ -922,16 +952,165 @@ static void ParseFormats (void)
 
 
 
+static void ParseConDes (void)
+/* Parse the CONDES feature */
+{
+    static const IdentTok Attributes [] = {
+               {   "SEGMENT",          CFGTOK_SEGMENT          },
+       {   "LABEL",            CFGTOK_LABEL            },
+       {   "TYPE",             CFGTOK_TYPE             },
+    };
+
+    static const IdentTok Types [] = {
+               {   "CONSTRUCTOR",      CFGTOK_CONSTRUCTOR      },
+       {   "DESTRUCTOR",       CFGTOK_DESTRUCTOR       },
+    };
+
+    /* Attribute values. */
+    char SegName[sizeof (CfgSVal)];
+    char Label[sizeof (CfgSVal)];
+    int Type = -1;     /* Initialize to avoid gcc warnings */
+
+    /* Bitmask to remember the attributes we got already */
+    enum {
+       atNone          = 0x0000,
+       atSegName       = 0x0001,
+       atLabel         = 0x0002,
+       atType          = 0x0004
+    };
+    unsigned AttrFlags = atNone;
+
+    /* Parse the attributes */
+    while (1) {
+
+       /* Map the identifier to a token */
+       cfgtok_t AttrTok;
+               CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
+       AttrTok = CfgTok;
+
+       /* An optional assignment follows */
+       CfgNextTok ();
+       CfgOptionalAssign ();
+
+       /* Check which attribute was given */
+       switch (AttrTok) {
+
+           case CFGTOK_SEGMENT:
+               /* Don't allow this twice */
+               FlagAttr (&AttrFlags, atSegName, "SEGMENT");
+               /* We expect an identifier */
+               CfgAssureIdent ();
+               /* Remember the value for later */
+               strcpy (SegName, CfgSVal);
+               break;
+
+           case CFGTOK_LABEL:
+               /* Don't allow this twice */
+               FlagAttr (&AttrFlags, atLabel, "LABEL");
+               /* We expect an identifier */
+               CfgAssureIdent ();
+               /* Remember the value for later */
+               strcpy (Label, CfgSVal);
+               break;
+
+
+           case CFGTOK_TYPE:
+               /* Don't allow this twice */
+               FlagAttr (&AttrFlags, atType, "TYPE");
+               /* The type may be given as id or numerical */
+               if (CfgTok == CFGTOK_INTCON) {
+                   CfgRangeCheck (CD_TYPE_MIN, CD_TYPE_MAX);
+                   Type = (int) CfgIVal;
+               } else {
+                   CfgSpecialToken (Types, ENTRY_COUNT (Types), "Type");
+                   switch (CfgTok) {
+                       case CFGTOK_CONSTRUCTOR: Type = CD_TYPE_CON;    break;
+                       case CFGTOK_DESTRUCTOR:  Type = CD_TYPE_DES;    break;
+                       default: FAIL ("Unexpected type token");
+                   }
+               }
+               break;
+
+           default:
+               FAIL ("Unexpected attribute token");
+
+       }
+
+               /* Skip the attribute value */
+       CfgNextTok ();
+
+       /* Semicolon ends the ConDes decl, otherwise accept an optional comma */
+       if (CfgTok == CFGTOK_SEMI) {
+           break;
+       } else if (CfgTok == CFGTOK_COMMA) {
+           CfgNextTok ();
+       }
+    }
+
+    /* Check if we have all mandatory attributes */
+    AttrCheck (AttrFlags, atSegName, "SEGMENT");
+    AttrCheck (AttrFlags, atLabel, "LABEL");
+    AttrCheck (AttrFlags, atType, "TYPE");
+
+    /* Check if the condes has already attributes defined */
+    if (ConDesHasSegName(Type) || ConDesHasLabel(Type)) {
+       CfgError ("CONDES attributes for type %d are already defined", Type);
+    }
+
+    /* Define the attributes */
+    ConDesSetSegName (Type, SegName);
+    ConDesSetLabel (Type, Label);
+}
+
+
+
+static void ParseFeatures (void)
+/* Parse a features section */
+{
+    static const IdentTok Features [] = {
+               {   "CONDES",   CFGTOK_CONDES   },
+    };
+
+    while (CfgTok == CFGTOK_IDENT) {
+
+       /* Map the identifier to a token */
+       cfgtok_t FeatureTok;
+               CfgSpecialToken (Features, ENTRY_COUNT (Features), "Feature");
+               FeatureTok = CfgTok;
+
+       /* Skip the name and the following colon */
+       CfgNextTok ();
+       CfgConsumeColon ();
+
+       /* Parse the format options */
+       switch (FeatureTok) {
+
+           case CFGTOK_CONDES:
+               ParseConDes ();
+               break;
+
+           default:
+               Error ("Unexpected feature token");
+       }
+
+       /* Skip the semicolon */
+       CfgConsumeSemi ();
+    }
+}
+
+
+
 static void ParseConfig (void)
 /* Parse the config file */
 {
     static const IdentTok BlockNames [] = {
-       {   "MEMORY",   CFGTOK_MEMORY    },
-       {   "FILES",    CFGTOK_FILES     },
-        {   "SEGMENTS", CFGTOK_SEGMENTS  },
-       {   "FORMATS",  CFGTOK_FORMATS   },
+       {   "MEMORY",   CFGTOK_MEMORY   },
+       {   "FILES",    CFGTOK_FILES    },
+        {   "SEGMENTS", CFGTOK_SEGMENTS },
+       {   "FORMATS",  CFGTOK_FORMATS  },
+       {   "FEATURES", CFGTOK_FEATURES },
     };
-    unsigned BlockTok;
+    cfgtok_t BlockTok;
 
     do {
 
@@ -947,23 +1126,27 @@ static void ParseConfig (void)
        switch (BlockTok) {
 
            case CFGTOK_MEMORY:
-               ParseMemory ();
-               break;
+               ParseMemory ();
+               break;
 
            case CFGTOK_FILES:
-               ParseFiles ();
-               break;
+               ParseFiles ();
+               break;
 
            case CFGTOK_SEGMENTS:
-               ParseSegments ();
-               break;
+               ParseSegments ();
+               break;
 
            case CFGTOK_FORMATS:
-               ParseFormats ();
+               ParseFormats ();
+               break;
+
+           case CFGTOK_FEATURES:
+               ParseFeatures ();
                break;
 
            default:
-               FAIL ("Unexpected block token");
+               FAIL ("Unexpected block token");
 
        }
 
index ae72b280f6893d1e9264e2e881d6c6d6a565ce9e..515b8527d3c6e8ed5a8d8ae2c5ee364fb7ac6300 100644 (file)
 #include "xmalloc.h"
 
 /* ld65 */
-#include "global.h"
+#include "condes.h"
 #include "error.h"
 #include "fileio.h"
-#include "initfunc.h"
+#include "global.h"
 #include "objdata.h"
 #include "expr.h"
 #include "exports.h"
@@ -202,17 +202,18 @@ static Export* NewExport (unsigned char Type, const char* Name, ObjData* Obj)
 
     /* Initialize the fields */
     E->Next     = 0;
-    E->Flags   = 0;
+    E->Flags           = 0;
     E->Obj      = Obj;
     E->ImpCount = 0;
     E->ImpList  = 0;
     E->Expr            = 0;
     E->Type            = Type;
+    memset (E->ConDes, 0, sizeof (E->ConDes));
     if (Name) {
         E->Name = xstrdup (Name);
     } else {
-       /* Name will get added later */
-       E->Name = 0;
+               /* Name will get added later */
+               E->Name = 0;
     }
 
     /* Return the new entry */
@@ -229,9 +230,9 @@ void InsertExport (Export* E)
     Import* Imp;
     unsigned HashVal;
 
-    /* If this is an initializer, insert it into the initializer list */
-    if (IS_EXP_INIT (E->Type)) {
-       AddInitFunc (E);
+    /* Insert the export into any condes tables if needed */
+    if (IS_EXP_CONDES (E->Type)) {
+               ConDesAddExport (E);
     }
 
     /* Create a hash value for the given name */
@@ -272,7 +273,7 @@ void InsertExport (Export* E)
                    }
                } else {
                    /* Duplicate entry, ignore it */
-                   Warning ("Duplicate external identifier: `%s'", L->Name);
+                           Warning ("Duplicate external identifier: `%s'", L->Name);
                }
                return;
            }
@@ -293,6 +294,7 @@ Export* ReadExport (FILE* F, ObjData* O)
 /* Read an export from a file */
 {
     unsigned char Type;
+    unsigned      ConDesCount;
     Export* E;
 
     /* Read the type */
@@ -301,6 +303,29 @@ Export* ReadExport (FILE* F, ObjData* O)
     /* Create a new export without a name */
     E = NewExport (Type, 0, O);
 
+    /* Read the constructor/destructor decls if we have any */
+    ConDesCount = GET_EXP_CONDES_COUNT (Type);
+    if (ConDesCount > 0) {
+
+       unsigned char ConDes[CD_TYPE_COUNT];
+       unsigned I;
+
+       /* Read the data into temp storage */
+       ReadData (F, ConDes, ConDesCount);
+
+       /* Re-order the data. In the file, each decl is encoded into a byte
+        * which contains the type and the priority. In memory, we will use
+        * an array of types which contain the priority. This array was
+        * cleared by the constructor (NewExport), so we must only set the
+        * fields that contain values.
+        */
+       for (I = 0; I < ConDesCount; ++I) {
+           unsigned ConDesType = CD_GET_TYPE (ConDes[I]);
+           unsigned ConDesPrio = CD_GET_PRIO (ConDes[I]);
+           E->ConDes[ConDesType] = ConDesPrio;
+       }
+    }
+
     /* Read the name */
     E->Name = ReadStr (F);
 
@@ -562,7 +587,7 @@ void PrintExportMap (FILE* F)
                     GetExportVal (E),
                     E->ImpCount? 'R' : ' ',
                     IS_EXP_ZP (E->Type)? 'Z' : ' ',
-                    IS_EXP_INIT (E->Type)? 'I' : ' ');
+                    IS_EXP_CONDES (E->Type)? 'I' : ' ');
            if (++Count == 2) {
                Count = 0;
                fprintf (F, "\n");
index df35676109032d69d7102df58c24779e7914d506..8ee675f0c00758d85a091099b02d6c47c429923a 100644 (file)
@@ -41,6 +41,7 @@
 #include <stdio.h>
 
 /* common */
+#include "cddefs.h"
 #include "exprdefs.h"
 #include "filepos.h"
 
@@ -81,7 +82,8 @@ struct Export {
     Import*            ImpList;        /* List of imports for this symbol */
     FilePos            Pos;            /* File position of definition */
     ExprNode*                  Expr;           /* Expression (0 if not def'd) */
-    unsigned char      Type;           /* Type of export */
+    unsigned char      Type;           /* Type of export */              
+    unsigned char      ConDes[CD_TYPE_COUNT];  /* Constructor/destructor decls */
     char*                      Name;           /* Name - dynamically allocated */
 };
 
@@ -157,7 +159,7 @@ void CircularRefError (const Export* E);
 /* Print an error about a circular reference using to define the given export */
 
 
-            
+
 /* End of exports.h */
 
 #endif
index c13a202f264f18f56105d443f5e4c56a99454339..4998fe3ed572ced030c8f73950abaacac51e1d48 100644 (file)
@@ -284,9 +284,12 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 
 void* ReadData (FILE* F, void* Data, unsigned Size)
 /* Read data from the file */
-{
-    if (fread (Data, 1, Size, F) != Size) {
-       Error ("Read error (file corrupt?)");
+{     
+    /* Explicitly allow reading zero bytes */
+    if (Size > 0) {
+       if (fread (Data, 1, Size, F) != Size) {
+           Error ("Read error (file corrupt?)");
+       }
     }
     return Data;
 }
diff --git a/src/ld65/initfunc.c b/src/ld65/initfunc.c
deleted file mode 100644 (file)
index 60ea528..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                               initfunc.c                                 */
-/*                                                                           */
-/*                     Init/cleanup function handling                       */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
-/*                                                                           */
-/*                                                                           */
-/* 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.                                                          */
-/*                                                                           */
-/*****************************************************************************/
-
-
-
-/* common */
-#include "coll.h"
-
-/* ld65 */
-#include "exports.h"
-#include "segments.h"
-#include "initfunc.h"
-
-
-
-/*****************************************************************************/
-/*                                  Data                                    */
-/*****************************************************************************/
-
-
-
-/* List of all exports that are also initializers/cleanup functions */
-static Collection   InitFunctions      = STATIC_COLLECTION_INITIALIZER;
-static Collection   CleanupFunctions   = STATIC_COLLECTION_INITIALIZER;
-
-
-
-/*****************************************************************************/
-/*                                          Code                                    */
-/*****************************************************************************/
-
-
-
-void AddInitFunc (Export* E)
-/* Add the given export to the list of initializers */
-{
-    CollAppend (&InitFunctions, E);
-}
-
-
-
-void AddCleanupFunc (Export* E)
-/* Add the given export to the list of cleanup functions */
-{
-    CollAppend (&CleanupFunctions, E);
-}
-
-
-
diff --git a/src/ld65/initfunc.h b/src/ld65/initfunc.h
deleted file mode 100644 (file)
index fef48e1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*****************************************************************************/
-/*                                                                           */
-/*                               initfunc.h                                 */
-/*                                                                           */
-/*                     Init/cleanup function handling                       */
-/*                                                                           */
-/*                                                                           */
-/*                                                                           */
-/* (C) 2000      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
-/*                                                                           */
-/*                                                                           */
-/* 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 INITFUNC_H
-#define INITFUNC_H
-
-
-
-/*****************************************************************************/
-/*                                Forwards                                  */
-/*****************************************************************************/
-
-
-
-struct Export;
-
-
-
-/*****************************************************************************/
-/*                                          Code                                    */
-/*****************************************************************************/
-
-
-
-void AddInitFunc (struct Export* E);
-/* Add the given export to the list of initializers */
-
-void AddCleanupFunc (struct Export* E);
-/* Add the given export to the list of cleanup functions */
-
-
-
-/* End of initfunc.h */
-
-#endif
-
-
-
-
index 63ab842a493f7bff7e50dba80fcee314f00dd085..415c39ab6147f079a148c73aae02755870637059 100644 (file)
@@ -48,6 +48,7 @@
 
 /* ld65 */
 #include "binfmt.h"
+#include "condes.h"
 #include "config.h"
 #include "error.h"
 #include "exports.h"
@@ -404,6 +405,9 @@ int main (int argc, char* argv [])
     /* Read the config file */
     CfgRead ();
 
+    /* Create the condes tables if requested */
+    ConDesCreate ();
+
     /* Assign start addresses for the segments, define linker symbols */
     CfgAssignSegments ();
 
@@ -424,6 +428,7 @@ int main (int argc, char* argv [])
     /* Dump the data for debugging */
     if (Verbose > 1) {
        SegDump ();
+       ConDesDump ();
     }
 
     /* Return an apropriate exit code */
index abe8edf49598ff83eda82214f6e973dd388ad52a..1b4affcc840b200db559cc7a74769026b1218011 100644 (file)
@@ -19,6 +19,7 @@ CVT=cfg/cvt-cfg.pl
 
 OBJS =         bin.o           \
        binfmt.o        \
+       condes.o        \
        config.o        \
        dbgsyms.o       \
        error.o         \
@@ -28,7 +29,6 @@ OBJS =        bin.o           \
        fileio.o        \
        fragment.o      \
        global.o        \
-       initfunc.o      \
        library.o       \
        main.o          \
        mapfile.o       \
index 56870f11e5abd0e237a701a1d3ce0bcac4860a93..7b0770016335d41fdc77c3ad0880ed7e07327ff1 100644 (file)
@@ -56,7 +56,7 @@
 
 
 /* Current token and attributes */
-unsigned        CfgTok;
+cfgtok_t       CfgTok;
 char                   CfgSVal [CFG_MAX_IDENT_LEN+1];
 unsigned long   CfgIVal;
 
@@ -322,7 +322,7 @@ Again:
 
 
 
-void CfgConsume (unsigned T, const char* Msg)
+void CfgConsume (cfgtok_t T, const char* Msg)
 /* Skip a token, print an error message if not found */
 {
     if (CfgTok != T) {
@@ -535,3 +535,4 @@ void CfgCloseInput (void)
 
 
 
+                         
index 02d53497804739beeb0a4b037aa411195812d3e5..d5f86e3ec4024723ee862493348874327d9f585d 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 1998-2000 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /* Config file tokens */
-#define        CFGTOK_NONE             0
-#define CFGTOK_INTCON          1
-#define CFGTOK_STRCON          2
-#define CFGTOK_IDENT           3
-#define CFGTOK_LCURLY          4
-#define CFGTOK_RCURLY          5
-#define CFGTOK_SEMI            6
-#define CFGTOK_COMMA           7
-#define CFGTOK_EQ              8
-#define CFGTOK_COLON           9
-#define CFGTOK_DOT             10
-#define CFGTOK_EOF             11
-
-/* Special identifiers */
-#define CFGTOK_MEMORY                  20
-#define CFGTOK_FILES           21
-#define CFGTOK_SEGMENTS        22
-#define CFGTOK_FORMATS         23
-
-#define CFGTOK_START           30
-#define CFGTOK_SIZE            31
-#define CFGTOK_TYPE            32
-#define CFGTOK_FILE            33
-#define CFGTOK_DEFINE          34
-#define CFGTOK_FILL            35
-#define CFGTOK_FILLVAL         36
-#define CFGTOK_EXPORT          37
-#define CFGTOK_IMPORT          38
-#define CFGTOK_OS                      39
-#define CFGTOK_FORMAT          40
-
-#define CFGTOK_LOAD            50
-#define CFGTOK_RUN                     51
-#define CFGTOK_ALIGN                   52
-#define CFGTOK_OFFSET                  53
-
-#define CFGTOK_RO                      60
-#define CFGTOK_RW                      61
-#define CFGTOK_BSS                     62
-#define CFGTOK_ZP              63
-#define CFGTOK_WPROT           64
-
-#define CFGTOK_O65                     70
-#define CFGTOK_BIN                     71
-
-#define CFGTOK_SMALL           80
-#define CFGTOK_LARGE           81
-
-#define CFGTOK_TRUE            90
-#define CFGTOK_FALSE           91
-
-#define CFGTOK_LUNIX           100
-#define CFGTOK_OSA65           101
+typedef enum {
+    CFGTOK_NONE,
+    CFGTOK_INTCON,
+    CFGTOK_STRCON,
+    CFGTOK_IDENT,
+    CFGTOK_LCURLY,
+    CFGTOK_RCURLY,
+    CFGTOK_SEMI,
+    CFGTOK_COMMA,
+    CFGTOK_EQ,
+    CFGTOK_COLON,
+    CFGTOK_DOT,
+    CFGTOK_EOF,
+
+    /* Special identifiers */
+    CFGTOK_MEMORY,
+    CFGTOK_FILES,
+    CFGTOK_SEGMENTS,
+    CFGTOK_FORMATS,
+    CFGTOK_FEATURES,
+
+    CFGTOK_START,
+    CFGTOK_SIZE,
+    CFGTOK_TYPE,
+    CFGTOK_FILE,
+    CFGTOK_DEFINE,
+    CFGTOK_FILL,
+    CFGTOK_FILLVAL,
+    CFGTOK_EXPORT,
+    CFGTOK_IMPORT,
+    CFGTOK_OS,
+    CFGTOK_FORMAT,
+
+    CFGTOK_LOAD,
+    CFGTOK_RUN,
+    CFGTOK_ALIGN,
+    CFGTOK_OFFSET,
+
+    CFGTOK_RO,
+    CFGTOK_RW,
+    CFGTOK_BSS,
+    CFGTOK_ZP,
+    CFGTOK_WPROT,
+
+    CFGTOK_O65,
+    CFGTOK_BIN,
+
+    CFGTOK_SMALL,
+    CFGTOK_LARGE,
+
+    CFGTOK_TRUE,
+    CFGTOK_FALSE,
+
+    CFGTOK_LUNIX,
+    CFGTOK_OSA65,
+
+    CFGTOK_CONDES,
+    CFGTOK_SEGMENT,
+    CFGTOK_LABEL,
+    CFGTOK_CONSTRUCTOR,
+    CFGTOK_DESTRUCTOR
+
+} cfgtok_t;
 
 
 
 /* Mapping table entry, special identifier --> token */
 typedef struct IdentTok_ IdentTok;
 struct IdentTok_ {
-    const char*                Ident;          /* Identifier */
-    unsigned           Tok;            /* Token for identifier */
+    const char*        Ident;          /* Identifier */
+    cfgtok_t   Tok;            /* Token for identifier */
 };
 #define ENTRY_COUNT(s)         (sizeof (s) / sizeof (s [0]))
 
@@ -113,7 +123,7 @@ struct IdentTok_ {
 
 /* Current token and attributes */
 #define CFG_MAX_IDENT_LEN  255
-extern unsigned                CfgTok;
+extern cfgtok_t                CfgTok;
 extern char                    CfgSVal [CFG_MAX_IDENT_LEN+1];
 extern unsigned long   CfgIVal;
 
@@ -138,7 +148,7 @@ void CfgError (const char* Format, ...) attribute((format(printf,1,2)));
 void CfgNextTok (void);
 /* Read the next token from the input stream */
 
-void CfgConsume (unsigned T, const char* Msg);
+void CfgConsume (cfgtok_t T, const char* Msg);
 /* Skip a token, print an error message if not found */
 
 void CfgConsumeSemi (void);
@@ -196,4 +206,4 @@ void CfgCloseInput (void);
 
 
 
-                                      
+
index f5b880bdad90d708cf97e886df25e51b4af82f09..d44e12efd9d7c4a96b436d84d2cbd64db5de8e8f 100644 (file)
@@ -37,6 +37,7 @@
 #include <time.h>
 
 /* common */
+#include "cddefs.h"
 #include "exprdefs.h"
 #include "filepos.h"
 #include "objdefs.h"
@@ -196,24 +197,42 @@ static unsigned SkipFragment (FILE* F)
 
 
 
-static const char* GetExportFlags (unsigned Flags)
+static const char* GetExportFlags (unsigned Flags, const unsigned char* ConDes)
 /* Get the export flags as a (static) string */
 {
     /* Static buffer */
-    static char TypeDesc[128];
+    static char TypeDesc[256];
+    static char* T;
 
-    /* Get the flags */
+    unsigned Count;
+    unsigned I;
+
+    /* Adressing mode */
     TypeDesc[0] = '\0';
     switch (Flags & EXP_MASK_SIZE) {
-       case EXP_ABS:   strcat (TypeDesc, "EXP_ABS");           break;
-       case EXP_ZP:    strcat (TypeDesc, "EXP_ZP");            break;
+               case EXP_ABS:   strcat (TypeDesc, "EXP_ABS");           break;
+               case EXP_ZP:    strcat (TypeDesc, "EXP_ZP");            break;
     }
+
+    /* Type of expression */
     switch (Flags & EXP_MASK_VAL) {
-       case EXP_CONST: strcat (TypeDesc, ",EXP_CONST");        break;
-       case EXP_EXPR:  strcat (TypeDesc, ",EXP_EXPR");         break;
+               case EXP_CONST: strcat (TypeDesc, ",EXP_CONST");        break;
+               case EXP_EXPR:  strcat (TypeDesc, ",EXP_EXPR");         break;
     }
-    if (IS_EXP_INIT (Flags)) {
-       sprintf (TypeDesc+strlen(TypeDesc), ",EXP_INIT=%u", GET_EXP_INIT_VAL(Flags));
+
+    /* Constructor/destructor declarations */
+    T = TypeDesc + strlen (TypeDesc);
+    Count = GET_EXP_CONDES_COUNT (Flags);
+    if (Count > 0) {
+       T += sprintf (T, ",EXP_CONDES=");
+       for (I = 0; I < Count; ++I) {
+           unsigned Type = CD_GET_TYPE (ConDes[I]);
+           unsigned Prio = CD_GET_PRIO (ConDes[I]);
+           if (I > 0) {
+               *T++ = ',';
+           }
+                   T += sprintf (T, "[%u,%u]", Type, Prio);
+       }
     }
 
     /* Return the result */
@@ -537,10 +556,10 @@ void DumpObjImports (FILE* F, unsigned long Offset)
 void DumpObjExports (FILE* F, unsigned long Offset)
 /* Dump the exports in the object file */
 {
-    ObjHeader H;
-    unsigned  Count;
-    unsigned  I;
-    FilePos   Pos;
+    ObjHeader    H;
+    unsigned     Count;
+    unsigned     I;
+    FilePos      Pos;
 
     /* Seek to the header position */
     FileSeek (F, Offset);
@@ -563,12 +582,18 @@ void DumpObjExports (FILE* F, unsigned long Offset)
 
        unsigned long   Value = 0;
        int             HaveValue;
+       unsigned char   Type;
+       unsigned char   ConDes [CD_TYPE_COUNT];
+       char*           Name;
+       unsigned        Len;
+
 
                /* Read the data for one export */
-               unsigned char Type  = Read8 (F);
-       char*         Name  = ReadStr (F);
-       unsigned      Len   = strlen (Name);
-       if (Type & EXP_EXPR) {
+               Type  = Read8 (F);
+       ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
+       Name  = ReadStr (F);
+       Len   = strlen (Name);
+               if (IS_EXP_EXPR (Type)) {
            SkipExpr (F);
            HaveValue = 0;
        } else {
@@ -581,7 +606,7 @@ void DumpObjExports (FILE* F, unsigned long Offset)
        printf ("    Index:%27u\n", I);
 
        /* Print the data */
-               printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type));
+               printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, ConDes));
        printf ("      Name:%*s\"%s\"\n", 24-Len, "", Name);
        if (HaveValue) {
            printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
@@ -630,12 +655,17 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
 
        unsigned long   Value = 0;
        int             HaveValue;
+       unsigned char   Type;
+       unsigned char   ConDes [CD_TYPE_COUNT];
+       char*           Name;
+       unsigned        Len;
 
                /* Read the data for one symbol */
-               unsigned char Type  = Read8 (F);
-       char*         Name  = ReadStr (F);
-       unsigned      Len   = strlen (Name);
-       if (Type & EXP_EXPR) {
+               Type  = Read8 (F);
+       ReadData (F, ConDes, GET_EXP_CONDES_COUNT (Type));
+       Name  = ReadStr (F);
+       Len   = strlen (Name);
+       if (IS_EXP_EXPR (Type)) {
            SkipExpr (F);
            HaveValue = 0;
        } else {
@@ -648,7 +678,7 @@ void DumpObjDbgSyms (FILE* F, unsigned long Offset)
        printf ("    Index:%27u\n", I);
 
        /* Print the data */
-               printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type));
+               printf ("      Type:%22s0x%02X  (%s)\n", "", Type, GetExportFlags (Type, ConDes));
        printf ("      Name:%*s\"%s\"\n", 24-Len, "", Name);
        if (HaveValue) {
            printf ("      Value:%15s0x%08lX  (%lu)\n", "", Value, Value);
index f700f3186b9e0a77e97e6fd4e419313f64432d1d..1950400e080694c1679ce19ed97241167b76e23e 100644 (file)
@@ -179,8 +179,11 @@ FilePos* ReadFilePos (FILE* F, FilePos* Pos)
 void* ReadData (FILE* F, void* Data, unsigned Size)
 /* Read data from the file */
 {
-    if (fread (Data, 1, Size, F) != Size) {
-       Error ("Read error (file corrupt?)");
+    /* Accept zero sized reads */
+    if (Size > 0) {
+       if (fread (Data, 1, Size, F) != Size) {
+           Error ("Read error (file corrupt?)");
+       }          
     }
     return Data;
 }