| ... | @@ -46,6 +46,7 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value { | ... | @@ -46,6 +46,7 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value { |
| 46 | } | 46 | } |
| 47 | | 47 | |
| 48 | const max_aggregate_items = 100; | 48 | const max_aggregate_items = 100; |
| | 49 | const max_string_len = 256; |
| 49 | | 50 | |
| 50 | const FormatContext = struct { | 51 | const FormatContext = struct { |
| 51 | tv: TypedValue, | 52 | tv: TypedValue, |
| ... | @@ -141,10 +142,12 @@ pub fn print( | ... | @@ -141,10 +142,12 @@ pub fn print( |
| 141 | .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"), | 142 | .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"), |
| 142 | .type_info_type => return writer.writeAll("std.builtin.Type"), | 143 | .type_info_type => return writer.writeAll("std.builtin.Type"), |
| 143 | | 144 | |
| 144 | .empty_struct_value, .aggregate => { | 145 | .empty_struct_value => return writer.writeAll(".{}"), |
| | 146 | .aggregate => { |
| 145 | if (level == 0) { | 147 | if (level == 0) { |
| 146 | return writer.writeAll(".{ ... }"); | 148 | return writer.writeAll(".{ ... }"); |
| 147 | } | 149 | } |
| | 150 | const values = val.castTag(.aggregate).?; |
| 148 | if (ty.zigTypeTag() == .Struct) { | 151 | if (ty.zigTypeTag() == .Struct) { |
| 149 | try writer.writeAll(".{"); | 152 | try writer.writeAll(".{"); |
| 150 | const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items); | 153 | const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items); |
| ... | @@ -159,9 +162,9 @@ pub fn print( | ... | @@ -159,9 +162,9 @@ pub fn print( |
| 159 | try print(.{ | 162 | try print(.{ |
| 160 | .ty = ty.structFieldType(i), | 163 | .ty = ty.structFieldType(i), |
| 161 | .val = switch (ty.containerLayout()) { | 164 | .val = switch (ty.containerLayout()) { |
| 162 | .Packed => val.castTag(.aggregate).?.data[i], | 165 | .Packed => values.data[i], |
| 163 | else => ty.structFieldValueComptime(i) orelse b: { | 166 | else => ty.structFieldValueComptime(i) orelse b: { |
| 164 | const vals = val.castTag(.aggregate).?.data; | 167 | const vals = values.data; |
| 165 | break :b vals[i]; | 168 | break :b vals[i]; |
| 166 | }, | 169 | }, |
| 167 | }, | 170 | }, |
| ... | @@ -172,17 +175,31 @@ pub fn print( | ... | @@ -172,17 +175,31 @@ pub fn print( |
| 172 | } | 175 | } |
| 173 | return writer.writeAll("}"); | 176 | return writer.writeAll("}"); |
| 174 | } else { | 177 | } else { |
| 175 | try writer.writeAll(".{ "); | | |
| 176 | const elem_ty = ty.elemType2(); | 178 | const elem_ty = ty.elemType2(); |
| 177 | const len = ty.arrayLen(); | 179 | const len = ty.arrayLen(); |
| 178 | const max_len = std.math.min(len, max_aggregate_items); | | |
| 179 | | 180 | |
| | 181 | if (elem_ty.eql(Type.u8, mod)) str: { |
| | 182 | const max_len = @intCast(usize, std.math.min(len, max_string_len)); |
| | 183 | var buf: [max_string_len]u8 = undefined; |
| | 184 | |
| | 185 | var i: u32 = 0; |
| | 186 | while (i < max_len) : (i += 1) { |
| | 187 | buf[i] = std.math.cast(u8, values.data[i].toUnsignedInt(target)) orelse break :str; |
| | 188 | } |
| | 189 | |
| | 190 | const truncated = if (len > max_string_len) " (truncated)" else ""; |
| | 191 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); |
| | 192 | } |
| | 193 | |
| | 194 | try writer.writeAll(".{ "); |
| | 195 | |
| | 196 | const max_len = std.math.min(len, max_aggregate_items); |
| 180 | var i: u32 = 0; | 197 | var i: u32 = 0; |
| 181 | while (i < max_len) : (i += 1) { | 198 | while (i < max_len) : (i += 1) { |
| 182 | if (i != 0) try writer.writeAll(", "); | 199 | if (i != 0) try writer.writeAll(", "); |
| 183 | try print(.{ | 200 | try print(.{ |
| 184 | .ty = elem_ty, | 201 | .ty = elem_ty, |
| 185 | .val = val.castTag(.aggregate).?.data[i], | 202 | .val = values.data[i], |
| 186 | }, writer, level - 1, mod); | 203 | }, writer, level - 1, mod); |
| 187 | } | 204 | } |
| 188 | if (len > max_aggregate_items) { | 205 | if (len > max_aggregate_items) { |
| ... | @@ -372,11 +389,28 @@ pub fn print( | ... | @@ -372,11 +389,28 @@ pub fn print( |
| 372 | return writer.writeAll(".{ ... }"); | 389 | return writer.writeAll(".{ ... }"); |
| 373 | } | 390 | } |
| 374 | const payload = val.castTag(.slice).?.data; | 391 | const payload = val.castTag(.slice).?.data; |
| 375 | try writer.writeAll(".{ "); | | |
| 376 | const elem_ty = ty.elemType2(); | 392 | const elem_ty = ty.elemType2(); |
| 377 | const len = payload.len.toUnsignedInt(target); | 393 | const len = payload.len.toUnsignedInt(target); |
| 378 | const max_len = std.math.min(len, max_aggregate_items); | | |
| 379 | | 394 | |
| | 395 | if (elem_ty.eql(Type.u8, mod)) str: { |
| | 396 | const max_len = @intCast(usize, std.math.min(len, max_string_len)); |
| | 397 | var buf: [max_string_len]u8 = undefined; |
| | 398 | |
| | 399 | var i: u32 = 0; |
| | 400 | while (i < max_len) : (i += 1) { |
| | 401 | var elem_buf: Value.ElemValueBuffer = undefined; |
| | 402 | const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf); |
| | 403 | buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str; |
| | 404 | } |
| | 405 | |
| | 406 | // TODO would be nice if this had a bit of unicode awareness. |
| | 407 | const truncated = if (len > max_string_len) " (truncated)" else ""; |
| | 408 | return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); |
| | 409 | } |
| | 410 | |
| | 411 | try writer.writeAll(".{ "); |
| | 412 | |
| | 413 | const max_len = std.math.min(len, max_aggregate_items); |
| 380 | var i: u32 = 0; | 414 | var i: u32 = 0; |
| 381 | while (i < max_len) : (i += 1) { | 415 | while (i < max_len) : (i += 1) { |
| 382 | if (i != 0) try writer.writeAll(", "); | 416 | if (i != 0) try writer.writeAll(", "); |