1 #include "Localization.h"
2 
3 #ifdef BBGE_BUILD_UNIX
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <unistd.h>
7 #endif
8 
9 #ifdef BBGE_BUILD_MACOSX
10 #include <CoreFoundation/CFLocale.h>
11 #include <CoreFoundation/CFString.h>
12 
13 // veeery clunky.
_CFToStdString(CFStringRef cs)14 static std::string _CFToStdString(CFStringRef cs)
15 {
16 	char buf[1024];
17 	CFStringGetCString(cs, &buf[0], 1024, kCFStringEncodingUTF8);
18 	return &buf[0];
19 }
20 #endif
21 
22 static std::string s_locale;
23 static std::string s_modpath;
24 
setUsedLocale(const std::string & s)25 void setUsedLocale(const std::string& s)
26 {
27 	s_locale = s;
28 }
29 
getUsedLocale()30 const char *getUsedLocale()
31 {
32 	return s_locale.c_str();
33 }
34 
setLocalisationModPath(const std::string & s)35 void setLocalisationModPath(const std::string& s)
36 {
37 	s_modpath = s;
38 	stringToLower(s_modpath);
39 }
40 
41 // hackish
42 // intended to be used only for paths which are known to start with the mod path,
43 // but can deal with it if this is not the case
localisePathInternalModpath(const std::string & path)44 std::string localisePathInternalModpath(const std::string &path)
45 {
46 	std::string tmp = path;
47 	stringToLower(tmp);
48 
49 	if(!strncmp(tmp.c_str(), s_modpath.c_str(), s_modpath.length()))
50 		return localisePath(path, s_modpath);
51 
52 	return localisePath(path);
53 }
54 
localisePath(const std::string & path,const std::string & modpath)55 std::string localisePath(const std::string &path, const std::string& modpath /* = "" */)
56 {
57 	if (s_locale.empty() || s_locale == "-")
58 		return path;
59 	if(path.length() < modpath.length())
60 		return path;
61 
62 	const std::string fname = path.substr(modpath.length());
63 
64 	/* we first try with complete locale name, i.e "locales/en_US/" */
65 	std::string localisedPath = modpath + "locales/" + s_locale + "/" + fname;
66 
67 	if (exists(localisedPath.c_str()))
68 		return localisedPath;
69 
70 	/* ok didn't work, let's retry with only language part of locale name, i.e "locales/en/" */
71 	const size_t found = s_locale.find('_');
72 
73 	/* hmm, seems like we didn't have a full locale name anyway, use original path */
74 	if (found == std::string::npos)
75 		return path;
76 
77 	localisedPath = modpath + "locales/" + s_locale.substr(0,found) + "/" + fname;
78 
79 	/* hooray we found a file! */
80 	if (exists(localisedPath.c_str()))
81 		return localisedPath;
82 
83 	/* seems like we don't have a localized version of the file available, use original path */
84 	return path;
85 }
86 
getSystemLocale()87 std::string getSystemLocale()
88 {
89 	std::string localeStr;
90 
91 #ifdef BBGE_BUILD_WINDOWS
92 	LCID lcid = GetThreadLocale();
93 
94 	char buf[100];
95 	char ctry[100];
96 
97 	if (GetLocaleInfo(lcid, LOCALE_SISO639LANGNAME, buf, sizeof buf) != 0)
98 	{
99 		localeStr = buf;
100 
101 		if (GetLocaleInfo(lcid, LOCALE_SISO3166CTRYNAME, ctry, sizeof ctry) != 0)
102 		{
103 			localeStr += "_";
104 			localeStr += ctry;
105 		}
106 	}
107 #elif BBGE_BUILD_MACOSX
108 	CFLocaleRef locale = CFLocaleCopyCurrent();
109 	CFStringRef buf;
110 
111 	if ((buf = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleLanguageCode)) != NULL)
112 	{
113 		localeStr = _CFToStdString(buf);
114 
115 		if ((buf = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleCountryCode)) != NULL)
116 		{
117 			localeStr += "_";
118 			localeStr += _CFToStdString(buf);
119 		}
120 	}
121 
122 	CFRelease(locale);
123 
124 #else
125 	const char *lang = (const char *)getenv("LANG");
126 
127 	if (lang && *lang)
128 	{
129 		localeStr = lang;
130 
131 		size_t found = localeStr.find('.');
132 
133 		if (found != std::string::npos)
134 			localeStr.resize(found);
135 	}
136 #endif
137 
138 	return localeStr;
139 }
140 
141