| 173 | |
| 174 | |
| 175 | static void mi_cdecl mi_out_stderr(const char* msg, void* arg) { |
| 176 | MI_UNUSED(arg); |
| 177 | if (msg == NULL) return; |
| 178 | #ifdef _WIN32 |
| 179 | // on windows with redirection, the C runtime cannot handle locale dependent output |
| 180 | // after the main thread closes so we use direct console output. |
| 181 | if (!_mi_preloading()) { |
| 182 | // _cputs(msg); // _cputs cannot be used at is aborts if it fails to lock the console |
| 183 | static HANDLE hcon = INVALID_HANDLE_VALUE; |
| 184 | static bool hconIsConsole; |
| 185 | if (hcon == INVALID_HANDLE_VALUE) { |
| 186 | CONSOLE_SCREEN_BUFFER_INFO sbi; |
| 187 | hcon = GetStdHandle(STD_ERROR_HANDLE); |
| 188 | hconIsConsole = ((hcon != INVALID_HANDLE_VALUE) && GetConsoleScreenBufferInfo(hcon, &sbi)); |
| 189 | } |
| 190 | const size_t len = strlen(msg); |
| 191 | if (len > 0 && len < UINT32_MAX) { |
| 192 | DWORD written = 0; |
| 193 | if (hconIsConsole) { |
| 194 | WriteConsoleA(hcon, msg, (DWORD)len, &written, NULL); |
| 195 | } |
| 196 | else if (hcon != INVALID_HANDLE_VALUE) { |
| 197 | // use direct write if stderr was redirected |
| 198 | WriteFile(hcon, msg, (DWORD)len, &written, NULL); |
| 199 | } |
| 200 | else { |
| 201 | // finally fall back to fputs after all |
| 202 | fputs(msg, stderr); |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | #else |
| 207 | fputs(msg, stderr); |
| 208 | #endif |
| 209 | } |
| 210 | |
| 211 | // Since an output function can be registered earliest in the `main` |
| 212 | // function we also buffer output that happens earlier. When |
no test coverage detected