From 26d5cc694a4746b886a9f1949603440b6f2c0ad8 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 8 Jul 2025 11:43:49 +0200 Subject: [PATCH] Formatting option "%h" now supports pointers. --- lib/std/io/formatter.c3 | 5 +++++ releasenotes.md | 1 + src/compiler/compiler_internal.h | 3 ++- src/compiler/sema_expr.c | 4 ++-- test/test_suite/attributes/format_h.c3t | 13 +++++++++++++ 5 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 test/test_suite/attributes/format_h.c3t diff --git a/lib/std/io/formatter.c3 b/lib/std/io/formatter.c3 index 491a9ba60..db21b9bca 100644 --- a/lib/std/io/formatter.c3 +++ b/lib/std/io/formatter.c3 @@ -495,6 +495,11 @@ fn usz? Formatter.vprintf(&self, String format, any[] anys) out = ((char*)current.ptr)[:current.type.sizeof]; break; } + if (current.type.kindof == POINTER) + { + out = ((*(char**)current.ptr))[:current.type.inner.sizeof]; + break; + } total_len += self.out_substr("")!; continue; } diff --git a/releasenotes.md b/releasenotes.md index 047b08e7b..7a1a39748 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -12,6 +12,7 @@ - Catch accidental `foo == BAR;` where `foo = BAR;` was most likely intended. #2274 - Improve error message when doing a rethrow in a function that doesn't return an optional. - Add `--list-asm` to view all supported `asm` instructions. +- Formatting option "%h" now supports pointers. ### Fixes - mkdir/rmdir would not work properly with substring paths on non-windows platforms. diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index f50683870..1c7f5acb9 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -3241,9 +3241,10 @@ static inline Type *type_flatten_no_export(Type *type) } } -static inline bool type_flat_is_char_array_slice(Type *type) +static inline bool type_flat_is_valid_for_arg_h(Type *type) { type = type_flatten(type); + if (type->type_kind == TYPE_POINTER) return true; if (type->type_kind != TYPE_ARRAY && type->type_kind != TYPE_SLICE) return false; switch (type->array.base->type_kind) { diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index e8ed0b7ad..e1cc4431e 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2168,9 +2168,9 @@ NEXT_FLAG: goto NEXT; case 'H': case 'h': - if (!type_flat_is_char_array_slice(type)) + if (!type_flat_is_valid_for_arg_h(type)) { - RETURN_SEMA_ERROR(vaargs[idx], "Expected a char array or slice here."); + RETURN_SEMA_ERROR(vaargs[idx], "Expected a pointer, char array or slice here."); } goto NEXT; default: diff --git a/test/test_suite/attributes/format_h.c3t b/test/test_suite/attributes/format_h.c3t new file mode 100644 index 000000000..940f53e01 --- /dev/null +++ b/test/test_suite/attributes/format_h.c3t @@ -0,0 +1,13 @@ +module test; +import std; + +struct Foo +{ + int x, y; +} +fn int main() +{ + Foo f = { 33, 12323 }; + io::printfn("%h", &f); + return 0; +}