]> git.sur5r.net Git - cc65/blob - src/ca65/filetab.c
Added text tables
[cc65] / src / ca65 / filetab.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                 filetab.h                                 */
4 /*                                                                           */
5 /*                         Input file table for ca65                         */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000     Ullrich von Bassewitz                                        */
10 /*              Wacholderweg 14                                              */
11 /*              D-70597 Stuttgart                                            */
12 /* EMail:       uz@musoftware.de                                             */
13 /*                                                                           */
14 /*                                                                           */
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.                                    */
18 /*                                                                           */
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:                            */
22 /*                                                                           */
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              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <string.h>
37
38 /* common */
39 #include "check.h"
40 #include "hashstr.h"
41 #include "xmalloc.h"
42
43 /* ca65 */
44 #include "error.h"
45 #include "objfile.h"
46 #include "filetab.h"
47
48
49
50 /*****************************************************************************/
51 /*                                   Data                                    */
52 /*****************************************************************************/
53
54
55
56 /* An entry in the file table */
57 typedef struct FileEntry FileEntry;
58 struct FileEntry {
59     FileEntry*          Next;           /* Next in hash list */
60     unsigned            Index;          /* Index of entry */
61     unsigned long       Size;           /* Size of file */
62     unsigned long       MTime;          /* Time of last modification */
63     char                Name[1];        /* Name, dynamically allocated */
64 };
65
66 /* Array of all entries, listed by index */
67 static FileEntry**      FileTab   = 0;
68 static unsigned         FileCount = 0;
69 static unsigned         FileMax   = 0;
70
71 /* Hash table, hashed by name */
72 #define HASHTAB_SIZE    31
73 static FileEntry*       HashTab[HASHTAB_SIZE];
74
75
76
77 /*****************************************************************************/
78 /*                                   Code                                    */
79 /*****************************************************************************/
80
81
82
83 static FileEntry* NewFileEntry (const char* Name, unsigned long Size, unsigned long MTime)
84 /* Create a new FileEntry, insert it into the tables and return it */
85 {
86     /* Get the length of the name */
87     unsigned Len = strlen (Name);
88
89     /* Get the hash over the name */
90     unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
91
92     /* Allocate memory for the entry */
93     FileEntry* F = xmalloc (sizeof (FileEntry) + Len);
94
95     /* Initialize the fields */
96     F->Index    = FileCount+1;
97     F->Size     = Size;
98     F->MTime    = MTime;
99     memcpy (F->Name, Name, Len+1);
100
101     /* Count the entries and grow the file table if needed */
102     if (FileCount >= FileMax) {
103         /* We need to grow the table. Create a new one. */
104         unsigned NewFileMax   = (FileMax == 0)? 32 : FileMax * 2;
105         FileEntry** NewFileTab = xmalloc (sizeof (FileEntry*) * NewFileMax);
106
107         /* Copy the old entries */
108         memcpy (NewFileTab, FileTab, sizeof (FileEntry*) * FileCount);
109
110         /* Use the new table */
111         xfree (FileTab);
112         FileTab = NewFileTab;
113         FileMax = NewFileMax;
114     }
115
116     /* Insert the file into the file table */
117     FileTab [FileCount++] = F;
118
119     /* Insert the entry into the hash table */
120     F->Next = HashTab[Hash];
121     HashTab[Hash] = F;
122
123     /* Return the new entry */
124     return F;
125 }
126
127
128
129 const char* GetFileName (unsigned Name)
130 /* Get the name of a file where the name index is known */
131 {
132     PRECONDITION (Name <= FileCount);
133     if (Name == 0) {
134         /* Name was defined outside any file scope, use the name of the first
135          * file instead. Errors are then reported with a file position of
136          * line zero in the first file.
137          */
138         if (FileCount == 0) {
139             /* No files defined until now */
140             return "(outside file scope)";
141         } else {
142             return FileTab [0]->Name;
143         }
144     } else {
145         return FileTab [Name-1]->Name;
146     }
147 }
148
149
150
151 unsigned GetFileIndex (const char* Name)
152 /* Return the file index for the given file name. */
153 {
154     /* Get the hash over the name */
155     unsigned Hash = HashStr (Name) % HASHTAB_SIZE;
156
157     /* Search the linear hash list */
158     FileEntry* F = HashTab[Hash];
159     while (F) {
160         /* Is it this one? */
161         if (strcmp (Name, F->Name) == 0) {
162             /* Found, return the index */
163             return F->Index;
164         }
165         /* No, check next */
166         F = F->Next;
167     }
168
169     /* Not found, use main file */
170     Error (ERR_FILENAME_NOT_FOUND, Name);
171     return 0;
172 }
173
174
175
176 unsigned AddFile (const char* Name, unsigned long Size, unsigned long MTime)
177 /* Add a new file to the list of input files. Return the index of the file in
178  * the table.
179  */
180 {
181     /* Create a new file entry and insert it into the tables */
182     FileEntry* F = NewFileEntry (Name, Size, MTime);
183
184     /* Return the index */
185     return F->Index;
186 }
187
188
189
190 void WriteFiles (void)
191 /* Write the list of input files to the object file */
192 {
193     unsigned I;
194
195     /* Tell the obj file module that we're about to start the file list */
196     ObjStartFiles ();
197
198     /* Write the file count */
199     ObjWriteVar (FileCount);
200
201     /* Write the file data */
202     for (I = 0; I < FileCount; ++I) {
203         /* Get a pointer to the entry */
204         FileEntry* F = FileTab[I];
205         /* Write the fields */
206         ObjWrite32 (F->MTime);
207         ObjWrite32 (F->Size);
208         ObjWriteStr (F->Name);
209     }
210
211     /* Done writing files */
212     ObjEndFiles ();
213 }
214
215
216