authorgravatar for suirad@users.noreply.github.comSuirad <suirad@users.noreply.github.com> 2018-11-22 04:15:22-06:00
committergravatar for suirad@users.noreply.github.comSuirad <suirad@users.noreply.github.com> 2018-11-30 02:08:33-06:00
log5dfca87a65884f8564a8c8e2444bb906073425f3
tree1e094e5f0387975dd89fea7a244d1949787672d7
parent823969a5a47e054842056e3380b3987058ccd2dd

Update windows imports


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

std/os/index.zig+71-10
...@@ -702,8 +702,8 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -702,8 +702,8 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
702 errdefer result.deinit();702 errdefer result.deinit();
703703
704 if (is_windows) {704 if (is_windows) {
705 const ptr = windows.GetEnvironmentStringsA() orelse return error.OutOfMemory;705 const ptr = windows.GetEnvironmentStringsW() orelse return error.OutOfMemory;
706 defer assert(windows.FreeEnvironmentStringsA(ptr) != 0);706 defer assert(windows.FreeEnvironmentStringsW(ptr) != 0);
707707
708 var i: usize = 0;708 var i: usize = 0;
709 while (true) {709 while (true) {
...@@ -712,17 +712,50 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -712,17 +712,50 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
712 const key_start = i;712 const key_start = i;
713713
714 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}714 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
715 const key = ptr[key_start..i];715
716 const stack_var_len = 50;
717 const key_slice = ptr[key_start..i];
718 var key: []u8 = undefined;
719 var heap_key = false;
720
721 // parse the key on the stack if smaller than 'stack_var_len'
722 if (key_slice.len < stack_var_len-@sizeOf(usize)) {
723 var buf = []u8{0} ** stack_var_len;
724 var fallocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
725 key = try std.unicode.utf16leToUtf8Alloc(fallocator, key_slice);
726 } else {
727 key = try std.unicode.utf16leToUtf8Alloc(allocator, key_slice);
728 heap_key = true; // key needs to outlive this scope, so we cannot defer
729 }
716730
717 if (ptr[i] == '=') i += 1;731 if (ptr[i] == '=') i += 1;
718732
719 const value_start = i;733 const value_start = i;
720 while (ptr[i] != 0) : (i += 1) {}734 while (ptr[i] != 0) : (i += 1) {}
721 const value = ptr[value_start..i];735
736 const value_slice = ptr[value_start..i];
737 var value: []u8 = undefined;
738 var heap_value = false;
739
740 if (value_slice.len < stack_var_len-@sizeOf(usize)) {
741 var buf = []u8{0} ** stack_var_len;
742 var fallocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
743 value = try std.unicode.utf16leToUtf8Alloc(fallocator, value_slice);
744 } else {
745 value = try std.unicode.utf16leToUtf8Alloc(allocator, value_slice);
746 heap_value = true; // value needs to outlive this scope, so we cannot defer
747 }
722748
723 i += 1; // skip over null byte749 i += 1; // skip over null byte
724750
725 try result.set(key, value);751 try result.set(key, value);
752
753 if (heap_key) {
754 allocator.free(key);
755 }
756 if (heap_value) {
757 allocator.free(value);
758 }
726 }759 }
727 } else {760 } else {
728 for (posix_environ_raw) |ptr| {761 for (posix_environ_raw) |ptr| {
...@@ -740,6 +773,19 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -740,6 +773,19 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
740 }773 }
741}774}
742775
776test "os.getEnvMap" {
777 var env = try getEnvMap(std.debug.global_allocator);
778 var seen_path = false;
779 var it = env.iterator();
780 while (it.next()) |pair| {
781 if (mem.eql(u8, pair.key, "PATH")) {
782 seen_path = true;
783 }
784 }
785
786 assert(seen_path == true);
787}
788
743/// TODO make this go through libc when we have it789/// TODO make this go through libc when we have it
744pub fn getEnvPosix(key: []const u8) ?[]const u8 {790pub fn getEnvPosix(key: []const u8) ?[]const u8 {
745 for (posix_environ_raw) |ptr| {791 for (posix_environ_raw) |ptr| {
...@@ -760,21 +806,27 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {...@@ -760,21 +806,27 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
760pub const GetEnvVarOwnedError = error{806pub const GetEnvVarOwnedError = error{
761 OutOfMemory,807 OutOfMemory,
762 EnvironmentVariableNotFound,808 EnvironmentVariableNotFound,
809 DanglingSurrogateHalf,
810 ExpectedSecondSurrogateHalf,
811 UnexpectedSecondSurrogateHalf,
812
813 /// See https://github.com/ziglang/zig/issues/1774
814 InvalidUtf8,
763};815};
764816
765/// Caller must free returned memory.817/// Caller must free returned memory.
766/// TODO make this go through libc when we have it818/// TODO make this go through libc when we have it
767pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {819pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
768 if (is_windows) {820 if (is_windows) {
769 const key_with_null = try cstr.addNullByte(allocator, key);821 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
770 defer allocator.free(key_with_null);822 defer allocator.free(key_with_null);
771823
772 var buf = try allocator.alloc(u8, 256);824 var buf = try allocator.alloc(u16, 256);
773 errdefer allocator.free(buf);825 defer allocator.free(buf);
774826
775 while (true) {827 while (true) {
776 const windows_buf_len = math.cast(windows.DWORD, buf.len) catch return error.OutOfMemory;828 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);829 const result = windows.GetEnvironmentVariableW(key_with_null.ptr, buf.ptr, windows_buf_len);
778830
779 if (result == 0) {831 if (result == 0) {
780 const err = windows.GetLastError();832 const err = windows.GetLastError();
...@@ -788,11 +840,11 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned...@@ -788,11 +840,11 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
788 }840 }
789841
790 if (result > buf.len) {842 if (result > buf.len) {
791 buf = try allocator.realloc(u8, buf, result);843 buf = try allocator.realloc(u16, buf, result);
792 continue;844 continue;
793 }845 }
794846
795 return allocator.shrink(u8, buf, result);847 return try std.unicode.utf16leToUtf8Alloc(allocator, buf);
796 }848 }
797 } else {849 } else {
798 const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;850 const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;
...@@ -800,6 +852,15 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned...@@ -800,6 +852,15 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
800 }852 }
801}853}
802854
855test "os.getEnvVarOwned" {
856 switch (builtin.os) {
857 builtin.Os.windows, builtin.Os.linux, builtin.Os.macosx,
858 builtin.Os.ios => _ = try getEnvVarOwned(debug.global_allocator, "PATH"),
859 else => @compileError("unimplemented"),
860 }
861}
862
863
803/// Caller must free the returned memory.864/// Caller must free the returned memory.
804pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {865pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
805 var buf: [MAX_PATH_BYTES]u8 = undefined;866 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...@@ -50,7 +50,7 @@ pub extern "kernel32" stdcallcc fn FindFirstFileW(lpFileName: [*]const u16, lpFi
50pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;50pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
51pub extern "kernel32" stdcallcc fn FindNextFileW(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAW) BOOL;51pub 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
55pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;55pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
5656
...@@ -63,9 +63,9 @@ pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lp...@@ -63,9 +63,9 @@ pub extern "kernel32" stdcallcc fn GetCurrentDirectoryW(nBufferLength: DWORD, lp
63pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;63pub extern "kernel32" stdcallcc fn GetCurrentThread() HANDLE;
64pub extern "kernel32" stdcallcc fn GetCurrentThreadId() DWORD;64pub 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
70pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;70pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;
7171