LCOV - code coverage report
Current view: top level - src/util - translation.h (source / functions) Coverage Total Hit
Test: total_coverage.info Lines: 100.0 % 25 25
Test Date: 2025-01-19 05:08:01 Functions: 79.5 % 39 31
Branches: 33.5 % 206 69

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2019-present The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #ifndef BITCOIN_UTIL_TRANSLATION_H
       6                 :             : #define BITCOIN_UTIL_TRANSLATION_H
       7                 :             : 
       8                 :             : #include <tinyformat.h>
       9                 :             : #include <util/string.h>
      10                 :             : 
      11                 :             : #include <cassert>
      12                 :             : #include <functional>
      13                 :             : #include <string>
      14                 :             : 
      15                 :             : /** Translate a message to the native language of the user. */
      16                 :             : using TranslateFn = std::function<std::string(const char*)>;
      17                 :             : const extern TranslateFn G_TRANSLATION_FUN;
      18                 :             : 
      19                 :             : /**
      20                 :             :  * Bilingual messages:
      21                 :             :  *   - in GUI: user's native language + untranslated (i.e. English)
      22                 :             :  *   - in log and stderr: untranslated only
      23                 :             :  */
      24   [ +  -  +  -  :      389490 : struct bilingual_str {
           +  - ][ +  +  
          -  -  -  -  -  
           - ][ +  -  +  
          -  +  -  +  +  
          -  -  +  -  +  
           - ][ +  +  +  
             -  +  -  #  
           # ][ +  -  -  
          -  +  -  -  -  
          -  -  +  -  +  
           - ][ +  -  -  
          -  -  -  +  +  
          -  -  +  +  #  
           # ][ +  -  +  
          -  #  #  #  #  
             #  #  #  # ]
      25                 :             :     std::string original;
      26                 :             :     std::string translated;
      27                 :             : 
      28                 :         281 :     bilingual_str& operator+=(const bilingual_str& rhs)
      29                 :             :     {
      30                 :         281 :         original += rhs.original;
      31                 :         281 :         translated += rhs.translated;
      32                 :         281 :         return *this;
      33                 :             :     }
      34                 :             : 
      35                 :       16625 :     bool empty() const
      36                 :             :     {
      37   [ +  +  +  +  :       16625 :         return original.empty();
                   +  + ]
           [ +  +  +  - ]
           [ -  +  +  +  
                   -  + ]
      38                 :             :     }
      39                 :             : 
      40                 :             :     void clear()
      41                 :             :     {
      42                 :             :         original.clear();
      43                 :             :         translated.clear();
      44                 :             :     }
      45                 :             : };
      46                 :             : 
      47                 :         134 : inline bilingual_str operator+(bilingual_str lhs, const bilingual_str& rhs)
      48                 :             : {
      49   [ -  -  -  -  :         134 :     lhs += rhs;
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  +  -  -  
          -  +  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
             +  -  +  - ]
           [ +  -  +  - ]
           [ +  -  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
           [ +  -  +  -  
          +  -  +  -  +  
                      - ]
      50                 :         134 :     return lhs;
      51                 :             : }
      52                 :             : 
      53                 :             : namespace util {
      54                 :             : //! Compile-time literal string that can be translated with an optional translation function.
      55                 :             : struct TranslatedLiteral {
      56                 :             :     const char* const original;
      57                 :             :     const TranslateFn* translate_fn;
      58                 :             : 
      59                 :             :     consteval TranslatedLiteral(const char* str, const TranslateFn* fn = &G_TRANSLATION_FUN) : original{str}, translate_fn{fn} { assert(original); }
      60   [ +  -  +  + ]:       17890 :     operator std::string() const { return translate_fn && *translate_fn ? (*translate_fn)(original) : original; }
      61         [ +  - ]:        9445 :     operator bilingual_str() const { return {original, std::string{*this}}; }
      62                 :             : };
      63                 :             : 
      64                 :             : // TranslatedLiteral operators for formatting and adding to strings.
      65         [ +  - ]:        1287 : inline std::ostream& operator<<(std::ostream& os, const TranslatedLiteral& lit) { return os << std::string{lit}; }
      66                 :             : template<typename T>
      67         [ +  - ]:          70 : T operator+(const T& lhs, const TranslatedLiteral& rhs) { return lhs + static_cast<T>(rhs); }
      68                 :             : template<typename T>
      69         [ +  - ]:          60 : T operator+(const TranslatedLiteral& lhs, const T& rhs) { return static_cast<T>(lhs) + rhs; }
      70                 :             : 
      71                 :             : template <unsigned num_params>
      72                 :             : struct BilingualFmt {
      73                 :             :     const ConstevalFormatString<num_params> original;
      74                 :             :     TranslatedLiteral lit;
      75                 :             :     consteval BilingualFmt(TranslatedLiteral l) : original{l.original}, lit{l} {}
      76                 :             : };
      77                 :             : } // namespace util
      78                 :             : 
      79                 :             : consteval auto _(util::TranslatedLiteral str) { return str; }
      80                 :             : 
      81                 :             : /** Mark a bilingual_str as untranslated */
      82         [ +  - ]:      160232 : inline bilingual_str Untranslated(std::string original) { return {original, original}; }
      83                 :             : 
      84                 :             : // Provide an overload of tinyformat::format for BilingualFmt format strings and bilingual_str or TranslatedLiteral args.
      85                 :             : namespace tinyformat {
      86                 :             : template <typename... Args>
      87                 :         329 : bilingual_str format(util::BilingualFmt<sizeof...(Args)> fmt, const Args&... args)
      88                 :             : {
      89                 :           3 :     const auto original_arg{[](const auto& arg) -> const auto& {
      90                 :             :         if constexpr (std::is_same_v<decltype(arg), const bilingual_str&>) {
      91                 :           2 :             return arg.original;
      92                 :             :         } else if constexpr (std::is_same_v<decltype(arg), const util::TranslatedLiteral&>) {
      93                 :           1 :             return arg.original;
      94                 :             :         } else {
      95                 :             :             return arg;
      96                 :             :         }
      97                 :             :     }};
      98                 :           2 :     const auto translated_arg{[](const auto& arg) -> const auto& {
      99                 :             :         if constexpr (std::is_same_v<decltype(arg), const bilingual_str&>) {
     100                 :           2 :             return arg.translated;
     101                 :             :         } else {
     102                 :             :             return arg;
     103                 :             :         }
     104                 :             :     }};
     105                 :         329 :     return bilingual_str{tfm::format(fmt.original, original_arg(args)...),
     106         [ +  - ]:         658 :                          tfm::format(RuntimeFormat{std::string{fmt.lit}}, translated_arg(args)...)};
           [ +  -  +  - ]
     107   [ +  -  +  - ]:         330 : }
     108                 :             : } // namespace tinyformat
     109                 :             : 
     110                 :             : #endif // BITCOIN_UTIL_TRANSLATION_H
        

Generated by: LCOV version 2.0-1