authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 15:57:24-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 15:57:24-05:00
log457f03e37d368bcc470fb690778d880fd1878082
treeafa8f95769ce2e8df252b2c5e90e164288c6e1c2
parente98ba5fc4044cd84ab88b10cb8c88d765884462f
parentcf266ff80a69d19140465b949350421dc541d4c8
signature Commit is signed but in an unrecognized format.

Merge branch 'windows-wide-imports' of https://github.com/suirad/zig into suirad-windows-wide-imports


2 files changed, 60 insertions(+), 13 deletions(-)

std/os/index.zig+57-10
......@@ -702,27 +702,57 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
702702 errdefer result.deinit();
703703
704704 if (is_windows) {
705 const ptr = windows.GetEnvironmentStringsA() orelse return error.OutOfMemory;
706 defer assert(windows.FreeEnvironmentStringsA(ptr) != 0);
705 const ptr = windows.GetEnvironmentStringsW() orelse return error.OutOfMemory;
706 defer assert(windows.FreeEnvironmentStringsW(ptr) != 0);
707
708 var buf: [100]u8 = undefined;
707709
708710 var i: usize = 0;
709711 while (true) {
710712 if (ptr[i] == 0) return result;
711713
712714 const key_start = i;
715 var fallocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
713716
714717 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
715 const key = ptr[key_start..i];
718
719 const key_slice = ptr[key_start..i];
720 var key: []u8 = undefined;
721 var heap_key = false;
722
723 key = std.unicode.utf16leToUtf8Alloc(fallocator, key_slice) catch undefined;
724
725 if (key.len == 0) {
726 key = try std.unicode.utf16leToUtf8Alloc(allocator, key_slice);
727 heap_key = true;
728 }
716729
717730 if (ptr[i] == '=') i += 1;
718731
719732 const value_start = i;
720733 while (ptr[i] != 0) : (i += 1) {}
721 const value = ptr[value_start..i];
734
735 const value_slice = ptr[value_start..i];
736 var value: []u8 = undefined;
737 var heap_value = false;
738
739 value = std.unicode.utf16leToUtf8Alloc(fallocator, value_slice) catch undefined;
740
741 if (value.len == 0) {
742 value = try std.unicode.utf16leToUtf8Alloc(allocator, value_slice);
743 heap_value = true;
744 }
722745
723746 i += 1; // skip over null byte
724747
725748 try result.set(key, value);
749
750 if (heap_key) {
751 allocator.free(key);
752 }
753 if (heap_value) {
754 allocator.free(value);
755 }
726756 }
727757 } else {
728758 for (posix_environ_raw) |ptr| {
......@@ -740,6 +770,11 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
740770 }
741771}
742772
773test "os.getEnvMap" {
774 var env = try getEnvMap(std.debug.global_allocator);
775 defer env.deinit();
776}
777
743778/// TODO make this go through libc when we have it
744779pub fn getEnvPosix(key: []const u8) ?[]const u8 {
745780 for (posix_environ_raw) |ptr| {
......@@ -760,21 +795,27 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
760795pub const GetEnvVarOwnedError = error{
761796 OutOfMemory,
762797 EnvironmentVariableNotFound,
798 DanglingSurrogateHalf,
799 ExpectedSecondSurrogateHalf,
800 UnexpectedSecondSurrogateHalf,
801
802 /// See https://github.com/ziglang/zig/issues/1774
803 InvalidUtf8,
763804};
764805
765806/// Caller must free returned memory.
766807/// TODO make this go through libc when we have it
767808pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
768809 if (is_windows) {
769 const key_with_null = try cstr.addNullByte(allocator, key);
810 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
770811 defer allocator.free(key_with_null);
771812
772 var buf = try allocator.alloc(u8, 256);
773 errdefer allocator.free(buf);
813 var buf = try allocator.alloc(u16, 256);
814 defer allocator.free(buf);
774815
775816 while (true) {
776817 const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;
777 const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
818 const result = windows.GetEnvironmentVariableW(key_with_null.ptr, buf.ptr, windows_buf_len);
778819
779820 if (result == 0) {
780821 const err = windows.GetLastError();
......@@ -788,11 +829,11 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
788829 }
789830
790831 if (result > buf.len) {
791 buf = try allocator.realloc(u8, buf, result);
832 buf = try allocator.realloc(u16, buf, result);
792833 continue;
793834 }
794835
795 return allocator.shrink(u8, buf, result);
836 return try std.unicode.utf16leToUtf8Alloc(allocator, buf);
796837 }
797838 } else {
798839 const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;
......@@ -800,6 +841,12 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
800841 }
801842}
802843
844test "os.getEnvVarOwned" {
845 var ga = debug.global_allocator;
846 debug.assertError(getEnvVarOwned(ga, "BADENV"), error.EnvironmentVariableNotFound);
847}
848
849
803850/// Caller must free the returned memory.
804851pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
805852 var buf: [MAX_PATH_BYTES]u8 = undefined;
std/os/windows/kernel32.zig+3-3
......@@ -50,7 +50,7 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi
5050pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
5151pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;
5252
53pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL;
53pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsW(penv: [*]u16) BOOL;
5454
5555pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
5656
......@@ -63,9 +63,9 @@ pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lp
6363pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;
6464pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD;
6565
66pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
66pub extern "kernel32" stdcallcc fn GetEnvironmentStringsW() ?[*]u16;
6767
68pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
68pub extern "kernel32" stdcallcc fn GetEnvironmentVariableW(lpName: LPWSTR, lpBuffer: LPWSTR, nSize: DWORD) DWORD;
6969
7070pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;
7171