ack/lang/m2/comp/error.c

303 lines
4.7 KiB
C
Raw Normal View History

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
* Author: Ceriel J.H. Jacobs
*/
1986-03-26 15:11:02 +00:00
/* 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 */
1986-03-20 14:52:03 +00:00
/* $Header$ */
1986-03-20 14:52:03 +00:00
/* This file contains the (non-portable) error-message and diagnostic
giving functions. Be aware that they are called with a variable
number of arguments!
*/
1986-04-17 09:28:09 +00:00
#include "errout.h"
1986-04-18 17:53:47 +00:00
#include "debug.h"
1986-04-17 09:28:09 +00:00
1988-04-15 15:19:27 +00:00
#include <varargs.h>
1986-05-01 19:06:53 +00:00
#include <system.h>
#include <em_arith.h>
#include <em_label.h>
#include <em_code.h>
1986-05-01 19:06:53 +00:00
#include "strict3rd.h"
1986-03-20 14:52:03 +00:00
#include "input.h"
#include "f_info.h"
#include "LLlex.h"
1986-04-03 17:41:26 +00:00
#include "main.h"
1986-04-06 17:42:56 +00:00
#include "node.h"
1986-11-05 14:33:00 +00:00
#include "warning.h"
1987-11-09 16:11:04 +00:00
#include "nostrict.h"
1986-03-20 14:52:03 +00:00
1986-03-26 15:11:02 +00:00
/* error classes */
1986-03-20 14:52:03 +00:00
#define ERROR 1
#define WARNING 2
#define LEXERROR 3
#define LEXWARNING 4
#define CRASH 5
#define FATAL 6
1986-03-26 15:11:02 +00:00
#ifdef DEBUG
#define VDEBUG 7
#endif
1986-03-20 14:52:03 +00:00
int err_occurred;
1986-03-26 15:11:02 +00:00
extern char *symbol2str();
1986-03-20 14:52:03 +00:00
1986-03-26 15:11:02 +00:00
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
error() syntactic and semantic error messages
1986-04-06 17:42:56 +00:00
node_error() errors in nodes
1986-03-26 15:11:02 +00:00
The difference lies in the place where the file name and line
number come from.
Lexical errors report from the global variables LineNumber and
1986-04-06 17:42:56 +00:00
FileName, node errors get their information from the
node, whereas other errors use the information in the token.
1986-03-20 14:52:03 +00:00
*/
1986-03-26 15:11:02 +00:00
#ifdef DEBUG
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
debug(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(VDEBUG, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1986-03-26 15:11:02 +00:00
#endif DEBUG
1986-03-20 14:52:03 +00:00
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
error(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(ERROR, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
node_error(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
t_node *node = va_arg(ap, t_node *);
_error(ERROR, node, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
warning(va_alist)
va_dcl
1986-03-26 15:11:02 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(WARNING, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
node_warning(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
t_node *nd = va_arg(ap, t_node *);
_error(WARNING, nd, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
lexerror(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(LEXERROR, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
lexwarning(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(LEXWARNING, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
fatal(va_alist)
va_dcl
1986-03-20 14:52:03 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
1986-03-26 15:11:02 +00:00
1988-04-15 15:19:27 +00:00
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(FATAL, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-26 15:11:02 +00:00
sys_stop(S_EXIT);
1986-03-20 14:52:03 +00:00
}
1988-09-05 15:51:35 +00:00
/*VARARGS*/
1988-04-15 15:19:27 +00:00
crash(va_alist)
va_dcl
1986-05-21 18:32:20 +00:00
{
1988-04-15 15:19:27 +00:00
va_list ap;
1986-05-21 18:32:20 +00:00
1988-04-15 15:19:27 +00:00
va_start(ap);
1988-04-25 16:24:42 +00:00
{
_error(CRASH, NULLNODE, ap);
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-05-21 18:32:20 +00:00
#ifdef DEBUG
sys_stop(S_ABORT);
#else
sys_stop(S_EXIT);
#endif
}
1988-04-15 15:19:27 +00:00
_error(class, node, ap)
1986-03-20 14:52:03 +00:00
int class;
t_node *node;
1988-04-29 15:41:38 +00:00
register va_list ap;
1986-03-20 14:52:03 +00:00
{
1986-03-26 15:11:02 +00:00
/* _error attempts to limit the number of error messages
for a given line to MAXERR_LINE.
*/
static unsigned int last_ln = 0;
unsigned int ln = 0;
1986-04-06 17:42:56 +00:00
static char * last_fn = 0;
static int e_seen = 0;
1986-05-23 19:25:21 +00:00
register char *remark = 0;
1988-04-29 15:41:38 +00:00
int warn_class;
char *fmt;
1986-03-26 15:11:02 +00:00
/* Since name and number are gathered from different places
depending on the class, we first collect the relevant
values and then decide what to print.
*/
/* preliminaries */
1986-03-20 14:52:03 +00:00
switch (class) {
case ERROR:
case LEXERROR:
1986-03-26 15:11:02 +00:00
case CRASH:
case FATAL:
1986-04-23 22:12:22 +00:00
if (C_busy()) C_ms_err();
1986-03-26 15:11:02 +00:00
err_occurred = 1;
break;
}
/* the remark */
switch (class) {
1986-03-20 14:52:03 +00:00
case WARNING:
case LEXWARNING:
1988-04-29 15:41:38 +00:00
warn_class = va_arg(ap, int);
if (! (warn_class & warning_classes)) return;
1986-11-05 14:33:00 +00:00
switch(warn_class) {
#ifndef STRICT_3RD_ED
1986-11-05 14:33:00 +00:00
case W_OLDFASHIONED:
remark = "(old-fashioned use)";
break;
#endif
1987-11-09 16:11:04 +00:00
#ifndef NOSTRICT
1986-11-05 14:33:00 +00:00
case W_STRICT:
remark = "(strict)";
break;
1987-11-09 10:17:20 +00:00
#endif
1986-11-05 14:33:00 +00:00
default:
remark = "(warning)";
break;
}
1986-03-20 14:52:03 +00:00
break;
case CRASH:
1986-03-26 15:11:02 +00:00
remark = "CRASH\007";
1986-03-20 14:52:03 +00:00
break;
case FATAL:
1986-03-26 15:11:02 +00:00
remark = "fatal error --";
1986-03-20 14:52:03 +00:00
break;
1986-04-06 17:42:56 +00:00
#ifdef DEBUG
case VDEBUG:
remark = "(debug)";
break;
#endif DEBUG
1986-03-26 15:11:02 +00:00
}
/* the place */
switch (class) {
case WARNING:
case ERROR:
1986-04-06 17:42:56 +00:00
ln = node ? node->nd_lineno : dot.tk_lineno;
1986-03-20 14:52:03 +00:00
break;
1986-03-26 15:11:02 +00:00
case LEXWARNING:
case LEXERROR:
case CRASH:
case FATAL:
1986-03-26 17:53:13 +00:00
#ifdef DEBUG
case VDEBUG:
#endif DEBUG
1986-03-26 15:11:02 +00:00
ln = LineNumber;
1986-03-20 14:52:03 +00:00
break;
}
1988-04-29 15:41:38 +00:00
fmt = va_arg(ap, char *);
1986-03-26 15:11:02 +00:00
#ifdef DEBUG
if (class != VDEBUG) {
#endif
1986-05-23 19:25:21 +00:00
if (FileName == last_fn && ln == last_ln) {
1986-03-26 15:11:02 +00:00
/* we've seen this place before */
e_seen++;
1986-03-26 17:53:13 +00:00
if (e_seen == MAXERR_LINE) fmt = "etc ...";
1986-03-26 15:11:02 +00:00
else
if (e_seen > MAXERR_LINE)
/* and too often, I'd say ! */
return;
}
else {
/* brand new place */
last_ln = ln;
1986-05-23 19:25:21 +00:00
last_fn = FileName;
1986-03-26 15:11:02 +00:00
e_seen = 0;
}
#ifdef DEBUG
}
1986-03-26 17:53:13 +00:00
#endif DEBUG
1986-05-23 19:25:21 +00:00
if (FileName) fprint(ERROUT, "\"%s\", line %u: ", FileName, ln);
1986-03-26 17:53:13 +00:00
1986-04-03 17:41:26 +00:00
if (remark) fprint(ERROUT, "%s ", remark);
1986-03-26 17:53:13 +00:00
1988-04-15 15:19:27 +00:00
doprnt(ERROUT, fmt, ap); /* contents of error */
1986-04-03 17:41:26 +00:00
fprint(ERROUT, "\n");
1986-03-20 14:52:03 +00:00
}