]> git.sur5r.net Git - cc65/blob - src/ca65/error.c
On errors and warnings, output additional information using extra line info
[cc65] / src / ca65 / error.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                  error.c                                  */
4 /*                                                                           */
5 /*                Error handling for the ca65 macroassembler                 */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2011, 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 #include <stdio.h>
37 #include <stdlib.h>
38 #include <stdarg.h>
39
40 /* common */
41 #include "strbuf.h"
42
43 /* ca65 */
44 #include "error.h"
45 #include "filetab.h"
46 #include "lineinfo.h"
47 #include "nexttok.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 /* Warning level */
58 unsigned WarnLevel      = 1;
59
60 /* Statistics */
61 unsigned ErrorCount     = 0;
62 unsigned WarningCount   = 0;
63
64
65
66 /*****************************************************************************/
67 /*                             Helper functions                              */
68 /*****************************************************************************/
69
70
71
72 static void FormatVMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
73                         const char* Format, va_list ap)
74 /* Format an error/warning message into S. A trailing newline and a NUL
75  * terminator will be added to S.
76  */
77 {
78     /* Format the actual message */
79     StrBuf Msg = STATIC_STRBUF_INITIALIZER;
80     SB_VPrintf (&Msg, Format, ap);
81     SB_Terminate (&Msg);
82
83     /* Format the message header */
84     SB_Printf (S, "%s(%lu): %s: ",
85                SB_GetConstBuf (GetFileName (Pos->Name)),
86                Pos->Line,
87                Desc);
88
89     /* Append the message to the message header */
90     SB_Append (S, &Msg);
91
92     /* Delete the formatted message */
93     SB_Done (&Msg);
94
95     /* Add a new line and terminate the generated message */
96     SB_AppendChar (S, '\n');
97     SB_Terminate (S);
98 }
99
100
101
102 static void FormatMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
103                        const char* Format, ...)
104 /* Format an error/warning message into S. A trailing newline and a NUL
105  * terminator will be added to S.
106  */
107 {
108     va_list ap;
109     va_start (ap, Format);
110     FormatVMsg (S, Pos, Desc, Format, ap);
111     va_end (ap);
112 }
113
114
115
116 static void AddNotifications (const Collection* LineInfos)
117 /* Output additional notifications for an error or warning */
118 {
119     StrBuf Msg = STATIC_STRBUF_INITIALIZER;
120
121     /* The basic line info is always in slot zero. It has been used to
122      * output the actual error or warning. The following slots may contain
123      * more information. Check them and additional notifications if they're
124      * present.
125      */
126     unsigned I;
127     for (I = 1; I < CollCount (LineInfos); ++I) {
128         /* Get next line info */
129         const LineInfo* LI = CollConstAt (LineInfos, I);
130         /* Check the type and output an appropriate note */
131         unsigned Type = GetLineInfoType (LI);
132         if (Type == LI_TYPE_EXT) {
133             FormatMsg (&Msg, GetSourcePos (LI), "Note",
134                        "Assembler code generated from this line");
135             fputs (SB_GetConstBuf (&Msg), stderr);
136
137         } else if (Type == LI_TYPE_MACRO) {
138
139         }
140     }
141
142     SB_Done (&Msg);
143 }
144
145
146
147 /*****************************************************************************/
148 /*                                 Warnings                                  */
149 /*****************************************************************************/
150
151
152
153 void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list ap)
154 /* Print warning message. */
155 {
156     if (Level <= WarnLevel) {
157
158         StrBuf Msg = STATIC_STRBUF_INITIALIZER;
159         FormatVMsg (&Msg, Pos, "Warning", Format, ap);
160         fputs (SB_GetConstBuf (&Msg), stderr);
161         SB_Done (&Msg);
162
163         ++WarningCount;
164     }
165 }
166
167
168
169 void Warning (unsigned Level, const char* Format, ...)
170 /* Print warning message. */
171 {
172     va_list ap;
173     va_start (ap, Format);
174     WarningMsg (&CurTok.Pos, Level, Format, ap);
175     va_end (ap);
176 }
177
178
179
180 void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
181 /* Print warning message giving an explicit file and position. */
182 {
183     va_list ap;
184     va_start (ap, Format);
185     WarningMsg (Pos, Level, Format, ap);
186     va_end (ap);
187 }
188
189
190
191 void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...)
192 /* Print warning message using the given line infos */
193 {
194     if (Level <= WarnLevel) {
195
196         va_list ap;
197
198         /* The first entry in the collection is that of the actual source pos */
199         const LineInfo* LI = CollConstAt (LineInfos, 0);
200
201         /* Output a warning for this position */
202         va_start (ap, Format);
203         WarningMsg (GetSourcePos (LI), Level, Format, ap);
204         va_end (ap);
205
206         /* Add additional notifications if necessary */
207         AddNotifications (LineInfos);
208     }
209 }
210
211
212
213 /*****************************************************************************/
214 /*                                  Errors                                   */
215 /*****************************************************************************/
216
217
218
219 void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
220 /* Print an error message */
221 {
222     StrBuf Msg = STATIC_STRBUF_INITIALIZER;
223     FormatVMsg (&Msg, Pos, "Error", Format, ap);
224     fputs (SB_GetConstBuf (&Msg), stderr);
225     SB_Done (&Msg);
226
227     ++ErrorCount;
228 }
229
230
231
232 void Error (const char* Format, ...)
233 /* Print an error message */
234 {
235     va_list ap;
236     va_start (ap, Format);
237     ErrorMsg (&CurTok.Pos, Format, ap);
238     va_end (ap);
239 }
240
241
242
243 void PError (const FilePos* Pos, const char* Format, ...)
244 /* Print an error message giving an explicit file and position. */
245 {
246     va_list ap;
247     va_start (ap, Format);
248     ErrorMsg (Pos, Format, ap);
249     va_end (ap);
250 }
251
252
253
254 void LIError (const Collection* LineInfos, const char* Format, ...)
255 /* Print an error message using the given line infos. */
256 {
257     va_list ap;
258
259     /* The first entry in the collection is that of the actual source pos */
260     const LineInfo* LI = CollConstAt (LineInfos, 0);
261
262     /* Output an error for this position */
263     va_start (ap, Format);
264     ErrorMsg (GetSourcePos (LI), Format, ap);
265     va_end (ap);
266
267     /* Add additional notifications if necessary */
268     AddNotifications (LineInfos);
269 }
270
271
272
273 void ErrorSkip (const char* Format, ...)
274 /* Print an error message and skip the rest of the line */
275 {
276     va_list ap;
277     va_start (ap, Format);
278     ErrorMsg (&CurTok.Pos, Format, ap);
279     va_end (ap);
280
281     SkipUntilSep ();
282 }
283
284
285
286 /*****************************************************************************/
287 /*                                   Code                                    */
288 /*****************************************************************************/
289
290
291
292 void Fatal (const char* Format, ...)
293 /* Print a message about a fatal error and die */
294 {
295     va_list ap;
296     StrBuf S = STATIC_STRBUF_INITIALIZER;
297
298     va_start (ap, Format);
299     SB_VPrintf (&S, Format, ap);
300     SB_Terminate (&S);
301     va_end (ap);
302
303     fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
304
305     SB_Done (&S);
306
307     /* And die... */
308     exit (EXIT_FAILURE);
309 }
310
311
312
313 void Internal (const char* Format, ...)
314 /* Print a message about an internal assembler error and die. */
315 {
316     va_list ap;
317     StrBuf S = STATIC_STRBUF_INITIALIZER;
318
319     va_start (ap, Format);
320     SB_VPrintf (&S, Format, ap);
321     SB_Terminate (&S);
322     va_end (ap);
323
324     fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S));
325
326     SB_Done (&S);
327
328     exit (EXIT_FAILURE);
329 }
330
331
332