ack/lang/m2/comp/error.c

411 lines
6.4 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
1994-06-24 14:02:31 +00:00
/* $Id$ */
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!
*/
#include "parameters.h"
1986-04-18 17:53:47 +00:00
#include "debug.h"
1986-04-17 09:28:09 +00:00
#if __STDC__
#include <stdarg.h>
#else
1988-04-15 15:19:27 +00:00
#include <varargs.h>
#endif
1988-04-15 15:19:27 +00:00
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
1986-03-20 14:52:03 +00:00
#include "input.h"
#include "f_info.h"
#include "print.h"
1986-03-20 14:52:03 +00:00
#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"
#include "error.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
*/
static void _error(int, struct node *, char *, register va_list, int);
#if __STDC__
#ifdef DEBUG
/*VARARGS*/
void debug(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(VDEBUG, NULLNODE, ap, 0);
}
va_end(ap);
}
#endif /* DEBUG */
/*VARARGS*/
void error(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(ERROR, NULLNODE, fmt, ap, 0);
}
va_end(ap);
}
/*VARARGS*/
void node_error(struct node *node, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(ERROR, node, fmt, ap, 0);
}
va_end(ap);
}
/*VARARGS*/
void warning(int class, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(WARNING, NULLNODE, fmt, ap, class);
}
va_end(ap);
}
/*VARARGS*/
void node_warning(struct node *node, int class, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(WARNING, node, fmt, ap, class);
}
va_end(ap);
}
/*VARARGS*/
void lexerror(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(LEXERROR, NULLNODE, fmt, ap, 0);
}
va_end(ap);
}
/*VARARGS*/
void lexwarning(int class, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(LEXWARNING, NULLNODE, fmt, ap, class);
}
va_end(ap);
}
/*VARARGS*/
void fatal(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(FATAL, NULLNODE, fmt, ap, 0);
}
va_end(ap);
sys_stop(S_EXIT);
}
/*VARARGS*/
void crash(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
{
1995-12-04 15:29:42 +00:00
_error(CRASH, NULLNODE, fmt, ap, 0);
}
va_end(ap);
#ifdef DEBUG
sys_stop(S_ABORT);
#else
sys_stop(S_EXIT);
#endif
}
#else
1986-03-26 15:11:02 +00:00
#ifdef DEBUG
1988-09-05 15:51:35 +00:00
/*VARARGS*/
void debug(va_alist)
1988-04-15 15:19:27 +00:00
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
{
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(VDEBUG, NULLNODE, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:19:27 +00:00
va_end(ap);
1986-03-20 14:52:03 +00:00
}
#endif /* DEBUG */
1986-03-20 14:52:03 +00:00
1988-09-05 15:51:35 +00:00
/*VARARGS*/
void error(va_alist)
1988-04-15 15:19:27 +00:00
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
{
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(ERROR, NULLNODE, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
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*/
void node_error(va_alist)
1988-04-15 15:19:27 +00:00
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
{
struct node *node = va_arg(ap, struct node *);
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(ERROR, node, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
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*/
void warning(va_alist)
1988-04-15 15:19:27 +00:00
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
{
1995-12-04 15:29:42 +00:00
int class = va_arg(ap, int);
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(WARNING, NULLNODE, fmt, ap, class);
1988-04-25 16:24:42 +00:00
}
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*/
void node_warning(va_alist)
1988-04-15 15:19:27 +00:00
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
{
struct node *nd = va_arg(ap, struct node *);
1995-12-04 15:29:42 +00:00
int class = va_arg(ap, int);
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(WARNING, nd, fmt, ap, class);
1988-04-25 16:24:42 +00:00
}
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*/
void lexerror(va_alist)
1988-04-15 15:19:27 +00:00
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
{
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(LEXERROR, NULLNODE, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
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*/
void lexwarning(va_alist)
1988-04-15 15:19:27 +00:00
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
{
1995-12-04 15:29:42 +00:00
int class = va_arg(ap, int);
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(LEXWARNING, NULLNODE, fmt, ap, class);
1988-04-25 16:24:42 +00:00
}
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*/
void fatal(va_alist)
1988-04-15 15:19:27 +00:00
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
{
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(FATAL, NULLNODE, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
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*/
void crash(va_alist)
1988-04-15 15:19:27 +00:00
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
{
char *fmt = va_arg(ap, char *);
1995-12-04 15:29:42 +00:00
_error(CRASH, NULLNODE, fmt, ap, 0);
1988-04-25 16:24:42 +00:00
}
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
}
#endif
1986-05-21 18:32:20 +00:00
static void _error(int class, struct node *node, char *fmt, register va_list ap, int warn_class)
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.
*/
unsigned int ln = 0;
1986-05-23 19:25:21 +00:00
register char *remark = 0;
1986-03-26 15:11:02 +00:00
1991-11-27 13:40:52 +00:00
/* check visibility of message */
if (class == ERROR || class == WARNING) {
if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
/* warning or error message overshadowed */
return;
}
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:
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
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
}