1 #include "c.h"
2 
3 
4 static void printtoken(void);
5 int errcnt   = 0;
6 int errlimit = 20;
7 char kind[] = {
8 #define xx(a,b,c,d,e,f,g) f,
9 #define yy(a,b,c,d,e,f,g) f,
10 #include "token.h"
11 };
12 int wflag;		/* != 0 to suppress warning messages */
13 
test(int tok,char set[])14 void test(int tok, char set[]) {
15 	if (t == tok)
16 		t = gettok();
17 	else {
18 		expect(tok);
19 		skipto(tok, set);
20 		if (t == tok)
21 			t = gettok();
22 	}
23 }
expect(int tok)24 void expect(int tok) {
25 	if (t == tok)
26 		t = gettok();
27 	else {
28 		error("syntax error; found");
29 		printtoken();
30 		fprint(stderr, " expecting `%k'\n", tok);
31 	}
32 }
error(const char * fmt,...)33 void error(const char *fmt, ...) {
34 	va_list ap;
35 
36 	if (errcnt++ >= errlimit) {
37 		errcnt = -1;
38 		error("too many errors\n");
39 		exit(1);
40 	}
41 	va_start(ap, fmt);
42 	if (firstfile != file && firstfile && *firstfile)
43 		fprint(stderr, "%s: ", firstfile);
44 	fprint(stderr, "%w: ", &src);
45 	vfprint(stderr, NULL, fmt, ap);
46 	va_end(ap);
47 }
48 
skipto(int tok,char set[])49 void skipto(int tok, char set[]) {
50 	int n;
51 	char *s;
52 
53 	assert(set);
54 	for (n = 0; t != EOI && t != tok; t = gettok()) {
55 		for (s = set; *s && kind[t] != *s; s++)
56 			;
57 		if (kind[t] == *s)
58 			break;
59 		if (n++ == 0)
60 			error("skipping");
61 		if (n <= 8)
62 			printtoken();
63 		else if (n == 9)
64 			fprint(stderr, " ...");
65 	}
66 	if (n > 8) {
67 		fprint(stderr, " up to");
68 		printtoken();
69 	}
70 	if (n > 0)
71 		fprint(stderr, "\n");
72 }
73 /* fatal - issue fatal error message and exit */
fatal(const char * name,const char * fmt,int n)74 int fatal(const char *name, const char *fmt, int n) {
75 	print("\n");
76 	errcnt = -1;
77 	error("compiler error in %s--", name);
78 	fprint(stderr, fmt, n);
79 	exit(EXIT_FAILURE);
80 	return 0;
81 }
82 
83 /* printtoken - print current token preceeded by a space */
printtoken(void)84 static void printtoken(void) {
85 	switch (t) {
86 	case ID: fprint(stderr, " `%s'", token); break;
87 	case ICON:
88 		fprint(stderr, " `%s'", vtoa(tsym->type, tsym->u.c.v));
89 		break;
90 	case SCON: {
91 		int i, n;
92 		if (ischar(tsym->type->type)) {
93 			char *s = tsym->u.c.v.p;
94 			n = tsym->type->size;
95 			fprint(stderr, " \"");
96 			for (i = 0; i < 20 && i < n && *s; s++, i++)
97 				if (*s < ' ' || *s >= 0177)
98 					fprint(stderr, "\\%o", *s);
99 				else
100 					fprint(stderr, "%c", *s);
101 		} else {	/* wchar_t string */
102 			unsigned int *s = tsym->u.c.v.p;
103 			assert(tsym->type->type->size == widechar->size);
104 			n = tsym->type->size/widechar->size;
105 			fprint(stderr, " L\"");
106 			for (i = 0; i < 20 && i < n && *s; s++, i++)
107 				if (*s < ' ' || *s >= 0177)
108 					fprint(stderr, "\\x%x", *s);
109 				else
110 					fprint(stderr, "%c", *s);
111 		}
112 		if (i < n)
113 			fprint(stderr, " ...");
114 		else
115 			fprint(stderr, "\"");
116 		break;
117 		}
118 	case FCON:
119 		fprint(stderr, " `%S'", token, (char*)cp - token);
120 		break;
121 	case '`': case '\'': fprint(stderr, " \"%k\"", t); break;
122 	default: fprint(stderr, " `%k'", t);
123 	}
124 }
125 
126 /* warning - issue warning error message */
warning(const char * fmt,...)127 void warning(const char *fmt, ...) {
128 	va_list ap;
129 
130 	va_start(ap, fmt);
131 	if (wflag == 0) {
132 		errcnt--;
133 		error("warning: ");
134 		vfprint(stderr, NULL, fmt, ap);
135 	}
136 	va_end(ap);
137 }
138