Commit 7e2a26c0c4
Changed files (29)
lib
compiler
std
Build
Step
math
zig
llvm
src
arch
riscv64
link
Sema
lib/compiler/aro/aro/Diagnostics.zig
@@ -461,10 +461,10 @@ pub fn renderMessage(comp: *Compilation, m: anytype, msg: Message) void {
try writer.writeByte(@intCast(codepoint));
} else if (codepoint < 0xFFFF) {
try writer.writeAll("\\u");
- try writer.printIntOptions(codepoint, 16, .upper, .{ .fill = '0', .width = 4 });
+ try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 4 });
} else {
try writer.writeAll("\\U");
- try writer.printIntOptions(codepoint, 16, .upper, .{ .fill = '0', .width = 8 });
+ try writer.printInt(codepoint, 16, .upper, .{ .fill = '0', .width = 8 });
}
}
}
lib/compiler/aro/aro/Preprocessor.zig
@@ -3262,7 +3262,7 @@ fn printLinemarker(
// containing the same bytes as the input regardless of encoding.
else => {
try w.writeAll("\\x");
- // TODO try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
+ // TODO try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
try w.print("{x:0>2}", .{byte});
},
};
lib/compiler/aro/aro/Value.zig
@@ -961,8 +961,7 @@ pub fn print(v: Value, ty: Type, comp: *const Compilation, w: anytype) @TypeOf(w
switch (key) {
.null => return w.writeAll("nullptr_t"),
.int => |repr| switch (repr) {
- inline .u64, .i64 => |x| return w.print("{d}", .{x}),
- .big_int => |x| return w.print("{fd}", .{x}),
+ inline .u64, .i64, .big_int => |x| return w.print("{d}", .{x}),
},
.float => |repr| switch (repr) {
.f16 => |x| return w.print("{d}", .{@round(@as(f64, @floatCast(x)) * 1000) / 1000}),
lib/std/Build/Step/CheckObject.zig
@@ -230,12 +230,7 @@ const ComputeCompareExpected = struct {
literal: u64,
},
- pub fn format(
- value: ComputeCompareExpected,
- bw: *Writer,
- comptime fmt: []const u8,
- ) !void {
- if (fmt.len != 0) std.fmt.invalidFmtError(fmt, value);
+ pub fn format(value: ComputeCompareExpected, bw: *Writer) Writer.Error!void {
try bw.print("{s} ", .{@tagName(value.op)});
switch (value.value) {
.variable => |name| try bw.writeAll(name),
@@ -571,7 +566,9 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void {
null,
.of(u64),
null,
- ) catch |err| return step.fail("unable to read '{f'}': {s}", .{ src_path, @errorName(err) });
+ ) catch |err| return step.fail("unable to read '{f}': {s}", .{
+ std.fmt.alt(src_path, .formatEscapeChar), @errorName(err),
+ });
var vars: std.StringHashMap(u64) = .init(gpa);
for (check_object.checks.items) |chk| {
lib/std/io/Writer.zig
@@ -777,15 +777,15 @@ pub fn printAddress(w: *Writer, value: anytype) Error!void {
.pointer => |info| {
try w.writeAll(@typeName(info.child) ++ "@");
if (info.size == .slice)
- try w.printIntOptions(@intFromPtr(value.ptr), 16, .lower, .{})
+ try w.printInt(@intFromPtr(value.ptr), 16, .lower, .{})
else
- try w.printIntOptions(@intFromPtr(value), 16, .lower, .{});
+ try w.printInt(@intFromPtr(value), 16, .lower, .{});
return;
},
.optional => |info| {
if (@typeInfo(info.child) == .pointer) {
try w.writeAll(@typeName(info.child) ++ "@");
- try w.printIntOptions(@intFromPtr(value), 16, .lower, .{});
+ try w.printInt(@intFromPtr(value), 16, .lower, .{});
return;
}
},
@@ -804,11 +804,147 @@ pub fn printValue(
) Error!void {
const T = @TypeOf(value);
- if (fmt.len == 1) switch (fmt[0]) {
- '*' => return w.printAddress(value),
- 'f' => return value.format(w),
+ switch (fmt.len) {
+ 1 => switch (fmt[0]) {
+ '*' => return w.printAddress(value),
+ 'f' => return value.format(w),
+ 'd' => switch (@typeInfo(T)) {
+ .float, .comptime_float => return printFloat(w, value, .decimal, options),
+ .int, .comptime_int => return printInt(w, value, 10, .lower, options),
+ .@"struct" => return value.formatInteger(w, 10, .lower),
+ .@"enum" => return printInt(w, @intFromEnum(value), 10, .lower, options),
+ .vector => return printVector(w, fmt, options, value, max_depth),
+ else => invalidFmtError(fmt, value),
+ },
+ 'c' => return w.printAsciiChar(value, options),
+ 'u' => return w.printUnicodeCodepoint(value),
+ 'b' => switch (@typeInfo(T)) {
+ .int, .comptime_int => return printInt(w, value, 2, .lower, options),
+ .@"enum" => return printInt(w, @intFromEnum(value), 2, .lower, options),
+ .@"struct" => return value.formatInteger(w, 2, .lower),
+ .vector => return printVector(w, fmt, options, value, max_depth),
+ else => invalidFmtError(fmt, value),
+ },
+ 'o' => switch (@typeInfo(T)) {
+ .int, .comptime_int => return printInt(w, value, 8, .lower, options),
+ .@"enum" => return printInt(w, @intFromEnum(value), 8, .lower, options),
+ .@"struct" => return value.formatInteger(w, 8, .lower),
+ .vector => return printVector(w, fmt, options, value, max_depth),
+ else => invalidFmtError(fmt, value),
+ },
+ 'x' => switch (@typeInfo(T)) {
+ .float, .comptime_float => return printFloatHexOptions(w, value, .lower, options),
+ .int, .comptime_int => return printInt(w, value, 16, .lower, options),
+ .@"enum" => return printInt(w, @intFromEnum(value), 16, .lower, options),
+ .@"struct" => return value.formatInteger(w, 16, .lower),
+ .pointer => |info| switch (info.size) {
+ .one, .slice => {
+ const slice: []const u8 = value;
+ return printHex(w, slice, .lower);
+ },
+ .many, .c => {
+ const slice: [:0]const u8 = std.mem.span(value);
+ return printHex(w, slice, .lower);
+ },
+ },
+ .array => {
+ const slice: []const u8 = &value;
+ return printHex(w, slice, .lower);
+ },
+ .vector => return printVector(w, fmt, options, value, max_depth),
+ else => invalidFmtError(fmt, value),
+ },
+ 'X' => switch (@typeInfo(T)) {
+ .float, .comptime_float => return printFloatHexOptions(w, value, .lower, options),
+ .int, .comptime_int => return printInt(w, value, 16, .upper, options),
+ .@"enum" => return printInt(w, @intFromEnum(value), 16, .upper, options),
+ .@"struct" => return value.formatInteger(w, 16, .upper),
+ .pointer => |info| switch (info.size) {
+ .one, .slice => {
+ const slice: []const u8 = value;
+ return printHex(w, slice, .upper);
+ },
+ .many, .c => {
+ const slice: [:0]const u8 = std.mem.span(value);
+ return printHex(w, slice, .upper);
+ },
+ },
+ .array => {
+ const slice: []const u8 = &value;
+ return printHex(w, slice, .upper);
+ },
+ .vector => return printVector(w, fmt, options, value, max_depth),
+ else => invalidFmtError(fmt, value),
+ },
+ 's' => switch (@typeInfo(T)) {
+ .pointer => |info| switch (info.size) {
+ .one, .slice => {
+ const slice: []const u8 = value;
+ return w.writeAll(slice);
+ },
+ .many, .c => {
+ const slice: [:0]const u8 = std.mem.span(value);
+ return w.writeAll(slice);
+ },
+ },
+ .array => {
+ const slice: []const u8 = &value;
+ return w.writeAll(slice);
+ },
+ else => invalidFmtError(fmt, value),
+ },
+ 'B' => switch (@typeInfo(T)) {
+ .int, .comptime_int => return w.printByteSize(value, .decimal, options),
+ .@"struct" => return value.formatByteSize(w, .decimal),
+ else => invalidFmtError(fmt, value),
+ },
+ 'D' => switch (@typeInfo(T)) {
+ .int, .comptime_int => return w.printDuration(value, options),
+ .@"struct" => return value.formatDuration(w),
+ else => invalidFmtError(fmt, value),
+ },
+ 'e' => switch (@typeInfo(T)) {
+ .float, .comptime_float => return printFloat(w, value, .scientific, options),
+ .@"struct" => return value.formatFloat(w, .scientific),
+ else => invalidFmtError(fmt, value),
+ },
+ 't' => switch (@typeInfo(T)) {
+ .error_set => return w.writeAll(@errorName(value)),
+ .@"enum", .@"union" => return w.writeAll(@tagName(value)),
+ else => invalidFmtError(fmt, value),
+ },
+ else => {},
+ },
+ 2 => switch (fmt[0]) {
+ 'B' => switch (fmt[1]) {
+ 'i' => switch (@typeInfo(T)) {
+ .int, .comptime_int => return w.printByteSize(value, .binary, options),
+ .@"struct" => return value.formatByteSize(w, .binary),
+ else => invalidFmtError(fmt, value),
+ },
+ else => {},
+ },
+ else => {},
+ },
+ 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') switch (@typeInfo(T)) {
+ .pointer => |info| switch (info.size) {
+ .one, .slice => {
+ const slice: []const u8 = value;
+ return w.printBase64(slice);
+ },
+ .many, .c => {
+ const slice: [:0]const u8 = std.mem.span(value);
+ return w.printBase64(slice);
+ },
+ },
+ .array => {
+ const slice: []const u8 = &value;
+ return w.printBase64(slice);
+ },
+ else => invalidFmtError(fmt, value),
+ },
else => {},
- };
+ }
const is_any = comptime std.mem.eql(u8, fmt, ANY);
if (!is_any and std.meta.hasMethod(T, "format") and fmt.len == 0) {
@@ -817,15 +953,21 @@ pub fn printValue(
}
switch (@typeInfo(T)) {
- .float, .comptime_float => return w.printFloat(if (is_any) "d" else fmt, options, value),
- .int, .comptime_int => return w.printInt(if (is_any) "d" else fmt, options, value),
+ .float, .comptime_float => {
+ if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
+ return printFloat(w, value, .decimal, options);
+ },
+ .int, .comptime_int => {
+ if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
+ return printInt(w, value, 10, .lower, options);
+ },
.bool => {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- return w.alignBufferOptions(if (value) "true" else "false", options);
+ return w.writeAll(if (value) "true" else "false");
},
.void => {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- return w.alignBufferOptions("void", options);
+ return w.writeAll("void");
},
.optional => {
const remaining_fmt = comptime if (fmt.len > 0 and fmt[0] == '?')
@@ -854,40 +996,18 @@ pub fn printValue(
}
},
.error_set => {
- if (fmt.len == 1 and fmt[0] == 't') return w.writeAll(@errorName(value));
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- try printErrorSet(w, value);
+ return printErrorSet(w, value);
},
- .@"enum" => {
- if (fmt.len == 1 and fmt[0] == 't') {
- try w.writeAll(@tagName(value));
- return;
- }
- if (!is_any) {
- if (fmt.len != 0) return printValue(w, fmt, options, @intFromEnum(value), max_depth);
- return printValue(w, ANY, options, value, max_depth);
- }
- const enum_info = @typeInfo(T).@"enum";
- if (enum_info.is_exhaustive) {
- var vecs: [2][]const u8 = .{ ".", @tagName(value) };
- try w.writeVecAll(&vecs);
- return;
- }
- if (std.enums.tagName(T, value)) |tag_name| {
- var vecs: [2][]const u8 = .{ ".", tag_name };
- try w.writeVecAll(&vecs);
- return;
+ .@"enum" => |info| {
+ if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
+ if (info.is_exhaustive) {
+ return printEnumExhaustive(w, value);
+ } else {
+ return printEnumNonexhaustive(w, value);
}
- try w.writeAll("@enumFromInt(");
- try w.printValue(ANY, options, @intFromEnum(value), max_depth);
- try w.writeByte(')');
- return;
},
.@"union" => |info| {
- if (fmt.len == 1 and fmt[0] == 't') {
- try w.writeAll(@tagName(value));
- return;
- }
if (!is_any) {
if (fmt.len != 0) invalidFmtError(fmt, value);
return printValue(w, ANY, options, value, max_depth);
@@ -971,38 +1091,18 @@ pub fn printValue(
else => {
var buffers: [2][]const u8 = .{ @typeName(ptr_info.child), "@" };
try w.writeVecAll(&buffers);
- try w.printIntOptions(@intFromPtr(value), 16, .lower, options);
+ try w.printInt(@intFromPtr(value), 16, .lower, options);
return;
},
},
.many, .c => {
- if (ptr_info.sentinel() != null)
- return w.printValue(fmt, options, std.mem.span(value), max_depth);
- if (fmt.len == 1 and fmt[0] == 's' and ptr_info.child == u8)
- return w.alignBufferOptions(std.mem.span(value), options);
- if (!is_any and fmt.len == 0)
- @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
- if (!is_any and fmt.len != 0)
- invalidFmtError(fmt, value);
+ if (!is_any) @compileError("cannot format pointer without a specifier (i.e. {s} or {*})");
try w.printAddress(value);
},
.slice => {
- if (!is_any and fmt.len == 0)
+ if (!is_any)
@compileError("cannot format slice without a specifier (i.e. {s}, {x}, {b64}, or {any})");
- if (max_depth == 0)
- return w.writeAll("{ ... }");
- if (ptr_info.child == u8) switch (fmt.len) {
- 1 => switch (fmt[0]) {
- 's' => return w.alignBufferOptions(value, options),
- 'x' => return w.printHex(value, .lower),
- 'X' => return w.printHex(value, .upper),
- else => {},
- },
- 3 => if (fmt[0] == 'b' and fmt[1] == '6' and fmt[2] == '4') {
- return w.printBase64(value);
- },
- else => {},
- };
+ if (max_depth == 0) return w.writeAll("{ ... }");
try w.writeAll("{ ");
for (value, 0..) |elem, i| {
try w.printValue(fmt, options, elem, max_depth - 1);
@@ -1013,21 +1113,9 @@ pub fn printValue(
try w.writeAll(" }");
},
},
- .array => |info| {
- if (fmt.len == 0)
- @compileError("cannot format array without a specifier (i.e. {s} or {any})");
- if (max_depth == 0) {
- return w.writeAll("{ ... }");
- }
- if (info.child == u8) {
- if (fmt[0] == 's') {
- return w.alignBufferOptions(&value, options);
- } else if (fmt[0] == 'x') {
- return w.printHex(&value, .lower);
- } else if (fmt[0] == 'X') {
- return w.printHex(&value, .upper);
- }
- }
+ .array => {
+ if (!is_any) @compileError("cannot format array without a specifier (i.e. {s} or {any})");
+ if (max_depth == 0) return w.writeAll("{ ... }");
try w.writeAll("{ ");
for (value, 0..) |elem, i| {
try w.printValue(fmt, options, elem, max_depth - 1);
@@ -1037,33 +1125,23 @@ pub fn printValue(
}
try w.writeAll(" }");
},
- .vector => |info| {
- if (max_depth == 0) {
- return w.writeAll("{ ... }");
- }
- try w.writeAll("{ ");
- var i: usize = 0;
- while (i < info.len) : (i += 1) {
- try w.printValue(fmt, options, value[i], max_depth - 1);
- if (i < info.len - 1) {
- try w.writeAll(", ");
- }
- }
- try w.writeAll(" }");
+ .vector => {
+ if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
+ return printVector(w, fmt, options, value, max_depth);
},
.@"fn" => @compileError("unable to format function body type, use '*const " ++ @typeName(T) ++ "' for a function pointer type"),
.type => {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- return w.alignBufferOptions(@typeName(value), options);
+ return w.writeAll(@typeName(value));
},
.enum_literal => {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- const buffer = [_]u8{'.'} ++ @tagName(value);
- return w.alignBufferOptions(buffer, options);
+ var vecs: [2][]const u8 = .{ ".", @tagName(value) };
+ return w.writeVecAll(&vecs);
},
.null => {
if (!is_any and fmt.len != 0) invalidFmtError(fmt, value);
- return w.alignBufferOptions("null", options);
+ return w.writeAll("null");
},
else => @compileError("unable to format type '" ++ @typeName(T) ++ "'"),
}
@@ -1074,75 +1152,68 @@ fn printErrorSet(w: *Writer, error_set: anyerror) Error!void {
try w.writeVecAll(&vecs);
}
-pub fn printInt(
+fn printEnumExhaustive(w: *Writer, value: anytype) Error!void {
+ var vecs: [2][]const u8 = .{ ".", @tagName(value) };
+ try w.writeVecAll(&vecs);
+}
+
+fn printEnumNonexhaustive(w: *Writer, value: anytype) Error!void {
+ if (std.enums.tagName(@TypeOf(value), value)) |tag_name| {
+ var vecs: [2][]const u8 = .{ ".", tag_name };
+ try w.writeVecAll(&vecs);
+ return;
+ }
+ try w.writeAll("@enumFromInt(");
+ try w.printInt(@intFromEnum(value), 10, .lower, .{});
+ try w.writeByte(')');
+}
+
+pub fn printVector(
w: *Writer,
comptime fmt: []const u8,
options: std.fmt.Options,
value: anytype,
+ max_depth: usize,
) Error!void {
- const int_value = if (@TypeOf(value) == comptime_int) blk: {
- const Int = std.math.IntFittingRange(value, value);
- break :blk @as(Int, value);
- } else value;
-
- switch (fmt.len) {
- 0 => return w.printIntOptions(int_value, 10, .lower, options),
- 1 => switch (fmt[0]) {
- 'd' => return w.printIntOptions(int_value, 10, .lower, options),
- 'c' => {
- if (@typeInfo(@TypeOf(int_value)).int.bits <= 8) {
- return w.printAsciiChar(@as(u8, int_value), options);
- } else {
- @compileError("cannot print integer that is larger than 8 bits as an ASCII character");
- }
- },
- 'u' => {
- if (@typeInfo(@TypeOf(int_value)).int.bits <= 21) {
- return w.printUnicodeCodepoint(@as(u21, int_value), options);
- } else {
- @compileError("cannot print integer that is larger than 21 bits as an UTF-8 sequence");
- }
- },
- 'b' => return w.printIntOptions(int_value, 2, .lower, options),
- 'x' => return w.printIntOptions(int_value, 16, .lower, options),
- 'X' => return w.printIntOptions(int_value, 16, .upper, options),
- 'o' => return w.printIntOptions(int_value, 8, .lower, options),
- 'B' => return w.printByteSize(int_value, .decimal, options),
- 'D' => return w.printDuration(int_value, options),
- else => invalidFmtError(fmt, value),
- },
- 2 => {
- if (fmt[0] == 'B' and fmt[1] == 'i') {
- return w.printByteSize(int_value, .binary, options);
- } else {
- invalidFmtError(fmt, value);
- }
- },
- else => invalidFmtError(fmt, value),
+ const len = @typeInfo(@TypeOf(value)).vector.len;
+ if (max_depth == 0) return w.writeAll("{ ... }");
+ try w.writeAll("{ ");
+ inline for (0..len) |i| {
+ try w.printValue(fmt, options, value[i], max_depth - 1);
+ if (i < len - 1) try w.writeAll(", ");
}
- comptime unreachable;
-}
-
-pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void {
- return w.alignBufferOptions(@as(*const [1]u8, &c), options);
+ try w.writeAll(" }");
}
-pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void {
- return w.alignBufferOptions(bytes, options);
-}
-
-pub fn printUnicodeCodepoint(w: *Writer, c: u21, options: std.fmt.Options) Error!void {
- var buf: [4]u8 = undefined;
- const len = std.unicode.utf8Encode(c, &buf) catch |err| switch (err) {
- error.Utf8CannotEncodeSurrogateHalf, error.CodepointTooLarge => l: {
- buf[0..3].* = std.unicode.replacement_character_utf8;
- break :l 3;
+// A wrapper around `printIntAny` to avoid the generic explosion of this
+// function by funneling smaller integer types through `isize` and `usize`.
+pub inline fn printInt(
+ w: *Writer,
+ value: anytype,
+ base: u8,
+ case: std.fmt.Case,
+ options: std.fmt.Options,
+) Error!void {
+ switch (@TypeOf(value)) {
+ isize, usize => {},
+ comptime_int => {
+ if (comptime std.math.cast(usize, value)) |x| return printIntAny(w, x, base, case, options);
+ if (comptime std.math.cast(isize, value)) |x| return printIntAny(w, x, base, case, options);
+ const Int = std.math.IntFittingRange(value, value);
+ return printIntAny(w, @as(Int, value), base, case, options);
},
- };
- return w.alignBufferOptions(buf[0..len], options);
+ else => switch (@typeInfo(@TypeOf(value)).int.signedness) {
+ .signed => if (std.math.cast(isize, value)) |x| return printIntAny(w, x, base, case, options),
+ .unsigned => if (std.math.cast(usize, value)) |x| return printIntAny(w, x, base, case, options),
+ },
+ }
+ return printIntAny(w, value, base, case, options);
}
-pub fn printIntOptions(
+/// In general, prefer `printInt` to avoid generic explosion. However this
+/// function may be used when optimal codegen for a particular integer type is
+/// desired.
+pub fn printIntAny(
w: *Writer,
value: anytype,
base: u8,
@@ -1150,20 +1221,14 @@ pub fn printIntOptions(
options: std.fmt.Options,
) Error!void {
assert(base >= 2);
-
- const int_value = if (@TypeOf(value) == comptime_int) blk: {
- const Int = std.math.IntFittingRange(value, value);
- break :blk @as(Int, value);
- } else value;
-
- const value_info = @typeInfo(@TypeOf(int_value)).int;
+ const value_info = @typeInfo(@TypeOf(value)).int;
// The type must have the same size as `base` or be wider in order for the
// division to work
const min_int_bits = comptime @max(value_info.bits, 8);
const MinInt = std.meta.Int(.unsigned, min_int_bits);
- const abs_value = @abs(int_value);
+ const abs_value = @abs(value);
// The worst case in terms of space needed is base 2, plus 1 for the sign
var buf: [1 + @max(@as(comptime_int, value_info.bits), 1)]u8 = undefined;
@@ -1210,38 +1275,49 @@ pub fn printIntOptions(
return w.alignBufferOptions(buf[index..], options);
}
+pub fn printAsciiChar(w: *Writer, c: u8, options: std.fmt.Options) Error!void {
+ return w.alignBufferOptions(@as(*const [1]u8, &c), options);
+}
+
+pub fn printAscii(w: *Writer, bytes: []const u8, options: std.fmt.Options) Error!void {
+ return w.alignBufferOptions(bytes, options);
+}
+
+pub fn printUnicodeCodepoint(w: *Writer, c: u21) Error!void {
+ var buf: [4]u8 = undefined;
+ const len = std.unicode.utf8Encode(c, &buf) catch |err| switch (err) {
+ error.Utf8CannotEncodeSurrogateHalf, error.CodepointTooLarge => l: {
+ buf[0..3].* = std.unicode.replacement_character_utf8;
+ break :l 3;
+ },
+ };
+ return w.writeAll(buf[0..len]);
+}
+
pub fn printFloat(
w: *Writer,
- comptime fmt: []const u8,
- options: std.fmt.Options,
value: anytype,
+ mode: std.fmt.float.Mode,
+ options: std.fmt.Options,
) Error!void {
var buf: [std.fmt.float.bufferSize(.decimal, f64)]u8 = undefined;
+ const s = std.fmt.float.render(&buf, value, .{
+ .mode = mode,
+ .precision = options.precision,
+ }) catch |err| switch (err) {
+ error.BufferTooSmall => "(float)",
+ };
+ return w.alignBufferOptions(s, options);
+}
- if (fmt.len > 1) invalidFmtError(fmt, value);
- switch (if (fmt.len == 0) 'e' else fmt[0]) {
- 'e' => {
- const s = std.fmt.float.render(&buf, value, .{ .mode = .scientific, .precision = options.precision }) catch |err| switch (err) {
- error.BufferTooSmall => "(float)",
- };
- return w.alignBufferOptions(s, options);
- },
- 'd' => {
- const s = std.fmt.float.render(&buf, value, .{ .mode = .decimal, .precision = options.precision }) catch |err| switch (err) {
- error.BufferTooSmall => "(float)",
- };
- return w.alignBufferOptions(s, options);
- },
- 'x' => {
- var sub_bw: Writer = .fixed(&buf);
- sub_bw.printFloatHexadecimal(value, options.precision) catch unreachable;
- return w.alignBufferOptions(sub_bw.buffered(), options);
- },
- else => invalidFmtError(fmt, value),
- }
+pub fn printFloatHexOptions(w: *Writer, value: anytype, case: std.fmt.Case, options: std.fmt.Options) Error!void {
+ var buf: [50]u8 = undefined; // for aligning
+ var sub_writer: Writer = .fixed(&buf);
+ printFloatHex(&sub_writer, value, case, options.precision) catch unreachable; // buf is large enough
+ return w.alignBufferOptions(sub_writer.buffered(), options);
}
-pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize) Error!void {
+pub fn printFloatHex(w: *Writer, value: anytype, case: std.fmt.Case, opt_precision: ?usize) Error!void {
if (std.math.signbit(value)) try w.writeByte('-');
if (std.math.isNan(value)) return w.writeAll("nan");
if (std.math.isInf(value)) return w.writeAll("inf");
@@ -1320,7 +1396,7 @@ pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize)
// +1 for the decimal part.
var buf: [1 + mantissa_digits]u8 = undefined;
- assert(std.fmt.printInt(&buf, mantissa, 16, .lower, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len);
+ assert(std.fmt.printInt(&buf, mantissa, 16, case, .{ .fill = '0', .width = 1 + mantissa_digits }) == buf.len);
try w.writeAll("0x");
try w.writeByte(buf[0]);
@@ -1337,7 +1413,7 @@ pub fn printFloatHexadecimal(w: *Writer, value: anytype, opt_precision: ?usize)
try w.splatByteAll('0', precision - trimmed.len);
};
try w.writeAll("p");
- try w.printIntOptions(exponent - exponent_bias, 10, .lower, .{});
+ try w.printInt(exponent - exponent_bias, 10, case, .{});
}
pub const ByteSizeUnits = enum {
@@ -1433,7 +1509,7 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
}) |unit| {
if (ns_remaining >= unit.ns) {
const units = ns_remaining / unit.ns;
- try w.printIntOptions(units, 10, .lower, .{});
+ try w.printInt(units, 10, .lower, .{});
try w.writeByte(unit.sep);
ns_remaining -= units * unit.ns;
if (ns_remaining == 0) return;
@@ -1447,13 +1523,13 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
}) |unit| {
const kunits = ns_remaining * 1000 / unit.ns;
if (kunits >= 1000) {
- try w.printIntOptions(kunits / 1000, 10, .lower, .{});
+ try w.printInt(kunits / 1000, 10, .lower, .{});
const frac = kunits % 1000;
if (frac > 0) {
// Write up to 3 decimal places
var decimal_buf = [_]u8{ '.', 0, 0, 0 };
var inner: Writer = .fixed(decimal_buf[1..]);
- inner.printIntOptions(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable;
+ inner.printInt(frac, 10, .lower, .{ .fill = '0', .width = 3 }) catch unreachable;
var end: usize = 4;
while (end > 1) : (end -= 1) {
if (decimal_buf[end - 1] != '0') break;
@@ -1464,7 +1540,7 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
}
}
- try w.printIntOptions(ns_remaining, 10, .lower, .{});
+ try w.printInt(ns_remaining, 10, .lower, .{});
try w.writeAll("ns");
}
@@ -1474,12 +1550,18 @@ pub fn printDurationUnsigned(w: *Writer, ns: u64) Error!void {
pub fn printDuration(w: *Writer, nanoseconds: anytype, options: std.fmt.Options) Error!void {
// worst case: "-XXXyXXwXXdXXhXXmXX.XXXs".len = 24
var buf: [24]u8 = undefined;
- var sub_bw: Writer = .fixed(&buf);
- switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) {
- .signed => sub_bw.printDurationSigned(nanoseconds) catch unreachable,
- .unsigned => sub_bw.printDurationUnsigned(nanoseconds) catch unreachable,
+ var sub_writer: Writer = .fixed(&buf);
+ if (@TypeOf(nanoseconds) == comptime_int) {
+ if (nanoseconds >= 0) {
+ sub_writer.printDurationUnsigned(nanoseconds) catch unreachable;
+ } else {
+ sub_writer.printDurationSigned(nanoseconds) catch unreachable;
+ }
+ } else switch (@typeInfo(@TypeOf(nanoseconds)).int.signedness) {
+ .signed => sub_writer.printDurationSigned(nanoseconds) catch unreachable,
+ .unsigned => sub_writer.printDurationUnsigned(nanoseconds) catch unreachable,
}
- return w.alignBufferOptions(sub_bw.buffered(), options);
+ return w.alignBufferOptions(sub_writer.buffered(), options);
}
pub fn printHex(w: *Writer, bytes: []const u8, case: std.fmt.Case) Error!void {
@@ -1749,7 +1831,7 @@ fn testDurationCaseSigned(expected: []const u8, input: i64) !void {
try testing.expectEqualStrings(expected, w.buffered());
}
-test printIntOptions {
+test printInt {
try testPrintIntCase("-1", @as(i1, -1), 10, .lower, .{});
try testPrintIntCase("-101111000110000101001110", @as(i32, -12345678), 2, .lower, .{});
@@ -1765,27 +1847,22 @@ test printIntOptions {
try testPrintIntCase("+42", @as(i32, 42), 10, .lower, .{ .width = 3 });
try testPrintIntCase("-42", @as(i32, -42), 10, .lower, .{ .width = 3 });
-}
-test "printInt with comptime_int" {
- var buf: [20]u8 = undefined;
- var w: Writer = .fixed(&buf);
- try w.printInt("", .{}, @as(comptime_int, 123456789123456789));
- try std.testing.expectEqualStrings("123456789123456789", w.buffered());
+ try testPrintIntCase("123456789123456789", @as(comptime_int, 123456789123456789), 10, .lower, .{});
}
test "printFloat with comptime_float" {
var buf: [20]u8 = undefined;
var w: Writer = .fixed(&buf);
- try w.printFloat("", .{}, @as(comptime_float, 1.0));
+ try w.printFloat(@as(comptime_float, 1.0), .scientific, .{});
try std.testing.expectEqualStrings(w.buffered(), "1e0");
- try std.testing.expectFmt("1e0", "{}", .{1.0});
+ try std.testing.expectFmt("1", "{}", .{1.0});
}
fn testPrintIntCase(expected: []const u8, value: anytype, base: u8, case: std.fmt.Case, options: std.fmt.Options) !void {
var buffer: [100]u8 = undefined;
var w: Writer = .fixed(&buffer);
- try w.printIntOptions(value, base, case, options);
+ try w.printInt(value, base, case, options);
try testing.expectEqualStrings(expected, w.buffered());
}
lib/std/json/dynamic_test.zig
@@ -254,7 +254,7 @@ test "Value.jsonStringify" {
\\ true,
\\ 42,
\\ 43,
- \\ 4.2e1,
+ \\ 42,
\\ "weeee",
\\ [
\\ 1,
@@ -266,7 +266,7 @@ test "Value.jsonStringify" {
\\ }
\\]
;
- try testing.expectEqualSlices(u8, expected, fbs.getWritten());
+ try testing.expectEqualStrings(expected, fbs.getWritten());
}
test "parseFromValue(std.json.Value,...)" {
lib/std/json/stringify.zig
@@ -469,7 +469,6 @@ pub fn WriteStream(
/// * When option `emit_nonportable_numbers_as_strings` is true, if the value is outside the range `+-1<<53` (the precise integer range of f64), it is rendered as a JSON string in base 10. Otherwise, it is rendered as JSON number.
/// * Zig floats -> JSON number or string.
/// * If the value cannot be precisely represented by an f64, it is rendered as a JSON string. Otherwise, it is rendered as JSON number.
- /// * TODO: Float rendering will likely change in the future, e.g. to remove the unnecessary "e+00".
/// * Zig `[]const u8`, `[]u8`, `*[N]u8`, `@Vector(N, u8)`, and similar -> JSON string.
/// * See `StringifyOptions.emit_strings_as_arrays`.
/// * If the content is not valid UTF-8, rendered as an array of numbers instead.
lib/std/json/stringify_test.zig
@@ -74,16 +74,16 @@ fn testBasicWriteStream(w: anytype, slice_stream: anytype) !void {
\\{
\\ "object": {
\\ "one": 1,
- \\ "two": 2e0
+ \\ "two": 2
\\ },
\\ "string": "This is a string",
\\ "array": [
\\ "Another string",
\\ 1,
- \\ 3.5e0
+ \\ 3.5
\\ ],
\\ "int": 10,
- \\ "float": 3.5e0
+ \\ "float": 3.5
\\}
;
try std.testing.expectEqualStrings(expected, result);
@@ -123,12 +123,12 @@ test "stringify basic types" {
try testStringify("null", @as(?u8, null), .{});
try testStringify("null", @as(?*u32, null), .{});
try testStringify("42", 42, .{});
- try testStringify("4.2e1", 42.0, .{});
+ try testStringify("42", 42.0, .{});
try testStringify("42", @as(u8, 42), .{});
try testStringify("42", @as(u128, 42), .{});
try testStringify("9999999999999999", 9999999999999999, .{});
- try testStringify("4.2e1", @as(f32, 42), .{});
- try testStringify("4.2e1", @as(f64, 42), .{});
+ try testStringify("42", @as(f32, 42), .{});
+ try testStringify("42", @as(f64, 42), .{});
try testStringify("\"ItBroke\"", @as(anyerror, error.ItBroke), .{});
try testStringify("\"ItBroke\"", error.ItBroke, .{});
}
lib/std/math/big/int.zig
@@ -2028,6 +2028,14 @@ pub const Mutable = struct {
pub fn normalize(r: *Mutable, length: usize) void {
r.len = llnormalize(r.limbs[0..length]);
}
+
+ pub fn format(self: Mutable, w: *std.io.Writer) std.io.Writer.Error!void {
+ return formatInteger(self, w, 10, .lower);
+ }
+
+ pub fn formatInteger(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
+ return self.toConst().formatInteger(w, base, case);
+ }
};
/// A arbitrary-precision big integer, with a fixed set of immutable limbs.
@@ -2321,7 +2329,7 @@ pub const Const = struct {
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
/// See `toString` and `toStringAlloc` for a way to print big integers without failure.
- pub fn print(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
+ pub fn formatInteger(self: Const, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
const available_len = 64;
if (self.limbs.len > available_len)
return w.writeAll("(BigInt)");
@@ -2337,20 +2345,6 @@ pub const Const = struct {
return w.writeAll(buf[0..len]);
}
- const Format = struct {
- int: Const,
- base: u8,
- case: std.fmt.Case,
-
- pub fn default(f: Format, w: *std.io.Writer) std.io.Writer.Error!void {
- return print(f.int, w, f.base, f.case);
- }
- };
-
- pub fn fmt(self: Const, base: u8, case: std.fmt.Case) std.fmt.Formatter(Format, Format.default) {
- return .{ .data = .{ .int = self, .base = base, .case = case } };
- }
-
/// Converts self to a string in the requested base.
/// Caller owns returned memory.
/// Asserts that `base` is in the range [2, 36].
@@ -2918,16 +2912,16 @@ pub const Managed = struct {
}
/// To allow `std.fmt.format` to work with `Managed`.
- pub fn format(self: Managed, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
- return self.toConst().format(w, f);
+ pub fn format(self: Managed, w: *std.io.Writer) std.io.Writer.Error!void {
+ return formatInteger(self, w, 10, .lower);
}
/// If the absolute value of integer is greater than or equal to `pow(2, 64 * @sizeOf(usize) * 8)`,
/// this function will fail to print the string, printing "(BigInt)" instead of a number.
/// This is because the rendering algorithm requires reversing a string, which requires O(N) memory.
/// See `toString` and `toStringAlloc` for a way to print big integers without failure.
- pub fn fmt(self: Managed, base: u8, case: std.fmt.Case) std.fmt.Formatter(Const.Format, Const.Format.default) {
- return .{ .data = .{ .int = self.toConst(), .base = base, .case = case } };
+ pub fn formatInteger(self: Managed, w: *std.io.Writer, base: u8, case: std.fmt.Case) std.io.Writer.Error!void {
+ return self.toConst().formatInteger(w, base, case);
}
/// Returns math.Order.lt, math.Order.eq, math.Order.gt if |a| < |b|, |a| ==
lib/std/math/big/int_test.zig
@@ -3813,8 +3813,8 @@ test "(BigInt) positive" {
try a.pow(&a, 64 * @sizeOf(Limb) * 8);
try b.sub(&a, &c);
- try testing.expectFmt("(BigInt)", "{f}", .{a.fmt(10, .lower)});
- try testing.expectFmt("1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335", "{f}", .{b.fmt(10, .lower)});
+ try testing.expectFmt("(BigInt)", "{d}", .{a});
+ try testing.expectFmt("1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085903001302413467189726673216491511131602920781738033436090243804708340403154190335", "{d}", .{b});
}
test "(BigInt) negative" {
@@ -3832,10 +3832,10 @@ test "(BigInt) negative" {
a.negate();
try b.add(&a, &c);
- const a_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{a.fmt(10, .lower)});
+ const a_fmt = try std.fmt.allocPrint(testing.allocator, "{d}", .{a});
defer testing.allocator.free(a_fmt);
- const b_fmt = try std.fmt.allocPrint(testing.allocator, "{f}", .{b.fmt(10, .lower)});
+ const b_fmt = try std.fmt.allocPrint(testing.allocator, "{d}", .{b});
defer testing.allocator.free(b_fmt);
try testing.expect(mem.eql(u8, a_fmt, "(BigInt)"));
lib/std/zig/llvm/Builder.zig
@@ -246,7 +246,7 @@ pub const Type = enum(u32) {
_,
pub const ptr_amdgpu_constant =
- @field(Type, std.fmt.comptimePrint("ptr{f }", .{AddrSpace.amdgpu.constant}));
+ @field(Type, std.fmt.comptimePrint("ptr{f}", .{AddrSpace.amdgpu.constant.fmt(" ")}));
pub const Tag = enum(u4) {
simple,
@@ -779,7 +779,7 @@ pub const Type = enum(u32) {
}
},
.integer => try w.print("i{d}", .{item.data}),
- .pointer => try w.print("ptr{f }", .{@as(AddrSpace, @enumFromInt(item.data))}),
+ .pointer => try w.print("ptr{f}", .{@as(AddrSpace, @enumFromInt(item.data)).fmt(" ")}),
.target => {
var extra = data.builder.typeExtraDataTrail(Type.Target, item.data);
const types = extra.trail.next(extra.data.types_len, Type, data.builder);
@@ -1242,7 +1242,7 @@ pub const Attribute = union(Kind) {
.sret,
.elementtype,
=> |ty| try w.print(" {s}({f})", .{ @tagName(attribute), ty.fmt(data.builder, .percent) }),
- .@"align" => |alignment| try w.print("{f }", .{alignment}),
+ .@"align" => |alignment| try w.print("{f}", .{alignment.fmt(" ")}),
.dereferenceable,
.dereferenceable_or_null,
=> |size| try w.print(" {s}({d})", .{ @tagName(attribute), size }),
@@ -1853,10 +1853,31 @@ pub const ThreadLocal = enum(u3) {
initialexec = 3,
localexec = 4,
- pub fn format(self: ThreadLocal, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- if (self == .default) return;
- try w.print("{s}thread_local", .{prefix});
- if (self != .generaldynamic) try w.print("({s})", .{@tagName(self)});
+ pub fn format(tl: ThreadLocal, w: *Writer) Writer.Error!void {
+ return Prefixed.format(.{ .thread_local = tl, .prefix = "" }, w);
+ }
+
+ pub const Prefixed = struct {
+ thread_local: ThreadLocal,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ switch (p.thread_local) {
+ .default => return,
+ .generaldynamic => {
+ var vecs: [2][]const u8 = .{ p.prefix, "thread_local" };
+ return w.writeVecAll(&vecs);
+ },
+ else => {
+ var vecs: [4][]const u8 = .{ p.prefix, "thread_local(", @tagName(p.thread_local), ")" };
+ return w.writeVecAll(&vecs);
+ },
+ }
+ }
+ };
+
+ pub fn fmt(tl: ThreadLocal, prefix: []const u8) Prefixed {
+ return .{ .thread_local = tl, .prefix = prefix };
}
};
@@ -1961,8 +1982,24 @@ pub const AddrSpace = enum(u24) {
pub const funcref: AddrSpace = @enumFromInt(20);
};
- pub fn format(self: AddrSpace, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- if (self != .default) try w.print("{s}addrspace({d})", .{ prefix, @intFromEnum(self) });
+ pub fn format(addr_space: AddrSpace, w: *Writer) Writer.Error!void {
+ return Prefixed.format(.{ .addr_space = addr_space, .prefix = "" }, w);
+ }
+
+ pub const Prefixed = struct {
+ addr_space: AddrSpace,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ switch (p.addr_space) {
+ .default => return,
+ else => return w.print("{s}addrspace({d})", .{ p.prefix, p.addr_space }),
+ }
+ }
+ };
+
+ pub fn fmt(addr_space: AddrSpace, prefix: []const u8) Prefixed {
+ return .{ .addr_space = addr_space, .prefix = prefix };
}
};
@@ -1994,8 +2031,18 @@ pub const Alignment = enum(u6) {
return if (self == .default) 0 else (@intFromEnum(self) + 1);
}
- pub fn format(self: Alignment, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- try w.print("{s}align {d}", .{ prefix, self.toByteUnits() orelse return });
+ pub const Prefixed = struct {
+ alignment: Alignment,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ const byte_units = p.alignment.toByteUnits() orelse return;
+ return w.print("{s}align ({d})", .{ p.prefix, byte_units });
+ }
+ };
+
+ pub fn fmt(alignment: Alignment, prefix: []const u8) Prefixed {
+ return .{ .alignment = alignment, .prefix = prefix };
}
};
@@ -6978,8 +7025,27 @@ pub const MemoryAccessKind = enum(u1) {
normal,
@"volatile",
- pub fn format(self: MemoryAccessKind, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- if (self != .normal) try w.print("{s}{s}", .{ prefix, @tagName(self) });
+ pub fn format(memory_access_kind: MemoryAccessKind, w: *Writer) Writer.Error!void {
+ return Prefixed.format(.{ .memory_access_kind = memory_access_kind, .prefix = "" }, w);
+ }
+
+ pub const Prefixed = struct {
+ memory_access_kind: MemoryAccessKind,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ switch (p.memory_access_kind) {
+ .normal => return,
+ .@"volatile" => {
+ var vecs: [2][]const u8 = .{ p.prefix, "volatile" };
+ return w.writeVecAll(&vecs);
+ },
+ }
+ }
+ };
+
+ pub fn fmt(memory_access_kind: MemoryAccessKind, prefix: []const u8) Prefixed {
+ return .{ .memory_access_kind = memory_access_kind, .prefix = prefix };
}
};
@@ -6987,10 +7053,27 @@ pub const SyncScope = enum(u1) {
singlethread,
system,
- pub fn format(self: SyncScope, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- if (self != .system) try w.print(
- \\{s}syncscope("{s}")
- , .{ prefix, @tagName(self) });
+ pub fn format(sync_scope: SyncScope, w: *Writer) Writer.Error!void {
+ return Prefixed.format(.{ .sync_scope = sync_scope, .prefix = "" }, w);
+ }
+
+ pub const Prefixed = struct {
+ sync_scope: SyncScope,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ switch (p.sync_scope) {
+ .system => return,
+ .singlethread => {
+ var vecs: [2][]const u8 = .{ p.prefix, "syncscope(\"singlethread\")" };
+ return w.writeVecAll(&vecs);
+ },
+ }
+ }
+ };
+
+ pub fn fmt(sync_scope: SyncScope, prefix: []const u8) Prefixed {
+ return .{ .sync_scope = sync_scope, .prefix = prefix };
}
};
@@ -7003,8 +7086,27 @@ pub const AtomicOrdering = enum(u3) {
acq_rel = 5,
seq_cst = 6,
- pub fn format(self: AtomicOrdering, w: *Writer, comptime prefix: []const u8) Writer.Error!void {
- if (self != .none) try w.print("{s}{s}", .{ prefix, @tagName(self) });
+ pub fn format(atomic_ordering: AtomicOrdering, w: *Writer) Writer.Error!void {
+ return Prefixed.format(.{ .atomic_ordering = atomic_ordering, .prefix = "" }, w);
+ }
+
+ pub const Prefixed = struct {
+ atomic_ordering: AtomicOrdering,
+ prefix: []const u8,
+
+ pub fn format(p: Prefixed, w: *Writer) Writer.Error!void {
+ switch (p.atomic_ordering) {
+ .none => return,
+ else => {
+ var vecs: [2][]const u8 = .{ p.prefix, @tagName(p.atomic_ordering) };
+ return w.writeVecAll(&vecs);
+ },
+ }
+ }
+ };
+
+ pub fn fmt(atomic_ordering: AtomicOrdering, prefix: []const u8) Prefixed {
+ return .{ .atomic_ordering = atomic_ordering, .prefix = prefix };
}
};
@@ -8550,7 +8652,7 @@ pub fn init(options: Options) Allocator.Error!Builder {
inline for (.{ 0, 4 }) |addr_space_index| {
const addr_space: AddrSpace = @enumFromInt(addr_space_index);
assert(self.ptrTypeAssumeCapacity(addr_space) ==
- @field(Type, std.fmt.comptimePrint("ptr{f }", .{addr_space})));
+ @field(Type, std.fmt.comptimePrint("ptr{f}", .{addr_space.fmt(" ")})));
}
}
@@ -9469,7 +9571,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
metadata_formatter.need_comma = true;
defer metadata_formatter.need_comma = undefined;
try w.print(
- \\{f} ={f}{f}{f}{f}{f }{f}{f }{f} {s} {f}{f}{f, }{f}
+ \\{f} ={f}{f}{f}{f}{f}{f}{f}{f} {s} {f}{f}{f}{f}
\\
, .{
variable.global.fmt(self),
@@ -9479,14 +9581,14 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
global.preemption,
global.visibility,
global.dll_storage_class,
- variable.thread_local,
+ variable.thread_local.fmt(" "),
global.unnamed_addr,
- global.addr_space,
+ global.addr_space.fmt(" "),
global.externally_initialized,
@tagName(variable.mutability),
global.type.fmt(self, .percent),
variable.init.fmt(self, .{ .space = true }),
- variable.alignment,
+ variable.alignment.fmt(", "),
try metadata_formatter.fmt("!dbg ", global.dbg, null),
});
}
@@ -9500,7 +9602,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
metadata_formatter.need_comma = true;
defer metadata_formatter.need_comma = undefined;
try w.print(
- \\{f} ={f}{f}{f}{f}{f }{f} alias {f}, {f}{f}
+ \\{f} ={f}{f}{f}{f}{f}{f} alias {f}, {f}{f}
\\
, .{
alias.global.fmt(self),
@@ -9508,7 +9610,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
global.preemption,
global.visibility,
global.dll_storage_class,
- alias.thread_local,
+ alias.thread_local.fmt(" "),
global.unnamed_addr,
global.type.fmt(self, .percent),
alias.aliasee.fmt(self, .{ .percent = true }),
@@ -9564,15 +9666,15 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
try w.writeAll("...");
},
}
- try w.print("){f}{f }", .{ global.unnamed_addr, global.addr_space });
+ try w.print("){f}{f}", .{ global.unnamed_addr, global.addr_space.fmt(" ") });
if (function_attributes != .none) try w.print(" #{d}", .{
(try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
});
{
metadata_formatter.need_comma = false;
defer metadata_formatter.need_comma = undefined;
- try w.print("{f }{f}", .{
- function.alignment,
+ try w.print("{f}{f}", .{
+ function.alignment.fmt(" "),
try metadata_formatter.fmt(" !dbg ", global.dbg, null),
});
}
@@ -9709,7 +9811,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
.@"alloca inalloca",
=> |tag| {
const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
- try w.print(" %{f} = {s} {f}{f}{f, }{f, }", .{
+ try w.print(" %{f} = {s} {f}{f}{f}{f}", .{
instruction_index.name(&function).fmt(self),
@tagName(tag),
extra.type.fmt(self, .percent),
@@ -9720,24 +9822,24 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
.comma = true,
.percent = true,
}),
- extra.info.alignment,
- extra.info.addr_space,
+ extra.info.alignment.fmt(", "),
+ extra.info.addr_space.fmt(", "),
});
},
.arg => unreachable,
.atomicrmw => |tag| {
const extra =
function.extraData(Function.Instruction.AtomicRmw, instruction.data);
- try w.print(" %{f} = {s}{f } {s} {f}, {f}{f }{f }{f, }", .{
+ try w.print(" %{f} = {t}{f} {t} {f}, {f}{f}{f}{f}", .{
instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
- @tagName(extra.info.atomic_rmw_operation),
+ tag,
+ extra.info.access_kind.fmt(" "),
+ extra.info.atomic_rmw_operation,
extra.ptr.fmt(function_index, self, .{ .percent = true }),
extra.val.fmt(function_index, self, .{ .percent = true }),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
+ extra.info.sync_scope.fmt(" "),
+ extra.info.success_ordering.fmt(" "),
+ extra.info.alignment.fmt(", "),
});
},
.block => {
@@ -9792,8 +9894,8 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
}),
.none => unreachable,
}
- try w.print("{s}{f}{f}{f} {f} {f}(", .{
- @tagName(tag),
+ try w.print("{t}{f}{f}{f} {f} {f}(", .{
+ tag,
extra.data.info.call_conv,
extra.data.attributes.ret(self).fmt(self, .{}),
extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
@@ -9831,17 +9933,17 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
=> |tag| {
const extra =
function.extraData(Function.Instruction.CmpXchg, instruction.data);
- try w.print(" %{f} = {s}{f } {f}, {f}, {f}{f }{f }{f }{f, }", .{
+ try w.print(" %{f} = {t}{f} {f}, {f}, {f}{f}{f}{f}{f}", .{
instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
+ tag,
+ extra.info.access_kind.fmt(" "),
extra.ptr.fmt(function_index, self, .{ .percent = true }),
extra.cmp.fmt(function_index, self, .{ .percent = true }),
extra.new.fmt(function_index, self, .{ .percent = true }),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.failure_ordering,
- extra.info.alignment,
+ extra.info.sync_scope.fmt(" "),
+ extra.info.success_ordering.fmt(" "),
+ extra.info.failure_ordering.fmt(" "),
+ extra.info.alignment.fmt(", "),
});
},
.extractelement => |tag| {
@@ -9869,10 +9971,10 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
},
.fence => |tag| {
const info: MemoryAccessInfo = @bitCast(instruction.data);
- try w.print(" {s}{f }{f }", .{
- @tagName(tag),
- info.sync_scope,
- info.success_ordering,
+ try w.print(" {t}{f}{f}", .{
+ tag,
+ info.sync_scope.fmt(" "),
+ info.success_ordering.fmt(" "),
});
},
.fneg,
@@ -9947,15 +10049,15 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
.@"load atomic",
=> |tag| {
const extra = function.extraData(Function.Instruction.Load, instruction.data);
- try w.print(" %{f} = {s}{f } {f}, {f}{f }{f }{f, }", .{
+ try w.print(" %{f} = {t}{f} {f}, {f}{f}{f}{f}", .{
instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
+ tag,
+ extra.info.access_kind.fmt(" "),
extra.type.fmt(self, .percent),
extra.ptr.fmt(function_index, self, .{ .percent = true }),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
+ extra.info.sync_scope.fmt(" "),
+ extra.info.success_ordering.fmt(" "),
+ extra.info.alignment.fmt(", "),
});
},
.phi,
@@ -10015,14 +10117,14 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void
.@"store atomic",
=> |tag| {
const extra = function.extraData(Function.Instruction.Store, instruction.data);
- try w.print(" {s}{f } {f}, {f}{f }{f }{f, }", .{
- @tagName(tag),
- extra.info.access_kind,
+ try w.print(" {t}{f} {f}, {f}{f}{f}{f}", .{
+ tag,
+ extra.info.access_kind.fmt(" "),
extra.val.fmt(function_index, self, .{ .percent = true }),
extra.ptr.fmt(function_index, self, .{ .percent = true }),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
+ extra.info.sync_scope.fmt(" "),
+ extra.info.success_ordering.fmt(" "),
+ extra.info.alignment.fmt(", "),
});
},
.@"switch" => |tag| {
lib/std/zon/stringify.zig
@@ -615,7 +615,7 @@ pub fn Serializer(Writer: type) type {
/// Serialize an integer.
pub fn int(self: *Self, val: anytype) Writer.Error!void {
- //try self.writer.printIntOptions(val, 10, .lower, .{});
+ //try self.writer.printInt(val, 10, .lower, .{});
try std.fmt.deprecatedFormat(self.writer, "{d}", .{val});
}
lib/std/fmt.zig
@@ -53,16 +53,20 @@ pub const Options = struct {
/// - when using a field name, you are required to enclose the field name (an identifier) in square
/// brackets, e.g. {[score]...} as opposed to the numeric index form which can be written e.g. {2...}
/// - *specifier* is a type-dependent formatting option that determines how a type should formatted (see below)
-/// - *fill* is a single byte which is used to pad the formatted text
-/// - *alignment* is one of the three bytes '<', '^', or '>' to make the text left-, center-, or right-aligned, respectively
-/// - *width* is the total width of the field in bytes. This is generally only
-/// useful for ASCII text, such as numbers.
-/// - *precision* specifies how many decimals a formatted number should have
+/// - *fill* is a single byte which is used to pad formatted numbers.
+/// - *alignment* is one of the three bytes '<', '^', or '>' to make numbers
+/// left, center, or right-aligned, respectively.
+/// - *width* is the total width of the field in bytes. This only applies to number formatting.
+/// - *precision* specifies how many decimals a formatted number should have.
///
-/// Note that most of the parameters are optional and may be omitted. Also you can leave out separators like `:` and `.` when
-/// all parameters after the separator are omitted.
-/// Only exception is the *fill* parameter. If a non-zero *fill* character is required at the same time as *width* is specified,
-/// one has to specify *alignment* as well, as otherwise the digit following `:` is interpreted as *width*, not *fill*.
+/// Note that most of the parameters are optional and may be omitted. Also you
+/// can leave out separators like `:` and `.` when all parameters after the
+/// separator are omitted.
+///
+/// Only exception is the *fill* parameter. If a non-zero *fill* character is
+/// required at the same time as *width* is specified, one has to specify
+/// *alignment* as well, as otherwise the digit following `:` is interpreted as
+/// *width*, not *fill*.
///
/// The *specifier* has several options for types:
/// - `x` and `X`: output numeric value in hexadecimal notation, or string in hexadecimal bytes
@@ -405,9 +409,9 @@ pub const ArgState = struct {
/// Asserts the rendered integer value fits in `buffer`.
/// Returns the end index within `buffer`.
pub fn printInt(buffer: []u8, value: anytype, base: u8, case: Case, options: Options) usize {
- var bw: Writer = .fixed(buffer);
- bw.printIntOptions(value, base, case, options) catch unreachable;
- return bw.end;
+ var w: Writer = .fixed(buffer);
+ w.printInt(value, base, case, options) catch unreachable;
+ return w.end;
}
/// Converts values in the range [0, 100) to a base 10 string.
@@ -956,35 +960,23 @@ fn expectArrayFmt(expected: []const u8, comptime template: []const u8, comptime
}
test "array" {
- {
- const value: [3]u8 = "abc".*;
- try expectArrayFmt("array: abc\n", "array: {s}\n", value);
- try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {d}\n", value);
- try expectArrayFmt("array: 616263\n", "array: {x}\n", value);
- try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {any}\n", value);
-
- var buf: [100]u8 = undefined;
- try expectFmt(
- try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
- "array: {*}\n",
- .{&value},
- );
- }
+ const value: [3]u8 = "abc".*;
+ try expectArrayFmt("array: abc\n", "array: {s}\n", value);
+ try expectArrayFmt("array: 616263\n", "array: {x}\n", value);
+ try expectArrayFmt("array: { 97, 98, 99 }\n", "array: {any}\n", value);
- {
- const value = [2][3]u8{ "abc".*, "def".* };
-
- try expectArrayFmt("array: { abc, def }\n", "array: {s}\n", value);
- try expectArrayFmt("array: { { 97, 98, 99 }, { 100, 101, 102 } }\n", "array: {d}\n", value);
- try expectArrayFmt("array: { 616263, 646566 }\n", "array: {x}\n", value);
- }
+ var buf: [100]u8 = undefined;
+ try expectFmt(
+ try bufPrint(buf[0..], "array: [3]u8@{x}\n", .{@intFromPtr(&value)}),
+ "array: {*}\n",
+ .{&value},
+ );
}
test "slice" {
{
const value: []const u8 = "abc";
try expectFmt("slice: abc\n", "slice: {s}\n", .{value});
- try expectFmt("slice: { 97, 98, 99 }\n", "slice: {d}\n", .{value});
try expectFmt("slice: 616263\n", "slice: {x}\n", .{value});
try expectFmt("slice: { 97, 98, 99 }\n", "slice: {any}\n", .{value});
}
@@ -999,17 +991,12 @@ test "slice" {
try expectFmt("buf: \x00hello\x00\n", "buf: {s}\n", .{null_term_slice});
}
- try expectFmt("buf: Test\n", "buf: {s:5}\n", .{"Test"});
try expectFmt("buf: Test\n Other text", "buf: {s}\n Other text", .{"Test"});
{
var int_slice = [_]u32{ 1, 4096, 391891, 1111111111 };
- var runtime_zero: usize = 0;
- _ = &runtime_zero;
- try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {any}", .{int_slice[runtime_zero..]});
- try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {d}", .{int_slice[runtime_zero..]});
- try expectFmt("int: { 1, 1000, 5fad3, 423a35c7 }", "int: {x}", .{int_slice[runtime_zero..]});
- try expectFmt("int: { 00001, 01000, 5fad3, 423a35c7 }", "int: {x:0>5}", .{int_slice[runtime_zero..]});
+ const input: []const u32 = &int_slice;
+ try expectFmt("int: { 1, 4096, 391891, 1111111111 }", "int: {any}", .{input});
}
{
const S1 = struct {
@@ -1054,11 +1041,6 @@ test "cstr" {
"cstr: {s}\n",
.{@as([*c]const u8, @ptrCast("Test C"))},
);
- try expectFmt(
- "cstr: Test C\n",
- "cstr: {s:10}\n",
- .{@as([*c]const u8, @ptrCast("Test C"))},
- );
}
test "struct" {
@@ -1428,16 +1410,12 @@ test "enum-literal" {
test "padding" {
try expectFmt("Simple", "{s}", .{"Simple"});
- try expectFmt(" true", "{:10}", .{true});
- try expectFmt(" true", "{:>10}", .{true});
- try expectFmt("======true", "{:=>10}", .{true});
- try expectFmt("true======", "{:=<10}", .{true});
- try expectFmt(" true ", "{:^10}", .{true});
- try expectFmt("===true===", "{:=^10}", .{true});
- try expectFmt(" Minimum width", "{s:18} width", .{"Minimum"});
- try expectFmt("==================Filled", "{s:=>24}", .{"Filled"});
- try expectFmt(" Centered ", "{s:^24}", .{"Centered"});
- try expectFmt("-", "{s:-^1}", .{""});
+ try expectFmt(" 1234", "{:10}", .{1234});
+ try expectFmt(" 1234", "{:>10}", .{1234});
+ try expectFmt("======1234", "{:=>10}", .{1234});
+ try expectFmt("1234======", "{:=<10}", .{1234});
+ try expectFmt(" 1234 ", "{:^10}", .{1234});
+ try expectFmt("===1234===", "{:=^10}", .{1234});
try expectFmt("====a", "{c:=>5}", .{'a'});
try expectFmt("==a==", "{c:=^5}", .{'a'});
try expectFmt("a====", "{c:=<5}", .{'a'});
@@ -1485,17 +1463,17 @@ test "named arguments" {
test "runtime width specifier" {
const width: usize = 9;
- try expectFmt("~~hello~~", "{s:~^[1]}", .{ "hello", width });
- try expectFmt("~~hello~~", "{s:~^[width]}", .{ .string = "hello", .width = width });
- try expectFmt(" hello", "{s:[1]}", .{ "hello", width });
- try expectFmt("42 hello", "{d} {s:[2]}", .{ 42, "hello", width });
+ try expectFmt("~~12345~~", "{d:~^[1]}", .{ 12345, width });
+ try expectFmt("~~12345~~", "{d:~^[width]}", .{ .string = 12345, .width = width });
+ try expectFmt(" 12345", "{d:[1]}", .{ 12345, width });
+ try expectFmt("42 12345", "{d} {d:[2]}", .{ 42, 12345, width });
}
test "runtime precision specifier" {
const number: f32 = 3.1415;
const precision: usize = 2;
- try expectFmt("3.14e0", "{:1.[1]}", .{ number, precision });
- try expectFmt("3.14e0", "{:1.[precision]}", .{ .number = number, .precision = precision });
+ try expectFmt("3.14e0", "{e:1.[1]}", .{ number, precision });
+ try expectFmt("3.14e0", "{e:1.[precision]}", .{ .number = number, .precision = precision });
}
test "recursive format function" {
lib/std/Target.zig
@@ -301,24 +301,13 @@ pub const Os = struct {
/// This function is defined to serialize a Zig source code representation of this
/// type, that, when parsed, will deserialize into the same data.
- pub fn format(ver: WindowsVersion, w: *std.io.Writer, comptime f: []const u8) std.io.Writer.Error!void {
- const maybe_name = std.enums.tagName(WindowsVersion, ver);
- if (comptime std.mem.eql(u8, f, "s")) {
- if (maybe_name) |name|
- try w.print(".{s}", .{name})
- else
- try w.print(".{d}", .{@intFromEnum(ver)});
- } else if (comptime std.mem.eql(u8, f, "c")) {
- if (maybe_name) |name|
- try w.print(".{s}", .{name})
- else
- try w.print("@enumFromInt(0x{X:0>8})", .{@intFromEnum(ver)});
- } else if (f.len == 0) {
- if (maybe_name) |name|
- try w.print("WindowsVersion.{s}", .{name})
- else
- try w.print("WindowsVersion(0x{X:0>8})", .{@intFromEnum(ver)});
- } else std.fmt.invalidFmtError(f, ver);
+ pub fn format(wv: WindowsVersion, w: *std.io.Writer) std.io.Writer.Error!void {
+ if (std.enums.tagName(WindowsVersion, wv)) |name| {
+ var vecs: [2][]const u8 = .{ ".", name };
+ return w.writeVecAll(&vecs);
+ } else {
+ return w.print("@enumFromInt(0x{X:0>8})", .{wv});
+ }
}
};
lib/std/Uri.zig
@@ -240,6 +240,10 @@ pub fn parseAfterScheme(scheme: []const u8, text: []const u8) ParseError!Uri {
return uri;
}
+pub fn format(uri: *const Uri, writer: *std.io.Writer) std.io.Writer.Error!void {
+ return writeToStream(uri, writer, .all);
+}
+
pub fn writeToStream(uri: *const Uri, writer: *std.io.Writer, flags: Format.Flags) std.io.Writer.Error!void {
if (flags.scheme) {
try writer.print("{s}:", .{uri.scheme});
@@ -302,6 +306,16 @@ pub const Format = struct {
fragment: bool = false,
/// When true, include the port part of the URI. Ignored when `port` is null.
port: bool = true,
+
+ pub const all: Flags = .{
+ .scheme = true,
+ .authentication = true,
+ .authority = true,
+ .path = true,
+ .query = true,
+ .fragment = true,
+ .port = true,
+ };
};
pub fn default(f: Format, writer: *std.io.Writer) std.io.Writer.Error!void {
lib/std/zig.zig
@@ -475,7 +475,7 @@ pub fn stringEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!vo
' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
else => {
try w.writeAll("\\x");
- try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
+ try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
},
};
}
@@ -492,7 +492,7 @@ pub fn charEscape(bytes: []const u8, w: *std.io.Writer) std.io.Writer.Error!void
' ', '!', '#'...'&', '('...'[', ']'...'~' => try w.writeByte(byte),
else => {
try w.writeAll("\\x");
- try w.printIntOptions(byte, 16, .lower, .{ .width = 2, .fill = '0' });
+ try w.printInt(byte, 16, .lower, .{ .width = 2, .fill = '0' });
},
};
}
src/arch/riscv64/bits.zig
@@ -249,6 +249,12 @@ pub const FrameIndex = enum(u32) {
spill_frame,
/// Other indices are used for local variable stack slots
_,
+
+ pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len;
+
+ pub fn isNamed(fi: FrameIndex) bool {
+ return @intFromEnum(fi) < named_count;
+ }
};
/// A linker symbol not yet allocated in VM.
src/arch/riscv64/CodeGen.zig
@@ -1151,7 +1151,7 @@ fn gen(func: *Func) !void {
func.ret_mcv.long.address().offset(-func.ret_mcv.short.indirect.off),
);
func.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
- tracking_log.debug("spill {} to {f}", .{ func.ret_mcv.long, frame_index });
+ tracking_log.debug("spill {} to {}", .{ func.ret_mcv.long, frame_index });
},
else => unreachable,
}
@@ -1987,7 +1987,7 @@ fn allocFrameIndex(func: *Func, alloc: FrameAlloc) !FrameIndex {
}
const frame_index: FrameIndex = @enumFromInt(func.frame_allocs.len);
try func.frame_allocs.append(func.gpa, alloc);
- log.debug("allocated frame {f}", .{frame_index});
+ log.debug("allocated frame {}", .{frame_index});
return frame_index;
}
src/arch/x86_64/bits.zig
@@ -721,6 +721,12 @@ pub const FrameIndex = enum(u32) {
call_frame,
// Other indices are used for local variable stack slots
_,
+
+ pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len;
+
+ pub fn isNamed(fi: FrameIndex) bool {
+ return @intFromEnum(fi) < named_count;
+ }
};
pub const FrameAddr = struct { index: FrameIndex, off: i32 = 0 };
src/arch/x86_64/CodeGen.zig
@@ -525,47 +525,47 @@ pub const MCValue = union(enum) {
};
}
- pub fn format(mcv: MCValue, bw: *Writer) Writer.Error!void {
+ pub fn format(mcv: MCValue, w: *Writer) Writer.Error!void {
switch (mcv) {
- .none, .unreach, .dead, .undef => try bw.print("({s})", .{@tagName(mcv)}),
- .immediate => |pl| try bw.print("0x{x}", .{pl}),
- .memory => |pl| try bw.print("[ds:0x{x}]", .{pl}),
- inline .eflags, .register => |pl| try bw.print("{s}", .{@tagName(pl)}),
- .register_pair => |pl| try bw.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
- .register_triple => |pl| try bw.print("{s}:{s}:{s}", .{
+ .none, .unreach, .dead, .undef => try w.print("({s})", .{@tagName(mcv)}),
+ .immediate => |pl| try w.print("0x{x}", .{pl}),
+ .memory => |pl| try w.print("[ds:0x{x}]", .{pl}),
+ inline .eflags, .register => |pl| try w.print("{s}", .{@tagName(pl)}),
+ .register_pair => |pl| try w.print("{s}:{s}", .{ @tagName(pl[1]), @tagName(pl[0]) }),
+ .register_triple => |pl| try w.print("{s}:{s}:{s}", .{
@tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
}),
- .register_quadruple => |pl| try bw.print("{s}:{s}:{s}:{s}", .{
+ .register_quadruple => |pl| try w.print("{s}:{s}:{s}:{s}", .{
@tagName(pl[3]), @tagName(pl[2]), @tagName(pl[1]), @tagName(pl[0]),
}),
- .register_offset => |pl| try bw.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
- .register_overflow => |pl| try bw.print("{s}:{s}", .{
+ .register_offset => |pl| try w.print("{s} + 0x{x}", .{ @tagName(pl.reg), pl.off }),
+ .register_overflow => |pl| try w.print("{s}:{s}", .{
@tagName(pl.eflags),
@tagName(pl.reg),
}),
- .register_mask => |pl| try bw.print("mask({s},{f}):{c}{s}", .{
+ .register_mask => |pl| try w.print("mask({s},{f}):{c}{s}", .{
@tagName(pl.info.kind),
pl.info.scalar,
@as(u8, if (pl.info.inverted) '!' else ' '),
@tagName(pl.reg),
}),
- .indirect => |pl| try bw.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
- .indirect_load_frame => |pl| try bw.print("[[{f} + 0x{x}]]", .{ pl.index, pl.off }),
- .load_frame => |pl| try bw.print("[{f} + 0x{x}]", .{ pl.index, pl.off }),
- .lea_frame => |pl| try bw.print("{f} + 0x{x}", .{ pl.index, pl.off }),
- .load_nav => |pl| try bw.print("[nav:{d}]", .{@intFromEnum(pl)}),
- .lea_nav => |pl| try bw.print("nav:{d}", .{@intFromEnum(pl)}),
- .load_uav => |pl| try bw.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
- .lea_uav => |pl| try bw.print("uav:{d}", .{@intFromEnum(pl.val)}),
- .load_lazy_sym => |pl| try bw.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
- .lea_lazy_sym => |pl| try bw.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
- .load_extern_func => |pl| try bw.print("[extern:{d}]", .{@intFromEnum(pl)}),
- .lea_extern_func => |pl| try bw.print("extern:{d}", .{@intFromEnum(pl)}),
- .elementwise_args => |pl| try bw.print("elementwise:{d}:[{f} + 0x{x}]", .{
+ .indirect => |pl| try w.print("[{s} + 0x{x}]", .{ @tagName(pl.reg), pl.off }),
+ .indirect_load_frame => |pl| try w.print("[[{} + 0x{x}]]", .{ pl.index, pl.off }),
+ .load_frame => |pl| try w.print("[{} + 0x{x}]", .{ pl.index, pl.off }),
+ .lea_frame => |pl| try w.print("{} + 0x{x}", .{ pl.index, pl.off }),
+ .load_nav => |pl| try w.print("[nav:{d}]", .{@intFromEnum(pl)}),
+ .lea_nav => |pl| try w.print("nav:{d}", .{@intFromEnum(pl)}),
+ .load_uav => |pl| try w.print("[uav:{d}]", .{@intFromEnum(pl.val)}),
+ .lea_uav => |pl| try w.print("uav:{d}", .{@intFromEnum(pl.val)}),
+ .load_lazy_sym => |pl| try w.print("[lazy:{s}:{d}]", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
+ .lea_lazy_sym => |pl| try w.print("lazy:{s}:{d}", .{ @tagName(pl.kind), @intFromEnum(pl.ty) }),
+ .load_extern_func => |pl| try w.print("[extern:{d}]", .{@intFromEnum(pl)}),
+ .lea_extern_func => |pl| try w.print("extern:{d}", .{@intFromEnum(pl)}),
+ .elementwise_args => |pl| try w.print("elementwise:{d}:[{} + 0x{x}]", .{
pl.regs, pl.frame_index, pl.frame_off,
}),
- .reserved_frame => |pl| try bw.print("(dead:{f})", .{pl}),
- .air_ref => |pl| try bw.print("(air:0x{x})", .{@intFromEnum(pl)}),
+ .reserved_frame => |pl| try w.print("(dead:{})", .{pl}),
+ .air_ref => |pl| try w.print("(air:0x{x})", .{@intFromEnum(pl)}),
}
}
};
@@ -2026,7 +2026,7 @@ fn gen(
.{},
);
self.ret_mcv.long = .{ .load_frame = .{ .index = frame_index } };
- tracking_log.debug("spill {f} to {f}", .{ self.ret_mcv.long, frame_index });
+ tracking_log.debug("spill {f} to {}", .{ self.ret_mcv.long, frame_index });
},
else => unreachable,
}
src/arch/x86_64/encoder.zig
@@ -259,7 +259,7 @@ pub const Instruction = struct {
switch (sib.base) {
.none => any = false,
.reg => |reg| try w.print("{s}", .{@tagName(reg)}),
- .frame => |frame_index| try w.print("{f}", .{frame_index}),
+ .frame => |frame_index| try w.print("{}", .{frame_index}),
.table => try w.print("Table", .{}),
.rip_inst => |inst_index| try w.print("RipInst({d})", .{inst_index}),
.nav => |nav| try w.print("Nav({d})", .{@intFromEnum(nav)}),
src/link/C.zig
@@ -503,8 +503,8 @@ pub fn flush(self: *C, arena: Allocator, tid: Zcu.PerThread.Id, prog_node: std.P
var fw = file.writer(&.{});
var w = &fw.interface;
w.writeVecAll(f.all_buffers.items) catch |err| switch (err) {
- error.WriteFailed => return diags.fail("failed to write to '{f'}': {s}", .{
- self.base.emit, @errorName(fw.err.?),
+ error.WriteFailed => return diags.fail("failed to write to '{f}': {s}", .{
+ std.fmt.alt(self.base.emit, .formatEscapeChar), @errorName(fw.err.?),
}),
};
}
src/Package/Fetch/git.zig
@@ -662,13 +662,21 @@ pub const Session = struct {
fn init(allocator: Allocator, uri: std.Uri) !Location {
const scheme = try allocator.dupe(u8, uri.scheme);
errdefer allocator.free(scheme);
- const user = if (uri.user) |user| try std.fmt.allocPrint(allocator, "{fuser}", .{user}) else null;
+ const user = if (uri.user) |user| try std.fmt.allocPrint(allocator, "{f}", .{
+ std.fmt.alt(user, .formatUser),
+ }) else null;
errdefer if (user) |s| allocator.free(s);
- const password = if (uri.password) |password| try std.fmt.allocPrint(allocator, "{fpassword}", .{password}) else null;
+ const password = if (uri.password) |password| try std.fmt.allocPrint(allocator, "{f}", .{
+ std.fmt.alt(password, .formatPassword),
+ }) else null;
errdefer if (password) |s| allocator.free(s);
- const host = if (uri.host) |host| try std.fmt.allocPrint(allocator, "{fhost}", .{host}) else null;
+ const host = if (uri.host) |host| try std.fmt.allocPrint(allocator, "{f}", .{
+ std.fmt.alt(host, .formatHost),
+ }) else null;
errdefer if (host) |s| allocator.free(s);
- const path = try std.fmt.allocPrint(allocator, "{fpath}", .{uri.path});
+ const path = try std.fmt.allocPrint(allocator, "{f}", .{
+ std.fmt.alt(uri.path, .formatPath),
+ });
errdefer allocator.free(path);
// The query and fragment are not used as part of the base server URI.
return .{
@@ -699,7 +707,9 @@ pub const Session = struct {
fn getCapabilities(session: *Session, http_headers_buffer: []u8) !CapabilityIterator {
var info_refs_uri = session.location.uri;
{
- const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
+ const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
+ std.fmt.alt(session.location.uri.path, .formatPath),
+ });
defer session.allocator.free(session_uri_path);
info_refs_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "info/refs" }) };
}
@@ -723,7 +733,9 @@ pub const Session = struct {
if (request.response.status != .ok) return error.ProtocolError;
const any_redirects_occurred = request.redirect_behavior.remaining() < max_redirects;
if (any_redirects_occurred) {
- const request_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{request.uri.path});
+ const request_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
+ std.fmt.alt(request.uri.path, .formatPath),
+ });
defer session.allocator.free(request_uri_path);
if (!mem.endsWith(u8, request_uri_path, "/info/refs")) return error.UnparseableRedirect;
var new_uri = request.uri;
@@ -810,7 +822,9 @@ pub const Session = struct {
pub fn listRefs(session: Session, options: ListRefsOptions) !RefIterator {
var upload_pack_uri = session.location.uri;
{
- const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
+ const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
+ std.fmt.alt(session.location.uri.path, .formatPath),
+ });
defer session.allocator.free(session_uri_path);
upload_pack_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "git-upload-pack" }) };
}
@@ -925,7 +939,9 @@ pub const Session = struct {
) !FetchStream {
var upload_pack_uri = session.location.uri;
{
- const session_uri_path = try std.fmt.allocPrint(session.allocator, "{fpath}", .{session.location.uri.path});
+ const session_uri_path = try std.fmt.allocPrint(session.allocator, "{f}", .{
+ std.fmt.alt(session.location.uri.path, .formatPath),
+ });
defer session.allocator.free(session_uri_path);
upload_pack_uri.path = .{ .percent_encoded = try std.fs.path.resolvePosix(session.allocator, &.{ "/", session_uri_path, "git-upload-pack" }) };
}
src/Package/Fetch.zig
@@ -227,9 +227,9 @@ pub const JobQueue = struct {
}
try buf.writer().print(
- \\ pub const build_root = "{fq}";
+ \\ pub const build_root = "{f}";
\\
- , .{fetch.package_root});
+ , .{std.fmt.alt(fetch.package_root, .formatEscapeString)});
if (fetch.has_build_zig) {
try buf.writer().print(
@@ -1079,7 +1079,10 @@ fn initResource(f: *Fetch, uri: std.Uri, server_header_buffer: []u8) RunError!Re
});
const notes_start = try eb.reserveNotes(notes_len);
eb.extra.items[notes_start] = @intFromEnum(try eb.addErrorMessage(.{
- .msg = try eb.printString("try .url = \"{f;+/}#{f}\",", .{ uri, want_oid }),
+ .msg = try eb.printString("try .url = \"{f}#{f}\",", .{
+ uri.fmt(.{ .scheme = true, .authority = true, .path = true }),
+ want_oid,
+ }),
}));
return error.FetchFailed;
}
src/Sema/LowerZon.zig
@@ -492,7 +492,7 @@ fn lowerInt(
if (!val.fitsInTwosComp(int_info.signedness, int_info.bits)) {
return self.fail(
node,
- "type '{f}' cannot represent integer value '{f}'",
+ "type '{f}' cannot represent integer value '{d}'",
.{ res_ty.fmt(self.sema.pt), val },
);
}
src/Builtin.zig
@@ -200,8 +200,8 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {
}),
.windows => |windows| try buffer.print(
\\ .windows = .{{
- \\ .min = {fc},
- \\ .max = {fc},
+ \\ .min = {f},
+ \\ .max = {f},
\\ }}}},
\\
, .{ windows.min, windows.max }),
src/link.zig
@@ -838,8 +838,10 @@ pub const File = struct {
const cached_pp_file_path = the_key.status.success.object_path;
cached_pp_file_path.root_dir.handle.copyFile(cached_pp_file_path.sub_path, emit.root_dir.handle, emit.sub_path, .{}) catch |err| {
const diags = &base.comp.link_diags;
- return diags.fail("failed to copy '{f'}' to '{f'}': {s}", .{
- @as(Path, cached_pp_file_path), @as(Path, emit), @errorName(err),
+ return diags.fail("failed to copy '{f}' to '{f}': {s}", .{
+ std.fmt.alt(@as(Path, cached_pp_file_path), .formatEscapeChar),
+ std.fmt.alt(@as(Path, emit), .formatEscapeChar),
+ @errorName(err),
});
};
return;
@@ -2086,14 +2088,14 @@ fn resolvePathInputLib(
}) {
var file = test_path.root_dir.handle.openFile(test_path.sub_path, .{}) catch |err| switch (err) {
error.FileNotFound => return .no_match,
- else => |e| fatal("unable to search for {s} library '{f'}': {s}", .{
- @tagName(link_mode), test_path, @errorName(e),
+ else => |e| fatal("unable to search for {s} library '{f}': {s}", .{
+ @tagName(link_mode), std.fmt.alt(test_path, .formatEscapeChar), @errorName(e),
}),
};
errdefer file.close();
try ld_script_bytes.resize(gpa, @max(std.elf.MAGIC.len, std.elf.ARMAG.len));
- const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f'}': {s}", .{
- test_path, @errorName(err),
+ const n = file.preadAll(ld_script_bytes.items, 0) catch |err| fatal("failed to read '{f}': {s}", .{
+ std.fmt.alt(test_path, .formatEscapeChar), @errorName(err),
});
const buf = ld_script_bytes.items[0..n];
if (mem.startsWith(u8, buf, std.elf.MAGIC) or mem.startsWith(u8, buf, std.elf.ARMAG)) {
src/main.zig
@@ -6964,7 +6964,9 @@ fn cmdFetch(
std.log.info("resolved ref '{s}' to commit {s}", .{ target_ref, latest_commit_hex });
// include the original refspec in a query parameter, could be used to check for updates
- uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={f%}", .{fragment}) };
+ uri.query = .{ .percent_encoded = try std.fmt.allocPrint(arena, "ref={f}", .{
+ std.fmt.alt(fragment, .formatEscaped),
+ }) };
} else {
std.log.info("resolved to commit {s}", .{latest_commit_hex});
}
src/print_value.zig
@@ -77,7 +77,7 @@ pub fn print(
.func => |func| try writer.print("(function '{f}')", .{ip.getNav(func.owner_nav).name.fmt(ip)}),
.int => |int| switch (int.storage) {
inline .u64, .i64 => |x| try writer.print("{d}", .{x}),
- .big_int => |x| try writer.print("{fd}", .{x}),
+ .big_int => |x| try writer.print("{d}", .{x}),
.lazy_align => |ty| if (opt_sema != null) {
const a = try Type.fromInterned(ty).abiAlignmentSema(pt);
try writer.print("{d}", .{a.toByteUnits() orelse 0});