]> git.sur5r.net Git - cc65/blob - src/ca65/error.c
Changed text of notification.
[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 VPrintMsg (const FilePos* Pos, const char* Desc,
73                        const char* Format, va_list ap)
74 /* Format and output an error/warning message. */
75 {
76     StrBuf S = STATIC_STRBUF_INITIALIZER;
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 full message */
96     SB_AppendChar (&S, '\n');
97     SB_Terminate (&S);
98
99     /* Output the full message */
100     fputs (SB_GetConstBuf (&S), stderr);
101
102     /* Delete the buffer for the full message */
103     SB_Done (&S);
104 }
105
106
107
108 static void PrintMsg (const FilePos* Pos, const char* Desc,
109                       const char* Format, ...)
110 /* Format and output an error/warning message. */
111 {
112     va_list ap;
113     va_start (ap, Format);
114     VPrintMsg (Pos, Desc, Format, ap);
115     va_end (ap);
116 }
117
118
119
120 static void AddNotifications (const Collection* LineInfos)
121 /* Output additional notifications for an error or warning */
122 {
123     /* The basic line info is always in slot zero. It has been used to
124      * output the actual error or warning. The following slots may contain
125      * more information. Check them and additional notifications if they're
126      * present.
127      */
128     unsigned I;
129     for (I = 1; I < CollCount (LineInfos); ++I) {
130         /* Get next line info */
131         const LineInfo* LI = CollConstAt (LineInfos, I);
132         /* Check the type and output an appropriate note */
133         unsigned Type = GetLineInfoType (LI);
134         if (Type == LI_TYPE_EXT) {
135             PrintMsg (GetSourcePos (LI), "Note",
136                       "Assembler code generated from this line");
137         } else if (Type == LI_TYPE_MACRO) {
138             PrintMsg (GetSourcePos (LI), "Note",
139                       "Macro was defined here");
140         }
141     }
142 }
143
144
145
146 /*****************************************************************************/
147 /*                                 Warnings                                  */
148 /*****************************************************************************/
149
150
151
152 static void WarningMsg (const Collection* LineInfos, const char* Format, va_list ap)
153 /* Print warning message. */
154 {
155     /* The first entry in the collection is that of the actual source pos */
156     const LineInfo* LI = CollConstAt (LineInfos, 0);
157
158     /* Output a warning for this position */
159     VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
160
161     /* Add additional notifications if necessary */
162     AddNotifications (LineInfos);
163
164     /* Count warnings */
165     ++WarningCount;
166 }
167
168
169
170 void Warning (unsigned Level, const char* Format, ...)
171 /* Print warning message. */
172 {
173     if (Level <= WarnLevel) {
174
175         va_list ap;
176         Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
177
178         /* Get line infos for the current position */
179         GetFullLineInfo (&LineInfos, 0);
180
181         /* Output the message */
182         va_start (ap, Format);
183         WarningMsg (&LineInfos, Format, ap);
184         va_end (ap);
185
186         /* Free the line info list */
187         DoneCollection (&LineInfos);
188     }
189 }
190
191
192
193 void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
194 /* Print warning message giving an explicit file and position. */
195 {
196     if (Level <= WarnLevel) {
197         va_list ap;
198         va_start (ap, Format);
199         VPrintMsg (Pos, "Warning", Format, ap);
200         va_end (ap);
201
202         /* Count warnings */
203         ++WarningCount;
204     }
205 }
206
207
208
209 void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...)
210 /* Print warning message using the given line infos */
211 {
212     if (Level <= WarnLevel) {
213         /* Output the message */
214         va_list ap;
215         va_start (ap, Format);
216         WarningMsg (LineInfos, Format, ap);
217         va_end (ap);
218     }
219 }
220
221
222
223 /*****************************************************************************/
224 /*                                  Errors                                   */
225 /*****************************************************************************/
226
227
228
229 void ErrorMsg (const Collection* LineInfos, const char* Format, va_list ap)
230 /* Print an error message */
231 {
232     /* The first entry in the collection is that of the actual source pos */
233     const LineInfo* LI = CollConstAt (LineInfos, 0);
234
235     /* Output an error for this position */
236     VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
237
238     /* Add additional notifications if necessary */
239     AddNotifications (LineInfos);
240
241     /* Count errors */
242     ++ErrorCount;
243 }
244
245
246
247 void Error (const char* Format, ...)
248 /* Print an error message */
249 {
250     va_list ap;
251     Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
252
253     /* Get line infos for the current position */
254     GetFullLineInfo (&LineInfos, 0);
255
256     /* Output the message */
257     va_start (ap, Format);
258     ErrorMsg (&LineInfos, Format, ap);
259     va_end (ap);
260
261     /* Free the line info list */
262     DoneCollection (&LineInfos);
263 }
264
265
266
267 void LIError (const Collection* LineInfos, const char* Format, ...)
268 /* Print an error message using the given line infos. */
269 {
270     /* Output an error for this position */
271     va_list ap;
272     va_start (ap, Format);
273     ErrorMsg (LineInfos, Format, ap);
274     va_end (ap);
275 }
276
277
278
279 void ErrorSkip (const char* Format, ...)
280 /* Print an error message and skip the rest of the line */
281 {
282     va_list ap;
283     Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
284
285     /* Get line infos for the current position */
286     GetFullLineInfo (&LineInfos, 0);
287
288     /* Output the message */
289     va_start (ap, Format);
290     ErrorMsg (&LineInfos, Format, ap);
291     va_end (ap);
292
293     /* Free the line info list */
294     DoneCollection (&LineInfos);
295
296     /* Skip tokens until we reach the end of the line */
297     SkipUntilSep ();
298 }
299
300
301
302 /*****************************************************************************/
303 /*                                   Code                                    */
304 /*****************************************************************************/
305
306
307
308 void Fatal (const char* Format, ...)
309 /* Print a message about a fatal error and die */
310 {
311     va_list ap;
312     StrBuf S = STATIC_STRBUF_INITIALIZER;
313
314     va_start (ap, Format);
315     SB_VPrintf (&S, Format, ap);
316     SB_Terminate (&S);
317     va_end (ap);
318
319     fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
320
321     SB_Done (&S);
322
323     /* And die... */
324     exit (EXIT_FAILURE);
325 }
326
327
328
329 void Internal (const char* Format, ...)
330 /* Print a message about an internal assembler error and die. */
331 {
332     va_list ap;
333     StrBuf S = STATIC_STRBUF_INITIALIZER;
334
335     va_start (ap, Format);
336     SB_VPrintf (&S, Format, ap);
337     SB_Terminate (&S);
338     va_end (ap);
339
340     fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S));
341
342     SB_Done (&S);
343
344     exit (EXIT_FAILURE);
345 }
346
347
348