/* * Module that will perform more elaborate error handling at some future date. */ #include #include "list.h" #include "std-macros.h" #include "parse-tree.h" /* for nodep */ #include "sym.h" #include "translator.h" #include "error.h" /* * Local flag incremented when any error is messaged. */ static int ErrorOccurred; /* * Local flag that points to non-local error counter (typically * CurSyntab->Errors). */ static int *ErrorCounter; /* * Hook for more elaborate error routine. */ error(a1, a2, a3, a4, a5, a6, a7, a8) char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; { fprintf(stderr, a1, a2, a3, a4, a5, a6, a7, a8); fflush(stderr); } /* * Line-orinented error routine. The first arg is the tree node nearest the * site of the error. Note that it may be possible to call lerror with t == * NULL, so the code protects itself from this possibility. */ lerror(t, a1, a2, a3, a4, a5, a6, a7, a8) nodep t; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; { ErrorOccurred++; if (ErrorCounter) (*ErrorCounter)++; lerror1("", "", t, a1, a2, a3, a4, a5, a6, a7, a8); } /* * Like lerror, but error counter is not incremented. Called from places like * undefined component logic, where we want an error, but don't want to count * it agains the browser being able to come up. */ lchastise(t, a1, a2, a3, a4, a5, a6, a7, a8) nodep t; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; { lerror1("", "", t, a1, a2, a3, a4, a5, a6, a7, a8); } /* * Line-orinented warning routine. The first arg is the tree node nearest the * site of the error. Note that it may be possible to call lerror with t == * NULL, so the code protects itself from this possibility. */ lwarn(t, a1, a2, a3, a4, a5, a6, a7, a8) nodep t; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; { lerror1("", "Warning: ", t, a1, a2, a3, a4, a5, a6, a7, a8); } /* * Common work doer for lerror and lwarn. */ lerror1(prefix, suffix, t, a1, a2, a3, a4, a5, a6, a7, a8) char* prefix, *suffix; nodep t; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; { if (((not Conversing) or (NumLexInFiles() > 0)) and t) fprintf(stderr, " %sFile %s, line %d, char %d:\n\t%s", prefix, t->header.loc.file, t->header.loc.line, t->header.loc.col, suffix); error(a1, a2, a3, a4, a5, a6, a7, a8); } /* * Lerror callable with SrcLoc directly. This gets called from places like the * lexer, where we don't have our hands on a tree node. */ lserror(loc, a1, a2, a3, a4, a5, a6, a7, a8) SrcLoc loc; char *a1; { ErrorOccurred++; if (ErrorCounter) (*ErrorCounter)++; fprintf(stderr, " File %s, line %d, char %d:\n\t", loc.file, loc.line, loc.col); error(a1, a2, a3, a4, a5, a6, a7, a8); } /* * Set the error counter to the given parameter. This is typically called * before checking a scope to detect how many errors occur during checking. * What's passed in is the addr of CurSymtab->Errors. */ SetErrorCounter(c) int *c; { ErrorCounter = c; } /* * Save current error counter on stack and set to given parm. This is a hack * used in breakpointing (see debug.c:ChkBreak). */ PushErrorCounter(c) int *c; { PushCppList(ErrorCounterStack, ErrorCounter); SetErrorCounter(c); } PopErrorCounter() { ErrorCounter = (int *) PopCppList(ErrorCounterStack); } /* * Clear the ErrorOccurred flag. Can be called before checking a scope to * detect how many errors occur during checking, but SetErrorCounter is * currently used instead of ClearErrors. */ ClearErrors() { ErrorOccurred = 0; } /* * Report how many errors have occured since last ClearErrors(). */ int ErrorsOccurred() { return ErrorOccurred; } InitErrors() { ErrorCounterStack = NewCppList(); if (CurSymtab) CurSymtab->Errors = 0; }