authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-05 16:52:18-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-05 16:52:18-05:00
log84323504acc2c872a55d0b59ff2c54b60b809405
tree36b0b4eeeded5ae409f4af42f466c25a3180bc75
parent378d733439a574cc7b961f1d6a09167479225da8
signaturelock-open Commit is signed but in an unrecognized format.

std.fmt.format: comptime output parameter


4 files changed, 38 insertions(+), 45 deletions(-)

lib/std/fmt.zig+16-16
...@@ -78,7 +78,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {...@@ -78,7 +78,7 @@ fn peekIsAlign(comptime fmt: []const u8) bool {
78pub fn format(78pub fn format(
79 context: var,79 context: var,
80 comptime Errors: type,80 comptime Errors: type,
81 output: fn (@TypeOf(context), []const u8) Errors!void,81 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
82 comptime fmt: []const u8,82 comptime fmt: []const u8,
83 args: var,83 args: var,
84) Errors!void {84) Errors!void {
...@@ -326,7 +326,7 @@ pub fn formatType(...@@ -326,7 +326,7 @@ pub fn formatType(
326 options: FormatOptions,326 options: FormatOptions,
327 context: var,327 context: var,
328 comptime Errors: type,328 comptime Errors: type,
329 output: fn (@TypeOf(context), []const u8) Errors!void,329 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
330 max_depth: usize,330 max_depth: usize,
331) Errors!void {331) Errors!void {
332 if (comptime std.mem.eql(u8, fmt, "*")) {332 if (comptime std.mem.eql(u8, fmt, "*")) {
...@@ -488,7 +488,7 @@ fn formatValue(...@@ -488,7 +488,7 @@ fn formatValue(
488 options: FormatOptions,488 options: FormatOptions,
489 context: var,489 context: var,
490 comptime Errors: type,490 comptime Errors: type,
491 output: fn (@TypeOf(context), []const u8) Errors!void,491 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
492) Errors!void {492) Errors!void {
493 if (comptime std.mem.eql(u8, fmt, "B")) {493 if (comptime std.mem.eql(u8, fmt, "B")) {
494 return formatBytes(value, options, 1000, context, Errors, output);494 return formatBytes(value, options, 1000, context, Errors, output);
...@@ -510,7 +510,7 @@ pub fn formatIntValue(...@@ -510,7 +510,7 @@ pub fn formatIntValue(
510 options: FormatOptions,510 options: FormatOptions,
511 context: var,511 context: var,
512 comptime Errors: type,512 comptime Errors: type,
513 output: fn (@TypeOf(context), []const u8) Errors!void,513 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
514) Errors!void {514) Errors!void {
515 comptime var radix = 10;515 comptime var radix = 10;
516 comptime var uppercase = false;516 comptime var uppercase = false;
...@@ -552,7 +552,7 @@ fn formatFloatValue(...@@ -552,7 +552,7 @@ fn formatFloatValue(
552 options: FormatOptions,552 options: FormatOptions,
553 context: var,553 context: var,
554 comptime Errors: type,554 comptime Errors: type,
555 output: fn (@TypeOf(context), []const u8) Errors!void,555 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
556) Errors!void {556) Errors!void {
557 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) {557 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "e")) {
558 return formatFloatScientific(value, options, context, Errors, output);558 return formatFloatScientific(value, options, context, Errors, output);
...@@ -569,7 +569,7 @@ pub fn formatText(...@@ -569,7 +569,7 @@ pub fn formatText(
569 options: FormatOptions,569 options: FormatOptions,
570 context: var,570 context: var,
571 comptime Errors: type,571 comptime Errors: type,
572 output: fn (@TypeOf(context), []const u8) Errors!void,572 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
573) Errors!void {573) Errors!void {
574 if (fmt.len == 0) {574 if (fmt.len == 0) {
575 return output(context, bytes);575 return output(context, bytes);
...@@ -590,7 +590,7 @@ pub fn formatAsciiChar(...@@ -590,7 +590,7 @@ pub fn formatAsciiChar(
590 options: FormatOptions,590 options: FormatOptions,
591 context: var,591 context: var,
592 comptime Errors: type,592 comptime Errors: type,
593 output: fn (@TypeOf(context), []const u8) Errors!void,593 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
594) Errors!void {594) Errors!void {
595 return output(context, @as(*const [1]u8, &c)[0..]);595 return output(context, @as(*const [1]u8, &c)[0..]);
596}596}
...@@ -600,7 +600,7 @@ pub fn formatBuf(...@@ -600,7 +600,7 @@ pub fn formatBuf(
600 options: FormatOptions,600 options: FormatOptions,
601 context: var,601 context: var,
602 comptime Errors: type,602 comptime Errors: type,
603 output: fn (@TypeOf(context), []const u8) Errors!void,603 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
604) Errors!void {604) Errors!void {
605 try output(context, buf);605 try output(context, buf);
606606
...@@ -620,7 +620,7 @@ pub fn formatFloatScientific(...@@ -620,7 +620,7 @@ pub fn formatFloatScientific(
620 options: FormatOptions,620 options: FormatOptions,
621 context: var,621 context: var,
622 comptime Errors: type,622 comptime Errors: type,
623 output: fn (@TypeOf(context), []const u8) Errors!void,623 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
624) Errors!void {624) Errors!void {
625 var x = @floatCast(f64, value);625 var x = @floatCast(f64, value);
626626
...@@ -715,7 +715,7 @@ pub fn formatFloatDecimal(...@@ -715,7 +715,7 @@ pub fn formatFloatDecimal(
715 options: FormatOptions,715 options: FormatOptions,
716 context: var,716 context: var,
717 comptime Errors: type,717 comptime Errors: type,
718 output: fn (@TypeOf(context), []const u8) Errors!void,718 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
719) Errors!void {719) Errors!void {
720 var x = @as(f64, value);720 var x = @as(f64, value);
721721
...@@ -861,7 +861,7 @@ pub fn formatBytes(...@@ -861,7 +861,7 @@ pub fn formatBytes(
861 comptime radix: usize,861 comptime radix: usize,
862 context: var,862 context: var,
863 comptime Errors: type,863 comptime Errors: type,
864 output: fn (@TypeOf(context), []const u8) Errors!void,864 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
865) Errors!void {865) Errors!void {
866 if (value == 0) {866 if (value == 0) {
867 return output(context, "0B");867 return output(context, "0B");
...@@ -902,7 +902,7 @@ pub fn formatInt(...@@ -902,7 +902,7 @@ pub fn formatInt(
902 options: FormatOptions,902 options: FormatOptions,
903 context: var,903 context: var,
904 comptime Errors: type,904 comptime Errors: type,
905 output: fn (@TypeOf(context), []const u8) Errors!void,905 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
906) Errors!void {906) Errors!void {
907 const int_value = if (@TypeOf(value) == comptime_int) blk: {907 const int_value = if (@TypeOf(value) == comptime_int) blk: {
908 const Int = math.IntFittingRange(value, value);908 const Int = math.IntFittingRange(value, value);
...@@ -924,7 +924,7 @@ fn formatIntSigned(...@@ -924,7 +924,7 @@ fn formatIntSigned(
924 options: FormatOptions,924 options: FormatOptions,
925 context: var,925 context: var,
926 comptime Errors: type,926 comptime Errors: type,
927 output: fn (@TypeOf(context), []const u8) Errors!void,927 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
928) Errors!void {928) Errors!void {
929 const new_options = FormatOptions{929 const new_options = FormatOptions{
930 .width = if (options.width) |w| (if (w == 0) 0 else w - 1) else null,930 .width = if (options.width) |w| (if (w == 0) 0 else w - 1) else null,
...@@ -955,7 +955,7 @@ fn formatIntUnsigned(...@@ -955,7 +955,7 @@ fn formatIntUnsigned(
955 options: FormatOptions,955 options: FormatOptions,
956 context: var,956 context: var,
957 comptime Errors: type,957 comptime Errors: type,
958 output: fn (@TypeOf(context), []const u8) Errors!void,958 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
959) Errors!void {959) Errors!void {
960 assert(base >= 2);960 assert(base >= 2);
961 var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;961 var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;
...@@ -1419,7 +1419,7 @@ test "custom" {...@@ -1419,7 +1419,7 @@ test "custom" {
1419 options: FormatOptions,1419 options: FormatOptions,
1420 context: var,1420 context: var,
1421 comptime Errors: type,1421 comptime Errors: type,
1422 output: fn (@TypeOf(context), []const u8) Errors!void,1422 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
1423 ) Errors!void {1423 ) Errors!void {
1424 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {1424 if (fmt.len == 0 or comptime std.mem.eql(u8, fmt, "p")) {
1425 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });1425 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });
...@@ -1626,7 +1626,7 @@ test "formatType max_depth" {...@@ -1626,7 +1626,7 @@ test "formatType max_depth" {
1626 options: FormatOptions,1626 options: FormatOptions,
1627 context: var,1627 context: var,
1628 comptime Errors: type,1628 comptime Errors: type,
1629 output: fn (@TypeOf(context), []const u8) Errors!void,1629 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
1630 ) Errors!void {1630 ) Errors!void {
1631 if (fmt.len == 0) {1631 if (fmt.len == 0) {
1632 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });1632 return std.fmt.format(context, Errors, output, "({d:.3},{d:.3})", .{ self.x, self.y });
lib/std/io/out_stream.zig+1-1
...@@ -36,7 +36,7 @@ pub fn OutStream(comptime WriteError: type) type {...@@ -36,7 +36,7 @@ pub fn OutStream(comptime WriteError: type) type {
36 }36 }
3737
38 pub fn print(self: *Self, comptime format: []const u8, args: var) Error!void {38 pub fn print(self: *Self, comptime format: []const u8, args: var) Error!void {
39 return std.fmt.format(self, Error, self.writeFn, format, args);39 return std.fmt.format(self, Error, write, format, args);
40 }40 }
4141
42 pub fn writeByte(self: *Self, byte: u8) Error!void {42 pub fn writeByte(self: *Self, byte: u8) Error!void {
lib/std/net.zig+11-5
...@@ -271,7 +271,7 @@ pub const Address = extern union {...@@ -271,7 +271,7 @@ pub const Address = extern union {
271 options: std.fmt.FormatOptions,271 options: std.fmt.FormatOptions,
272 context: var,272 context: var,
273 comptime Errors: type,273 comptime Errors: type,
274 output: fn (@TypeOf(context), []const u8) Errors!void,274 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
275 ) !void {275 ) !void {
276 switch (self.any.family) {276 switch (self.any.family) {
277 os.AF_INET => {277 os.AF_INET => {
...@@ -361,7 +361,7 @@ pub const Address = extern union {...@@ -361,7 +361,7 @@ pub const Address = extern union {
361};361};
362362
363pub fn connectUnixSocket(path: []const u8) !fs.File {363pub fn connectUnixSocket(path: []const u8) !fs.File {
364 const opt_non_block = if (std.io.mode == .evented) os.SOCK_NONBLOCK else 0;364 const opt_non_block = if (std.io.is_async) os.SOCK_NONBLOCK else 0;
365 const sockfd = try os.socket(365 const sockfd = try os.socket(
366 os.AF_UNIX,366 os.AF_UNIX,
367 os.SOCK_STREAM | os.SOCK_CLOEXEC | opt_non_block,367 os.SOCK_STREAM | os.SOCK_CLOEXEC | opt_non_block,
...@@ -377,7 +377,10 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {...@@ -377,7 +377,10 @@ pub fn connectUnixSocket(path: []const u8) !fs.File {
377 addr.getOsSockLen(),377 addr.getOsSockLen(),
378 );378 );
379379
380 return fs.File.openHandle(sockfd);380 return fs.File{
381 .handle = socket,
382 .is_blocking = std.io.mode,
383 };
381}384}
382385
383pub const AddressList = struct {386pub const AddressList = struct {
...@@ -412,7 +415,7 @@ pub fn tcpConnectToAddress(address: Address) !fs.File {...@@ -412,7 +415,7 @@ pub fn tcpConnectToAddress(address: Address) !fs.File {
412 errdefer os.close(sockfd);415 errdefer os.close(sockfd);
413 try os.connect(sockfd, &address.any, address.getOsSockLen());416 try os.connect(sockfd, &address.any, address.getOsSockLen());
414417
415 return fs.File{ .handle = sockfd };418 return fs.File{ .handle = sockfd, .io_mode = std.io.mode };
416}419}
417420
418/// Call `AddressList.deinit` on the result.421/// Call `AddressList.deinit` on the result.
...@@ -1379,7 +1382,10 @@ pub const StreamServer = struct {...@@ -1379,7 +1382,10 @@ pub const StreamServer = struct {
1379 var adr_len: os.socklen_t = @sizeOf(Address);1382 var adr_len: os.socklen_t = @sizeOf(Address);
1380 if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {1383 if (os.accept4(self.sockfd.?, &accepted_addr.any, &adr_len, accept_flags)) |fd| {
1381 return Connection{1384 return Connection{
1382 .file = fs.File.openHandle(fd),1385 .file = fs.File{
1386 .handle = fd,
1387 .io_mode = std.io.mode,
1388 },
1383 .address = accepted_addr,1389 .address = accepted_addr,
1384 };1390 };
1385 } else |err| switch (err) {1391 } else |err| switch (err) {
src-self-hosted/dep_tokenizer.zig+10-23
...@@ -998,7 +998,8 @@ fn printCharValues(out: var, bytes: []const u8) !void {...@@ -998,7 +998,8 @@ fn printCharValues(out: var, bytes: []const u8) !void {
998998
999fn printUnderstandableChar(out: var, char: u8) !void {999fn printUnderstandableChar(out: var, char: u8) !void {
1000 if (!std.ascii.isPrint(char) or char == ' ') {1000 if (!std.ascii.isPrint(char) or char == ' ') {
1001 std.fmt.format(out.context, anyerror, out.output, "\\x{X:2}", .{char}) catch {};1001 const output = @typeInfo(@TypeOf(out)).Pointer.child.output;
1002 std.fmt.format(out.context, anyerror, output, "\\x{X:2}", .{char}) catch {};
1002 } else {1003 } else {
1003 try out.write("'");1004 try out.write("'");
1004 try out.write(&[_]u8{printable_char_tab[char]});1005 try out.write(&[_]u8{printable_char_tab[char]});
...@@ -1021,34 +1022,20 @@ comptime {...@@ -1021,34 +1022,20 @@ comptime {
1021// output: must be a function that takes a `self` idiom parameter1022// output: must be a function that takes a `self` idiom parameter
1022// and a bytes parameter1023// and a bytes parameter
1023// context: must be that self1024// context: must be that self
1024fn makeOutput(output: var, context: var) Output(@TypeOf(output)) {1025fn makeOutput(comptime output: var, context: var) Output(output, @TypeOf(context)) {
1025 return Output(@TypeOf(output)){1026 return Output(output, @TypeOf(context)){
1026 .output = output,
1027 .context = context,1027 .context = context,
1028 };1028 };
1029}1029}
10301030
1031fn Output(comptime T: type) type {1031fn Output(comptime output_func: var, comptime Context: type) type {
1032 const args = switch (@typeInfo(T)) {
1033 .Fn => |f| f.args,
1034 else => @compileError("output parameter is not a function"),
1035 };
1036 if (args.len != 2) {
1037 @compileError("output function must take 2 arguments");
1038 }
1039 const at0 = args[0].arg_type orelse @compileError("output arg[0] does not have a type");
1040 const at1 = args[1].arg_type orelse @compileError("output arg[1] does not have a type");
1041 const arg1p = switch (@typeInfo(at1)) {
1042 .Pointer => |p| p,
1043 else => @compileError("output arg[1] is not a slice"),
1044 };
1045 if (arg1p.child != u8) @compileError("output arg[1] is not a u8 slice");
1046 return struct {1032 return struct {
1047 output: T,1033 context: Context,
1048 context: at0,1034
1035 pub const output = output_func;
10491036
1050 fn write(self: *@This(), bytes: []const u8) !void {1037 fn write(self: @This(), bytes: []const u8) !void {
1051 try self.output(self.context, bytes);1038 try output_func(self.context, bytes);
1052 }1039 }
1053 };1040 };
1054}1041}