refactor: Delay translation of _() literals

This is required for a future commit that requires _() to be consteval
for format literals.

Co-Authored-By: Ryan Ofsky <ryan@ofsky.org>
This commit is contained in:
MarcoFalke 2024-10-09 13:23:28 +02:00
parent 35bf426e02
commit eeee6cf2ff
No known key found for this signature in database
8 changed files with 43 additions and 34 deletions

View file

@ -30,7 +30,7 @@ void BanMan::LoadBanlist()
{
LOCK(m_banned_mutex);
if (m_client_interface) m_client_interface->InitMessage(_("Loading banlist…").translated);
if (m_client_interface) m_client_interface->InitMessage(_("Loading banlist…"));
const auto start{SteadyClock::now()};
if (m_ban_db.Read(m_banned)) {

View file

@ -95,7 +95,7 @@ std::string LicenseInfo()
strprintf(_("The source code is available from %s."), URL_SOURCE_CODE).translated +
"\n" +
"\n" +
_("This is experimental software.").translated + "\n" +
_("This is experimental software.") + "\n" +
strprintf(_("Distributed under the MIT software license, see the accompanying file %s or %s"), "COPYING", "<https://opensource.org/licenses/MIT>").translated +
"\n";
}

View file

@ -1244,8 +1244,8 @@ static ChainstateLoadResult InitAndLoadChainstate(
_("Error reading from database, shutting down."),
"", CClientUIInterface::MSG_ERROR);
};
uiInterface.InitMessage(_("Loading block index…").translated);
auto catch_exceptions = [](auto&& f) {
uiInterface.InitMessage(_("Loading block index…"));
auto catch_exceptions = [](auto&& f) -> ChainstateLoadResult {
try {
return f();
} catch (const std::exception& e) {
@ -1255,7 +1255,7 @@ static ChainstateLoadResult InitAndLoadChainstate(
};
auto [status, error] = catch_exceptions([&] { return LoadChainstate(chainman, cache_sizes, options); });
if (status == node::ChainstateLoadStatus::SUCCESS) {
uiInterface.InitMessage(_("Verifying blocks…").translated);
uiInterface.InitMessage(_("Verifying blocks…"));
if (chainman.m_blockman.m_have_pruned && options.check_blocks > MIN_BLOCKS_TO_KEEP) {
LogWarning("pruned datadir may not have more than %d blocks; only checking available blocks\n",
MIN_BLOCKS_TO_KEEP);
@ -1418,7 +1418,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// Initialize addrman
assert(!node.addrman);
uiInterface.InitMessage(_("Loading P2P addresses…").translated);
uiInterface.InitMessage(_("Loading P2P addresses…"));
auto addrman{LoadAddrman(*node.netgroupman, args)};
if (!addrman) return InitError(util::ErrorString(addrman));
node.addrman = std::move(*addrman);
@ -1703,7 +1703,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (chainman.m_blockman.m_blockfiles_indexed) {
LOCK(cs_main);
for (Chainstate* chainstate : chainman.GetAll()) {
uiInterface.InitMessage(_("Pruning blockstore…").translated);
uiInterface.InitMessage(_("Pruning blockstore…"));
chainstate->PruneAndFlush();
}
}
@ -1999,7 +1999,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// ChainstateManager's active tip.
SetRPCWarmupFinished();
uiInterface.InitMessage(_("Done loading").translated);
uiInterface.InitMessage(_("Done loading"));
for (const auto& client : node.chain_clients) {
client->start(scheduler);

View file

@ -3296,7 +3296,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
}
if (m_client_interface) {
m_client_interface->InitMessage(_("Starting network threads…").translated);
m_client_interface->InitMessage(_("Starting network threads…"));
}
fAddressesInitialized = true;

View file

@ -6,12 +6,15 @@
#define BITCOIN_UTIL_TRANSLATION_H
#include <tinyformat.h>
#include <util/string.h>
#include <cassert>
#include <functional>
#include <string>
/** Translate a message to the native language of the user. */
const extern std::function<std::string(const char*)> G_TRANSLATION_FUN;
using TranslateFn = std::function<std::string(const char*)>;
const extern TranslateFn G_TRANSLATION_FUN;
/**
* Bilingual messages:
@ -47,6 +50,27 @@ inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs)
return lhs;
}
namespace util {
//! Compile-time literal string that can be translated with an optional translation function.
struct TranslatedLiteral {
const char* const original;
const TranslateFn* translate_fn;
consteval TranslatedLiteral(const char* str, const TranslateFn* fn = &G_TRANSLATION_FUN) : original{str}, translate_fn{fn} { assert(original); }
operator std::string() const { return translate_fn && *translate_fn ? (*translate_fn)(original) : original; }
operator bilingual_str() const { return {original, std::string{*this}}; }
};
// TranslatedLiteral operators for formatting and adding to strings.
inline std::ostream& operator<<(std::ostream& os, const TranslatedLiteral& lit) { return os << std::string{lit}; }
template<typename T>
T operator+(const T& lhs, const TranslatedLiteral& rhs) { return lhs + static_cast<T>(rhs); }
template<typename T>
T operator+(const TranslatedLiteral& lhs, const T& rhs) { return static_cast<T>(lhs) + rhs; }
} // namespace util
consteval auto _(util::TranslatedLiteral str) { return str; }
/** Mark a bilingual_str as untranslated */
inline bilingual_str Untranslated(std::string original) { return {original, original}; }
@ -67,19 +91,4 @@ bilingual_str format(const bilingual_str& fmt, const Args&... args)
}
} // namespace tinyformat
struct ConstevalStringLiteral {
const char* const lit;
consteval ConstevalStringLiteral(const char* str) : lit{str} {}
consteval ConstevalStringLiteral(std::nullptr_t) = delete;
};
/**
* Translation function.
* If no translation function is set, simply return the input.
*/
inline bilingual_str _(ConstevalStringLiteral str)
{
return bilingual_str{str.lit, G_TRANSLATION_FUN ? (G_TRANSLATION_FUN)(str.lit) : str.lit};
}
#endif // BITCOIN_UTIL_TRANSLATION_H

View file

@ -52,7 +52,7 @@ bool VerifyWallets(WalletContext& context)
LogPrintf("Using wallet directory %s\n", fs::PathToString(GetWalletDir()));
chain.initMessage(_("Verifying wallet(s)…").translated);
chain.initMessage(_("Verifying wallet(s)…"));
// For backwards compatibility if an unnamed top level wallet exists in the
// wallets directory, include it in the default list of wallets to load.
@ -135,7 +135,7 @@ bool LoadWallets(WalletContext& context)
if (!database && status == DatabaseStatus::FAILED_NOT_FOUND) {
continue;
}
chain.initMessage(_("Loading wallet…").translated);
chain.initMessage(_("Loading wallet…"));
std::shared_ptr<CWallet> pwallet = database ? CWallet::Create(context, name, std::move(database), options.create_flags, error, warnings) : nullptr;
if (!warnings.empty()) chain.initWarning(Join(warnings, Untranslated("\n")));
if (!pwallet) {

View file

@ -534,7 +534,7 @@ RPCHelpMan importwallet()
// Use uiInterface.ShowProgress instead of pwallet.ShowProgress because pwallet.ShowProgress has a cancel button tied to AbortRescan which
// we don't want for this progress bar showing the import progress. uiInterface.ShowProgress does not have a cancel button.
pwallet->chain().showProgress(strprintf("%s %s", pwallet->GetDisplayName(), _("Importing…").translated), 0, false); // show progress dialog in GUI
pwallet->chain().showProgress(strprintf("%s %s", pwallet->GetDisplayName(), _("Importing…")), 0, false); // show progress dialog in GUI
std::vector<std::tuple<CKey, int64_t, bool, std::string>> keys;
std::vector<std::pair<CScript, int64_t>> scripts;
while (file.good()) {

View file

@ -280,7 +280,7 @@ std::shared_ptr<CWallet> LoadWalletInternal(WalletContext& context, const std::s
return nullptr;
}
context.chain->initMessage(_("Loading wallet…").translated);
context.chain->initMessage(_("Loading wallet…"));
std::shared_ptr<CWallet> wallet = CWallet::Create(context, name, std::move(database), options.create_flags, error, warnings);
if (!wallet) {
error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error;
@ -430,7 +430,7 @@ std::shared_ptr<CWallet> CreateWallet(WalletContext& context, const std::string&
}
// Make the wallet
context.chain->initMessage(_("Loading wallet…").translated);
context.chain->initMessage(_("Loading wallet…"));
std::shared_ptr<CWallet> wallet = CWallet::Create(context, name, std::move(database), wallet_creation_flags, error, warnings);
if (!wallet) {
error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error;
@ -1903,7 +1903,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
fast_rescan_filter ? "fast variant using block filters" : "slow variant inspecting all blocks");
fAbortRescan = false;
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…").translated), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption)
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…")), 0); // show rescan progress in GUI as dialog or on splashscreen, if rescan required on startup (e.g. due to corruption)
uint256 tip_hash = WITH_LOCK(cs_wallet, return GetLastBlockHash());
uint256 end_hash = tip_hash;
if (max_height) chain().findAncestorByHeight(tip_hash, *max_height, FoundBlock().hash(end_hash));
@ -1918,7 +1918,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
m_scanning_progress = 0;
}
if (block_height % 100 == 0 && progress_end - progress_begin > 0.0) {
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…").translated), std::max(1, std::min(99, (int)(m_scanning_progress * 100))));
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…")), std::max(1, std::min(99, (int)(m_scanning_progress * 100))));
}
bool next_interval = reserver.now() >= current_time + INTERVAL_TIME;
@ -2015,7 +2015,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
WalletLogPrintf("Scanning current mempool transactions.\n");
WITH_LOCK(cs_wallet, chain().requestMempoolTransactions(*this));
}
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…").translated), 100); // hide progress dialog in GUI
ShowProgress(strprintf("%s %s", GetDisplayName(), _("Rescanning…")), 100); // hide progress dialog in GUI
if (block_height && fAbortRescan) {
WalletLogPrintf("Rescan aborted at block %d. Progress=%f\n", block_height, progress_current);
result.status = ScanResult::USER_ABORT;
@ -3353,7 +3353,7 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
}
}
chain.initMessage(_("Rescanning…").translated);
chain.initMessage(_("Rescanning…"));
walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
{