// TODO(rsc): remember that there was a package
// name, so that the name cannot be redeclared
// as a non-package in other files.
- if(!s->def->used) {
- print("%L: imported and not used: %s\n", s->def->lineno, s->def->sym->name);
- nerrors++;
- }
+ if(!s->def->used && !nsyntaxerrors)
+ yyerrorl(s->def->lineno, "imported and not used: %s", s->def->sym->name);
s->def = N;
continue;
}
if(s->def->sym != s) {
// throw away top-level name left over
// from previous import . "x"
- if(s->def->pack != N && !s->def->pack->used) {
- print("%L: imported and not used: %s\n", s->def->pack->lineno, s->def->pack->sym->name);
- nerrors++;
+ if(s->def->pack != N && !s->def->pack->used && !nsyntaxerrors) {
+ yyerrorl(s->def->pack->lineno, "imported and not used: %s", s->def->pack->sym->name);
s->def->pack->used = 1;
}
s->def = N;
#include "y.tab.h"
#include "opnames.h"
+typedef struct Error Error;
+struct Error
+{
+ int lineno;
+ int seq;
+ char *msg;
+};
+static Error *err;
+static int nerr;
+static int merr;
+
void
errorexit(void)
{
+ flusherrors();
if(outfile)
remove(outfile);
exit(1);
return lineno;
}
+static void
+adderr(int line, char *fmt, va_list arg)
+{
+ Fmt f;
+ Error *p;
+
+ fmtstrinit(&f);
+ fmtprint(&f, "%L: ", line);
+ fmtvprint(&f, fmt, arg);
+ fmtprint(&f, "\n");
+
+ if(nerr >= merr) {
+ if(merr == 0)
+ merr = 16;
+ else
+ merr *= 2;
+ p = realloc(err, merr*sizeof err[0]);
+ if(p == nil) {
+ merr = nerr;
+ flusherrors();
+ print("out of memory\n");
+ errorexit();
+ }
+ err = p;
+ }
+ err[nerr].seq = nerr;
+ err[nerr].lineno = line;
+ err[nerr].msg = fmtstrflush(&f);
+ nerr++;
+}
+
+static int
+errcmp(const void *va, const void *vb)
+{
+ Error *a, *b;
+
+ a = (Error*)va;
+ b = (Error*)vb;
+ if(a->lineno != b->lineno)
+ return a->lineno - b->lineno;
+ if(a->seq != b->seq)
+ return a->seq - b->seq;
+ return 0;
+}
+
+void
+flusherrors(void)
+{
+ int i;
+
+ if(nerr == 0)
+ return;
+ qsort(err, nerr, sizeof err[0], errcmp);
+ for(i=0; i<nerr; i++)
+ print("%s", err[i].msg);
+ nerr = 0;
+}
+
+static void
+hcrash(void)
+{
+ if(debug['h']) {
+ flusherrors();
+ if(outfile)
+ unlink(outfile);
+ *(int*)0 = 0;
+ }
+}
+
+void
+yyerrorl(int line, char *fmt, ...)
+{
+ va_list arg;
+
+ va_start(arg, fmt);
+ adderr(line, fmt, arg);
+ va_end(arg);
+
+ hcrash();
+ nerrors++;
+ if(nerrors >= 10 && !debug['e'])
+ fatal("too many errors");
+}
+
void
yyerror(char *fmt, ...)
{
va_list arg;
if(strcmp(fmt, "syntax error") == 0) {
- print("%L: syntax error near %s\n", lexlineno, lexbuf);
+ yyerrorl(lexlineno, "syntax error near %s", lexbuf);
nsyntaxerrors++;
- goto out;
+ return;
}
- print("%L: ", parserline());
va_start(arg, fmt);
- vfprint(1, fmt, arg);
+ adderr(parserline(), fmt, arg);
va_end(arg);
- print("\n");
-out:
- if(debug['h'])
- *(int*)0 = 0;
+ hcrash();
nerrors++;
if(nerrors >= 10 && !debug['e'])
fatal("too many errors");
{
va_list arg;
- print("%L: ", lineno);
va_start(arg, fmt);
- vfprint(1, fmt, arg);
+ adderr(parserline(), fmt, arg);
va_end(arg);
- print("\n");
- if(debug['h'])
- *(int*)0 = 0;
+
+ hcrash();
}
void
{
va_list arg;
+ flusherrors();
+
print("%L: fatal error: ", lineno);
va_start(arg, fmt);
vfprint(1, fmt, arg);
va_end(arg);
print("\n");
- if(debug['h']) {
- if(outfile)
- unlink(outfile);
- *(int*)0 = 0;
- }
+
+ hcrash();
errorexit();
}
}
if(n == 0) {
// can't possibly be used - there were no symbols
- print("%L: imported and not used: %s\n", pack->lineno, pack->sym->name);
- nerrors++;
+ yyerrorl(pack->lineno, "imported and not used: %s", pack->sym->name);
}
}
nh = 10L*NHUNK;
h = (char*)malloc(nh);
if(h == (char*)-1) {
+ flusherrors();
yyerror("out of memory");
errorexit();
}
needexplicit = 1;
}
if(wrong) {
- yyerror("%T is not %T\n\tmissing %S%hhT",
- t, iface, m->sym, m->type);
if(samename)
- print("\tdo have %S%hhT\n", samename->sym, samename->type);
+ yyerror("%T is not %T\n\tmissing %S%hhT\n\tdo have %S%hhT",
+ t, iface, m->sym, m->type, samename->sym, samename->type);
+ else
+ yyerror("%T is not %T\n\tmissing %S%hhT", t, iface, m->sym, m->type);
}
else if(!p->explicit && needexplicit) {
if(m) {
- yyerror("need type assertion to use %T as %T\n\tmissing %S%hhT",
- p->src, p->dst, m->sym, m->type);
if(samename)
- print("\tdo have %S%hhT\n", samename->sym, samename->type);
- }
- else
+ yyerror("need type assertion to use %T as %T\n\tmissing %S %hhT\n\tdo have %S%hhT",
+ p->src, p->dst, m->sym, m->type, samename->sym, samename->type);
+ else
+ yyerror("need type assertion to use %T as %T\n\tmissing %S%hhT",
+ p->src, p->dst, m->sym, m->type);
+ } else
yyerror("need type assertion to use %T as %T",
p->src, p->dst);
}