authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-12 13:12:56-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:09-08:00
log6484101f7860988d2147b519c0c53b9fdc23b7c2
tree0a8a0e33a90bd8213b2cb542f0c5fc8d81d1c754
parent1ed845e1f6fabdde8795513de2d06bc9b573779c

update occurences of std.fs.openDirAbsolute


4 files changed, 146 insertions(+), 146 deletions(-)

lib/compiler/aro/aro/Diagnostics.zig+1-1
......@@ -292,7 +292,7 @@ const Diagnostics = @This();
292292output: union(enum) {
293293 to_writer: struct {
294294 writer: *std.Io.Writer,
295 color: std.Io.tty.Config,
295 color: std.Io.File.Writer.Mode,
296296 },
297297 to_list: struct {
298298 messages: std.ArrayList(Message) = .empty,
lib/std/crypto/Certificate/Bundle.zig+3-3
......@@ -9,8 +9,8 @@ const builtin = @import("builtin");
99
1010const std = @import("../../std.zig");
1111const Io = std.Io;
12const Dir = std.Io.Dir;
1213const assert = std.debug.assert;
13const fs = std.fs;
1414const mem = std.mem;
1515const crypto = std.crypto;
1616const Allocator = std.mem.Allocator;
......@@ -192,8 +192,8 @@ pub fn addCertsFromDirPathAbsolute(
192192 now: Io.Timestamp,
193193 abs_dir_path: []const u8,
194194) AddCertsFromDirPathError!void {
195 assert(fs.path.isAbsolute(abs_dir_path));
196 var iterable_dir = try fs.openDirAbsolute(abs_dir_path, .{ .iterate = true });
195 assert(Dir.path.isAbsolute(abs_dir_path));
196 var iterable_dir = try Dir.openDirAbsolute(io, abs_dir_path, .{ .iterate = true });
197197 defer iterable_dir.close(io);
198198 return addCertsFromDir(cb, gpa, io, now, iterable_dir);
199199}
lib/std/fs/test.zig+6-6
......@@ -346,7 +346,7 @@ test "openDirAbsolute" {
346346 defer testing.allocator.free(sub_path);
347347
348348 // Can open sub_path
349 var tmp_sub = try fs.openDirAbsolute(sub_path, .{});
349 var tmp_sub = try Dir.openDirAbsolute(io, sub_path, .{});
350350 defer tmp_sub.close(io);
351351
352352 const sub_ino = (try tmp_sub.stat(io)).inode;
......@@ -356,7 +356,7 @@ test "openDirAbsolute" {
356356 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".." });
357357 defer testing.allocator.free(dir_path);
358358
359 var dir = try fs.openDirAbsolute(dir_path, .{});
359 var dir = try Dir.openDirAbsolute(io, dir_path, .{});
360360 defer dir.close(io);
361361
362362 const ino = (try dir.stat(io)).inode;
......@@ -368,7 +368,7 @@ test "openDirAbsolute" {
368368 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, "." });
369369 defer testing.allocator.free(dir_path);
370370
371 var dir = try fs.openDirAbsolute(dir_path, .{});
371 var dir = try Dir.openDirAbsolute(io, dir_path, .{});
372372 defer dir.close(io);
373373
374374 const ino = (try dir.stat(io)).inode;
......@@ -380,7 +380,7 @@ test "openDirAbsolute" {
380380 const dir_path = try fs.path.join(testing.allocator, &.{ sub_path, ".", "..", "." });
381381 defer testing.allocator.free(dir_path);
382382
383 var dir = try fs.openDirAbsolute(dir_path, .{});
383 var dir = try Dir.openDirAbsolute(io, dir_path, .{});
384384 defer dir.close(io);
385385
386386 const ino = (try dir.stat(io)).inode;
......@@ -1978,7 +1978,7 @@ test "'.' and '..' in absolute functions" {
19781978 const subdir_path = try fs.path.join(allocator, &.{ base_path, "./subdir" });
19791979 try fs.makeDirAbsolute(subdir_path);
19801980 try fs.accessAbsolute(subdir_path, .{});
1981 var created_subdir = try fs.openDirAbsolute(subdir_path, .{});
1981 var created_subdir = try Dir.openDirAbsolute(io, subdir_path, .{});
19821982 created_subdir.close(io);
19831983
19841984 const created_file_path = try fs.path.join(allocator, &.{ subdir_path, "../file" });
......@@ -2108,7 +2108,7 @@ test "invalid UTF-8/WTF-8 paths" {
21082108 try expectError(expected_err, Dir.makeDirAbsolute(invalid_path));
21092109 try expectError(expected_err, Dir.deleteDirAbsolute(invalid_path));
21102110 try expectError(expected_err, Dir.renameAbsolute(invalid_path, invalid_path));
2111 try expectError(expected_err, Dir.openDirAbsolute(invalid_path, .{}));
2111 try expectError(expected_err, Dir.openDirAbsolute(io, invalid_path, .{}));
21122112 try expectError(expected_err, Dir.openFileAbsolute(invalid_path, .{}));
21132113 try expectError(expected_err, Dir.accessAbsolute(invalid_path, .{}));
21142114 try expectError(expected_err, Dir.createFileAbsolute(invalid_path, .{}));
lib/std/zig/WindowsSdk.zig+136-136
......@@ -3,6 +3,7 @@ const builtin = @import("builtin");
33
44const std = @import("std");
55const Io = std.Io;
6const Dir = std.Io.Dir;
67const Writer = std.Io.Writer;
78const Allocator = std.mem.Allocator;
89
......@@ -22,8 +23,8 @@ const product_version_max_length = version_major_minor_max_length + ".65535".len
2223
2324/// Find path and version of Windows 10 SDK and Windows 8.1 SDK, and find path to MSVC's `lib/` directory.
2425/// Caller owns the result's fields.
25/// After finishing work, call `free(allocator)`.
26pub fn find(allocator: Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, NotFound, PathTooLong }!WindowsSdk {
26/// Returns memory allocated by `gpa`
27pub fn find(gpa: Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory, NotFound, PathTooLong }!WindowsSdk {
2728 if (builtin.os.tag != .windows) return error.NotFound;
2829
2930 //note(dimenus): If this key doesn't exist, neither the Win 8 SDK nor the Win 10 SDK is installed
......@@ -32,27 +33,27 @@ pub fn find(allocator: Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory,
3233 };
3334 defer roots_key.closeKey();
3435
35 const windows10sdk = Installation.find(allocator, roots_key, "KitsRoot10", "", "v10.0") catch |err| switch (err) {
36 const windows10sdk = Installation.find(gpa, roots_key, "KitsRoot10", "", "v10.0") catch |err| switch (err) {
3637 error.InstallationNotFound => null,
3738 error.PathTooLong => null,
3839 error.VersionTooLong => null,
3940 error.OutOfMemory => return error.OutOfMemory,
4041 };
41 errdefer if (windows10sdk) |*w| w.free(allocator);
42 errdefer if (windows10sdk) |*w| w.free(gpa);
4243
43 const windows81sdk = Installation.find(allocator, roots_key, "KitsRoot81", "winver", "v8.1") catch |err| switch (err) {
44 const windows81sdk = Installation.find(gpa, roots_key, "KitsRoot81", "winver", "v8.1") catch |err| switch (err) {
4445 error.InstallationNotFound => null,
4546 error.PathTooLong => null,
4647 error.VersionTooLong => null,
4748 error.OutOfMemory => return error.OutOfMemory,
4849 };
49 errdefer if (windows81sdk) |*w| w.free(allocator);
50 errdefer if (windows81sdk) |*w| w.free(gpa);
5051
51 const msvc_lib_dir: ?[]const u8 = MsvcLibDir.find(allocator, arch) catch |err| switch (err) {
52 const msvc_lib_dir: ?[]const u8 = MsvcLibDir.find(gpa, arch) catch |err| switch (err) {
5253 error.MsvcLibDirNotFound => null,
5354 error.OutOfMemory => return error.OutOfMemory,
5455 };
55 errdefer allocator.free(msvc_lib_dir);
56 errdefer gpa.free(msvc_lib_dir);
5657
5758 return .{
5859 .windows10sdk = windows10sdk,
......@@ -61,15 +62,15 @@ pub fn find(allocator: Allocator, arch: std.Target.Cpu.Arch) error{ OutOfMemory,
6162 };
6263}
6364
64pub fn free(sdk: WindowsSdk, allocator: Allocator) void {
65pub fn free(sdk: WindowsSdk, gpa: Allocator) void {
6566 if (sdk.windows10sdk) |*w10sdk| {
66 w10sdk.free(allocator);
67 w10sdk.free(gpa);
6768 }
6869 if (sdk.windows81sdk) |*w81sdk| {
69 w81sdk.free(allocator);
70 w81sdk.free(gpa);
7071 }
7172 if (sdk.msvc_lib_dir) |msvc_lib_dir| {
72 allocator.free(msvc_lib_dir);
73 gpa.free(msvc_lib_dir);
7374 }
7475}
7576
......@@ -77,8 +78,8 @@ pub fn free(sdk: WindowsSdk, allocator: Allocator) void {
7778/// and a version. Returns slice of version strings sorted in descending order.
7879/// Caller owns result.
7980fn iterateAndFilterByVersion(
80 iterator: *Io.Dir.Iterator,
81 allocator: Allocator,
81 iterator: *Dir.Iterator,
82 gpa: Allocator,
8283 prefix: []const u8,
8384) error{OutOfMemory}![][]const u8 {
8485 const Version = struct {
......@@ -95,11 +96,11 @@ fn iterateAndFilterByVersion(
9596 std.mem.order(u8, lhs.build, rhs.build);
9697 }
9798 };
98 var versions = std.array_list.Managed(Version).init(allocator);
99 var dirs = std.array_list.Managed([]const u8).init(allocator);
99 var versions = std.array_list.Managed(Version).init(gpa);
100 var dirs = std.array_list.Managed([]const u8).init(gpa);
100101 defer {
101102 versions.deinit();
102 for (dirs.items) |filtered_dir| allocator.free(filtered_dir);
103 for (dirs.items) |filtered_dir| gpa.free(filtered_dir);
103104 dirs.deinit();
104105 }
105106
......@@ -119,8 +120,8 @@ fn iterateAndFilterByVersion(
119120 num.* = Version.parseNum(num_it.next() orelse break) orelse continue :iterate
120121 else if (num_it.next()) |_| continue;
121122
122 const name = try allocator.dupe(u8, suffix);
123 errdefer allocator.free(name);
123 const name = try gpa.dupe(u8, suffix);
124 errdefer gpa.free(name);
124125 if (underscore) |pos| version.build = name[pos + 1 ..];
125126
126127 try versions.append(version);
......@@ -177,7 +178,7 @@ const RegistryWtf8 = struct {
177178
178179 /// Get string from registry.
179180 /// Caller owns result.
180 pub fn getString(reg: RegistryWtf8, allocator: Allocator, subkey: []const u8, value_name: []const u8) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]u8 {
181 pub fn getString(reg: RegistryWtf8, gpa: Allocator, subkey: []const u8, value_name: []const u8) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]u8 {
181182 const subkey_wtf16le: [:0]const u16 = subkey_wtf16le: {
182183 var subkey_wtf16le_buf: [RegistryWtf16Le.key_name_max_len]u16 = undefined;
183184 const subkey_wtf16le_len: usize = std.unicode.wtf8ToWtf16Le(subkey_wtf16le_buf[0..], subkey) catch unreachable;
......@@ -193,11 +194,11 @@ const RegistryWtf8 = struct {
193194 };
194195
195196 const registry_wtf16le: RegistryWtf16Le = .{ .key = reg.key };
196 const value_wtf16le = try registry_wtf16le.getString(allocator, subkey_wtf16le, value_name_wtf16le);
197 defer allocator.free(value_wtf16le);
197 const value_wtf16le = try registry_wtf16le.getString(gpa, subkey_wtf16le, value_name_wtf16le);
198 defer gpa.free(value_wtf16le);
198199
199 const value_wtf8: []u8 = try std.unicode.wtf16LeToWtf8Alloc(allocator, value_wtf16le);
200 errdefer allocator.free(value_wtf8);
200 const value_wtf8: []u8 = try std.unicode.wtf16LeToWtf8Alloc(gpa, value_wtf16le);
201 errdefer gpa.free(value_wtf8);
201202
202203 return value_wtf8;
203204 }
......@@ -285,7 +286,7 @@ const RegistryWtf16Le = struct {
285286 }
286287
287288 /// Get string ([:0]const u16) from registry.
288 fn getString(reg: RegistryWtf16Le, allocator: Allocator, subkey_wtf16le: [:0]const u16, value_name_wtf16le: [:0]const u16) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]const u16 {
289 fn getString(reg: RegistryWtf16Le, gpa: Allocator, subkey_wtf16le: [:0]const u16, value_name_wtf16le: [:0]const u16) error{ OutOfMemory, ValueNameNotFound, NotAString, StringNotFound }![]const u16 {
289290 var actual_type: windows.ULONG = undefined;
290291
291292 // Calculating length to allocate
......@@ -314,8 +315,8 @@ const RegistryWtf16Le = struct {
314315 else => return error.NotAString,
315316 }
316317
317 const value_wtf16le_buf: []u16 = try allocator.alloc(u16, std.math.divCeil(u32, value_wtf16le_buf_size, 2) catch unreachable);
318 errdefer allocator.free(value_wtf16le_buf);
318 const value_wtf16le_buf: []u16 = try gpa.alloc(u16, std.math.divCeil(u32, value_wtf16le_buf_size, 2) catch unreachable);
319 errdefer gpa.free(value_wtf16le_buf);
319320
320321 return_code_int = windows.advapi32.RegGetValueW(
321322 reg.key,
......@@ -349,7 +350,7 @@ const RegistryWtf16Le = struct {
349350 break :value_wtf16le std.mem.span(value_wtf16le_overestimated);
350351 };
351352
352 _ = allocator.resize(value_wtf16le_buf, value_wtf16le.len);
353 _ = gpa.resize(value_wtf16le_buf, value_wtf16le.len);
353354 return value_wtf16le;
354355 }
355356
......@@ -417,66 +418,65 @@ pub const Installation = struct {
417418
418419 /// Find path and version of Windows SDK.
419420 /// Caller owns the result's fields.
420 /// After finishing work, call `free(allocator)`.
421421 fn find(
422 allocator: Allocator,
422 gpa: Allocator,
423423 roots_key: RegistryWtf8,
424424 roots_subkey: []const u8,
425425 prefix: []const u8,
426426 version_key_name: []const u8,
427427 ) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation {
428428 roots: {
429 const installation = findFromRoot(allocator, roots_key, roots_subkey, prefix) catch
429 const installation = findFromRoot(gpa, roots_key, roots_subkey, prefix) catch
430430 break :roots;
431431 if (installation.isValidVersion()) return installation;
432 installation.free(allocator);
432 installation.free(gpa);
433433 }
434434 {
435 const installation = try findFromInstallationFolder(allocator, version_key_name);
435 const installation = try findFromInstallationFolder(gpa, version_key_name);
436436 if (installation.isValidVersion()) return installation;
437 installation.free(allocator);
437 installation.free(gpa);
438438 }
439439 return error.InstallationNotFound;
440440 }
441441
442442 fn findFromRoot(
443 allocator: Allocator,
443 gpa: Allocator,
444444 io: Io,
445445 roots_key: RegistryWtf8,
446446 roots_subkey: []const u8,
447447 prefix: []const u8,
448448 ) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation {
449449 const path = path: {
450 const path_maybe_with_trailing_slash = roots_key.getString(allocator, "", roots_subkey) catch |err| switch (err) {
450 const path_maybe_with_trailing_slash = roots_key.getString(gpa, "", roots_subkey) catch |err| switch (err) {
451451 error.NotAString => return error.InstallationNotFound,
452452 error.ValueNameNotFound => return error.InstallationNotFound,
453453 error.StringNotFound => return error.InstallationNotFound,
454454
455455 error.OutOfMemory => return error.OutOfMemory,
456456 };
457 if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
458 allocator.free(path_maybe_with_trailing_slash);
457 if (path_maybe_with_trailing_slash.len > Dir.max_path_bytes or !Dir.path.isAbsolute(path_maybe_with_trailing_slash)) {
458 gpa.free(path_maybe_with_trailing_slash);
459459 return error.PathTooLong;
460460 }
461461
462 var path = std.array_list.Managed(u8).fromOwnedSlice(allocator, path_maybe_with_trailing_slash);
462 var path = std.array_list.Managed(u8).fromOwnedSlice(gpa, path_maybe_with_trailing_slash);
463463 errdefer path.deinit();
464464
465465 // String might contain trailing slash, so trim it here
466466 if (path.items.len > "C:\\".len and path.getLast() == '\\') _ = path.pop();
467467 break :path try path.toOwnedSlice();
468468 };
469 errdefer allocator.free(path);
469 errdefer gpa.free(path);
470470
471471 const version = version: {
472 var buf: [std.fs.max_path_bytes]u8 = undefined;
472 var buf: [Dir.max_path_bytes]u8 = undefined;
473473 const sdk_lib_dir_path = std.fmt.bufPrint(buf[0..], "{s}\\Lib\\", .{path}) catch |err| switch (err) {
474474 error.NoSpaceLeft => return error.PathTooLong,
475475 };
476 if (!std.fs.path.isAbsolute(sdk_lib_dir_path)) return error.InstallationNotFound;
476 if (!Dir.path.isAbsolute(sdk_lib_dir_path)) return error.InstallationNotFound;
477477
478478 // enumerate files in sdk path looking for latest version
479 var sdk_lib_dir = std.fs.openDirAbsolute(sdk_lib_dir_path, .{
479 var sdk_lib_dir = Dir.openDirAbsolute(io, sdk_lib_dir_path, .{
480480 .iterate = true,
481481 }) catch |err| switch (err) {
482482 error.NameTooLong => return error.PathTooLong,
......@@ -485,21 +485,21 @@ pub const Installation = struct {
485485 defer sdk_lib_dir.close(io);
486486
487487 var iterator = sdk_lib_dir.iterate();
488 const versions = try iterateAndFilterByVersion(&iterator, allocator, prefix);
488 const versions = try iterateAndFilterByVersion(&iterator, gpa, prefix);
489489 if (versions.len == 0) return error.InstallationNotFound;
490490 defer {
491 for (versions[1..]) |version| allocator.free(version);
492 allocator.free(versions);
491 for (versions[1..]) |version| gpa.free(version);
492 gpa.free(versions);
493493 }
494494 break :version versions[0];
495495 };
496 errdefer allocator.free(version);
496 errdefer gpa.free(version);
497497
498498 return .{ .path = path, .version = version };
499499 }
500500
501501 fn findFromInstallationFolder(
502 allocator: Allocator,
502 gpa: Allocator,
503503 version_key_name: []const u8,
504504 ) error{ OutOfMemory, InstallationNotFound, PathTooLong, VersionTooLong }!Installation {
505505 var key_name_buf: [RegistryWtf16Le.key_name_max_len]u8 = undefined;
......@@ -518,7 +518,7 @@ pub const Installation = struct {
518518 defer key.closeKey();
519519
520520 const path: []const u8 = path: {
521 const path_maybe_with_trailing_slash = key.getString(allocator, "", "InstallationFolder") catch |err| switch (err) {
521 const path_maybe_with_trailing_slash = key.getString(gpa, "", "InstallationFolder") catch |err| switch (err) {
522522 error.NotAString => return error.InstallationNotFound,
523523 error.ValueNameNotFound => return error.InstallationNotFound,
524524 error.StringNotFound => return error.InstallationNotFound,
......@@ -526,12 +526,12 @@ pub const Installation = struct {
526526 error.OutOfMemory => return error.OutOfMemory,
527527 };
528528
529 if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
530 allocator.free(path_maybe_with_trailing_slash);
529 if (path_maybe_with_trailing_slash.len > Dir.max_path_bytes or !Dir.path.isAbsolute(path_maybe_with_trailing_slash)) {
530 gpa.free(path_maybe_with_trailing_slash);
531531 return error.PathTooLong;
532532 }
533533
534 var path = std.array_list.Managed(u8).fromOwnedSlice(allocator, path_maybe_with_trailing_slash);
534 var path = std.array_list.Managed(u8).fromOwnedSlice(gpa, path_maybe_with_trailing_slash);
535535 errdefer path.deinit();
536536
537537 // String might contain trailing slash, so trim it here
......@@ -540,12 +540,12 @@ pub const Installation = struct {
540540 const path_without_trailing_slash = try path.toOwnedSlice();
541541 break :path path_without_trailing_slash;
542542 };
543 errdefer allocator.free(path);
543 errdefer gpa.free(path);
544544
545545 const version: []const u8 = version: {
546546
547547 // note(dimenus): Microsoft doesn't include the .0 in the ProductVersion key....
548 const version_without_0 = key.getString(allocator, "", "ProductVersion") catch |err| switch (err) {
548 const version_without_0 = key.getString(gpa, "", "ProductVersion") catch |err| switch (err) {
549549 error.NotAString => return error.InstallationNotFound,
550550 error.ValueNameNotFound => return error.InstallationNotFound,
551551 error.StringNotFound => return error.InstallationNotFound,
......@@ -553,11 +553,11 @@ pub const Installation = struct {
553553 error.OutOfMemory => return error.OutOfMemory,
554554 };
555555 if (version_without_0.len + ".0".len > product_version_max_length) {
556 allocator.free(version_without_0);
556 gpa.free(version_without_0);
557557 return error.VersionTooLong;
558558 }
559559
560 var version = std.array_list.Managed(u8).fromOwnedSlice(allocator, version_without_0);
560 var version = std.array_list.Managed(u8).fromOwnedSlice(gpa, version_without_0);
561561 errdefer version.deinit();
562562
563563 try version.appendSlice(".0");
......@@ -565,14 +565,14 @@ pub const Installation = struct {
565565 const version_with_0 = try version.toOwnedSlice();
566566 break :version version_with_0;
567567 };
568 errdefer allocator.free(version);
568 errdefer gpa.free(version);
569569
570570 return .{ .path = path, .version = version };
571571 }
572572
573573 /// Check whether this version is enumerated in registry.
574574 fn isValidVersion(installation: Installation) bool {
575 var buf: [std.fs.max_path_bytes]u8 = undefined;
575 var buf: [Dir.max_path_bytes]u8 = undefined;
576576 const reg_query_as_wtf8 = std.fmt.bufPrint(buf[0..], "{s}\\{s}\\Installed Options", .{
577577 windows_kits_reg_key,
578578 installation.version,
......@@ -601,21 +601,21 @@ pub const Installation = struct {
601601 return (reg_value == 1);
602602 }
603603
604 fn free(install: Installation, allocator: Allocator) void {
605 allocator.free(install.path);
606 allocator.free(install.version);
604 fn free(install: Installation, gpa: Allocator) void {
605 gpa.free(install.path);
606 gpa.free(install.version);
607607 }
608608};
609609
610610const MsvcLibDir = struct {
611 fn findInstancesDirViaSetup(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir {
611 fn findInstancesDirViaSetup(gpa: Allocator, io: Io) error{ OutOfMemory, PathNotFound }!Dir {
612612 const vs_setup_key_path = "SOFTWARE\\Microsoft\\VisualStudio\\Setup";
613613 const vs_setup_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, vs_setup_key_path, .{}) catch |err| switch (err) {
614614 error.KeyNotFound => return error.PathNotFound,
615615 };
616616 defer vs_setup_key.closeKey();
617617
618 const packages_path = vs_setup_key.getString(allocator, "", "CachePath") catch |err| switch (err) {
618 const packages_path = vs_setup_key.getString(gpa, "", "CachePath") catch |err| switch (err) {
619619 error.NotAString,
620620 error.ValueNameNotFound,
621621 error.StringNotFound,
......@@ -623,24 +623,24 @@ const MsvcLibDir = struct {
623623
624624 error.OutOfMemory => return error.OutOfMemory,
625625 };
626 defer allocator.free(packages_path);
626 defer gpa.free(packages_path);
627627
628 if (!std.fs.path.isAbsolute(packages_path)) return error.PathNotFound;
628 if (!Dir.path.isAbsolute(packages_path)) return error.PathNotFound;
629629
630 const instances_path = try std.fs.path.join(allocator, &.{ packages_path, "_Instances" });
631 defer allocator.free(instances_path);
630 const instances_path = try Dir.path.join(gpa, &.{ packages_path, "_Instances" });
631 defer gpa.free(instances_path);
632632
633 return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound;
633 return Dir.openDirAbsolute(io, instances_path, .{ .iterate = true }) catch return error.PathNotFound;
634634 }
635635
636 fn findInstancesDirViaCLSID(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir {
636 fn findInstancesDirViaCLSID(gpa: Allocator, io: Io) error{ OutOfMemory, PathNotFound }!Dir {
637637 const setup_configuration_clsid = "{177f0c4a-1cd3-4de7-a32c-71dbbb9fa36d}";
638638 const setup_config_key = RegistryWtf8.openKey(windows.HKEY_CLASSES_ROOT, "CLSID\\" ++ setup_configuration_clsid, .{}) catch |err| switch (err) {
639639 error.KeyNotFound => return error.PathNotFound,
640640 };
641641 defer setup_config_key.closeKey();
642642
643 const dll_path = setup_config_key.getString(allocator, "InprocServer32", "") catch |err| switch (err) {
643 const dll_path = setup_config_key.getString(gpa, "InprocServer32", "") catch |err| switch (err) {
644644 error.NotAString,
645645 error.ValueNameNotFound,
646646 error.StringNotFound,
......@@ -648,11 +648,11 @@ const MsvcLibDir = struct {
648648
649649 error.OutOfMemory => return error.OutOfMemory,
650650 };
651 defer allocator.free(dll_path);
651 defer gpa.free(dll_path);
652652
653 if (!std.fs.path.isAbsolute(dll_path)) return error.PathNotFound;
653 if (!Dir.path.isAbsolute(dll_path)) return error.PathNotFound;
654654
655 var path_it = std.fs.path.componentIterator(dll_path);
655 var path_it = Dir.path.componentIterator(dll_path);
656656 // the .dll filename
657657 _ = path_it.last();
658658 const root_path = while (path_it.previous()) |dir_component| {
......@@ -663,17 +663,17 @@ const MsvcLibDir = struct {
663663 return error.PathNotFound;
664664 };
665665
666 const instances_path = try std.fs.path.join(allocator, &.{ root_path, "Packages", "_Instances" });
667 defer allocator.free(instances_path);
666 const instances_path = try Dir.path.join(gpa, &.{ root_path, "Packages", "_Instances" });
667 defer gpa.free(instances_path);
668668
669 return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch return error.PathNotFound;
669 return Dir.openDirAbsolute(io, instances_path, .{ .iterate = true }) catch return error.PathNotFound;
670670 }
671671
672 fn findInstancesDir(allocator: Allocator) error{ OutOfMemory, PathNotFound }!Io.Dir {
672 fn findInstancesDir(gpa: Allocator, io: Io) error{ OutOfMemory, PathNotFound }!Dir {
673673 // First, try getting the packages cache path from the registry.
674674 // This only seems to exist when the path is different from the default.
675675 method1: {
676 return findInstancesDirViaSetup(allocator) catch |err| switch (err) {
676 return findInstancesDirViaSetup(gpa) catch |err| switch (err) {
677677 error.OutOfMemory => |e| return e,
678678 error.PathNotFound => break :method1,
679679 };
......@@ -681,7 +681,7 @@ const MsvcLibDir = struct {
681681 // Otherwise, try to get the path from the .dll that would have been
682682 // loaded via COM for SetupConfiguration.
683683 method2: {
684 return findInstancesDirViaCLSID(allocator) catch |err| switch (err) {
684 return findInstancesDirViaCLSID(gpa, io) catch |err| switch (err) {
685685 error.OutOfMemory => |e| return e,
686686 error.PathNotFound => break :method2,
687687 };
......@@ -689,19 +689,19 @@ const MsvcLibDir = struct {
689689 // If that can't be found, fall back to manually appending
690690 // `Microsoft\VisualStudio\Packages\_Instances` to %PROGRAMDATA%
691691 method3: {
692 const program_data = std.process.getEnvVarOwned(allocator, "PROGRAMDATA") catch |err| switch (err) {
692 const program_data = std.process.getEnvVarOwned(gpa, "PROGRAMDATA") catch |err| switch (err) {
693693 error.OutOfMemory => |e| return e,
694694 error.InvalidWtf8 => unreachable,
695695 error.EnvironmentVariableNotFound => break :method3,
696696 };
697 defer allocator.free(program_data);
697 defer gpa.free(program_data);
698698
699 if (!std.fs.path.isAbsolute(program_data)) break :method3;
699 if (!Dir.path.isAbsolute(program_data)) break :method3;
700700
701 const instances_path = try std.fs.path.join(allocator, &.{ program_data, "Microsoft", "VisualStudio", "Packages", "_Instances" });
702 defer allocator.free(instances_path);
701 const instances_path = try Dir.path.join(gpa, &.{ program_data, "Microsoft", "VisualStudio", "Packages", "_Instances" });
702 defer gpa.free(instances_path);
703703
704 return std.fs.openDirAbsolute(instances_path, .{ .iterate = true }) catch break :method3;
704 return Dir.openDirAbsolute(io, instances_path, .{ .iterate = true }) catch break :method3;
705705 }
706706 return error.PathNotFound;
707707 }
......@@ -752,17 +752,17 @@ const MsvcLibDir = struct {
752752 ///
753753 /// The logic in this function is intended to match what ISetupConfiguration does
754754 /// under-the-hood, as verified using Procmon.
755 fn findViaCOM(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
755 fn findViaCOM(gpa: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
756756 // Typically `%PROGRAMDATA%\Microsoft\VisualStudio\Packages\_Instances`
757757 // This will contain directories with names of instance IDs like 80a758ca,
758758 // which will contain `state.json` files that have the version and
759759 // installation directory.
760 var instances_dir = try findInstancesDir(allocator);
760 var instances_dir = try findInstancesDir(gpa, io);
761761 defer instances_dir.close(io);
762762
763 var state_subpath_buf: [std.fs.max_name_bytes + 32]u8 = undefined;
763 var state_subpath_buf: [Dir.max_name_bytes + 32]u8 = undefined;
764764 var latest_version_lib_dir: std.ArrayList(u8) = .empty;
765 errdefer latest_version_lib_dir.deinit(allocator);
765 errdefer latest_version_lib_dir.deinit(gpa);
766766
767767 var latest_version: u64 = 0;
768768 var instances_dir_it = instances_dir.iterateAssumeFirstIteration();
......@@ -772,13 +772,13 @@ const MsvcLibDir = struct {
772772 var writer: Writer = .fixed(&state_subpath_buf);
773773
774774 writer.writeAll(entry.name) catch unreachable;
775 writer.writeByte(std.fs.path.sep) catch unreachable;
775 writer.writeByte(Dir.path.sep) catch unreachable;
776776 writer.writeAll("state.json") catch unreachable;
777777
778 const json_contents = instances_dir.readFileAlloc(io, writer.buffered(), allocator, .limited(std.math.maxInt(usize))) catch continue;
779 defer allocator.free(json_contents);
778 const json_contents = instances_dir.readFileAlloc(io, writer.buffered(), gpa, .limited(std.math.maxInt(usize))) catch continue;
779 defer gpa.free(json_contents);
780780
781 var parsed = std.json.parseFromSlice(std.json.Value, allocator, json_contents, .{}) catch continue;
781 var parsed = std.json.parseFromSlice(std.json.Value, gpa, json_contents, .{}) catch continue;
782782 defer parsed.deinit();
783783
784784 if (parsed.value != .object) continue;
......@@ -795,40 +795,40 @@ const MsvcLibDir = struct {
795795 const installation_path = parsed.value.object.get("installationPath") orelse continue;
796796 if (installation_path != .string) continue;
797797
798 const lib_dir_path = libDirFromInstallationPath(allocator, io, installation_path.string, arch) catch |err| switch (err) {
798 const lib_dir_path = libDirFromInstallationPath(gpa, io, installation_path.string, arch) catch |err| switch (err) {
799799 error.OutOfMemory => |e| return e,
800800 error.PathNotFound => continue,
801801 };
802 defer allocator.free(lib_dir_path);
802 defer gpa.free(lib_dir_path);
803803
804804 latest_version_lib_dir.clearRetainingCapacity();
805 try latest_version_lib_dir.appendSlice(allocator, lib_dir_path);
805 try latest_version_lib_dir.appendSlice(gpa, lib_dir_path);
806806 latest_version = parsed_version;
807807 }
808808
809809 if (latest_version_lib_dir.items.len == 0) return error.PathNotFound;
810 return latest_version_lib_dir.toOwnedSlice(allocator);
810 return latest_version_lib_dir.toOwnedSlice(gpa);
811811 }
812812
813813 fn libDirFromInstallationPath(
814 allocator: Allocator,
814 gpa: Allocator,
815815 io: Io,
816816 installation_path: []const u8,
817817 arch: std.Target.Cpu.Arch,
818818 ) error{ OutOfMemory, PathNotFound }![]const u8 {
819 var lib_dir_buf = try std.array_list.Managed(u8).initCapacity(allocator, installation_path.len + 64);
819 var lib_dir_buf = try std.array_list.Managed(u8).initCapacity(gpa, installation_path.len + 64);
820820 errdefer lib_dir_buf.deinit();
821821
822822 lib_dir_buf.appendSliceAssumeCapacity(installation_path);
823823
824 if (!std.fs.path.isSep(lib_dir_buf.getLast())) {
824 if (!Dir.path.isSep(lib_dir_buf.getLast())) {
825825 try lib_dir_buf.append('\\');
826826 }
827827 const installation_path_with_trailing_sep_len = lib_dir_buf.items.len;
828828
829829 try lib_dir_buf.appendSlice("VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
830830 var default_tools_version_buf: [512]u8 = undefined;
831 const default_tools_version_contents = Io.Dir.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch {
831 const default_tools_version_contents = Dir.cwd().readFile(lib_dir_buf.items, &default_tools_version_buf) catch {
832832 return error.PathNotFound;
833833 };
834834 var tokenizer = std.mem.tokenizeAny(u8, default_tools_version_contents, " \r\n");
......@@ -854,64 +854,64 @@ const MsvcLibDir = struct {
854854 }
855855
856856 // https://learn.microsoft.com/en-us/visualstudio/install/tools-for-managing-visual-studio-instances?view=vs-2022#editing-the-registry-for-a-visual-studio-instance
857 fn findViaRegistry(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
857 fn findViaRegistry(gpa: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
858858
859859 // %localappdata%\Microsoft\VisualStudio\
860860 // %appdata%\Local\Microsoft\VisualStudio\
861 const visualstudio_folder_path = std.fs.getAppDataDir(allocator, "Microsoft\\VisualStudio\\") catch return error.PathNotFound;
862 defer allocator.free(visualstudio_folder_path);
861 const visualstudio_folder_path = std.fs.getAppDataDir(gpa, "Microsoft\\VisualStudio\\") catch return error.PathNotFound;
862 defer gpa.free(visualstudio_folder_path);
863863
864864 const vs_versions: []const []const u8 = vs_versions: {
865 if (!std.fs.path.isAbsolute(visualstudio_folder_path)) return error.PathNotFound;
865 if (!Dir.path.isAbsolute(visualstudio_folder_path)) return error.PathNotFound;
866866 // enumerate folders that contain `privateregistry.bin`, looking for all versions
867867 // f.i. %localappdata%\Microsoft\VisualStudio\17.0_9e9cbb98\
868 var visualstudio_folder = std.fs.openDirAbsolute(visualstudio_folder_path, .{
868 var visualstudio_folder = Dir.openDirAbsolute(io, visualstudio_folder_path, .{
869869 .iterate = true,
870870 }) catch return error.PathNotFound;
871871 defer visualstudio_folder.close(io);
872872
873873 var iterator = visualstudio_folder.iterate();
874 break :vs_versions try iterateAndFilterByVersion(&iterator, allocator, "");
874 break :vs_versions try iterateAndFilterByVersion(&iterator, gpa, "");
875875 };
876876 defer {
877 for (vs_versions) |vs_version| allocator.free(vs_version);
878 allocator.free(vs_versions);
877 for (vs_versions) |vs_version| gpa.free(vs_version);
878 gpa.free(vs_versions);
879879 }
880880 var config_subkey_buf: [RegistryWtf16Le.key_name_max_len * 2]u8 = undefined;
881881 const source_directories: []const u8 = source_directories: for (vs_versions) |vs_version| {
882 const privateregistry_absolute_path = std.fs.path.join(allocator, &.{ visualstudio_folder_path, vs_version, "privateregistry.bin" }) catch continue;
883 defer allocator.free(privateregistry_absolute_path);
884 if (!std.fs.path.isAbsolute(privateregistry_absolute_path)) continue;
882 const privateregistry_absolute_path = Dir.path.join(gpa, &.{ visualstudio_folder_path, vs_version, "privateregistry.bin" }) catch continue;
883 defer gpa.free(privateregistry_absolute_path);
884 if (!Dir.path.isAbsolute(privateregistry_absolute_path)) continue;
885885
886886 const visualstudio_registry = RegistryWtf8.loadFromPath(privateregistry_absolute_path) catch continue;
887887 defer visualstudio_registry.closeKey();
888888
889889 const config_subkey = std.fmt.bufPrint(config_subkey_buf[0..], "Software\\Microsoft\\VisualStudio\\{s}_Config", .{vs_version}) catch unreachable;
890890
891 const source_directories_value = visualstudio_registry.getString(allocator, config_subkey, "Source Directories") catch |err| switch (err) {
891 const source_directories_value = visualstudio_registry.getString(gpa, config_subkey, "Source Directories") catch |err| switch (err) {
892892 error.OutOfMemory => return error.OutOfMemory,
893893 else => continue,
894894 };
895 if (source_directories_value.len > (std.fs.max_path_bytes * 30)) { // note(bratishkaerik): guessing from the fact that on my computer it has 15 paths and at least some of them are not of max length
896 allocator.free(source_directories_value);
895 if (source_directories_value.len > (Dir.max_path_bytes * 30)) { // note(bratishkaerik): guessing from the fact that on my computer it has 15 paths and at least some of them are not of max length
896 gpa.free(source_directories_value);
897897 continue;
898898 }
899899
900900 break :source_directories source_directories_value;
901901 } else return error.PathNotFound;
902 defer allocator.free(source_directories);
902 defer gpa.free(source_directories);
903903
904904 var source_directories_split = std.mem.splitScalar(u8, source_directories, ';');
905905
906906 const msvc_dir: []const u8 = msvc_dir: {
907 const msvc_include_dir_maybe_with_trailing_slash = try allocator.dupe(u8, source_directories_split.first());
907 const msvc_include_dir_maybe_with_trailing_slash = try gpa.dupe(u8, source_directories_split.first());
908908
909 if (msvc_include_dir_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(msvc_include_dir_maybe_with_trailing_slash)) {
910 allocator.free(msvc_include_dir_maybe_with_trailing_slash);
909 if (msvc_include_dir_maybe_with_trailing_slash.len > Dir.max_path_bytes or !Dir.path.isAbsolute(msvc_include_dir_maybe_with_trailing_slash)) {
910 gpa.free(msvc_include_dir_maybe_with_trailing_slash);
911911 return error.PathNotFound;
912912 }
913913
914 var msvc_dir = std.array_list.Managed(u8).fromOwnedSlice(allocator, msvc_include_dir_maybe_with_trailing_slash);
914 var msvc_dir = std.array_list.Managed(u8).fromOwnedSlice(gpa, msvc_include_dir_maybe_with_trailing_slash);
915915 errdefer msvc_dir.deinit();
916916
917917 // String might contain trailing slash, so trim it here
......@@ -933,7 +933,7 @@ const MsvcLibDir = struct {
933933 const msvc_dir_with_arch = try msvc_dir.toOwnedSlice();
934934 break :msvc_dir msvc_dir_with_arch;
935935 };
936 errdefer allocator.free(msvc_dir);
936 errdefer gpa.free(msvc_dir);
937937
938938 if (!verifyLibDir(io, msvc_dir)) {
939939 return error.PathNotFound;
......@@ -942,10 +942,10 @@ const MsvcLibDir = struct {
942942 return msvc_dir;
943943 }
944944
945 fn findViaVs7Key(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
945 fn findViaVs7Key(gpa: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, PathNotFound }![]const u8 {
946946 var base_path: std.array_list.Managed(u8) = base_path: {
947947 try_env: {
948 var env_map = std.process.getEnvMap(allocator) catch |err| switch (err) {
948 var env_map = std.process.getEnvMap(gpa) catch |err| switch (err) {
949949 error.OutOfMemory => return error.OutOfMemory,
950950 else => break :try_env,
951951 };
......@@ -953,8 +953,8 @@ const MsvcLibDir = struct {
953953
954954 if (env_map.get("VS140COMNTOOLS")) |VS140COMNTOOLS| {
955955 if (VS140COMNTOOLS.len < "C:\\Common7\\Tools".len) break :try_env;
956 if (!std.fs.path.isAbsolute(VS140COMNTOOLS)) break :try_env;
957 var list = std.array_list.Managed(u8).init(allocator);
956 if (!Dir.path.isAbsolute(VS140COMNTOOLS)) break :try_env;
957 var list = std.array_list.Managed(u8).init(gpa);
958958 errdefer list.deinit();
959959
960960 try list.appendSlice(VS140COMNTOOLS); // C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools
......@@ -968,17 +968,17 @@ const MsvcLibDir = struct {
968968 const vs7_key = RegistryWtf8.openKey(windows.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", .{ .wow64_32 = true }) catch return error.PathNotFound;
969969 defer vs7_key.closeKey();
970970 try_vs7_key: {
971 const path_maybe_with_trailing_slash = vs7_key.getString(allocator, "", "14.0") catch |err| switch (err) {
971 const path_maybe_with_trailing_slash = vs7_key.getString(gpa, "", "14.0") catch |err| switch (err) {
972972 error.OutOfMemory => return error.OutOfMemory,
973973 else => break :try_vs7_key,
974974 };
975975
976 if (path_maybe_with_trailing_slash.len > std.fs.max_path_bytes or !std.fs.path.isAbsolute(path_maybe_with_trailing_slash)) {
977 allocator.free(path_maybe_with_trailing_slash);
976 if (path_maybe_with_trailing_slash.len > Dir.max_path_bytes or !Dir.path.isAbsolute(path_maybe_with_trailing_slash)) {
977 gpa.free(path_maybe_with_trailing_slash);
978978 break :try_vs7_key;
979979 }
980980
981 var path = std.array_list.Managed(u8).fromOwnedSlice(allocator, path_maybe_with_trailing_slash);
981 var path = std.array_list.Managed(u8).fromOwnedSlice(gpa, path_maybe_with_trailing_slash);
982982 errdefer path.deinit();
983983
984984 // String might contain trailing slash, so trim it here
......@@ -1007,9 +1007,9 @@ const MsvcLibDir = struct {
10071007 }
10081008
10091009 fn verifyLibDir(io: Io, lib_dir_path: []const u8) bool {
1010 std.debug.assert(std.fs.path.isAbsolute(lib_dir_path)); // should be already handled in `findVia*`
1010 std.debug.assert(Dir.path.isAbsolute(lib_dir_path)); // should be already handled in `findVia*`
10111011
1012 var dir = std.fs.openDirAbsolute(lib_dir_path, .{}) catch return false;
1012 var dir = Dir.openDirAbsolute(io, lib_dir_path, .{}) catch return false;
10131013 defer dir.close(io);
10141014
10151015 const stat = dir.statFile(io, "vcruntime.lib", .{}) catch return false;
......@@ -1021,18 +1021,18 @@ const MsvcLibDir = struct {
10211021
10221022 /// Find path to MSVC's `lib/` directory.
10231023 /// Caller owns the result.
1024 pub fn find(allocator: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, MsvcLibDirNotFound }![]const u8 {
1025 const full_path = MsvcLibDir.findViaCOM(allocator, io, arch) catch |err1| switch (err1) {
1024 pub fn find(gpa: Allocator, io: Io, arch: std.Target.Cpu.Arch) error{ OutOfMemory, MsvcLibDirNotFound }![]const u8 {
1025 const full_path = MsvcLibDir.findViaCOM(gpa, io, arch) catch |err1| switch (err1) {
10261026 error.OutOfMemory => return error.OutOfMemory,
1027 error.PathNotFound => MsvcLibDir.findViaRegistry(allocator, io, arch) catch |err2| switch (err2) {
1027 error.PathNotFound => MsvcLibDir.findViaRegistry(gpa, io, arch) catch |err2| switch (err2) {
10281028 error.OutOfMemory => return error.OutOfMemory,
1029 error.PathNotFound => MsvcLibDir.findViaVs7Key(allocator, io, arch) catch |err3| switch (err3) {
1029 error.PathNotFound => MsvcLibDir.findViaVs7Key(gpa, io, arch) catch |err3| switch (err3) {
10301030 error.OutOfMemory => return error.OutOfMemory,
10311031 error.PathNotFound => return error.MsvcLibDirNotFound,
10321032 },
10331033 },
10341034 };
1035 errdefer allocator.free(full_path);
1035 errdefer gpa.free(full_path);
10361036
10371037 return full_path;
10381038 }