1 /*****************************************************************************/
5 /* Input file table for ca65 */
9 /* (C) 2000-2003 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
52 /*****************************************************************************/
54 /*****************************************************************************/
58 /* An entry in the file table */
59 typedef struct FileEntry FileEntry;
61 unsigned Name; /* File name */
62 FileEntry* Next; /* Next in hash list */
63 unsigned Index; /* Index of entry */
64 unsigned long Size; /* Size of file */
65 unsigned long MTime; /* Time of last modification */
68 /* Array of all entries, listed by index */
69 static Collection FileTab = STATIC_COLLECTION_INITIALIZER;
71 /* Hash table, hashed by name */
72 #define HASHTAB_MASK 0x1FU
73 #define HASHTAB_SIZE (HASHTAB_MASK + 1)
74 static FileEntry* HashTab[HASHTAB_SIZE];
78 /*****************************************************************************/
80 /*****************************************************************************/
84 static FileEntry* NewFileEntry (unsigned Name, unsigned long Size, unsigned long MTime)
85 /* Create a new FileEntry, insert it into the tables and return it */
87 /* Get the hash over the name */
88 unsigned Hash = (Name & HASHTAB_MASK);
90 /* Allocate memory for the entry */
91 FileEntry* F = xmalloc (sizeof (FileEntry));
93 /* Initialize the fields */
95 F->Index = CollCount (&FileTab) + 1; /* First file has index #1 */
99 /* Insert the file into the file table */
100 CollAppend (&FileTab, F);
102 /* Insert the entry into the hash table */
103 F->Next = HashTab[Hash];
106 /* Return the new entry */
112 const char* GetFileName (unsigned Name)
113 /* Get the name of a file where the name index is known */
118 /* Name was defined outside any file scope, use the name of the first
119 * file instead. Errors are then reported with a file position of
120 * line zero in the first file.
122 if (CollCount (&FileTab) == 0) {
123 /* No files defined until now */
124 return "(outside file scope)";
126 F = CollConstAt (&FileTab, 0);
129 F = CollConstAt (&FileTab, Name-1);
131 return GetString (F->Name);
136 unsigned GetFileIndex (const char* Name)
137 /* Return the file index for the given file name. */
139 /* Get the string pool index from the name */
140 unsigned NameIdx = GetStringId (Name);
142 /* Get the hash over the name */
143 unsigned Hash = (NameIdx & HASHTAB_MASK);
145 /* Search the linear hash list */
146 FileEntry* F = HashTab[Hash];
148 /* Is it this one? */
149 if (NameIdx == F->Name) {
150 /* Found, return the index */
157 /* Not found, use main file */
158 Error (ERR_FILENAME_NOT_FOUND, Name);
164 unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime)
165 /* Add a new file to the list of input files. Return the index of the file in
169 /* Create a new file entry and insert it into the tables */
170 FileEntry* F = NewFileEntry (GetStringId (Name), Size, MTime);
172 /* Return the index */
178 void WriteFiles (void)
179 /* Write the list of input files to the object file */
183 /* Tell the obj file module that we're about to start the file list */
186 /* Write the file count */
187 ObjWriteVar (CollCount (&FileTab));
189 /* Write the file data */
190 for (I = 0; I < CollCount (&FileTab); ++I) {
191 /* Get a pointer to the entry */
192 const FileEntry* F = CollConstAt (&FileTab, I);
193 /* Write the fields */
194 ObjWriteVar (F->Name);
195 ObjWrite32 (F->MTime);
196 ObjWrite32 (F->Size);
199 /* Done writing files */