PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/cc65/error.c

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