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 { ) !void {
if (fmt.len != 0) @compileError("Unknown format string: '" ++ fmt ++ "'"); if (fmt.len != 0) @compileError("Unknown format string: '" ++ fmt ++ "'");
try std.fmt.format(out_stream, "{}.{}.{}", .{ self.major, self.minor, self.patch }); 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.pre) |pre| try std.fmt.format(out_stream, "-{s}", .{pre});
if (self.build) |build| try std.fmt.format(out_stream, "+{}", .{build}); if (self.build) |build| try std.fmt.format(out_stream, "+{s}", .{build});
} }
const expect = std.testing.expect; 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; if (std.mem.eql(u8, result, expected)) return;
std.debug.warn("\n====== expected this output: =========\n", .{}); 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("\n======== instead found this: =========\n", .{});
std.debug.warn("{}", .{result}); std.debug.warn("{s}", .{result});
std.debug.warn("\n======================================\n", .{}); std.debug.warn("\n======================================\n", .{});
return error.TestFailed; 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`. /// To run an executable built with zig build, see `LibExeObjStep.run`.
pub fn addSystemCommand(self: *Builder, argv: []const []const u8) *RunStep { pub fn addSystemCommand(self: *Builder, argv: []const []const u8) *RunStep {
assert(argv.len >= 1); 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); run_step.addArgs(argv);
return run_step; return run_step;
} }
@ -409,7 +409,7 @@ pub const Builder = struct {
for (self.installed_files.items) |installed_file| { for (self.installed_files.items) |installed_file| {
const full_path = self.getInstallPath(installed_file.dir, installed_file.path); const full_path = self.getInstallPath(installed_file.dir, installed_file.path);
if (self.verbose) { if (self.verbose) {
warn("rm {}\n", .{full_path}); warn("rm {s}\n", .{full_path});
} }
fs.cwd().deleteTree(full_path) catch {}; fs.cwd().deleteTree(full_path) catch {};
} }
@ -419,7 +419,7 @@ pub const Builder = struct {
fn makeOneStep(self: *Builder, s: *Step) anyerror!void { fn makeOneStep(self: *Builder, s: *Step) anyerror!void {
if (s.loop_flag) { if (s.loop_flag) {
warn("Dependency loop detected:\n {}\n", .{s.name}); warn("Dependency loop detected:\n {s}\n", .{s.name});
return error.DependencyLoopDetected; return error.DependencyLoopDetected;
} }
s.loop_flag = true; s.loop_flag = true;
@ -427,7 +427,7 @@ pub const Builder = struct {
for (s.dependencies.items) |dep| { for (s.dependencies.items) |dep| {
self.makeOneStep(dep) catch |err| { self.makeOneStep(dep) catch |err| {
if (err == error.DependencyLoopDetected) { if (err == error.DependencyLoopDetected) {
warn(" {}\n", .{s.name}); warn(" {s}\n", .{s.name});
} }
return err; return err;
}; };
@ -444,7 +444,7 @@ pub const Builder = struct {
return &top_level_step.step; 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; return error.InvalidStepName;
} }
@ -456,7 +456,7 @@ pub const Builder = struct {
.description = description, .description = description,
}; };
if ((self.available_options_map.fetchPut(name, available_option) catch unreachable) != null) { 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; self.available_options_list.append(available_option) catch unreachable;
@ -471,32 +471,32 @@ pub const Builder = struct {
} else if (mem.eql(u8, s, "false")) { } else if (mem.eql(u8, s, "false")) {
return false; return false;
} else { } 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(); self.markInvalidUserInput();
return null; return null;
} }
}, },
.List => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
}, },
.Int => switch (entry.value.value) { .Int => switch (entry.value.value) {
.Flag => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
.Scalar => |s| { .Scalar => |s| {
const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) { const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {
error.Overflow => { 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(); self.markInvalidUserInput();
return null; return null;
}, },
else => { 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(); self.markInvalidUserInput();
return null; return null;
}, },
@ -504,34 +504,34 @@ pub const Builder = struct {
return n; return n;
}, },
.List => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
}, },
.Float => switch (entry.value.value) { .Float => switch (entry.value.value) {
.Flag => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
.Scalar => |s| { .Scalar => |s| {
const n = std.fmt.parseFloat(T, s) catch |err| { 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(); self.markInvalidUserInput();
return null; return null;
}; };
return n; return n;
}, },
.List => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
}, },
.Enum => switch (entry.value.value) { .Enum => switch (entry.value.value) {
.Flag => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
@ -539,25 +539,25 @@ pub const Builder = struct {
if (std.meta.stringToEnum(T, s)) |enum_lit| { if (std.meta.stringToEnum(T, s)) |enum_lit| {
return enum_lit; return enum_lit;
} else { } 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(); self.markInvalidUserInput();
return null; return null;
} }
}, },
.List => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
}, },
.String => switch (entry.value.value) { .String => switch (entry.value.value) {
.Flag => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
.List => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
@ -565,7 +565,7 @@ pub const Builder = struct {
}, },
.List => switch (entry.value.value) { .List => switch (entry.value.value) {
.Flag => { .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(); self.markInvalidUserInput();
return null; return null;
}, },
@ -592,7 +592,7 @@ pub const Builder = struct {
if (self.release_mode != null) { if (self.release_mode != null) {
@panic("setPreferredReleaseMode must be called before standardReleaseOptions and may not be called twice"); @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.is_release = self.option(bool, "release", description) orelse false;
self.release_mode = if (self.is_release) mode else builtin.Mode.Debug; self.release_mode = if (self.is_release) mode else builtin.Mode.Debug;
} }
@ -646,12 +646,12 @@ pub const Builder = struct {
.diagnostics = &diags, .diagnostics = &diags,
}) catch |err| switch (err) { }) catch |err| switch (err) {
error.UnknownCpuModel => { error.UnknownCpuModel => {
warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{ warn("Unknown CPU: '{s}'\nAvailable CPUs for architecture '{s}':\n", .{
diags.cpu_name.?, diags.cpu_name.?,
@tagName(diags.arch.?), @tagName(diags.arch.?),
}); });
for (diags.arch.?.allCpuModels()) |cpu| { for (diags.arch.?.allCpuModels()) |cpu| {
warn(" {}\n", .{cpu.name}); warn(" {s}\n", .{cpu.name});
} }
warn("\n", .{}); warn("\n", .{});
self.markInvalidUserInput(); self.markInvalidUserInput();
@ -659,15 +659,15 @@ pub const Builder = struct {
}, },
error.UnknownCpuFeature => { error.UnknownCpuFeature => {
warn( warn(
\\Unknown CPU feature: '{}' \\Unknown CPU feature: '{s}'
\\Available CPU features for architecture '{}': \\Available CPU features for architecture '{s}':
\\ \\
, .{ , .{
diags.unknown_feature_name, diags.unknown_feature_name,
@tagName(diags.arch.?), @tagName(diags.arch.?),
}); });
for (diags.arch.?.allFeaturesList()) |feature| { for (diags.arch.?.allFeaturesList()) |feature| {
warn(" {}: {}\n", .{ feature.name, feature.description }); warn(" {s}: {s}\n", .{ feature.name, feature.description });
} }
warn("\n", .{}); warn("\n", .{});
self.markInvalidUserInput(); self.markInvalidUserInput();
@ -675,19 +675,19 @@ pub const Builder = struct {
}, },
error.UnknownOperatingSystem => { error.UnknownOperatingSystem => {
warn( warn(
\\Unknown OS: '{}' \\Unknown OS: '{s}'
\\Available operating systems: \\Available operating systems:
\\ \\
, .{diags.os_name}); , .{diags.os_name});
inline for (std.meta.fields(std.Target.Os.Tag)) |field| { inline for (std.meta.fields(std.Target.Os.Tag)) |field| {
warn(" {}\n", .{field.name}); warn(" {s}\n", .{field.name});
} }
warn("\n", .{}); warn("\n", .{});
self.markInvalidUserInput(); self.markInvalidUserInput();
return args.default_target; return args.default_target;
}, },
else => |e| { 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(); self.markInvalidUserInput();
return args.default_target; return args.default_target;
}, },
@ -703,12 +703,12 @@ pub const Builder = struct {
break :whitelist_check; 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, selected_canonicalized_triple,
}); });
for (list) |t| { for (list) |t| {
const t_triple = t.zigTriple(self.allocator) catch unreachable; const t_triple = t.zigTriple(self.allocator) catch unreachable;
warn(" {}\n", .{t_triple}); warn(" {s}\n", .{t_triple});
} }
warn("\n", .{}); warn("\n", .{});
self.markInvalidUserInput(); self.markInvalidUserInput();
@ -752,7 +752,7 @@ pub const Builder = struct {
}) catch unreachable; }) catch unreachable;
}, },
UserValue.Flag => { 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; return true;
}, },
} }
@ -773,11 +773,11 @@ pub const Builder = struct {
// option already exists // option already exists
switch (gop.entry.value.value) { switch (gop.entry.value.value) {
UserValue.Scalar => |s| { 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; return true;
}, },
UserValue.List => { 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; return true;
}, },
UserValue.Flag => {}, UserValue.Flag => {},
@ -820,7 +820,7 @@ pub const Builder = struct {
while (true) { while (true) {
const entry = it.next() orelse break; const entry = it.next() orelse break;
if (!entry.value.used) { if (!entry.value.used) {
warn("Invalid option: -D{}\n\n", .{entry.key}); warn("Invalid option: -D{s}\n\n", .{entry.key});
self.markInvalidUserInput(); self.markInvalidUserInput();
} }
} }
@ -833,9 +833,9 @@ pub const Builder = struct {
} }
fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void { 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| { for (argv) |arg| {
warn("{} ", .{arg}); warn("{s} ", .{arg});
} }
warn("\n", .{}); warn("\n", .{});
} }
@ -852,7 +852,7 @@ pub const Builder = struct {
child.env_map = env_map; child.env_map = env_map;
const term = child.spawnAndWait() catch |err| { 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; return err;
}; };
@ -875,7 +875,7 @@ pub const Builder = struct {
pub fn makePath(self: *Builder, path: []const u8) !void { pub fn makePath(self: *Builder, path: []const u8) !void {
fs.cwd().makePath(self.pathFromRoot(path)) catch |err| { 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; return err;
}; };
} }
@ -959,7 +959,7 @@ pub const Builder = struct {
pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void { pub fn updateFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void {
if (self.verbose) { if (self.verbose) {
warn("cp {} {} ", .{ source_path, dest_path }); warn("cp {s} {s} ", .{ source_path, dest_path });
} }
const cwd = fs.cwd(); const cwd = fs.cwd();
const prev_status = try fs.Dir.updateFile(cwd, source_path, cwd, dest_path, .{}); 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{ const full_path = try fs.path.join(self.allocator, &[_][]const u8{
search_prefix, search_prefix,
"bin", "bin",
self.fmt("{}{}", .{ name, exe_extension }), self.fmt("{s}{s}", .{ name, exe_extension }),
}); });
return fs.realpathAlloc(self.allocator, full_path) catch continue; return fs.realpathAlloc(self.allocator, full_path) catch continue;
} }
@ -1002,7 +1002,7 @@ pub const Builder = struct {
while (it.next()) |path| { while (it.next()) |path| {
const full_path = try fs.path.join(self.allocator, &[_][]const u8{ const full_path = try fs.path.join(self.allocator, &[_][]const u8{
path, path,
self.fmt("{}{}", .{ name, exe_extension }), self.fmt("{s}{s}", .{ name, exe_extension }),
}); });
return fs.realpathAlloc(self.allocator, full_path) catch continue; return fs.realpathAlloc(self.allocator, full_path) catch continue;
} }
@ -1015,7 +1015,7 @@ pub const Builder = struct {
for (paths) |path| { for (paths) |path| {
const full_path = try fs.path.join(self.allocator, &[_][]const u8{ const full_path = try fs.path.join(self.allocator, &[_][]const u8{
path, path,
self.fmt("{}{}", .{ name, exe_extension }), self.fmt("{s}{s}", .{ name, exe_extension }),
}); });
return fs.realpathAlloc(self.allocator, full_path) catch continue; return fs.realpathAlloc(self.allocator, full_path) catch continue;
} }
@ -1070,19 +1070,19 @@ pub const Builder = struct {
var code: u8 = undefined; var code: u8 = undefined;
return self.execAllowFail(argv, &code, .Inherit) catch |err| switch (err) { return self.execAllowFail(argv, &code, .Inherit) catch |err| switch (err) {
error.FileNotFound => { 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", .{}); warn("Unable to spawn the following command: file not found\n", .{});
printCmd(null, argv); printCmd(null, argv);
std.os.exit(@truncate(u8, code)); std.os.exit(@truncate(u8, code));
}, },
error.ExitCodeFailure => { error.ExitCodeFailure => {
if (src_step) |s| warn("{}...", .{s.name}); if (src_step) |s| warn("{s}...", .{s.name});
warn("The following command exited with error code {}:\n", .{code}); warn("The following command exited with error code {d}:\n", .{code});
printCmd(null, argv); printCmd(null, argv);
std.os.exit(@truncate(u8, code)); std.os.exit(@truncate(u8, code));
}, },
error.ProcessTerminated => { error.ProcessTerminated => {
if (src_step) |s| warn("{}...", .{s.name}); if (src_step) |s| warn("{s}...", .{s.name});
warn("The following command terminated unexpectedly:\n", .{}); warn("The following command terminated unexpectedly:\n", .{});
printCmd(null, argv); printCmd(null, argv);
std.os.exit(@truncate(u8, code)); std.os.exit(@truncate(u8, code));
@ -1405,7 +1405,7 @@ pub const LibExeObjStep = struct {
ver: ?Version, ver: ?Version,
) LibExeObjStep { ) LibExeObjStep {
if (mem.indexOf(u8, name, "/") != null or mem.indexOf(u8, name, "\\") != null) { 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{ var self = LibExeObjStep{
.strip = false, .strip = false,
@ -1421,9 +1421,9 @@ pub const LibExeObjStep = struct {
.step = Step.init(.LibExeObj, name, builder.allocator, make), .step = Step.init(.LibExeObj, name, builder.allocator, make),
.version = ver, .version = ver,
.out_filename = undefined, .out_filename = undefined,
.out_h_filename = builder.fmt("{}.h", .{name}), .out_h_filename = builder.fmt("{s}.h", .{name}),
.out_lib_filename = undefined, .out_lib_filename = undefined,
.out_pdb_filename = builder.fmt("{}.pdb", .{name}), .out_pdb_filename = builder.fmt("{s}.pdb", .{name}),
.major_only_filename = undefined, .major_only_filename = undefined,
.name_only_filename = undefined, .name_only_filename = undefined,
.packages = ArrayList(Pkg).init(builder.allocator), .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. // 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 // Consider that this is declarative; the run step may not be run unless a user
// option is supplied. // 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); run_step.addArtifactArg(exe);
if (exe.vcpkg_bin_path) |path| { if (exe.vcpkg_bin_path) |path| {
@ -1680,7 +1680,7 @@ pub const LibExeObjStep = struct {
} else if (mem.eql(u8, tok, "-pthread")) { } else if (mem.eql(u8, tok, "-pthread")) {
self.linkLibC(); self.linkLibC();
} else if (self.builder.verbose) { } 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 => {}, 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. /// The value is the path in the cache dir.
@ -2048,7 +2048,7 @@ pub const LibExeObjStep = struct {
const builder = self.builder; const builder = self.builder;
if (self.root_src == null and self.link_objects.items.len == 0) { 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; 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. // Render build artifact options at the last minute, now that the path is known.
for (self.build_options_artifact_args.items) |item| { for (self.build_options_artifact_args.items) |item| {
const out = self.build_options_contents.writer(); 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( const build_options_file = try fs.path.join(
builder.allocator, 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); const path_from_root = builder.pathFromRoot(build_options_file);
try fs.cwd().writeFile(path_from_root, self.build_options_contents.items); try fs.cwd().writeFile(path_from_root, self.build_options_contents.items);
@ -2294,16 +2294,16 @@ pub const LibExeObjStep = struct {
} else { } else {
var mcpu_buffer = std.ArrayList(u8).init(builder.allocator); 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| { for (all_features) |feature, i_usize| {
const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize); const i = @intCast(std.Target.Cpu.Feature.Set.Index, i_usize);
const in_cpu_set = populated_cpu_features.isEnabled(i); const in_cpu_set = populated_cpu_features.isEnabled(i);
const in_actual_set = cross.cpu.features.isEnabled(i); const in_actual_set = cross.cpu.features.isEnabled(i);
if (in_cpu_set and !in_actual_set) { 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) { } 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; const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{ self.* = Self{
.builder = builder, .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, .artifact = artifact,
.dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) { .dest_dir = artifact.override_dest_dir orelse switch (artifact.kind) {
.Obj => unreachable, .Obj => unreachable,
@ -2612,7 +2612,7 @@ pub const InstallFileStep = struct {
builder.pushInstalledFile(dir, dest_rel_path); builder.pushInstalledFile(dir, dest_rel_path);
return InstallFileStep{ return InstallFileStep{
.builder = builder, .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, .src_path = src_path,
.dir = dir, .dir = dir,
.dest_rel_path = dest_rel_path, .dest_rel_path = dest_rel_path,
@ -2646,7 +2646,7 @@ pub const InstallDirStep = struct {
builder.pushInstalledFile(options.install_dir, options.install_subdir); builder.pushInstalledFile(options.install_dir, options.install_subdir);
return InstallDirStep{ return InstallDirStep{
.builder = builder, .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, .options = options,
}; };
} }
@ -2682,14 +2682,14 @@ pub const LogStep = struct {
pub fn init(builder: *Builder, data: []const u8) LogStep { pub fn init(builder: *Builder, data: []const u8) LogStep {
return LogStep{ return LogStep{
.builder = builder, .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, .data = data,
}; };
} }
fn make(step: *Step) anyerror!void { fn make(step: *Step) anyerror!void {
const self = @fieldParentPtr(LogStep, "step", step); 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 { pub fn init(builder: *Builder, dir_path: []const u8) RemoveDirStep {
return RemoveDirStep{ return RemoveDirStep{
.builder = builder, .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, .dir_path = dir_path,
}; };
} }
@ -2711,7 +2711,7 @@ pub const RemoveDirStep = struct {
const full_path = self.builder.pathFromRoot(self.dir_path); const full_path = self.builder.pathFromRoot(self.dir_path);
fs.cwd().deleteTree(full_path) catch |err| { 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; return err;
}; };
} }
@ -2799,7 +2799,7 @@ fn doAtomicSymLinks(allocator: *Allocator, output_path: []const u8, filename_maj
&[_][]const u8{ out_dir, filename_major_only }, &[_][]const u8{ out_dir, filename_major_only },
) catch unreachable; ) catch unreachable;
fs.atomicSymLink(allocator, out_basename, major_only_path) catch |err| { 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; return err;
}; };
// sym link for libfoo.so to libfoo.so.1 // 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 }, &[_][]const u8{ out_dir, filename_name_only },
) catch unreachable; ) catch unreachable;
fs.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| { 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; return err;
}; };
} }

View File

@ -45,9 +45,9 @@ pub const CheckFileStep = struct {
warn( warn(
\\ \\
\\========= Expected to find: =================== \\========= Expected to find: ===================
\\{} \\{s}
\\========= But file does not contain it: ======= \\========= But file does not contain it: =======
\\{} \\{s}
\\ \\
, .{ expected_match, contents }); , .{ expected_match, contents });
return error.TestFailed; 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 { pub fn create(builder: *Builder, artifact: *LibExeObjStep, dest_filename: []const u8) *Self {
const self = builder.allocator.create(Self) catch unreachable; const self = builder.allocator.create(Self) catch unreachable;
self.* = Self{ 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, .builder = builder,
.artifact = artifact, .artifact = artifact,
.dest_dir = switch (artifact.kind) { .dest_dir = switch (artifact.kind) {

View File

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

View File

@ -80,14 +80,14 @@ pub const WriteFileStep = struct {
}); });
// TODO replace with something like fs.makePathAndOpenDir // TODO replace with something like fs.makePathAndOpenDir
fs.cwd().makePath(self.output_dir) catch |err| { 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; return err;
}; };
var dir = try fs.cwd().openDir(self.output_dir, .{}); var dir = try fs.cwd().openDir(self.output_dir, .{});
defer dir.close(); defer dir.close();
for (self.files.items) |file| { for (self.files.items) |file| {
dir.writeFile(file.basename, file.bytes) catch |err| { 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, file.basename,
self.output_dir, self.output_dir,
@errorName(err), @errorName(err),

View File

@ -67,12 +67,12 @@ pub const StackTrace = struct {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit(); defer arena.deinit();
const debug_info = std.debug.getSelfDebugInfo() catch |err| { 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(); const tty_config = std.debug.detectTTYConfig();
try writer.writeAll("\n"); try writer.writeAll("\n");
std.debug.writeStackTrace(self, writer, &arena.allocator, debug_info, tty_config) catch |err| { 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"); try writer.writeAll("\n");
} }
@ -529,12 +529,12 @@ pub const Version = struct {
if (fmt.len == 0) { if (fmt.len == 0) {
if (self.patch == 0) { if (self.patch == 0) {
if (self.minor == 0) { if (self.minor == 0) {
return std.fmt.format(out_stream, "{}", .{self.major}); return std.fmt.format(out_stream, "{d}", .{self.major});
} else { } else {
return std.fmt.format(out_stream, "{}.{}", .{ self.major, self.minor }); return std.fmt.format(out_stream, "{d}.{d}", .{ self.major, self.minor });
} }
} else { } 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 { } else {
@compileError("Unknown format string: '" ++ fmt ++ "'"); @compileError("Unknown format string: '" ++ fmt ++ "'");
@ -683,7 +683,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
} }
}, },
.wasi => { .wasi => {
std.debug.warn("{}", .{msg}); std.debug.warn("{s}", .{msg});
std.os.abort(); std.os.abort();
}, },
.uefi => { .uefi => {
@ -692,7 +692,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn
}, },
else => { else => {
const first_trace_addr = @returnAddress(); 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| { for (expected_tokens) |expected_token_id| {
const token = tokenizer.next(); const token = tokenizer.next();
if (!std.meta.eql(token.id, expected_token_id)) { 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(); 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]); Codec.encode(ct_str[0..], ct[0 .. ct.len - 1]);
var s_buf: [hash_length]u8 = undefined; 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); debug.assert(s.len == s_buf.len);
return s_buf; return s_buf;
} }

View File

@ -108,11 +108,11 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
return; return;
} }
const debug_info = getSelfDebugInfo() catch |err| { 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; return;
}; };
writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(), start_addr) catch |err| { 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; return;
}; };
} }
@ -129,7 +129,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
return; return;
} }
const debug_info = getSelfDebugInfo() catch |err| { 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; return;
}; };
const tty_config = detectTTYConfig(); const tty_config = detectTTYConfig();
@ -199,11 +199,11 @@ pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void {
return; return;
} }
const debug_info = getSelfDebugInfo() catch |err| { 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; return;
}; };
writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, detectTTYConfig()) catch |err| { 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; return;
}; };
} }
@ -611,7 +611,7 @@ fn printLineInfo(
tty_config.setColor(out_stream, .White); tty_config.setColor(out_stream, .White);
if (line_info) |*li| { 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 { } else {
try out_stream.writeAll("???:?:?"); try out_stream.writeAll("???:?:?");
} }
@ -619,7 +619,7 @@ fn printLineInfo(
tty_config.setColor(out_stream, .Reset); tty_config.setColor(out_stream, .Reset);
try out_stream.writeAll(": "); try out_stream.writeAll(": ");
tty_config.setColor(out_stream, .Dim); 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); tty_config.setColor(out_stream, .Reset);
try out_stream.writeAll("\n"); try out_stream.writeAll("\n");

View File

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

View File

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

View File

@ -314,7 +314,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
if (is_used) { if (is_used) {
const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index); const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index);
const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc); 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; leaks = true;
} }
if (bit_index == math.maxInt(u3)) if (bit_index == math.maxInt(u3))
@ -342,7 +342,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
} }
var it = self.large_allocations.iterator(); var it = self.large_allocations.iterator();
while (it.next()) |large_alloc| { 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; leaks = true;
} }
return leaks; return leaks;
@ -443,7 +443,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
.index = 0, .index = 0,
}; };
std.debug.captureStackTrace(ret_addr, &free_stack_trace); 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, entry.value.bytes.len,
old_mem.len, old_mem.len,
entry.value.getStackTrace(), entry.value.getStackTrace(),
@ -526,7 +526,7 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type {
.index = 0, .index = 0,
}; };
std.debug.captureStackTrace(ret_addr, &second_free_stack_trace); 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, alloc_stack_trace,
free_stack_trace, free_stack_trace,
second_free_stack_trace, second_free_stack_trace,

View File

@ -147,7 +147,7 @@ test "FixedBufferStream output" {
var fbs = fixedBufferStream(&buf); var fbs = fixedBufferStream(&buf);
const stream = fbs.writer(); const stream = fbs.writer();
try stream.print("{}{}!", .{ "Hello", "World" }); try stream.print("{s}{s}!", .{ "Hello", "World" });
testing.expectEqualSlices(u8, "HelloWorld!", fbs.getWritten()); 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) { if (self.expected_remaining.len < bytes.len) {
std.debug.warn( std.debug.warn(
\\====== expected this output: ========= \\====== expected this output: =========
\\{} \\{s}
\\======== instead found this: ========= \\======== instead found this: =========
\\{} \\{s}
\\====================================== \\======================================
, .{ , .{
self.expected_remaining, 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)) { if (!mem.eql(u8, self.expected_remaining[0..bytes.len], bytes)) {
std.debug.warn( std.debug.warn(
\\====== expected this output: ========= \\====== expected this output: =========
\\{} \\{s}
\\======== instead found this: ========= \\======== instead found this: =========
\\{} \\{s}
\\====================================== \\======================================
, .{ , .{
self.expected_remaining[0..bytes.len], self.expected_remaining[0..bytes.len],

View File

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

View File

@ -1618,7 +1618,7 @@ pub fn unexpectedError(err: Win32Error) std.os.UnexpectedError {
null, null,
); );
_ = std.unicode.utf16leToUtf8(&buf_u8, buf_u16[0..len]) catch unreachable; _ = 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); std.debug.dumpCurrentStackTrace(null);
} }
return error.Unexpected; 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| { for (expected_args) |expected_arg| {
const arg = it.next(std.testing.allocator).? catch unreachable; const arg = it.next(std.testing.allocator).? catch unreachable;
defer std.testing.allocator.free(arg); 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); 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(); test_node.activate();
progress.refresh(); progress.refresh();
if (progress.terminal == null) { 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) { const result = if (test_fn.async_frame_size) |size| switch (io_mode) {
.evented => blk: { .evented => blk: {
@ -62,7 +62,7 @@ pub fn main() anyerror!void {
.blocking => { .blocking => {
skip_count += 1; skip_count += 1;
test_node.end(); 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", .{}); if (progress.terminal == null) std.debug.print("SKIP (async test)\n", .{});
continue; continue;
}, },
@ -75,7 +75,7 @@ pub fn main() anyerror!void {
error.SkipZigTest => { error.SkipZigTest => {
skip_count += 1; skip_count += 1;
test_node.end(); 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", .{}); if (progress.terminal == null) std.debug.print("SKIP\n", .{});
}, },
else => { else => {
@ -86,15 +86,15 @@ pub fn main() anyerror!void {
} }
root_node.end(); root_node.end();
if (ok_count == test_fn_list.len) { 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 { } 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) { 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) { 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) { if (leaks != 0 or log_err_count != 0) {
std.process.exit(1); std.process.exit(1);
@ -111,6 +111,6 @@ pub fn log(
log_err_count += 1; log_err_count += 1;
} }
if (@enumToInt(message_level) <= @enumToInt(std.testing.log_level)) { 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 (std.event.Loop.instance) |loop| {
if (!@hasDecl(root, "event_loop")) { if (!@hasDecl(root, "event_loop")) {
loop.init() catch |err| { loop.init() catch |err| {
std.log.err("{}", .{@errorName(err)}); std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*); std.debug.dumpStackTrace(trace.*);
} }
@ -295,7 +295,7 @@ inline fn initEventLoopAndCallWinMain() std.os.windows.INT {
if (std.event.Loop.instance) |loop| { if (std.event.Loop.instance) |loop| {
if (!@hasDecl(root, "event_loop")) { if (!@hasDecl(root, "event_loop")) {
loop.init() catch |err| { loop.init() catch |err| {
std.log.err("{}", .{@errorName(err)}); std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*); std.debug.dumpStackTrace(trace.*);
} }
@ -343,7 +343,7 @@ pub fn callMain() u8 {
}, },
.ErrorUnion => { .ErrorUnion => {
const result = root.main() catch |err| { const result = root.main() catch |err| {
std.log.err("{}", .{@errorName(err)}); std.log.err("{s}", .{@errorName(err)});
if (@errorReturnTrace()) |trace| { if (@errorReturnTrace()) |trace| {
std.debug.dumpStackTrace(trace.*); std.debug.dumpStackTrace(trace.*);
} }

View File

@ -136,14 +136,14 @@ pub const Target = struct {
) !void { ) !void {
if (fmt.len > 0 and fmt[0] == 's') { if (fmt.len > 0 and fmt[0] == 's') {
if (@enumToInt(self) >= @enumToInt(WindowsVersion.nt4) and @enumToInt(self) <= @enumToInt(WindowsVersion.latest)) { 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 { } else {
// TODO this code path breaks zig triples, but it is used in `builtin` // 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)}); try std.fmt.format(out_stream, "@intToEnum(Target.Os.WindowsVersion, 0x{X:0>8})", .{@enumToInt(self)});
} }
} else { } else {
if (@enumToInt(self) >= @enumToInt(WindowsVersion.nt4) and @enumToInt(self) <= @enumToInt(WindowsVersion.latest)) { 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 { } else {
try std.fmt.format(out_stream, "WindowsVersion(0x{X:0>8})", .{@enumToInt(self)}); 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 { 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 { pub fn linuxTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
@ -1381,7 +1381,7 @@ pub const Target = struct {
if (self.abi == .android) { if (self.abi == .android) {
const suffix = if (self.cpu.arch.ptrBitWidth() == 64) "64" else ""; 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()) { if (self.abi.isMusl()) {
@ -1395,7 +1395,7 @@ pub const Target = struct {
else => |arch| @tagName(arch), else => |arch| @tagName(arch),
}; };
const arch_suffix = if (is_arm and self.abi.floatAbi() == .hard) "hf" else ""; 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) { switch (self.os.tag) {
@ -1434,7 +1434,7 @@ pub const Target = struct {
}; };
const is_nan_2008 = mips.featureSetHas(self.cpu.features, .nan2008); 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"; 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"), .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. /// and then aborts when actual_error_union is not expected_error.
pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void { pub fn expectError(expected_error: anyerror, actual_error_union: anytype) void {
if (actual_error_union) |actual_payload| { 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| { } else |actual_error| {
if (expected_error != 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(expected_error),
@errorName(actual_error), @errorName(actual_error),
}); });
@ -60,7 +61,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void {
.Type => { .Type => {
if (actual != expected) { 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| { for (expected[0..diff_index]) |value| {
if (value == '\n') diff_line_number += 1; 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", .{}); print("expected:\n", .{});
printIndicatorLine(expected, diff_index); 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) { while (std.mem.indexOf(u8, source[i..], "\n")) |nl| : (i += nl + 1) {
printLine(source[i .. i + nl]); 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 { fn printLine(line: []const u8) void {
if (line.len != 0) switch (line[line.len - 1]) { 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 => {}, else => {},
}; };
print("{}\n", .{line}); print("{s}\n", .{line});
} }
test "" { test "" {

View File

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

View File

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

View File

@ -519,7 +519,7 @@ pub const CrossTarget = struct {
var result = std.ArrayList(u8).init(allocator); var result = std.ArrayList(u8).init(allocator);
defer result.deinit(); 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 // The zig target syntax does not allow specifying a max os version with no min, so
// if either are present, we need the min. // if either are present, we need the min.
@ -539,9 +539,9 @@ pub const CrossTarget = struct {
} }
if (self.glibc_version) |v| { 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| { } else if (self.abi) |abi| {
try result.outStream().print("-{}", .{@tagName(abi)}); try result.outStream().print("-{s}", .{@tagName(abi)});
} }
return result.toOwnedSlice(); return result.toOwnedSlice();
@ -595,7 +595,7 @@ pub const CrossTarget = struct {
.Dynamic => "", .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) { pub const Executor = union(enum) {
@ -790,7 +790,7 @@ test "CrossTarget.parse" {
var buf: [256]u8 = undefined; var buf: [256]u8 = undefined;
const triple = std.fmt.bufPrint( const triple = std.fmt.bufPrint(
buf[0..], buf[0..],
"native-native-{}.2.1.1", "native-native-{s}.2.1.1",
.{@tagName(std.Target.current.abi)}, .{@tagName(std.Target.current.abi)},
) catch unreachable; ) 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()); const loc = tree.tokenLocation(0, parse_error.loc());
try stderr.print("(memory buffer):{}:{}: error: ", .{ loc.line + 1, loc.column + 1 }); try stderr.print("(memory buffer):{}:{}: error: ", .{ loc.line + 1, loc.column + 1 });
try tree.renderError(parse_error, stderr); 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; var i: usize = 0;
while (i < loc.column) : (i += 1) { while (i < loc.column) : (i += 1) {

View File

@ -41,7 +41,7 @@ fn renderRoot(
for (tree.token_ids) |token_id, i| { for (tree.token_ids) |token_id, i| {
if (token_id != .LineComment) break; if (token_id != .LineComment) break;
const token_loc = tree.token_locs[i]; 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 next_token = tree.token_locs[i + 1];
const loc = tree.tokenLocationLoc(token_loc.end, next_token); const loc = tree.tokenLocationLoc(token_loc.end, next_token);
if (loc.line >= 2) { if (loc.line >= 2) {

View File

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

View File

@ -334,7 +334,7 @@ pub const Tokenizer = struct {
/// For debugging purposes /// For debugging purposes
pub fn dump(self: *Tokenizer, token: *const Token) void { 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 { 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| { for (expected_tokens) |expected_token_id| {
const token = tokenizer.next(); const token = tokenizer.next();
if (token.id != expected_token_id) { 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(); const last_token = tokenizer.next();

View File

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