Check translated strprintf
calls at compile time to prevent tinyformat::format_error
exceptions when the original string does not contain format specifiers matching the number of formatted arguments. Exceptions are still thrown if the translated strings do not contain the right number of format specifiers.
Most of the commits in this PR are code cleanup needed to make the compile time checks apply, but the relevant commits implementing the checks are simple:
c49aaff65280
util: Add bilingual_lit type2b4668ec6877
scripted-diff: Replace _() with _<>() for compile time format checking649b9b62ecfc
util: Check bilingual_str format strings at compile time
This PR is alternative to #31061, that has messier syntax than #31061, but a cleaner implementation and a less confusing API. Unlike #31061, the _
and Untranslated
functions continue to return bilingual_str
structs with original
and translated
members instead of returning different structs with lit
and translate()
members. This approach is less confusing because it means there’s a single type for representing bilingual values, and means that unlike #31061, code that is not doing string formatting does not need to change. Only code actually using tinyformat changes in this PR.
A drawback to this change compared to #31061 is that syntax for translated format strings is messier:
0- return strprintf(_("%s is set very high!"), optname);
1+ return strprintf(_<"%s is set very high!">(), optname);
But that’s also a good way of showing that the string is used at compile time, and without this, there’s no way to get the _
function to return a type that is compatible with bilingual_str.
Marking this as a draft because I need to think about differences of the two approaches. But I am inclined to think this approach is better because it is not fighting with compiler to be able evaluate function arguments at compile time, when this is supposed to be what template arguments are for https://old.reddit.com/r/cpp/comments/lxmv2z/allowing_parameters_of_consteval_function_to_be/gpp40lf/