Merge remote-tracking branch 'origin/master' into ast-memory-layout
This commit is contained in:
@@ -25,6 +25,13 @@ terminal: ?std.fs.File = undefined,
|
||||
/// Whether the terminal supports ANSI escape codes.
|
||||
supports_ansi_escape_codes: bool = false,
|
||||
|
||||
/// If the terminal is "dumb", don't print output.
|
||||
/// This can be useful if you don't want to print all
|
||||
/// the stages of code generation if there are a lot.
|
||||
/// You should not use it if the user should see output
|
||||
/// for example showing the user what tests run.
|
||||
dont_print_on_dumb: bool = false,
|
||||
|
||||
root: Node = undefined,
|
||||
|
||||
/// Keeps track of how much time has passed since the beginning.
|
||||
@@ -141,6 +148,9 @@ pub fn start(self: *Progress, name: []const u8, estimated_total_items: usize) !*
|
||||
self.supports_ansi_escape_codes = true;
|
||||
} else if (std.builtin.os.tag == .windows and stderr.isTty()) {
|
||||
self.terminal = stderr;
|
||||
} else if (std.builtin.os.tag != .windows) {
|
||||
// we are in a "dumb" terminal like in acme or writing to a file
|
||||
self.terminal = stderr;
|
||||
}
|
||||
self.root = Node{
|
||||
.context = self,
|
||||
@@ -178,6 +188,8 @@ pub fn refresh(self: *Progress) void {
|
||||
}
|
||||
|
||||
fn refreshWithHeldLock(self: *Progress) void {
|
||||
const is_dumb = !self.supports_ansi_escape_codes and !(std.builtin.os.tag == .windows);
|
||||
if (is_dumb and self.dont_print_on_dumb) return;
|
||||
const file = self.terminal orelse return;
|
||||
|
||||
const prev_columns_written = self.columns_written;
|
||||
@@ -226,7 +238,11 @@ fn refreshWithHeldLock(self: *Progress) void {
|
||||
|
||||
if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)
|
||||
unreachable;
|
||||
} else unreachable;
|
||||
} else {
|
||||
// we are in a "dumb" terminal like in acme or writing to a file
|
||||
self.output_buffer[end] = '\n';
|
||||
end += 1;
|
||||
}
|
||||
|
||||
self.columns_written = 0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ cond: Condition = .{},
|
||||
//! It is OK to initialize this field to any value.
|
||||
permits: usize = 0,
|
||||
|
||||
const RwLock = @This();
|
||||
const Semaphore = @This();
|
||||
const std = @import("../std.zig");
|
||||
const Mutex = std.Thread.Mutex;
|
||||
const Condition = std.Thread.Condition;
|
||||
|
||||
@@ -543,7 +543,7 @@ pub const Builder = struct {
|
||||
.Scalar => |s| {
|
||||
const n = std.fmt.parseInt(T, s, 10) catch |err| switch (err) {
|
||||
error.Overflow => {
|
||||
warn("-D{s} value {} cannot fit into type {s}.\n\n", .{ name, s, @typeName(T) });
|
||||
warn("-D{s} value {s} cannot fit into type {s}.\n\n", .{ name, s, @typeName(T) });
|
||||
self.markInvalidUserInput();
|
||||
return null;
|
||||
},
|
||||
@@ -1308,6 +1308,12 @@ const BuildOptionArtifactArg = struct {
|
||||
artifact: *LibExeObjStep,
|
||||
};
|
||||
|
||||
const BuildOptionWriteFileArg = struct {
|
||||
name: []const u8,
|
||||
write_file: *WriteFileStep,
|
||||
basename: []const u8,
|
||||
};
|
||||
|
||||
pub const LibExeObjStep = struct {
|
||||
step: Step,
|
||||
builder: *Builder,
|
||||
@@ -1355,6 +1361,7 @@ pub const LibExeObjStep = struct {
|
||||
packages: ArrayList(Pkg),
|
||||
build_options_contents: std.ArrayList(u8),
|
||||
build_options_artifact_args: std.ArrayList(BuildOptionArtifactArg),
|
||||
build_options_write_file_args: std.ArrayList(BuildOptionWriteFileArg),
|
||||
|
||||
object_src: []const u8,
|
||||
|
||||
@@ -1515,6 +1522,7 @@ pub const LibExeObjStep = struct {
|
||||
.object_src = undefined,
|
||||
.build_options_contents = std.ArrayList(u8).init(builder.allocator),
|
||||
.build_options_artifact_args = std.ArrayList(BuildOptionArtifactArg).init(builder.allocator),
|
||||
.build_options_write_file_args = std.ArrayList(BuildOptionWriteFileArg).init(builder.allocator),
|
||||
.c_std = Builder.CStd.C99,
|
||||
.override_lib_dir = null,
|
||||
.main_pkg_path = null,
|
||||
@@ -2008,6 +2016,23 @@ pub const LibExeObjStep = struct {
|
||||
self.step.dependOn(&artifact.step);
|
||||
}
|
||||
|
||||
/// The value is the path in the cache dir.
|
||||
/// Adds a dependency automatically.
|
||||
/// basename refers to the basename of the WriteFileStep
|
||||
pub fn addBuildOptionWriteFile(
|
||||
self: *LibExeObjStep,
|
||||
name: []const u8,
|
||||
write_file: *WriteFileStep,
|
||||
basename: []const u8,
|
||||
) void {
|
||||
self.build_options_write_file_args.append(.{
|
||||
.name = name,
|
||||
.write_file = write_file,
|
||||
.basename = basename,
|
||||
}) catch unreachable;
|
||||
self.step.dependOn(&write_file.step);
|
||||
}
|
||||
|
||||
pub fn addSystemIncludeDir(self: *LibExeObjStep, path: []const u8) void {
|
||||
self.include_dirs.append(IncludeDir{ .RawPathSystem = self.builder.dupe(path) }) catch unreachable;
|
||||
}
|
||||
@@ -2228,11 +2253,27 @@ pub const LibExeObjStep = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (self.build_options_contents.items.len > 0 or self.build_options_artifact_args.items.len > 0) {
|
||||
// Render build artifact options at the last minute, now that the path is known.
|
||||
if (self.build_options_contents.items.len > 0 or
|
||||
self.build_options_artifact_args.items.len > 0 or
|
||||
self.build_options_write_file_args.items.len > 0)
|
||||
{
|
||||
// Render build artifact and write file options at the last minute, now that the path is known.
|
||||
//
|
||||
// Note that pathFromRoot uses resolve path, so this will have
|
||||
// correct behavior even if getOutputPath is already absolute.
|
||||
for (self.build_options_artifact_args.items) |item| {
|
||||
const out = self.build_options_contents.writer();
|
||||
out.print("pub const {s}: []const u8 = \"{}\";\n", .{ item.name, std.zig.fmtEscapes(item.artifact.getOutputPath()) }) catch unreachable;
|
||||
self.addBuildOption(
|
||||
[]const u8,
|
||||
item.name,
|
||||
self.builder.pathFromRoot(item.artifact.getOutputPath()),
|
||||
);
|
||||
}
|
||||
for (self.build_options_write_file_args.items) |item| {
|
||||
self.addBuildOption(
|
||||
[]const u8,
|
||||
item.name,
|
||||
self.builder.pathFromRoot(item.write_file.getOutputPath(item.basename)),
|
||||
);
|
||||
}
|
||||
|
||||
const build_options_file = try fs.path.join(
|
||||
|
||||
@@ -100,6 +100,8 @@ pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64)
|
||||
pub extern "c" fn mmap(addr: ?*align(page_size) c_void, len: usize, prot: c_uint, flags: c_uint, fd: fd_t, offset: u64) *c_void;
|
||||
pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
|
||||
pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
|
||||
pub extern "c" fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: c_int) c_int;
|
||||
pub extern "c" fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: c_int) c_int;
|
||||
pub extern "c" fn unlink(path: [*:0]const u8) c_int;
|
||||
pub extern "c" fn unlinkat(dirfd: fd_t, path: [*:0]const u8, flags: c_uint) c_int;
|
||||
pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
|
||||
|
||||
@@ -207,7 +207,7 @@ pub const Ed25519 = struct {
|
||||
|
||||
test "ed25519 key pair creation" {
|
||||
var seed: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
const key_pair = try Ed25519.KeyPair.create(seed);
|
||||
var buf: [256]u8 = undefined;
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{key_pair.secret_key}), "8052030376D47112BE7F73ED7A019293DD12AD910B654455798B4667D73DE1662D6F7455D97B4A3A10D7293909D1A4F2058CB9A370E43FA8154BB280DB839083");
|
||||
@@ -216,7 +216,7 @@ test "ed25519 key pair creation" {
|
||||
|
||||
test "ed25519 signature" {
|
||||
var seed: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(seed[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
const key_pair = try Ed25519.KeyPair.create(seed);
|
||||
|
||||
const sig = try Ed25519.sign("test", key_pair, null);
|
||||
@@ -339,11 +339,11 @@ test "ed25519 test vectors" {
|
||||
};
|
||||
for (entries) |entry, i| {
|
||||
var msg: [entry.msg_hex.len / 2]u8 = undefined;
|
||||
try fmt.hexToBytes(&msg, entry.msg_hex);
|
||||
_ = try fmt.hexToBytes(&msg, entry.msg_hex);
|
||||
var public_key: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(&public_key, entry.public_key_hex);
|
||||
_ = try fmt.hexToBytes(&public_key, entry.public_key_hex);
|
||||
var sig: [64]u8 = undefined;
|
||||
try fmt.hexToBytes(&sig, entry.sig_hex);
|
||||
_ = try fmt.hexToBytes(&sig, entry.sig_hex);
|
||||
if (entry.expected) |error_type| {
|
||||
std.testing.expectError(error_type, Ed25519.verify(sig, &msg, public_key));
|
||||
} else {
|
||||
|
||||
@@ -173,7 +173,7 @@ test "ristretto255" {
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{p.toBytes()}), "E2F2AE0A6ABC4E71A884A961C500515F58E30B6AA582DD8DB6A65945E08D2D76");
|
||||
|
||||
var r: [Ristretto255.encoded_length]u8 = undefined;
|
||||
try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");
|
||||
_ = try fmt.hexToBytes(r[0..], "6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919");
|
||||
var q = try Ristretto255.fromBytes(r);
|
||||
q = q.dbl().add(p);
|
||||
std.testing.expectEqualStrings(try std.fmt.bufPrint(&buf, "{X}", .{q.toBytes()}), "E882B131016B52C1D3337080187CF768423EFCCBB517BB495AB812C4160FF44E");
|
||||
|
||||
@@ -85,8 +85,8 @@ const htest = @import("../test.zig");
|
||||
test "x25519 public key calculation from secret key" {
|
||||
var sk: [32]u8 = undefined;
|
||||
var pk_expected: [32]u8 = undefined;
|
||||
try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
||||
_ = try fmt.hexToBytes(sk[0..], "8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166");
|
||||
_ = try fmt.hexToBytes(pk_expected[0..], "f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50");
|
||||
const pk_calculated = try X25519.recoverPublicKey(sk);
|
||||
std.testing.expectEqual(pk_calculated, pk_expected);
|
||||
}
|
||||
|
||||
@@ -122,11 +122,11 @@ test "expand 128-bit key" {
|
||||
var exp: [16]u8 = undefined;
|
||||
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
}
|
||||
@@ -144,11 +144,11 @@ test "expand 256-bit key" {
|
||||
var exp: [16]u8 = undefined;
|
||||
|
||||
for (enc.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_enc[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
for (dec.key_schedule.round_keys) |round_key, i| {
|
||||
try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
_ = try std.fmt.hexToBytes(&exp, exp_dec[i]);
|
||||
testing.expectEqualSlices(u8, &exp, &round_key.toBytes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -663,7 +663,7 @@ fn testBlake3(hasher: *Blake3, input_len: usize, expected_hex: [262]u8) void {
|
||||
|
||||
// Compare to expected value
|
||||
var expected_bytes: [expected_hex.len / 2]u8 = undefined;
|
||||
fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable;
|
||||
_ = fmt.hexToBytes(expected_bytes[0..], expected_hex[0..]) catch unreachable;
|
||||
testing.expectEqual(actual_bytes, expected_bytes);
|
||||
|
||||
// Restore initial state
|
||||
|
||||
@@ -270,7 +270,7 @@ pub fn hash(out: []u8, in: []const u8, options: Hash.Options) void {
|
||||
test "hash" {
|
||||
// a test vector (30) from NIST KAT submission.
|
||||
var msg: [58 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("1C9A03DC6A5DDC5444CFC6F4B154CFF5CF081633B2CEA4D7D0AE7CCFED5AAA44", &md);
|
||||
@@ -278,7 +278,7 @@ test "hash" {
|
||||
|
||||
test "hash test vector 17" {
|
||||
var msg: [32 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("404C130AF1B9023A7908200919F690FFBB756D5176E056FFDE320016A37C7282", &md);
|
||||
@@ -286,7 +286,7 @@ test "hash test vector 17" {
|
||||
|
||||
test "hash test vector 33" {
|
||||
var msg: [32]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&msg, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
var md: [32]u8 = undefined;
|
||||
hash(&md, &msg, .{});
|
||||
htest.assertEqual("A8F4FA28708BDA7EFB4C1914CA4AFA9E475B82D588D36504F87DBB0ED9AB3C4B", &md);
|
||||
@@ -436,9 +436,9 @@ pub const Aead = struct {
|
||||
|
||||
test "cipher" {
|
||||
var key: [32]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&key, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&key, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
var nonce: [16]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&nonce, "000102030405060708090A0B0C0D0E0F");
|
||||
_ = try std.fmt.hexToBytes(&nonce, "000102030405060708090A0B0C0D0E0F");
|
||||
{ // test vector (1) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
const pt: [0]u8 = undefined;
|
||||
@@ -456,7 +456,7 @@ test "cipher" {
|
||||
{ // test vector (34) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
var pt: [2 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "00");
|
||||
_ = try std.fmt.hexToBytes(&pt, "00");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@@ -470,9 +470,9 @@ test "cipher" {
|
||||
}
|
||||
{ // test vector (106) from NIST KAT submission.
|
||||
var ad: [12 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&ad, "000102030405");
|
||||
_ = try std.fmt.hexToBytes(&ad, "000102030405");
|
||||
var pt: [6 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@@ -486,9 +486,9 @@ test "cipher" {
|
||||
}
|
||||
{ // test vector (790) from NIST KAT submission.
|
||||
var ad: [60 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&ad, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D");
|
||||
_ = try std.fmt.hexToBytes(&ad, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D");
|
||||
var pt: [46 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F10111213141516");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
@@ -503,7 +503,7 @@ test "cipher" {
|
||||
{ // test vector (1057) from NIST KAT submission.
|
||||
const ad: [0]u8 = undefined;
|
||||
var pt: [64 / 2]u8 = undefined;
|
||||
try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
_ = try std.fmt.hexToBytes(&pt, "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
|
||||
|
||||
var ct: [pt.len]u8 = undefined;
|
||||
var tag: [16]u8 = undefined;
|
||||
|
||||
@@ -440,13 +440,11 @@ pub const Loop = struct {
|
||||
.overlapped = ResumeNode.overlapped_init,
|
||||
},
|
||||
};
|
||||
var need_to_delete = false;
|
||||
var need_to_delete = true;
|
||||
defer if (need_to_delete) self.linuxRemoveFd(fd);
|
||||
|
||||
suspend {
|
||||
if (self.linuxAddFd(fd, &resume_node.base, flags)) |_| {
|
||||
need_to_delete = true;
|
||||
} else |err| switch (err) {
|
||||
self.linuxAddFd(fd, &resume_node.base, flags) catch |err| switch (err) {
|
||||
error.FileDescriptorNotRegistered => unreachable,
|
||||
error.OperationCausesCircularLoop => unreachable,
|
||||
error.FileDescriptorIncompatibleWithEpoll => unreachable,
|
||||
@@ -456,6 +454,7 @@ pub const Loop = struct {
|
||||
error.UserResourceLimitReached,
|
||||
error.Unexpected,
|
||||
=> {
|
||||
need_to_delete = false;
|
||||
// Fall back to a blocking poll(). Ideally this codepath is never hit, since
|
||||
// epoll should be just fine. But this is better than incorrect behavior.
|
||||
var poll_flags: i16 = 0;
|
||||
@@ -479,7 +478,7 @@ pub const Loop = struct {
|
||||
};
|
||||
resume @frame();
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ pub fn LinearFifo(
|
||||
count: usize,
|
||||
|
||||
const Self = @This();
|
||||
pub const Reader = std.io.Reader(*Self, error{}, readFn);
|
||||
pub const Writer = std.io.Writer(*Self, error{OutOfMemory}, appendWrite);
|
||||
|
||||
// Type of Self argument for slice operations.
|
||||
// If buffer is inline (Static) then we need to ensure we haven't
|
||||
@@ -153,7 +155,7 @@ pub fn LinearFifo(
|
||||
var start = self.head + offset;
|
||||
if (start >= self.buf.len) {
|
||||
start -= self.buf.len;
|
||||
return self.buf[start .. self.count - offset];
|
||||
return self.buf[start .. start + (self.count - offset)];
|
||||
} else {
|
||||
const end = math.min(self.head + self.count, self.buf.len);
|
||||
return self.buf[start..end];
|
||||
@@ -228,7 +230,7 @@ pub fn LinearFifo(
|
||||
return self.read(dest);
|
||||
}
|
||||
|
||||
pub fn reader(self: *Self) std.io.Reader(*Self, error{}, readFn) {
|
||||
pub fn reader(self: *Self) Reader {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
@@ -318,7 +320,7 @@ pub fn LinearFifo(
|
||||
return bytes.len;
|
||||
}
|
||||
|
||||
pub fn writer(self: *Self) std.io.Writer(*Self, error{OutOfMemory}, appendWrite) {
|
||||
pub fn writer(self: *Self) Writer {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
@@ -427,6 +429,8 @@ test "LinearFifo(u8, .Dynamic)" {
|
||||
fifo.writeAssumeCapacity("6<chars<11");
|
||||
testing.expectEqualSlices(u8, "HELLO6<char", fifo.readableSlice(0));
|
||||
testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(11));
|
||||
testing.expectEqualSlices(u8, "11", fifo.readableSlice(13));
|
||||
testing.expectEqualSlices(u8, "", fifo.readableSlice(15));
|
||||
fifo.discard(11);
|
||||
testing.expectEqualSlices(u8, "s<11", fifo.readableSlice(0));
|
||||
fifo.discard(4);
|
||||
|
||||
@@ -524,7 +524,7 @@ pub fn formatType(
|
||||
if (actual_fmt.len == 0)
|
||||
@compileError("cannot format array ref without a specifier (i.e. {s} or {*})");
|
||||
if (info.child == u8) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
||||
return formatText(value, actual_fmt, options, writer);
|
||||
}
|
||||
}
|
||||
@@ -542,7 +542,7 @@ pub fn formatType(
|
||||
return formatType(mem.span(value), actual_fmt, options, writer, max_depth);
|
||||
}
|
||||
if (ptr_info.child == u8) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
||||
return formatText(mem.span(value), actual_fmt, options, writer);
|
||||
}
|
||||
}
|
||||
@@ -555,7 +555,7 @@ pub fn formatType(
|
||||
return writer.writeAll("{ ... }");
|
||||
}
|
||||
if (ptr_info.child == u8) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
||||
return formatText(value, actual_fmt, options, writer);
|
||||
}
|
||||
}
|
||||
@@ -576,7 +576,7 @@ pub fn formatType(
|
||||
return writer.writeAll("{ ... }");
|
||||
}
|
||||
if (info.child == u8) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeEzZ", actual_fmt[0]) != null) {
|
||||
if (comptime mem.indexOfScalar(u8, "sxXeE", actual_fmt[0]) != null) {
|
||||
return formatText(&value, actual_fmt, options, writer);
|
||||
}
|
||||
}
|
||||
@@ -658,8 +658,6 @@ pub fn formatIntValue(
|
||||
} else {
|
||||
@compileError("Cannot print integer that is larger than 8 bits as a ascii");
|
||||
}
|
||||
} else if (comptime std.mem.eql(u8, fmt, "Z")) {
|
||||
@compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");
|
||||
} else if (comptime std.mem.eql(u8, fmt, "u")) {
|
||||
if (@typeInfo(@TypeOf(int_value)).Int.bits <= 21) {
|
||||
return formatUnicodeCodepoint(@as(u21, int_value), options, writer);
|
||||
@@ -735,10 +733,6 @@ pub fn formatText(
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else if (comptime std.mem.eql(u8, fmt, "z")) {
|
||||
@compileError("specifier 'z' has been deprecated, wrap your argument in std.zig.fmtId instead");
|
||||
} else if (comptime std.mem.eql(u8, fmt, "Z")) {
|
||||
@compileError("specifier 'Z' has been deprecated, wrap your argument in std.zig.fmtEscapes instead");
|
||||
} else {
|
||||
@compileError("Unsupported format string '" ++ fmt ++ "' for type '" ++ @typeName(@TypeOf(value)) ++ "'");
|
||||
}
|
||||
@@ -1988,23 +1982,34 @@ test "bytes.hex" {
|
||||
pub const trim = @compileError("deprecated; use std.mem.trim with std.ascii.spaces instead");
|
||||
pub const isWhiteSpace = @compileError("deprecated; use std.ascii.isSpace instead");
|
||||
|
||||
pub fn hexToBytes(out: []u8, input: []const u8) !void {
|
||||
if (out.len * 2 < input.len)
|
||||
/// Decodes the sequence of bytes represented by the specified string of
|
||||
/// hexadecimal characters.
|
||||
/// Returns a slice of the output buffer containing the decoded bytes.
|
||||
pub fn hexToBytes(out: []u8, input: []const u8) ![]u8 {
|
||||
// Expect 0 or n pairs of hexadecimal digits.
|
||||
if (input.len & 1 != 0)
|
||||
return error.InvalidLength;
|
||||
if (out.len * 2 < input.len)
|
||||
return error.NoSpaceLeft;
|
||||
|
||||
var in_i: usize = 0;
|
||||
while (in_i != input.len) : (in_i += 2) {
|
||||
while (in_i < input.len) : (in_i += 2) {
|
||||
const hi = try charToDigit(input[in_i], 16);
|
||||
const lo = try charToDigit(input[in_i + 1], 16);
|
||||
out[in_i / 2] = (hi << 4) | lo;
|
||||
}
|
||||
|
||||
return out[0 .. in_i / 2];
|
||||
}
|
||||
|
||||
test "hexToBytes" {
|
||||
const test_hex_str = "909A312BB12ED1F819B3521AC4C1E896F2160507FFC1C8381E3B07BB16BD1706";
|
||||
var pb: [32]u8 = undefined;
|
||||
try hexToBytes(pb[0..], test_hex_str);
|
||||
try expectFmt(test_hex_str, "{X}", .{pb});
|
||||
var buf: [32]u8 = undefined;
|
||||
try expectFmt("90" ** 32, "{X}", .{try hexToBytes(&buf, "90" ** 32)});
|
||||
try expectFmt("ABCD", "{X}", .{try hexToBytes(&buf, "ABCD")});
|
||||
try expectFmt("", "{X}", .{try hexToBytes(&buf, "")});
|
||||
std.testing.expectError(error.InvalidCharacter, hexToBytes(&buf, "012Z"));
|
||||
std.testing.expectError(error.InvalidLength, hexToBytes(&buf, "AAA"));
|
||||
std.testing.expectError(error.NoSpaceLeft, hexToBytes(buf[0..1], "ABAB"));
|
||||
}
|
||||
|
||||
test "formatIntValue with comptime_int" {
|
||||
|
||||
@@ -2186,7 +2186,7 @@ pub const Walker = struct {
|
||||
var top = &self.stack.items[self.stack.items.len - 1];
|
||||
const dirname_len = top.dirname_len;
|
||||
if (try top.dir_it.next()) |base| {
|
||||
self.name_buffer.shrinkAndFree(dirname_len);
|
||||
self.name_buffer.shrinkRetainingCapacity(dirname_len);
|
||||
try self.name_buffer.append(path.sep);
|
||||
try self.name_buffer.appendSlice(base.name);
|
||||
if (base.kind == .Directory) {
|
||||
|
||||
@@ -587,6 +587,7 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
/// See equivalent function: `std.net.Stream.writev`.
|
||||
pub fn writev(self: File, iovecs: []const os.iovec_const) WriteError!usize {
|
||||
if (is_windows) {
|
||||
// TODO improve this to use WriteFileScatter
|
||||
@@ -605,6 +606,7 @@ pub const File = struct {
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial writes from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
/// See equivalent function: `std.net.Stream.writevAll`.
|
||||
pub fn writevAll(self: File, iovecs: []os.iovec_const) WriteError!void {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ pub fn Reader(
|
||||
delimiter: u8,
|
||||
max_size: usize,
|
||||
) !void {
|
||||
array_list.shrinkAndFree(0);
|
||||
array_list.shrinkRetainingCapacity(0);
|
||||
while (true) {
|
||||
var byte: u8 = try self.readByte();
|
||||
|
||||
|
||||
@@ -2018,7 +2018,7 @@ pub const Parser = struct {
|
||||
|
||||
pub fn reset(p: *Parser) void {
|
||||
p.state = .Simple;
|
||||
p.stack.shrinkAndFree(0);
|
||||
p.stack.shrinkRetainingCapacity(0);
|
||||
}
|
||||
|
||||
pub fn parse(p: *Parser, input: []const u8) !ValueTree {
|
||||
|
||||
@@ -607,7 +607,7 @@ pub const Mutable = struct {
|
||||
/// it will have the same length as it had when the function was called.
|
||||
pub fn gcd(rma: *Mutable, x: Const, y: Const, limbs_buffer: *std.ArrayList(Limb)) !void {
|
||||
const prev_len = limbs_buffer.items.len;
|
||||
defer limbs_buffer.shrinkAndFree(prev_len);
|
||||
defer limbs_buffer.shrinkRetainingCapacity(prev_len);
|
||||
const x_copy = if (rma.limbs.ptr == x.limbs.ptr) blk: {
|
||||
const start = limbs_buffer.items.len;
|
||||
try limbs_buffer.appendSlice(x.limbs);
|
||||
|
||||
@@ -1205,13 +1205,13 @@ fn linuxLookupNameFromDnsSearch(
|
||||
|
||||
var tok_it = mem.tokenize(search, " \t");
|
||||
while (tok_it.next()) |tok| {
|
||||
canon.shrinkAndFree(canon_name.len + 1);
|
||||
canon.shrinkRetainingCapacity(canon_name.len + 1);
|
||||
try canon.appendSlice(tok);
|
||||
try linuxLookupNameFromDns(addrs, canon, canon.items, family, rc, port);
|
||||
if (addrs.items.len != 0) return;
|
||||
}
|
||||
|
||||
canon.shrinkAndFree(canon_name.len);
|
||||
canon.shrinkRetainingCapacity(canon_name.len);
|
||||
return linuxLookupNameFromDns(addrs, canon, name, family, rc, port);
|
||||
}
|
||||
|
||||
@@ -1621,6 +1621,9 @@ pub const Stream = struct {
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO in evented I/O mode, this implementation incorrectly uses the event loop's
|
||||
/// file system thread instead of non-blocking. It needs to be reworked to properly
|
||||
/// use non-blocking I/O.
|
||||
pub fn write(self: Stream, buffer: []const u8) WriteError!usize {
|
||||
if (std.Target.current.os.tag == .windows) {
|
||||
return os.windows.WriteFile(self.handle, buffer, null, io.default_mode);
|
||||
@@ -1632,6 +1635,40 @@ pub const Stream = struct {
|
||||
return os.write(self.handle, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
/// See equivalent function: `std.fs.File.writev`.
|
||||
pub fn writev(self: Stream, iovecs: []const os.iovec_const) WriteError!usize {
|
||||
if (std.io.is_async) {
|
||||
// TODO improve to actually take advantage of writev syscall, if available.
|
||||
if (iovecs.len == 0) return 0;
|
||||
const first_buffer = iovecs[0].iov_base[0..iovecs[0].iov_len];
|
||||
try self.write(first_buffer);
|
||||
return first_buffer.len;
|
||||
} else {
|
||||
return os.writev(self.handle, iovecs);
|
||||
}
|
||||
}
|
||||
|
||||
/// The `iovecs` parameter is mutable because this function needs to mutate the fields in
|
||||
/// order to handle partial writes from the underlying OS layer.
|
||||
/// See https://github.com/ziglang/zig/issues/7699
|
||||
/// See equivalent function: `std.fs.File.writevAll`.
|
||||
pub fn writevAll(self: Stream, iovecs: []os.iovec_const) WriteError!void {
|
||||
if (iovecs.len == 0) return;
|
||||
|
||||
var i: usize = 0;
|
||||
while (true) {
|
||||
var amt = try self.writev(iovecs[i..]);
|
||||
while (amt >= iovecs[i].iov_len) {
|
||||
amt -= iovecs[i].iov_len;
|
||||
i += 1;
|
||||
if (i >= iovecs.len) return;
|
||||
}
|
||||
iovecs[i].iov_base += amt;
|
||||
iovecs[i].iov_len -= amt;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const StreamServer = struct {
|
||||
|
||||
@@ -1634,6 +1634,92 @@ pub fn symlinkatZ(target_path: [*:0]const u8, newdirfd: fd_t, sym_link_path: [*:
|
||||
}
|
||||
}
|
||||
|
||||
pub const LinkError = UnexpectedError || error{
|
||||
AccessDenied,
|
||||
DiskQuota,
|
||||
PathAlreadyExists,
|
||||
FileSystem,
|
||||
SymLinkLoop,
|
||||
LinkQuotaExceeded,
|
||||
NameTooLong,
|
||||
FileNotFound,
|
||||
SystemResources,
|
||||
NoSpaceLeft,
|
||||
ReadOnlyFileSystem,
|
||||
NotSameFileSystem,
|
||||
};
|
||||
|
||||
pub fn linkZ(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) LinkError!void {
|
||||
switch (errno(system.link(oldpath, newpath, flags))) {
|
||||
0 => return,
|
||||
EACCES => return error.AccessDenied,
|
||||
EDQUOT => return error.DiskQuota,
|
||||
EEXIST => return error.PathAlreadyExists,
|
||||
EFAULT => unreachable,
|
||||
EIO => return error.FileSystem,
|
||||
ELOOP => return error.SymLinkLoop,
|
||||
EMLINK => return error.LinkQuotaExceeded,
|
||||
ENAMETOOLONG => return error.NameTooLong,
|
||||
ENOENT => return error.FileNotFound,
|
||||
ENOMEM => return error.SystemResources,
|
||||
ENOSPC => return error.NoSpaceLeft,
|
||||
EPERM => return error.AccessDenied,
|
||||
EROFS => return error.ReadOnlyFileSystem,
|
||||
EXDEV => return error.NotSameFileSystem,
|
||||
EINVAL => unreachable,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn link(oldpath: []const u8, newpath: []const u8, flags: i32) LinkError!void {
|
||||
const old = try toPosixPath(oldpath);
|
||||
const new = try toPosixPath(newpath);
|
||||
return try linkZ(&old, &new, flags);
|
||||
}
|
||||
|
||||
pub const LinkatError = LinkError || error{NotDir};
|
||||
|
||||
pub fn linkatZ(
|
||||
olddir: fd_t,
|
||||
oldpath: [*:0]const u8,
|
||||
newdir: fd_t,
|
||||
newpath: [*:0]const u8,
|
||||
flags: i32,
|
||||
) LinkatError!void {
|
||||
switch (errno(system.linkat(olddir, oldpath, newdir, newpath, flags))) {
|
||||
0 => return,
|
||||
EACCES => return error.AccessDenied,
|
||||
EDQUOT => return error.DiskQuota,
|
||||
EEXIST => return error.PathAlreadyExists,
|
||||
EFAULT => unreachable,
|
||||
EIO => return error.FileSystem,
|
||||
ELOOP => return error.SymLinkLoop,
|
||||
EMLINK => return error.LinkQuotaExceeded,
|
||||
ENAMETOOLONG => return error.NameTooLong,
|
||||
ENOENT => return error.FileNotFound,
|
||||
ENOMEM => return error.SystemResources,
|
||||
ENOSPC => return error.NoSpaceLeft,
|
||||
ENOTDIR => return error.NotDir,
|
||||
EPERM => return error.AccessDenied,
|
||||
EROFS => return error.ReadOnlyFileSystem,
|
||||
EXDEV => return error.NotSameFileSystem,
|
||||
EINVAL => unreachable,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linkat(
|
||||
olddir: fd_t,
|
||||
oldpath: []const u8,
|
||||
newdir: fd_t,
|
||||
newpath: []const u8,
|
||||
flags: i32,
|
||||
) LinkatError!void {
|
||||
const old = try toPosixPath(oldpath);
|
||||
const new = try toPosixPath(newpath);
|
||||
return try linkatZ(olddir, &old, newdir, &new, flags);
|
||||
}
|
||||
|
||||
pub const UnlinkError = error{
|
||||
FileNotFound,
|
||||
|
||||
|
||||
@@ -412,6 +412,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
breakpoint = 0x0f0001,
|
||||
cacheflush = 0x0f0002,
|
||||
|
||||
@@ -313,6 +313,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -448,6 +448,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -430,6 +430,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = Linux + 438,
|
||||
faccessat2 = Linux + 439,
|
||||
process_madvise = Linux + 440,
|
||||
epoll_pwait2 = Linux + 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -409,6 +409,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -310,6 +310,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -387,6 +387,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -375,6 +375,7 @@ pub const SYS = extern enum(usize) {
|
||||
pidfd_getfd = 438,
|
||||
faccessat2 = 439,
|
||||
process_madvise = 440,
|
||||
epoll_pwait2 = 441,
|
||||
|
||||
_,
|
||||
};
|
||||
|
||||
@@ -634,6 +634,37 @@ pub fn tgkill(tgid: pid_t, tid: pid_t, sig: i32) usize {
|
||||
return syscall2(.tgkill, @bitCast(usize, @as(isize, tgid)), @bitCast(usize, @as(isize, tid)), @bitCast(usize, @as(isize, sig)));
|
||||
}
|
||||
|
||||
pub fn link(oldpath: [*:0]const u8, newpath: [*:0]const u8, flags: i32) usize {
|
||||
if (@hasField(SYS, "link")) {
|
||||
return syscall3(
|
||||
.link,
|
||||
@ptrToInt(oldpath),
|
||||
@ptrToInt(newpath),
|
||||
@bitCast(usize, @as(isize, flags)),
|
||||
);
|
||||
} else {
|
||||
return syscall5(
|
||||
.linkat,
|
||||
@bitCast(usize, @as(isize, AT_FDCWD)),
|
||||
@ptrToInt(oldpath),
|
||||
@bitCast(usize, @as(isize, AT_FDCWD)),
|
||||
@ptrToInt(newpath),
|
||||
@bitCast(usize, @as(isize, flags)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn linkat(oldfd: fd_t, oldpath: [*:0]const u8, newfd: fd_t, newpath: [*:0]const u8, flags: i32) usize {
|
||||
return syscall5(
|
||||
.linkat,
|
||||
@bitCast(usize, @as(isize, oldfd)),
|
||||
@ptrToInt(oldpath),
|
||||
@bitCast(usize, @as(isize, newfd)),
|
||||
@ptrToInt(newpath),
|
||||
@bitCast(usize, @as(isize, flags)),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn unlink(path: [*:0]const u8) usize {
|
||||
if (@hasField(SYS, "unlink")) {
|
||||
return syscall1(.unlink, @ptrToInt(path));
|
||||
|
||||
@@ -189,6 +189,75 @@ fn testReadlink(target_path: []const u8, symlink_path: []const u8) !void {
|
||||
expect(mem.eql(u8, target_path, given));
|
||||
}
|
||||
|
||||
test "link with relative paths" {
|
||||
if (builtin.os.tag != .linux) return error.SkipZigTest;
|
||||
var cwd = fs.cwd();
|
||||
|
||||
cwd.deleteFile("example.txt") catch {};
|
||||
cwd.deleteFile("new.txt") catch {};
|
||||
|
||||
try cwd.writeFile("example.txt", "example");
|
||||
try os.link("example.txt", "new.txt", 0);
|
||||
|
||||
const efd = try cwd.openFile("example.txt", .{});
|
||||
defer efd.close();
|
||||
|
||||
const nfd = try cwd.openFile("new.txt", .{});
|
||||
defer nfd.close();
|
||||
|
||||
{
|
||||
const estat = try os.fstat(efd.handle);
|
||||
const nstat = try os.fstat(nfd.handle);
|
||||
|
||||
testing.expectEqual(estat.ino, nstat.ino);
|
||||
testing.expectEqual(@as(usize, 2), nstat.nlink);
|
||||
}
|
||||
|
||||
try os.unlink("new.txt");
|
||||
|
||||
{
|
||||
const estat = try os.fstat(efd.handle);
|
||||
testing.expectEqual(@as(usize, 1), estat.nlink);
|
||||
}
|
||||
|
||||
try cwd.deleteFile("example.txt");
|
||||
}
|
||||
|
||||
test "linkat with different directories" {
|
||||
if (builtin.os.tag != .linux) return error.SkipZigTest;
|
||||
var cwd = fs.cwd();
|
||||
var tmp = tmpDir(.{});
|
||||
|
||||
cwd.deleteFile("example.txt") catch {};
|
||||
tmp.dir.deleteFile("new.txt") catch {};
|
||||
|
||||
try cwd.writeFile("example.txt", "example");
|
||||
try os.linkat(cwd.fd, "example.txt", tmp.dir.fd, "new.txt", 0);
|
||||
|
||||
const efd = try cwd.openFile("example.txt", .{});
|
||||
defer efd.close();
|
||||
|
||||
const nfd = try tmp.dir.openFile("new.txt", .{});
|
||||
|
||||
{
|
||||
defer nfd.close();
|
||||
const estat = try os.fstat(efd.handle);
|
||||
const nstat = try os.fstat(nfd.handle);
|
||||
|
||||
testing.expectEqual(estat.ino, nstat.ino);
|
||||
testing.expectEqual(@as(usize, 2), nstat.nlink);
|
||||
}
|
||||
|
||||
try os.unlinkat(tmp.dir.fd, "new.txt", 0);
|
||||
|
||||
{
|
||||
const estat = try os.fstat(efd.handle);
|
||||
testing.expectEqual(@as(usize, 1), estat.nlink);
|
||||
}
|
||||
|
||||
try cwd.deleteFile("example.txt");
|
||||
}
|
||||
|
||||
test "fstatat" {
|
||||
// enable when `fstat` and `fstatat` are implemented on Windows
|
||||
if (builtin.os.tag == .windows) return error.SkipZigTest;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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");
|
||||
|
||||
/// A protocol is an interface identified by a GUID.
|
||||
pub const protocols = @import("uefi/protocols.zig");
|
||||
|
||||
@@ -33,10 +35,10 @@ pub const Guid = extern struct {
|
||||
self: @This(),
|
||||
comptime f: []const u8,
|
||||
options: std.fmt.FormatOptions,
|
||||
out_stream: anytype,
|
||||
) Errors!void {
|
||||
writer: anytype,
|
||||
) !void {
|
||||
if (f.len == 0) {
|
||||
return std.fmt.format(out_stream, "{x:0>8}-{x:0>4}-{x:0>4}-{x:0>2}{x:0>2}-{x:0>12}", .{
|
||||
return std.fmt.format(writer, "{x:0>8}-{x:0>4}-{x:0>4}-{x:0>2}{x:0>2}-{x:0>12}", .{
|
||||
self.time_low,
|
||||
self.time_mid,
|
||||
self.time_high_and_version,
|
||||
@@ -48,6 +50,15 @@ pub const Guid = extern struct {
|
||||
@compileError("Unknown format character: '" ++ f ++ "'");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eql(a: std.os.uefi.Guid, b: std.os.uefi.Guid) bool {
|
||||
return a.time_low == b.time_low and
|
||||
a.time_mid == b.time_mid and
|
||||
a.time_high_and_version == b.time_high_and_version and
|
||||
a.clock_seq_high_and_reserved == b.clock_seq_high_and_reserved and
|
||||
a.clock_seq_low == b.clock_seq_low and
|
||||
std.mem.eql(u8, &a.node, &b.node);
|
||||
}
|
||||
};
|
||||
|
||||
/// An EFI Handle represents a collection of related interfaces.
|
||||
|
||||
@@ -253,6 +253,20 @@ pub fn section(val: Section) u8 {
|
||||
return @enumToInt(val);
|
||||
}
|
||||
|
||||
/// The kind of the type when importing or exporting to/from the host environment
|
||||
/// https://webassembly.github.io/spec/core/syntax/modules.html
|
||||
pub const ExternalKind = enum(u8) {
|
||||
function,
|
||||
table,
|
||||
memory,
|
||||
global,
|
||||
};
|
||||
|
||||
/// Returns the integer value of a given `ExternalKind`
|
||||
pub fn externalKind(val: ExternalKind) u8 {
|
||||
return @enumToInt(val);
|
||||
}
|
||||
|
||||
// types
|
||||
pub const element_type: u8 = 0x70;
|
||||
pub const function_type: u8 = 0x60;
|
||||
|
||||
@@ -648,7 +648,7 @@ test "zig fmt: struct literal 1 element" {
|
||||
);
|
||||
}
|
||||
|
||||
test "zig fmt: struct literal 1 element comma" {
|
||||
test "zig fmt: Unicode code point literal larger than u8" {
|
||||
try testCanonical(
|
||||
\\test {
|
||||
\\ const x = X{
|
||||
|
||||
@@ -1535,7 +1535,7 @@ test "tokenizer - unknown length pointer and then c pointer" {
|
||||
});
|
||||
}
|
||||
|
||||
test "tokenizer - char literal with hex escape" {
|
||||
test "tokenizer - code point literal with hex escape" {
|
||||
testTokenize(
|
||||
\\'\x1b'
|
||||
, &.{.char_literal});
|
||||
@@ -1544,7 +1544,7 @@ test "tokenizer - char literal with hex escape" {
|
||||
, &.{ .invalid, .invalid });
|
||||
}
|
||||
|
||||
test "tokenizer - char literal with unicode escapes" {
|
||||
test "tokenizer - code point literal with unicode escapes" {
|
||||
// Valid unicode escapes
|
||||
testTokenize(
|
||||
\\'\u{3}'
|
||||
@@ -1594,7 +1594,7 @@ test "tokenizer - char literal with unicode escapes" {
|
||||
, &.{ .invalid, .integer_literal, .invalid });
|
||||
}
|
||||
|
||||
test "tokenizer - char literal with unicode code point" {
|
||||
test "tokenizer - code point literal with unicode code point" {
|
||||
testTokenize(
|
||||
\\'💩'
|
||||
, &.{.char_literal});
|
||||
|
||||
Reference in New Issue
Block a user