From a8a1b5af07519b49b5ba31ad6c802a7ccc8a5e23 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 18 Jul 2018 10:07:22 -0400 Subject: fix build on windows * move getAppDataDir and utf16leToUtf8 from self-hosted to std lib * fix std.event.Loop on windows --- std/os/get_app_data_dir.zig | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 std/os/get_app_data_dir.zig (limited to 'std/os/get_app_data_dir.zig') diff --git a/std/os/get_app_data_dir.zig b/std/os/get_app_data_dir.zig new file mode 100644 index 0000000000..b5efdb826a --- /dev/null +++ b/std/os/get_app_data_dir.zig @@ -0,0 +1,60 @@ +const std = @import("../index.zig"); +const builtin = @import("builtin"); +const unicode = std.unicode; +const mem = std.mem; +const os = std.os; + +pub const GetAppDataDirError = error{ + OutOfMemory, + AppDataDirUnavailable, +}; + +/// Caller owns returned memory. +pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataDirError![]u8 { + switch (builtin.os) { + builtin.Os.windows => { + var dir_path_ptr: [*]u16 = undefined; + switch (os.windows.SHGetKnownFolderPath( + &os.windows.FOLDERID_LocalAppData, + os.windows.KF_FLAG_CREATE, + null, + &dir_path_ptr, + )) { + os.windows.S_OK => { + defer os.windows.CoTaskMemFree(@ptrCast(*c_void, dir_path_ptr)); + const global_dir = unicode.utf16leToUtf8(allocator, utf16lePtrSlice(dir_path_ptr)) 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 os.path.join(allocator, global_dir, appname); + }, + os.windows.E_OUTOFMEMORY => return error.OutOfMemory, + else => return error.AppDataDirUnavailable, + } + }, + // TODO for macos it should be "~/Library/Application Support/" + else => { + const home_dir = os.getEnvVarOwned(allocator, "HOME") catch |err| switch (err) { + error.OutOfMemory => return error.OutOfMemory, + error.EnvironmentVariableNotFound => return error.AppDataDirUnavailable, // TODO look in /etc/passwd + }; + defer allocator.free(home_dir); + return os.path.join(allocator, home_dir, ".local", "share", appname); + }, + } +} + +fn utf16lePtrSlice(ptr: [*]const u16) []const u16 { + var index: usize = 0; + while (ptr[index] != 0) : (index += 1) {} + return ptr[0..index]; +} + +test "getAppDataDir" { + const result = try getAppDataDir(std.debug.global_allocator, "zig"); + std.debug.warn("{}...", result); +} + -- cgit v1.2.3 From cd488c9da56a03d2244a67629612445c451441da Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 18 Jul 2018 10:45:17 -0400 Subject: fix std.os.getAppDataDir test on linux --- std/os/get_app_data_dir.zig | 27 ++++++++++++++++++--------- std/os/index.zig | 3 +++ 2 files changed, 21 insertions(+), 9 deletions(-) (limited to 'std/os/get_app_data_dir.zig') diff --git a/std/os/get_app_data_dir.zig b/std/os/get_app_data_dir.zig index b5efdb826a..e8ae5dd490 100644 --- a/std/os/get_app_data_dir.zig +++ b/std/os/get_app_data_dir.zig @@ -35,15 +35,21 @@ pub fn getAppDataDir(allocator: *mem.Allocator, appname: []const u8) GetAppDataD else => return error.AppDataDirUnavailable, } }, - // TODO for macos it should be "~/Library/Application Support/" - else => { - const home_dir = os.getEnvVarOwned(allocator, "HOME") catch |err| switch (err) { - error.OutOfMemory => return error.OutOfMemory, - error.EnvironmentVariableNotFound => return error.AppDataDirUnavailable, // TODO look in /etc/passwd + builtin.Os.macosx => { + const home_dir = os.getEnvPosix("HOME") orelse { + // TODO look in /etc/passwd + return error.AppDataDirUnavailable; + }; + return os.path.join(allocator, home_dir, "Library", "Application Support", appname); + }, + builtin.Os.linux => { + const home_dir = os.getEnvPosix("HOME") orelse { + // TODO look in /etc/passwd + return error.AppDataDirUnavailable; }; - defer allocator.free(home_dir); return os.path.join(allocator, home_dir, ".local", "share", appname); }, + else => @compileError("Unsupported OS"), } } @@ -53,8 +59,11 @@ fn utf16lePtrSlice(ptr: [*]const u16) []const u16 { return ptr[0..index]; } -test "getAppDataDir" { - const result = try getAppDataDir(std.debug.global_allocator, "zig"); - std.debug.warn("{}...", result); +test "std.os.getAppDataDir" { + var buf: [512]u8 = undefined; + const allocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator; + + // We can't actually validate the result + _ = getAppDataDir(allocator, "zig") catch return; } diff --git a/std/os/index.zig b/std/os/index.zig index cb4358af4d..87053fd8df 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -498,6 +498,7 @@ pub var linux_aux_raw = []usize{0} ** 38; pub var posix_environ_raw: [][*]u8 = undefined; /// Caller must free result when done. +/// TODO make this go through libc when we have it pub fn getEnvMap(allocator: *Allocator) !BufMap { var result = BufMap.init(allocator); errdefer result.deinit(); @@ -541,6 +542,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap { } } +/// TODO make this go through libc when we have it pub fn getEnvPosix(key: []const u8) ?[]const u8 { for (posix_environ_raw) |ptr| { var line_i: usize = 0; @@ -563,6 +565,7 @@ pub const GetEnvVarOwnedError = error{ }; /// Caller must free returned memory. +/// TODO make this go through libc when we have it pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 { if (is_windows) { const key_with_null = try cstr.addNullByte(allocator, key); -- cgit v1.2.3