PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/src/cc65/error.c

https://bitbucket.org/dserpell/cc65-trunk-old
C | 313 lines | 162 code | 80 blank | 71 comment | 15 complexity | bfce8c68ca783448ae8c83c52da4cbb7 MD5 | raw file
  1. /*****************************************************************************/
  2. /* */
  3. /* error.c */
  4. /* */
  5. /* Error handling for the cc65 C compiler */
  6. /* */
  7. /* */
  8. /* */
  9. /* (C) 1998-2010, 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. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <stdarg.h>
  36. /* common */
  37. #include "print.h"
  38. /* cc65 */
  39. #include "global.h"
  40. #include "input.h"
  41. #include "lineinfo.h"
  42. #include "scanner.h"
  43. #include "stmt.h"
  44. #include "error.h"
  45. /*****************************************************************************/
  46. /* Data */
  47. /*****************************************************************************/
  48. /* Count of errors/warnings */
  49. unsigned ErrorCount = 0;
  50. unsigned WarningCount = 0;
  51. /* Warning and error options */
  52. IntStack WarnEnable = INTSTACK(1); /* Enable warnings */
  53. IntStack WarningsAreErrors = INTSTACK(0); /* Treat warnings as errors */
  54. /* Warn about: */
  55. IntStack WarnNoEffect = INTSTACK(1); /* ... statements without an effect */
  56. IntStack WarnStructParam = INTSTACK(1); /* ... structs passed by val */
  57. IntStack WarnUnusedLabel = INTSTACK(1); /* ... unused labels */
  58. IntStack WarnUnusedParam = INTSTACK(1); /* ... unused parameters */
  59. IntStack WarnUnusedVar = INTSTACK(1); /* ... unused variables */
  60. IntStack WarnUnknownPragma = INTSTACK(1); /* ... unknown #pragmas */
  61. /* Map the name of a warning to the intstack that holds its state */
  62. typedef struct WarnMapEntry WarnMapEntry;
  63. struct WarnMapEntry {
  64. IntStack* Stack;
  65. const char* Name;
  66. };
  67. static WarnMapEntry WarnMap[] = {
  68. /* Keep sorted, even if this isn't used for now */
  69. { &WarningsAreErrors, "error" },
  70. { &WarnNoEffect, "no-effect" },
  71. { &WarnStructParam, "struct-param" },
  72. { &WarnUnknownPragma, "unknown-pragma" },
  73. { &WarnUnusedLabel, "unused-label" },
  74. { &WarnUnusedParam, "unused-param" },
  75. { &WarnUnusedVar, "unused-var" },
  76. };
  77. /*****************************************************************************/
  78. /* Handling of fatal errors */
  79. /*****************************************************************************/
  80. void Fatal (const char* Format, ...)
  81. /* Print a message about a fatal error and die */
  82. {
  83. va_list ap;
  84. const char* FileName;
  85. unsigned LineNum;
  86. if (CurTok.LI) {
  87. FileName = GetInputName (CurTok.LI);
  88. LineNum = GetInputLine (CurTok.LI);
  89. } else {
  90. FileName = GetCurrentFile ();
  91. LineNum = GetCurrentLine ();
  92. }
  93. fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum);
  94. va_start (ap, Format);
  95. vfprintf (stderr, Format, ap);
  96. va_end (ap);
  97. fprintf (stderr, "\n");
  98. if (Line) {
  99. Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
  100. }
  101. exit (EXIT_FAILURE);
  102. }
  103. void Internal (const char* Format, ...)
  104. /* Print a message about an internal compiler error and die. */
  105. {
  106. va_list ap;
  107. const char* FileName;
  108. unsigned LineNum;
  109. if (CurTok.LI) {
  110. FileName = GetInputName (CurTok.LI);
  111. LineNum = GetInputLine (CurTok.LI);
  112. } else {
  113. FileName = GetCurrentFile ();
  114. LineNum = GetCurrentLine ();
  115. }
  116. fprintf (stderr, "%s(%u): Internal compiler error:\n",
  117. FileName, LineNum);
  118. va_start (ap, Format);
  119. vfprintf (stderr, Format, ap);
  120. va_end (ap);
  121. fprintf (stderr, "\n");
  122. if (Line) {
  123. fprintf (stderr, "\nInput: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
  124. }
  125. /* Use abort to create a core dump */
  126. abort ();
  127. }
  128. /*****************************************************************************/
  129. /* Handling of errors */
  130. /*****************************************************************************/
  131. static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
  132. /* Print an error message - internal function*/
  133. {
  134. fprintf (stderr, "%s(%u): Error: ", Filename, LineNo);
  135. vfprintf (stderr, Msg, ap);
  136. fprintf (stderr, "\n");
  137. if (Line) {
  138. Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
  139. }
  140. ++ErrorCount;
  141. if (ErrorCount > 10) {
  142. Fatal ("Too many errors");
  143. }
  144. }
  145. void Error (const char* Format, ...)
  146. /* Print an error message */
  147. {
  148. va_list ap;
  149. va_start (ap, Format);
  150. IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
  151. va_end (ap);
  152. }
  153. void LIError (const LineInfo* LI, const char* Format, ...)
  154. /* Print an error message with the line info given explicitly */
  155. {
  156. va_list ap;
  157. va_start (ap, Format);
  158. IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
  159. va_end (ap);
  160. }
  161. void PPError (const char* Format, ...)
  162. /* Print an error message. For use within the preprocessor. */
  163. {
  164. va_list ap;
  165. va_start (ap, Format);
  166. IntError (GetCurrentFile(), GetCurrentLine(), Format, ap);
  167. va_end (ap);
  168. }
  169. /*****************************************************************************/
  170. /* Handling of warnings */
  171. /*****************************************************************************/
  172. static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
  173. /* Print warning message - internal function. */
  174. {
  175. if (IS_Get (&WarningsAreErrors)) {
  176. /* Treat the warning as an error */
  177. IntError (Filename, LineNo, Msg, ap);
  178. } else if (IS_Get (&WarnEnable)) {
  179. fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo);
  180. vfprintf (stderr, Msg, ap);
  181. fprintf (stderr, "\n");
  182. if (Line) {
  183. Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
  184. }
  185. ++WarningCount;
  186. }
  187. }
  188. void Warning (const char* Format, ...)
  189. /* Print warning message. */
  190. {
  191. va_list ap;
  192. va_start (ap, Format);
  193. IntWarning (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
  194. va_end (ap);
  195. }
  196. void LIWarning (const LineInfo* LI, const char* Format, ...)
  197. /* Print a warning message with the line info given explicitly */
  198. {
  199. va_list ap;
  200. va_start (ap, Format);
  201. IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
  202. va_end (ap);
  203. }
  204. void PPWarning (const char* Format, ...)
  205. /* Print warning message. For use within the preprocessor. */
  206. {
  207. va_list ap;
  208. va_start (ap, Format);
  209. IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
  210. va_end (ap);
  211. }
  212. IntStack* FindWarning (const char* Name)
  213. /* Search for a warning in the WarnMap table and return a pointer to the
  214. * intstack that holds its state. Return NULL if there is no such warning.
  215. */
  216. {
  217. unsigned I;
  218. /* For now, do a linear search */
  219. for (I = 0; I < sizeof(WarnMap) / sizeof (WarnMap[0]); ++I) {
  220. if (strcmp (WarnMap[I].Name, Name) == 0) {
  221. return WarnMap[I].Stack;
  222. }
  223. }
  224. return 0;
  225. }
  226. /*****************************************************************************/
  227. /* Code */
  228. /*****************************************************************************/
  229. void ErrorReport (void)
  230. /* Report errors (called at end of compile) */
  231. {
  232. Print (stdout, 1, "%u errors, %u warnings\n", ErrorCount, WarningCount);
  233. }