1
// $Id: dictionary_manager.cpp 3353 2007-10-28 08:05:10Z grumbel $
3
// TinyGetText - A small flexible gettext() replacement
4
// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
6
// This program is free software; you can redistribute it and/or
7
// modify it under the terms of the GNU General Public License
8
// as published by the Free Software Foundation; either version 2
9
// of the License, or (at your option) any later version.
11
// This program is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
// GNU General Public License for more details.
16
// You should have received a copy of the GNU General Public License
17
// along with this program; if not, write to the Free Software
18
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
#include <sys/types.h>
26
# include "../win32/uce_dirent.h"
30
#include "dictionary_manager.hpp"
31
#include "po_file_reader.hpp"
33
namespace TinyGetText {
35
static bool has_suffix(const std::string& lhs, const std::string rhs)
37
if (lhs.length() < rhs.length())
40
return lhs.compare(lhs.length() - rhs.length(), rhs.length(), rhs) == 0;
43
DictionaryManager::DictionaryManager()
44
: empty_dict(&lang_en, "ISO-8859-1"),
46
current_dict(&empty_dict)
52
// setup language from environment vars
53
const char* lang = getenv("LC_ALL");
55
lang = getenv("LC_MESSAGES");
57
lang = getenv("LANG");
60
set_current_dictionary(lang);
64
DictionaryManager::parseLocaleAliases()
66
// try to parse language alias list
67
std::ifstream in("/usr/share/locale/locale.alias");
70
while(in.good() && !in.eof()) {
71
while(isspace(c) && !in.eof())
74
if(c == '#') { // skip comments
75
while(c != '\n' && !in.eof())
81
while(!isspace(c) && !in.eof()) {
85
while(isspace(c) && !in.eof())
88
while(!isspace(c) && !in.eof()) {
96
set_language_alias(alias, lang);
101
DictionaryManager::get_dictionary(LanguageDef* lang)
103
Dictionaries::iterator i = dictionaries.find(lang);
104
if (i != dictionaries.end())
108
else // Dictionary for languages lang isn't loaded, so we load it
110
Dictionary& dict = dictionaries[lang];
112
dict.set_language(lang);
114
for(SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
116
DIR* dir = opendir(p->c_str());
119
std::cerr << "TinyGetText: Error: opendir() failed on " << *p << std::endl;
124
while((ent = readdir(dir)))
126
if (std::string(ent->d_name) == std::string(lang->code) + ".po")
128
std::string pofile = *p + "/" + ent->d_name;
129
std::ifstream in(pofile.c_str());
132
std::cerr << "Error: Failure file opening: " << pofile << std::endl;
136
POFileReader reader(in, dict);
148
std::set<std::string>
149
DictionaryManager::get_languages()
151
std::set<std::string> languages;
153
for (SearchPath::iterator p = search_path.begin(); p != search_path.end(); ++p)
155
DIR* dir = opendir(p->c_str());
158
std::cerr << "Error: opendir() failed on " << *p << std::endl;
163
while((ent = readdir(dir)))
165
if (has_suffix(ent->d_name, ".po"))
167
std::string filename = ent->d_name;
168
languages.insert(filename.substr(0, filename.length()-3));
178
DictionaryManager::set_current_dictionary(const std::string& lang)
180
LanguageDef* new_lang = get_canonical_language(lang);
183
std::cout << "Error: DictionaryManager: Couldn't find LanguageDef for '" << lang
184
<< "', leaving current dictionary unchanged" << std::endl;
189
// std::cout << "Language: supplied: '" << lang << "' -> canonical: '" << language->code << "'" << std::endl;
190
current_dict = &(get_dictionary(language));
195
DictionaryManager::set_language_alias(const std::string& alias,
196
const std::string& language)
198
language_aliases.insert(std::make_pair(alias, language));
202
DictionaryManager::get_canonical_language(const std::string& spec)
204
std::string lang_code = spec;
206
// Check for language aliases
207
Aliases::iterator i = language_aliases.find(spec);
208
if(i != language_aliases.end())
209
lang_code = i->second;
211
// Cut away any specification of the codeset (i.e. de_DE.ISO-8859-1)
212
std::string::size_type s = lang_code.find_first_of(".");
214
if (s != std::string::npos)
215
lang_code = std::string(spec, 0, s);
217
LanguageDef* lang_def = get_language_def(lang_code);
220
else if (lang_code.length() == 5) // 'en_EN' failed, try 'en'
221
return get_language_def(lang_code.substr(0, 2));
227
DictionaryManager::add_directory(const std::string& pathname)
229
dictionaries.clear(); // adding directories invalidates cache
230
search_path.push_back(pathname);
231
current_dict = &(get_dictionary(language));
234
} // namespace TinyGetText