]> git.sur5r.net Git - cc65/blob - src/ld65/lineinfo.c
Removed (pretty inconsistently used) tab chars from source code base.
[cc65] / src / ld65 / lineinfo.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                lineinfo.h                                 */
4 /*                                                                           */
5 /*                      Source file line info structure                      */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2001-2012, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
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 /* common */
37 #include "check.h"
38 #include "lidefs.h"
39 #include "xmalloc.h"
40
41 /* ld65 */
42 #include "error.h"
43 #include "fileinfo.h"
44 #include "fileio.h"
45 #include "lineinfo.h"
46 #include "objdata.h"
47 #include "segments.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Code                                    */
53 /*****************************************************************************/
54
55
56
57 static LineInfo* NewLineInfo (void)
58 /* Create and return a new LineInfo struct with mostly empty fields */
59 {
60     /* Allocate memory */
61     LineInfo* LI = xmalloc (sizeof (LineInfo));
62
63     /* Initialize the fields */
64     LI->Id         = ~0U;
65     LI->File       = 0;
66     LI->Type       = LI_MAKE_TYPE (LI_TYPE_ASM, 0);
67     LI->Pos.Name   = INVALID_STRING_ID;
68     LI->Pos.Line   = 0;
69     LI->Pos.Col    = 0;
70     LI->Spans      = 0;
71
72     /* Return the new struct */
73     return LI;
74 }
75
76
77
78 void FreeLineInfo (LineInfo* LI)
79 /* Free a LineInfo structure. */
80 {
81     /* Free the span list */
82     xfree (LI->Spans);
83
84     /* Free the structure itself */
85     xfree (LI);
86 }
87
88
89
90 LineInfo* DupLineInfo (const LineInfo* LI)
91 /* Creates a duplicate of a line info structure */
92 {
93     /* Allocate memory */
94     LineInfo* New = xmalloc (sizeof (LineInfo));
95
96     /* Copy the fields (leave id invalid) */
97     New->Id     = LI->Id;
98     New->File   = LI->File;
99     New->Type   = LI->Type;
100     New->Pos    = LI->Pos;
101     New->Spans  = DupSpanList (LI->Spans);
102
103     /* Return the copy */
104     return New;
105 }
106
107
108
109 LineInfo* GenLineInfo (const FilePos* Pos)
110 /* Generate a new (internally used) line info with the given information */
111 {
112     /* Create a new LineInfo struct */
113     LineInfo* LI = NewLineInfo ();
114
115     /* Initialize the fields in the new LineInfo */
116     LI->Pos = *Pos;
117
118     /* Return the struct read */
119     return LI;
120 }
121
122
123
124 LineInfo* ReadLineInfo (FILE* F, ObjData* O)
125 /* Read a line info from a file and return it */
126 {
127     /* Create a new LineInfo struct */
128     LineInfo* LI = NewLineInfo ();
129
130     /* Read/fill the fields in the new LineInfo */
131     LI->Pos.Line = ReadVar (F);
132     LI->Pos.Col  = ReadVar (F);
133     LI->File     = CollAt (&O->Files, ReadVar (F));
134     LI->Pos.Name = LI->File->Name;
135     LI->Type     = ReadVar (F);
136     LI->Spans    = ReadSpanList (F);
137
138     /* Return the struct read */
139     return LI;
140 }
141
142
143
144 void ReadLineInfoList (FILE* F, ObjData* O, Collection* LineInfos)
145 /* Read a list of line infos stored as a list of indices in the object file,
146  * make real line infos from them and place them into the passed collection.
147  */
148 {
149     /* Read the number of line info indices that follow */
150     unsigned LineInfoCount = ReadVar (F);
151
152     /* Grow the collection as needed */
153     CollGrow (LineInfos, LineInfoCount);
154
155     /* Read the line infos and resolve them */
156     while (LineInfoCount--) {
157
158         /* Read an index */
159         unsigned LineInfoIndex = ReadVar (F);
160
161         /* The line info index was written by the assembler and must
162          * therefore be part of the line infos read from the object file.
163          */
164         if (LineInfoIndex >= CollCount (&O->LineInfos)) {
165             Internal ("Invalid line info index %u in module `%s' - max is %u",
166                       LineInfoIndex,
167                       GetObjFileName (O),
168                       CollCount (&O->LineInfos));
169         }
170
171         /* Add the line info to the collection */
172         CollAppend (LineInfos, CollAt (&O->LineInfos, LineInfoIndex));
173     }
174 }
175
176
177
178 const LineInfo* GetAsmLineInfo (const Collection* LineInfos)
179 /* Find a line info of type LI_TYPE_ASM and count zero in the given collection
180  * and return it. Return NULL if no such line info was found.
181  */
182 {
183     unsigned I;
184
185     /* Search for a line info of LI_TYPE_ASM */
186     for (I = 0; I < CollCount (LineInfos); ++I) {
187         const LineInfo* LI = CollConstAt (LineInfos, I);
188         if (LI->Type == LI_MAKE_TYPE (LI_TYPE_ASM, 0)) {
189             return LI;
190         }
191     }
192
193     /* Not found */
194     return 0;
195 }
196
197
198
199 unsigned LineInfoCount (void)
200 /* Return the total number of line infos */
201 {
202     /* Walk over all object files */
203     unsigned I;
204     unsigned Count = 0;
205     for (I = 0; I < CollCount (&ObjDataList); ++I) {
206
207         /* Get this object file */
208         const ObjData* O = CollAtUnchecked (&ObjDataList, I);
209
210         /* Count spans */
211         Count += CollCount (&O->LineInfos);
212     }
213
214     return Count;
215 }
216
217
218
219 void AssignLineInfoIds (void)
220 /* Assign the ids to the line infos */
221 {
222     unsigned I, J;
223
224     /* Walk over all line infos */
225     unsigned Id = 0;
226     for (I = 0; I < CollCount (&ObjDataList); ++I) {
227
228         /* Get the object file */
229         ObjData* O = CollAtUnchecked (&ObjDataList, I);
230
231         /* Output the line infos */
232         for (J = 0; J < CollCount (&O->LineInfos); ++J) {
233
234             /* Get this line info */
235             LineInfo* LI = CollAtUnchecked (&O->LineInfos, J);
236
237             /* Assign the id */
238             LI->Id = Id++;
239         }
240     }
241 }
242
243
244
245 void PrintDbgLineInfo (FILE* F)
246 /* Output the line infos to a debug info file */
247 {
248     unsigned I, J;
249
250     /* Print line infos from all modules we have linked into the output file */
251     for (I = 0; I < CollCount (&ObjDataList); ++I) {
252
253         /* Get the object file */
254         const ObjData* O = CollAtUnchecked (&ObjDataList, I);
255
256         /* Output the line infos */
257         for (J = 0; J < CollCount (&O->LineInfos); ++J) {
258
259             /* Get this line info */
260             const LineInfo* LI = CollConstAt (&O->LineInfos, J);
261
262             /* Get the line info type and count */
263             unsigned Type  = LI_GET_TYPE (LI->Type);
264             unsigned Count = LI_GET_COUNT (LI->Type);
265
266             /* Print the start of the line */
267             fprintf (F,
268                      "line\tid=%u,file=%u,line=%u",
269                      LI->Id, LI->File->Id, GetSourceLine (LI));
270
271             /* Print type if not LI_TYPE_ASM and count if not zero */
272             if (Type != LI_TYPE_ASM) {
273                 fprintf (F, ",type=%u", Type);
274             }
275             if (Count != 0) {
276                 fprintf (F, ",count=%u", Count);
277             }
278
279             /* Add spans if the line info has it */
280             PrintDbgSpanList (F, O, LI->Spans);
281
282             /* Terminate line */
283             fputc ('\n', F);
284         }
285     }
286 }
287
288
289