ack/lang/m2/comp/error.c

217 lines
3.8 KiB
C
Raw Normal View History

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
/* 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-03-26 15:11:02 +00:00
static char *RcsId = "$Header$";
#include <system.h>
#include <em_arith.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-03-20 14:52:03 +00:00
1986-03-26 15:11:02 +00:00
#define MAXERR_LINE 5 /* Number of error messages on one line ... */
#define ERROUT STDERR
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
/*VARARGS2*/
1986-04-07 17:40:38 +00:00
debug(fmt, args)
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-07 17:40:38 +00:00
_error(VDEBUG, NULLNODE, fmt, &args);
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
1986-03-26 15:11:02 +00:00
/*VARARGS1*/
error(fmt, args)
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(ERROR, NULLNODE, fmt, &args);
1986-03-20 14:52:03 +00:00
}
1986-03-26 15:11:02 +00:00
/*VARARGS2*/
1986-04-06 17:42:56 +00:00
node_error(node, fmt, args)
struct node *node;
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(ERROR, node, fmt, &args);
1986-03-20 14:52:03 +00:00
}
/*VARARGS1*/
1986-03-26 15:11:02 +00:00
warning(fmt, args)
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(WARNING, NULLNODE, fmt, &args);
1986-03-20 14:52:03 +00:00
}
1986-03-26 15:11:02 +00:00
/*VARARGS2*/
1986-04-06 17:42:56 +00:00
node_warning(node, fmt, args)
struct node *node;
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(WARNING, node, fmt, &args);
1986-03-20 14:52:03 +00:00
}
/*VARARGS1*/
1986-03-26 15:11:02 +00:00
lexerror(fmt, args)
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(LEXERROR, NULLNODE, fmt, &args);
1986-03-20 14:52:03 +00:00
}
/*VARARGS1*/
1986-03-26 15:11:02 +00:00
lexwarning(fmt, args)
1986-03-20 14:52:03 +00:00
char *fmt;
{
1986-04-06 17:42:56 +00:00
_error(LEXWARNING, NULLNODE, fmt, &args);
1986-03-20 14:52:03 +00:00
}
/*VARARGS1*/
1986-03-26 15:11:02 +00:00
fatal(fmt, args)
1986-03-20 14:52:03 +00:00
char *fmt;
1986-03-26 15:11:02 +00:00
int args;
1986-03-20 14:52:03 +00:00
{
1986-03-26 15:11:02 +00:00
1986-04-06 17:42:56 +00:00
_error(FATAL, NULLNODE, fmt, &args);
1986-03-26 15:11:02 +00:00
sys_stop(S_EXIT);
1986-03-20 14:52:03 +00:00
}
1986-04-06 17:42:56 +00:00
_error(class, node, fmt, argv)
1986-03-20 14:52:03 +00:00
int class;
1986-04-06 17:42:56 +00:00
struct node *node;
1986-03-20 14:52:03 +00:00
char *fmt;
int argv[];
{
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;
char *fn = 0;
static int e_seen = 0;
1986-03-26 15:11:02 +00:00
char *remark = 0;
/* 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-03-27 17:37:41 +00:00
/* ????
1986-03-26 15:11:02 +00:00
if (C_busy())
C_ms_err();
*/
err_occurred = 1;
break;
case WARNING:
case LEXWARNING:
if (options['w'])
return;
1986-03-20 14:52:03 +00:00
break;
1986-03-26 15:11:02 +00:00
}
/* the remark */
switch (class) {
1986-03-20 14:52:03 +00:00
case WARNING:
case LEXWARNING:
1986-03-26 15:11:02 +00:00
remark = "(warning)";
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
fn = node ? node->nd_filename : dot.tk_filename;
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-04-06 17:42:56 +00:00
fn = FileName;
1986-03-20 14:52:03 +00:00
break;
}
1986-03-26 15:11:02 +00:00
#ifdef DEBUG
if (class != VDEBUG) {
#endif
1986-04-06 17:42:56 +00:00
if (fn == 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-04-06 17:42:56 +00:00
last_fn = fn;
1986-03-26 15:11:02 +00:00
e_seen = 0;
}
#ifdef DEBUG
}
1986-03-26 17:53:13 +00:00
#endif DEBUG
1986-04-06 17:42:56 +00:00
if (fn) fprint(ERROUT, "\"%s\", line %u: ", fn, 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
1986-03-26 15:11:02 +00:00
doprnt(ERROUT, fmt, argv); /* contents of error */
1986-04-03 17:41:26 +00:00
fprint(ERROUT, "\n");
1986-03-20 14:52:03 +00:00
}