From 9d5f15fe3da40813527d19c75b3633dcf2d00b0b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 8 Oct 2017 21:40:33 -0400 Subject: [PATCH] implement os.getCwd for windows --- std/os/index.zig | 21 +++++++++++++++++---- std/os/path.zig | 24 ++++++------------------ std/os/windows/index.zig | 5 ++++- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/std/os/index.zig b/std/os/index.zig index fa51065299..d4681eaa15 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -476,10 +476,23 @@ pub const args = struct { pub fn getCwd(allocator: &Allocator) -> %[]u8 { switch (builtin.os) { Os.windows => { - @panic("implement getCwd for windows"); - //if (windows.GetCurrentDirectoryA(buf_len(out_cwd), buf_ptr(out_cwd)) == 0) { - // zig_panic("GetCurrentDirectory failed"); - //} + var buf = %return allocator.alloc(u8, 256); + %defer allocator.free(buf); + + while (true) { + const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr); + + if (result == 0) { + return error.Unexpected; + } + + if (result > buf.len) { + buf = %return allocator.realloc(u8, buf, result); + continue; + } + + return buf[0..result]; + } }, else => { var buf = %return allocator.alloc(u8, 1024); diff --git a/std/os/path.zig b/std/os/path.zig index 8c00ae7a5e..eea0df461a 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -176,25 +176,13 @@ test "os.path.networkShare" { assert(networkShare("\\\\a\\") == null); } -pub fn root(path: []const u8) -> []const u8 { - if (is_windows) { - return rootWindows(path); - } else { - return rootPosix(path); - } -} +pub fn diskDesignator(path: []const u8) -> []const u8 { + if (!is_windows) + return ""; -pub fn rootWindows(path: []const u8) -> []const u8 { return drive(path) ?? (networkShare(path) ?? []u8{}); } -pub fn rootPosix(path: []const u8) -> []const u8 { - if (path.len == 0 or path[0] != '/') - return []u8{}; - - return path[0..1]; -} - // TODO ASCII is wrong, we actually need full unicode support to compare paths. fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool { const sep1 = ns1[0]; @@ -346,7 +334,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 mem.copy(u8, result, cwd); result_index += cwd.len; - root_slice = rootWindows(result[0..result_index]); + root_slice = diskDesignator(result[0..result_index]); } %defer allocator.free(result); @@ -362,7 +350,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 continue; } } - var it = mem.split(p[rootWindows(p).len..], "/\\"); + var it = mem.split(p[diskDesignator(p).len..], "/\\"); while (it.next()) |component| { if (mem.eql(u8, component, ".")) { continue; @@ -517,7 +505,7 @@ pub fn dirnameWindows(path: []const u8) -> []const u8 { if (path.len == 0) return path[0..0]; - const root_slice = rootWindows(path); + const root_slice = diskDesignator(path); if (path.len == root_slice.len) return path; diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index 8922de8599..83e96d6777 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -13,6 +13,8 @@ pub extern "kernel32" stdcallcc fn GetCommandLine() -> LPTSTR; pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: &DWORD) -> bool; +pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPTSTR) -> DWORD; + /// Retrieves the calling thread's last-error code value. The last-error code is maintained on a per-thread basis. /// Multiple threads do not overwrite each other's last-error code. pub extern "kernel32" stdcallcc fn GetLastError() -> DWORD; @@ -50,7 +52,7 @@ pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lp pub const PROV_RSA_FULL = 1; pub const UNICODE = false; -pub const LPTSTR = if (unicode) LPWSTR else LPSTR; +pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR; pub const LPWSTR = &WCHAR; pub const LPSTR = &CHAR; pub const CHAR = u8; @@ -59,6 +61,7 @@ pub const SIZE_T = usize; pub const BOOL = bool; pub const BYTE = u8; +pub const WORD = u16; pub const DWORD = u32; pub const FLOAT = f32; pub const HANDLE = &c_void;