diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-09-21 18:38:55 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-09-21 18:38:55 -0700 |
| commit | 528832bd3a2e7b686ee84aef5887df740a6114db (patch) | |
| tree | 90ccff9faa2ba2604c8538aeec0a147a4b01148c /src/introspect.zig | |
| parent | b9f61d401502f5d221e72c0d0e3bf448b11dcd68 (diff) | |
| download | zig-528832bd3a2e7b686ee84aef5887df740a6114db.tar.gz zig-528832bd3a2e7b686ee84aef5887df740a6114db.zip | |
rename src-self-hosted/ to src/
Diffstat (limited to 'src/introspect.zig')
| -rw-r--r-- | src/introspect.zig | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/introspect.zig b/src/introspect.zig new file mode 100644 index 0000000000..067326ebb6 --- /dev/null +++ b/src/introspect.zig @@ -0,0 +1,82 @@ +const std = @import("std"); +const mem = std.mem; +const fs = std.fs; +const Compilation = @import("Compilation.zig"); + +/// Returns the sub_path that worked, or `null` if none did. +/// The path of the returned Directory is relative to `base`. +/// The handle of the returned Directory is open. +fn testZigInstallPrefix(base_dir: fs.Dir) ?Compilation.Directory { + const test_index_file = "std" ++ fs.path.sep_str ++ "std.zig"; + + zig_dir: { + // Try lib/zig/std/std.zig + const lib_zig = "lib" ++ fs.path.sep_str ++ "zig"; + var test_zig_dir = base_dir.openDir(lib_zig, .{}) catch break :zig_dir; + const file = test_zig_dir.openFile(test_index_file, .{}) catch { + test_zig_dir.close(); + break :zig_dir; + }; + file.close(); + return Compilation.Directory{ .handle = test_zig_dir, .path = lib_zig }; + } + + // Try lib/std/std.zig + var test_zig_dir = base_dir.openDir("lib", .{}) catch return null; + const file = test_zig_dir.openFile(test_index_file, .{}) catch { + test_zig_dir.close(); + return null; + }; + file.close(); + return Compilation.Directory{ .handle = test_zig_dir, .path = "lib" }; +} + +/// Both the directory handle and the path are newly allocated resources which the caller now owns. +pub fn findZigLibDir(gpa: *mem.Allocator) !Compilation.Directory { + const self_exe_path = try fs.selfExePathAlloc(gpa); + defer gpa.free(self_exe_path); + + return findZigLibDirFromSelfExe(gpa, self_exe_path); +} + +/// Both the directory handle and the path are newly allocated resources which the caller now owns. +pub fn findZigLibDirFromSelfExe( + allocator: *mem.Allocator, + self_exe_path: []const u8, +) error{ OutOfMemory, FileNotFound }!Compilation.Directory { + const cwd = fs.cwd(); + var cur_path: []const u8 = self_exe_path; + while (fs.path.dirname(cur_path)) |dirname| : (cur_path = dirname) { + var base_dir = cwd.openDir(dirname, .{}) catch continue; + defer base_dir.close(); + + const sub_directory = testZigInstallPrefix(base_dir) orelse continue; + return Compilation.Directory{ + .handle = sub_directory.handle, + .path = try fs.path.join(allocator, &[_][]const u8{ dirname, sub_directory.path.? }), + }; + } + return error.FileNotFound; +} + +/// Caller owns returned memory. +pub fn resolveGlobalCacheDir(allocator: *mem.Allocator) ![]u8 { + const appname = "zig"; + + if (std.Target.current.os.tag != .windows) { + if (std.os.getenv("XDG_CACHE_HOME")) |cache_root| { + return fs.path.join(allocator, &[_][]const u8{ cache_root, appname }); + } else if (std.os.getenv("HOME")) |home| { + return fs.path.join(allocator, &[_][]const u8{ home, ".cache", appname }); + } + } + + return fs.getAppDataDir(allocator, appname); +} + +pub fn openGlobalCacheDir() !fs.Dir { + var buf: [fs.MAX_PATH_BYTES]u8 = undefined; + var fba = std.heap.FixedBufferAllocator.init(&buf); + const path_name = try resolveGlobalCacheDir(&fba.allocator); + return fs.cwd().makeOpenPath(path_name, .{}); +} |
