|
const std = @import("../std.zig"); const builtin = @import("builtin"); const unicode = std.unicode; const mem = std.mem; const fs = std.fs; const os = std.os; |
GetAppDataDirError |
pub const GetAppDataDirError = error{ OutOfMemory, AppDataDirUnavailable, }; |
getAppDataDir()Caller owns returned memory. TODO determine if we can remove the allocator requirement |
pub fn getAppDataDir(allocator: mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 { switch (builtin.os.tag) { .windows => { var dir_path_ptr: [*:0]u16 = undefined; switch (os.windows.shell32.SHGetKnownFolderPath( &os.windows.FOLDERID_LocalAppData, os.windows.KF_FLAG_CREATE, null, &dir_path_ptr, )) { os.windows.S_OK => { defer os.windows.ole32.CoTaskMemFree(dir_path_ptr); const global_dir = unicode.utf16leToUtf8Alloc(allocator, mem.sliceTo(dir_path_ptr, 0)) catch |err| switch (err) { error.UnexpectedSecondSurrogateHalf => return error.AppDataDirUnavailable, error.ExpectedSecondSurrogateHalf => return error.AppDataDirUnavailable, error.DanglingSurrogateHalf => return error.AppDataDirUnavailable, error.OutOfMemory => return error.OutOfMemory, }; defer allocator.free(global_dir); return fs.path.join(allocator, &[_][]const u8{ global_dir, appname }); }, os.windows.E_OUTOFMEMORY => return error.OutOfMemory, else => return error.AppDataDirUnavailable, } }, .macos => { const home_dir = os.getenv("HOME") orelse { // TODO look in /etc/passwd return error.AppDataDirUnavailable; }; return fs.path.join(allocator, &[_][]const u8{ home_dir, "Library", "Application Support", appname }); }, .linux, .freebsd, .netbsd, .dragonfly, .openbsd, .solaris, .illumos => { if (os.getenv("XDG_DATA_HOME")) |xdg| { return fs.path.join(allocator, &[_][]const u8{ xdg, appname }); } const home_dir = os.getenv("HOME") orelse { // TODO look in /etc/passwd return error.AppDataDirUnavailable; }; return fs.path.join(allocator, &[_][]const u8{ home_dir, ".local", "share", appname }); }, .haiku => { var dir_path_ptr: [*:0]u8 = undefined; // TODO look into directory_which const be_user_settings = 0xbbe; const rc = os.system.find_directory(be_user_settings, -1, true, dir_path_ptr, 1); const settings_dir = try allocator.dupeZ(u8, mem.sliceTo(dir_path_ptr, 0)); defer allocator.free(settings_dir); switch (rc) { 0 => return fs.path.join(allocator, &[_][]const u8{ settings_dir, appname }), else => return error.AppDataDirUnavailable, } }, else => @compileError("Unsupported OS"), } } |
Test:getAppDataDir |
test "getAppDataDir" { if (builtin.os.tag == .wasi) return error.SkipZigTest; // We can't actually validate the result const dir = getAppDataDir(std.testing.allocator, "zig") catch return; defer std.testing.allocator.free(dir); } |
Generated by zstd-browse2 on 2023-11-04 14:12:27 -0400. |