authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-07 15:05:55+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-07 20:32:27+02:00
logf8dcd3477541aabf3bfb05a1d2c51fa3797c0b48
tree165303454d6b604f8ede5c6de11a17a893605351
parent4fb9c75fc944bbc3242feff653aacd69e17b75dc

TypedValue.print: detect string literals

Closes #4281 Closes #13785

1 files changed, 42 insertions(+), 8 deletions(-)

src/TypedValue.zig+42-8
......@@ -46,6 +46,7 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value {
4646}
4747
4848const max_aggregate_items = 100;
49const max_string_len = 256;
4950
5051const FormatContext = struct {
5152 tv: TypedValue,
......@@ -141,10 +142,12 @@ pub fn print(
141142 .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"),
142143 .type_info_type => return writer.writeAll("std.builtin.Type"),
143144
144 .empty_struct_value, .aggregate => {
145 .empty_struct_value => return writer.writeAll(".{}"),
146 .aggregate => {
145147 if (level == 0) {
146148 return writer.writeAll(".{ ... }");
147149 }
150 const values = val.castTag(.aggregate).?;
148151 if (ty.zigTypeTag() == .Struct) {
149152 try writer.writeAll(".{");
150153 const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items);
......@@ -159,9 +162,9 @@ pub fn print(
159162 try print(.{
160163 .ty = ty.structFieldType(i),
161164 .val = switch (ty.containerLayout()) {
162 .Packed => val.castTag(.aggregate).?.data[i],
165 .Packed => values.data[i],
163166 else => ty.structFieldValueComptime(i) orelse b: {
164 const vals = val.castTag(.aggregate).?.data;
167 const vals = values.data;
165168 break :b vals[i];
166169 },
167170 },
......@@ -172,17 +175,31 @@ pub fn print(
172175 }
173176 return writer.writeAll("}");
174177 } else {
175 try writer.writeAll(".{ ");
176178 const elem_ty = ty.elemType2();
177179 const len = ty.arrayLen();
178 const max_len = std.math.min(len, max_aggregate_items);
179180
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);
180197 var i: u32 = 0;
181198 while (i < max_len) : (i += 1) {
182199 if (i != 0) try writer.writeAll(", ");
183200 try print(.{
184201 .ty = elem_ty,
185 .val = val.castTag(.aggregate).?.data[i],
202 .val = values.data[i],
186203 }, writer, level - 1, mod);
187204 }
188205 if (len > max_aggregate_items) {
......@@ -372,11 +389,28 @@ pub fn print(
372389 return writer.writeAll(".{ ... }");
373390 }
374391 const payload = val.castTag(.slice).?.data;
375 try writer.writeAll(".{ ");
376392 const elem_ty = ty.elemType2();
377393 const len = payload.len.toUnsignedInt(target);
378 const max_len = std.math.min(len, max_aggregate_items);
379394
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);
380414 var i: u32 = 0;
381415 while (i < max_len) : (i += 1) {
382416 if (i != 0) try writer.writeAll(", ");