ack/lang/cem/cemcom/error.c

321 lines
5 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".
*/
1986-03-10 13:07:55 +00:00
/* $Header$ */
/* 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 */
#include "lint.h"
1988-04-15 15:07:51 +00:00
#include <varargs.h>
1986-03-25 10:39:23 +00:00
#include <system.h>
#ifndef LINT
#include <em.h>
#else
#include "em_lint.h"
#endif LINT
1986-03-10 13:07:55 +00:00
#include "nopp.h"
#include "errout.h"
#include "debug.h"
#include "tokenname.h"
#include "arith.h"
#include "label.h"
#include "expr.h"
1988-08-19 13:55:22 +00:00
#include "def.h"
1986-03-10 13:07:55 +00:00
#include "LLlex.h"
1988-04-15 15:07:51 +00:00
/* This file contains the error-message and diagnostic
1986-03-10 13:07:55 +00:00
functions. Beware, they are called with a variable number of
arguments!
*/
/* error classes */
1988-09-16 23:19:50 +00:00
#define WARNING 1
#define ERROR 2
#define CRASH 3
#define FATAL 4
1986-03-10 13:07:55 +00:00
1986-04-28 09:56:33 +00:00
int err_occurred = 0;
1986-03-10 13:07:55 +00:00
extern char options[];
#ifdef LINT
extern char loptions[];
#endif LINT
1986-03-10 13:07:55 +00:00
/* There are three general error-message functions:
lexerror() lexical and pre-processor error messages
error() syntactic and semantic error messages
expr_error() errors in expressions
The difference lies in the place where the file name and line
number come from.
Lexical errors report from the global variables LineNumber and
FileName, expression errors get their information from the
expression, whereas other errors use the information in the token.
*/
1988-09-16 23:19:50 +00:00
static _error();
1988-08-19 13:55:22 +00:00
/*VARARGS*/
error(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(ERROR, dot.tk_file, dot.tk_line, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1986-03-10 13:07:55 +00:00
}
1988-08-19 13:55:22 +00:00
/*VARARGS*/
expr_error(va_alist) /* expr, fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
register struct expr *expr = va_arg(ap, struct expr *);
if (!(expr->ex_flags & EX_ERROR)) {
/* to prevent proliferation */
1988-09-16 23:19:50 +00:00
_error(ERROR, expr->ex_file, expr->ex_line, ap);
1988-04-25 16:24:42 +00:00
expr->ex_flags |= EX_ERROR;
}
1988-04-15 15:07:51 +00:00
}
va_end(ap);
1986-03-10 13:07:55 +00:00
}
1988-08-19 13:55:22 +00:00
/*VARARGS*/
warning(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(WARNING, dot.tk_file, dot.tk_line, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1986-03-10 13:07:55 +00:00
}
1988-08-19 13:55:22 +00:00
/*VARARGS*/
expr_warning(va_alist) /* expr, fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
struct expr *expr = va_arg(ap, struct expr *);
if (!(expr->ex_flags & EX_ERROR)) {
/* to prevent proliferation */
1988-09-16 23:19:50 +00:00
_error(WARNING, expr->ex_file, expr->ex_line, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
}
va_end(ap);
1986-03-10 13:07:55 +00:00
}
#ifdef LINT
/*VARARGS*/
def_warning(va_alist) /* def, fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
register struct def *def = va_arg(ap, struct def *);
_error(WARNING, def->df_file, def->df_line, ap);
}
va_end(ap);
}
/*VARARGS*/
hwarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
if (loptions['h'])
_error(WARNING, dot.tk_file, dot.tk_line, ap);
}
va_end(ap);
}
/*VARARGS*/
awarning(va_alist) /* fmt, args */
va_dcl
{
va_list ap;
va_start(ap);
{
if (loptions['a'])
_error(WARNING, dot.tk_file, dot.tk_line, ap);
}
va_end(ap);
}
#endif LINT
1988-08-19 13:55:22 +00:00
/*VARARGS*/
lexerror(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(ERROR, FileName, LineNumber, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1986-03-10 13:07:55 +00:00
}
#ifndef NOPP
1988-08-19 13:55:22 +00:00
/*VARARGS*/
lexwarning(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
{
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(WARNING, FileName, LineNumber, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1986-03-10 13:07:55 +00:00
}
#endif NOPP
1988-08-19 13:55:22 +00:00
/*VARARGS*/
crash(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(CRASH, FileName, LineNumber, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1988-04-25 16:24:42 +00:00
1986-03-10 13:07:55 +00:00
C_close();
#ifdef DEBUG
1986-03-25 10:39:23 +00:00
sys_stop(S_ABORT);
1986-03-10 13:07:55 +00:00
#else DEBUG
1986-03-25 10:39:23 +00:00
sys_stop(S_EXIT);
1986-03-10 13:07:55 +00:00
#endif DEBUG
1988-08-19 13:55:22 +00:00
/* NOTREACHED */
1986-03-10 13:07:55 +00:00
}
1988-08-19 13:55:22 +00:00
/*VARARGS*/
fatal(va_alist) /* fmt, args */
1988-04-15 15:07:51 +00:00
va_dcl
1986-03-10 13:07:55 +00:00
{
1988-04-15 15:07:51 +00:00
va_list ap;
va_start(ap);
1988-04-25 16:24:42 +00:00
{
1988-09-16 23:19:50 +00:00
_error(FATAL, FileName, LineNumber, ap);
1988-04-25 16:24:42 +00:00
}
1988-04-15 15:07:51 +00:00
va_end(ap);
1988-04-25 16:24:42 +00:00
if (C_busy()) C_close();
1986-03-25 10:39:23 +00:00
sys_stop(S_EXIT);
1988-09-16 23:19:50 +00:00
/*NOTREACHED*/
1986-03-10 13:07:55 +00:00
}
1988-09-16 23:19:50 +00:00
static
_error(class, fn, ln, ap)
1986-03-10 13:07:55 +00:00
int class;
1988-09-16 23:19:50 +00:00
char *fn;
unsigned int ln;
1988-04-15 15:07:51 +00:00
va_list ap;
1986-03-10 13:07:55 +00:00
{
1988-09-16 23:19:50 +00:00
char *remark;
1988-04-15 15:07:51 +00:00
char *fmt = va_arg(ap, char *);
/* check visibility of message */
switch (class) {
case WARNING:
case ERROR:
if (token_nmb < tk_nmb_at_last_syn_err + ERR_SHADOW)
/* warning or error message overshadowed */
return;
break;
}
1986-03-10 13:07:55 +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 */
switch (class) {
1988-09-16 23:19:50 +00:00
case WARNING:
if (options['w'])
return;
break;
1986-03-10 13:07:55 +00:00
case ERROR:
case CRASH:
case FATAL:
if (C_busy())
C_ms_err();
err_occurred = 1;
break;
}
/* the remark */
switch (class) {
case WARNING:
#ifndef LINT
1986-03-10 13:07:55 +00:00
remark = "(warning)";
#else LINT
remark = 0;
#endif LINT
1986-03-10 13:07:55 +00:00
break;
1988-09-16 23:19:50 +00:00
case ERROR:
remark = 0;
break;
1986-03-10 13:07:55 +00:00
case CRASH:
remark = "CRASH\007";
break;
1988-09-16 23:19:50 +00:00
1986-03-10 13:07:55 +00:00
case FATAL:
remark = "fatal error --";
break;
1988-09-16 23:19:50 +00:00
default:
/*NOTREACHED*/;
1986-03-10 13:07:55 +00:00
}
#ifdef LINT
if ( /* there is a file name */
fn
&& /* the file name is global */
fn[0] == '/'
&& /* it is not a .c file */
strcmp(&fn[strlen(fn)-2], ".c") != 0
) {
/* we skip this message */
return;
}
#endif LINT
1986-03-10 13:07:55 +00:00
if (fn)
1986-04-03 14:32:56 +00:00
fprint(ERROUT, "\"%s\", line %u: ", fn, ln);
1986-03-10 13:07:55 +00:00
if (remark)
1986-04-03 14:32:56 +00:00
fprint(ERROUT, "%s ", remark);
1988-04-15 15:07:51 +00:00
doprnt(ERROUT, fmt, ap); /* contents of error */
1986-04-03 14:32:56 +00:00
fprint(ERROUT, "\n");
1986-03-10 13:07:55 +00:00
}