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

Reply via email to