1 /*****************************************************************************/
5 /* Error handling for the ca65 macroassembler */
9 /* (C) 1998-2011, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
51 /*****************************************************************************/
53 /*****************************************************************************/
58 unsigned WarnLevel = 1;
61 unsigned ErrorCount = 0;
62 unsigned WarningCount = 0;
66 /*****************************************************************************/
67 /* Helper functions */
68 /*****************************************************************************/
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. */
76 StrBuf S = STATIC_STRBUF_INITIALIZER;
78 /* Format the actual message */
79 StrBuf Msg = STATIC_STRBUF_INITIALIZER;
80 SB_VPrintf (&Msg, Format, ap);
83 /* Format the message header */
84 SB_Printf (&S, "%s(%lu): %s: ",
85 SB_GetConstBuf (GetFileName (Pos->Name)),
89 /* Append the message to the message header */
92 /* Delete the formatted message */
95 /* Add a new line and terminate the generated full message */
96 SB_AppendChar (&S, '\n');
99 /* Output the full message */
100 fputs (SB_GetConstBuf (&S), stderr);
102 /* Delete the buffer for the full message */
108 static void PrintMsg (const FilePos* Pos, const char* Desc,
109 const char* Format, ...)
110 /* Format and output an error/warning message. */
113 va_start (ap, Format);
114 VPrintMsg (Pos, Desc, Format, ap);
120 static void AddNotifications (const Collection* LineInfos)
121 /* Output additional notifications for an error or warning */
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
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");
146 /*****************************************************************************/
148 /*****************************************************************************/
152 static void WarningMsg (const Collection* LineInfos, const char* Format, va_list ap)
153 /* Print warning message. */
155 /* The first entry in the collection is that of the actual source pos */
156 const LineInfo* LI = CollConstAt (LineInfos, 0);
158 /* Output a warning for this position */
159 VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
161 /* Add additional notifications if necessary */
162 AddNotifications (LineInfos);
170 void Warning (unsigned Level, const char* Format, ...)
171 /* Print warning message. */
173 if (Level <= WarnLevel) {
176 Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
178 /* Get line infos for the current position */
179 GetFullLineInfo (&LineInfos, 0);
181 /* Output the message */
182 va_start (ap, Format);
183 WarningMsg (&LineInfos, Format, ap);
186 /* Free the line info list */
187 DoneCollection (&LineInfos);
193 void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
194 /* Print warning message giving an explicit file and position. */
196 if (Level <= WarnLevel) {
198 va_start (ap, Format);
199 VPrintMsg (Pos, "Warning", Format, ap);
209 void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...)
210 /* Print warning message using the given line infos */
212 if (Level <= WarnLevel) {
213 /* Output the message */
215 va_start (ap, Format);
216 WarningMsg (LineInfos, Format, ap);
223 /*****************************************************************************/
225 /*****************************************************************************/
229 void ErrorMsg (const Collection* LineInfos, const char* Format, va_list ap)
230 /* Print an error message */
232 /* The first entry in the collection is that of the actual source pos */
233 const LineInfo* LI = CollConstAt (LineInfos, 0);
235 /* Output an error for this position */
236 VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
238 /* Add additional notifications if necessary */
239 AddNotifications (LineInfos);
247 void Error (const char* Format, ...)
248 /* Print an error message */
251 Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
253 /* Get line infos for the current position */
254 GetFullLineInfo (&LineInfos, 0);
256 /* Output the message */
257 va_start (ap, Format);
258 ErrorMsg (&LineInfos, Format, ap);
261 /* Free the line info list */
262 DoneCollection (&LineInfos);
267 void LIError (const Collection* LineInfos, const char* Format, ...)
268 /* Print an error message using the given line infos. */
270 /* Output an error for this position */
272 va_start (ap, Format);
273 ErrorMsg (LineInfos, Format, ap);
279 void ErrorSkip (const char* Format, ...)
280 /* Print an error message and skip the rest of the line */
283 Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
285 /* Get line infos for the current position */
286 GetFullLineInfo (&LineInfos, 0);
288 /* Output the message */
289 va_start (ap, Format);
290 ErrorMsg (&LineInfos, Format, ap);
293 /* Free the line info list */
294 DoneCollection (&LineInfos);
296 /* Skip tokens until we reach the end of the line */
302 /*****************************************************************************/
304 /*****************************************************************************/
308 void Fatal (const char* Format, ...)
309 /* Print a message about a fatal error and die */
312 StrBuf S = STATIC_STRBUF_INITIALIZER;
314 va_start (ap, Format);
315 SB_VPrintf (&S, Format, ap);
319 fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
329 void Internal (const char* Format, ...)
330 /* Print a message about an internal assembler error and die. */
333 StrBuf S = STATIC_STRBUF_INITIALIZER;
335 va_start (ap, Format);
336 SB_VPrintf (&S, Format, ap);
340 fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S));