| ... | ... | @@ -367,6 +367,36 @@ pub fn format( |
| 367 | 367 | } |
| 368 | 368 | } |
| 369 | 369 | |
| 370 | pub fn formatAddress(value: anytype, options: FormatOptions, writer: anytype) @TypeOf(writer).Error!void { |
| 371 | const T = @TypeOf(value); |
| 372 | |
| 373 | switch (@typeInfo(T)) { |
| 374 | .Pointer => |info| { |
| 375 | try writer.writeAll(@typeName(info.child) ++ "@"); |
| 376 | if (info.size == .Slice) |
| 377 | try formatInt(@ptrToInt(value.ptr), 16, false, FormatOptions{}, writer) |
| 378 | else |
| 379 | try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer); |
| 380 | return; |
| 381 | }, |
| 382 | .Optional => |info| { |
| 383 | if (@typeInfo(info.child) == .Pointer) { |
| 384 | try writer.writeAll(@typeName(info.child) ++ "@"); |
| 385 | try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer); |
| 386 | return; |
| 387 | } |
| 388 | }, |
| 389 | .Array => |info| { |
| 390 | try writer.writeAll(@typeName(info.child) ++ "@"); |
| 391 | try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer); |
| 392 | return; |
| 393 | }, |
| 394 | else => {}, |
| 395 | } |
| 396 | |
| 397 | @compileError("Cannot format non-pointer type " ++ @typeName(T) ++ " with * specifier"); |
| 398 | } |
| 399 | |
| 370 | 400 | pub fn formatType( |
| 371 | 401 | value: anytype, |
| 372 | 402 | comptime fmt: []const u8, |
| ... | ... | @@ -375,10 +405,7 @@ pub fn formatType( |
| 375 | 405 | max_depth: usize, |
| 376 | 406 | ) @TypeOf(writer).Error!void { |
| 377 | 407 | if (comptime std.mem.eql(u8, fmt, "*")) { |
| 378 | | try writer.writeAll(@typeName(std.meta.Child(@TypeOf(value)))); |
| 379 | | try writer.writeAll("@"); |
| 380 | | try formatInt(@ptrToInt(value), 16, false, FormatOptions{}, writer); |
| 381 | | return; |
| 408 | return formatAddress(value, options, writer); |
| 382 | 409 | } |
| 383 | 410 | |
| 384 | 411 | const T = @TypeOf(value); |
| ... | ... | @@ -499,25 +526,18 @@ pub fn formatType( |
| 499 | 526 | return format(writer, "{}@{x}", .{ @typeName(@typeInfo(T).Pointer.child), @ptrToInt(value) }); |
| 500 | 527 | }, |
| 501 | 528 | .Slice => { |
| 502 | | if (fmt.len > 0 and ((fmt[0] == 'x') or (fmt[0] == 'X'))) { |
| 503 | | return formatText(value, fmt, options, writer); |
| 504 | | } |
| 505 | 529 | if (ptr_info.child == u8) { |
| 506 | 530 | return formatText(value, fmt, options, writer); |
| 507 | | } else if (fmt.len > 0 and ((fmt[0] == 'v') or (fmt[0] == 'V'))) { |
| 508 | | try format(writer, "[", .{}); |
| 509 | | var i: usize = 0; |
| 510 | | for (value) |one| { |
| 511 | | if (i == value.len - 1) { |
| 512 | | try format(writer, "{}", .{one}); |
| 513 | | } else { |
| 514 | | try format(writer, "{}, ", .{one}); |
| 515 | | } |
| 516 | | i += 1; |
| 531 | } |
| 532 | |
| 533 | try writer.writeAll("["); |
| 534 | for (value) |elem, i| { |
| 535 | try formatType(elem, fmt, options, writer, max_depth); |
| 536 | if (i != value.len - 1) { |
| 537 | try writer.writeAll(", "); |
| 517 | 538 | } |
| 518 | | return format(writer, "]", .{}); |
| 519 | 539 | } |
| 520 | | return format(writer, "{}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value.ptr) }); |
| 540 | try writer.writeAll("]"); |
| 521 | 541 | }, |
| 522 | 542 | }, |
| 523 | 543 | .Array => |info| { |
| ... | ... | @@ -1553,7 +1573,7 @@ test "slice" { |
| 1553 | 1573 | { |
| 1554 | 1574 | var runtime_zero: usize = 0; |
| 1555 | 1575 | const value = @intToPtr([*]align(1) const []const u8, 0xdeadbeef)[runtime_zero..runtime_zero]; |
| 1556 | | try testFmt("slice: []const u8@deadbeef\n", "slice: {}\n", .{value}); |
| 1576 | try testFmt("slice: []const u8@deadbeef\n", "slice: {*}\n", .{value}); |
| 1557 | 1577 | } |
| 1558 | 1578 | { |
| 1559 | 1579 | const null_term_slice: [:0]const u8 = "\x00hello\x00"; |
| ... | ... | @@ -1562,6 +1582,15 @@ test "slice" { |
| 1562 | 1582 | |
| 1563 | 1583 | try testFmt("buf: Test\n", "buf: {s:5}\n", .{"Test"}); |
| 1564 | 1584 | try testFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"}); |
| 1585 | |
| 1586 | { |
| 1587 | var int_slice = [_]u32{ 1, 4096, 391891, 1111111111 }; |
| 1588 | var runtime_zero: usize = 0; |
| 1589 | try testFmt("int: [1, 4096, 391891, 1111111111]", "int: {}", .{int_slice[runtime_zero..]}); |
| 1590 | try testFmt("int: [1, 4096, 391891, 1111111111]", "int: {d}", .{int_slice[runtime_zero..]}); |
| 1591 | try testFmt("int: [1, 1000, 5fad3, 423a35c7]", "int: {x}", .{int_slice[runtime_zero..]}); |
| 1592 | try testFmt("int: [00001, 01000, 5fad3, 423a35c7]", "int: {x:0>5}", .{int_slice[runtime_zero..]}); |
| 1593 | } |
| 1565 | 1594 | } |
| 1566 | 1595 | |
| 1567 | 1596 | test "escape non-printable" { |