Merge duplicate file entries (same name, size and timestamp).
git-svn-id: svn://svn.cc65.org/cc65/trunk@5061 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2003-2010, Ullrich von Bassewitz */
|
/* (C) 2003-2011, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
|||||||
@@ -58,10 +58,13 @@ void PrintDbgInfo (ObjData* O, FILE* F)
|
|||||||
|
|
||||||
/* Output the files section */
|
/* Output the files section */
|
||||||
for (I = 0; I < CollCount (&O->Files); ++I) {
|
for (I = 0; I < CollCount (&O->Files); ++I) {
|
||||||
const FileInfo* FI = CollConstAt (&O->Files, I);
|
FileInfo* FI = CollAt (&O->Files, I);
|
||||||
fprintf (F,
|
if (!FI->Dumped) {
|
||||||
"file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n",
|
fprintf (F,
|
||||||
FI->Id, GetString (FI->Name), FI->Size, FI->MTime);
|
"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 */
|
/* Output the line infos */
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "coll.h"
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
|
||||||
/* ld65 */
|
/* ld65 */
|
||||||
@@ -42,12 +43,63 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* A list of all file infos without duplicates */
|
||||||
|
static Collection FileInfos = STATIC_COLLECTION_INITIALIZER;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Code */
|
/* 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)
|
static FileInfo* NewFileInfo (void)
|
||||||
/* Allocate and initialize a new FileInfo struct and return it */
|
/* Allocate and initialize a new FileInfo struct and return it */
|
||||||
{
|
{
|
||||||
@@ -58,7 +110,8 @@ static FileInfo* NewFileInfo (void)
|
|||||||
FileInfo* FI = xmalloc (sizeof (FileInfo));
|
FileInfo* FI = xmalloc (sizeof (FileInfo));
|
||||||
|
|
||||||
/* Initialize stuff */
|
/* Initialize stuff */
|
||||||
FI->Id = Id++;
|
FI->Id = Id++;
|
||||||
|
FI->Dumped = 0;
|
||||||
|
|
||||||
/* Return the new struct */
|
/* Return the new struct */
|
||||||
return FI;
|
return FI;
|
||||||
@@ -69,13 +122,57 @@ static FileInfo* NewFileInfo (void)
|
|||||||
FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
FileInfo* ReadFileInfo (FILE* F, ObjData* O)
|
||||||
/* Read a file info from a file and return it */
|
/* Read a file info from a file and return it */
|
||||||
{
|
{
|
||||||
/* Allocate a new FileInfo structure */
|
FileInfo* FI;
|
||||||
FileInfo* FI = NewFileInfo ();
|
|
||||||
|
|
||||||
/* Read the fields from the file */
|
/* Read the fields from the file */
|
||||||
FI->Name = MakeGlobalStringId (O, ReadVar (F));
|
unsigned Name = MakeGlobalStringId (O, ReadVar (F));
|
||||||
FI->MTime = Read32 (F);
|
unsigned long MTime = Read32 (F);
|
||||||
FI->Size = ReadVar (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 the new struct */
|
||||||
return FI;
|
return FI;
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ struct FileInfo {
|
|||||||
unsigned long MTime; /* Time of last modification */
|
unsigned long MTime; /* Time of last modification */
|
||||||
unsigned long Size; /* Size of the file */
|
unsigned long Size; /* Size of the file */
|
||||||
unsigned Id; /* Id of file for debug info */
|
unsigned Id; /* Id of file for debug info */
|
||||||
|
unsigned Dumped; /* Flag: Dumped to debug info file */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user