9765d751d6c7611e44e0439c9ca4358b1e4ce4c8
[supertux.git] / external / tinygettext / tinygettext / dictionary.cpp
1 //  tinygettext - A gettext replacement that works directly on .po files
2 //  Copyright (C) 2006 Ingo Ruhnke <grumbel@gmx.de>
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License
6 //  as published by the Free Software Foundation; either version 2
7 //  of the License, or (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
18 #include <assert.h>
19 #include "log_stream.hpp"
20 #include "dictionary.hpp"
21
22 namespace tinygettext {
23 \f
24 Dictionary::Dictionary(const std::string& charset_) :
25   entries(),
26   ctxt_entries(),
27   charset(charset_),
28   plural_forms()
29 {
30 }
31
32 Dictionary::~Dictionary()
33 {
34 }
35
36 std::string
37 Dictionary::get_charset() const
38 {
39   return charset;
40 }
41
42 void
43 Dictionary::set_plural_forms(const PluralForms& plural_forms_)
44 {
45   plural_forms = plural_forms_;
46 }
47
48 PluralForms
49 Dictionary::get_plural_forms() const
50 {
51   return plural_forms;
52 }
53
54 std::string
55 Dictionary::translate_plural(const std::string& msgid, const std::string& msgid_plural, int num)
56 {
57   return translate_plural(entries, msgid, msgid_plural, num);
58 }
59
60 std::string
61 Dictionary::translate_plural(const Entries& dict, const std::string& msgid, const std::string& msgid_plural, int count)
62 {
63   Entries::const_iterator i = dict.find(msgid);
64   const std::vector<std::string>& msgstrs = i->second;
65
66   if (i != dict.end())
67   {
68     unsigned int n = 0;
69     n = plural_forms.get_plural(count);
70     assert(/*n >= 0 &&*/ n < msgstrs.size());
71
72     if (!msgstrs[n].empty())
73       return msgstrs[n];
74     else
75       if (count == 1) // default to english rules
76         return msgid;
77       else
78         return msgid_plural;
79   }
80   else
81   {
82     log_info << "Couldn't translate: " << msgid << std::endl;
83     log_info << "Candidates: " << std::endl;
84     for (i = dict.begin(); i != dict.end(); ++i)
85       log_info << "'" << i->first << "'" << std::endl;
86
87     if (count == 1) // default to english rules
88       return msgid;
89     else
90       return msgid_plural;
91   }
92 }
93
94 std::string
95 Dictionary::translate(const std::string& msgid)
96 {
97   return translate(entries, msgid);
98 }
99
100 std::string
101 Dictionary::translate(const Entries& dict, const std::string& msgid)
102 {
103   Entries::const_iterator i = dict.find(msgid);
104   if (i != dict.end() && !i->second.empty())
105   {
106     return i->second[0];
107   }
108   else
109   {
110     log_info << "Couldn't translate: " << msgid << std::endl;
111     return msgid;
112   } 
113 }
114
115 std::string
116 Dictionary::translate_ctxt(const std::string& msgctxt, const std::string& msgid)
117 {
118   CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
119   if (i != ctxt_entries.end())
120   {
121     return translate(i->second, msgid);
122   }
123   else
124   {
125     log_info << "Couldn't translate: " << msgid << std::endl;
126     return msgid;
127   }
128 }
129
130 std::string
131 Dictionary::translate_ctxt_plural(const std::string& msgctxt, 
132                                   const std::string& msgid, const std::string& msgidplural, int num)
133 {
134   CtxtEntries::iterator i = ctxt_entries.find(msgctxt);
135   if (i != ctxt_entries.end())
136   {
137     return translate_plural(i->second, msgid, msgidplural, num);
138   }
139   else
140   {
141     log_info << "Couldn't translate: " << msgid << std::endl;
142     if (num != 1) // default to english
143       return msgidplural;
144     else
145       return msgid;
146   }
147 }
148 \f
149 void
150 Dictionary::add_translation(const std::string& msgid, const std::string& ,
151                             const std::vector<std::string>& msgstrs)
152 {
153   // Do we need msgid2 for anything? its after all supplied to the
154   // translate call, so we just throw it away here
155   entries[msgid] = msgstrs;
156 }
157
158 void
159 Dictionary::add_translation(const std::string& msgid, const std::string& msgstr)
160 {
161   std::vector<std::string>& vec = entries[msgid];
162   if (vec.empty())
163   {
164     vec.push_back(msgstr);
165   }
166   else
167   {
168     log_warning << "collision in add_translation: '" 
169                 << msgid << "' -> '" << msgstr << "' vs '" << vec[0] << "'" << std::endl;
170     vec[0] = msgstr;
171   }
172 }
173
174 void
175 Dictionary::add_translation(const std::string& msgctxt, 
176                             const std::string& msgid, const std::string& msgid_plural,
177                             const std::vector<std::string>& msgstrs)
178 {
179   std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
180   if (vec.empty())
181   {
182     vec = msgstrs;
183   }
184   else
185   {
186     log_warning << "collision in add_translation(\"" << msgctxt << "\", \"" << msgid << "\", \"" << msgid_plural << "\")" << std::endl;
187     vec = msgstrs;
188   }
189 }
190
191 void
192 Dictionary::add_translation(const std::string& msgctxt, const std::string& msgid, const std::string& msgstr)
193 {
194   std::vector<std::string>& vec = ctxt_entries[msgctxt][msgid];
195   if (vec.empty())
196   {
197     vec.push_back(msgstr);
198   }
199   else
200   {
201     log_warning << "collision in add_translation(\"" << msgctxt << "\", \"" << msgid << "\")" << std::endl;
202     vec[0] = msgstr;
203   }
204 }
205 \f
206 } // namespace tinygettext
207
208 /* EOF */