8271437b7da4a49af9813023b4d2820b7b1807d7
[supertux.git] / external / tinygettext / tinygettext / plural_forms.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 "plural_forms.hpp"
19
20 #include <map>
21
22 namespace tinygettext {
23 \f
24 /** 
25  *  Plural functions are used to select a string that matches a given
26  *  count. \a n is the count and the return value is the string index
27  *  used in the .po file, for example:
28  *   
29  *   msgstr[0] = "You got %d error";
30  *   msgstr[1] = "You got %d errors";        
31  *          ^-- return value of plural function 
32  */
33 unsigned int plural1(int )     { return 0; }
34 unsigned int plural2_1(int n)  { return (n != 1); }
35 unsigned int plural2_2(int n)  { return (n > 1); }
36 unsigned int plural2_mk(int n) { return n==1 || n%10==1 ? 0 : 1; }
37 unsigned int plural3_lv(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2); }
38 unsigned int plural3_ga(int n) { return static_cast<unsigned int>(n==1 ? 0 : n==2 ? 1 : 2); }
39 unsigned int plural3_lt(int n) { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2); }
40 unsigned int plural3_1(int n)  { return static_cast<unsigned int>(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
41 unsigned int plural3_sk(int n) { return static_cast<unsigned int>( (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2 ); }
42 unsigned int plural3_pl(int n) { return static_cast<unsigned int>(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); }
43 unsigned int plural3_sl(int n) { return static_cast<unsigned int>(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3); }
44 unsigned int plural4_ar(int n) { return static_cast<unsigned int>( n==1 ? 0 : n==2 ? 1 : n>=3 && n<=10 ? 2 : 3 ); }
45 \f
46 PluralForms
47 PluralForms::from_string(const std::string& str)
48 {
49   static std::map<std::string, struct PluralForms> plural_forms;
50     
51   if (plural_forms.empty())
52   {
53     // Note that the plural forms here shouldn't contain any spaces
54     plural_forms["Plural-Forms:nplurals=1;plural=0;"] = PluralForms(1, plural1);
55     plural_forms["Plural-Forms:nplurals=2;plural=(n!=1);"] = PluralForms(2, plural2_1);
56     plural_forms["Plural-Forms:nplurals=2;plural=n!=1;"] = PluralForms(2, plural2_1);
57     plural_forms["Plural-Forms:nplurals=2;plural=(n>1);"] = PluralForms(2, plural2_2);
58     plural_forms["Plural-Forms:nplurals=2;plural=n==1||n%10==1?0:1;"] = PluralForms(2, plural2_mk);
59     plural_forms["Plural-Forms:nplurals=3;plural=n%10==1&&n%100!=11?0:n!=0?1:2);"] = PluralForms(2, plural3_lv);
60     plural_forms["Plural-Forms:nplurals=3;plural=n==1?0:n==2?1:2;"] = PluralForms(3, plural3_ga);
61     plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_lt);
62     plural_forms["Plural-Forms:nplurals=3;plural=(n%10==1&&n%100!=11?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_1);
63     plural_forms["Plural-Forms:nplurals=3;plural=(n==1)?0:(n>=2&&n<=4)?1:2;"] = PluralForms(3, plural3_sk);
64     plural_forms["Plural-Forms:nplurals=3;plural=(n==1?0:n%10>=2&&n%10<=4&&(n%100<10||n%100>=20)?1:2);"] = PluralForms(3, plural3_pl);
65     plural_forms["Plural-Forms:nplurals=3;plural=(n%100==1?0:n%100==2?1:n%100==3||n%100==4?2:3);"] = PluralForms(3, plural3_sl);
66
67     plural_forms["Plural-Forms:nplurals=4;plural=n==1?0:n==2?1:n>=3&&n<=10?2:3;"]=PluralForms(4, plural4_ar);
68   }
69   
70   // Remove spaces from string before lookup
71   std::string space_less_str;
72   for(std::string::size_type i = 0; i < str.size(); ++i)
73     if (!isspace(str[i]))
74       space_less_str += str[i];
75   
76   std::map<std::string, struct PluralForms>::const_iterator it= plural_forms.find(space_less_str);
77   if (it != plural_forms.end())
78   {
79     return it->second;
80   }
81   else
82   {
83     return PluralForms();
84   }
85 }
86
87 } // namespace tinygettext
88
89 /* EOF */