error.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /* $Header$ */
  2. /* 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 */
  3. #include <system.h>
  4. #include <em.h>
  5. #include "nopp.h"
  6. #include "use_tmp.h"
  7. #include "errout.h"
  8. #include "debug.h"
  9. #include "tokenname.h"
  10. #include "arith.h"
  11. #include "label.h"
  12. #include "expr.h"
  13. #include "LLlex.h"
  14. /* This file contains the (non-portable) error-message and diagnostic
  15. functions. Beware, they are called with a variable number of
  16. arguments!
  17. */
  18. /* error classes */
  19. #define ERROR 1
  20. #define WARNING 2
  21. #define LEXERROR 3
  22. #define LEXWARNING 4
  23. #define CRASH 5
  24. #define FATAL 6
  25. int err_occurred;
  26. extern char *symbol2str();
  27. extern char options[];
  28. /* There are three general error-message functions:
  29. lexerror() lexical and pre-processor error messages
  30. error() syntactic and semantic error messages
  31. expr_error() errors in expressions
  32. The difference lies in the place where the file name and line
  33. number come from.
  34. Lexical errors report from the global variables LineNumber and
  35. FileName, expression errors get their information from the
  36. expression, whereas other errors use the information in the token.
  37. */
  38. /*VARARGS1*/
  39. error(fmt, args)
  40. char *fmt;
  41. {
  42. _error(ERROR, NILEXPR, fmt, &args);
  43. }
  44. /*VARARGS2*/
  45. expr_error(expr, fmt, args)
  46. struct expr *expr;
  47. char *fmt;
  48. {
  49. _error(ERROR, expr, fmt, &args);
  50. }
  51. /*VARARGS1*/
  52. warning(fmt, args)
  53. char *fmt;
  54. {
  55. _error(WARNING, NILEXPR, fmt, &args);
  56. }
  57. /*VARARGS2*/
  58. expr_warning(expr, fmt, args)
  59. struct expr *expr;
  60. char *fmt;
  61. {
  62. _error(WARNING, expr, fmt, &args);
  63. }
  64. /*VARARGS1*/
  65. lexerror(fmt, args)
  66. char *fmt;
  67. {
  68. _error(LEXERROR, NILEXPR, fmt, &args);
  69. }
  70. #ifndef NOPP
  71. /*VARARGS1*/
  72. lexwarning(fmt, args) char *fmt; {
  73. _error(LEXWARNING, NILEXPR, fmt, &args);
  74. }
  75. #endif NOPP
  76. /*VARARGS1*/
  77. crash(fmt, args)
  78. char *fmt;
  79. int args;
  80. {
  81. _error(CRASH, NILEXPR, fmt, &args);
  82. C_close();
  83. #ifdef DEBUG
  84. sys_stop(S_ABORT);
  85. #else DEBUG
  86. sys_stop(S_EXIT);
  87. #endif DEBUG
  88. }
  89. /*VARARGS1*/
  90. fatal(fmt, args)
  91. char *fmt;
  92. int args;
  93. {
  94. #ifdef USE_TMP
  95. extern char *tmpfile; /* main.c */
  96. if (tmpfile)
  97. sys_remove(tmpfile); /* may not successful! */
  98. #endif USE_TMP
  99. _error(FATAL, NILEXPR, fmt, &args);
  100. sys_stop(S_EXIT);
  101. }
  102. _error(class, expr, fmt, argv)
  103. int class;
  104. struct expr *expr;
  105. char *fmt;
  106. int argv[];
  107. {
  108. /* _error attempts to limit the number of error messages
  109. for a given line to MAXERR_LINE.
  110. */
  111. static char *last_fn = 0;
  112. static unsigned int last_ln = 0;
  113. static int e_seen = 0;
  114. char *fn = 0;
  115. unsigned int ln = 0;
  116. char *remark = 0;
  117. /* Since name and number are gathered from different places
  118. depending on the class, we first collect the relevant
  119. values and then decide what to print.
  120. */
  121. /* preliminaries */
  122. switch (class) {
  123. case ERROR:
  124. case LEXERROR:
  125. case CRASH:
  126. case FATAL:
  127. if (C_busy())
  128. C_ms_err();
  129. err_occurred = 1;
  130. break;
  131. case WARNING:
  132. case LEXWARNING:
  133. if (options['w'])
  134. return;
  135. break;
  136. }
  137. /* the remark */
  138. switch (class) {
  139. case WARNING:
  140. case LEXWARNING:
  141. remark = "(warning)";
  142. break;
  143. case CRASH:
  144. remark = "CRASH\007";
  145. break;
  146. case FATAL:
  147. remark = "fatal error --";
  148. break;
  149. }
  150. /* the place */
  151. switch (class) {
  152. case WARNING:
  153. case ERROR:
  154. fn = expr ? expr->ex_file : dot.tk_file;
  155. ln = expr ? expr->ex_line : dot.tk_line;
  156. break;
  157. case LEXWARNING:
  158. case LEXERROR:
  159. case CRASH:
  160. case FATAL:
  161. fn = FileName;
  162. ln = LineNumber;
  163. break;
  164. }
  165. if (ln == last_ln && fn && last_fn && strcmp(fn, last_fn) == 0) {
  166. /* we've seen this place before */
  167. e_seen++;
  168. if (e_seen == MAXERR_LINE)
  169. fmt = "etc ...";
  170. else
  171. if (e_seen > MAXERR_LINE)
  172. /* and too often, I'd say ! */
  173. return;
  174. }
  175. else {
  176. /* brand new place */
  177. last_fn = fn;
  178. last_ln = ln;
  179. e_seen = 0;
  180. }
  181. if (fn)
  182. fprintf(ERROUT, "\"%s\", line %u: ", fn, ln);
  183. if (remark)
  184. fprintf(ERROUT, "%s ", remark);
  185. doprnt(ERROUT, fmt, argv); /* contents of error */
  186. fprintf(ERROUT, "\n");
  187. }