Commit e1c03d9e8e

Andrew Kelley <superjoe30@gmail.com>
2018-01-04 19:48:45
self-hosted compiler works on windows
* better error message for realpath failing * fix bug in std.io.readFileAllocExtra incorrectly returning error.EndOfStream * implement std.os.selfExePath and std.os.selfExeDirPath for windows
1 parent 0cd63b2
Changed files (4)
src-self-hosted
std
src-self-hosted/module.zig
@@ -208,7 +208,7 @@ pub const Module = struct {
 
         const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path");
         const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| {
-            %return printError("unable to open '{}': {}", root_src_path, err);
+            %return printError("unable to get real path '{}': {}", root_src_path, err);
             return err;
         };
         %defer self.allocator.free(root_src_real_path);
std/os/windows/index.zig
@@ -48,6 +48,8 @@ pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCo
 
 pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: &LARGE_INTEGER) -> BOOL;
 
+pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) -> DWORD;
+
 pub extern "kernel32" stdcallcc fn GetLastError() -> DWORD;
 
 pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,
std/os/index.zig
@@ -1544,6 +1544,40 @@ pub fn openSelfExe() -> %io.File {
     }
 }
 
+/// Get the path to the current executable.
+/// If you only need the directory, use selfExeDirPath.
+/// If you only want an open file handle, use openSelfExe.
+/// This function may return an error if the current executable
+/// was deleted after spawning.
+/// Caller owns returned memory.
+pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
+    switch (builtin.os) {
+        Os.linux => {
+            @compileError("TODO: selfExePath for linux");
+        },
+        Os.windows => {
+            var out_path = %return Buffer.initSize(allocator, 256);
+            %defer out_path.deinit();
+            while (true) {
+                const dword_len = %return math.cast(windows.DWORD, out_path.len());
+                const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);
+                if (copied_amt <= 0) {
+                    const err = windows.GetLastError();
+                    return switch (err) {
+                        else => unexpectedErrorWindows(err),
+                    };
+                }
+                if (copied_amt < out_path.len()) {
+                    out_path.shrink(copied_amt);
+                    return out_path.toOwnedSlice();
+                }
+                %return out_path.resize(out_path.len() * 2);
+            }
+        },
+        else => @compileError("Unsupported OS"),
+    }
+}
+
 /// Get the directory path that contains the current executable.
 /// Caller owns returned memory.
 pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
@@ -1559,19 +1593,10 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
             return allocator.shrink(u8, full_exe_path, dir.len);
         },
         Os.windows => {
-            @panic("TODO windows std.os.selfExeDirPath");
-            //buf_resize(out_path, 256);
-            //for (;;) {
-            //    DWORD copied_amt = GetModuleFileName(nullptr, buf_ptr(out_path), buf_len(out_path));
-            //    if (copied_amt <= 0) {
-            //        return ErrorFileNotFound;
-            //    }
-            //    if (copied_amt < buf_len(out_path)) {
-            //        buf_resize(out_path, copied_amt);
-            //        return 0;
-            //    }
-            //    buf_resize(out_path, buf_len(out_path) * 2);
-            //}
+            const self_exe_path = %return selfExePath(allocator);
+            %defer allocator.free(self_exe_path);
+            const dirname = os.path.dirname(self_exe_path);
+            return allocator.shrink(u8, self_exe_path, dirname.len);
         },
         else => @compileError("unimplemented: std.os.selfExeDirPath for " ++ @tagName(builtin.os)),
     }
std/io.zig
@@ -513,7 +513,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len
     %defer allocator.free(buf);
 
     var adapter = FileInStream.init(&file);
-    %return adapter.stream.readNoEof(buf);
+    %return adapter.stream.readNoEof(buf[0..size]);
     return buf;
 }