123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- /*
- * (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
- */
- /* 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 */
- /* $Id$ */
- /* 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 "errout.h"
- #include "debug.h"
- #if __STDC__
- #include <stdarg.h>
- #else
- #include <varargs.h>
- #endif
- #include <system.h>
- #include <em_arith.h>
- #include <em_label.h>
- #include <em_code.h>
- #include "strict3rd.h"
- #include "input.h"
- #include "f_info.h"
- #include "LLlex.h"
- #include "main.h"
- #include "node.h"
- #include "warning.h"
- #include "nostrict.h"
- /* error classes */
- #define ERROR 1
- #define WARNING 2
- #define LEXERROR 3
- #define LEXWARNING 4
- #define CRASH 5
- #define FATAL 6
- #ifdef DEBUG
- #define VDEBUG 7
- #endif
- int err_occurred;
- extern char *symbol2str();
- /* There are three general error-message functions:
- lexerror() lexical and pre-processor error messages
- error() syntactic and semantic error messages
- node_error() errors in nodes
- 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, node errors get their information from the
- node, whereas other errors use the information in the token.
- */
- #if __STDC__
- #ifdef DEBUG
- /*VARARGS*/
- debug(char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(VDEBUG, NULLNODE, ap, 0);
- }
- va_end(ap);
- }
- #endif /* DEBUG */
- /*VARARGS*/
- error(char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(ERROR, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- node_error(t_node *node, char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(ERROR, node, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- warning(int class, char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(WARNING, NULLNODE, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- node_warning(t_node *node, int class, char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(WARNING, node, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- lexerror(char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(LEXERROR, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- lexwarning(int class, char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(LEXWARNING, NULLNODE, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- fatal(char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(FATAL, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- sys_stop(S_EXIT);
- }
- /*VARARGS*/
- crash(char *fmt, ...)
- {
- va_list ap;
- va_start(ap, fmt);
- {
- _error(CRASH, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- #ifdef DEBUG
- sys_stop(S_ABORT);
- #else
- sys_stop(S_EXIT);
- #endif
- }
- #else
- #ifdef DEBUG
- /*VARARGS*/
- debug(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- char *fmt = va_arg(ap, char *);
- _error(VDEBUG, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- }
- #endif /* DEBUG */
- /*VARARGS*/
- error(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- char *fmt = va_arg(ap, char *);
- _error(ERROR, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- node_error(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- t_node *node = va_arg(ap, t_node *);
- char *fmt = va_arg(ap, char *);
- _error(ERROR, node, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- warning(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- int class = va_arg(ap, int);
- char *fmt = va_arg(ap, char *);
- _error(WARNING, NULLNODE, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- node_warning(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- t_node *nd = va_arg(ap, t_node *);
- int class = va_arg(ap, int);
- char *fmt = va_arg(ap, char *);
- _error(WARNING, nd, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- lexerror(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- char *fmt = va_arg(ap, char *);
- _error(LEXERROR, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- }
- /*VARARGS*/
- lexwarning(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- int class = va_arg(ap, int);
- char *fmt = va_arg(ap, char *);
- _error(LEXWARNING, NULLNODE, fmt, ap, class);
- }
- va_end(ap);
- }
- /*VARARGS*/
- fatal(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- char *fmt = va_arg(ap, char *);
- _error(FATAL, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- sys_stop(S_EXIT);
- }
- /*VARARGS*/
- crash(va_alist)
- va_dcl
- {
- va_list ap;
- va_start(ap);
- {
- char *fmt = va_arg(ap, char *);
- _error(CRASH, NULLNODE, fmt, ap, 0);
- }
- va_end(ap);
- #ifdef DEBUG
- sys_stop(S_ABORT);
- #else
- sys_stop(S_EXIT);
- #endif
- }
- #endif
- _error(class, node, fmt, ap, warn_class)
- int class;
- t_node *node;
- char *fmt;
- register va_list ap;
- int warn_class;
- {
- /* _error attempts to limit the number of error messages
- for a given line to MAXERR_LINE.
- */
- unsigned int ln = 0;
- register char *remark = 0;
-
- /* 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;
- }
- /* 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) {
- case ERROR:
- case LEXERROR:
- case CRASH:
- case FATAL:
- if (C_busy()) C_ms_err();
- err_occurred = 1;
- break;
- }
- /* the remark */
- switch (class) {
- case WARNING:
- case LEXWARNING:
- if (! (warn_class & warning_classes)) return;
- switch(warn_class) {
- #ifndef STRICT_3RD_ED
- case W_OLDFASHIONED:
- remark = "(old-fashioned use)";
- break;
- #endif
- #ifndef NOSTRICT
- case W_STRICT:
- remark = "(strict)";
- break;
- #endif
- default:
- remark = "(warning)";
- break;
- }
- break;
- case CRASH:
- remark = "CRASH\007";
- break;
- case FATAL:
- remark = "fatal error --";
- break;
- #ifdef DEBUG
- case VDEBUG:
- remark = "(debug)";
- break;
- #endif /* DEBUG */
- }
-
- /* the place */
- switch (class) {
- case WARNING:
- case ERROR:
- ln = node ? node->nd_lineno : dot.tk_lineno;
- break;
- case LEXWARNING:
- case LEXERROR:
- case CRASH:
- case FATAL:
- #ifdef DEBUG
- case VDEBUG:
- #endif /* DEBUG */
- ln = LineNumber;
- break;
- }
- if (FileName) fprint(ERROUT, "\"%s\", line %u: ", FileName, ln);
- if (remark) fprint(ERROUT, "%s ", remark);
- doprnt(ERROUT, fmt, ap); /* contents of error */
- fprint(ERROUT, "\n");
- }
|