diff options
| -rw-r--r-- | src/fmt.cff | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/src/fmt.cff b/src/fmt.cff index 5635103..90b6423 100644 --- a/src/fmt.cff +++ b/src/fmt.cff @@ -1,5 +1,6 @@ import "cffc.hff"; import "common.hff"; +import "map.hff"; import "util.hff"; extern fn vpfmt(proc *fn(u8, *void) void, parg *void, fmt *const u8, ap va_list) void { @@ -282,10 +283,33 @@ extern fn ssfmt(fmt *const u8, ...) *const u8 { ap->end(); } +fn eprifileline(loc Loc) void { + let path = fileid2path(loc.fileid); + let fp = fopen(path, "rb"); + let line_begin = 0; + for let i = 0; i < loc.idx; ++i { + if fgetc(fp) == '\n' { + line_begin = i + 1; + } + } + fseek(fp, line_begin, SEEK_SET); + fprintf(stderr, "%4d | ", loc.line); + for let c u8 = fgetc(fp); c != EOF and c != '\n'; c = fgetc(fp) { + fputc(c, stderr); + } + fputc('\n', stderr); + fclose(fp); + for let i = 0; i < loc.col; ++i { + fputc(' ', stderr); + } + fprintf(stderr, "^\n"); +} + extern fn vdiag(P *Parser, loc Loc, kind *const u8, fmt *const u8, ap va_list) void { efmt("%s:%i:%i: %s: ", fileid2path(loc.fileid), loc.line, loc.col, kind); vefmt(fmt, ap); efmt("\n"); + eprifileline(loc); } extern fn fatal(P *Parser, loc Loc, fmt *const u8, ...) void { |