aboutsummaryrefslogtreecommitdiffstats
path: root/lcc/src/error.c
blob: 2187c1014e445bc362a4c0ce76157b0368b44459 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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);
}