]> git.sur5r.net Git - cc65/blobdiff - src/ar65/library.c
Deduct temporary library path name from library path name.
[cc65] / src / ar65 / library.c
index 9f194410924eabb7d25b536e697a9c472bd58a36..e68f23d3dac22b884102db279d35d703b4a81bee 100644 (file)
@@ -1,12 +1,12 @@
 /*****************************************************************************/
 /*                                                                           */
-/*                                library.c                                 */
+/*                                 library.c                                 */
 /*                                                                           */
-/*        Library data structures and helpers for the ar65 archiver         */
+/*         Library data structures and helpers for the ar65 archiver         */
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2013, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -38,9 +38,8 @@
 #include <errno.h>
 
 /* common */
-#include "bitops.h"
+#include "cmdline.h"
 #include "exprdefs.h"
-#include "filepos.h"
 #include "libdefs.h"
 #include "print.h"
 #include "symdefs.h"
 
 /* ar65 */
 #include "error.h"
-#include "global.h"
-#include "fileio.h"
-#include "objdata.h"
 #include "exports.h"
+#include "fileio.h"
+#include "global.h"
 #include "library.h"
+#include "objdata.h"
+#include "objfile.h"
 
 
 
 /*****************************************************************************/
-/*                                          Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
 
+/* Name of the library file */
+const char*             LibName = 0;
+static char*            NewLibName = 0;
+
 /* File descriptor for the library file */
-FILE*                  NewLib = 0;
-static FILE*           Lib = 0;
-static const char*     LibName = 0;
+static FILE*            Lib = 0;
+static FILE*            NewLib = 0;
 
 /* The library header */
-static LibHeader               Header = {
+static LibHeader        Header = {
     LIB_MAGIC,
     LIB_VERSION,
     0,
@@ -78,7 +81,7 @@ static LibHeader              Header = {
 
 
 /*****************************************************************************/
-/*                      Writing file data structures                        */
+/*                       Writing file data structures                        */
 /*****************************************************************************/
 
 
@@ -92,11 +95,11 @@ static void ReadHeader (void)
     /* Read the header fields, checking magic and version */
     Header.Magic   = Read32 (Lib);
     if (Header.Magic != LIB_MAGIC) {
-       Error ("`%s' is not a valid library file", LibName);
+        Error ("`%s' is not a valid library file", LibName);
     }
     Header.Version = Read16 (Lib);
     if (Header.Version != LIB_VERSION) {
-       Error ("Wrong data version in `%s'", LibName);
+        Error ("Wrong data version in `%s'", LibName);
     }
     Header.Flags   = Read16 (Lib);
     Header.IndexOffs = Read32 (Lib);
@@ -107,34 +110,15 @@ static void ReadHeader (void)
 static void ReadIndexEntry (void)
 /* Read one entry in the index */
 {
-    unsigned I;
-
     /* Create a new entry and insert it into the list */
-    ObjData* O         = NewObjData ();
+    ObjData* O  = NewObjData ();
 
     /* Module name/flags/MTime/Start/Size */
-    O->Name            = ReadStr (Lib);
-    O->Flags           = Read16 (Lib);
+    O->Name     = ReadStr (Lib);
+    O->Flags    = Read16 (Lib);
     O->MTime    = Read32 (Lib);
     O->Start    = Read32 (Lib);
     O->Size     = Read32 (Lib);
-
-    /* Strings */
-    O->StringCount = ReadVar (Lib);
-    O->Strings     = xmalloc (O->StringCount * sizeof (char*));
-    for (I = 0; I < O->StringCount; ++I) {
-        O->Strings[I] = ReadStr (Lib);
-    }
-
-    /* Imports */
-    O->ImportSize = ReadVar (Lib);
-    O->Imports    = xmalloc (O->ImportSize);
-    ReadData (Lib, O->Imports, O->ImportSize);
-
-    /* Exports */
-    O->ExportSize = ReadVar (Lib);
-    O->Exports    = xmalloc (O->ExportSize);
-    ReadData (Lib, O->Exports, O->ExportSize);
 }
 
 
@@ -142,7 +126,7 @@ static void ReadIndexEntry (void)
 static void ReadIndex (void)
 /* Read the index of a library file */
 {
-    unsigned Count;
+    unsigned Count, I;
 
     /* Seek to the start of the index */
     fseek (Lib, Header.IndexOffs, SEEK_SET);
@@ -152,14 +136,24 @@ static void ReadIndex (void)
 
     /* Read all entries in the index */
     while (Count--) {
-       ReadIndexEntry ();
+        ReadIndexEntry ();
+    }
+
+    /* Read basic object file data from the actual entries */
+    for (I = 0; I < CollCount (&ObjPool); ++I) {
+
+        /* Get the object file entry */
+        ObjData* O = CollAtUnchecked (&ObjPool, I);
+
+        /* Read data */
+        ObjReadData (Lib, O);
     }
 }
 
 
 
 /*****************************************************************************/
-/*                      Writing file data structures                        */
+/*                       Writing file data structures                        */
 /*****************************************************************************/
 
 
@@ -179,31 +173,15 @@ static void WriteHeader (void)
 
 
 
-static void WriteIndexEntry (ObjData* O)
+static void WriteIndexEntry (const ObjData* O)
 /* Write one index entry */
 {
-    unsigned I;
-
     /* Module name/flags/MTime/start/size */
     WriteStr (NewLib, O->Name);
     Write16  (NewLib, O->Flags & ~OBJ_HAVEDATA);
     Write32  (NewLib, O->MTime);
     Write32  (NewLib, O->Start);
     Write32  (NewLib, O->Size);
-
-    /* Strings */
-    WriteVar (NewLib, O->StringCount);
-    for (I = 0; I < O->StringCount; ++I) {
-        WriteStr (NewLib, O->Strings[I]);
-    }
-
-    /* Imports */
-    WriteVar (NewLib, O->ImportSize);
-    WriteData (NewLib, O->Imports, O->ImportSize);
-
-    /* Exports */
-    WriteVar (NewLib, O->ExportSize);
-    WriteData (NewLib, O->Exports, O->ExportSize);
 }
 
 
@@ -211,7 +189,7 @@ static void WriteIndexEntry (ObjData* O)
 static void WriteIndex (void)
 /* Write the index of a library file */
 {
-    ObjData* O;
+    unsigned I;
 
     /* Sync I/O in case the last operation was a read */
     fseek (NewLib, 0, SEEK_CUR);
@@ -220,20 +198,18 @@ static void WriteIndex (void)
     Header.IndexOffs = ftell (NewLib);
 
     /* Write the object file count */
-    WriteVar (NewLib, ObjCount);
+    WriteVar (NewLib, CollCount (&ObjPool));
 
     /* Write the object files */
-    O = ObjRoot;
-    while (O) {
-       WriteIndexEntry (O);
-               O = O->Next;
+    for (I = 0; I < CollCount (&ObjPool); ++I) {
+        WriteIndexEntry (CollConstAt (&ObjPool, I));
     }
 }
 
 
 
 /*****************************************************************************/
-/*                            High level stuff                              */
+/*                             High level stuff                              */
 /*****************************************************************************/
 
 
@@ -251,32 +227,40 @@ void LibOpen (const char* Name, int MustExist, int NeedTemp)
     Lib = fopen (Name, "rb");
     if (Lib == 0) {
 
-               /* File does not exist */
-               if (MustExist) {
-                   Error ("Library `%s' does not exist", Name);
-               } else {
-           Warning ("Library `%s' not found - will be created", Name);
-               }
+        /* File does not exist */
+        if (MustExist) {
+            Error ("Library `%s' does not exist", Name);
+        } else {
+            /* Announce the library's creation if ar65 is verbose. */
+            Print (stdout, 1,
+                   "%s: Library `%s' will be created.\n", ProgName, Name);
+        }
 
     } else {
 
         /* We have an existing file: Read the header */
-       ReadHeader ();
+        ReadHeader ();
 
-       /* Now read the existing index */
-               ReadIndex ();
+        /* Now read the existing index */
+        ReadIndex ();
 
     }
 
     if (NeedTemp) {
-       /* Create the temporary library */
-       NewLib = tmpfile ();
-       if (NewLib == 0) {
-           Error ("Cannot create temporary file: %s", strerror (errno));
-       }
-
-       /* Write a dummy header to the temp file */
-       WriteHeader ();
+
+        /* Create the temporary library name */
+        NewLibName = xmalloc (strlen (Name) + strlen (".temp") + 1);
+        strcpy (NewLibName, Name);
+        strcat (NewLibName, ".temp");
+
+        /* Create the temporary library */
+        NewLib = fopen (NewLibName, "w+b");
+        if (NewLib == 0) {
+            Error ("Cannot create temporary library file: %s", strerror (errno));
+        }
+
+        /* Write a dummy header to the temp file */
+        WriteHeader ();
     }
 }
 
@@ -294,10 +278,10 @@ unsigned long LibCopyTo (FILE* F, unsigned long Bytes)
 
     /* Copy loop */
     while (Bytes) {
-       unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
-       ReadData (F, Buf, Count);
-       WriteData (NewLib, Buf, Count);
-       Bytes -= Count;
+        unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
+        ReadData (F, Buf, Count);
+        WriteData (NewLib, Buf, Count);
+        Bytes -= Count;
     }
 
     /* Return the start position */
@@ -316,82 +300,10 @@ void LibCopyFrom (unsigned long Pos, unsigned long Bytes, FILE* F)
 
     /* Copy loop */
     while (Bytes) {
-       unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
-       ReadData (Lib, Buf, Count);
-       WriteData (F, Buf, Count);
-       Bytes -= Count;
-    }
-}
-
-
-
-static unsigned long GetVar (unsigned char** Buf)
-/* Get a variable sized value from Buf */
-{
-    unsigned char C;
-    unsigned long V = 0;
-    unsigned Shift = 0;
-    do {
-       /* Read one byte */
-               C = **Buf;
-       ++(*Buf);
-       /* Add this char to the value */
-       V |= ((unsigned long)(C & 0x7F)) << Shift;
-       /* Next value */
-       Shift += 7;
-    } while (C & 0x80);
-
-    /* Return the result */
-    return V;
-}
-
-
-
-static void SkipExpr (unsigned char** Buf)
-/* Skip an expression in Buf */
-{
-    /* Get the operation and skip it */
-    unsigned char Op = **Buf;
-    ++(*Buf);
-
-    /* Filter leaf nodes */
-    switch (Op) {
-
-       case EXPR_NULL:
-           return;
-
-        case EXPR_LITERAL:
-           /* 32 bit literal value */
-           *Buf += 4;
-           return;
-
-        case EXPR_SYMBOL:
-           /* Variable seized symbol index */
-           (void) GetVar (Buf);
-           return;
-
-        case EXPR_SECTION:
-           /* 8 bit segment number */
-           *Buf += 1;
-           return;
-    }
-
-    /* What's left are unary and binary nodes */
-    SkipExpr (Buf);                    /* Skip left */
-    SkipExpr (Buf);            /* Skip right */
-}
-
-
-
-static void SkipLineInfoList (unsigned char** Buf)
-/* Skip a list of line infos in Buf */
-{
-    /* Number of indices preceeds the list */
-    unsigned long Count = GetVar (Buf);
-
-    /* Skip indices */
-    while (Count--) {
-        (void) GetVar (Buf);
+        unsigned Count = (Bytes > sizeof (Buf))? sizeof (Buf) : Bytes;
+        ReadData (Lib, Buf, Count);
+        WriteData (F, Buf, Count);
+        Bytes -= Count;
     }
 }
 
@@ -402,43 +314,20 @@ static void LibCheckExports (ObjData* O)
  * checking for duplicates.
  */
 {
-    /* Get a pointer to the buffer */
-    unsigned char* Exports = O->Exports;
-
-    /* Get the export count */
-    unsigned Count = GetVar (&Exports);
-
-    /* Read the exports */
-    Print (stdout, 1, "Module `%s' (%u exports):\n", O->Name, Count);
-    while (Count--) {
-
-       const char*     Name;
-
-       /* Get the export tag and skip the address size */
-               unsigned Type = GetVar (&Exports);
-        ++Exports;
-
-       /* condes decls may follow */
-       Exports += SYM_GET_CONDES_COUNT (Type);
+    unsigned I;
 
-               /* Next thing is index of name of symbol */
-        Name = GetObjString (O, GetVar (&Exports));
+    /* Let the user know what we do */
+    Print (stdout, 2, "Module `%s' (%u exports):\n", O->Name, CollCount (&O->Exports));
 
-       /* Skip value of symbol */
-       if (SYM_IS_EXPR (Type)) {
-           /* Expression tree */
-           SkipExpr (&Exports);
-       } else {
-           /* Constant 32 bit value */
-           Exports += 4;
-       }
+    /* Insert the exports into the global table */
+    for (I = 0; I < CollCount (&O->Exports); ++I) {
 
-       /* Skip the line info */
-               SkipLineInfoList (&Exports);
+        /* Get the name of the export */
+        const char* Name = CollConstAt (&O->Exports, I);
 
-       /* Insert the name into the hash table */
-       Print (stdout, 1, "  %s\n", Name);
-       ExpInsert (Name, O->Index);
+        /* Insert the name into the hash table */
+        Print (stdout, 2, "  %s\n", Name);
+        ExpInsert (Name, O);
     }
 }
 
@@ -452,68 +341,68 @@ void LibClose (void)
     /* Do we have a temporary library? */
     if (NewLib) {
 
-       unsigned I;
-       unsigned char Buf [4096];
-       size_t Count;
-
-       /* Index the object files and make an array containing the objects */
-       MakeObjPool ();
+        unsigned I;
+        unsigned char Buf [4096];
+        size_t Count;
 
         /* Walk through the object file list, inserting exports into the
-        * export list checking for duplicates. Copy any data that is still
-        * in the old library into the new one.
-        */
-       for (I = 0; I < ObjCount; ++I) {
-
-           /* Get a pointer to the object */
-           ObjData* O = ObjPool [I];
-
-           /* Check exports, make global export table */
-           LibCheckExports (O);
-
-           /* Copy data if needed */
-           if ((O->Flags & OBJ_HAVEDATA) == 0) {
-               /* Data is still in the old library */
-               fseek (Lib, O->Start, SEEK_SET);
-               O->Start = ftell (NewLib);
-               LibCopyTo (Lib, O->Size);
-               O->Flags |= OBJ_HAVEDATA;
-           }
-       }
-
-       /* Write the index */
-       WriteIndex ();
-
-       /* Write the updated header */
-       WriteHeader ();
-
-       /* Close the file */
-       if (Lib && fclose (Lib) != 0) {
-           Error ("Error closing library: %s", strerror (errno));
-       }
-
-       /* Reopen the library and truncate it */
-       Lib = fopen (LibName, "wb");
-       if (Lib == 0) {
-           Error ("Cannot open library `%s' for writing: %s",
-                  LibName, strerror (errno));
-       }
-
-       /* Copy the new library to the new one */
-       fseek (NewLib, 0, SEEK_SET);
-       while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) {
-           if (fwrite (Buf, 1, Count, Lib) != Count) {
-               Error ("Cannot write to `%s': %s", LibName, strerror (errno));
-           }
-       }
+         * export list checking for duplicates. Copy any data that is still
+         * in the old library into the new one.
+         */
+        for (I = 0; I < CollCount (&ObjPool); ++I) {
+
+            /* Get a pointer to the object */
+            ObjData* O = CollAtUnchecked (&ObjPool, I);
+
+            /* Check exports, make global export table */
+            LibCheckExports (O);
+
+            /* Copy data if needed */
+            if ((O->Flags & OBJ_HAVEDATA) == 0) {
+                /* Data is still in the old library */
+                fseek (Lib, O->Start, SEEK_SET);
+                O->Start = ftell (NewLib);
+                LibCopyTo (Lib, O->Size);
+                O->Flags |= OBJ_HAVEDATA;
+            }
+        }
+
+        /* Write the index */
+        WriteIndex ();
+
+        /* Write the updated header */
+        WriteHeader ();
+
+        /* Close the file */
+        if (Lib && fclose (Lib) != 0) {
+            Error ("Error closing library: %s", strerror (errno));
+        }
+
+        /* Reopen the library and truncate it */
+        Lib = fopen (LibName, "wb");
+        if (Lib == 0) {
+            Error ("Cannot open library `%s' for writing: %s",
+                   LibName, strerror (errno));
+        }
+
+        /* Copy the temporary library to the new one */
+        fseek (NewLib, 0, SEEK_SET);
+        while ((Count = fread (Buf, 1, sizeof (Buf), NewLib)) != 0) {
+            if (fwrite (Buf, 1, Count, Lib) != Count) {
+                Error ("Cannot write to `%s': %s", LibName, strerror (errno));
+            }
+        }
     }
 
     /* Close both files */
     if (Lib && fclose (Lib) != 0) {
-       Error ("Problem closing `%s': %s", LibName, strerror (errno));
+        Error ("Problem closing `%s': %s", LibName, strerror (errno));
     }
     if (NewLib && fclose (NewLib) != 0) {
-       Error ("Problem closing temporary library file: %s", strerror (errno));
+        Error ("Problem closing temporary library file: %s", strerror (errno));
+    }
+    if (NewLibName && remove (NewLibName) != 0) {
+        Error ("Problem deleting temporary library file: %s", strerror (errno));
     }
 }