X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Ffiletab.c;h=4e1d28c448a663c1d4ebb37e90751f0f63febb41;hb=e67f4dcbd6a50c170d3e45da4fdcd08e4f6caeab;hp=5b31fff3dc8475bc7fcdadc6789cdf18bb5498b3;hpb=097a01094eedd3b030c2c7a26ddc2ac5067ead28;p=cc65 diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c index 5b31fff3d..4e1d28c44 100644 --- a/src/ca65/filetab.c +++ b/src/ca65/filetab.c @@ -33,8 +33,11 @@ +#include + /* common */ #include "check.h" +#include "hashstr.h" #include "xmalloc.h" /* ca65 */ @@ -50,13 +53,24 @@ -/* List of input files */ -static struct { - unsigned long MTime; /* Time of last modification */ - unsigned long Size; /* Size of file */ - const char* Name; /* Name of file */ -} Files [MAX_INPUT_FILES]; -static unsigned FileCount = 0; +/* An entry in the file table */ +typedef struct FileEntry FileEntry; +struct FileEntry { + FileEntry* Next; /* Next in hash list */ + unsigned Index; /* Index of entry */ + unsigned long Size; /* Size of file */ + unsigned long MTime; /* Time of last modification */ + char Name[1]; /* Name, dynamically allocated */ +}; + +/* Array of all entries, listed by index */ +static FileEntry** FileTab = 0; +static unsigned FileCount = 0; +static unsigned FileMax = 0; + +/* Hash table, hashed by name */ +#define HASHTAB_SIZE 31 +static FileEntry* HashTab[HASHTAB_SIZE]; @@ -66,6 +80,52 @@ static unsigned FileCount = 0; +static FileEntry* NewFileEntry (const char* Name, unsigned long Size, unsigned long MTime) +/* Create a new FileEntry, insert it into the tables and return it */ +{ + /* Get the length of the name */ + unsigned Len = strlen (Name); + + /* Get the hash over the name */ + unsigned Hash = HashStr (Name) % HASHTAB_SIZE; + + /* Allocate memory for the entry */ + FileEntry* F = xmalloc (sizeof (FileEntry) + Len); + + /* Initialize the fields */ + F->Index = FileCount+1; + F->Size = Size; + F->MTime = MTime; + memcpy (F->Name, Name, Len+1); + + /* Count the entries and grow the file table if needed */ + if (FileCount >= FileMax) { + /* We need to grow the table. Create a new one. */ + unsigned NewFileMax = (FileMax == 0)? 32 : FileMax * 2; + FileEntry** NewFileTab = xmalloc (sizeof (FileEntry*) * NewFileMax); + + /* Copy the old entries */ + memcpy (NewFileTab, FileTab, sizeof (FileEntry*) * FileCount); + + /* Use the new table */ + xfree (FileTab); + FileTab = NewFileTab; + FileMax = NewFileMax; + } + + /* Insert the file into the file table */ + FileTab [FileCount++] = F; + + /* Insert the entry into the hash table */ + F->Next = HashTab[Hash]; + HashTab[Hash] = F; + + /* Return the new entry */ + return F; +} + + + const char* GetFileName (unsigned Name) /* Get the name of a file where the name index is known */ { @@ -79,33 +139,50 @@ const char* GetFileName (unsigned Name) /* No files defined until now */ return "(outside file scope)"; } else { - return Files [0].Name; + return FileTab [0]->Name; } } else { - return Files [Name-1].Name; + return FileTab [Name-1]->Name; } } +unsigned GetFileIndex (const char* Name) +/* Return the file index for the given file name. */ +{ + /* Get the hash over the name */ + unsigned Hash = HashStr (Name) % HASHTAB_SIZE; + + /* Search the linear hash list */ + FileEntry* F = HashTab[Hash]; + while (F) { + /* Is it this one? */ + if (strcmp (Name, F->Name) == 0) { + /* Found, return the index */ + return F->Index; + } + /* No, check next */ + F = F->Next; + } + + /* Not found, use main file */ + Error (ERR_FILENAME_NOT_FOUND, Name); + return 0; +} + + + unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime) /* Add a new file to the list of input files. Return the index of the file in * the table. */ { - /* Check for a table overflow */ - if (FileCount >= MAX_INPUT_FILES) { - /* Table overflow */ - Fatal (FAT_MAX_INPUT_FILES); - } - - /* Add the file to the table */ - Files [FileCount].Name = xstrdup (Name); - Files [FileCount].Size = Size; - Files [FileCount].MTime = MTime; + /* Create a new file entry and insert it into the tables */ + FileEntry* F = NewFileEntry (Name, Size, MTime); - /* One more file */ - return ++FileCount; + /* Return the index */ + return F->Index; } @@ -123,9 +200,12 @@ void WriteFiles (void) /* Write the file data */ for (I = 0; I < FileCount; ++I) { - ObjWrite32 (Files [I].MTime); - ObjWrite32 (Files [I].Size); - ObjWriteStr (Files [I].Name); + /* Get a pointer to the entry */ + FileEntry* F = FileTab[I]; + /* Write the fields */ + ObjWrite32 (F->MTime); + ObjWrite32 (F->Size); + ObjWriteStr (F->Name); } /* Done writing files */