LCOV - code coverage report
Current view: top level - source/third_party/tinygettext/src - dictionary.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 101 1.0 %
Date: 2023-01-19 00:18:29 Functions: 2 18 11.1 %

          Line data    Source code
       1             : // tinygettext - A gettext replacement that works directly on .po files
       2             : // Copyright (c) 2006 Ingo Ruhnke <grumbel@gmail.com>
       3             : //
       4             : // This software is provided 'as-is', without any express or implied
       5             : // warranty. In no event will the authors be held liable for any damages
       6             : // arising from the use of this software.
       7             : //
       8             : // Permission is granted to anyone to use this software for any purpose,
       9             : // including commercial applications, and to alter it and redistribute it
      10             : // freely, subject to the following restrictions:
      11             : //
      12             : // 1. The origin of this software must not be misrepresented; you must not
      13             : //    claim that you wrote the original software. If you use this software
      14             : //    in a product, an acknowledgement in the product documentation would be
      15             : //    appreciated but is not required.
      16             : // 2. Altered source versions must be plainly marked as such, and must not be
      17             : //    misrepresented as being the original software.
      18             : // 3. This notice may not be removed or altered from any source distribution.
      19             : 
      20             : #include "precompiled.h"
      21             : 
      22             : #include <assert.h>
      23             : 
      24             : #include "tinygettext/log_stream.hpp"
      25             : #include "tinygettext/dictionary.hpp"
      26             : 
      27             : namespace tinygettext {
      28             : 
      29             : namespace {
      30             : 
      31           0 : std::ostream& operator<<(std::ostream& o, const std::vector<std::string>& v)
      32             : {
      33           0 :   for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it)
      34             :   {
      35           0 :     if (it != v.begin())
      36           0 :       o << ", ";
      37           0 :     o << "'" << *it << "'";
      38             :   }
      39           0 :   return o;
      40             : }
      41             : 
      42             : } // namespace
      43             : 
      44           0 : Dictionary::Dictionary(const std::string& charset_) :
      45             :   entries(),
      46             :   ctxt_entries(),
      47             :   charset(charset_),
      48             :   plural_forms(),
      49             :   m_has_fallback(false),
      50           0 :   m_fallback()
      51             : {
      52           0 : }
      53             : 
      54           0 : Dictionary::~Dictionary()
      55             : {
      56           0 : }
      57             : 
      58             : std::string
      59           0 : Dictionary::get_charset() const
      60             : {
      61           0 :   return charset;
      62             : }
      63             : 
      64             : void
      65           0 : Dictionary::set_plural_forms(const PluralForms& plural_forms_)
      66             : {
      67           0 :   plural_forms = plural_forms_;
      68           0 : }
      69             : 
      70             : PluralForms
      71           0 : Dictionary::get_plural_forms() const
      72             : {
      73           0 :   return plural_forms;
      74             : }
      75             : 
      76             : std::string
      77           0 : Dictionary::translate_plural(const std::string& msgid, const std::string& msgid_plural, int num) const
      78             : {
      79           0 :   return translate_plural(entries, msgid, msgid_plural, num);
      80             : }
      81             : 
      82             : std::string
      83           0 : Dictionary::translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgid_plural, int count) const
      84             : {
      85           0 :   Entries::const_iterator it = dict.find(msgid);
      86           0 :   if (it != dict.end())
      87             :   {
      88           0 :     unsigned int n = plural_forms.get_plural(count);
      89           0 :     const std::vector<std::string>& msgstrs = it->second;
      90           0 :     if (n >= msgstrs.size())
      91             :     {
      92           0 :       log_error << "Plural translation not available (and not set to empty): '" << msgid << "'" << std::endl;
      93           0 :       log_error << "Missing plural form: " << n << std::endl;
      94           0 :       return msgid;
      95             :     }
      96             : 
      97           0 :     if (!msgstrs[n].empty())
      98           0 :       return msgstrs[n];
      99             :     else
     100           0 :       if (count == 1) // default to english rules
     101           0 :         return msgid;
     102             :       else
     103           0 :         return msgid_plural;
     104             :   }
     105             :   else
     106             :   {
     107           0 :     log_info << "Couldn't translate: " << msgid << std::endl;
     108           0 :     log_info << "Candidates: " << std::endl;
     109           0 :     for (it = dict.begin(); it != dict.end(); ++it)
     110           0 :       log_info << "'" << it->first << "'" << std::endl;
     111             : 
     112           0 :     if (count == 1) // default to english rules
     113           0 :       return msgid;
     114             :     else
     115           0 :       return msgid_plural;
     116             :   }
     117             : }
     118             : 
     119             : std::string
     120           0 : Dictionary::translate(const std::string& msgid) const
     121             : {
     122           0 :   return translate(entries, msgid);
     123             : }
     124             : 
     125             : std::string
     126           0 : Dictionary::translate(const Entries& dict, const std::string& msgid) const
     127             : {
     128           0 :   Entries::const_iterator i = dict.find(msgid);
     129           0 :   if (i != dict.end() && !i->second.empty())
     130             :   {
     131           0 :     return i->second[0];
     132             :   }
     133             :   else
     134             :   {
     135           0 :     log_info << "Couldn't translate: " << msgid << std::endl;
     136             : 
     137           0 :     if (m_has_fallback) return m_fallback->translate(msgid);
     138           0 :     else return msgid;
     139             :   }
     140             : }
     141             : 
     142             : std::string
     143           0 : Dictionary::translate_ctxt(const std::string& msgctxt, const std::string& msgid) const
     144             : {
     145           0 :   CtxtEntries::const_iterator i = ctxt_entries.find(msgctxt);
     146           0 :   if (i != ctxt_entries.end())
     147             :   {
     148           0 :     return translate(i->second, msgid);
     149             :   }
     150             :   else
     151             :   {
     152           0 :     log_info << "Couldn't translate: " << msgid << std::endl;
     153           0 :     return msgid;
     154             :   }
     155             : }
     156             : 
     157             : std::string
     158           0 : Dictionary::translate_ctxt_plural(const std::string& msgctxt,
     159             :                                   const std::string& msgid, const std::string& msgidplural, int num) const
     160             : {
     161           0 :   CtxtEntries::const_iterator i = ctxt_entries.find(msgctxt);
     162           0 :   if (i != ctxt_entries.end())
     163             :   {
     164           0 :     return translate_plural(i->second, msgid, msgidplural, num);
     165             :   }
     166             :   else
     167             :   {
     168           0 :     log_info << "Couldn't translate: " << msgid << std::endl;
     169           0 :     if (num != 1) // default to english
     170           0 :       return msgidplural;
     171             :     else
     172           0 :       return msgid;
     173             :   }
     174             : }
     175             : 
     176             : void
     177           0 : Dictionary::add_translation(const std::string& msgid, const std::string& msgid_plural,
     178             :                             const std::vector<std::string>& msgstrs)
     179             : {
     180           0 :   std::vector<std::string>& vec = entries[msgid];
     181           0 :   if (vec.empty())
     182             :   {
     183           0 :     vec = msgstrs;
     184             :   }
     185           0 :   else if (vec != msgstrs)
     186             :   {
     187           0 :     log_warning << "collision in add_translation: '"
     188             :                 << msgid << "', '" << msgid_plural
     189           0 :                 << "' -> [" << vec << "] vs [" << msgstrs << "]" << std::endl;
     190           0 :     vec = msgstrs;
     191             :   }
     192           0 : }
     193             : 
     194             : void
     195           0 : Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
     196             : {
     197           0 :   std::vector<std::string>& vec = entries[msgid];
     198           0 :   if (vec.empty())
     199             :   {
     200           0 :     vec.push_back(msgstr);
     201             :   }
     202           0 :   else if (vec[0] != msgstr)
     203             :   {
     204           0 :     log_warning << "collision in add_translation: '"
     205           0 :                 << msgid << "' -> '" << msgstr << "' vs '" << vec[0] << "'" << std::endl;
     206           0 :     vec[0] = msgstr;
     207             :   }
     208           0 : }
     209             : 
     210             : void
     211           0 : Dictionary::add_translation(const std::string& msgctxt,
     212             :                             const std::string& msgid, const std::string& msgid_plural,
     213             :                             const std::vector<std::string>& msgstrs)
     214             : {
     215           0 :   std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
     216           0 :   if (vec.empty())
     217             :   {
     218           0 :     vec = msgstrs;
     219             :   }
     220           0 :   else if (vec != msgstrs)
     221             :   {
     222           0 :     log_warning << "collision in add_translation: '"
     223             :                 << msgctxt << "', '" << msgid << "', '" << msgid_plural
     224           0 :                 << "' -> [" << vec << "] vs [" << msgstrs << "]" << std::endl;
     225           0 :     vec = msgstrs;
     226             :   }
     227           0 : }
     228             : 
     229             : void
     230           0 : Dictionary::add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr)
     231             : {
     232           0 :   std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
     233           0 :   if (vec.empty())
     234             :   {
     235           0 :     vec.push_back(msgstr);
     236             :   }
     237           0 :   else if (vec[0] != msgstr)
     238             :   {
     239           0 :     log_warning << "collision in add_translation: '"
     240             :                 << msgctxt << "', '" << msgid
     241           0 :                 << "' -> '" << vec[0] << "' vs '" << msgstr << "'" << std::endl;
     242           0 :     vec[0] = msgstr;
     243             :   }
     244           0 : }
     245             : 
     246           3 : } // namespace tinygettext
     247             : 
     248             : /* EOF */

Generated by: LCOV version 1.13