diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index df762e8fbe7a170ea62820a45a97f148c30d5811..5ddac49ecd6a461411c4db4616142d15b9580ecf 100644 --- 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 index 76e5d11cc46e76cd90aa83601735138367b9d4dd..29eb1ab644bf5b77e0d693bd9aa6cf4f15a92be0 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -471,6 +471,42 @@ 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(); +} + +/// 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); +} + /// An allocator that always fails to allocate. pub const failing: Allocator = .{ .ptr = undefined,