| ... | ... | @@ -37,7 +37,11 @@ const ErrorMsg = union(enum) { |
| 37 | 37 | src: struct { |
| 38 | 38 | src_path: []const u8, |
| 39 | 39 | msg: []const u8, |
| 40 | // maxint means match anything |
| 41 | // this is a workaround for stage1 compiler bug I ran into when making it ?u32 |
| 40 | 42 | line: u32, |
| 43 | // maxint means match anything |
| 44 | // this is a workaround for stage1 compiler bug I ran into when making it ?u32 |
| 41 | 45 | column: u32, |
| 42 | 46 | kind: Kind, |
| 43 | 47 | }, |
| ... | ... | @@ -81,13 +85,23 @@ const ErrorMsg = union(enum) { |
| 81 | 85 | _ = options; |
| 82 | 86 | switch (self) { |
| 83 | 87 | .src => |src| { |
| 84 | | return writer.print("{s}:{d}:{d}: {s}: {s}", .{ |
| 85 | | src.src_path, |
| 86 | | src.line + 1, |
| 87 | | src.column + 1, |
| 88 | | @tagName(src.kind), |
| 89 | | src.msg, |
| 90 | | }); |
| 88 | if (!std.mem.eql(u8, src.src_path, "?") or |
| 89 | src.line != std.math.maxInt(u32) or |
| 90 | src.column != std.math.maxInt(u32)) |
| 91 | { |
| 92 | try writer.print("{s}:", .{src.src_path}); |
| 93 | if (src.line != std.math.maxInt(u32)) { |
| 94 | try writer.print("{d}:", .{src.line + 1}); |
| 95 | } else { |
| 96 | try writer.writeAll("?:"); |
| 97 | } |
| 98 | if (src.column != std.math.maxInt(u32)) { |
| 99 | try writer.print("{d}: ", .{src.column + 1}); |
| 100 | } else { |
| 101 | try writer.writeAll("?: "); |
| 102 | } |
| 103 | } |
| 104 | return writer.print("{s}: {s}", .{ @tagName(src.kind), src.msg }); |
| 91 | 105 | }, |
| 92 | 106 | .plain => |plain| { |
| 93 | 107 | return writer.print("{s}: {s}", .{ @tagName(plain.kind), plain.msg }); |
| ... | ... | @@ -220,8 +234,14 @@ pub const TestContext = struct { |
| 220 | 234 | const kind_text = it.next() orelse @panic("missing 'error'/'note'"); |
| 221 | 235 | const msg = it.rest()[1..]; // skip over the space at end of "error: " |
| 222 | 236 | |
| 223 | | const line = std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number"); |
| 224 | | const column = std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number"); |
| 237 | const line: ?u32 = if (std.mem.eql(u8, line_text, "?")) |
| 238 | null |
| 239 | else |
| 240 | std.fmt.parseInt(u32, line_text, 10) catch @panic("bad line number"); |
| 241 | const column: ?u32 = if (std.mem.eql(u8, line_text, "?")) |
| 242 | null |
| 243 | else |
| 244 | std.fmt.parseInt(u32, col_text, 10) catch @panic("bad column number"); |
| 225 | 245 | const kind: ErrorMsg.Kind = if (std.mem.eql(u8, kind_text, " error")) |
| 226 | 246 | .@"error" |
| 227 | 247 | else if (std.mem.eql(u8, kind_text, " note")) |
| ... | ... | @@ -229,16 +249,28 @@ pub const TestContext = struct { |
| 229 | 249 | else |
| 230 | 250 | @panic("expected 'error'/'note'"); |
| 231 | 251 | |
| 232 | | if (line == 0 or column == 0) { |
| 233 | | @panic("line and column must be specified starting at one"); |
| 234 | | } |
| 252 | const line_0based: u32 = if (line) |n| blk: { |
| 253 | if (n == 0) { |
| 254 | print("{s}: line must be specified starting at one\n", .{self.name}); |
| 255 | return; |
| 256 | } |
| 257 | break :blk n - 1; |
| 258 | } else std.math.maxInt(u32); |
| 259 | |
| 260 | const column_0based: u32 = if (column) |n| blk: { |
| 261 | if (n == 0) { |
| 262 | print("{s}: line must be specified starting at one\n", .{self.name}); |
| 263 | return; |
| 264 | } |
| 265 | break :blk n - 1; |
| 266 | } else std.math.maxInt(u32); |
| 235 | 267 | |
| 236 | 268 | array[i] = .{ |
| 237 | 269 | .src = .{ |
| 238 | 270 | .src_path = src_path, |
| 239 | 271 | .msg = msg, |
| 240 | | .line = line - 1, |
| 241 | | .column = column - 1, |
| 272 | .line = line_0based, |
| 273 | .column = column_0based, |
| 242 | 274 | .kind = kind, |
| 243 | 275 | }, |
| 244 | 276 | }; |
| ... | ... | @@ -737,7 +769,7 @@ pub const TestContext = struct { |
| 737 | 769 | } |
| 738 | 770 | var ok = true; |
| 739 | 771 | if (case.expect_exact) { |
| 740 | | var err_iter = ErrLineIter.init(result.stderr); |
| 772 | var err_iter = std.mem.split(result.stderr, "\n"); |
| 741 | 773 | var i: usize = 0; |
| 742 | 774 | ok = while (err_iter.next()) |line| : (i += 1) { |
| 743 | 775 | if (i >= case_error_list.len) break false; |
| ... | ... | @@ -940,8 +972,10 @@ pub const TestContext = struct { |
| 940 | 972 | std.mem.eql(u8, case_msg.src.src_path, actual_msg.src_path); |
| 941 | 973 | |
| 942 | 974 | if (src_path_ok and |
| 943 | | actual_msg.line == case_msg.src.line and |
| 944 | | actual_msg.column == case_msg.src.column and |
| 975 | (case_msg.src.line == std.math.maxInt(u32) or |
| 976 | actual_msg.line == case_msg.src.line) and |
| 977 | (case_msg.src.column == std.math.maxInt(u32) or |
| 978 | actual_msg.column == case_msg.src.column) and |
| 945 | 979 | std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and |
| 946 | 980 | case_msg.src.kind == .@"error") |
| 947 | 981 | { |
| ... | ... | @@ -978,8 +1012,10 @@ pub const TestContext = struct { |
| 978 | 1012 | } |
| 979 | 1013 | if (ex_tag != .src) continue; |
| 980 | 1014 | |
| 981 | | if (actual_msg.line == case_msg.src.line and |
| 982 | | actual_msg.column == case_msg.src.column and |
| 1015 | if ((case_msg.src.line == std.math.maxInt(u32) or |
| 1016 | actual_msg.line == case_msg.src.line) and |
| 1017 | (case_msg.src.column == std.math.maxInt(u32) or |
| 1018 | actual_msg.column == case_msg.src.column) and |
| 983 | 1019 | std.mem.eql(u8, case_msg.src.msg, actual_msg.msg) and |
| 984 | 1020 | case_msg.src.kind == .note) |
| 985 | 1021 | { |
| ... | ... | @@ -1162,19 +1198,3 @@ fn dumpArgs(argv: []const []const u8) void { |
| 1162 | 1198 | } |
| 1163 | 1199 | |
| 1164 | 1200 | const tmp_src_path = "tmp.zig"; |
| 1165 | | |
| 1166 | | const ErrLineIter = struct { |
| 1167 | | lines: std.mem.SplitIterator, |
| 1168 | | |
| 1169 | | fn init(input: []const u8) ErrLineIter { |
| 1170 | | return ErrLineIter{ .lines = std.mem.split(input, "\n") }; |
| 1171 | | } |
| 1172 | | |
| 1173 | | fn next(self: *ErrLineIter) ?[]const u8 { |
| 1174 | | while (self.lines.next()) |line| { |
| 1175 | | if (std.mem.indexOf(u8, line, tmp_src_path) != null) |
| 1176 | | return line; |
| 1177 | | } |
| 1178 | | return null; |
| 1179 | | } |
| 1180 | | }; |