1 | /*****************************************************************************/ |
2 | /* */ |
3 | /* lineinfo.c */ |
4 | /* */ |
5 | /* Source file line info structure */ |
6 | /* */ |
7 | /* */ |
8 | /* */ |
9 | /* (C) 2001 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 "chartype.h" |
40 | #include "check.h" |
41 | #include "xmalloc.h" |
42 | |
43 | /* cc65 */ |
44 | #include "global.h" |
45 | #include "input.h" |
46 | #include "lineinfo.h" |
47 | |
48 | |
49 | |
50 | /*****************************************************************************/ |
51 | /* Data */ |
52 | /*****************************************************************************/ |
53 | |
54 | |
55 | |
56 | /* Global pointer to line information for the current line */ |
57 | static LineInfo* CurLineInfo = 0; |
58 | |
59 | |
60 | |
61 | /*****************************************************************************/ |
62 | /* Code */ |
63 | /*****************************************************************************/ |
64 | |
65 | |
66 | |
67 | static LineInfo* NewLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line) |
68 | /* Create and return a new line info. Ref count will be 1. */ |
69 | { |
70 | unsigned Len; |
71 | LineInfo* LI; |
72 | const char* S; |
73 | char* T; |
74 | |
75 | /* Get the length of the line and a pointer to the line buffer */ |
76 | Len = SB_GetLen (Line); |
77 | S = SB_GetConstBuf (Line); |
78 | |
79 | /* Skip leading spaces in Line */ |
80 | while (Len > 0 && IsBlank (*S)) { |
81 | ++S; |
82 | --Len; |
83 | } |
84 | |
85 | /* Allocate memory for the line info and the input line */ |
86 | LI = xmalloc (sizeof (LineInfo) + Len); |
87 | |
88 | /* Initialize the fields */ |
89 | LI->RefCount = 1; |
90 | LI->InputFile = F; |
91 | LI->LineNum = LineNum; |
92 | |
93 | /* Copy the line, replacing tabs by spaces in the given line since tabs |
94 | ** will give rather arbitrary results when used in the output later, and |
95 | ** if we do it here, we won't need another copy later. |
96 | */ |
97 | T = LI->Line; |
98 | while (Len--) { |
99 | if (*S == '\t') { |
100 | *T = ' '; |
101 | } else { |
102 | *T = *S; |
103 | } |
104 | ++S; |
105 | ++T; |
106 | } |
107 | |
108 | /* Add the terminator */ |
109 | *T = '\0'; |
110 | |
111 | /* Return the new struct */ |
112 | return LI; |
113 | } |
114 | |
115 | |
116 | |
117 | static void FreeLineInfo (LineInfo* LI) |
118 | /* Free a LineInfo structure */ |
119 | { |
120 | xfree (LI); |
121 | } |
122 | |
123 | |
124 | |
125 | LineInfo* UseLineInfo (LineInfo* LI) |
126 | /* Increase the reference count of the given line info and return it. */ |
127 | { |
128 | CHECK (LI != 0); |
129 | ++LI->RefCount; |
130 | return LI; |
131 | } |
132 | |
133 | |
134 | |
135 | void ReleaseLineInfo (LineInfo* LI) |
136 | /* Release a reference to the given line info, free the structure if the |
137 | ** reference count drops to zero. |
138 | */ |
139 | { |
140 | CHECK (LI && LI->RefCount > 0); |
141 | if (--LI->RefCount == 0) { |
142 | /* No more references, free it */ |
143 | FreeLineInfo (LI); |
144 | } |
145 | } |
146 | |
147 | |
148 | |
149 | LineInfo* GetCurLineInfo (void) |
150 | /* Return a pointer to the current line info. The reference count is NOT |
151 | ** increased, use UseLineInfo for that purpose. |
152 | */ |
153 | { |
154 | return CurLineInfo; |
155 | } |
156 | |
157 | |
158 | |
159 | void UpdateLineInfo (struct IFile* F, unsigned LineNum, const StrBuf* Line) |
160 | /* Update the line info - called if a new line is read */ |
161 | { |
162 | /* If a current line info exists, release it */ |
163 | if (CurLineInfo) { |
164 | ReleaseLineInfo (CurLineInfo); |
165 | } |
166 | |
167 | /* If we have intermixed assembly switched off, use an empty line instead |
168 | ** of the supplied one to save some memory. |
169 | */ |
170 | if (!AddSource) { |
171 | Line = &EmptyStrBuf; |
172 | } |
173 | |
174 | /* Create a new line info */ |
175 | CurLineInfo = NewLineInfo (F, LineNum, Line); |
176 | } |
177 | |
178 | |
179 | |
180 | const char* GetInputName (const LineInfo* LI) |
181 | /* Return the file name from a line info */ |
182 | { |
183 | PRECONDITION (LI != 0); |
184 | return GetInputFile (LI->InputFile); |
185 | } |
186 | |
187 | |
188 | |
189 | unsigned GetInputLine (const LineInfo* LI) |
190 | /* Return the line number from a line info */ |
191 | { |
192 | PRECONDITION (LI != 0); |
193 | return LI->LineNum; |
194 | } |
195 | |