| 428 | } |
| 429 | |
| 430 | int wrapApplication( |
| 431 | int (*innerApplication)(int argc, char* argv[]), int argc, char* argv[], std::string_view appName) |
| 432 | { |
| 433 | #if defined _WIN32 |
| 434 | (void)attachParentConsole(); |
| 435 | SetConsoleOutputCP(CP_UTF8); |
| 436 | #endif |
| 437 | rawStdout = std::make_unique<std::ostream>(std::cout.rdbuf()); |
| 438 | rawStderr = std::make_unique<std::ostream>(std::cerr.rdbuf()); |
| 439 | rawStderrMutex = std::make_unique<std::mutex>(); |
| 440 | |
| 441 | #if defined(_WIN32) && defined(_DEBUG) |
| 442 | // Redirect cout and cerr to VS debug output when running in debug mode |
| 443 | sb.open(DebugOutput()); |
| 444 | std::cout.rdbuf(&sb); |
| 445 | std::cerr.rdbuf(&sb); |
| 446 | #else |
| 447 | constexpr std::size_t bufferCapacity = 1024; |
| 448 | |
| 449 | bufferedOut.open(Tee(Buffer(bufferCapacity, globalBuffer), Coloured(*rawStdout))); |
| 450 | bufferedErr.open(Tee(Buffer(bufferCapacity, globalBuffer), Coloured(*rawStderr))); |
| 451 | |
| 452 | std::cout.rdbuf(&bufferedOut); |
| 453 | std::cerr.rdbuf(&bufferedErr); |
| 454 | #endif |
| 455 | |
| 456 | int ret = 0; |
| 457 | try |
| 458 | { |
| 459 | if (const auto env = std::getenv("OPENMW_DISABLE_CRASH_CATCHER"); |
| 460 | env == nullptr || Misc::StringUtils::toNumeric<int>(env, 0) == 0) |
| 461 | { |
| 462 | #if defined(_WIN32) |
| 463 | const std::string crashDumpName = Misc::StringUtils::lowerCase(appName) + "-crash.dmp"; |
| 464 | const std::string freezeDumpName = Misc::StringUtils::lowerCase(appName) + "-freeze.dmp"; |
| 465 | std::filesystem::path dumpDirectory = std::filesystem::temp_directory_path(); |
| 466 | PWSTR userProfile = nullptr; |
| 467 | if (SUCCEEDED(SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &userProfile))) |
| 468 | { |
| 469 | dumpDirectory = userProfile; |
| 470 | } |
| 471 | CoTaskMemFree(userProfile); |
| 472 | Crash::CrashCatcher crashy(argc, argv, dumpDirectory, crashDumpName, freezeDumpName); |
| 473 | #else |
| 474 | const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log"; |
| 475 | // install the crash handler as soon as possible. |
| 476 | crashCatcherInstall(argc, argv, std::filesystem::temp_directory_path() / crashLogName); |
| 477 | #endif |
| 478 | ret = innerApplication(argc, argv); |
| 479 | } |
| 480 | else |
| 481 | ret = innerApplication(argc, argv); |
| 482 | } |
| 483 | catch (const std::exception& e) |
| 484 | { |
| 485 | #if (defined(__APPLE__) || defined(__linux) || defined(__unix) || defined(__posix)) |
| 486 | if (!isatty(fileno(stdin))) |
| 487 | #endif |
no test coverage detected