error.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. /* stripped down version from the one in the Modula-2 compiler */
  9. /* $Id$ */
  10. /* This file contains the error-message and diagnostic
  11. giving functions. Be aware that they are called with a variable
  12. number of arguments!
  13. */
  14. #if __STDC__
  15. #include <stdarg.h>
  16. #else
  17. #include <varargs.h>
  18. #endif
  19. #include <system.h>
  20. #include "input.h"
  21. #include "f_info.h"
  22. #include "LLlex.h"
  23. /* error classes */
  24. #define ERROR 1
  25. #define LEXERROR 3
  26. #define CRASH 5
  27. #define FATAL 6
  28. int err_occurred;
  29. extern char *symbol2str();
  30. /* There are three general error-message functions:
  31. lexerror() lexical and pre-processor error messages
  32. error() syntactic and semantic error messages
  33. node_error() errors in nodes
  34. The difference lies in the place where the file name and line
  35. number come from.
  36. Lexical errors report from the global variables LineNumber and
  37. FileName, node errors get their information from the
  38. node, whereas other errors use the information in the token.
  39. */
  40. #if __STDC__
  41. /*VARARGS1*/
  42. error(char *fmt, ...)
  43. {
  44. va_list ap;
  45. va_start(ap, fmt);
  46. _error(ERROR, fmt, ap);
  47. va_end(ap);
  48. }
  49. /*VARARGS1*/
  50. Gerror(char *fmt, ...)
  51. {
  52. va_list ap;
  53. char *fn = FileName;
  54. FileName = 0;
  55. va_start(ap, fmt);
  56. _error(ERROR, fmt, ap);
  57. va_end(ap);
  58. FileName = fn;
  59. }
  60. /*VARARGS1*/
  61. lexerror(char *fmt, ...)
  62. {
  63. va_list ap;
  64. va_start(ap, fmt);
  65. _error(LEXERROR, fmt, ap);
  66. va_end(ap);
  67. }
  68. /*VARARGS1*/
  69. fatal(char *fmt, ...)
  70. {
  71. va_list ap;
  72. va_start(ap, fmt);
  73. _error(FATAL, fmt, ap);
  74. va_end(ap);
  75. sys_stop(S_EXIT);
  76. }
  77. /*VARARGS1*/
  78. crash(char *fmt, ...)
  79. {
  80. va_list ap;
  81. va_start(ap, fmt);
  82. _error(CRASH, fmt, ap);
  83. va_end(ap);
  84. #ifdef DEBUG
  85. sys_stop(S_ABORT);
  86. #else
  87. sys_stop(S_EXIT);
  88. #endif
  89. }
  90. #else
  91. /*VARARGS1*/
  92. error(va_alist)
  93. va_dcl
  94. {
  95. va_list ap;
  96. char *fmt;
  97. va_start(ap);
  98. fmt = va_arg(ap, char *);
  99. _error(ERROR, fmt, ap);
  100. va_end(ap);
  101. }
  102. /*VARARGS1*/
  103. Gerror(va_alist)
  104. va_dcl
  105. {
  106. va_list ap;
  107. char *fmt;
  108. char *fn = FileName;
  109. FileName = 0;
  110. va_start(ap);
  111. fmt = va_arg(ap, char *);
  112. _error(ERROR, fmt, ap);
  113. va_end(ap);
  114. FileName = fn;
  115. }
  116. /*VARARGS1*/
  117. lexerror(va_alist)
  118. va_dcl
  119. {
  120. va_list ap;
  121. char *fmt;
  122. va_start(ap);
  123. fmt = va_arg(ap, char *);
  124. _error(LEXERROR, fmt, ap);
  125. va_end(ap);
  126. }
  127. /*VARARGS1*/
  128. fatal(va_alist)
  129. va_dcl
  130. {
  131. va_list ap;
  132. char *fmt;
  133. va_start(ap);
  134. fmt = va_arg(ap, char *);
  135. _error(FATAL, fmt, ap);
  136. va_end(ap);
  137. sys_stop(S_EXIT);
  138. }
  139. /*VARARGS1*/
  140. crash(va_alist)
  141. va_dcl
  142. {
  143. va_list ap;
  144. char *fmt;
  145. va_start(ap);
  146. fmt = va_arg(ap, char *);
  147. _error(CRASH, fmt, ap);
  148. va_end(ap);
  149. #ifdef DEBUG
  150. sys_stop(S_ABORT);
  151. #else
  152. sys_stop(S_EXIT);
  153. #endif
  154. }
  155. #endif
  156. _error(class, fmt, argv)
  157. int class;
  158. char *fmt;
  159. va_list argv;
  160. {
  161. /* _error attempts to limit the number of error messages
  162. for a given line to MAXERR_LINE.
  163. */
  164. unsigned int ln = 0;
  165. register char *remark = 0;
  166. /* Since name and number are gathered from different places
  167. depending on the class, we first collect the relevant
  168. values and then decide what to print.
  169. */
  170. /* preliminaries */
  171. switch (class) {
  172. case ERROR:
  173. case LEXERROR:
  174. case CRASH:
  175. case FATAL:
  176. err_occurred = 1;
  177. break;
  178. }
  179. /* the remark */
  180. switch (class) {
  181. case CRASH:
  182. remark = "CRASH\007";
  183. break;
  184. case FATAL:
  185. remark = "fatal error --";
  186. break;
  187. }
  188. /* the place */
  189. switch (class) {
  190. case ERROR:
  191. ln = dot.tk_lineno;
  192. break;
  193. case LEXERROR:
  194. case CRASH:
  195. case FATAL:
  196. ln = LineNumber;
  197. break;
  198. }
  199. if (FileName) fprint(STDERR, "\"%s\", line %u: ", FileName, ln);
  200. if (remark) fprint(STDERR, "%s ", remark);
  201. doprnt(STDERR, fmt, argv); /* contents of error */
  202. fprint(STDERR, "\n");
  203. }