From 82bab7fb89eb3dc6876a29c1da6ca12fd4dce47f Mon Sep 17 00:00:00 2001 From: uz Date: Tue, 14 Jun 2011 18:26:22 +0000 Subject: [PATCH] Merge duplicate file entries (same name, size and timestamp). git-svn-id: svn://svn.cc65.org/cc65/trunk@5061 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/ld65/dbgfile.c | 2 +- src/ld65/dbginfo.c | 11 +++-- src/ld65/fileinfo.c | 109 +++++++++++++++++++++++++++++++++++++++++--- src/ld65/fileinfo.h | 1 + 4 files changed, 112 insertions(+), 11 deletions(-) diff --git a/src/ld65/dbgfile.c b/src/ld65/dbgfile.c index 8cde4ab66..30d8bd1fd 100644 --- a/src/ld65/dbgfile.c +++ b/src/ld65/dbgfile.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 2003-2010, Ullrich von Bassewitz */ +/* (C) 2003-2011, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ diff --git a/src/ld65/dbginfo.c b/src/ld65/dbginfo.c index 2b81367cc..72363fe78 100644 --- a/src/ld65/dbginfo.c +++ b/src/ld65/dbginfo.c @@ -58,10 +58,13 @@ void PrintDbgInfo (ObjData* O, FILE* F) /* Output the files section */ for (I = 0; I < CollCount (&O->Files); ++I) { - const FileInfo* FI = CollConstAt (&O->Files, I); - fprintf (F, - "file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n", - FI->Id, GetString (FI->Name), FI->Size, FI->MTime); + FileInfo* FI = CollAt (&O->Files, I); + if (!FI->Dumped) { + fprintf (F, + "file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n", + FI->Id, GetString (FI->Name), FI->Size, FI->MTime); + FI->Dumped = 1; + } } /* Output the line infos */ diff --git a/src/ld65/fileinfo.c b/src/ld65/fileinfo.c index 5617b472b..7bf4e1d55 100644 --- a/src/ld65/fileinfo.c +++ b/src/ld65/fileinfo.c @@ -34,6 +34,7 @@ /* common */ +#include "coll.h" #include "xmalloc.h" /* ld65 */ @@ -42,12 +43,63 @@ +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +/* A list of all file infos without duplicates */ +static Collection FileInfos = STATIC_COLLECTION_INITIALIZER; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ +static int FindFileInfo (unsigned Name, unsigned* Index) +/* Find the FileInfo for a given file name. The function returns true if the + * name was found. In this case, Index contains the index of the first item + * that matches. If the item wasn't found, the function returns false and + * Index contains the insert position for FileName. + */ +{ + /* Do a binary search */ + int Lo = 0; + int Hi = (int) CollCount (&FileInfos) - 1; + int Found = 0; + while (Lo <= Hi) { + + /* Mid of range */ + int Cur = (Lo + Hi) / 2; + + /* Get item */ + FileInfo* CurItem = CollAt (&FileInfos, Cur); + + /* Found? */ + if (CurItem->Name < Name) { + Lo = Cur + 1; + } else { + Hi = Cur - 1; + /* Since we may have duplicates, repeat the search until we've + * the first item that has a match. + */ + if (CurItem->Name == Name) { + Found = 1; + } + } + } + + /* Pass back the index. This is also the insert position */ + *Index = Lo; + return Found; +} + + + static FileInfo* NewFileInfo (void) /* Allocate and initialize a new FileInfo struct and return it */ { @@ -58,7 +110,8 @@ static FileInfo* NewFileInfo (void) FileInfo* FI = xmalloc (sizeof (FileInfo)); /* Initialize stuff */ - FI->Id = Id++; + FI->Id = Id++; + FI->Dumped = 0; /* Return the new struct */ return FI; @@ -69,13 +122,57 @@ static FileInfo* NewFileInfo (void) FileInfo* ReadFileInfo (FILE* F, ObjData* O) /* Read a file info from a file and return it */ { - /* Allocate a new FileInfo structure */ - FileInfo* FI = NewFileInfo (); + FileInfo* FI; /* Read the fields from the file */ - FI->Name = MakeGlobalStringId (O, ReadVar (F)); - FI->MTime = Read32 (F); - FI->Size = ReadVar (F); + unsigned Name = MakeGlobalStringId (O, ReadVar (F)); + unsigned long MTime = Read32 (F); + unsigned long Size = ReadVar (F); + + /* Search for the first entry with this name */ + unsigned Index; + if (FindFileInfo (Name, &Index)) { + + /* We have at least one such entry. Try all of them and, if size and + * modification time matches, return the first match. When the loop + * is terminated without finding an entry, Index points one behind + * the last entry with the name, which is the perfect insert position. + */ + FI = CollAt (&FileInfos, Index); + while (1) { + + /* Check size and modification time stamp */ + if (FI->Size == Size && FI->MTime == MTime) { + /* Return this one */ + return FI; + } + + /* Check the next one */ + if (++Index >= CollCount (&FileInfos)) { + /* Nothing left */ + break; + } + FI = CollAt (&FileInfos, Index); + + /* Done if the name differs */ + if (FI->Name != Name) { + break; + } + } + } + + /* Not found. Allocate a new FileInfo structure */ + FI = NewFileInfo (); + + /* Set the fields */ + FI->Name = Name; + FI->MTime = MTime; + FI->Size = Size; + + /* Insert the file info in our global list. Index points to the insert + * position. + */ + CollInsert (&FileInfos, FI, Index); /* Return the new struct */ return FI; diff --git a/src/ld65/fileinfo.h b/src/ld65/fileinfo.h index 8ebee7972..1cd4fef92 100644 --- a/src/ld65/fileinfo.h +++ b/src/ld65/fileinfo.h @@ -61,6 +61,7 @@ struct FileInfo { unsigned long MTime; /* Time of last modification */ unsigned long Size; /* Size of the file */ unsigned Id; /* Id of file for debug info */ + unsigned Dumped; /* Flag: Dumped to debug info file */ };