error.c 9.5 KB

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