MCPcopy Create free account
hub / github.com/ddnet/ddnet / log_logger_stdout

Function log_logger_stdout

src/base/log.cpp:385–456  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

383#endif
384
385std::unique_ptr<ILogger> log_logger_stdout()
386{
387#if !defined(CONF_FAMILY_WINDOWS)
388 // TODO: Only enable true color when COLORTERM contains "truecolor".
389 // https://github.com/termstandard/colors/tree/65bf0cd1ece7c15fa33a17c17528b02c99f1ae0b#checking-for-colorterm
390 const bool Colors = getenv("NO_COLOR") == nullptr && isatty(STDOUT_FILENO);
391 return std::make_unique<CLoggerAsync>(io_stdout(), Colors, false);
392#else
393 // If we currently have no stdout (console, file, pipe),
394 // try to attach to the console of the parent process.
395 if(GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_UNKNOWN)
396 {
397 AttachConsole(ATTACH_PARENT_PROCESS);
398 }
399
400 HANDLE pOutput = GetStdHandle(STD_OUTPUT_HANDLE);
401 if(pOutput == nullptr)
402 {
403 // There is no console, file or pipe that we can output to.
404 return nullptr;
405 }
406 dbg_assert(pOutput != INVALID_HANDLE_VALUE, "GetStdHandle failure");
407
408 const DWORD OutputType = GetFileType(pOutput);
409 if(OutputType == FILE_TYPE_CHAR)
410 {
411 DWORD OldConsoleMode = 0;
412 if(!GetConsoleMode(pOutput, &OldConsoleMode))
413 {
414 // GetConsoleMode can fail with ERROR_INVALID_HANDLE when redirecting output to "nul",
415 // which is considered a character file but cannot be used as a console.
416 dbg_assert(GetLastError() == ERROR_INVALID_HANDLE, "GetConsoleMode failure");
417 return nullptr;
418 }
419
420 const bool Colors = _wgetenv(L"NO_COLOR") == nullptr;
421
422 // Try to enable virtual terminal processing in the Windows console.
423 // See https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
424 if(!SetConsoleMode(pOutput, OldConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN))
425 {
426 // Try to downgrade mode gracefully when failing to set both.
427 if(!SetConsoleMode(pOutput, OldConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING))
428 {
429 // Fallback to old, slower Windows logging API, when failing to enable virtual terminal processing.
430 return std::make_unique<CWindowsConsoleLogger>(pOutput, Colors);
431 }
432 }
433
434 // Virtual terminal processing was enabled successfully. We can
435 // use the async logger with ANSI escape codes for colors now.
436 // We need to set the output encoding to UTF-8 manually and
437 // convert the HANDLE to an IOHANDLE to use the async logger.
438 // We assume UTF-8 is available when virtual terminal processing is.
439 dbg_assert(SetConsoleOutputCP(CP_UTF8) != 0, "SetConsoleOutputCP failure");
440 return std::make_unique<CLoggerAsync>(ConvertWindowsHandle(pOutput, _O_TEXT), Colors, false);
441 }
442 else if(OutputType == FILE_TYPE_DISK || OutputType == FILE_TYPE_PIPE)

Callers 4

mainFunction · 0.85
mainFunction · 0.85
mainFunction · 0.85

Calls 2

io_stdoutFunction · 0.85
ConvertWindowsHandleFunction · 0.85

Tested by

no test coverage detected