The SWORD Project  1.9.0.svnversion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
localemgr.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * localemgr.cpp - implementation of class LocaleMgr used to interact with
4  * registered locales for a SWORD installation
5  *
6  * $Id: localemgr.cpp 3822 2020-11-03 18:54:47Z scribe $
7  *
8  * Copyright 2000-2013 CrossWire Bible Society (http://www.crosswire.org)
9  * CrossWire Bible Society
10  * P. O. Box 2528
11  * Tempe, AZ 85280-2528
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU General Public License as published by the
15  * Free Software Foundation version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but
18  * WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20  * General Public License for more details.
21  *
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <fcntl.h>
27 
28 #include <sys/stat.h>
29 #include <dirent.h>
30 
31 #include <swmgr.h>
32 #include <utilstr.h>
33 
34 #include <stringmgr.h>
35 #include <filemgr.h>
36 #include <localemgr.h>
37 #include <swlocale.h>
38 #include <swlog.h>
39 
40 
42 
43 
45 
46 
48 public:
52 
53 
55  if (!systemLocaleMgr) {
57  }
58 
59  return systemLocaleMgr;
60 }
61 
62 
64  if (systemLocaleMgr)
65  delete systemLocaleMgr;
66  systemLocaleMgr = newLocaleMgr;
67  SWLocale *locale = new SWLocale(0);
68  systemLocaleMgr->locales->insert(LocaleMap::value_type(locale->getName(), locale));
69 }
70 
71 
72 LocaleMgr::LocaleMgr(const char *iConfigPath) {
73  locales = new LocaleMap();
74  char *prefixPath = 0;
75  char *configPath = 0;
76  SWConfig *sysConf = 0;
77  char configType = 0;
78  SWBuf path;
79  std::list<SWBuf> augPaths;
80  ConfigEntMap::iterator entry;
81 
83 
84  if (!iConfigPath) {
85  SWLOGTI("LOOKING UP LOCALE DIRECTORY...");
86  SWMgr::findConfig(&configType, &prefixPath, &configPath, &augPaths, &sysConf);
87  if (sysConf) {
88  if ((entry = sysConf->getSection("Install").find("LocalePath")) != sysConf->getSection("Install").end()) {
89  configType = 9; // our own
90  stdstr(&prefixPath, (char *)entry->second.c_str());
91  SWLOGTI("LocalePath provided in sysConfig.");
92  }
93  }
94  SWLOGTI("LOOKING UP LOCALE DIRECTORY COMPLETE.");
95  }
96  else {
97  loadConfigDir(iConfigPath);
98  }
99 
100  if (prefixPath) {
101  switch (configType) {
102  case 2:
103  int i;
104  for (i = (int)strlen(configPath)-1; ((i) && (configPath[i] != '/') && (configPath[i] != '\\')); i--);
105  configPath[i] = 0;
106  path = configPath;
107  path += "/";
108  break;
109  default:
110  path = prefixPath;
111  if ((prefixPath[strlen(prefixPath)-1] != '\\') && (prefixPath[strlen(prefixPath)-1] != '/'))
112  path += "/";
113 
114  break;
115  }
116  if (FileMgr::existsDir(path.c_str(), "locales.d")) {
117  path += "locales.d";
118  loadConfigDir(path.c_str());
119  }
120  }
121 
122  if (augPaths.size() && configType != 9) { //load locale files from all augmented paths
123  std::list<SWBuf>::iterator it = augPaths.begin();
124  std::list<SWBuf>::iterator end = augPaths.end();
125 
126  for (;it != end; ++it) {
127  if (FileMgr::existsDir((*it).c_str(), "locales.d")) {
128  SWBuf path = (*it) + "locales.d";
129  loadConfigDir(path.c_str());
130  }
131  }
132  }
133 
134  // Locales will be invalidated if you change the StringMgr
135  // So only use the default hardcoded locale and let the
136  // frontends change the locale if they want
138 
139  if (prefixPath)
140  delete [] prefixPath;
141 
142  if (configPath)
143  delete [] configPath;
144 
145  if (sysConf)
146  delete sysConf;
147 }
148 
149 
151  if (defaultLocaleName)
152  delete [] defaultLocaleName;
153  deleteLocales();
154  delete locales;
155 }
156 
157 
158 void LocaleMgr::loadConfigDir(const char *ipath) {
159  LocaleMap::iterator it;
160  SWLOGD("LocaleMgr::loadConfigDir loading %s", ipath);
161 
162  SWBuf baseDir = ipath;
163  if (!baseDir.endsWith('/') && !baseDir.endsWith('\\')) baseDir += '/';
164 
165  std::vector<DirEntry> dirList = FileMgr::getDirList(ipath);
166  for (unsigned int i = 0; i < dirList.size(); ++i) {
167  if (dirList[i].name.endsWith(".conf")) {
168  SWBuf localeFile;
169  localeFile = baseDir + dirList[i].name;
170  SWLocale *locale = new SWLocale(localeFile);
171 
172  if (locale->getName()) {
173  bool supported = false;
175  supported = (locale->getEncoding() && (!strcmp(locale->getEncoding(), "UTF-8") || !strcmp(locale->getEncoding(), "ASCII")) );
176  }
177  else {
178  supported = !locale->getEncoding() || (locale->getEncoding() && (strcmp(locale->getEncoding(), "UTF-8") != 0)); //exclude UTF-8 locales
179  }
180 
181  if (!supported) { //not supported
182  delete locale;
183  continue;
184  }
185 
186  it = locales->find(locale->getName());
187  if (it != locales->end()) { // already present
188  *((*it).second) += *locale;
189  delete locale;
190  }
191  else locales->insert(LocaleMap::value_type(locale->getName(), locale));
192  }
193  else delete locale;
194  }
195  }
196 }
197 
198 
200 
201  LocaleMap::iterator it;
202 
203  for (it = locales->begin(); it != locales->end(); it++)
204  delete (*it).second;
205 
206  locales->erase(locales->begin(), locales->end());
207 }
208 
209 
210 SWLocale *LocaleMgr::getLocale(const char *name) {
211  LocaleMap::iterator it;
212 
213  it = locales->find(name);
214  if (it != locales->end())
215  return (*it).second;
216 
217  SWLog::getSystemLog()->logWarning("LocaleMgr::getLocale failed to find %s\n", name);
219 }
220 
221 
222 std::list <SWBuf> LocaleMgr::getAvailableLocales() {
223  std::list <SWBuf> retVal;
224  for (LocaleMap::iterator it = locales->begin(); it != locales->end(); it++) {
225  if (strcmp(it->second->getName(), "locales")) {
226  retVal.push_back((*it).second->getName());
227  }
228  }
229 
230  return retVal;
231 }
232 
233 
234 const char *LocaleMgr::translate(const char *text, const char *localeName) {
235  SWLocale *target;
236  if (!localeName) {
237  localeName = getDefaultLocaleName();
238  }
239  target = getLocale(localeName);
240  if (target)
241  return target->translate(text);
242  return text;
243 }
244 
245 
247  return defaultLocaleName;
248 }
249 
250 
251 void LocaleMgr::setDefaultLocaleName(const char *name) {
252  char *tmplang=0;
253  stdstr(&tmplang, name);
254  // discard everything after '.' usually encoding e.g. .UTF-8
255  strtok(tmplang, ".");
256  // also discard after '@' so e.g. @euro locales are found
257  strtok(tmplang, "@");
258 
259  stdstr(&defaultLocaleName, tmplang);
260 
261  // First check for what we ask for
262  if (locales->find(tmplang) == locales->end()) {
263  // check for locale without country
264  char *nocntry=0;
265  stdstr(&nocntry, tmplang);
266  strtok(nocntry, "_");
267  if (locales->find(nocntry) != locales->end()) {
268  stdstr(&defaultLocaleName, nocntry);
269  }
270  delete [] nocntry;
271  }
272  delete [] tmplang;
273 }
274 
275 
277 
#define SWORD_NAMESPACE_START
Definition: defs.h:39
virtual void setDefaultLocaleName(const char *name)
Definition: localemgr.cpp:251
Definition: swbuf.h:47
SWBuf baseDir
Definition: installmgr.cpp:49
static signed char existsDir(const char *ipath, const char *idirName=0)
Definition: filemgr.cpp:357
static bool hasUTF8Support()
Definition: stringmgr.h:58
static SWLog * getSystemLog()
Definition: swlog.cpp:53
virtual const char * getDefaultLocaleName()
Definition: localemgr.cpp:246
virtual void loadConfigDir(const char *ipath)
Definition: localemgr.cpp:158
LocaleMgr(const LocaleMgr &)
LocaleMap * locales
Definition: localemgr.h:59
bool endsWith(const SWBuf &postfix) const
Definition: swbuf.h:501
SWORD_NAMESPACE_START char * stdstr(char **ipstr, const char *istr, unsigned int memPadFactor=1)
Definition: utilstr.h:44
ConfigEntMap & getSection(const char *section)
Definition: swconfig.h:76
virtual SWLocale * getLocale(const char *name)
Definition: localemgr.cpp:210
const char * c_str() const
Definition: swbuf.h:158
static const char * DEFAULT_LOCALE_NAME
Definition: swlocale.h:75
static LocaleMgr * getSystemLocaleMgr()
Definition: localemgr.cpp:54
std::map< SWBuf, SWLocale *, std::less< SWBuf > > LocaleMap
Definition: localemgr.h:38
virtual const char * translate(const char *text, const char *localeName=0)
Definition: localemgr.cpp:234
virtual const char * translate(const char *text)
Definition: swlocale.cpp:106
static std::vector< struct DirEntry > getDirList(const char *dirPath, bool includeSize=false, bool includeIsDirectory=true)
Definition: filemgr.cpp:379
void logWarning(const char *fmt,...) const
Definition: swlog.cpp:74
static void setSystemLocaleMgr(LocaleMgr *newLocaleMgr)
Definition: localemgr.cpp:63
static void findConfig(char *configType, char **prefixPath, char **configPath, StringList *augPaths=0, SWConfig **providedSysConf=0)
Definition: swmgr.cpp:449
virtual StringList getAvailableLocales()
Definition: localemgr.cpp:222
#define SWLOGTI(...)
Definition: defs.h:194
class __staticsystemLocaleMgr _staticsystemLocaleMgr
void deleteLocales()
Definition: localemgr.cpp:199
static LocaleMgr * systemLocaleMgr
Definition: localemgr.h:60
char * defaultLocaleName
Definition: localemgr.h:54
#define SWORD_NAMESPACE_END
Definition: defs.h:40
#define SWLOGD(...)
Definition: defs.h:187
virtual const char * getEncoding()
Definition: swlocale.cpp:168
virtual ~LocaleMgr()
Definition: localemgr.cpp:150
virtual const char * getName()
Definition: swlocale.cpp:158