error.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. *
  5. * Author: Ceriel J.H. Jacobs
  6. */
  7. /* E R R O R A N D D I A G N O S T I C R O U T I N E S */
  8. /* $Id$ */
  9. /* This file contains the (non-portable) error-message and diagnostic
  10. giving functions. Be aware that they are called with a variable
  11. number of arguments!
  12. */
  13. #include "errout.h"
  14. #include "debug.h"
  15. #if __STDC__
  16. #include <stdarg.h>
  17. #else
  18. #include <varargs.h>
  19. #endif
  20. #include <system.h>
  21. #include <em_arith.h>
  22. #include <em_label.h>
  23. #include <em_code.h>
  24. #include "strict3rd.h"
  25. #include "input.h"
  26. #include "f_info.h"
  27. #include "LLlex.h"
  28. #include "main.h"
  29. #include "node.h"
  30. #include "warning.h"
  31. #include "nostrict.h"
  32. /* error classes */
  33. #define ERROR 1
  34. #define WARNING 2
  35. #define LEXERROR 3
  36. #define LEXWARNING 4
  37. #define CRASH 5
  38. #define FATAL 6
  39. #ifdef DEBUG
  40. #define VDEBUG 7
  41. #endif
  42. int err_occurred;
  43. extern char *symbol2str();
  44. /* There are three general error-message functions:
  45. lexerror() lexical and pre-processor error messages
  46. error() syntactic and semantic error messages
  47. node_error() errors in nodes
  48. The difference lies in the place where the file name and line
  49. number come from.
  50. Lexical errors report from the global variables LineNumber and
  51. FileName, node errors get their information from the
  52. node, whereas other errors use the information in the token.
  53. */
  54. #if __STDC__
  55. #ifdef DEBUG
  56. /*VARARGS*/
  57. debug(char *fmt, ...)
  58. {
  59. va_list ap;
  60. va_start(ap, fmt);
  61. {
  62. _error(VDEBUG, NULLNODE, ap, 0);
  63. }
  64. va_end(ap);
  65. }
  66. #endif /* DEBUG */
  67. /*VARARGS*/
  68. error(char *fmt, ...)
  69. {
  70. va_list ap;
  71. va_start(ap, fmt);
  72. {
  73. _error(ERROR, NULLNODE, fmt, ap, 0);
  74. }
  75. va_end(ap);
  76. }
  77. /*VARARGS*/
  78. node_error(t_node *node, char *fmt, ...)
  79. {
  80. va_list ap;
  81. va_start(ap, fmt);
  82. {
  83. _error(ERROR, node, fmt, ap, 0);
  84. }
  85. va_end(ap);
  86. }
  87. /*VARARGS*/
  88. warning(int class, char *fmt, ...)
  89. {
  90. va_list ap;
  91. va_start(ap, fmt);
  92. {
  93. _error(WARNING, NULLNODE, fmt, ap, class);
  94. }
  95. va_end(ap);
  96. }
  97. /*VARARGS*/
  98. node_warning(t_node *node, int class, char *fmt, ...)
  99. {
  100. va_list ap;
  101. va_start(ap, fmt);
  102. {
  103. _error(WARNING, node, fmt, ap, class);
  104. }
  105. va_end(ap);
  106. }
  107. /*VARARGS*/
  108. lexerror(char *fmt, ...)
  109. {
  110. va_list ap;
  111. va_start(ap, fmt);
  112. {
  113. _error(LEXERROR, NULLNODE, fmt, ap, 0);
  114. }
  115. va_end(ap);
  116. }
  117. /*VARARGS*/
  118. lexwarning(int class, char *fmt, ...)
  119. {
  120. va_list ap;
  121. va_start(ap, fmt);
  122. {
  123. _error(LEXWARNING, NULLNODE, fmt, ap, class);
  124. }
  125. va_end(ap);
  126. }
  127. /*VARARGS*/
  128. fatal(char *fmt, ...)
  129. {
  130. va_list ap;
  131. va_start(ap, fmt);
  132. {
  133. _error(FATAL, NULLNODE, fmt, ap, 0);
  134. }
  135. va_end(ap);
  136. sys_stop(S_EXIT);
  137. }
  138. /*VARARGS*/
  139. crash(char *fmt, ...)
  140. {
  141. va_list ap;
  142. va_start(ap, fmt);
  143. {
  144. _error(CRASH, NULLNODE, fmt, ap, 0);
  145. }
  146. va_end(ap);
  147. #ifdef DEBUG
  148. sys_stop(S_ABORT);
  149. #else
  150. sys_stop(S_EXIT);
  151. #endif
  152. }
  153. #else
  154. #ifdef DEBUG
  155. /*VARARGS*/
  156. debug(va_alist)
  157. va_dcl
  158. {
  159. va_list ap;
  160. va_start(ap);
  161. {
  162. char *fmt = va_arg(ap, char *);
  163. _error(VDEBUG, NULLNODE, fmt, ap, 0);
  164. }
  165. va_end(ap);
  166. }
  167. #endif /* DEBUG */
  168. /*VARARGS*/
  169. error(va_alist)
  170. va_dcl
  171. {
  172. va_list ap;
  173. va_start(ap);
  174. {
  175. char *fmt = va_arg(ap, char *);
  176. _error(ERROR, NULLNODE, fmt, ap, 0);
  177. }
  178. va_end(ap);
  179. }
  180. /*VARARGS*/
  181. node_error(va_alist)
  182. va_dcl
  183. {
  184. va_list ap;
  185. va_start(ap);
  186. {
  187. t_node *node = va_arg(ap, t_node *);
  188. char *fmt = va_arg(ap, char *);
  189. _error(ERROR, node, fmt, ap, 0);
  190. }
  191. va_end(ap);
  192. }
  193. /*VARARGS*/
  194. warning(va_alist)
  195. va_dcl
  196. {
  197. va_list ap;
  198. va_start(ap);
  199. {
  200. int class = va_arg(ap, int);
  201. char *fmt = va_arg(ap, char *);
  202. _error(WARNING, NULLNODE, fmt, ap, class);
  203. }
  204. va_end(ap);
  205. }
  206. /*VARARGS*/
  207. node_warning(va_alist)
  208. va_dcl
  209. {
  210. va_list ap;
  211. va_start(ap);
  212. {
  213. t_node *nd = va_arg(ap, t_node *);
  214. int class = va_arg(ap, int);
  215. char *fmt = va_arg(ap, char *);
  216. _error(WARNING, nd, fmt, ap, class);
  217. }
  218. va_end(ap);
  219. }
  220. /*VARARGS*/
  221. lexerror(va_alist)
  222. va_dcl
  223. {
  224. va_list ap;
  225. va_start(ap);
  226. {
  227. char *fmt = va_arg(ap, char *);
  228. _error(LEXERROR, NULLNODE, fmt, ap, 0);
  229. }
  230. va_end(ap);
  231. }
  232. /*VARARGS*/
  233. lexwarning(va_alist)
  234. va_dcl
  235. {
  236. va_list ap;
  237. va_start(ap);
  238. {
  239. int class = va_arg(ap, int);
  240. char *fmt = va_arg(ap, char *);
  241. _error(LEXWARNING, NULLNODE, fmt, ap, class);
  242. }
  243. va_end(ap);
  244. }
  245. /*VARARGS*/
  246. fatal(va_alist)
  247. va_dcl
  248. {
  249. va_list ap;
  250. va_start(ap);
  251. {
  252. char *fmt = va_arg(ap, char *);
  253. _error(FATAL, NULLNODE, fmt, ap, 0);
  254. }
  255. va_end(ap);
  256. sys_stop(S_EXIT);
  257. }
  258. /*VARARGS*/
  259. crash(va_alist)
  260. va_dcl
  261. {
  262. va_list ap;
  263. va_start(ap);
  264. {
  265. char *fmt = va_arg(ap, char *);
  266. _error(CRASH, NULLNODE, fmt, ap, 0);
  267. }
  268. va_end(ap);
  269. #ifdef DEBUG
  270. sys_stop(S_ABORT);
  271. #else
  272. sys_stop(S_EXIT);
  273. #endif
  274. }
  275. #endif
  276. _error(class, node, fmt, ap, warn_class)
  277. int class;
  278. t_node *node;
  279. char *fmt;
  280. register va_list ap;
  281. int warn_class;
  282. {
  283. /* _error attempts to limit the number of error messages
  284. for a given line to MAXERR_LINE.
  285. */
  286. unsigned int ln = 0;
  287. register char *remark = 0;
  288. /* check visibility of message */
  289. if (class == ERROR || class == WARNING) {
  290. if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
  291. /* warning or error message overshadowed */
  292. return;
  293. }
  294. /* Since name and number are gathered from different places
  295. depending on the class, we first collect the relevant
  296. values and then decide what to print.
  297. */
  298. /* preliminaries */
  299. switch (class) {
  300. case ERROR:
  301. case LEXERROR:
  302. case CRASH:
  303. case FATAL:
  304. if (C_busy()) C_ms_err();
  305. err_occurred = 1;
  306. break;
  307. }
  308. /* the remark */
  309. switch (class) {
  310. case WARNING:
  311. case LEXWARNING:
  312. if (! (warn_class & warning_classes)) return;
  313. switch(warn_class) {
  314. #ifndef STRICT_3RD_ED
  315. case W_OLDFASHIONED:
  316. remark = "(old-fashioned use)";
  317. break;
  318. #endif
  319. #ifndef NOSTRICT
  320. case W_STRICT:
  321. remark = "(strict)";
  322. break;
  323. #endif
  324. default:
  325. remark = "(warning)";
  326. break;
  327. }
  328. break;
  329. case CRASH:
  330. remark = "CRASH\007";
  331. break;
  332. case FATAL:
  333. remark = "fatal error --";
  334. break;
  335. #ifdef DEBUG
  336. case VDEBUG:
  337. remark = "(debug)";
  338. break;
  339. #endif /* DEBUG */
  340. }
  341. /* the place */
  342. switch (class) {
  343. case WARNING:
  344. case ERROR:
  345. ln = node ? node->nd_lineno : dot.tk_lineno;
  346. break;
  347. case LEXWARNING:
  348. case LEXERROR:
  349. case CRASH:
  350. case FATAL:
  351. #ifdef DEBUG
  352. case VDEBUG:
  353. #endif /* DEBUG */
  354. ln = LineNumber;
  355. break;
  356. }
  357. if (FileName) fprint(ERROUT, "\"%s\", line %u: ", FileName, ln);
  358. if (remark) fprint(ERROUT, "%s ", remark);
  359. doprnt(ERROUT, fmt, ap); /* contents of error */
  360. fprint(ERROUT, "\n");
  361. }