| author | |
| committer | |
| log | 173a143dd04f9ec75355c04be9b0e6353ee9bc03 |
| tree | 3abbee7296ffab6e9e4b40f0d65a23dd9fd4ead7 |
| parent | 0a2519fafb083e13fb40eac5afcfcb8b741e3438 |
| parent | 155e631aa6f9fabc101abceeeec00b4808a3e4e3 |
| signature |
Progressbar for Windows4 files changed, 55 insertions(+), 10 deletions(-)
lib/std/os/windows/kernel32.zig+3| ... | ... | @@ -83,6 +83,9 @@ pub extern "kernel32" fn GetCommandLineA() callconv(.Stdcall) LPSTR; |
| 83 | 83 | pub extern "kernel32" fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) callconv(.Stdcall) BOOL; |
| 84 | 84 | |
| 85 | 85 | pub extern "kernel32" fn GetConsoleScreenBufferInfo(hConsoleOutput: HANDLE, lpConsoleScreenBufferInfo: *CONSOLE_SCREEN_BUFFER_INFO) callconv(.Stdcall) BOOL; |
| 86 | pub extern "kernel32" fn FillConsoleOutputCharacterA(hConsoleOutput: HANDLE, cCharacter: TCHAR, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfCharsWritten: LPDWORD) callconv(.Stdcall) BOOL; | |
| 87 | pub extern "kernel32" fn FillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: WORD, nLength: DWORD, dwWriteCoord: COORD, lpNumberOfAttrsWritten: LPDWORD) callconv(.Stdcall) BOOL; | |
| 88 | pub extern "kernel32" fn SetConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD) callconv(.Stdcall) BOOL; | |
| 86 | 89 | |
| 87 | 90 | pub extern "kernel32" fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: ?[*]WCHAR) callconv(.Stdcall) DWORD; |
| 88 | 91 |
lib/std/progress.zig+49-7| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | const windows = std.os.windows; | |
| 2 | 3 | const testing = std.testing; |
| 3 | 4 | const assert = std.debug.assert; |
| 4 | 5 | |
| ... | ... | @@ -99,7 +100,12 @@ pub const Progress = struct { |
| 99 | 100 | /// API to return Progress rather than accept it as a parameter. |
| 100 | 101 | pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node { |
| 101 | 102 | const stderr = std.io.getStdErr(); |
| 102 | self.terminal = if (stderr.supportsAnsiEscapeCodes()) stderr else null; | |
| 103 | self.terminal = null; | |
| 104 | if (stderr.supportsAnsiEscapeCodes()) { | |
| 105 | self.terminal = stderr; | |
| 106 | } else if (std.builtin.os.tag == .windows and stderr.isTty()) { | |
| 107 | self.terminal = stderr; | |
| 108 | } | |
| 103 | 109 | self.root = Node{ |
| 104 | 110 | .context = self, |
| 105 | 111 | .parent = null, |
| ... | ... | @@ -129,12 +135,48 @@ pub const Progress = struct { |
| 129 | 135 | const prev_columns_written = self.columns_written; |
| 130 | 136 | var end: usize = 0; |
| 131 | 137 | if (self.columns_written > 0) { |
| 132 | // restore cursor position | |
| 133 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{}D", .{self.columns_written}) catch unreachable).len; | |
| 134 | self.columns_written = 0; | |
| 138 | // restore the cursor position by moving the cursor | |
| 139 | // `columns_written` cells to the left, then clear the rest of the | |
| 140 | // line | |
| 141 | if (std.builtin.os.tag != .windows) { | |
| 142 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{}D", .{self.columns_written}) catch unreachable).len; | |
| 143 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[0K", .{}) catch unreachable).len; | |
| 144 | } else { | |
| 145 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | |
| 146 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) | |
| 147 | unreachable; | |
| 148 | ||
| 149 | var cursor_pos = windows.COORD{ | |
| 150 | .X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written), | |
| 151 | .Y = info.dwCursorPosition.Y, | |
| 152 | }; | |
| 153 | ||
| 154 | if (cursor_pos.X < 0) | |
| 155 | cursor_pos.X = 0; | |
| 135 | 156 | |
| 136 | // clear rest of line | |
| 137 | end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[0K", .{}) catch unreachable).len; | |
| 157 | const fill_chars = @intCast(windows.DWORD, info.dwSize.X - cursor_pos.X); | |
| 158 | ||
| 159 | var written: windows.DWORD = undefined; | |
| 160 | if (windows.kernel32.FillConsoleOutputAttribute( | |
| 161 | file.handle, | |
| 162 | info.wAttributes, | |
| 163 | fill_chars, | |
| 164 | cursor_pos, | |
| 165 | &written, | |
| 166 | ) != windows.TRUE) unreachable; | |
| 167 | if (windows.kernel32.FillConsoleOutputCharacterA( | |
| 168 | file.handle, | |
| 169 | ' ', | |
| 170 | fill_chars, | |
| 171 | cursor_pos, | |
| 172 | &written, | |
| 173 | ) != windows.TRUE) unreachable; | |
| 174 | ||
| 175 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) | |
| 176 | unreachable; | |
| 177 | } | |
| 178 | ||
| 179 | self.columns_written = 0; | |
| 138 | 180 | } |
| 139 | 181 | |
| 140 | 182 | if (!self.done) { |
| ... | ... | @@ -195,7 +237,7 @@ pub const Progress = struct { |
| 195 | 237 | end.* = self.output_buffer.len; |
| 196 | 238 | }, |
| 197 | 239 | } |
| 198 | const bytes_needed_for_esc_codes_at_end = 11; | |
| 240 | const bytes_needed_for_esc_codes_at_end = if (std.builtin.os.tag == .windows) 0 else 11; | |
| 199 | 241 | const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; |
| 200 | 242 | if (end.* > max_end) { |
| 201 | 243 | const suffix = "..."; |
src/analyze.cpp+1-1| ... | ... | @@ -9044,7 +9044,7 @@ static void resolve_llvm_types_fn_type(CodeGen *g, ZigType *fn_type) { |
| 9044 | 9044 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| 9045 | 9045 | bool first_arg_return = want_first_arg_sret(g, fn_type_id); |
| 9046 | 9046 | bool is_async = fn_type_id->cc == CallingConventionAsync; |
| 9047 | bool is_c_abi = fn_type_id->cc == CallingConventionC; | |
| 9047 | bool is_c_abi = !calling_convention_allows_zig_types(fn_type_id->cc); | |
| 9048 | 9048 | bool prefix_arg_error_return_trace = g->have_err_ret_tracing && fn_type_can_fail(fn_type_id); |
| 9049 | 9049 | // +1 for maybe making the first argument the return value |
| 9050 | 9050 | // +1 for maybe first argument the error return trace |
src/codegen.cpp+2-2| ... | ... | @@ -2071,7 +2071,7 @@ var_ok: |
| 2071 | 2071 | |
| 2072 | 2072 | void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) { |
| 2073 | 2073 | CallingConvention cc = fn_type->data.fn.fn_type_id.cc; |
| 2074 | if (cc == CallingConventionC) { | |
| 2074 | if (!calling_convention_allows_zig_types(cc)) { | |
| 2075 | 2075 | size_t src_i = 0; |
| 2076 | 2076 | for (;;) { |
| 2077 | 2077 | if (!iter_function_params_c_abi(g, fn_type, fn_walk, src_i)) |
| ... | ... | @@ -7862,7 +7862,7 @@ static void do_code_gen(CodeGen *g) { |
| 7862 | 7862 | |
| 7863 | 7863 | FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id; |
| 7864 | 7864 | CallingConvention cc = fn_type_id->cc; |
| 7865 | bool is_c_abi = cc == CallingConventionC; | |
| 7865 | bool is_c_abi = !calling_convention_allows_zig_types(cc); | |
| 7866 | 7866 | bool want_sret = want_first_arg_sret(g, fn_type_id); |
| 7867 | 7867 | |
| 7868 | 7868 | LLVMValueRef fn = fn_llvm_value(g, fn_table_entry); |