error.c 3.8 KB

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