unicode_util.cpp (Firebird-3.0.2.32703-0.tar.bz2) | : | unicode_util.cpp (Firebird-3.0.4.33054-0.tar.bz2) | ||
---|---|---|---|---|
skipping to change at line 53 | skipping to change at line 53 | |||
#include <unicode/ustring.h> | #include <unicode/ustring.h> | |||
#include <unicode/utrans.h> | #include <unicode/utrans.h> | |||
#include <unicode/uchar.h> | #include <unicode/uchar.h> | |||
#include <unicode/ucol.h> | #include <unicode/ucol.h> | |||
#include <unicode/uversion.h> | #include <unicode/uversion.h> | |||
#if U_ICU_VERSION_MAJOR_NUM >= 51 | #if U_ICU_VERSION_MAJOR_NUM >= 51 | |||
# include <unicode/utf_old.h> | # include <unicode/utf_old.h> | |||
#endif | #endif | |||
// The next major ICU version after 4.8 is 49. | ||||
#define ICU_NEW_VERSION_MEANING 49 | ||||
using namespace Firebird; | using namespace Firebird; | |||
namespace { | namespace { | |||
#if defined(WIN_NT) | #if defined(WIN_NT) | |||
const char* const inTemplate = "icuin%s.dll"; | const char* const inTemplate = "icuin%s.dll"; | |||
const char* const ucTemplate = "icuuc%s.dll"; | const char* const ucTemplate = "icuuc%s.dll"; | |||
#elif defined(DARWIN) | #elif defined(DARWIN) | |||
//const char* const inTemplate = "/Library/Frameworks/Firebird.framework/Version | const char* const inTemplate = "/Library/Frameworks/Firebird.framework/Versions/ | |||
s/A/Libraries/libicui18n.dylib"; | A/Libraries/libicui18n.dylib"; | |||
//const char* const ucTemplate = "/Library/Frameworks/Firebird.framework/version | const char* const ucTemplate = "/Library/Frameworks/Firebird.framework/versions/ | |||
s/A/Libraries/libicuuc.dylib"; | A/Libraries/libicuuc.dylib"; | |||
const char* const inTemplate = "libicui18n.dylib"; | //const char* const inTemplate = "libicui18n.dylib"; | |||
const char* const ucTemplate = "libicuuc.dylib"; | //const char* const ucTemplate = "libicuuc.dylib"; | |||
#elif defined(HPUX) | #elif defined(HPUX) | |||
const char* const inTemplate = "libicui18n.sl.%s"; | const char* const inTemplate = "libicui18n.sl.%s"; | |||
const char* const ucTemplate = "libicuuc.sl.%s"; | const char* const ucTemplate = "libicuuc.sl.%s"; | |||
#elif defined(ANDROID) | #elif defined(ANDROID) | |||
const char* const inTemplate = "libicui18n.so"; | const char* const inTemplate = "libicui18n.so"; | |||
const char* const ucTemplate = "libicuuc.so"; | const char* const ucTemplate = "libicuuc.so"; | |||
#else | #else | |||
const char* const inTemplate = "libicui18n.so.%s"; | const char* const inTemplate = "libicui18n.so.%s"; | |||
const char* const ucTemplate = "libicuuc.so.%s"; | const char* const ucTemplate = "libicuuc.so.%s"; | |||
#endif | #endif | |||
skipping to change at line 124 | skipping to change at line 121 | |||
int majorVersion; | int majorVersion; | |||
int minorVersion; | int minorVersion; | |||
void (U_EXPORT2 *uInit)(UErrorCode* status); | void (U_EXPORT2 *uInit)(UErrorCode* status); | |||
void (U_EXPORT2 *uSetDataDirectory)(const char* directory); | void (U_EXPORT2 *uSetDataDirectory)(const char* directory); | |||
}; | }; | |||
} | } | |||
namespace Jrd { | namespace Jrd { | |||
static void formatFilename(PathName& filename, const char* templateName, | static ModuleLoader::Module* formatAndLoad(const char* templateName, | |||
int majorVersion, int minorVersion); | int majorVersion, int minorVersion); | |||
// encapsulate ICU collations libraries | // encapsulate ICU collations libraries | |||
struct UnicodeUtil::ICU : public BaseICU | struct UnicodeUtil::ICU : public BaseICU | |||
{ | { | |||
public: | public: | |||
ICU(int aMajorVersion, int aMinorVersion) | ICU(int aMajorVersion, int aMinorVersion) | |||
: BaseICU(aMajorVersion, aMinorVersion), | : BaseICU(aMajorVersion, aMinorVersion), | |||
inModule(NULL), | inModule(NULL), | |||
ucModule(NULL), | ucModule(NULL), | |||
skipping to change at line 230 | skipping to change at line 227 | |||
UErrorCode* status); | UErrorCode* status); | |||
}; | }; | |||
// encapsulate ICU conversion library | // encapsulate ICU conversion library | |||
class ImplementConversionICU : public UnicodeUtil::ConversionICU, BaseICU | class ImplementConversionICU : public UnicodeUtil::ConversionICU, BaseICU | |||
{ | { | |||
private: | private: | |||
ImplementConversionICU(int aMajorVersion, int aMinorVersion) | ImplementConversionICU(int aMajorVersion, int aMinorVersion) | |||
: BaseICU(aMajorVersion, aMinorVersion) | : BaseICU(aMajorVersion, aMinorVersion) | |||
{ | { | |||
PathName filename; | module = formatAndLoad(ucTemplate, aMajorVersion, aMinorVersion); | |||
formatFilename(filename, ucTemplate, aMajorVersion, aMinorVersion | ||||
); | ||||
module = ModuleLoader::fixAndLoadModule(filename); | ||||
if (!module) | if (!module) | |||
return; | return; | |||
try | try | |||
{ | { | |||
getEntryPoint("u_init", module, uInit); | getEntryPoint("u_init", module, uInit); | |||
} | } | |||
catch (const status_exception&) | catch (const status_exception&) | |||
{ } | { } | |||
skipping to change at line 340 | skipping to change at line 334 | |||
} | } | |||
ModulesMap modules; | ModulesMap modules; | |||
RWLock lock; | RWLock lock; | |||
}; | }; | |||
static const char* const COLL_30_VERSION = "41.128.4.4"; // ICU 3.0 collat or version | static const char* const COLL_30_VERSION = "41.128.4.4"; // ICU 3.0 collat or version | |||
static GlobalPtr<UnicodeUtil::ICUModules> icuModules; | static GlobalPtr<UnicodeUtil::ICUModules> icuModules; | |||
static void formatFilename(PathName& filename, const char* templateName, | static ModuleLoader::Module* formatAndLoad(const char* templateName, | |||
int majorVersion, int minorVersion) | int majorVersion, int minorVersion) | |||
{ | { | |||
string s; | // ICU has several schemas for placing version into file name | |||
if (majorVersion >= ICU_NEW_VERSION_MEANING) | const char* patterns[] = | |||
s.printf("%d", majorVersion); | { | |||
else | "%d", "%d_%d", "%d%d", NULL | |||
s.printf("%d%d", majorVersion, minorVersion); | }; | |||
PathName s, filename; | ||||
for (const char** p = patterns; *p; ++p) | ||||
{ | ||||
s.printf(*p, majorVersion, minorVersion); | ||||
filename.printf(templateName, s.c_str()); | ||||
filename.printf(templateName, s.c_str()); | ModuleLoader::Module* module = ModuleLoader::fixAndLoadModule(NUL | |||
L, filename); | ||||
if (module) | ||||
return module; | ||||
} | ||||
return NULL; | ||||
} | } | |||
static void getVersions(const string& configInfo, ObjectsArray<string>& versions ) | static void getVersions(const string& configInfo, ObjectsArray<string>& versions ) | |||
{ | { | |||
charset cs; | charset cs; | |||
IntlUtil::initAsciiCharset(&cs); | IntlUtil::initAsciiCharset(&cs); | |||
AutoPtr<CharSet> ascii(Jrd::CharSet::createInstance(*getDefaultMemoryPool (), 0, &cs)); | AutoPtr<CharSet> ascii(Jrd::CharSet::createInstance(*getDefaultMemoryPool (), 0, &cs)); | |||
IntlUtil::SpecificAttributesMap config; | IntlUtil::SpecificAttributesMap config; | |||
skipping to change at line 957 | skipping to change at line 962 | |||
int majorVersion, minorVersion; | int majorVersion, minorVersion; | |||
int n = sscanf((*i == "default" ? version : *i).c_str(), "%d.%d", | int n = sscanf((*i == "default" ? version : *i).c_str(), "%d.%d", | |||
&majorVersion, &minorVersion); | &majorVersion, &minorVersion); | |||
if (n == 1) | if (n == 1) | |||
minorVersion = 0; | minorVersion = 0; | |||
else if (n != 2) | else if (n != 2) | |||
continue; | continue; | |||
string configVersion; | string configVersion; | |||
configVersion.printf("%d.%d", majorVersion, minorVersion); | ||||
if (majorVersion >= ICU_NEW_VERSION_MEANING) | if (version != configVersion) | |||
{ | { | |||
minorVersion = 0; | minorVersion = 0; | |||
configVersion.printf("%d", majorVersion); | configVersion.printf("%d", majorVersion); | |||
if (version != configVersion) | ||||
continue; | ||||
} | } | |||
else | ||||
configVersion.printf("%d.%d", majorVersion, minorVersion) | ||||
; | ||||
if (version != configVersion) | ||||
continue; | ||||
ReadLockGuard readGuard(icuModules->lock, "UnicodeUtil::loadICU") ; | ReadLockGuard readGuard(icuModules->lock, "UnicodeUtil::loadICU") ; | |||
ICU* icu; | ICU* icu; | |||
if (icuModules->modules.get(version, icu)) | if (icuModules->modules.get(version, icu)) | |||
return icu; | return icu; | |||
PathName filename; | ||||
formatFilename(filename, ucTemplate, majorVersion, minorVersion); | ||||
icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, mino rVersion); | icu = FB_NEW_POOL(*getDefaultMemoryPool()) ICU(majorVersion, mino rVersion); | |||
icu->ucModule = formatAndLoad(ucTemplate, majorVersion, minorVers | ||||
icu->ucModule = ModuleLoader::fixAndLoadModule(filename); | ion); | |||
if (!icu->ucModule) | if (!icu->ucModule) | |||
{ | { | |||
gds__log("failed to load module %s", filename.c_str()); | gds__log("failed to load UC icu module version %s", confi gVersion.c_str()); | |||
delete icu; | delete icu; | |||
continue; | continue; | |||
} | } | |||
formatFilename(filename, inTemplate, majorVersion, minorVersion); | icu->inModule = formatAndLoad(inTemplate, majorVersion, minorVers | |||
ion); | ||||
icu->inModule = ModuleLoader::fixAndLoadModule(filename); | ||||
if (!icu->inModule) | if (!icu->inModule) | |||
{ | { | |||
gds__log("failed to load module %s", filename.c_str()); | gds__log("failed to load IN icu module version %s", confi gVersion.c_str()); | |||
delete icu; | delete icu; | |||
continue; | continue; | |||
} | } | |||
try | try | |||
{ | { | |||
icu->getEntryPoint("u_init", icu->ucModule, icu->uInit); | icu->getEntryPoint("u_init", icu->ucModule, icu->uInit); | |||
} | } | |||
catch (const status_exception&) | catch (const status_exception&) | |||
{ } | { } | |||
skipping to change at line 1119 | skipping to change at line 1113 | |||
if ((convIcu = ImplementConversionICU::create(favMaj, favMin))) | if ((convIcu = ImplementConversionICU::create(favMaj, favMin))) | |||
return *convIcu; | return *convIcu; | |||
} | } | |||
catch (const Exception&) | catch (const Exception&) | |||
{ } | { } | |||
// Do a regular search | // Do a regular search | |||
LocalStatus ls; | LocalStatus ls; | |||
CheckStatusWrapper lastError(&ls); | CheckStatusWrapper lastError(&ls); | |||
string version; | string version; | |||
const int majorArray[] = {5, 4, 3, 6, 0}; | ||||
for (const int* major = majorArray; *major; ++major) | for (int major = 4; major <= 79; ++major) | |||
{ | { | |||
for (int minor = 20; minor--; ) // from 19 down to 0 | for (int minor = 20; minor--; ) // from 19 down to 0 | |||
{ | { | |||
if ((*major == favMaj) && (minor == favMin)) | if ((major == favMaj) && (minor == favMin)) | |||
{ | { | |||
continue; | continue; | |||
} | } | |||
try | try | |||
{ | { | |||
if ((convIcu = ImplementConversionICU::create(*ma jor, minor))) | if ((convIcu = ImplementConversionICU::create(maj or, minor))) | |||
return *convIcu; | return *convIcu; | |||
} | } | |||
catch (const Exception& ex) | catch (const Exception& ex) | |||
{ | { | |||
ex.stuffException(&lastError); | ex.stuffException(&lastError); | |||
version.printf("Error loading ICU library version %d.%d", *major, minor); | version.printf("Error loading ICU library version %d.%d", major, minor); | |||
} | } | |||
} | } | |||
} | } | |||
if (lastError.getState() & Firebird::IStatus::STATE_ERRORS) | if (lastError.getState() & Firebird::IStatus::STATE_ERRORS) | |||
{ | { | |||
(Arg::Gds(isc_random) << "Could not find acceptable ICU library" | (Arg::Gds(isc_random) << "Could not find acceptable ICU library" | |||
<< Arg::StatusVector(lastError.getErrors())).raise(); | << Arg::StatusVector(lastError.getErrors())).raise(); | |||
} | } | |||
else | else | |||
skipping to change at line 1160 | skipping to change at line 1153 | |||
// compiler warning silencer | // compiler warning silencer | |||
return *convIcu; | return *convIcu; | |||
} | } | |||
string UnicodeUtil::getDefaultIcuVersion() | string UnicodeUtil::getDefaultIcuVersion() | |||
{ | { | |||
string rc; | string rc; | |||
UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU()); | UnicodeUtil::ConversionICU& icu(UnicodeUtil::getConversionICU()); | |||
if (icu.vMajor >= ICU_NEW_VERSION_MEANING) | if (icu.vMajor >= 10 && icu.vMinor == 0) | |||
rc.printf("%d", icu.vMajor); | rc.printf("%d", icu.vMajor); | |||
else | else | |||
rc.printf("%d.%d", icu.vMajor, icu.vMinor); | rc.printf("%d.%d", icu.vMajor, icu.vMinor); | |||
return rc; | return rc; | |||
} | } | |||
bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion, | bool UnicodeUtil::getCollVersion(const Firebird::string& icuVersion, | |||
const Firebird::string& configInfo, Firebird::string& collVersion) | const Firebird::string& configInfo, Firebird::string& collVersion) | |||
{ | { | |||
skipping to change at line 1306 | skipping to change at line 1299 | |||
if (isNumericSort) | if (isNumericSort) | |||
{ | { | |||
icu->ucolSetAttribute(compareCollator, UCOL_NUMERIC_COLLATION, UC OL_ON, &status); | icu->ucolSetAttribute(compareCollator, UCOL_NUMERIC_COLLATION, UC OL_ON, &status); | |||
icu->ucolSetAttribute(partialCollator, UCOL_NUMERIC_COLLATION, UC OL_ON, &status); | icu->ucolSetAttribute(partialCollator, UCOL_NUMERIC_COLLATION, UC OL_ON, &status); | |||
icu->ucolSetAttribute(sortCollator, UCOL_NUMERIC_COLLATION, UCOL_ ON, &status); | icu->ucolSetAttribute(sortCollator, UCOL_NUMERIC_COLLATION, UCOL_ ON, &status); | |||
icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCOL_IDENTI CAL, &status); | icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCOL_IDENTI CAL, &status); | |||
icu->ucolSetAttribute(sortCollator, UCOL_STRENGTH, UCOL_IDENTICAL , &status); | icu->ucolSetAttribute(sortCollator, UCOL_STRENGTH, UCOL_IDENTICAL , &status); | |||
tt->texttype_flags = TEXTTYPE_UNSORTED_UNIQUE; | tt->texttype_flags |= TEXTTYPE_UNSORTED_UNIQUE; | |||
} | } | |||
else | else | |||
{ | { | |||
if ((attributes & (TEXTTYPE_ATTR_CASE_INSENSITIVE | TEXTTYPE_ATTR _ACCENT_INSENSITIVE)) == | if ((attributes & (TEXTTYPE_ATTR_CASE_INSENSITIVE | TEXTTYPE_ATTR _ACCENT_INSENSITIVE)) == | |||
(TEXTTYPE_ATTR_CASE_INSENSITIVE | TEXTTYPE_ATTR_ACCENT_IN SENSITIVE)) | (TEXTTYPE_ATTR_CASE_INSENSITIVE | TEXTTYPE_ATTR_ACCENT_IN SENSITIVE)) | |||
{ | { | |||
icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCO L_PRIMARY, &status); | icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCO L_PRIMARY, &status); | |||
} | } | |||
else if (attributes & TEXTTYPE_ATTR_CASE_INSENSITIVE) | else if (attributes & TEXTTYPE_ATTR_CASE_INSENSITIVE) | |||
icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCO L_SECONDARY, &status); | icu->ucolSetAttribute(compareCollator, UCOL_STRENGTH, UCO L_SECONDARY, &status); | |||
skipping to change at line 1401 | skipping to change at line 1394 | |||
// Remove last bytes of key if they are start of a contra ction | // Remove last bytes of key if they are start of a contra ction | |||
// to correctly find in the index. | // to correctly find in the index. | |||
ConversionICU& cIcu(getConversionICU()); | ConversionICU& cIcu(getConversionICU()); | |||
for (int i = 0; i < contractionsCount; ++i) | for (int i = 0; i < contractionsCount; ++i) | |||
{ | { | |||
UChar str[10]; | UChar str[10]; | |||
UErrorCode status = U_ZERO_ERROR; | UErrorCode status = U_ZERO_ERROR; | |||
int len = icu->usetGetItem(contractions, i, NULL, NULL, str, sizeof(str), &status); | int len = icu->usetGetItem(contractions, i, NULL, NULL, str, sizeof(str), &status); | |||
if (len > srcLenLong) | if (len > SLONG(srcLenLong)) | |||
len = srcLenLong; | len = srcLenLong; | |||
else | else | |||
--len; | --len; | |||
// safe cast - alignment not changed | // safe cast - alignment not changed | |||
if (cIcu.u_strCompare(str, len, | if (cIcu.u_strCompare(str, len, | |||
reinterpret_cast<const UChar*>(sr c) + srcLenLong - len, len, true) == 0) | reinterpret_cast<const UChar*>(sr c) + srcLenLong - len, len, true) == 0) | |||
{ | { | |||
srcLenLong -= len; | srcLenLong -= len; | |||
break; | break; | |||
End of changes. 23 change blocks. | ||||
50 lines changed or deleted | 44 lines changed or added |