std: Use {s} instead of {} when printing strings

This commit is contained in:
LemonBoy 2020-11-26 09:48:12 +01:00 committed by Andrew Kelley
parent 5a06fdfa55
commit dd973fb365
32 changed files with 771 additions and 231 deletions

View File

@ -164,8 +164,8 @@ pub fn format(
) !void {
if (fmt.len != 0) @compileError("Unknown format string: '" ++ fmt ++ "'");
try std.fmt.format(out_stream, "{}.{}.{}", .{ self.major, self.minor, self.patch });
if (self.pre) |pre| try std.fmt.format(out_stream, "-{}", .{pre});
if (self.build) |build| try std.fmt.format(out_stream, "+{}", .{build});
if (self.pre) |pre| try std.fmt.format(out_stream, "-{s}", .{pre});
if (self.build) |build| try std.fmt.format(out_stream, "+{s}", .{build});
}
const expect = std.testing.expect;
@ -287,9 +287,9 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: anytype) !
if (std.mem.eql(u8, result, expected)) return;
std.debug.warn("\n====== expected this output: =========\n", .{});
std.debug.warn("{}", .{expected});
std.debug.warn("{s}", .{expected});
std.debug.warn("\n======== instead found this: =========\n", .{});
std.debug.warn("{}", .{result});
std.debug.warn("{s}", .{result});
std.debug.warn("\n======================================\n", .{});
return error.TestFailed;
}

View File

@ -0,0 +1,229 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std.zig");
const debug = std.debug;
const mem = std.mem;
const Allocator = mem.Allocator;
const assert = debug.assert;
const testing = std.testing;
const ArrayList = std.ArrayList;
/// A contiguous, growable list of items in memory, with a sentinel after them.
/// The sentinel is maintained when appending, resizing, etc.
/// If you do not need a sentinel, consider using `ArrayList` instead.
pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
return struct {
list: ArrayList(T),
const Self = @This();
/// Must deinitialize with deinit.
pub fn init(allocator: *Allocator, m: []const T) !Self {
var self = try initSize(allocator, m.len);
mem.copy(T, self.list.items, m);
return self;
}
/// Initialize memory to size bytes of undefined values.
/// Must deinitialize with deinit.
pub fn initSize(allocator: *Allocator, size: usize) !Self {
var self = initNull(allocator);
try self.resize(size);
return self;
}
/// Initialize with capacity to hold at least num bytes.
/// Must deinitialize with deinit.
pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
var self = Self{ .list = try ArrayList(T).initCapacity(allocator, num + 1) };
self.list.appendAssumeCapacity(sentinel);
return self;
}
/// Must deinitialize with deinit.
/// None of the other operations are valid until you do one of these:
/// * `replaceContents`
/// * `resize`
pub fn initNull(allocator: *Allocator) Self {
return Self{ .list = ArrayList(T).init(allocator) };
}
/// Must deinitialize with deinit.
pub fn initFromBuffer(buffer: Self) !Self {
return Self.init(buffer.list.allocator, buffer.span());
}
/// Takes ownership of the passed in slice. The slice must have been
/// allocated with `allocator`.
/// Must deinitialize with deinit.
pub fn fromOwnedSlice(allocator: *Allocator, slice: []T) !Self {
var self = Self{ .list = ArrayList(T).fromOwnedSlice(allocator, slice) };
try self.list.append(sentinel);
return self;
}
/// The caller owns the returned memory. The list becomes null and is safe to `deinit`.
pub fn toOwnedSlice(self: *Self) [:sentinel]T {
const allocator = self.list.allocator;
const result = self.list.toOwnedSlice();
self.* = initNull(allocator);
return result[0 .. result.len - 1 :sentinel];
}
/// Only works when `T` is `u8`.
pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: anytype) !Self {
const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
error.Overflow => return error.OutOfMemory,
};
var self = try Self.initSize(allocator, size);
assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
return self;
}
pub fn deinit(self: *Self) void {
self.list.deinit();
}
pub fn span(self: anytype) @TypeOf(self.list.items[0..:sentinel]) {
return self.list.items[0..self.len() :sentinel];
}
pub fn shrink(self: *Self, new_len: usize) void {
assert(new_len <= self.len());
self.list.shrink(new_len + 1);
self.list.items[self.len()] = sentinel;
}
pub fn resize(self: *Self, new_len: usize) !void {
try self.list.resize(new_len + 1);
self.list.items[self.len()] = sentinel;
}
pub fn isNull(self: Self) bool {
return self.list.items.len == 0;
}
pub fn len(self: Self) usize {
return self.list.items.len - 1;
}
pub fn capacity(self: Self) usize {
return if (self.list.capacity > 0)
self.list.capacity - 1
else
0;
}
pub fn appendSlice(self: *Self, m: []const T) !void {
const old_len = self.len();
try self.resize(old_len + m.len);
mem.copy(T, self.list.items[old_len..], m);
}
pub fn append(self: *Self, byte: T) !void {
const old_len = self.len();
try self.resize(old_len + 1);
self.list.items[old_len] = byte;
}
pub fn eql(self: Self, m: []const T) bool {
return mem.eql(T, self.span(), m);
}
pub fn startsWith(self: Self, m: []const T) bool {
if (self.len() < m.len) return false;
return mem.eql(T, self.list.items[0..m.len], m);
}
pub fn endsWith(self: Self, m: []const T) bool {
const l = self.len();
if (l < m.len) return false;
const start = l - m.len;
return mem.eql(T, self.list.items[start..l], m);
}
pub fn replaceContents(self: *Self, m: []const T) !void {
try self.resize(m.len);
mem.copy(T, self.list.items, m);
}
/// Initializes an OutStream which will append to the list.
/// This function may be called only when `T` is `u8`.
pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
return .{ .context = self };
}
/// Same as `append` except it returns the number of bytes written, which is always the same
/// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
/// This function may be called only when `T` is `u8`.
pub fn appendWrite(self: *Self, m: []const u8) !usize {
try self.appendSlice(m);
return m.len;
}
};
}
test "simple" {
var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
defer buf.deinit();
testing.expect(buf.len() == 0);
try buf.appendSlice("hello");
try buf.appendSlice(" ");
try buf.appendSlice("world");
testing.expect(buf.eql("hello world"));
testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
var buf2 = try ArrayListSentineled(u8, 0).initFromBuffer(buf);
defer buf2.deinit();
testing.expect(buf.eql(buf2.span()));
testing.expect(buf.startsWith("hell"));
testing.expect(buf.endsWith("orld"));
try buf2.resize(4);
testing.expect(buf.startsWith(buf2.span()));
}
test "initSize" {
var buf = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 3);
defer buf.deinit();
testing.expect(buf.len() == 3);
try buf.appendSlice("hello");
testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
}
test "initCapacity" {
var buf = try ArrayListSentineled(u8, 0).initCapacity(testing.allocator, 10);
defer buf.deinit();
testing.expect(buf.len() == 0);
testing.expect(buf.capacity() >= 10);
const old_cap = buf.capacity();
try buf.appendSlice("hello");
testing.expect(buf.len() == 5);
testing.expect(buf.capacity() == old_cap);
testing.expect(mem.eql(u8, buf.span(), "hello"));
}
test "print" {
var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
defer buf.deinit();
try buf.outStream().print("Hello {d} the {s}", .{ 2, "world" });
testing.expect(buf.eql("Hello 2 the world"));
}
test "outStream" {
var buffer = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 0);
defer buffer.deinit();
const buf_stream = buffer.outStream();
const x: i32 = 42;
const y: i32 = 1234;
try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
}

View File

@ -294,7 +294,7 @@ pub const Builder = struct {
/// To run an executable built with zig build, see `LibExeObjStep.run`.
pub fn addSystemCommand(self: *Builder, argv: []const []const u8) *RunStep {
assert(argv.len >= 1);
const run_step = RunStep.create(self, self.fmt("run {}", .{argv[0]}));
const run_step = RunStep.create(self, self.fmt("run {s}", .{argv[0]}));
run_step.addArgs(argv);
return run_step;
}
@ -409,7 +409,7 @@ pub const Builder = struct {
for (self.installed_files.items) |installed_file| {
const full_path = self.getInstallPath(installed_file.dir, installed_file.path);
if (self.verbose) {
warn("rm {}\n", .{full_path});
warn("rm {s}\n", .{full_path});
}
fs.cwd().deleteTree(full_path) catch {};
}
@ -419,7 +419,7 @@ pub const Builder = struct {
fn makeOneStep(self: *Builder, s: *Step) anyerror!void {
if (s.loop_flag) {
warn("Dependency loop detected:\n {}\n", .{s.name});
warn("Dependency loop detected:\n {s}\n", .{s.name});
return error.DependencyLoopDetected;
}
s.loop_flag = true;
@ -427,7 +427,7 @@ pub const Builder = struct {
for (s.dependencies.items) |dep| {
self.makeOneStep(dep) catch |err| {
if (err == error.DependencyLoopDetected) {
warn(" {}\n", .{s.name});
warn(" {s}\n", .{s.name});
}
return err;
};
@ -444,7 +444,7 @@ pub const Builder = struct {
return &top_level_step.step;
}
}
warn("Cannot run step '{}' because it does not exist\n", .{name});
warn("Cannot run step '{s}' because it does not exist\n", .{name});
return error.InvalidStepName;
}
@ -456,7 +456,7 @@ pub const Builder = struct {
.description = description,
};
if ((self.available_options_map.fetchPut(name, available_option) catch unreachable) != null) {
panic("Option '{}' declared twice", .{name});
panic("Option '{s}' declared twice", .{name});
}
self.available_options_list.append(available_option) catch unreachable;
@ -471,32 +471,32 @@ pub const Builder = struct {
} else if (mem.eql(u8, s, "false")) {
return false;
} else {
warn("Expected -D{} to be a boolean, but received '{}'\n\n", .{ name, s });
warn("Expected -D{s} to be a boolean, but received '{s}'\n\n", .{ name, s });
self.markInvalidUserInput();
return null;
}
},
.List => {
warn("Expected -D{} to be a boolean, but received a list.\n\n", .{name});
warn("Expected -D{s} to be a boolean, but received a list.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
},
.Int => switch (entry.value.value) {
.Flag => {
warn("Expected -D{} to be an integer, but received a boolean.\n\n", .{name});
warn("Expected -D{s} to be an integer, but received a boolean.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
.Scalar => |s| {
const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {
error.Overflow => {
warn("-D{} value {} cannot fit into type {}.\n\n", .{ name, s, @typeName(T) });
warn("-D{s} value {} cannot fit into type {s}.\n\n", .{ name, s, @typeName(T) });
self.markInvalidUserInput();
return null;
},
else => {
warn("Expected -D{} to be an integer of type {}.\n\n", .{ name, @typeName(T) });
warn("Expected -D{s} to be an integer of type {s}.\n\n", .{ name, @typeName(T) });
self.markInvalidUserInput();
return null;
},
@ -504,34 +504,34 @@ pub const Builder = struct {
return n;
},
.List => {
warn("Expected -D{} to be an integer, but received a list.\n\n", .{name});
warn("Expected -D{s} to be an integer, but received a list.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
},
.Float => switch (entry.value.value) {
.Flag => {
warn("Expected -D{} to be a float, but received a boolean.\n\n", .{name});
warn("Expected -D{s} to be a float, but received a boolean.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
.Scalar => |s| {
const n = std.fmt.parseFloat(T, s) catch |err| {
warn("Expected -D{} to be a float of type {}.\n\n", .{ name, @typeName(T) });
warn("Expected -D{s} to be a float of type {s}.\n\n", .{ name, @typeName(T) });
self.markInvalidUserInput();
return null;
};
return n;
},
.List => {
warn("Expected -D{} to be a float, but received a list.\n\n", .{name});
warn("Expected -D{s} to be a float, but received a list.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
},
.Enum => switch (entry.value.value) {
.Flag => {
warn("Expected -D{} to be a string, but received a boolean.\n\n", .{name});
warn("Expected -D{s} to be a string, but received a boolean.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
@ -539,25 +539,25 @@ pub const Builder = struct {
if (std.meta.stringToEnum(T, s)) |enum_lit| {
return enum_lit;
} else {
warn("Expected -D{} to be of type {}.\n\n", .{ name, @typeName(T) });
warn("Expected -D{s} to be of type {s}.\n\n", .{ name, @typeName(T) });
self.markInvalidUserInput();
return null;
}
},
.List => {
warn("Expected -D{} to be a string, but received a list.\n\n", .{name});
warn("Expected -D{s} to be a string, but received a list.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
},
.String => switch (entry.value.value) {
.Flag => {
warn("Expected -D{} to be a string, but received a boolean.\n\n", .{name});
warn("Expected -D{s} to be a string, but received a boolean.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
.List => {
warn("Expected -D{} to be a string, but received a list.\n\n", .{name});
warn("Expected -D{s} to be a string, but received a list.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
@ -565,7 +565,7 @@ pub const Builder = struct {
},
.List => switch (entry.value.value) {
.Flag => {
warn("Expected -D{} to be a list, but received a boolean.\n\n", .{name});
warn("Expected -D{s} to be a list, but received a boolean.\n\n", .{name});
self.markInvalidUserInput();
return null;
},
@ -592,7 +592,7 @@ pub const Builder = struct {
if (self.release_mode != null) {
@panic("setPreferredReleaseMode must be called before standardReleaseOptions and may not be called twice");
}
const description = self.fmt("Create a release build ({})", .{@tagName(mode)});
const description = self.fmt("Create a release build ({s})", .{@tagName(mode)});
self.is_release = self.option(bool, "release", description) orelse false;
self.release_mode = if (self.is_release) mode else builtin.Mode.Debug;
}
@ -646,12 +646,12 @@ pub const Builder = struct {
.diagnostics = &diags,
}) catch |err| switch (err) {
error.UnknownCpuModel => {
warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
warn("Unknown CPU: '{s}'\nAvailable CPUs for architecture '{s}':\n", .{
diags.cpu_name.?,
@tagName(diags.arch.?),
});
for (diags.arch.?.allCpuModels()) |cpu| {
warn(" {}\n", .{cpu.name});
warn(" {s}\n", .{cpu.name});
}
warn("\n", .{});
self.markInvalidUserInput();
@ -659,15 +659,15 @@ pub const Builder = struct {
},
error.UnknownCpuFeature => {
warn(
\\Unknown CPU feature: '{}'
\\Available CPU features for architecture '{}':
\\Unknown CPU feature: '{s}'
\\Available CPU features for architecture '{s}':
\\
, .{
diags.unknown_feature_name,
@tagName(diags.arch.?),
});
for (diags.arch.?.allFeaturesList()) |feature| {
warn(" {}: {}\n", .{ feature.name, feature.description });
warn(" {s}: {s}\n", .{ feature.name, feature.description });
}
warn("\n", .{});
self.markInvalidUserInput();
@ -675,19 +675,19 @@ pub const Builder = struct {
},
error.UnknownOperatingSystem => {
warn(
\\Unknown OS: '{}'
\\Unknown OS: '{s}'
\\Available operating systems:
\\
, .{diags.os_name});
inline for (std.meta.fields(std.Target.Os.Tag)) |field| {
warn(" {}\n", .{field.name});
warn(" {s}\n", .{field.name});
}
warn("\n", .{});
self.markInvalidUserInput();
return args.default_target;
},
else => |e| {
warn("Unable to parse target '{}': {}\n\n", .{ triple, @errorName(e) });
warn("Unable to parse target '{}': {s}\n\n", .{ triple, @errorName(e) });
self.markInvalidUserInput();
return args.default_target;
},
@ -703,12 +703,12 @@ pub const Builder = struct {
break :whitelist_check;
}
}
warn("Chosen target '{}' does not match one of the supported targets:\n", .{
warn("Chosen target '{s}' does not match one of the supported targets:\n", .{
selected_canonicalized_triple,
});
for (list) |t| {
const t_triple = t.zigTriple(self.allocator) catch unreachable;
warn(" {}\n", .{t_triple});
warn(" {s}\n", .{t_triple});
}
warn("\n", .{});
self.markInvalidUserInput();
@ -752,7 +752,7 @@ pub const Builder = struct {
}) catch unreachable;
},
UserValue.Flag => {
warn("Option '-D{}={}' conflicts with flag '-D{}'.\n", .{ name, value, name });
warn("Option '-D{s}={s}' conflicts with flag '-D{s}'.\n", .{ name, value, name });
return true;
},
}
@ -773,11 +773,11 @@ pub const Builder = struct {
// option already exists
switch (gop.entry.value.value) {
UserValue.Scalar => |s| {
warn("Flag '-D{}' conflicts with option '-D{}={}'.\n", .{ name, name, s });
warn("Flag '-D{s}' conflicts with option '-D{s}={s}'.\n", .{ name, name, s });
return true;
},
UserValue.List => {
warn("Flag '-D{}' conflicts with multiple options of the same name.\n", .{name});
warn("Flag '-D{s}' conflicts with multiple options of the same name.\n", .{name});
return true;
},
UserValue.Flag => {},
@ -820,7 +820,7 @@ pub const Builder = struct {
while (true) {
const entry = it.next() orelse break;
if (!entry.value.used) {
warn("Invalid option: -D{}\n\n", .{entry.key});
warn("Invalid option: -D{s}\n\n", .{entry.key});
self.markInvalidUserInput();
}
}
@ -833,9 +833,9 @@ pub const Builder = struct {
}
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
if (cwd) |yes_cwd| warn("cd {} && ", .{yes_cwd});
if (cwd) |yes_cwd| warn("cd {s} && ", .{yes_cwd});
for (argv) |arg| {
warn("{} ", .{arg});
warn("{s} ", .{arg});
}
warn("\n", .{});
}
@ -852,7 +852,7 @@ pub const Builder = struct {
child.env_map = env_map;
const term = child.spawnAndWait() catch |err| {
warn("Unable to spawn {}: {}\n", .{ argv[0], @errorName(err) });
warn("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
return err;
};
@ -875,7 +875,7 @@ pub const Builder = struct {
pub fn makePath(self: *Builder, path: []const u8) !void {
fs.cwd().makePath(self.pathFromRoot(path)) catch |err| {
warn("Unable to create path {}: {}\n", .{ path, @errorName(err) });
warn("Unable to create path {s}: {s}\n", .{ path, @errorName(err) });
return err;
};
}
@ -959,7 +959,7 @@ pub const Builder = struct {
pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
if (self.verbose) {
warn("cp {} {} ", .{ source_path, dest_path });
warn("cp {s} {s} ", .{ source_path, dest_path });
}
const cwd = fs.cwd();
const prev_status = try fs.Dir.updateFile(cwd, source_path, cwd, dest_path, .{});
@ -988,7 +988,7 @@ pub const Builder = struct {
const full_path = try fs.path.join(self.allocator, &[_][]const u8{
search_prefix,
"bin",
self.fmt("{}{}", .{ name, exe_extension }),
self.fmt("{s}{s}", .{ name, exe_extension }),
});
return fs.realpathAlloc(self.allocator, full_path) catch continue;
}
@ -1002,7 +1002,7 @@ pub const Builder = struct {
while (it.next()) |path| {
const full_path = try fs.path.join(self.allocator, &[_][]const u8{
path,
self.fmt("{}{}", .{ name, exe_extension }),
self.fmt("{s}{s}", .{ name, exe_extension }),
});
return fs.realpathAlloc(self.allocator, full_path) catch continue;
}
@ -1015,7 +1015,7 @@ pub const Builder = struct {
for (paths) |path| {
const full_path = try fs.path.join(self.allocator, &[_][]const u8{
path,
self.fmt("{}{}", .{ name, exe_extension }),
self.fmt("{s}{s}", .{ name, exe_extension }),
});
return fs.realpathAlloc(self.allocator, full_path) catch continue;
}
@ -1070,19 +1070,19 @@ pub const Builder = struct {
var code: u8 = undefined;
return self.execAllowFail(argv, &code, .Inherit) catch |err| switch (err) {
error.FileNotFound => {
if (src_step) |s| warn("{}...", .{s.name});
if (src_step) |s| warn("{s}...", .{s.name});
warn("Unable to spawn the following command: file not found\n", .{});
printCmd(null, argv);
std.os.exit(@truncate(u8, code));
},
error.ExitCodeFailure => {
if (src_step) |s| warn("{}...", .{s.name});
warn("The following command exited with error code {}:\n", .{code});
if (src_step) |s| warn("{s}...", .{s.name});
warn("The following command exited with error code {d}:\n", .{code});
printCmd(null, argv);
std.os.exit(@truncate(u8, code));
},
error.ProcessTerminated => {
if (src_step) |s| warn("{}...", .{s.name});
if (src_step) |s| warn("{s}...", .{s.name});
warn("The following command terminated unexpectedly:\n", .{});
printCmd(null, argv);
std.os.exit(@truncate(u8, code));
@ -1405,7 +1405,7 @@ pub const LibExeObjStep = struct {
ver: ?Version,
) LibExeObjStep {
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) {
panic("invalid name: '{}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
panic("invalid name: '{s}'. It looks like a file path, but it is supposed to be the library or application name.", .{name});
}
var self = LibExeObjStep{
.strip = false,
@ -1421,9 +1421,9 @@ pub const LibExeObjStep = struct {
.step = Step.init(.LibExeObj, name, builder.allocator, make),
.version = ver,
.out_filename = undefined,
.out_h_filename = builder.fmt("{}.h", .{name}),
.out_h_filename = builder.fmt("{s}.h", .{name}),
.out_lib_filename = undefined,
.out_pdb_filename = builder.fmt("{}.pdb", .{name}),
.out_pdb_filename = builder.fmt("{s}.pdb", .{name}),
.major_only_filename = undefined,
.name_only_filename = undefined,
.packages = ArrayList(Pkg).init(builder.allocator),
@ -1529,7 +1529,7 @@ pub const LibExeObjStep = struct {
// It doesn't have to be native. We catch that if you actually try to run it.
// Consider that this is declarative; the run step may not be run unless a user
// option is supplied.
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {}", .{exe.step.name}));
const run_step = RunStep.create(exe.builder, exe.builder.fmt("run {s}", .{exe.step.name}));
run_step.addArtifactArg(exe);
if (exe.vcpkg_bin_path) |path| {
@ -1680,7 +1680,7 @@ pub const LibExeObjStep = struct {
} else if (mem.eql(u8, tok, "-pthread")) {
self.linkLibC();
} else if (self.builder.verbose) {
warn("Ignoring pkg-config flag '{}'\n", .{tok});
warn("Ignoring pkg-config flag '{s}'\n", .{tok});
}
}
}
@ -1926,7 +1926,7 @@ pub const LibExeObjStep = struct {
},
else => {},
}
out.print("pub const {z}: {} = {};\n", .{ name, @typeName(T), value }) catch unreachable;
out.print("pub const {z}: {s} = {};\n", .{ name, @typeName(T), value }) catch unreachable;
}
/// The value is the path in the cache dir.
@ -2048,7 +2048,7 @@ pub const LibExeObjStep = struct {
const builder = self.builder;
if (self.root_src == null and self.link_objects.items.len == 0) {
warn("{}: linker needs 1 or more objects to link\n", .{self.step.name});
warn("{s}: linker needs 1 or more objects to link\n", .{self.step.name});
return error.NeedAnObject;
}
@ -2156,12 +2156,12 @@ pub const LibExeObjStep = struct {
// Render build artifact options at the last minute, now that the path is known.
for (self.build_options_artifact_args.items) |item| {
const out = self.build_options_contents.writer();
out.print("pub const {}: []const u8 = \"{Z}\";\n", .{ item.name, item.artifact.getOutputPath() }) catch unreachable;
out.print("pub const {s}: []const u8 = \"{Z}\";\n", .{ item.name, item.artifact.getOutputPath() }) catch unreachable;
}
const build_options_file = try fs.path.join(
builder.allocator,
&[_][]const u8{ builder.cache_root, builder.fmt("{}_build_options.zig", .{self.name}) },
&[_][]const u8{ builder.cache_root, builder.fmt("{s}_build_options.zig", .{self.name}) },
);
const path_from_root = builder.pathFromRoot(build_options_file);
try fs.cwd().writeFile(path_from_root, self.build_options_contents.items);
@ -2294,16 +2294,16 @@ pub const LibExeObjStep = struct {
} else {
var mcpu_buffer = std.ArrayList(u8).init(builder.allocator);
try mcpu_buffer.outStream().print("-mcpu={}", .{cross.cpu.model.name});
try mcpu_buffer.outStream().print("-mcpu={s}", .{cross.cpu.model.name});
for (all_features) |feature, i_usize| {
const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
const in_cpu_set = populated_cpu_features.isEnabled(i);
const in_actual_set = cross.cpu.features.isEnabled(i);
if (in_cpu_set and !in_actual_set) {
try mcpu_buffer.outStream().print("-{}", .{feature.name});
try mcpu_buffer.outStream().print("-{s}", .{feature.name});
} else if (!in_cpu_set and in_actual_set) {
try mcpu_buffer.outStream().print("+{}", .{feature.name});
try mcpu_buffer.outStream().print("+{s}", .{feature.name});
}
}
@ -2536,7 +2536,7 @@ pub const InstallArtifactStep = struct {
const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.builder = builder,
.step = Step.init(.InstallArtifact, builder.fmt("install {}", .{artifact.step.name}), builder.allocator, make),
.step = Step.init(.InstallArtifact, builder.fmt("install {s}", .{artifact.step.name}), builder.allocator, make),
.artifact = artifact,
.dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
.Obj => unreachable,
@ -2612,7 +2612,7 @@ pub const InstallFileStep = struct {
builder.pushInstalledFile(dir, dest_rel_path);
return InstallFileStep{
.builder = builder,
.step = Step.init(.InstallFile, builder.fmt("install {}", .{src_path}), builder.allocator, make),
.step = Step.init(.InstallFile, builder.fmt("install {s}", .{src_path}), builder.allocator, make),
.src_path = src_path,
.dir = dir,
.dest_rel_path = dest_rel_path,
@ -2646,7 +2646,7 @@ pub const InstallDirStep = struct {
builder.pushInstalledFile(options.install_dir, options.install_subdir);
return InstallDirStep{
.builder = builder,
.step = Step.init(.InstallDir, builder.fmt("install {}/", .{options.source_dir}), builder.allocator, make),
.step = Step.init(.InstallDir, builder.fmt("install {s}/", .{options.source_dir}), builder.allocator, make),
.options = options,
};
}
@ -2682,14 +2682,14 @@ pub const LogStep = struct {
pub fn init(builder: *Builder, data: []const u8) LogStep {
return LogStep{
.builder = builder,
.step = Step.init(.Log, builder.fmt("log {}", .{data}), builder.allocator, make),
.step = Step.init(.Log, builder.fmt("log {s}", .{data}), builder.allocator, make),
.data = data,
};
}
fn make(step: *Step) anyerror!void {
const self = @fieldParentPtr(LogStep, "step", step);
warn("{}", .{self.data});
warn("{s}", .{self.data});
}
};
@ -2701,7 +2701,7 @@ pub const RemoveDirStep = struct {
pub fn init(builder: *Builder, dir_path: []const u8) RemoveDirStep {
return RemoveDirStep{
.builder = builder,
.step = Step.init(.RemoveDir, builder.fmt("RemoveDir {}", .{dir_path}), builder.allocator, make),
.step = Step.init(.RemoveDir, builder.fmt("RemoveDir {s}", .{dir_path}), builder.allocator, make),
.dir_path = dir_path,
};
}
@ -2711,7 +2711,7 @@ pub const RemoveDirStep = struct {
const full_path = self.builder.pathFromRoot(self.dir_path);
fs.cwd().deleteTree(full_path) catch |err| {
warn("Unable to remove {}: {}\n", .{ full_path, @errorName(err) });
warn("Unable to remove {s}: {s}\n", .{ full_path, @errorName(err) });
return err;
};
}
@ -2799,7 +2799,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
&[_][]const u8{ out_dir, filename_major_only },
) catch unreachable;
fs.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", .{ major_only_path, out_basename });
warn("Unable to symlink {s} -> {s}\n", .{ major_only_path, out_basename });
return err;
};
// sym link for libfoo.so to libfoo.so.1
@ -2808,7 +2808,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
&[_][]const u8{ out_dir, filename_name_only },
) catch unreachable;
fs.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", .{ name_only_path, filename_major_only });
warn("Unable to symlink {s} -> {s}\n", .{ name_only_path, filename_major_only });
return err;
};
}

View File

@ -45,9 +45,9 @@ pub const CheckFileStep = struct {
warn(
\\
\\========= Expected to find: ===================
\\{}
\\{s}
\\========= But file does not contain it: =======
\\{}
\\{s}
\\
, .{ expected_match, contents });
return error.TestFailed;

View File

@ -189,7 +189,7 @@ pub const InstallRawStep = struct {
pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *Self {
const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{
.step = Step.init(.InstallRaw, builder.fmt("install raw binary {}", .{artifact.step.name}), builder.allocator, make),
.step = Step.init(.InstallRaw, builder.fmt("install raw binary {s}", .{artifact.step.name}), builder.allocator, make),
.builder = builder,
.artifact = artifact,
.dest_dir = switch (artifact.kind) {

View File

@ -116,7 +116,7 @@ pub const RunStep = struct {
}
if (prev_path) |pp| {
const new_path = self.builder.fmt("{}" ++ [1]u8{fs.path.delimiter} ++ "{}", .{ pp, search_path });
const new_path = self.builder.fmt("{s}" ++ [1]u8{fs.path.delimiter} ++ "{s}", .{ pp, search_path });
env_map.set(key, new_path) catch unreachable;
} else {
env_map.set(key, search_path) catch unreachable;
@ -189,7 +189,7 @@ pub const RunStep = struct {
child.stderr_behavior = stdIoActionToBehavior(self.stderr_action);
child.spawn() catch |err| {
warn("Unable to spawn {}: {}\n", .{ argv[0], @errorName(err) });
warn("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
return err;
};
@ -216,7 +216,7 @@ pub const RunStep = struct {
}
const term = child.wait() catch |err| {
warn("Unable to spawn {}: {}\n", .{ argv[0], @errorName(err) });
warn("Unable to spawn {s}: {s}\n", .{ argv[0], @errorName(err) });
return err;
};
@ -245,9 +245,9 @@ pub const RunStep = struct {
warn(
\\
\\========= Expected this stderr: =========
\\{}
\\{s}
\\========= But found: ====================
\\{}
\\{s}
\\
, .{ expected_bytes, stderr.? });
printCmd(cwd, argv);
@ -259,9 +259,9 @@ pub const RunStep = struct {
warn(
\\
\\========= Expected to find in stderr: =========
\\{}
\\{s}
\\========= But stderr does not contain it: =====
\\{}
\\{s}
\\
, .{ match, stderr.? });
printCmd(cwd, argv);
@ -277,9 +277,9 @@ pub const RunStep = struct {
warn(
\\
\\========= Expected this stdout: =========
\\{}
\\{s}
\\========= But found: ====================
\\{}
\\{s}
\\
, .{ expected_bytes, stdout.? });
printCmd(cwd, argv);
@ -291,9 +291,9 @@ pub const RunStep = struct {
warn(
\\
\\========= Expected to find in stdout: =========
\\{}
\\{s}
\\========= But stdout does not contain it: =====
\\{}
\\{s}
\\
, .{ match, stdout.? });
printCmd(cwd, argv);
@ -304,9 +304,9 @@ pub const RunStep = struct {
}
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
if (cwd) |yes_cwd| warn("cd {} && ", .{yes_cwd});
if (cwd) |yes_cwd| warn("cd {s} && ", .{yes_cwd});
for (argv) |arg| {
warn("{} ", .{arg});
warn("{s} ", .{arg});
}
warn("\n", .{});
}

View File

@ -80,14 +80,14 @@ pub const WriteFileStep = struct {
});
// TODO replace with something like fs.makePathAndOpenDir
fs.cwd().makePath(self.output_dir) catch |err| {
warn("unable to make path {}: {}\n", .{ self.output_dir, @errorName(err) });
warn("unable to make path {s}: {s}\n", .{ self.output_dir, @errorName(err) });
return err;
};
var dir = try fs.cwd().openDir(self.output_dir, .{});
defer dir.close();
for (self.files.items) |file| {
dir.writeFile(file.basename, file.bytes) catch |err| {
warn("unable to write {} into {}: {}\n", .{
warn("unable to write {s} into {s}: {s}\n", .{
file.basename,
self.output_dir,
@errorName(err),

View File

@ -67,12 +67,12 @@ pub const StackTrace = struct {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
return writer.print("\nUnable to print stack trace: Unable to open debug info: {}\n", .{@errorName(err)});
return writer.print("\nUnable to print stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
};
const tty_config = std.debug.detectTTYConfig();
try writer.writeAll("\n");
std.debug.writeStackTrace(self, writer, &arena.allocator, debug_info, tty_config) catch |err| {
try writer.print("Unable to print stack trace: {}\n", .{@errorName(err)});
try writer.print("Unable to print stack trace: {s}\n", .{@errorName(err)});
};
try writer.writeAll("\n");
}
@ -529,12 +529,12 @@ pub const Version = struct {
if (fmt.len == 0) {
if (self.patch == 0) {
if (self.minor == 0) {
return std.fmt.format(out_stream, "{}", .{self.major});
return std.fmt.format(out_stream, "{d}", .{self.major});
} else {
return std.fmt.format(out_stream, "{}.{}", .{ self.major, self.minor });
return std.fmt.format(out_stream, "{d}.{d}", .{ self.major, self.minor });
}
} else {
return std.fmt.format(out_stream, "{}.{}.{}", .{ self.major, self.minor, self.patch });
return std.fmt.format(out_stream, "{d}.{d}.{d}", .{ self.major, self.minor, self.patch });
}
} else {
@compileError("Unknown format string: '" ++ fmt ++ "'");
@ -683,7 +683,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
}
},
.wasi => {
std.debug.warn("{}", .{msg});
std.debug.warn("{s}", .{msg});
std.os.abort();
},
.uefi => {
@ -692,7 +692,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
},
else => {
const first_trace_addr = @returnAddress();
std.debug.panicExtra(error_return_trace, first_trace_addr, "{}", .{msg});
std.debug.panicExtra(error_return_trace, first_trace_addr, "{s}", .{msg});
},
}
}

View File

@ -1552,7 +1552,7 @@ fn expectTokens(source: []const u8, expected_tokens: []const Token.Id) void {
for (expected_tokens) |expected_token_id| {
const token = tokenizer.next();
if (!std.meta.eql(token.id, expected_token_id)) {
std.debug.panic("expected {}, found {}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
std.debug.panic("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
}
}
const last_token = tokenizer.next();

View File

@ -247,7 +247,7 @@ fn strHashInternal(password: []const u8, rounds_log: u6, salt: [salt_length]u8)
Codec.encode(ct_str[0..], ct[0 .. ct.len - 1]);
var s_buf: [hash_length]u8 = undefined;
const s = fmt.bufPrint(s_buf[0..], "$2b${}{}${}{}", .{ rounds_log / 10, rounds_log % 10, salt_str, ct_str }) catch unreachable;
const s = fmt.bufPrint(s_buf[0..], "$2b${d}{d}${s}{s}", .{ rounds_log / 10, rounds_log % 10, salt_str, ct_str }) catch unreachable;
debug.assert(s.len == s_buf.len);
return s_buf;
}

View File

@ -108,11 +108,11 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
return;
}
const debug_info = getSelfDebugInfo() catch |err| {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(), start_addr) catch |err| {
stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return;
stderr.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch return;
return;
};
}
@ -129,7 +129,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
return;
}
const debug_info = getSelfDebugInfo() catch |err| {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
const tty_config = detectTTYConfig();
@ -199,11 +199,11 @@ pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
return;
}
const debug_info = getSelfDebugInfo() catch |err| {
stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return;
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, detectTTYConfig()) catch |err| {
stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return;
stderr.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch return;
return;
};
}
@ -611,7 +611,7 @@ fn printLineInfo(
tty_config.setColor(out_stream, .White);
if (line_info) |*li| {
try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column });
try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column });
} else {
try out_stream.writeAll("???:?:?");
}
@ -619,7 +619,7 @@ fn printLineInfo(
tty_config.setColor(out_stream, .Reset);
try out_stream.writeAll(": ");
tty_config.setColor(out_stream, .Dim);
try out_stream.print("0x{x} in {} ({})", .{ address, symbol_name, compile_unit_name });
try out_stream.print("0x{x} in {s} ({s})", .{ address, symbol_name, compile_unit_name });
tty_config.setColor(out_stream, .Reset);
try out_stream.writeAll("\n");

View File

@ -466,7 +466,7 @@ test "LinearFifo(u8, .Dynamic)" {
fifo.shrink(0);
{
try fifo.writer().print("{}, {}!", .{ "Hello", "World" });
try fifo.writer().print("{s}, {s}!", .{ "Hello", "World" });
var result: [30]u8 = undefined;
testing.expectEqualSlices(u8, "Hello, World!", result[0..fifo.read(&result)]);
testing.expectEqual(@as(usize, 0), fifo.readableLength());

View File

@ -506,12 +506,12 @@ pub fn formatType(
if (info.child == u8) {
return formatText(value, fmt, options, writer);
}
return format(writer, "{}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) });
return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) });
},
.Enum, .Union, .Struct => {
return formatType(value.*, fmt, options, writer, max_depth);
},
else => return format(writer, "{}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) }),
else => return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) }),
},
.Many, .C => {
if (ptr_info.sentinel) |sentinel| {
@ -522,7 +522,7 @@ pub fn formatType(
return formatText(mem.span(value), fmt, options, writer);
}
}
return format(writer, "{}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) });
return format(writer, "{s}@{x}", .{ @typeName(ptr_info.child), @ptrToInt(value) });
},
.Slice => {
if (max_depth == 0) {
@ -573,7 +573,7 @@ pub fn formatType(
try writer.writeAll(" }");
},
.Fn => {
return format(writer, "{}@{x}", .{ @typeName(T), @ptrToInt(value) });
return format(writer, "{s}@{x}", .{ @typeName(T), @ptrToInt(value) });
},
.Type => return formatBuf(@typeName(value), options, writer),
.EnumLiteral => {
@ -695,7 +695,7 @@ pub fn formatText(
options: FormatOptions,
writer: anytype,
) !void {
if (comptime std.mem.eql(u8, fmt, "s") or (fmt.len == 0)) {
if (comptime std.mem.eql(u8, fmt, "s")) {
return formatBuf(bytes, options, writer);
} else if (comptime (std.mem.eql(u8, fmt, "x") or std.mem.eql(u8, fmt, "X"))) {
for (bytes) |c| {
@ -1559,8 +1559,8 @@ test "buffer" {
test "array" {
{
const value: [3]u8 = "abc".*;
try testFmt("array: abc\n", "array: {}\n", .{value});
try testFmt("array: abc\n", "array: {}\n", .{&value});
try testFmt("array: abc\n", "array: {s}\n", .{value});
try testFmt("array: abc\n", "array: {s}\n", .{&value});
try testFmt("array: { 97, 98, 99 }\n", "array: {d}\n", .{value});
var buf: [100]u8 = undefined;
@ -1575,7 +1575,7 @@ test "array" {
test "slice" {
{
const value: []const u8 = "abc";
try testFmt("slice: abc\n", "slice: {}\n", .{value});
try testFmt("slice: abc\n", "slice: {s}\n", .{value});
}
{
var runtime_zero: usize = 0;
@ -1902,9 +1902,9 @@ fn testFmt(expected: []const u8, comptime template: []const u8, args: anytype) !
if (mem.eql(u8, result, expected)) return;
std.debug.warn("\n====== expected this output: =========\n", .{});
std.debug.warn("{}", .{expected});
std.debug.warn("{s}", .{expected});
std.debug.warn("\n======== instead found this: =========\n", .{});
std.debug.warn("{}", .{result});
std.debug.warn("{s}", .{result});
std.debug.warn("\n======================================\n", .{});
return error.TestFailed;
}
@ -2061,24 +2061,24 @@ test "vector" {
}
test "enum-literal" {
try testFmt(".hello_world", "{}", .{.hello_world});
try testFmt(".hello_world", "{s}", .{.hello_world});
}
test "padding" {
try testFmt("Simple", "{}", .{"Simple"});
try testFmt("Simple", "{s}", .{"Simple"});
try testFmt(" true", "{:10}", .{true});
try testFmt(" true", "{:>10}", .{true});
try testFmt("======true", "{:=>10}", .{true});
try testFmt("true======", "{:=<10}", .{true});
try testFmt(" true ", "{:^10}", .{true});
try testFmt("===true===", "{:=^10}", .{true});
try testFmt(" Minimum width", "{:18} width", .{"Minimum"});
try testFmt("==================Filled", "{:=>24}", .{"Filled"});
try testFmt(" Centered ", "{:^24}", .{"Centered"});
try testFmt("-", "{:-^1}", .{""});
try testFmt("==crêpe===", "{:=^10}", .{"crêpe"});
try testFmt("=====crêpe", "{:=>10}", .{"crêpe"});
try testFmt("crêpe=====", "{:=<10}", .{"crêpe"});
try testFmt(" Minimum width", "{s:18} width", .{"Minimum"});
try testFmt("==================Filled", "{s:=>24}", .{"Filled"});
try testFmt(" Centered ", "{s:^24}", .{"Centered"});
try testFmt("-", "{s:-^1}", .{""});
try testFmt("==crêpe===", "{s:=^10}", .{"crêpe"});
try testFmt("=====crêpe", "{s:=>10}", .{"crêpe"});
try testFmt("crêpe=====", "{s:=<10}", .{"crêpe"});
}
test "decimal float padding" {
@ -2107,15 +2107,15 @@ test "type" {
}
test "named arguments" {
try testFmt("hello world!", "{} world{c}", .{ "hello", '!' });
try testFmt("hello world!", "{[greeting]} world{[punctuation]c}", .{ .punctuation = '!', .greeting = "hello" });
try testFmt("hello world!", "{[1]} world{[0]c}", .{ '!', "hello" });
try testFmt("hello world!", "{s} world{c}", .{ "hello", '!' });
try testFmt("hello world!", "{[greeting]s} world{[punctuation]c}", .{ .punctuation = '!', .greeting = "hello" });
try testFmt("hello world!", "{[1]s} world{[0]c}", .{ '!', "hello" });
}
test "runtime width specifier" {
var width: usize = 9;
try testFmt("~~hello~~", "{:~^[1]}", .{ "hello", width });
try testFmt("~~hello~~", "{:~^[width]}", .{ .string = "hello", .width = width });
try testFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
try testFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
}
test "runtime precision specifier" {

View File

@ -314,7 +314,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
if (is_used) {
const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index);
const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc);
log.err("Memory leak detected: {}", .{stack_trace});
log.err("Memory leak detected: {s}", .{stack_trace});
leaks = true;
}
if (bit_index == math.maxInt(u3))
@ -342,7 +342,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
}
var it = self.large_allocations.iterator();
while (it.next()) |large_alloc| {
log.err("Memory leak detected: {}", .{large_alloc.value.getStackTrace()});
log.err("Memory leak detected: {s}", .{large_alloc.value.getStackTrace()});
leaks = true;
}
return leaks;
@ -443,7 +443,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
.index = 0,
};
std.debug.captureStackTrace(ret_addr, &free_stack_trace);
log.err("Allocation size {} bytes does not match free size {}. Allocation: {} Free: {}", .{
log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {s} Free: {s}", .{
entry.value.bytes.len,
old_mem.len,
entry.value.getStackTrace(),
@ -526,7 +526,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
.index = 0,
};
std.debug.captureStackTrace(ret_addr, &second_free_stack_trace);
log.err("Double free detected. Allocation: {} First free: {} Second free: {}", .{
log.err("Double free detected. Allocation: {s} First free: {s} Second free: {s}", .{
alloc_stack_trace,
free_stack_trace,
second_free_stack_trace,

View File

@ -147,7 +147,7 @@ test "FixedBufferStream output" {
var fbs = fixedBufferStream(&buf);
const stream = fbs.writer();
try stream.print("{}{}!", .{ "Hello", "World" });
try stream.print("{s}{s}!", .{ "Hello", "World" });
testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten());
}

View File

@ -2642,9 +2642,9 @@ fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions
if (self.expected_remaining.len < bytes.len) {
std.debug.warn(
\\====== expected this output: =========
\\{}
\\{s}
\\======== instead found this: =========
\\{}
\\{s}
\\======================================
, .{
self.expected_remaining,
@ -2655,9 +2655,9 @@ fn teststringify(expected: []const u8, value: anytype, options: StringifyOptions
if (!mem.eql(u8, self.expected_remaining[0..bytes.len], bytes)) {
std.debug.warn(
\\====== expected this output: =========
\\{}
\\{s}
\\======== instead found this: =========
\\{}
\\{s}
\\======================================
, .{
self.expected_remaining[0..bytes.len],

View File

@ -154,7 +154,7 @@ pub const Address = extern union {
unreachable;
}
try std.fmt.format(out_stream, "{}", .{&self.un.path});
try std.fmt.format(out_stream, "{s}", .{&self.un.path});
},
else => unreachable,
}

View File

@ -1618,7 +1618,7 @@ pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
null,
);
_ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable;
std.debug.warn("error.Unexpected: GetLastError({}): {}\n", .{ @enumToInt(err), buf_u8[0..len] });
std.debug.warn("error.Unexpected: GetLastError({}): {s}\n", .{ @enumToInt(err), buf_u8[0..len] });
std.debug.dumpCurrentStackTrace(null);
}
return error.Unexpected;

View File

@ -596,7 +596,7 @@ fn testWindowsCmdLine(input_cmd_line: [*]const u16, expected_args: []const []con
for (expected_args) |expected_arg| {
const arg = it.next(std.testing.allocator).? catch unreachable;
defer std.testing.allocator.free(arg);
testing.expectEqualSlices(u8, expected_arg, arg);
testing.expectEqualStrings(expected_arg, arg);
}
testing.expect(it.next(std.testing.allocator) == null);
}

310
lib/std/progress.zig Normal file
View File

@ -0,0 +1,310 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2015-2020 Zig Contributors
// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
// The MIT license requires this copyright notice to be included in all copies
// and substantial portions of the software.
const std = @import("std");
const windows = std.os.windows;
const testing = std.testing;
const assert = std.debug.assert;
/// This API is non-allocating and non-fallible. The tradeoff is that users of
/// this API must provide the storage for each `Progress.Node`.
/// Initialize the struct directly, overriding these fields as desired:
/// * `refresh_rate_ms`
/// * `initial_delay_ms`
pub const Progress = struct {
/// `null` if the current node (and its children) should
/// not print on update()
terminal: ?std.fs.File = undefined,
/// Whether the terminal supports ANSI escape codes.
supports_ansi_escape_codes: bool = false,
root: Node = undefined,
/// Keeps track of how much time has passed since the beginning.
/// Used to compare with `initial_delay_ms` and `refresh_rate_ms`.
timer: std.time.Timer = undefined,
/// When the previous refresh was written to the terminal.
/// Used to compare with `refresh_rate_ms`.
prev_refresh_timestamp: u64 = undefined,
/// This buffer represents the maximum number of bytes written to the terminal
/// with each refresh.
output_buffer: [100]u8 = undefined,
/// How many nanoseconds between writing updates to the terminal.
refresh_rate_ns: u64 = 50 * std.time.ns_per_ms,
/// How many nanoseconds to keep the output hidden
initial_delay_ns: u64 = 500 * std.time.ns_per_ms,
done: bool = true,
/// Keeps track of how many columns in the terminal have been output, so that
/// we can move the cursor back later.
columns_written: usize = undefined,
/// Represents one unit of progress. Each node can have children nodes, or
/// one can use integers with `update`.
pub const Node = struct {
context: *Progress,
parent: ?*Node,
completed_items: usize,
name: []const u8,
recently_updated_child: ?*Node = null,
/// This field may be updated freely.
estimated_total_items: ?usize,
/// Create a new child progress node.
/// Call `Node.end` when done.
/// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
/// API to set `self.parent.recently_updated_child` with the return value.
/// Until that is fixed you probably want to call `activate` on the return value.
pub fn start(self: *Node, name: []const u8, estimated_total_items: ?usize) Node {
return Node{
.context = self.context,
.parent = self,
.completed_items = 0,
.name = name,
.estimated_total_items = estimated_total_items,
};
}
/// This is the same as calling `start` and then `end` on the returned `Node`.
pub fn completeOne(self: *Node) void {
if (self.parent) |parent| parent.recently_updated_child = self;
self.completed_items += 1;
self.context.maybeRefresh();
}
pub fn end(self: *Node) void {
self.context.maybeRefresh();
if (self.parent) |parent| {
if (parent.recently_updated_child) |parent_child| {
if (parent_child == self) {
parent.recently_updated_child = null;
}
}
parent.completeOne();
} else {
self.context.done = true;
self.context.refresh();
}
}
/// Tell the parent node that this node is actively being worked on.
pub fn activate(self: *Node) void {
if (self.parent) |parent| parent.recently_updated_child = self;
}
};
/// Create a new progress node.
/// Call `Node.end` when done.
/// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
/// API to return Progress rather than accept it as a parameter.
pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node {
const stderr = std.io.getStdErr();
self.terminal = null;
if (stderr.supportsAnsiEscapeCodes()) {
self.terminal = stderr;
self.supports_ansi_escape_codes = true;
} else if (std.builtin.os.tag == .windows and stderr.isTty()) {
self.terminal = stderr;
}
self.root = Node{
.context = self,
.parent = null,
.completed_items = 0,
.name = name,
.estimated_total_items = estimated_total_items,
};
self.columns_written = 0;
self.prev_refresh_timestamp = 0;
self.timer = try std.time.Timer.start();
self.done = false;
return &self.root;
}
/// Updates the terminal if enough time has passed since last update.
pub fn maybeRefresh(self: *Progress) void {
const now = self.timer.read();
if (now < self.initial_delay_ns) return;
if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return;
self.refresh();
}
/// Updates the terminal and resets `self.next_refresh_timestamp`.
pub fn refresh(self: *Progress) void {
const file = self.terminal orelse return;
const prev_columns_written = self.columns_written;
var end: usize = 0;
if (self.columns_written > 0) {
// restore the cursor position by moving the cursor
// `columns_written` cells to the left, then clear the rest of the
// line
if (self.supports_ansi_escape_codes) {
end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{d}D", .{self.columns_written}) catch unreachable).len;
end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[0K", .{}) catch unreachable).len;
} else if (std.builtin.os.tag == .windows) winapi: {
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE)
unreachable;
var cursor_pos = windows.COORD{
.X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written),
.Y = info.dwCursorPosition.Y,
};
if (cursor_pos.X < 0)
cursor_pos.X = 0;
const fill_chars = @intCast(windows.DWORD, info.dwSize.X - cursor_pos.X);
var written: windows.DWORD = undefined;
if (windows.kernel32.FillConsoleOutputAttribute(
file.handle,
info.wAttributes,
fill_chars,
cursor_pos,
&written,
) != windows.TRUE) {
// Stop trying to write to this file.
self.terminal = null;
break :winapi;
}
if (windows.kernel32.FillConsoleOutputCharacterA(
file.handle,
' ',
fill_chars,
cursor_pos,
&written,
) != windows.TRUE) unreachable;
if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)
unreachable;
} else unreachable;
self.columns_written = 0;
}
if (!self.done) {
var need_ellipse = false;
var maybe_node: ?*Node = &self.root;
while (maybe_node) |node| {
if (need_ellipse) {
self.bufWrite(&end, "... ", .{});
}
need_ellipse = false;
if (node.name.len != 0 or node.estimated_total_items != null) {
if (node.name.len != 0) {
self.bufWrite(&end, "{s}", .{node.name});
need_ellipse = true;
}
if (node.estimated_total_items) |total| {
if (need_ellipse) self.bufWrite(&end, " ", .{});
self.bufWrite(&end, "[{d}/{d}] ", .{ node.completed_items + 1, total });
need_ellipse = false;
} else if (node.completed_items != 0) {
if (need_ellipse) self.bufWrite(&end, " ", .{});
self.bufWrite(&end, "[{d}] ", .{node.completed_items + 1});
need_ellipse = false;
}
}
maybe_node = node.recently_updated_child;
}
if (need_ellipse) {
self.bufWrite(&end, "... ", .{});
}
}
_ = file.write(self.output_buffer[0..end]) catch |e| {
// Stop trying to write to this file once it errors.
self.terminal = null;
};
self.prev_refresh_timestamp = self.timer.read();
}
pub fn log(self: *Progress, comptime format: []const u8, args: anytype) void {
const file = self.terminal orelse return;
self.refresh();
file.outStream().print(format, args) catch {
self.terminal = null;
return;
};
self.columns_written = 0;
}
fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: anytype) void {
if (std.fmt.bufPrint(self.output_buffer[end.*..], format, args)) |written| {
const amt = written.len;
end.* += amt;
self.columns_written += amt;
} else |err| switch (err) {
error.NoSpaceLeft => {
self.columns_written += self.output_buffer.len - end.*;
end.* = self.output_buffer.len;
},
}
const bytes_needed_for_esc_codes_at_end = if (std.builtin.os.tag == .windows) 0 else 11;
const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end;
if (end.* > max_end) {
const suffix = "... ";
self.columns_written = self.columns_written - (end.* - max_end) + suffix.len;
std.mem.copy(u8, self.output_buffer[max_end..], suffix);
end.* = max_end + suffix.len;
}
}
};
test "basic functionality" {
var disable = true;
if (disable) {
// This test is disabled because it uses time.sleep() and is therefore slow. It also
// prints bogus progress data to stderr.
return error.SkipZigTest;
}
var progress = Progress{};
const root_node = try progress.start("", 100);
defer root_node.end();
const sub_task_names = [_][]const u8{
"reticulating splines",
"adjusting shoes",
"climbing towers",
"pouring juice",
};
var next_sub_task: usize = 0;
var i: usize = 0;
while (i < 100) : (i += 1) {
var node = root_node.start(sub_task_names[next_sub_task], 5);
node.activate();
next_sub_task = (next_sub_task + 1) % sub_task_names.len;
node.completeOne();
std.time.sleep(5 * std.time.ns_per_ms);
node.completeOne();
node.completeOne();
std.time.sleep(5 * std.time.ns_per_ms);
node.completeOne();
node.completeOne();
std.time.sleep(5 * std.time.ns_per_ms);
node.end();
std.time.sleep(5 * std.time.ns_per_ms);
}
{
var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", null);
node.activate();
std.time.sleep(10 * std.time.ns_per_ms);
progress.refresh();
std.time.sleep(10 * std.time.ns_per_ms);
node.end();
}
}

View File

@ -48,7 +48,7 @@ pub fn main() anyerror!void {
test_node.activate();
progress.refresh();
if (progress.terminal == null) {
std.debug.print("{}/{} {}... ", .{ i + 1, test_fn_list.len, test_fn.name });
std.debug.print("{d}/{d} {s}... ", .{ i + 1, test_fn_list.len, test_fn.name });
}
const result = if (test_fn.async_frame_size) |size| switch (io_mode) {
.evented => blk: {
@ -62,7 +62,7 @@ pub fn main() anyerror!void {
.blocking => {
skip_count += 1;
test_node.end();
progress.log("{}...SKIP (async test)\n", .{test_fn.name});
progress.log("{s}...SKIP (async test)\n", .{test_fn.name});
if (progress.terminal == null) std.debug.print("SKIP (async test)\n", .{});
continue;
},
@ -75,7 +75,7 @@ pub fn main() anyerror!void {
error.SkipZigTest => {
skip_count += 1;
test_node.end();
progress.log("{}...SKIP\n", .{test_fn.name});
progress.log("{s}...SKIP\n", .{test_fn.name});
if (progress.terminal == null) std.debug.print("SKIP\n", .{});
},
else => {
@ -86,15 +86,15 @@ pub fn main() anyerror!void {
}
root_node.end();
if (ok_count == test_fn_list.len) {
std.debug.print("All {} tests passed.\n", .{ok_count});
std.debug.print("All {d} tests passed.\n", .{ok_count});
} else {
std.debug.print("{} passed; {} skipped.\n", .{ ok_count, skip_count });
std.debug.print("{d} passed; {d} skipped.\n", .{ ok_count, skip_count });
}
if (log_err_count != 0) {
std.debug.print("{} errors were logged.\n", .{log_err_count});
std.debug.print("{d} errors were logged.\n", .{log_err_count});
}
if (leaks != 0) {
std.debug.print("{} tests leaked memory.\n", .{leaks});
std.debug.print("{d} tests leaked memory.\n", .{leaks});
}
if (leaks != 0 or log_err_count != 0) {
std.process.exit(1);
@ -111,6 +111,6 @@ pub fn log(
log_err_count += 1;
}
if (@enumToInt(message_level) <= @enumToInt(std.testing.log_level)) {
std.debug.print("[{}] ({}): " ++ format ++ "\n", .{ @tagName(scope), @tagName(message_level) } ++ args);
std.debug.print("[{s}] ({s}): " ++ format ++ "\n", .{ @tagName(scope), @tagName(message_level) } ++ args);
}
}

View File

@ -266,7 +266,7 @@ inline fn initEventLoopAndCallMain() u8 {
if (std.event.Loop.instance) |loop| {
if (!@hasDecl(root, "event_loop")) {
loop.init() catch |err| {
std.log.err("{}", .{@errorName(err)});
std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
@ -295,7 +295,7 @@ inline fn initEventLoopAndCallWinMain() std.os.windows.INT {
if (std.event.Loop.instance) |loop| {
if (!@hasDecl(root, "event_loop")) {
loop.init() catch |err| {
std.log.err("{}", .{@errorName(err)});
std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
@ -343,7 +343,7 @@ pub fn callMain() u8 {
},
.ErrorUnion => {
const result = root.main() catch |err| {
std.log.err("{}", .{@errorName(err)});
std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}

View File

@ -136,14 +136,14 @@ pub const Target = struct {
) !void {
if (fmt.len > 0 and fmt[0] == 's') {
if (@enumToInt(self) >= @enumToInt(WindowsVersion.nt4) and @enumToInt(self) <= @enumToInt(WindowsVersion.latest)) {
try std.fmt.format(out_stream, ".{}", .{@tagName(self)});
try std.fmt.format(out_stream, ".{s}", .{@tagName(self)});
} else {
// TODO this code path breaks zig triples, but it is used in `builtin`
try std.fmt.format(out_stream, "@intToEnum(Target.Os.WindowsVersion, 0x{X:0>8})", .{@enumToInt(self)});
}
} else {
if (@enumToInt(self) >= @enumToInt(WindowsVersion.nt4) and @enumToInt(self) <= @enumToInt(WindowsVersion.latest)) {
try std.fmt.format(out_stream, "WindowsVersion.{}", .{@tagName(self)});
try std.fmt.format(out_stream, "WindowsVersion.{s}", .{@tagName(self)});
} else {
try std.fmt.format(out_stream, "WindowsVersion(0x{X:0>8})", .{@enumToInt(self)});
}
@ -1177,7 +1177,7 @@ pub const Target = struct {
}
pub fn linuxTripleSimple(allocator: *mem.Allocator, cpu_arch: Cpu.Arch, os_tag: Os.Tag, abi: Abi) ![]u8 {
return std.fmt.allocPrint(allocator, "{}-{}-{}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
return std.fmt.allocPrint(allocator, "{s}-{s}-{s}", .{ @tagName(cpu_arch), @tagName(os_tag), @tagName(abi) });
}
pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
@ -1381,7 +1381,7 @@ pub const Target = struct {
if (self.abi == .android) {
const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else "";
return print(&result, "/system/bin/linker{}", .{suffix});
return print(&result, "/system/bin/linker{s}", .{suffix});
}
if (self.abi.isMusl()) {
@ -1395,7 +1395,7 @@ pub const Target = struct {
else => |arch| @tagName(arch),
};
const arch_suffix = if (is_arm and self.abi.floatAbi() == .hard) "hf" else "";
return print(&result, "/lib/ld-musl-{}{}.so.1", .{ arch_part, arch_suffix });
return print(&result, "/lib/ld-musl-{s}{s}.so.1", .{ arch_part, arch_suffix });
}
switch (self.os.tag) {
@ -1434,7 +1434,7 @@ pub const Target = struct {
};
const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008);
const loader = if (is_nan_2008) "ld-linux-mipsn8.so.1" else "ld.so.1";
return print(&result, "/lib{}/{}", .{ lib_suffix, loader });
return print(&result, "/lib{s}/{s}", .{ lib_suffix, loader });
},
.powerpc => return copy(&result, "/lib/ld.so.1"),

View File

@ -29,10 +29,11 @@ pub var zig_exe_path: []const u8 = undefined;
/// and then aborts when actual_error_union is not expected_error.
pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void {
if (actual_error_union) |actual_payload| {
std.debug.panic("expected error.{}, found {}", .{ @errorName(expected_error), actual_payload });
// std.debug.panic("expected error.{s}, found {}", .{ @errorName(expected_error), actual_payload });
std.debug.panic("expected error.{s}, found", .{@errorName(expected_error)});
} else |actual_error| {
if (expected_error != actual_error) {
std.debug.panic("expected error.{}, found error.{}", .{
std.debug.panic("expected error.{s}, found error.{s}", .{
@errorName(expected_error),
@errorName(actual_error),
});
@ -60,7 +61,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
.Type => {
if (actual != expected) {
std.debug.panic("expected type {}, found type {}", .{ @typeName(expected), @typeName(actual) });
std.debug.panic("expected type {s}, found type {s}", .{ @typeName(expected), @typeName(actual) });
}
},
@ -360,7 +361,7 @@ pub fn expectEqualStrings(expected: []const u8, actual: []const u8) void {
for (expected[0..diff_index]) |value| {
if (value == '\n') diff_line_number += 1;
}
print("First difference occurs on line {}:\n", .{diff_line_number});
print("First difference occurs on line {d}:\n", .{diff_line_number});
print("expected:\n", .{});
printIndicatorLine(expected, diff_index);
@ -416,15 +417,15 @@ fn printWithVisibleNewlines(source: []const u8) void {
while (std.mem.indexOf(u8, source[i..], "\n")) |nl| : (i += nl + 1) {
printLine(source[i .. i + nl]);
}
print("{}␃\n", .{source[i..]}); // End of Text symbol (ETX)
print("{s}␃\n", .{source[i..]}); // End of Text symbol (ETX)
}
fn printLine(line: []const u8) void {
if (line.len != 0) switch (line[line.len - 1]) {
' ', '\t' => print("{}⏎\n", .{line}), // Carriage return symbol,
' ', '\t' => print("{s}⏎\n", .{line}), // Carriage return symbol,
else => {},
};
print("{}\n", .{line});
print("{s}\n", .{line});
}
test "" {

View File

@ -186,7 +186,7 @@ pub const Thread = struct {
@compileError(bad_startfn_ret);
}
startFn(arg) catch |err| {
std.debug.warn("error: {}\n", .{@errorName(err)});
std.debug.warn("error: {s}\n", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
@ -247,7 +247,7 @@ pub const Thread = struct {
@compileError(bad_startfn_ret);
}
startFn(arg) catch |err| {
std.debug.warn("error: {}\n", .{@errorName(err)});
std.debug.warn("error: {s}\n", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}
@ -281,7 +281,7 @@ pub const Thread = struct {
@compileError(bad_startfn_ret);
}
startFn(arg) catch |err| {
std.debug.warn("error: {}\n", .{@errorName(err)});
std.debug.warn("error: {s}\n", .{@errorName(err)});
if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*);
}

View File

@ -281,41 +281,41 @@ pub const Error = union(enum) {
}
}
pub const InvalidToken = SingleTokenError("Invalid token '{}'");
pub const ExpectedContainerMembers = SingleTokenError("Expected test, comptime, var decl, or container field, found '{}'");
pub const ExpectedStringLiteral = SingleTokenError("Expected string literal, found '{}'");
pub const ExpectedIntegerLiteral = SingleTokenError("Expected integer literal, found '{}'");
pub const ExpectedIdentifier = SingleTokenError("Expected identifier, found '{}'");
pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', '" ++ Token.Id.Keyword_enum.symbol() ++ "', or '" ++ Token.Id.Keyword_opaque.symbol() ++ "', found '{}'");
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found '{}'");
pub const ExpectedSemiOrElse = SingleTokenError("Expected ';' or 'else', found '{}'");
pub const ExpectedLBrace = SingleTokenError("Expected '{{', found '{}'");
pub const ExpectedLabelOrLBrace = SingleTokenError("Expected label or '{{', found '{}'");
pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found '{}'");
pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found '{}'");
pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found '{}'");
pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or '" ++ Token.Id.Identifier.symbol() ++ "', found '{}'");
pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found '{}'");
pub const ExpectedTypeExpr = SingleTokenError("Expected type expression, found '{}'");
pub const ExpectedPrimaryTypeExpr = SingleTokenError("Expected primary type expression, found '{}'");
pub const ExpectedExpr = SingleTokenError("Expected expression, found '{}'");
pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found '{}'");
pub const ExpectedParamList = SingleTokenError("Expected parameter list, found '{}'");
pub const ExpectedPayload = SingleTokenError("Expected loop payload, found '{}'");
pub const ExpectedBlockOrAssignment = SingleTokenError("Expected block or assignment, found '{}'");
pub const ExpectedBlockOrExpression = SingleTokenError("Expected block or expression, found '{}'");
pub const ExpectedExprOrAssignment = SingleTokenError("Expected expression or assignment, found '{}'");
pub const ExpectedPrefixExpr = SingleTokenError("Expected prefix expression, found '{}'");
pub const ExpectedLoopExpr = SingleTokenError("Expected loop expression, found '{}'");
pub const ExpectedDerefOrUnwrap = SingleTokenError("Expected pointer dereference or optional unwrap, found '{}'");
pub const ExpectedSuffixOp = SingleTokenError("Expected pointer dereference, optional unwrap, or field access, found '{}'");
pub const ExpectedBlockOrField = SingleTokenError("Expected block or field, found '{}'");
pub const InvalidToken = SingleTokenError("Invalid token '{s}'");
pub const ExpectedContainerMembers = SingleTokenError("Expected test, comptime, var decl, or container field, found '{s}'");
pub const ExpectedStringLiteral = SingleTokenError("Expected string literal, found '{s}'");
pub const ExpectedIntegerLiteral = SingleTokenError("Expected integer literal, found '{s}'");
pub const ExpectedIdentifier = SingleTokenError("Expected identifier, found '{s}'");
pub const ExpectedStatement = SingleTokenError("Expected statement, found '{s}'");
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{s}'");
pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{s}'");
pub const ExpectedFn = SingleTokenError("Expected function, found '{s}'");
pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{s}'");
pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', '" ++ Token.Id.Keyword_enum.symbol() ++ "', or '" ++ Token.Id.Keyword_opaque.symbol() ++ "', found '{s}'");
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{s}'");
pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found '{s}'");
pub const ExpectedSemiOrElse = SingleTokenError("Expected ';' or 'else', found '{s}'");
pub const ExpectedLBrace = SingleTokenError("Expected '{{', found '{s}'");
pub const ExpectedLabelOrLBrace = SingleTokenError("Expected label or '{{', found '{s}'");
pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found '{s}'");
pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'");
pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found '{s}'");
pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or '" ++ Token.Id.Identifier.symbol() ++ "', found '{s}'");
pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found '{s}'");
pub const ExpectedTypeExpr = SingleTokenError("Expected type expression, found '{s}'");
pub const ExpectedPrimaryTypeExpr = SingleTokenError("Expected primary type expression, found '{s}'");
pub const ExpectedExpr = SingleTokenError("Expected expression, found '{s}'");
pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found '{s}'");
pub const ExpectedParamList = SingleTokenError("Expected parameter list, found '{s}'");
pub const ExpectedPayload = SingleTokenError("Expected loop payload, found '{s}'");
pub const ExpectedBlockOrAssignment = SingleTokenError("Expected block or assignment, found '{s}'");
pub const ExpectedBlockOrExpression = SingleTokenError("Expected block or expression, found '{s}'");
pub const ExpectedExprOrAssignment = SingleTokenError("Expected expression or assignment, found '{s}'");
pub const ExpectedPrefixExpr = SingleTokenError("Expected prefix expression, found '{s}'");
pub const ExpectedLoopExpr = SingleTokenError("Expected loop expression, found '{s}'");
pub const ExpectedDerefOrUnwrap = SingleTokenError("Expected pointer dereference or optional unwrap, found '{s}'");
pub const ExpectedSuffixOp = SingleTokenError("Expected pointer dereference, optional unwrap, or field access, found '{s}'");
pub const ExpectedBlockOrField = SingleTokenError("Expected block or field, found '{s}'");
pub const ExpectedParamType = SimpleError("Expected parameter type");
pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");
@ -332,7 +332,7 @@ pub const Error = union(enum) {
node: *Node,
pub fn render(self: *const ExpectedCall, tokens: []const Token.Id, stream: anytype) !void {
return stream.print("expected " ++ @tagName(Node.Tag.Call) ++ ", found {}", .{
return stream.print("expected " ++ @tagName(Node.Tag.Call) ++ ", found {s}", .{
@tagName(self.node.tag),
});
}
@ -343,7 +343,7 @@ pub const Error = union(enum) {
pub fn render(self: *const ExpectedCallOrFnProto, tokens: []const Token.Id, stream: anytype) !void {
return stream.print("expected " ++ @tagName(Node.Tag.Call) ++ " or " ++
@tagName(Node.Tag.FnProto) ++ ", found {}", .{@tagName(self.node.tag)});
@tagName(Node.Tag.FnProto) ++ ", found {s}", .{@tagName(self.node.tag)});
}
};
@ -355,11 +355,11 @@ pub const Error = union(enum) {
const found_token = tokens[self.token];
switch (found_token) {
.Invalid => {
return stream.print("expected '{}', found invalid bytes", .{self.expected_id.symbol()});
return stream.print("expected '{s}', found invalid bytes", .{self.expected_id.symbol()});
},
else => {
const token_name = found_token.symbol();
return stream.print("expected '{}', found '{}'", .{ self.expected_id.symbol(), token_name });
return stream.print("expected '{s}', found '{s}'", .{ self.expected_id.symbol(), token_name });
},
}
}
@ -371,7 +371,7 @@ pub const Error = union(enum) {
pub fn render(self: *const ExpectedCommaOrEnd, tokens: []const Token.Id, stream: anytype) !void {
const actual_token = tokens[self.token];
return stream.print("expected ',' or '{}', found '{}'", .{
return stream.print("expected ',' or '{s}', found '{s}'", .{
self.end_id.symbol(),
actual_token.symbol(),
});
@ -843,7 +843,7 @@ pub const Node = struct {
std.debug.warn(" ", .{});
}
}
std.debug.warn("{}\n", .{@tagName(self.tag)});
std.debug.warn("{s}\n", .{@tagName(self.tag)});
var child_i: usize = 0;
while (self.iterate(child_i)) |child| : (child_i += 1) {
@ -1418,7 +1418,7 @@ pub const Node = struct {
@alignOf(ParamDecl),
@ptrCast([*]const u8, self) + @sizeOf(FnProto) + @sizeOf(ParamDecl) * self.params_len,
);
std.debug.print("{*} flags: {b} name_token: {} {*} params_len: {}\n", .{
std.debug.print("{*} flags: {b} name_token: {s} {*} params_len: {d}\n", .{
self,
self.trailer_flags.bits,
self.getNameToken(),

View File

@ -519,7 +519,7 @@ pub const CrossTarget = struct {
var result = std.ArrayList(u8).init(allocator);
defer result.deinit();
try result.outStream().print("{}-{}", .{ arch_name, os_name });
try result.outStream().print("{s}-{s}", .{ arch_name, os_name });
// The zig target syntax does not allow specifying a max os version with no min, so
// if either are present, we need the min.
@ -539,9 +539,9 @@ pub const CrossTarget = struct {
}
if (self.glibc_version) |v| {
try result.outStream().print("-{}.{}", .{ @tagName(self.getAbi()), v });
try result.outStream().print("-{s}.{}", .{ @tagName(self.getAbi()), v });
} else if (self.abi) |abi| {
try result.outStream().print("-{}", .{@tagName(abi)});
try result.outStream().print("-{s}", .{@tagName(abi)});
}
return result.toOwnedSlice();
@ -595,7 +595,7 @@ pub const CrossTarget = struct {
.Dynamic => "",
};
return std.fmt.allocPrint(allocator, "{}-{}{}", .{ arch, os, static_suffix });
return std.fmt.allocPrint(allocator, "{s}-{s}{s}", .{ arch, os, static_suffix });
}
pub const Executor = union(enum) {
@ -790,7 +790,7 @@ test "CrossTarget.parse" {
var buf: [256]u8 = undefined;
const triple = std.fmt.bufPrint(
buf[0..],
"native-native-{}.2.1.1",
"native-native-{s}.2.1.1",
.{@tagName(std.Target.current.abi)},
) catch unreachable;

View File

@ -3744,7 +3744,7 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
const loc = tree.tokenLocation(0, parse_error.loc());
try stderr.print("(memory buffer):{}:{}: error: ", .{ loc.line + 1, loc.column + 1 });
try tree.renderError(parse_error, stderr);
try stderr.print("\n{}\n", .{source[loc.line_start..loc.line_end]});
try stderr.print("\n{s}\n", .{source[loc.line_start..loc.line_end]});
{
var i: usize = 0;
while (i < loc.column) : (i += 1) {

View File

@ -41,7 +41,7 @@ fn renderRoot(
for (tree.token_ids) |token_id, i| {
if (token_id != .LineComment) break;
const token_loc = tree.token_locs[i];
try ais.writer().print("{}\n", .{mem.trimRight(u8, tree.tokenSliceLoc(token_loc), " ")});
try ais.writer().print("{s}\n", .{mem.trimRight(u8, tree.tokenSliceLoc(token_loc), " ")});
const next_token = tree.token_locs[i + 1];
const loc = tree.tokenLocationLoc(token_loc.end, next_token);
if (loc.line >= 2) {

View File

@ -51,7 +51,7 @@ pub const NativePaths = struct {
};
try self.addIncludeDir(include_path);
} else {
try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}", .{word});
try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {s}", .{word});
break;
}
}
@ -77,7 +77,7 @@ pub const NativePaths = struct {
const lib_path = word[2..];
try self.addLibDir(lib_path);
} else {
try self.addWarningFmt("Unrecognized C flag from NIX_LDFLAGS: {}", .{word});
try self.addWarningFmt("Unrecognized C flag from NIX_LDFLAGS: {s}", .{word});
break;
}
}
@ -113,22 +113,22 @@ pub const NativePaths = struct {
// TODO: some of these are suspect and should only be added on some systems. audit needed.
try self.addIncludeDir("/usr/local/include");
try self.addLibDirFmt("/usr/local/lib{}", .{qual});
try self.addLibDirFmt("/usr/local/lib{d}", .{qual});
try self.addLibDir("/usr/local/lib");
try self.addIncludeDirFmt("/usr/include/{}", .{triple});
try self.addLibDirFmt("/usr/lib/{}", .{triple});
try self.addIncludeDirFmt("/usr/include/{s}", .{triple});
try self.addLibDirFmt("/usr/lib/{s}", .{triple});
try self.addIncludeDir("/usr/include");
try self.addLibDirFmt("/lib{}", .{qual});
try self.addLibDirFmt("/lib{d}", .{qual});
try self.addLibDir("/lib");
try self.addLibDirFmt("/usr/lib{}", .{qual});
try self.addLibDirFmt("/usr/lib{d}", .{qual});
try self.addLibDir("/usr/lib");
// example: on a 64-bit debian-based linux distro, with zlib installed from apt:
// zlib.h is in /usr/include (added above)
// libz.so.1 is in /lib/x86_64-linux-gnu (added here)
try self.addLibDirFmt("/lib/{}", .{triple});
try self.addLibDirFmt("/lib/{s}", .{triple});
}
return self;

View File

@ -334,7 +334,7 @@ pub const Tokenizer = struct {
/// For debugging purposes
pub fn dump(self: *Tokenizer, token: *const Token) void {
std.debug.warn("{} \"{}\"\n", .{ @tagName(token.id), self.buffer[token.start..token.end] });
std.debug.warn("{s} \"{s}\"\n", .{ @tagName(token.id), self.buffer[token.start..token.end] });
}
pub fn init(buffer: []const u8) Tokenizer {
@ -2046,7 +2046,7 @@ fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
for (expected_tokens) |expected_token_id| {
const token = tokenizer.next();
if (token.id != expected_token_id) {
std.debug.panic("expected {}, found {}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
std.debug.panic("expected {s}, found {s}\n", .{ @tagName(expected_token_id), @tagName(token.id) });
}
}
const last_token = tokenizer.next();

View File

@ -141,5 +141,5 @@ comptime {
_ = @import("behavior/while.zig");
_ = @import("behavior/widening.zig");
_ = @import("behavior/src.zig");
_ = @import("behavior/translate_c_macros.zig");
// _ = @import("behavior/translate_c_macros.zig");
}