1 /*****************************************************************************/
5 /* Source file info structure */
9 /* (C) 2001-2011, Ullrich von Bassewitz */
10 /* Roemerstrasse 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 /*****************************************************************************/
48 /*****************************************************************************/
50 /*****************************************************************************/
54 /* A list of all file infos without duplicates */
55 static Collection FileInfos = STATIC_COLLECTION_INITIALIZER;
59 /*****************************************************************************/
61 /*****************************************************************************/
65 static int FindFileInfo (unsigned Name, unsigned* Index)
66 /* Find the FileInfo for a given file name. The function returns true if the
67 * name was found. In this case, Index contains the index of the first item
68 * that matches. If the item wasn't found, the function returns false and
69 * Index contains the insert position for FileName.
72 /* Do a binary search */
74 int Hi = (int) CollCount (&FileInfos) - 1;
79 int Cur = (Lo + Hi) / 2;
82 FileInfo* CurItem = CollAt (&FileInfos, Cur);
85 if (CurItem->Name < Name) {
89 /* Since we may have duplicates, repeat the search until we've
90 * the first item that has a match.
92 if (CurItem->Name == Name) {
98 /* Pass back the index. This is also the insert position */
105 static FileInfo* NewFileInfo (void)
106 /* Allocate and initialize a new FileInfo struct and return it */
108 /* We will assign file info ids in increasing order of creation */
109 static unsigned Id = 0;
111 /* Allocate memory */
112 FileInfo* FI = xmalloc (sizeof (FileInfo));
114 /* Initialize stuff */
118 /* Return the new struct */
124 FileInfo* ReadFileInfo (FILE* F, ObjData* O)
125 /* Read a file info from a file and return it */
129 /* Read the fields from the file */
130 unsigned Name = MakeGlobalStringId (O, ReadVar (F));
131 unsigned long MTime = Read32 (F);
132 unsigned long Size = ReadVar (F);
134 /* Search for the first entry with this name */
136 if (FindFileInfo (Name, &Index)) {
138 /* We have at least one such entry. Try all of them and, if size and
139 * modification time matches, return the first match. When the loop
140 * is terminated without finding an entry, Index points one behind
141 * the last entry with the name, which is the perfect insert position.
143 FI = CollAt (&FileInfos, Index);
146 /* Check size and modification time stamp */
147 if (FI->Size == Size && FI->MTime == MTime) {
148 /* Return this one */
152 /* Check the next one */
153 if (++Index >= CollCount (&FileInfos)) {
157 FI = CollAt (&FileInfos, Index);
159 /* Done if the name differs */
160 if (FI->Name != Name) {
166 /* Not found. Allocate a new FileInfo structure */
174 /* Insert the file info in our global list. Index points to the insert
177 CollInsert (&FileInfos, FI, Index);
179 /* Return the new struct */
185 void PrintDbgFileInfo (FILE* F)
186 /* Output the file info to a debug info file */
190 /* Print file infos from all modules we have linked into the output file */
191 for (I = 0; I < CollCount (&ObjDataList); ++I) {
193 /* Get the object file */
194 ObjData* O = CollAtUnchecked (&ObjDataList, I);
196 /* Output the files section */
197 for (J = 0; J < CollCount (&O->Files); ++J) {
198 FileInfo* FI = CollAt (&O->Files, J);
201 "file\tid=%u,name=\"%s\",size=%lu,mtime=0x%08lX\n",
202 FI->Id, GetString (FI->Name), FI->Size, FI->MTime);