error.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  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. /* $Id$ */
  6. /* 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 */
  7. #include "lint.h"
  8. #if __STDC__
  9. #include <stdarg.h>
  10. #else
  11. #include <varargs.h>
  12. #endif
  13. #include <system.h>
  14. #ifndef LINT
  15. #include <em.h>
  16. #else
  17. #include "l_em.h"
  18. #endif /* LINT */
  19. #include "nopp.h"
  20. #include "errout.h"
  21. #include "debug.h"
  22. #include "tokenname.h"
  23. #include "arith.h"
  24. #include "label.h"
  25. #include "expr.h"
  26. #include "def.h"
  27. #include "LLlex.h"
  28. /* This file contains the error-message and diagnostic
  29. functions. Beware, they are called with a variable number of
  30. arguments!
  31. */
  32. /* error classes */
  33. #define WARNING 1
  34. #define ERROR 2
  35. #define CRASH 3
  36. #define FATAL 4
  37. int err_occurred = 0;
  38. extern char options[];
  39. #ifdef LINT
  40. extern char loptions[];
  41. #endif /* LINT */
  42. /* There are three general error-message functions:
  43. lexerror() lexical and pre-processor error messages
  44. error() syntactic and semantic error messages
  45. expr_error() errors in expressions
  46. The difference lies in the place where the file name and line
  47. number come from.
  48. Lexical errors report from the global variables LineNumber and
  49. FileName, expression errors get their information from the
  50. expression, whereas other errors use the information in the token.
  51. */
  52. static _error();
  53. #if __STDC__
  54. /*VARARGS*/
  55. error(char *fmt, ...)
  56. {
  57. va_list ap;
  58. va_start(ap, fmt);
  59. {
  60. _error(ERROR, dot.tk_file, dot.tk_line, fmt, ap);
  61. }
  62. va_end(ap);
  63. }
  64. /*VARARGS*/
  65. expr_error(struct expr *expr, char *fmt, ...)
  66. {
  67. va_list ap;
  68. va_start(ap, fmt);
  69. {
  70. if (!(expr->ex_flags & EX_ERROR)) {
  71. /* to prevent proliferation */
  72. _error(ERROR, expr->ex_file, expr->ex_line, fmt, ap);
  73. expr->ex_flags |= EX_ERROR;
  74. }
  75. }
  76. va_end(ap);
  77. }
  78. /*VARARGS*/
  79. warning(char *fmt, ...)
  80. {
  81. va_list ap;
  82. va_start(ap, fmt);
  83. {
  84. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  85. }
  86. va_end(ap);
  87. }
  88. /*VARARGS*/
  89. expr_warning(struct expr *expr, char *fmt, ...)
  90. {
  91. va_list ap;
  92. va_start(ap, fmt);
  93. {
  94. if (!(expr->ex_flags & EX_ERROR)) {
  95. /* to prevent proliferation */
  96. _error(WARNING, expr->ex_file, expr->ex_line, fmt, ap);
  97. }
  98. }
  99. va_end(ap);
  100. }
  101. #ifdef LINT
  102. /*VARARGS*/
  103. def_warning(struct def *def, char *fmt, ...)
  104. {
  105. va_list ap;
  106. va_start(ap, fmt);
  107. {
  108. _error(WARNING, def->df_file, def->df_line, fmt, ap);
  109. }
  110. va_end(ap);
  111. }
  112. /*VARARGS*/
  113. hwarning(char *fmt, ...)
  114. {
  115. va_list ap;
  116. va_start(ap, fmt);
  117. {
  118. if (loptions['h'])
  119. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  120. }
  121. va_end(ap);
  122. }
  123. /*VARARGS*/
  124. awarning(char *fmt, ...)
  125. {
  126. va_list ap;
  127. va_start(ap, fmt);
  128. {
  129. if (loptions['a'])
  130. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  131. }
  132. va_end(ap);
  133. }
  134. #endif /* LINT */
  135. /*VARARGS*/
  136. lexerror(char *fmt, ...)
  137. {
  138. va_list ap;
  139. va_start(ap, fmt);
  140. {
  141. _error(ERROR, FileName, LineNumber, fmt, ap);
  142. }
  143. va_end(ap);
  144. }
  145. #ifndef NOPP
  146. /*VARARGS*/
  147. lexwarning(char *fmt, ...)
  148. {
  149. va_list ap;
  150. va_start(ap, fmt);
  151. {
  152. _error(WARNING, FileName, LineNumber, fmt, ap);
  153. }
  154. va_end(ap);
  155. }
  156. #endif /* NOPP */
  157. /*VARARGS*/
  158. crash(char *fmt, ...)
  159. {
  160. va_list ap;
  161. va_start(ap, fmt);
  162. {
  163. _error(CRASH, FileName, LineNumber, fmt, ap);
  164. }
  165. va_end(ap);
  166. C_close();
  167. #ifdef DEBUG
  168. sys_stop(S_ABORT);
  169. #else /* DEBUG */
  170. sys_stop(S_EXIT);
  171. #endif /* DEBUG */
  172. /* NOTREACHED */
  173. }
  174. /*VARARGS*/
  175. fatal(char *fmt, ...)
  176. {
  177. va_list ap;
  178. va_start(ap, fmt);
  179. {
  180. _error(FATAL, FileName, LineNumber, fmt, ap);
  181. }
  182. va_end(ap);
  183. if (C_busy()) C_close();
  184. sys_stop(S_EXIT);
  185. /*NOTREACHED*/
  186. }
  187. #else
  188. /*VARARGS*/
  189. error(va_alist) /* fmt, args */
  190. va_dcl
  191. {
  192. va_list ap;
  193. va_start(ap);
  194. {
  195. char *fmt = va_arg(ap, char *);
  196. _error(ERROR, dot.tk_file, dot.tk_line, fmt, ap);
  197. }
  198. va_end(ap);
  199. }
  200. /*VARARGS*/
  201. expr_error(va_alist) /* expr, fmt, args */
  202. va_dcl
  203. {
  204. va_list ap;
  205. va_start(ap);
  206. {
  207. register struct expr *expr = va_arg(ap, struct expr *);
  208. char *fmt = va_arg(ap, char *);
  209. if (!(expr->ex_flags & EX_ERROR)) {
  210. /* to prevent proliferation */
  211. _error(ERROR, expr->ex_file, expr->ex_line, fmt, ap);
  212. expr->ex_flags |= EX_ERROR;
  213. }
  214. }
  215. va_end(ap);
  216. }
  217. /*VARARGS*/
  218. warning(va_alist) /* fmt, args */
  219. va_dcl
  220. {
  221. va_list ap;
  222. va_start(ap);
  223. {
  224. char *fmt = va_arg(ap, char *);
  225. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  226. }
  227. va_end(ap);
  228. }
  229. /*VARARGS*/
  230. expr_warning(va_alist) /* expr, fmt, args */
  231. va_dcl
  232. {
  233. va_list ap;
  234. va_start(ap);
  235. {
  236. struct expr *expr = va_arg(ap, struct expr *);
  237. char *fmt = va_arg(ap, char *);
  238. if (!(expr->ex_flags & EX_ERROR)) {
  239. /* to prevent proliferation */
  240. _error(WARNING, expr->ex_file, expr->ex_line, fmt, ap);
  241. }
  242. }
  243. va_end(ap);
  244. }
  245. #ifdef LINT
  246. /*VARARGS*/
  247. def_warning(va_alist) /* def, fmt, args */
  248. va_dcl
  249. {
  250. va_list ap;
  251. va_start(ap);
  252. {
  253. register struct def *def = va_arg(ap, struct def *);
  254. char *fmt = va_arg(ap, char *);
  255. _error(WARNING, def->df_file, def->df_line, fmt, ap);
  256. }
  257. va_end(ap);
  258. }
  259. /*VARARGS*/
  260. hwarning(va_alist) /* fmt, args */
  261. va_dcl
  262. {
  263. va_list ap;
  264. va_start(ap);
  265. {
  266. char *fmt = va_arg(ap, char *);
  267. if (loptions['h'])
  268. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  269. }
  270. va_end(ap);
  271. }
  272. /*VARARGS*/
  273. awarning(va_alist) /* fmt, args */
  274. va_dcl
  275. {
  276. va_list ap;
  277. va_start(ap);
  278. {
  279. char *fmt = va_arg(ap, char *);
  280. if (loptions['a'])
  281. _error(WARNING, dot.tk_file, dot.tk_line, fmt, ap);
  282. }
  283. va_end(ap);
  284. }
  285. #endif /* LINT */
  286. /*VARARGS*/
  287. lexerror(va_alist) /* fmt, args */
  288. va_dcl
  289. {
  290. va_list ap;
  291. va_start(ap);
  292. {
  293. char *fmt = va_arg(ap, char *);
  294. _error(ERROR, FileName, LineNumber, fmt, ap);
  295. }
  296. va_end(ap);
  297. }
  298. #ifndef NOPP
  299. /*VARARGS*/
  300. lexwarning(va_alist) /* fmt, args */
  301. va_dcl
  302. {
  303. va_list ap;
  304. va_start(ap);
  305. {
  306. char *fmt = va_arg(ap, char *);
  307. _error(WARNING, FileName, LineNumber, fmt, ap);
  308. }
  309. va_end(ap);
  310. }
  311. #endif /* NOPP */
  312. /*VARARGS*/
  313. crash(va_alist) /* fmt, args */
  314. va_dcl
  315. {
  316. va_list ap;
  317. va_start(ap);
  318. {
  319. char *fmt = va_arg(ap, char *);
  320. _error(CRASH, FileName, LineNumber, fmt, ap);
  321. }
  322. va_end(ap);
  323. C_close();
  324. #ifdef DEBUG
  325. sys_stop(S_ABORT);
  326. #else /* DEBUG */
  327. sys_stop(S_EXIT);
  328. #endif /* DEBUG */
  329. /* NOTREACHED */
  330. }
  331. /*VARARGS*/
  332. fatal(va_alist) /* fmt, args */
  333. va_dcl
  334. {
  335. va_list ap;
  336. va_start(ap);
  337. {
  338. char *fmt = va_arg(ap, char *);
  339. _error(FATAL, FileName, LineNumber, fmt, ap);
  340. }
  341. va_end(ap);
  342. if (C_busy()) C_close();
  343. sys_stop(S_EXIT);
  344. /*NOTREACHED*/
  345. }
  346. #endif
  347. static
  348. _error(class, fn, ln, fmt, ap)
  349. int class;
  350. char *fn;
  351. unsigned int ln;
  352. char *fmt;
  353. va_list ap;
  354. {
  355. char *remark;
  356. /* check visibility of message */
  357. switch (class) {
  358. case WARNING:
  359. case ERROR:
  360. if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
  361. /* warning or error message overshadowed */
  362. return;
  363. break;
  364. }
  365. /* Since name and number are gathered from different places
  366. depending on the class, we first collect the relevant
  367. values and then decide what to print.
  368. */
  369. /* preliminaries */
  370. switch (class) {
  371. case WARNING:
  372. if (options['w'])
  373. return;
  374. break;
  375. case ERROR:
  376. case CRASH:
  377. case FATAL:
  378. if (C_busy())
  379. C_ms_err();
  380. err_occurred = 1;
  381. break;
  382. }
  383. /* the remark */
  384. switch (class) {
  385. case WARNING:
  386. #ifndef LINT
  387. remark = "(warning)";
  388. #else /* LINT */
  389. remark = 0;
  390. #endif /* LINT */
  391. break;
  392. case ERROR:
  393. remark = 0;
  394. break;
  395. case CRASH:
  396. remark = "CRASH\007";
  397. break;
  398. case FATAL:
  399. remark = "fatal error --";
  400. break;
  401. default:
  402. /*NOTREACHED*/;
  403. }
  404. #ifdef LINT
  405. if ( /* there is a file name */
  406. fn
  407. && /* the file name is global */
  408. fn[0] == '/'
  409. && /* it is not a .c file */
  410. strcmp(&fn[strlen(fn)-2], ".c") != 0
  411. ) {
  412. /* we skip this message */
  413. return;
  414. }
  415. #endif /* LINT */
  416. if (fn)
  417. fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
  418. if (remark)
  419. fprint(ERROUT, "%s ", remark);
  420. doprnt(ERROUT, fmt, ap); /* contents of error */
  421. fprint(ERROUT, "\n");
  422. }