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 */
57static LineInfo* CurLineInfo = 0;
58
59
60
61/*****************************************************************************/
62/* Code */
63/*****************************************************************************/
64
65
66
67static 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
117static void FreeLineInfo (LineInfo* LI)
118/* Free a LineInfo structure */
119{
120 xfree (LI);
121}
122
123
124
125LineInfo* 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
135void 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
149LineInfo* 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
159void 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
180const 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
189unsigned GetInputLine (const LineInfo* LI)
190/* Return the line number from a line info */
191{
192 PRECONDITION (LI != 0);
193 return LI->LineNum;
194}
195