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