zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 9dda196eea5fc5f299eb87feb93a8d7e756ba2fa (tree)
parent 7ff1556502ac3ec134b3c15d8c70fa9f7845a983
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Thu, 25 Jun 2026 01:59:23 +0200

Merge pull request 'std: move fmt.allocPrint to Allocator and document it' (#35926) from Allocator.print into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35926

Diffstat:
Mlib/std/fmt.zig | 16++++------------
Mlib/std/mem/Allocator.zig | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 62 insertions(+), 14 deletions(-)

diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig @@ -622,27 +622,19 @@ pub fn count(comptime fmt: []const u8, args: anytype) usize { return @intCast(dw.count + dw.writer.end); } +/// Deprecated in favor of `Allocator.print`. pub fn allocPrint(gpa: Allocator, comptime fmt: []const u8, args: anytype) Allocator.Error![]u8 { - var aw = try Writer.Allocating.initCapacity(gpa, fmt.len); - defer aw.deinit(); - aw.writer.print(fmt, args) catch |err| switch (err) { - error.WriteFailed => return error.OutOfMemory, - }; - return aw.toOwnedSlice(); + return gpa.print(fmt, args); } +/// Deprecated in favor of `Allocator.printSentinel`. pub fn allocPrintSentinel( gpa: Allocator, comptime fmt: []const u8, args: anytype, comptime sentinel: u8, ) Allocator.Error![:sentinel]u8 { - var aw = try Writer.Allocating.initCapacity(gpa, fmt.len); - defer aw.deinit(); - aw.writer.print(fmt, args) catch |err| switch (err) { - error.WriteFailed => return error.OutOfMemory, - }; - return aw.toOwnedSliceSentinel(sentinel); + return gpa.printSentinel(fmt, args, sentinel); } pub inline fn comptimePrint(comptime fmt: []const u8, args: anytype) *const [count(fmt, args):0]u8 { diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig @@ -1,11 +1,12 @@ //! The standard memory allocation interface. +const Allocator = @This(); + +const builtin = @import("builtin"); const std = @import("../std.zig"); const assert = std.debug.assert; const math = std.math; const mem = std.mem; -const Allocator = @This(); -const builtin = @import("builtin"); const Alignment = std.mem.Alignment; pub const Error = error{OutOfMemory}; @@ -471,6 +472,61 @@ pub fn dupeSentinel( return new_buf[0..m.len :sentinel]; } +/// Allocates a formatted string which is returned on success. +/// +/// Returned slice can be deallocated with `free`. If an arena-style allocator +/// is used instead, such as `std.heap.ArenaAllocator`, then no call to `free` +/// is necessary. +/// +/// See `std.Io.Writer.print`. +pub fn print(a: Allocator, comptime format: []const u8, args: anytype) Error![]u8 { + var aw = try std.Io.Writer.Allocating.initCapacity(a, format.len); + defer aw.deinit(); + aw.writer.print(format, args) catch |err| switch (err) { + error.WriteFailed => return error.OutOfMemory, + }; + return aw.toOwnedSlice(); +} + +test print { + const x: i32 = -1; + const y: []const u8 = "hi"; + const a = std.testing.allocator; + const s = try print(a, "{d}={s}", .{ x, y }); + defer free(a, s); + try std.testing.expectEqualStrings("-1=hi", s); +} + +/// Like `print` but returned slice has the provided sentinel. +/// +/// Returned slice can be deallocated with `free`. If an arena-style allocator +/// is used instead, such as `std.heap.ArenaAllocator`, then no call to `free` +/// is necessary. Illegal behavior occurs if the returned slice is type-coerced +/// to a slice without the sentinel and then passed to `free`. +pub fn printSentinel( + a: Allocator, + comptime format: []const u8, + args: anytype, + comptime sentinel: u8, +) Allocator.Error![:sentinel]u8 { + var aw = try std.Io.Writer.Allocating.initCapacity(a, format.len); + defer aw.deinit(); + aw.writer.print(format, args) catch |err| switch (err) { + error.WriteFailed => return error.OutOfMemory, + }; + return aw.toOwnedSliceSentinel(sentinel); +} + +test printSentinel { + const x: i32 = -1; + const y: []const u8 = "hi"; + const a = std.testing.allocator; + const s = try printSentinel(a, "{d}={s}", .{ x, y }, 0); + defer free(a, s); + try std.testing.expectEqualStrings("-1=hi", s); + try std.testing.expectEqual(0, s[s.len]); +} + /// An allocator that always fails to allocate. pub const failing: Allocator = .{ .ptr = undefined,