commit 91ad9c27591ec11bfed97b7a9b22ab9e99779dad
Author: asfernandes <asfernandes@de594faa-8d1b-4a0c-9a6a-a7de5f8bf859>
Date:   Fri Oct 12 21:20:30 2012 +0000

    Backport fix for CORE-3946 - UNICODE collations does not work with ICU 49.
    
    git-svn-id: https://firebird.svn.sourceforge.net/svnroot/firebird/firebird/branches/B2_5_Release@57236 de594faa-8d1b-4a0c-9a6a-a7de5f8bf859

diff --git a/src/jrd/unicode_util.cpp b/src/jrd/unicode_util.cpp
index ba675c3..ca561f9 100644
--- a/src/jrd/unicode_util.cpp
+++ b/src/jrd/unicode_util.cpp
@@ -42,6 +42,9 @@
 #include "unicode/ucnv.h"
 #include "unicode/ucol.h"
 
+// The next major ICU version after 4.8 is 49.
+#define ICU_NEW_VERSION_MEANING	49
+
 
 using namespace Firebird;
 
@@ -49,8 +52,16 @@ using namespace Firebird;
 namespace Jrd {
 
 
+#if U_ICU_VERSION_MAJOR_NUM >= ICU_NEW_VERSION_MEANING
+const char* const UnicodeUtil::DEFAULT_ICU_VERSION = STRINGIZE(U_ICU_VERSION_MAJOR_NUM);
+#else
 const char* const UnicodeUtil::DEFAULT_ICU_VERSION =
 	STRINGIZE(U_ICU_VERSION_MAJOR_NUM)"."STRINGIZE(U_ICU_VERSION_MINOR_NUM);
+#endif
+
+
+static void formatFilename(PathName& filename, const char* templateName,
+	int majorVersion, int minorVersion);
 
 
 // encapsulate ICU collations libraries
@@ -79,6 +90,11 @@ public:
 	{
 		string symbol;
 
+		symbol.printf("%s_%d", name, majorVersion);
+		module->findSymbol(symbol, ptr);
+		if (ptr)
+			return;
+
 		symbol.printf("%s_%d_%d", name, majorVersion, minorVersion);
 		module->findSymbol(symbol, ptr);
 		if (ptr)
@@ -157,14 +173,25 @@ public:
 	RWLock lock;
 };
 
-namespace {
-	GlobalPtr<UnicodeUtil::ICUModules> icuModules;
-}
+static GlobalPtr<UnicodeUtil::ICUModules> icuModules;
 
 
 static const char* const COLL_30_VERSION = "41.128.4.4";	// ICU 3.0 collator version
 
 
+static void formatFilename(PathName& filename, const char* templateName,
+	int majorVersion, int minorVersion)
+{
+	string s;
+	if (majorVersion >= ICU_NEW_VERSION_MEANING)
+		s.printf("%d", majorVersion);
+	else
+		s.printf("%d%d", majorVersion, minorVersion);
+
+	filename.printf(templateName, s.c_str());
+}
+
+
 static void getVersions(const string& configInfo, ObjectsArray<string>& versions)
 {
 	charset cs;
@@ -758,17 +785,17 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
 	const Firebird::string& configInfo)
 {
 #if defined(WIN_NT)
-	const char* const inTemplate = "icuin%d%d.dll";
-	const char* const ucTemplate = "icuuc%d%d.dll";
+	const char* const inTemplate = "icuin%s.dll";
+	const char* const ucTemplate = "icuuc%s.dll";
 #elif defined(DARWIN)
 	const char* const inTemplate = "/Library/Frameworks/Firebird.framework/Versions/A/Libraries/libicui18n.dylib";
 	const char* const ucTemplate = "/Library/Frameworks/Firebird.framework/versions/A/Libraries/libicuuc.dylib";
 #elif defined(HPUX)
-	const char* const inTemplate = "libicui18n.sl.%d%d";
-	const char* const ucTemplate = "libicuuc.sl.%d%d";
+	const char* const inTemplate = "libicui18n.sl.%s";
+	const char* const ucTemplate = "libicuuc.sl.%s";
 #else
-	const char* const inTemplate = "libicui18n.so.%d%d";
-	const char* const ucTemplate = "libicuuc.so.%d%d";
+	const char* const inTemplate = "libicui18n.so.%s";
+	const char* const ucTemplate = "libicuuc.so.%s";
 #endif
 
 	ObjectsArray<string> versions;
@@ -776,24 +803,28 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
 
 	string version = icuVersion.isEmpty() ? versions[0] : icuVersion;
 	if (version == "default")
-	{
-		version.printf("%d.%d", U_ICU_VERSION_MAJOR_NUM, U_ICU_VERSION_MINOR_NUM);
-	}
+		version = DEFAULT_ICU_VERSION;
 
 	for (ObjectsArray<string>::const_iterator i(versions.begin()); i != versions.end(); ++i)
 	{
 		int majorVersion, minorVersion;
+		int n = sscanf((*i == "default" ? version : *i).c_str(), "%d.%d",
+			&majorVersion, &minorVersion);
 
-		if (*i == "default")
-		{
-			majorVersion = U_ICU_VERSION_MAJOR_NUM;
-			minorVersion = U_ICU_VERSION_MINOR_NUM;
-		}
-		else if (sscanf(i->c_str(), "%d.%d", &majorVersion, &minorVersion) != 2)
+		if (n == 1)
+			minorVersion = 0;
+		else if (n != 2)
 			continue;
 
 		string configVersion;
-		configVersion.printf("%d.%d", majorVersion, minorVersion);
+
+		if (majorVersion >= ICU_NEW_VERSION_MEANING)
+		{
+			minorVersion = 0;
+			configVersion.printf("%d", majorVersion);
+		}
+		else
+			configVersion.printf("%d.%d", majorVersion, minorVersion);
 
 		if (version != configVersion)
 			continue;
@@ -805,7 +836,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
 			return icu;
 
 		PathName filename;
-		filename.printf(ucTemplate, majorVersion, minorVersion);
+		formatFilename(filename, ucTemplate, majorVersion, minorVersion);
 
 		icu = FB_NEW(*getDefaultMemoryPool()) ICU(majorVersion, minorVersion);
 
@@ -822,7 +853,7 @@ UnicodeUtil::ICU* UnicodeUtil::loadICU(const Firebird::string& icuVersion,
 			continue;
 		}
 
-		filename.printf(inTemplate, majorVersion, minorVersion);
+		formatFilename(filename, inTemplate, majorVersion, minorVersion);
 
 		icu->inModule = ModuleLoader::loadModule(filename);
 		if (!icu->inModule)
