summaryrefslogtreecommitdiff
path: root/src/tools/lcc/src/error.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/lcc/src/error.c')
-rw-r--r--src/tools/lcc/src/error.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/tools/lcc/src/error.c b/src/tools/lcc/src/error.c
new file mode 100644
index 00000000..2187c101
--- /dev/null
+++ b/src/tools/lcc/src/error.c
@@ -0,0 +1,137 @@
+#include "c.h"
+
+
+static void printtoken(void);
+int errcnt = 0;
+int errlimit = 20;
+char kind[] = {
+#define xx(a,b,c,d,e,f,g) f,
+#define yy(a,b,c,d,e,f,g) f,
+#include "token.h"
+};
+int wflag; /* != 0 to suppress warning messages */
+
+void test(int tok, char set[]) {
+ if (t == tok)
+ t = gettok();
+ else {
+ expect(tok);
+ skipto(tok, set);
+ if (t == tok)
+ t = gettok();
+ }
+}
+void expect(int tok) {
+ if (t == tok)
+ t = gettok();
+ else {
+ error("syntax error; found");
+ printtoken();
+ fprint(stderr, " expecting `%k'\n", tok);
+ }
+}
+void error(const char *fmt, ...) {
+ va_list ap;
+
+ if (errcnt++ >= errlimit) {
+ errcnt = -1;
+ error("too many errors\n");
+ exit(1);
+ }
+ va_start(ap, fmt);
+ if (firstfile != file && firstfile && *firstfile)
+ fprint(stderr, "%s: ", firstfile);
+ fprint(stderr, "%w: ", &src);
+ vfprint(stderr, NULL, fmt, ap);
+ va_end(ap);
+}
+
+void skipto(int tok, char set[]) {
+ int n;
+ char *s;
+
+ assert(set);
+ for (n = 0; t != EOI && t != tok; t = gettok()) {
+ for (s = set; *s && kind[t] != *s; s++)
+ ;
+ if (kind[t] == *s)
+ break;
+ if (n++ == 0)
+ error("skipping");
+ if (n <= 8)
+ printtoken();
+ else if (n == 9)
+ fprint(stderr, " ...");
+ }
+ if (n > 8) {
+ fprint(stderr, " up to");
+ printtoken();
+ }
+ if (n > 0)
+ fprint(stderr, "\n");
+}
+/* fatal - issue fatal error message and exit */
+int fatal(const char *name, const char *fmt, int n) {
+ print("\n");
+ errcnt = -1;
+ error("compiler error in %s--", name);
+ fprint(stderr, fmt, n);
+ exit(EXIT_FAILURE);
+ return 0;
+}
+
+/* printtoken - print current token preceeded by a space */
+static void printtoken(void) {
+ switch (t) {
+ case ID: fprint(stderr, " `%s'", token); break;
+ case ICON:
+ fprint(stderr, " `%s'", vtoa(tsym->type, tsym->u.c.v));
+ break;
+ case SCON: {
+ int i, n;
+ if (ischar(tsym->type->type)) {
+ char *s = tsym->u.c.v.p;
+ n = tsym->type->size;
+ fprint(stderr, " \"");
+ for (i = 0; i < 20 && i < n && *s; s++, i++)
+ if (*s < ' ' || *s >= 0177)
+ fprint(stderr, "\\%o", *s);
+ else
+ fprint(stderr, "%c", *s);
+ } else { /* wchar_t string */
+ unsigned int *s = tsym->u.c.v.p;
+ assert(tsym->type->type->size == widechar->size);
+ n = tsym->type->size/widechar->size;
+ fprint(stderr, " L\"");
+ for (i = 0; i < 20 && i < n && *s; s++, i++)
+ if (*s < ' ' || *s >= 0177)
+ fprint(stderr, "\\x%x", *s);
+ else
+ fprint(stderr, "%c", *s);
+ }
+ if (i < n)
+ fprint(stderr, " ...");
+ else
+ fprint(stderr, "\"");
+ break;
+ }
+ case FCON:
+ fprint(stderr, " `%S'", token, (char*)cp - token);
+ break;
+ case '`': case '\'': fprint(stderr, " \"%k\"", t); break;
+ default: fprint(stderr, " `%k'", t);
+ }
+}
+
+/* warning - issue warning error message */
+void warning(const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (wflag == 0) {
+ errcnt--;
+ error("warning: ");
+ vfprint(stderr, NULL, fmt, ap);
+ }
+ va_end(ap);
+}