Make the logging subsystem noexcept. This facilitates changes such as #17507 by making it possible to log in noexcept context.
First, adds a function tfm::format_noexcept that works like tfm::format for use in noexcept context if the format string and number of arguments are guaranteed to be correct (for example, if it is trivial like "%02x"). It will abort on any tinyformat error. This is used in utility functions, not for the logging strings itself, as formatting exceptions there are internally caught and logged in LogPrintf (for better troubleshooting of the complex arbitrary formatting expressions used there).
Then, go through the call hierarchy and make functions noexcept after checking them (see individual commits):
LogInstance
LogAcceptCategory
Logger::WillLogCategory
LogPrintf
Logger::Enabled
LogPrintStr
LogEscapeMessage
util::ThreadGetInternalName()
LogTimestampStr
GetTimeMicros
FormatISO8601DateTime
GetMockTime
fsbridge::fopen
FileWriteStr
Though I've checked these functions carefully, it is possible that I missed a function down the call tree. Please let me know if so.
The only functions I'm slightly uncertain about are the boost posix_time functions in
GetTimeMicros/GetTimeMillis, but I could not find any documented exceptions in
https://www.boost.org/doc/libs/1_71_0/doc/html/date_time/posix_time.html (fixed, thanks to practicalswift)
(I know the m_print_callbacks can potentially throw, there is as far as I saw no way to guarantee std::function as noexcept. I leave this as an responsibility to who registers it. FWIW, this functionality is only used as part of the test framework.)
(Also, thinking of it, any kind of allocation in C++ can except with bad_alloc&, including inside string manipulation, which is almost 100% of the code here. If that's an issue, I'm no longer convinced this is possible at all)