diff --git a/src/ca65/error.c b/src/ca65/error.c index 2337c668b..221a169f9 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -36,7 +36,7 @@ #include #include #include - + /* ca65 */ #include "filetab.h" #include "nexttok.h" @@ -186,6 +186,7 @@ void ErrorMsg (const FilePos* Pos, unsigned ErrNum, va_list ap) "Counter underflow", "Undefined label", "Open `%sī", + "File name `%s' not found in file table", }; fprintf (stderr, "%s(%lu): Error #%u: ", diff --git a/src/ca65/error.h b/src/ca65/error.h index f3ebceb7b..3f377db6c 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -38,7 +38,8 @@ -#include "scanner.h" +/* common */ +#include "filepos.h" @@ -126,6 +127,7 @@ enum Errors { ERR_COUNTER_UNDERFLOW, ERR_UNDEFINED_LABEL, ERR_OPEN_STMT, + ERR_FILENAME_NOT_FOUND, ERR_COUNT /* Error count */ }; diff --git a/src/ca65/filetab.c b/src/ca65/filetab.c index 5b31fff3d..8448d44df 100644 --- a/src/ca65/filetab.c +++ b/src/ca65/filetab.c @@ -35,6 +35,7 @@ /* common */ #include "check.h" +#include "hashstr.h" #include "xmalloc.h" /* ca65 */ @@ -50,13 +51,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 +78,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 +137,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); - } + /* Create a new file entry and insert it into the tables */ + FileEntry* F = NewFileEntry (Name, Size, MTime); - /* Add the file to the table */ - Files [FileCount].Name = xstrdup (Name); - Files [FileCount].Size = Size; - Files [FileCount].MTime = MTime; - - /* One more file */ - return ++FileCount; + /* Return the index */ + return F->Index; } @@ -123,9 +198,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 */ diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 23ce5d121..12d9a4745 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -46,6 +46,7 @@ #include "error.h" #include "expr.h" #include "objfile.h" +#include "scanner.h" #include "symtab.h" @@ -978,7 +979,7 @@ void WriteImports (void) /* Write the imports list to the object file */ { SymEntry* S; - + /* Tell the object file module that we're about to start the imports */ ObjStartImports (); diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index 1d29ec8dd..9176bc702 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -40,8 +40,10 @@ #include -#include "../common/exprdefs.h" - +/* common */ +#include "exprdefs.h" + +/* ca65 */ #include "symentry.h" @@ -143,3 +145,4 @@ void WriteDbgSyms (void); + diff --git a/src/ca65/toklist.h b/src/ca65/toklist.h index 9826724d4..c195d54fb 100644 --- a/src/ca65/toklist.h +++ b/src/ca65/toklist.h @@ -38,6 +38,10 @@ +#include "scanner.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/