feature. See also
. The project being documented here (as the example) is the Zig library itself.
ErrorBundle.renderErrorMessage
fn renderErrorMessage(
eb: ErrorBundle,
options: RenderOptions,
err_msg_index: MessageIndex,
t: Io.Terminal,
kind: []const u8,
color: Io.Terminal.Color,
indent: usize,
) Io.Terminal.SetColorError!void
File
Code
fn renderErrorMessage(
eb: ErrorBundle,
options: RenderOptions,
err_msg_index: MessageIndex,
t: Io.Terminal,
kind: []const u8,
color: Io.Terminal.Color,
indent: usize,
) Io.Terminal.SetColorError!void {
const w = t.writer;
const err_msg = eb.getErrorMessage(err_msg_index);
if (err_msg.src_loc != .none) {
const src = eb.extraData(SourceLocation, @backingInt(err_msg.src_loc));
var prefix: Writer.Discarding = .init(&.{});
try w.splatByteAll(' ', indent);
prefix.count += indent;
try t.setColor(.bold);
try w.print("{s}:{d}:{d}: ", .{
eb.nullTerminatedString(src.data.src_path),
src.data.line + 1,
src.data.column + 1,
});
try prefix.writer.print("{s}:{d}:{d}: ", .{
eb.nullTerminatedString(src.data.src_path),
src.data.line + 1,
src.data.column + 1,
});
try t.setColor(color);
try w.writeAll(kind);
prefix.count += kind.len;
try w.writeAll(": ");
prefix.count += 2;
// e.g. "file.zig:4:5: error: "
const prefix_len: usize = @intCast(prefix.count);
try t.setColor(.reset);
try t.setColor(.bold);
if (err_msg.count == 1) {
try writeMsg(eb, err_msg, w, prefix_len);
try w.writeByte('\n');
} else {
try writeMsg(eb, err_msg, w, prefix_len);
try t.setColor(.dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
try t.setColor(.reset);
if (src.data.source_line != 0 and options.include_source_line) {
try w.splatByteAll(' ', indent);
const line = eb.nullTerminatedString(src.data.source_line);
for (line) |b| switch (b) {
'\t' => try w.writeByte(' '),
else => try w.writeByte(b),
};
try w.writeByte('\n');
try w.splatByteAll(' ', indent);
const before_caret = src.data.span_main - src.data.span_start;
const after_caret = src.data.span_end -| src.data.span_main -| 1;
try w.splatByteAll(' ', src.data.column - before_caret);
try t.setColor(.green);
try w.splatByteAll('~', before_caret);
try w.writeByte('^');
try w.splatByteAll('~', after_caret);
try w.writeByte('\n');
try t.setColor(.reset);
}
for (eb.getNotes(err_msg_index)) |note| {
try renderErrorMessage(eb, options, note, t, "note", .cyan, indent);
}
if (src.data.reference_trace_len > 0 and options.include_reference_trace) {
try t.setColor(.reset);
try t.setColor(.dim);
try w.splatByteAll(' ', indent);
try w.print("referenced by:\n", .{});
var ref_index = src.end;
for (0..src.data.reference_trace_len) |_| {
const ref_trace = eb.extraData(ReferenceTrace, ref_index);
ref_index = ref_trace.end;
try w.splatByteAll(' ', indent);
if (ref_trace.data.src_loc != .none) {
const ref_src = eb.getSourceLocation(ref_trace.data.src_loc);
try w.print(" {s}: {s}:{d}:{d}\n", .{
eb.nullTerminatedString(ref_trace.data.decl_name),
eb.nullTerminatedString(ref_src.src_path),
ref_src.line + 1,
ref_src.column + 1,
});
} else if (ref_trace.data.decl_name != 0) {
const count = ref_trace.data.decl_name;
try w.print(
" {d} reference(s) hidden; use '-freference-trace={d}' to see all references\n",
.{ count, count + src.data.reference_trace_len - 1 },
);
} else {
try w.print(
" remaining reference traces hidden; use '-freference-trace' to see all reference traces\n",
.{},
);
}
}
try t.setColor(.reset);
}
} else {
try t.setColor(color);
try w.splatByteAll(' ', indent);
try w.writeAll(kind);
try w.writeAll(": ");
try t.setColor(.reset);
const msg = eb.nullTerminatedString(err_msg.msg);
if (err_msg.count == 1) {
try w.print("{s}\n", .{msg});
} else {
try w.print("{s}", .{msg});
try t.setColor(.dim);
try w.print(" ({d} times)\n", .{err_msg.count});
}
try t.setColor(.reset);
for (eb.getNotes(err_msg_index)) |note| {
try renderErrorMessage(eb, options, note, t, "note", .cyan, indent + 4);
}
}
}