Date: Friday, March 17, 2006 @ 20:45:55
Author: marc
Path: /cvsroot/carob/carob/src
Modified: Common.cpp (1.33 -> 1.34)
Added alternatives and heuristics to fallback on other UTF8 locales. CAROB-74.
------------+
Common.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 89 insertions(+), 6 deletions(-)
Index: carob/src/Common.cpp
diff -u carob/src/Common.cpp:1.33 carob/src/Common.cpp:1.34
--- carob/src/Common.cpp:1.33 Fri Mar 17 18:57:05 2006
+++ carob/src/Common.cpp Fri Mar 17 20:45:55 2006
@@ -63,7 +63,7 @@
// Using "C" should work fine as long as every string involved is pure
// ASCII.
-#define NAME_OF_ANY_UTF8_LOCALE_AVAILABLE "en_US.utf8"
+#define NAME_OF_ANY_UTF8_LOCALE_AVAILABLE "en_US.utf88"
void CarobNS::setLogLevel(const LogLevel l)
{
@@ -185,17 +185,100 @@
namespace {
using namespace CarobNS;
- // this function just to log an explicit error message
+
+ std::locale tryuserlocale();
+
std::locale tryUTF8locale()
{
+ // __func__ is unfortunately C99
+ wstring funcname(__WFILE__ L":tryUTF8locale()");
+
+ // 1. trying hardwired macro
try {
+ logInfo(funcname,
+ L"1. trying to use locale: " NAME_OF_ANY_UTF8_LOCALE_AVAILABLE);
return trylocale(NAME_OF_ANY_UTF8_LOCALE_AVAILABLE);
} catch (CodecException& ce) {
- logFatal(__WFILE__ L":tryUTF8locale()",
- L"please install the missing UTF8 locale carob was configured
with");
- throw;
+ logWarn(funcname,
+ L"please install the " NAME_OF_ANY_UTF8_LOCALE_AVAILABLE "
locale");
}
- }
+
+ // 2. try to fallback on the user defined locale
+ string user_loc;
+ try{
+ user_loc = std::locale("").name();
+ } catch (std::runtime_error&) {
+ user_loc = std::locale().name();
+ }
+ logInfo(funcname,
+ std::wstring(L"2. trying to fallback on locale: ")
+ + fromString(user_loc));
+
+ try { // search for "utf8" or variants
+
+ string::size_type utf8pos;
+
+ // sorry for this
+ (utf8pos = user_loc.rfind("UTF")) != string::npos
+ || (utf8pos = user_loc.rfind("Utf")) != string::npos
+ || ( utf8pos = user_loc.rfind("utf")) != string::npos;
+
+ if (utf8pos != string::npos)
+ if (user_loc.at(utf8pos+3) == '8'
+ || user_loc.at(utf8pos+4) == '8')
+ return std::locale(user_loc.c_str());
+
+ } catch (std::out_of_range& oor) {
+ // out_of_range => not found
+ }
+
+ logWarn(funcname, fromString(user_loc)
+ + L" does not seem to be an utf8 locale either");
+
+
+ // 3. Else try to hack the user locale name a bit
+ string::size_type delimpos;
+ string nocodeset;
+ if ((delimpos = user_loc.find_last_of('.')) != string::npos)
+ nocodeset = user_loc.substr(0, delimpos);
+ else if ((delimpos = user_loc.find_last_of('@')) != string::npos)
+ nocodeset = user_loc.substr(0, delimpos);
+ else
+ nocodeset = user_loc;
+
+ string hacked_names[2];
+ hacked_names[0] = nocodeset + ".UTF-8";
+ hacked_names[1] = nocodeset + ".utf8";
+
+ for (int i=0; i<2; i++)
+ try {
+ logInfo(funcname, std::wstring(L"3n. trying to fall back on locale ")
+ + fromString(hacked_names[i]));
+ return trylocale(hacked_names[i].c_str());
+ } catch (CodecException&) {
+ logWarn(funcname,
+ std::wstring(L"or please install locale ")
+ + fromString(hacked_names[i]));
+ }
+
+ // 4. nothing found
+ logFatal(funcname,
+ std::wstring(L"Please install one of the following locales: "
+ NAME_OF_ANY_UTF8_LOCALE_AVAILABLE ", ")
+ + fromString(user_loc) + L", "
+ + fromString(nocodeset)
+ + L".utf8"
+ );
+ throw CodecException(L"no UTF8 codec found");
+
+ // TODO: fall back on:
+ // - configuration file
+ // - iconv
+ // - MultiByteToWideChar(CP_UTF8,...)
+ // - others?
+ // See CAROB-74
+
+ } // tryUTF8locale()
std::locale tryuserlocale()
{
_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits