diff options
| author | 2025-11-26 18:07:01 +0100 | |
|---|---|---|
| committer | 2025-11-26 18:32:06 +0100 | |
| commit | 0bb43ea3af31d4c141285ab968b476228416f0c8 (patch) | |
| tree | 5bfb5b9f230bd63c7b99a1b57f01dcd16b3b96fe | |
| parent | ccb8e79a45d8e06c127e59fb1404a726691c5f26 (diff) | |
io: diagnostics print source code underline correctly with hard tabs
| -rw-r--r-- | io.c | 34 |
1 files changed, 26 insertions, 8 deletions
@@ -970,7 +970,7 @@ vdiag(const struct span *span, enum diagkind kind, const char *fmt, va_list ap) efmt("\n"); if (span) { uint i; - int j, nmark; + int nmark; char mark = '^'; /* find start of line */ @@ -979,17 +979,35 @@ vdiag(const struct span *span, enum diagkind kind, const char *fmt, va_list ap) nmark = loc->len; while (i < loc->off + loc->len) { - int end; + int j, end; int curoff = efmt("%5d | ", line); - for (end = 0; f->p[i] != '\n' && i < f->n; ++i, ++end) - ioputc(&bstderr, f->p[i]); + const uchar *linep = &f->p[i]; + bool begintabs = 1; + for (end = 0; f->p[i] != '\n' && i < f->n; ++i, ++end) { + uchar c = f->p[i]; + if (c == '\t') { + if (!begintabs) c = ' '; + } else { + begintabs = 0; + } + ioputc(&bstderr, c); + } + ioputc(&bstderr, '\n'); ++i; - ioputc(&bstderr, '\n'); - for (j = 0; j < curoff + col - 1; ++j) - ioputc(&bstderr, j == curoff-2 ? '|' : ' '); + for (j = -curoff; j < 0; ++j) + ioputc(&bstderr, j == -2 ? '|' : ' '); + for (begintabs = 1; j < col-1; ++j) { + uchar c = *linep++; + if (c == '\t') { + if (!begintabs) c = ' '; + } else { + c = ' '; + begintabs = 0; + } + ioputc(&bstderr, c); + } efmt(color[kind]); - j -= curoff; do { ioputc(&bstderr, mark); mark = '~'; |