blob: bbe9c8b0ed469ac8fa980e7a8fb531828e8de7ac [file] [log] [blame]
#include "c.h"
static char rcsid[] = "$Id: error.c 355 2007-02-18 22:08:49Z drh $";
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);
}