Commit 99ec511c4c
Changed files (3)
lib
std
lib/std/debug.zig
@@ -462,7 +462,7 @@ pub const TTY = struct {
// TODO give this a payload of file handle
windows_api,
- fn setColor(conf: Config, out_stream: anytype, color: Color) void {
+ pub fn setColor(conf: Config, out_stream: anytype, color: Color) void {
nosuspend switch (conf) {
.no_color => return,
.escape_codes => switch (color) {
src/Compilation.zig
@@ -6,6 +6,7 @@ const Allocator = std.mem.Allocator;
const assert = std.debug.assert;
const log = std.log.scoped(.compilation);
const Target = std.Target;
+const debug = std.debug;
const Value = @import("value.zig").Value;
const Type = @import("type.zig").Type;
@@ -266,9 +267,30 @@ pub const AllErrors = struct {
list: []const Message,
pub const Message = union(enum) {
+ const MessageType = enum {
+ pub fn render(self: @This(), stderr: anytype, ttyconf: std.debug.TTY.Config) !void {
+ switch (self) {
+ .err => {
+ ttyconf.setColor(stderr, .Red);
+ try stderr.writeAll("error:");
+ },
+ .note => {
+ ttyconf.setColor(stderr, .Green);
+ try stderr.writeAll("note:");
+ },
+ }
+ ttyconf.setColor(stderr, .Reset);
+ }
+ err,
+ note
+ };
+
src: struct {
msg: []const u8,
- src_path: []const u8,
+ src_path: union(enum) {
+ path: []const u8,
+ scope: *Module.Scope.File,
+ },
line: u32,
column: u32,
byte_offset: u32,
@@ -278,26 +300,70 @@ pub const AllErrors = struct {
msg: []const u8,
},
- pub fn renderToStdErr(msg: Message) void {
- return msg.renderToStdErrInner("error");
+ pub fn renderToStdErr(msg: Message, mod: ?*Module) !void {
+ return msg.renderToStdErrInner(.err, mod);
}
- fn renderToStdErrInner(msg: Message, kind: []const u8) void {
+ fn renderToStdErrInner(msg: Message, kind: MessageType, mod: ?*Module) (std.fs.File.WriteError || @typeInfo(@typeInfo(@TypeOf(Module.Scope.File.getSource)).Fn.return_type.?).ErrorUnion.error_set)!void {
+ const ttyconf = debug.detectTTYConfig();
+ const stderr = std.io.getStdErr().writer();
switch (msg) {
.src => |src| {
- std.debug.print("{s}:{d}:{d}: {s}: {s}\n", .{
- src.src_path,
- src.line + 1,
- src.column + 1,
- kind,
- src.msg,
- });
+ switch (src.src_path) {
+ .path => |p| {
+ // TODO read the file and do pretty printing for c objects?
+ try stderr.print("{s}:{d}:{d}: ", .{
+ p,
+ src.line + 1,
+ src.column + 1,
+ });
+ try kind.render(stderr, ttyconf);
+ try stderr.print(" {s}\n", .{
+ src.msg,
+ });
+ },
+ .scope => |s| {
+ const module = mod.?;
+ try stderr.print("{s}:{d}:{d}: ", .{
+ s.sub_file_path,
+ src.line + 1,
+ src.column + 1,
+ });
+ try kind.render(stderr, ttyconf);
+ try stderr.print(" {s}\n", .{
+ src.msg,
+ });
+ const fsource = try s.getSource(module);
+ const end_pos = blk: for (fsource[src.byte_offset..]) |c, i| {
+ if (c == '\n')
+ break :blk src.byte_offset + i + 1;
+ if (c == 0)
+ break :blk fsource.len - 1;
+ } else unreachable;
+ const start_pos = blk: {
+ var i = src.byte_offset;
+ var c: u8 = fsource[i];
+ while (i > 0) : ({
+ i -= 1;
+ c = fsource[i];
+ }) {
+ if (c == '\n') break :blk i + 1;
+ }
+ break :blk 0;
+ };
+ try stderr.writeAll(fsource[start_pos..end_pos]);
+ try stderr.writeByteNTimes(' ', src.column);
+ ttyconf.setColor(stderr, .Cyan);
+ try stderr.writeAll("^\n");
+ ttyconf.setColor(stderr, .Reset);
+ },
+ }
for (src.notes) |note| {
- note.renderToStdErrInner("note");
+ try note.renderToStdErrInner(.note, mod);
}
},
.plain => |plain| {
- std.debug.print("{s}: {s}\n", .{ kind, plain.msg });
+ debug.print("{s}: {s}\n", .{ kind, plain.msg });
},
}
}
@@ -319,10 +385,11 @@ pub const AllErrors = struct {
const source = try module_note.src_loc.fileScope().getSource(module);
const byte_offset = try module_note.src_loc.byteOffset();
const loc = std.zig.findLineColumn(source, byte_offset);
- const sub_file_path = module_note.src_loc.fileScope().sub_file_path;
+ const fscope = module_note.src_loc.fileScope();
note.* = .{
.src = .{
- .src_path = try arena.allocator.dupe(u8, sub_file_path),
+ // TODO this might be freed, might need to dupe the source
+ .src_path = .{ .scope = fscope },
.msg = try arena.allocator.dupe(u8, module_note.msg),
.byte_offset = byte_offset,
.line = @intCast(u32, loc.line),
@@ -333,10 +400,10 @@ pub const AllErrors = struct {
const source = try module_err_msg.src_loc.fileScope().getSource(module);
const byte_offset = try module_err_msg.src_loc.byteOffset();
const loc = std.zig.findLineColumn(source, byte_offset);
- const sub_file_path = module_err_msg.src_loc.fileScope().sub_file_path;
+ const fscope = module_err_msg.src_loc.fileScope();
try errors.append(.{
.src = .{
- .src_path = try arena.allocator.dupe(u8, sub_file_path),
+ .src_path = .{ .scope = fscope },
.msg = try arena.allocator.dupe(u8, module_err_msg.msg),
.byte_offset = byte_offset,
.line = @intCast(u32, loc.line),
@@ -1482,7 +1549,7 @@ pub fn getAllErrorsAlloc(self: *Compilation) !AllErrors {
// C error reporting bubbling up.
try errors.append(.{
.src = .{
- .src_path = try arena.allocator.dupe(u8, c_object.src.src_path),
+ .src_path = .{ .path = try arena.allocator.dupe(u8, c_object.src.src_path) },
.msg = try std.fmt.allocPrint(&arena.allocator, "unable to build C object: {s}", .{
err_msg.msg,
}),
src/main.zig
@@ -2107,7 +2107,7 @@ fn updateModule(gpa: *Allocator, comp: *Compilation, hook: AfterUpdateHook) !voi
if (errors.list.len != 0) {
for (errors.list) |full_err_msg| {
- full_err_msg.renderToStdErr();
+ try full_err_msg.renderToStdErr(comp.bin_file.options.module);
}
const log_text = comp.getCompileLogOutput();
if (log_text.len != 0) {