mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-10 07:39:16 +00:00
ICU-10051 Mutexes: introduce UInitOnce; remove UMTX_CHECK; replace all uses of UMTX_CHECK. All the directories this time.
X-SVN-Rev: 33788
This commit is contained in:
parent
978f71fe78
commit
ae87a3acc2
47 changed files with 1609 additions and 1976 deletions
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1997-2011, International Business Machines Corporation and
|
||||
* Copyright (C) 1997-2013, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*
|
||||
|
@ -271,6 +271,7 @@ U_NAMESPACE_END
|
|||
// defined in ucln_cmn.h
|
||||
|
||||
static icu::ICULocaleService* gService = NULL;
|
||||
static UInitOnce gInitOnce;
|
||||
|
||||
/**
|
||||
* Release all static memory held by breakiterator.
|
||||
|
@ -282,40 +283,33 @@ static UBool U_CALLCONV breakiterator_cleanup(void) {
|
|||
delete gService;
|
||||
gService = NULL;
|
||||
}
|
||||
gInitOnce.reset();
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static void U_CALLCONV
|
||||
initService(void) {
|
||||
gService = new ICUBreakIteratorService();
|
||||
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
|
||||
}
|
||||
|
||||
static ICULocaleService*
|
||||
getService(void)
|
||||
{
|
||||
UBool needsInit;
|
||||
UMTX_CHECK(NULL, (UBool)(gService == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
ICULocaleService *tService = new ICUBreakIteratorService();
|
||||
umtx_lock(NULL);
|
||||
if (gService == NULL) {
|
||||
gService = tService;
|
||||
tService = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR, breakiterator_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete tService;
|
||||
}
|
||||
umtx_initOnce(gInitOnce, &initService);
|
||||
return gService;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
static inline UBool
|
||||
hasService(void)
|
||||
{
|
||||
UBool retVal;
|
||||
UMTX_CHECK(NULL, gService != NULL, retVal);
|
||||
return retVal;
|
||||
return !gInitOnce.isReset() && getService() != NULL;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/common.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -129,7 +129,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/common.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -169,7 +169,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/common.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -206,7 +206,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/common.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
@ -237,17 +237,24 @@
|
|||
<ClCompile Include="ubidiln.c" />
|
||||
<ClCompile Include="ubidiwrt.c" />
|
||||
<ClCompile Include="ushape.cpp" />
|
||||
<ClCompile Include="brkeng.cpp" />
|
||||
<ClCompile Include="brkiter.cpp" />
|
||||
<ClCompile Include="brkeng.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="brkiter.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="dictbe.cpp" />
|
||||
<ClCompile Include="rbbi.cpp" />
|
||||
<ClCompile Include="rbbidata.cpp" />
|
||||
<ClCompile Include="rbbi.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="rbbidata.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="rbbinode.cpp" />
|
||||
<ClCompile Include="rbbirb.cpp" />
|
||||
<ClCompile Include="rbbirb.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="rbbiscan.cpp" />
|
||||
<ClCompile Include="rbbisetb.cpp" />
|
||||
<ClCompile Include="rbbistbl.cpp" />
|
||||
<ClCompile Include="rbbitblb.cpp" />
|
||||
<ClCompile Include="rbbistbl.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="rbbitblb.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="dictionarydata.cpp" />
|
||||
<ClCompile Include="ubrk.cpp" />
|
||||
<ClCompile Include="ucol_swp.cpp">
|
||||
|
@ -278,7 +285,8 @@
|
|||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="mutex.cpp" />
|
||||
<ClCompile Include="mutex.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="putil.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
|
@ -302,13 +310,15 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="ucnv.c" />
|
||||
<ClCompile Include="ucnv2022.cpp" />
|
||||
<ClCompile Include="ucnv_bld.cpp" />
|
||||
<ClCompile Include="ucnv_bld.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="ucnv_cb.c" />
|
||||
<ClCompile Include="ucnv_cnv.c" />
|
||||
<ClCompile Include="ucnv_ct.c" />
|
||||
<ClCompile Include="ucnv_err.c" />
|
||||
<ClCompile Include="ucnv_ext.cpp" />
|
||||
<ClCompile Include="ucnv_io.cpp" />
|
||||
<ClCompile Include="ucnv_io.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="ucnv_lmb.c" />
|
||||
<ClCompile Include="ucnv_set.c" />
|
||||
<ClCompile Include="ucnv_u16.c" />
|
||||
|
@ -322,7 +332,8 @@
|
|||
<ClCompile Include="ucnvlat1.c" />
|
||||
<ClCompile Include="ucnvmbcs.c" />
|
||||
<ClCompile Include="ucnvscsu.c" />
|
||||
<ClCompile Include="ucnvsel.cpp" />
|
||||
<ClCompile Include="ucnvsel.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="cmemory.c" />
|
||||
<ClCompile Include="ucln_cmn.c">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
|
@ -350,14 +361,18 @@
|
|||
<ClCompile Include="punycode.cpp" />
|
||||
<ClCompile Include="uidna.cpp" />
|
||||
<ClCompile Include="uts46.cpp" />
|
||||
<ClCompile Include="locavailable.cpp" />
|
||||
<ClCompile Include="locavailable.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="locbased.cpp" />
|
||||
<ClCompile Include="locdispnames.cpp" />
|
||||
<ClCompile Include="locid.cpp" />
|
||||
<ClCompile Include="locid.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="loclikely.cpp" />
|
||||
<ClCompile Include="locresdata.cpp" />
|
||||
<ClCompile Include="locutil.cpp" />
|
||||
<ClCompile Include="resbund.cpp" />
|
||||
<ClCompile Include="locutil.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="resbund.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="resbund_cnv.cpp" />
|
||||
<ClCompile Include="ucat.c" />
|
||||
<ClCompile Include="uloc.cpp" />
|
||||
|
@ -365,19 +380,25 @@
|
|||
<ClCompile Include="ures_cnv.c" />
|
||||
<ClCompile Include="uresbund.cpp" />
|
||||
<ClCompile Include="uresdata.c" />
|
||||
<ClCompile Include="caniter.cpp" />
|
||||
<ClCompile Include="caniter.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="filterednormalizer2.cpp" />
|
||||
<ClCompile Include="normalizer2.cpp" />
|
||||
<ClCompile Include="normalizer2impl.cpp" />
|
||||
<ClCompile Include="normlzr.cpp" />
|
||||
<ClCompile Include="normalizer2.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="normalizer2impl.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="normlzr.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="unorm.cpp" />
|
||||
<ClCompile Include="unorm_it.c" />
|
||||
<ClCompile Include="unormcmp.cpp" />
|
||||
<ClCompile Include="bmpset.cpp" />
|
||||
<ClCompile Include="patternprops.cpp" />
|
||||
<ClCompile Include="propname.cpp" />
|
||||
<ClCompile Include="propname.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="ruleiter.cpp" />
|
||||
<ClCompile Include="ucase.cpp" />
|
||||
<ClCompile Include="ucase.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="uchar.c" />
|
||||
<ClCompile Include="unames.cpp" />
|
||||
<ClCompile Include="unifilt.cpp" />
|
||||
|
@ -394,13 +415,20 @@
|
|||
<ClCompile Include="uset_props.cpp" />
|
||||
<ClCompile Include="usetiter.cpp" />
|
||||
<ClCompile Include="icuplug.c" />
|
||||
<ClCompile Include="serv.cpp" />
|
||||
<ClCompile Include="servlk.cpp" />
|
||||
<ClCompile Include="servlkf.cpp" />
|
||||
<ClCompile Include="servls.cpp" />
|
||||
<ClCompile Include="servnotf.cpp" />
|
||||
<ClCompile Include="servrbf.cpp" />
|
||||
<ClCompile Include="servslkf.cpp" />
|
||||
<ClCompile Include="serv.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servlk.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servlkf.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servls.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servnotf.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servrbf.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="servslkf.cpp">
|
||||
</ClCompile>
|
||||
<ClCompile Include="usprep.cpp" />
|
||||
<ClCompile Include="appendable.cpp" />
|
||||
<ClCompile Include="bytestream.cpp" />
|
||||
|
@ -438,7 +466,8 @@
|
|||
<ClCompile Include="ustrtrns.cpp" />
|
||||
<ClCompile Include="utext.cpp" />
|
||||
<ClCompile Include="utf_impl.c" />
|
||||
<ClCompile Include="listformatter.cpp" />
|
||||
<ClCompile Include="listformatter.cpp">
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="unicode\ubidi.h">
|
||||
|
@ -1722,4 +1751,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2012, International Business Machines
|
||||
* Copyright (C) 2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
* dictionarydata.h
|
||||
|
@ -19,11 +19,16 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
#ifndef CYGWINMSVC /* On Cygwin/MSVC, the error redefinition of symbols occurs.*/
|
||||
const int32_t DictionaryData::TRIE_TYPE_BYTES;
|
||||
const int32_t DictionaryData::TRIE_TYPE_UCHARS;
|
||||
#endif
|
||||
const int32_t DictionaryData::TRIE_TYPE_BYTES = 0;
|
||||
const int32_t DictionaryData::TRIE_TYPE_UCHARS = 1;
|
||||
const int32_t DictionaryData::TRIE_TYPE_MASK = 7;
|
||||
const int32_t DictionaryData::TRIE_HAS_VALUES = 8;
|
||||
|
||||
const int32_t DictionaryData::TRANSFORM_NONE = 0;
|
||||
const int32_t DictionaryData::TRANSFORM_TYPE_OFFSET = 0x1000000;
|
||||
const int32_t DictionaryData::TRANSFORM_TYPE_MASK = 0x7f000000;
|
||||
const int32_t DictionaryData::TRANSFORM_OFFSET_MASK = 0x1fffff;
|
||||
|
||||
DictionaryMatcher::~DictionaryMatcher() {
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2012, International Business Machines
|
||||
* Copyright (C) 2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
* dictionarydata.h
|
||||
|
@ -29,15 +29,15 @@ class BytesTrie;
|
|||
|
||||
class U_COMMON_API DictionaryData : public UMemory {
|
||||
public:
|
||||
static const int32_t TRIE_TYPE_BYTES = 0;
|
||||
static const int32_t TRIE_TYPE_UCHARS = 1;
|
||||
static const int32_t TRIE_TYPE_MASK = 7;
|
||||
static const int32_t TRIE_HAS_VALUES = 8;
|
||||
static const int32_t TRIE_TYPE_BYTES; // = 0;
|
||||
static const int32_t TRIE_TYPE_UCHARS; // = 1;
|
||||
static const int32_t TRIE_TYPE_MASK; // = 7;
|
||||
static const int32_t TRIE_HAS_VALUES; // = 8;
|
||||
|
||||
static const int32_t TRANSFORM_NONE = 0;
|
||||
static const int32_t TRANSFORM_TYPE_OFFSET = 0x1000000;
|
||||
static const int32_t TRANSFORM_TYPE_MASK = 0x7f000000;
|
||||
static const int32_t TRANSFORM_OFFSET_MASK = 0x1fffff;
|
||||
static const int32_t TRANSFORM_NONE; // = 0;
|
||||
static const int32_t TRANSFORM_TYPE_OFFSET; // = 0x1000000;
|
||||
static const int32_t TRANSFORM_TYPE_MASK; // = 0x7f000000;
|
||||
static const int32_t TRANSFORM_OFFSET_MASK; // = 0x1fffff;
|
||||
|
||||
enum {
|
||||
// Byte offsets from the start of the data, after the generic header.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2011, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "unicode/ures.h"
|
||||
#include "cmemory.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "uassert.h"
|
||||
#include "umutex.h"
|
||||
#include "uresimp.h"
|
||||
|
||||
|
@ -30,6 +31,7 @@
|
|||
|
||||
static icu::Locale* availableLocaleList = NULL;
|
||||
static int32_t availableLocaleListCount;
|
||||
static UInitOnce gInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
|
@ -42,6 +44,7 @@ static UBool U_CALLCONV locale_available_cleanup(void)
|
|||
availableLocaleList = NULL;
|
||||
}
|
||||
availableLocaleListCount = 0;
|
||||
gInitOnce.reset();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -50,40 +53,29 @@ U_CDECL_END
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
void U_CALLCONV locale_available_init() {
|
||||
// This function is a friend of class Locale.
|
||||
// This function is only invoked via umtx_initOnce().
|
||||
|
||||
// for now, there is a hardcoded list, so just walk through that list and set it up.
|
||||
// Note: this function is a friend of class Locale.
|
||||
availableLocaleListCount = uloc_countAvailable();
|
||||
if(availableLocaleListCount) {
|
||||
availableLocaleList = new Locale[availableLocaleListCount];
|
||||
}
|
||||
if (availableLocaleList == NULL) {
|
||||
availableLocaleListCount= 0;
|
||||
}
|
||||
for (int32_t locCount=availableLocaleListCount-1; locCount>=0; --locCount) {
|
||||
availableLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
|
||||
}
|
||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
|
||||
}
|
||||
|
||||
const Locale* U_EXPORT2
|
||||
Locale::getAvailableLocales(int32_t& count)
|
||||
{
|
||||
// for now, there is a hardcoded list, so just walk through that list and set it up.
|
||||
UBool needInit;
|
||||
UMTX_CHECK(NULL, availableLocaleList == NULL, needInit);
|
||||
|
||||
if (needInit) {
|
||||
int32_t locCount = uloc_countAvailable();
|
||||
Locale *newLocaleList = 0;
|
||||
if(locCount) {
|
||||
newLocaleList = new Locale[locCount];
|
||||
}
|
||||
if (newLocaleList == NULL) {
|
||||
count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = locCount;
|
||||
|
||||
while(--locCount >= 0) {
|
||||
newLocaleList[locCount].setFromPOSIXID(uloc_getAvailable(locCount));
|
||||
}
|
||||
|
||||
umtx_lock(NULL);
|
||||
if(availableLocaleList == 0) {
|
||||
availableLocaleListCount = count;
|
||||
availableLocaleList = newLocaleList;
|
||||
newLocaleList = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_LOCALE_AVAILABLE, locale_available_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete []newLocaleList;
|
||||
}
|
||||
umtx_initOnce(gInitOnce, &locale_available_init);
|
||||
count = availableLocaleListCount;
|
||||
return availableLocaleList;
|
||||
}
|
||||
|
@ -104,6 +96,7 @@ static const char _kIndexTag[] = "InstalledLocales";
|
|||
|
||||
static char** _installedLocales = NULL;
|
||||
static int32_t _installedLocalesCount = 0;
|
||||
static UInitOnce _installedLocalesInitOnce;
|
||||
|
||||
/* ### Get available **************************************************/
|
||||
|
||||
|
@ -115,57 +108,51 @@ static UBool U_CALLCONV uloc_cleanup(void) {
|
|||
_installedLocales = NULL;
|
||||
|
||||
_installedLocalesCount = 0;
|
||||
_installedLocalesInitOnce.reset();
|
||||
|
||||
uprv_free(temp);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Load Installed Locales. This function will be called exactly once
|
||||
// via the initOnce mechanism.
|
||||
|
||||
static void U_CALLCONV loadInstalledLocales() {
|
||||
UResourceBundle *indexLocale = NULL;
|
||||
UResourceBundle installed;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t i = 0;
|
||||
int32_t localeCount;
|
||||
|
||||
U_ASSERT(_installedLocales == NULL);
|
||||
U_ASSERT(_installedLocalesCount == 0);
|
||||
|
||||
_installedLocalesCount = 0;
|
||||
ures_initStackObject(&installed);
|
||||
indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
|
||||
ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
|
||||
|
||||
if(U_SUCCESS(status)) {
|
||||
localeCount = ures_getSize(&installed);
|
||||
_installedLocales = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
|
||||
if (_installedLocales != NULL) {
|
||||
ures_resetIterator(&installed);
|
||||
while(ures_hasNext(&installed)) {
|
||||
ures_getNextString(&installed, NULL, (const char **)&_installedLocales[i++], &status);
|
||||
}
|
||||
_installedLocales[i] = NULL;
|
||||
_installedLocalesCount = localeCount;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
||||
}
|
||||
}
|
||||
ures_close(&installed);
|
||||
ures_close(indexLocale);
|
||||
}
|
||||
|
||||
static void _load_installedLocales()
|
||||
{
|
||||
UBool localesLoaded;
|
||||
|
||||
UMTX_CHECK(NULL, _installedLocales != NULL, localesLoaded);
|
||||
|
||||
if (localesLoaded == FALSE) {
|
||||
UResourceBundle *indexLocale = NULL;
|
||||
UResourceBundle installed;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
char ** temp;
|
||||
int32_t i = 0;
|
||||
int32_t localeCount;
|
||||
|
||||
ures_initStackObject(&installed);
|
||||
indexLocale = ures_openDirect(NULL, _kIndexLocaleName, &status);
|
||||
ures_getByKey(indexLocale, _kIndexTag, &installed, &status);
|
||||
|
||||
if(U_SUCCESS(status)) {
|
||||
localeCount = ures_getSize(&installed);
|
||||
temp = (char **) uprv_malloc(sizeof(char*) * (localeCount+1));
|
||||
/* Check for null pointer */
|
||||
if (temp != NULL) {
|
||||
ures_resetIterator(&installed);
|
||||
while(ures_hasNext(&installed)) {
|
||||
ures_getNextString(&installed, NULL, (const char **)&temp[i++], &status);
|
||||
}
|
||||
temp[i] = NULL;
|
||||
|
||||
umtx_lock(NULL);
|
||||
if (_installedLocales == NULL)
|
||||
{
|
||||
_installedLocalesCount = localeCount;
|
||||
_installedLocales = temp;
|
||||
temp = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_ULOC, uloc_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
uprv_free(temp);
|
||||
}
|
||||
}
|
||||
ures_close(&installed);
|
||||
ures_close(indexLocale);
|
||||
}
|
||||
umtx_initOnce(_installedLocalesInitOnce, &loadInstalledLocales);
|
||||
}
|
||||
|
||||
U_CAPI const char* U_EXPORT2
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008-2011, International Business Machines
|
||||
* Copyright (C) 2008-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -18,114 +18,63 @@
|
|||
U_NAMESPACE_BEGIN
|
||||
|
||||
void *SimpleSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
void *&duplicate,
|
||||
UErrorCode &errorCode) {
|
||||
duplicate=NULL;
|
||||
if(U_FAILURE(errorCode)) {
|
||||
return NULL;
|
||||
}
|
||||
// TODO: With atomicops.h: void *instance = (void*)Acquire_Load(&fInstance);
|
||||
// and remove UMTX_ACQUIRE_BARRIER below.
|
||||
void *instance=ANNOTATE_UNPROTECTED_READ(fInstance);
|
||||
UMTX_ACQUIRE_BARRIER;
|
||||
ANNOTATE_HAPPENS_AFTER(&fInstance);
|
||||
if(instance!=NULL) {
|
||||
return instance;
|
||||
if (umtx_loadAcquire(fInitOnce.fState) == 2) {
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
// Attempt to create the instance.
|
||||
// If a race occurs, then the losing thread will assign its new instance
|
||||
// to the "duplicate" parameter, and the caller deletes it.
|
||||
instance=instantiator(context, errorCode);
|
||||
UMTX_RELEASE_BARRIER; // Release-barrier before fInstance=instance;
|
||||
Mutex mutex;
|
||||
if(fInstance==NULL && U_SUCCESS(errorCode)) {
|
||||
U_ASSERT(instance!=NULL);
|
||||
ANNOTATE_HAPPENS_BEFORE(&fInstance);
|
||||
// TODO: With atomicops.h: Release_Store(&fInstance, (AtomicWord)instance);
|
||||
// and remove UMTX_RELEASE_BARRIER above.
|
||||
fInstance=instance;
|
||||
} else {
|
||||
duplicate=instance;
|
||||
if (umtx_initImplPreInit(fInitOnce)) {
|
||||
fInstance = instantiator(context, errorCode);
|
||||
umtx_initImplPostInit(fInitOnce, fInstance != NULL);
|
||||
}
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Three states:
|
||||
*
|
||||
* Initial state: Instance creation not attempted yet.
|
||||
* fInstance=NULL && U_SUCCESS(fErrorCode)
|
||||
*
|
||||
* Instance creation succeeded:
|
||||
* Instance creation run & succeeded:
|
||||
* fInstance!=NULL && U_SUCCESS(fErrorCode)
|
||||
*
|
||||
* Instance creation failed:
|
||||
* Instance creation & failed:
|
||||
* fInstance=NULL && U_FAILURE(fErrorCode)
|
||||
* We will not attempt again to create the instance.
|
||||
*
|
||||
* fInstance changes at most once.
|
||||
* fErrorCode changes at most twice (intial->failed->succeeded).
|
||||
* The instantiator function will be called only once, whether it succeeds or fails.
|
||||
* The controlling state is maintained by the UInitOnce object, not by
|
||||
* fInstance and fErrorCode.
|
||||
* The values of fInstance and fErrorCode must only be set between pre and post init(),
|
||||
* where they are in a controlled memory environment.
|
||||
*/
|
||||
void *TriStateSingleton::getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
void *&duplicate,
|
||||
UErrorCode &errorCode) {
|
||||
duplicate=NULL;
|
||||
if(U_FAILURE(errorCode)) {
|
||||
return NULL;
|
||||
}
|
||||
// TODO: With atomicops.h: void *instance = (void*)Acquire_Load(&fInstance);
|
||||
// and remove UMTX_ACQUIRE_BARRIER below.
|
||||
void *instance=ANNOTATE_UNPROTECTED_READ(fInstance);
|
||||
UMTX_ACQUIRE_BARRIER;
|
||||
ANNOTATE_HAPPENS_AFTER(&fInstance);
|
||||
if(instance!=NULL) {
|
||||
// instance was created
|
||||
return instance;
|
||||
if (umtx_loadAcquire(fInitOnce.fState) == 2) {
|
||||
errorCode = fErrorCode;
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
// The read access to fErrorCode is thread-unsafe, but harmless because
|
||||
// at worst multiple threads race to each create a new instance,
|
||||
// and all losing threads delete their duplicates.
|
||||
UErrorCode localErrorCode=ANNOTATE_UNPROTECTED_READ(fErrorCode);
|
||||
if(U_FAILURE(localErrorCode)) {
|
||||
// instance creation failed
|
||||
errorCode=localErrorCode;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First attempt to create the instance.
|
||||
// If a race occurs, then the losing thread will assign its new instance
|
||||
// to the "duplicate" parameter, and the caller deletes it.
|
||||
instance=instantiator(context, errorCode);
|
||||
UMTX_RELEASE_BARRIER; // Release-barrier before fInstance=instance;
|
||||
Mutex mutex;
|
||||
if(fInstance==NULL && U_SUCCESS(errorCode)) {
|
||||
// instance creation newly succeeded
|
||||
U_ASSERT(instance!=NULL);
|
||||
ANNOTATE_HAPPENS_BEFORE(&fInstance);
|
||||
// TODO: With atomicops.h: Release_Store(&fInstance, (AtomicWord)instance);
|
||||
// and remove UMTX_RELEASE_BARRIER above.
|
||||
fInstance=instance;
|
||||
// Set fErrorCode on the off-chance that a previous instance creation failed.
|
||||
fErrorCode=errorCode;
|
||||
// Completed state transition: initial->succeeded, or failed->succeeded.
|
||||
} else {
|
||||
// Record a duplicate if we lost the race, or
|
||||
// if we got an instance but its creation failed anyway.
|
||||
duplicate=instance;
|
||||
if(fInstance==NULL && U_SUCCESS(fErrorCode) && U_FAILURE(errorCode)) {
|
||||
// instance creation newly failed
|
||||
fErrorCode=errorCode;
|
||||
// Completed state transition: initial->failed.
|
||||
}
|
||||
if (umtx_initImplPreInit(fInitOnce)) {
|
||||
errorCode = U_ZERO_ERROR;
|
||||
fInstance = instantiator(context, errorCode);
|
||||
fErrorCode = errorCode;
|
||||
umtx_initImplPostInit(fInitOnce, TRUE);
|
||||
}
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
|
||||
void TriStateSingleton::reset() {
|
||||
fInstance=NULL;
|
||||
fErrorCode=U_ZERO_ERROR;
|
||||
fInitOnce.reset();
|
||||
}
|
||||
|
||||
#if UCONFIG_NO_SERVICE
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2012, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -90,27 +90,26 @@ typedef void *InstantiatorFn(const void *context, UErrorCode &errorCode);
|
|||
* Define a static SimpleSingleton instance via the STATIC_SIMPLE_SINGLETON macro.
|
||||
*/
|
||||
struct SimpleSingleton {
|
||||
void *fInstance;
|
||||
void *fInstance;
|
||||
UInitOnce fInitOnce;
|
||||
|
||||
/**
|
||||
* Returns the singleton instance, or NULL if it could not be created.
|
||||
* Calls the instantiator with the context if the instance has not been
|
||||
* created yet. In a race condition, the duplicate may not be NULL.
|
||||
* The caller must delete the duplicate.
|
||||
* The caller need not initialize the duplicate before the call.
|
||||
* created yet.
|
||||
*/
|
||||
void *getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
void *&duplicate,
|
||||
UErrorCode &errorCode);
|
||||
/**
|
||||
* Resets the fields. The caller must have deleted the singleton instance.
|
||||
* Not mutexed.
|
||||
* Call this from a cleanup function.
|
||||
*/
|
||||
void reset() { fInstance=NULL; }
|
||||
void reset() { fInstance=NULL; fInitOnce.reset(); }
|
||||
};
|
||||
|
||||
#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name={ NULL }
|
||||
#define SIMPLE_SINGLETON_INITIALIZER {NULL, U_INITONCE_INITIALIZER}
|
||||
#define STATIC_SIMPLE_SINGLETON(name) static SimpleSingleton name = SIMPLE_SINGLETON_INITIALIZER
|
||||
|
||||
/**
|
||||
* Handy wrapper for a SimpleSingleton.
|
||||
|
@ -127,9 +126,7 @@ public:
|
|||
}
|
||||
T *getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
UErrorCode &errorCode) {
|
||||
void *duplicate;
|
||||
T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
|
||||
delete (T *)duplicate;
|
||||
T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
|
||||
return instance;
|
||||
}
|
||||
private:
|
||||
|
@ -143,20 +140,18 @@ private:
|
|||
* Define a static TriStateSingleton instance via the STATIC_TRI_STATE_SINGLETON macro.
|
||||
*/
|
||||
struct TriStateSingleton {
|
||||
void *fInstance;
|
||||
UErrorCode fErrorCode;
|
||||
void *fInstance;
|
||||
UErrorCode fErrorCode;
|
||||
UInitOnce fInitOnce;
|
||||
|
||||
/**
|
||||
* Returns the singleton instance, or NULL if it could not be created.
|
||||
* Calls the instantiator with the context if the instance has not been
|
||||
* created yet. In a race condition, the duplicate may not be NULL.
|
||||
* The caller must delete the duplicate.
|
||||
* The caller need not initialize the duplicate before the call.
|
||||
* created yet.
|
||||
* The singleton creation is only attempted once. If it fails,
|
||||
* the singleton will then always return NULL.
|
||||
*/
|
||||
void *getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
void *&duplicate,
|
||||
UErrorCode &errorCode);
|
||||
/**
|
||||
* Resets the fields. The caller must have deleted the singleton instance.
|
||||
|
@ -166,7 +161,7 @@ struct TriStateSingleton {
|
|||
void reset();
|
||||
};
|
||||
|
||||
#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR }
|
||||
#define STATIC_TRI_STATE_SINGLETON(name) static TriStateSingleton name={ NULL, U_ZERO_ERROR, U_INITONCE_INITIALIZER }
|
||||
|
||||
/**
|
||||
* Handy wrapper for a TriStateSingleton.
|
||||
|
@ -183,9 +178,7 @@ public:
|
|||
}
|
||||
T *getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
UErrorCode &errorCode) {
|
||||
void *duplicate;
|
||||
T *instance=(T *)singleton.getInstance(instantiator, context, duplicate, errorCode);
|
||||
delete (T *)duplicate;
|
||||
T *instance=(T *)singleton.getInstance(instantiator, context, errorCode);
|
||||
return instance;
|
||||
}
|
||||
private:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2012, International Business Machines
|
||||
* Copyright (C) 2009-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -1796,10 +1796,8 @@ public:
|
|||
CanonIterDataSingleton(SimpleSingleton &s, Normalizer2Impl &ni, UErrorCode &ec) :
|
||||
singleton(s), impl(ni), errorCode(ec) {}
|
||||
CanonIterData *getInstance(UErrorCode &errorCode) {
|
||||
void *duplicate;
|
||||
CanonIterData *instance=
|
||||
(CanonIterData *)singleton.getInstance(createInstance, this, duplicate, errorCode);
|
||||
delete (CanonIterData *)duplicate;
|
||||
(CanonIterData *)singleton.getInstance(createInstance, this, errorCode);
|
||||
return instance;
|
||||
}
|
||||
static void *createInstance(const void *context, UErrorCode &errorCode);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2011, International Business Machines
|
||||
* Copyright (C) 2009-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -216,7 +216,7 @@ private:
|
|||
class U_COMMON_API Normalizer2Impl : public UMemory {
|
||||
public:
|
||||
Normalizer2Impl() : memory(NULL), normTrie(NULL) {
|
||||
canonIterDataSingleton.fInstance=NULL;
|
||||
canonIterDataSingleton.reset();
|
||||
}
|
||||
~Normalizer2Impl();
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2012, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -183,7 +183,13 @@ typedef size_t uintptr_t;
|
|||
*/
|
||||
#ifdef U_HAVE_GCC_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif U_GCC_MAJOR_MINOR >= 404
|
||||
#elif U_PLATFORM == U_PF_MINGW
|
||||
#define U_HAVE_GCC_ATOMICS 0
|
||||
#elif U_GCC_MAJOR_MINOR >= 404 || defined(__clang__)
|
||||
/* TODO: Intel icc and IBM xlc on AIX also support gcc atomics. (Intel originated them.)
|
||||
* Add them for these compilers.
|
||||
* Note: Clang sets __GNUC__ defines for version 4.2, so misses the 4.4 test here.
|
||||
*/
|
||||
# define U_HAVE_GCC_ATOMICS 1
|
||||
#else
|
||||
# define U_HAVE_GCC_ATOMICS 0
|
||||
|
@ -191,6 +197,34 @@ typedef size_t uintptr_t;
|
|||
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* \def U_HAVE_STD_ATOMICS
|
||||
* Defines whether the standard C++11 <atomic> is available.
|
||||
* @internal
|
||||
*/
|
||||
#ifdef U_HAVE_STD_ATOMICS
|
||||
/* Use the predefined value. */
|
||||
#elif defined(__cplusplus) && __cplusplus>=201103L
|
||||
/* C++11, so we should have atomics, except for specific platforms or compilers. */
|
||||
|
||||
#if __clang__ && defined(__apple_build_version__) && __clang_major__==4 && __clang_minor__<=1
|
||||
/* Apple Clang 4.1, based on public llvm 3.1. Atomics are not fully implemented. */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#elif __clang__ && __clang_major__==3 && __clang_minor__<=1
|
||||
/* Clang 3.1. Atomics not fully implemented. */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#else
|
||||
# define U_HAVE_STD_ATOMICS 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* Not C++ 11 */
|
||||
# define U_HAVE_STD_ATOMICS 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*===========================================================================*/
|
||||
/** @{ Code alignment */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
***************************************************************************
|
||||
* Copyright (C) 1999-2012 International Business Machines Corporation
|
||||
* Copyright (C) 1999-2013 International Business Machines Corporation
|
||||
* and others. All rights reserved.
|
||||
***************************************************************************
|
||||
*/
|
||||
|
@ -1793,6 +1793,7 @@ U_NAMESPACE_END
|
|||
// defined in ucln_cmn.h
|
||||
|
||||
static icu::UStack *gLanguageBreakFactories = NULL;
|
||||
static UInitOnce gLanguageBreakFactoriesInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Release all static memory held by breakiterator.
|
||||
|
@ -1803,6 +1804,7 @@ static UBool U_CALLCONV breakiterator_cleanup_dict(void) {
|
|||
delete gLanguageBreakFactories;
|
||||
gLanguageBreakFactories = NULL;
|
||||
}
|
||||
gLanguageBreakFactoriesInitOnce.reset();
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
@ -1814,35 +1816,28 @@ static void U_CALLCONV _deleteFactory(void *obj) {
|
|||
U_CDECL_END
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
static void U_CALLCONV initLanguageFactories() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
U_ASSERT(gLanguageBreakFactories == NULL);
|
||||
gLanguageBreakFactories = new UStack(_deleteFactory, NULL, status);
|
||||
if (gLanguageBreakFactories != NULL && U_SUCCESS(status)) {
|
||||
ICULanguageBreakFactory *builtIn = new ICULanguageBreakFactory(status);
|
||||
gLanguageBreakFactories->push(builtIn, status);
|
||||
#ifdef U_LOCAL_SERVICE_HOOK
|
||||
LanguageBreakFactory *extra = (LanguageBreakFactory *)uprv_svc_hook("languageBreakFactory", &status);
|
||||
if (extra != NULL) {
|
||||
gLanguageBreakFactories->push(extra, status);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
|
||||
}
|
||||
|
||||
|
||||
static const LanguageBreakEngine*
|
||||
getLanguageBreakEngineFromFactory(UChar32 c, int32_t breakType)
|
||||
{
|
||||
UBool needsInit;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UMTX_CHECK(NULL, (UBool)(gLanguageBreakFactories == NULL), needsInit);
|
||||
|
||||
if (needsInit) {
|
||||
UStack *factories = new UStack(_deleteFactory, NULL, status);
|
||||
if (factories != NULL && U_SUCCESS(status)) {
|
||||
ICULanguageBreakFactory *builtIn = new ICULanguageBreakFactory(status);
|
||||
factories->push(builtIn, status);
|
||||
#ifdef U_LOCAL_SERVICE_HOOK
|
||||
LanguageBreakFactory *extra = (LanguageBreakFactory *)uprv_svc_hook("languageBreakFactory", &status);
|
||||
if (extra != NULL) {
|
||||
factories->push(extra, status);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
umtx_lock(NULL);
|
||||
if (gLanguageBreakFactories == NULL) {
|
||||
gLanguageBreakFactories = factories;
|
||||
factories = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_BREAKITERATOR_DICT, breakiterator_cleanup_dict);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete factories;
|
||||
}
|
||||
|
||||
umtx_initOnce(gLanguageBreakFactoriesInitOnce, &initLanguageFactories);
|
||||
if (gLanguageBreakFactories == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2011 International Business Machines
|
||||
* Copyright (C) 1999-2013 International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -49,6 +49,7 @@ ubrk_swap(const UDataSwapper *ds,
|
|||
|
||||
#include "unicode/uobject.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "umutex.h"
|
||||
#include "utrie.h"
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -180,7 +181,7 @@ public:
|
|||
UTrie fTrie;
|
||||
|
||||
private:
|
||||
int32_t fRefCount;
|
||||
atomic_int32_t fRefCount;
|
||||
UDataMemory *fUDataMem;
|
||||
UnicodeString fRuleString;
|
||||
UBool fDontFreeData;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1997-2011, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -48,6 +48,9 @@
|
|||
|
||||
#include "unicode/utypes.h"
|
||||
#include "unicode/resbund.h"
|
||||
|
||||
#include "mutex.h"
|
||||
#include "uassert.h"
|
||||
#include "umutex.h"
|
||||
|
||||
#include "uresimp.h"
|
||||
|
@ -216,6 +219,10 @@ ResourceBundle& ResourceBundle::operator=(const ResourceBundle& other)
|
|||
ures_close(fResource);
|
||||
fResource = NULL;
|
||||
}
|
||||
if (fLocale != NULL) {
|
||||
delete fLocale;
|
||||
fLocale = NULL;
|
||||
}
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if (other.fResource) {
|
||||
fResource = ures_copyResb(0, other.fResource, &status);
|
||||
|
@ -367,28 +374,17 @@ void ResourceBundle::getVersion(UVersionInfo versionInfo) const {
|
|||
ures_getVersion(fResource, versionInfo);
|
||||
}
|
||||
|
||||
const Locale &ResourceBundle::getLocale(void) const
|
||||
{
|
||||
UBool needInit;
|
||||
UMTX_CHECK(NULL, (fLocale == NULL), needInit);
|
||||
if(needInit) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const char *localeName = ures_getLocaleInternal(fResource, &status);
|
||||
Locale *tLocale = new Locale(localeName);
|
||||
// Null pointer check
|
||||
if (tLocale == NULL) {
|
||||
return Locale::getDefault(); // Return default locale if one could not be created.
|
||||
}
|
||||
umtx_lock(NULL);
|
||||
ResourceBundle *me = (ResourceBundle *)this; // semantically const
|
||||
if (me->fLocale == NULL) {
|
||||
me->fLocale = tLocale;
|
||||
tLocale = NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
delete tLocale;
|
||||
static UMutex gLocaleLock = U_MUTEX_INITIALIZER;
|
||||
const Locale &ResourceBundle::getLocale(void) const {
|
||||
Mutex lock(&gLocaleLock);
|
||||
if (fLocale != NULL) {
|
||||
return *fLocale;
|
||||
}
|
||||
return *fLocale;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const char *localeName = ures_getLocaleInternal(fResource, &status);
|
||||
ResourceBundle *ncThis = const_cast<ResourceBundle *>(this);
|
||||
ncThis->fLocale = new Locale(localeName);
|
||||
return ncThis->fLocale != NULL ? *ncThis->fLocale : Locale::getDefault();
|
||||
}
|
||||
|
||||
const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &status) const
|
||||
|
@ -396,5 +392,5 @@ const Locale ResourceBundle::getLocale(ULocDataLocaleType type, UErrorCode &stat
|
|||
return ures_getLocaleByType(fResource, type, &status);
|
||||
}
|
||||
|
||||
//eof
|
||||
U_NAMESPACE_END
|
||||
//eof
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2009-2012, International Business Machines
|
||||
// Copyright (C) 2009-2013, International Business Machines
|
||||
// Corporation and others. All Rights Reserved.
|
||||
//
|
||||
// Copyright 2004 and onwards Google Inc.
|
||||
|
@ -68,15 +68,6 @@ operator==(const StringPiece& x, const StringPiece& y) {
|
|||
}
|
||||
|
||||
|
||||
/* Microsft Visual Studios <= 8.0 complains about redefinition of this
|
||||
* static const class variable. However, the C++ standard states that this
|
||||
* definition is correct. Perhaps there is a bug in the Microsoft compiler.
|
||||
* This is not an issue on any other compilers (that we know of) including
|
||||
* Visual Studios 9.0.
|
||||
* Cygwin with MSVC 9.0 also complains here about redefinition.
|
||||
*/
|
||||
#if (!defined(_MSC_VER) || (_MSC_VER >= 1500)) && !defined(CYGWINMSVC)
|
||||
const int32_t StringPiece::npos;
|
||||
#endif
|
||||
const int32_t StringPiece::npos = 0x7fffffff;
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2001-2012, International Business Machines
|
||||
* Copyright (C) 2001-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: ucln_cmn.c
|
||||
|
@ -58,7 +58,6 @@ u_cleanup(void)
|
|||
|
||||
ucln_lib_cleanup();
|
||||
|
||||
umtx_cleanup();
|
||||
cmemory_cleanup(); /* undo any heap functions set by u_setMemoryFunctions(). */
|
||||
gICUInitialized = FALSE;
|
||||
UTRACE_EXIT(); /* Must be before utrace_cleanup(), which turns off tracing. */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1996-2012, International Business Machines Corporation and
|
||||
* Copyright (c) 1996-2013, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************
|
||||
*
|
||||
|
@ -27,7 +27,9 @@
|
|||
#include "unicode/udata.h"
|
||||
#include "unicode/ucnv.h"
|
||||
#include "unicode/uloc.h"
|
||||
#include "mutex.h"
|
||||
#include "putilimp.h"
|
||||
#include "uassert.h"
|
||||
#include "utracimp.h"
|
||||
#include "ucnv_io.h"
|
||||
#include "ucnv_bld.h"
|
||||
|
@ -165,6 +167,7 @@ static UMutex cnvCacheMutex = U_MUTEX_INITIALIZER; /* Mutex for synchronizing c
|
|||
|
||||
static const char **gAvailableConverters = NULL;
|
||||
static uint16_t gAvailableConverterCount = 0;
|
||||
static UInitOnce gAvailableConvertersInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
#if !U_CHARSET_IS_UTF8
|
||||
|
||||
|
@ -187,15 +190,18 @@ static UBool gDefaultConverterContainsOption;
|
|||
|
||||
static const char DATA_TYPE[] = "cnv";
|
||||
|
||||
/* ucnv_flushAvailableConverterCache. This is only called from ucnv_cleanup().
|
||||
* If it is ever to be called from elsewhere, synchronization
|
||||
* will need to be considered.
|
||||
*/
|
||||
static void
|
||||
ucnv_flushAvailableConverterCache() {
|
||||
gAvailableConverterCount = 0;
|
||||
if (gAvailableConverters) {
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
gAvailableConverterCount = 0;
|
||||
uprv_free((char **)gAvailableConverters);
|
||||
gAvailableConverters = NULL;
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
}
|
||||
gAvailableConvertersInitOnce.reset();
|
||||
}
|
||||
|
||||
/* ucnv_cleanup - delete all storage held by the converter cache, except any */
|
||||
|
@ -1110,59 +1116,46 @@ ucnv_flushCache ()
|
|||
|
||||
/* available converters list --------------------------------------------------- */
|
||||
|
||||
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
||||
int needInit;
|
||||
UMTX_CHECK(&cnvCacheMutex, (gAvailableConverters == NULL), needInit);
|
||||
if (needInit) {
|
||||
UConverter tempConverter;
|
||||
UEnumeration *allConvEnum = NULL;
|
||||
uint16_t idx;
|
||||
uint16_t localConverterCount;
|
||||
uint16_t allConverterCount;
|
||||
UErrorCode localStatus;
|
||||
const char *converterName;
|
||||
const char **localConverterList;
|
||||
static void U_CALLCONV initAvailableConvertersList(UErrorCode &errCode) {
|
||||
U_ASSERT(gAvailableConverterCount == 0);
|
||||
U_ASSERT(gAvailableConverters == NULL);
|
||||
|
||||
allConvEnum = ucnv_openAllNames(pErrorCode);
|
||||
allConverterCount = uenum_count(allConvEnum, pErrorCode);
|
||||
if (U_FAILURE(*pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We can't have more than "*converterTable" converters to open */
|
||||
localConverterList = (const char **) uprv_malloc(allConverterCount * sizeof(char*));
|
||||
if (!localConverterList) {
|
||||
*pErrorCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Open the default converter to make sure that it has first dibs in the hash table. */
|
||||
localStatus = U_ZERO_ERROR;
|
||||
ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus));
|
||||
|
||||
localConverterCount = 0;
|
||||
|
||||
for (idx = 0; idx < allConverterCount; idx++) {
|
||||
localStatus = U_ZERO_ERROR;
|
||||
converterName = uenum_next(allConvEnum, NULL, &localStatus);
|
||||
if (ucnv_canCreateConverter(converterName, &localStatus)) {
|
||||
localConverterList[localConverterCount++] = converterName;
|
||||
}
|
||||
}
|
||||
uenum_close(allConvEnum);
|
||||
|
||||
umtx_lock(&cnvCacheMutex);
|
||||
if (gAvailableConverters == NULL) {
|
||||
gAvailableConverterCount = localConverterCount;
|
||||
gAvailableConverters = localConverterList;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
}
|
||||
else {
|
||||
uprv_free((char **)localConverterList);
|
||||
}
|
||||
umtx_unlock(&cnvCacheMutex);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
UEnumeration *allConvEnum = ucnv_openAllNames(&errCode);
|
||||
int32_t allConverterCount = uenum_count(allConvEnum, &errCode);
|
||||
if (U_FAILURE(errCode)) {
|
||||
return;
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
/* We can't have more than "*converterTable" converters to open */
|
||||
gAvailableConverters = (const char **) uprv_malloc(allConverterCount * sizeof(char*));
|
||||
if (!gAvailableConverters) {
|
||||
errCode = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Open the default converter to make sure that it has first dibs in the hash table. */
|
||||
UErrorCode localStatus = U_ZERO_ERROR;
|
||||
UConverter tempConverter;
|
||||
ucnv_close(ucnv_createConverter(&tempConverter, NULL, &localStatus));
|
||||
|
||||
gAvailableConverterCount = 0;
|
||||
|
||||
for (int32_t idx = 0; idx < allConverterCount; idx++) {
|
||||
localStatus = U_ZERO_ERROR;
|
||||
const char *converterName = uenum_next(allConvEnum, NULL, &localStatus);
|
||||
if (ucnv_canCreateConverter(converterName, &localStatus)) {
|
||||
gAvailableConverters[gAvailableConverterCount++] = converterName;
|
||||
}
|
||||
}
|
||||
|
||||
uenum_close(allConvEnum);
|
||||
}
|
||||
|
||||
|
||||
static UBool haveAvailableConverterList(UErrorCode *pErrorCode) {
|
||||
umtx_initOnce(gAvailableConvertersInitOnce, &initAvailableConvertersList, *pErrorCode);
|
||||
return U_SUCCESS(*pErrorCode);
|
||||
}
|
||||
|
||||
U_CFUNC uint16_t
|
||||
|
@ -1228,6 +1221,9 @@ internalSetName(const char *name, UErrorCode *status) {
|
|||
|
||||
/* gDefaultConverterName MUST be the last global var set by this function. */
|
||||
/* It is the variable checked in ucnv_getDefaultName() to see if initialization is required. */
|
||||
// But there is nothing here preventing that from being reordered, either by the compiler
|
||||
// or hardware. I'm adding the mutex to ucnv_getDefaultName for now. UMTX_CHECK is not enough.
|
||||
// -- Andy
|
||||
gDefaultConverterName = gDefaultConverterNameBuffer;
|
||||
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV, ucnv_cleanup);
|
||||
|
@ -1253,10 +1249,13 @@ ucnv_getDefaultName() {
|
|||
const char *name;
|
||||
|
||||
/*
|
||||
Multiple calls to ucnv_getDefaultName must be thread safe,
|
||||
Concurrent calls to ucnv_getDefaultName must be thread safe,
|
||||
but ucnv_setDefaultName is not thread safe.
|
||||
*/
|
||||
UMTX_CHECK(&cnvCacheMutex, gDefaultConverterName, name);
|
||||
{
|
||||
icu::Mutex lock(&cnvCacheMutex);
|
||||
name = gDefaultConverterName;
|
||||
}
|
||||
if(name==NULL) {
|
||||
UErrorCode errorCode = U_ZERO_ERROR;
|
||||
UConverter *cnv = NULL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2012, International Business Machines
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include "umutex.h"
|
||||
#include "uarrsort.h"
|
||||
#include "uassert.h"
|
||||
#include "udataswp.h"
|
||||
#include "cstring.h"
|
||||
#include "cmemory.h"
|
||||
|
@ -172,6 +173,7 @@ static const char DATA_NAME[] = "cnvalias";
|
|||
static const char DATA_TYPE[] = "icu";
|
||||
|
||||
static UDataMemory *gAliasData=NULL;
|
||||
static UInitOnce gAliasDataInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
enum {
|
||||
tocLengthIndex=0,
|
||||
|
@ -218,113 +220,97 @@ static UBool U_CALLCONV ucnv_io_cleanup(void)
|
|||
udata_close(gAliasData);
|
||||
gAliasData = NULL;
|
||||
}
|
||||
gAliasDataInitOnce.reset();
|
||||
|
||||
uprv_memset(&gMainTable, 0, sizeof(gMainTable));
|
||||
|
||||
return TRUE; /* Everything was cleaned up */
|
||||
}
|
||||
|
||||
static void U_CALLCONV initAliasData(UErrorCode &errCode) {
|
||||
UDataMemory *data;
|
||||
const uint16_t *table;
|
||||
const uint32_t *sectionSizes;
|
||||
uint32_t tableStart;
|
||||
uint32_t currOffset;
|
||||
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
|
||||
|
||||
U_ASSERT(gAliasData == NULL);
|
||||
data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &errCode);
|
||||
if(U_FAILURE(errCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
sectionSizes = (const uint32_t *)udata_getMemory(data);
|
||||
table = (const uint16_t *)sectionSizes;
|
||||
|
||||
tableStart = sectionSizes[0];
|
||||
if (tableStart < minTocLength) {
|
||||
errCode = U_INVALID_FORMAT_ERROR;
|
||||
udata_close(data);
|
||||
return;
|
||||
}
|
||||
gAliasData = data;
|
||||
|
||||
gMainTable.converterListSize = sectionSizes[1];
|
||||
gMainTable.tagListSize = sectionSizes[2];
|
||||
gMainTable.aliasListSize = sectionSizes[3];
|
||||
gMainTable.untaggedConvArraySize = sectionSizes[4];
|
||||
gMainTable.taggedAliasArraySize = sectionSizes[5];
|
||||
gMainTable.taggedAliasListsSize = sectionSizes[6];
|
||||
gMainTable.optionTableSize = sectionSizes[7];
|
||||
gMainTable.stringTableSize = sectionSizes[8];
|
||||
|
||||
if (tableStart > 8) {
|
||||
gMainTable.normalizedStringTableSize = sectionSizes[9];
|
||||
}
|
||||
|
||||
currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
|
||||
gMainTable.converterList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.converterListSize;
|
||||
gMainTable.tagList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.tagListSize;
|
||||
gMainTable.aliasList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.aliasListSize;
|
||||
gMainTable.untaggedConvArray = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.untaggedConvArraySize;
|
||||
gMainTable.taggedAliasArray = table + currOffset;
|
||||
|
||||
/* aliasLists is a 1's based array, but it has a padding character */
|
||||
currOffset += gMainTable.taggedAliasArraySize;
|
||||
gMainTable.taggedAliasLists = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.taggedAliasListsSize;
|
||||
if (gMainTable.optionTableSize > 0
|
||||
&& ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT)
|
||||
{
|
||||
/* Faster table */
|
||||
gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset);
|
||||
}
|
||||
else {
|
||||
/* Smaller table, or I can't handle this normalization mode!
|
||||
Use the original slower table lookup. */
|
||||
gMainTable.optionTable = &defaultTableOptions;
|
||||
}
|
||||
|
||||
currOffset += gMainTable.optionTableSize;
|
||||
gMainTable.stringTable = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.stringTableSize;
|
||||
gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
|
||||
? gMainTable.stringTable : (table + currOffset));
|
||||
}
|
||||
|
||||
|
||||
static UBool
|
||||
haveAliasData(UErrorCode *pErrorCode) {
|
||||
int needInit;
|
||||
|
||||
if(pErrorCode==NULL || U_FAILURE(*pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UMTX_CHECK(NULL, (gAliasData==NULL), needInit);
|
||||
|
||||
/* load converter alias data from file if necessary */
|
||||
if (needInit) {
|
||||
UDataMemory *data;
|
||||
const uint16_t *table;
|
||||
const uint32_t *sectionSizes;
|
||||
uint32_t tableStart;
|
||||
uint32_t currOffset;
|
||||
|
||||
data = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode);
|
||||
if(U_FAILURE(*pErrorCode)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
sectionSizes = (const uint32_t *)udata_getMemory(data);
|
||||
table = (const uint16_t *)sectionSizes;
|
||||
|
||||
tableStart = sectionSizes[0];
|
||||
if (tableStart < minTocLength) {
|
||||
*pErrorCode = U_INVALID_FORMAT_ERROR;
|
||||
udata_close(data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
umtx_lock(NULL);
|
||||
if(gAliasData==NULL) {
|
||||
gMainTable.converterListSize = sectionSizes[1];
|
||||
gMainTable.tagListSize = sectionSizes[2];
|
||||
gMainTable.aliasListSize = sectionSizes[3];
|
||||
gMainTable.untaggedConvArraySize = sectionSizes[4];
|
||||
gMainTable.taggedAliasArraySize = sectionSizes[5];
|
||||
gMainTable.taggedAliasListsSize = sectionSizes[6];
|
||||
gMainTable.optionTableSize = sectionSizes[7];
|
||||
gMainTable.stringTableSize = sectionSizes[8];
|
||||
|
||||
if (tableStart > 8) {
|
||||
gMainTable.normalizedStringTableSize = sectionSizes[9];
|
||||
}
|
||||
|
||||
currOffset = tableStart * (sizeof(uint32_t)/sizeof(uint16_t)) + (sizeof(uint32_t)/sizeof(uint16_t));
|
||||
gMainTable.converterList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.converterListSize;
|
||||
gMainTable.tagList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.tagListSize;
|
||||
gMainTable.aliasList = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.aliasListSize;
|
||||
gMainTable.untaggedConvArray = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.untaggedConvArraySize;
|
||||
gMainTable.taggedAliasArray = table + currOffset;
|
||||
|
||||
/* aliasLists is a 1's based array, but it has a padding character */
|
||||
currOffset += gMainTable.taggedAliasArraySize;
|
||||
gMainTable.taggedAliasLists = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.taggedAliasListsSize;
|
||||
if (gMainTable.optionTableSize > 0
|
||||
&& ((const UConverterAliasOptions *)(table + currOffset))->stringNormalizationType < UCNV_IO_NORM_TYPE_COUNT)
|
||||
{
|
||||
/* Faster table */
|
||||
gMainTable.optionTable = (const UConverterAliasOptions *)(table + currOffset);
|
||||
}
|
||||
else {
|
||||
/* Smaller table, or I can't handle this normalization mode!
|
||||
Use the original slower table lookup. */
|
||||
gMainTable.optionTable = &defaultTableOptions;
|
||||
}
|
||||
|
||||
currOffset += gMainTable.optionTableSize;
|
||||
gMainTable.stringTable = table + currOffset;
|
||||
|
||||
currOffset += gMainTable.stringTableSize;
|
||||
gMainTable.normalizedStringTable = ((gMainTable.optionTable->stringNormalizationType == UCNV_IO_UNNORMALIZED)
|
||||
? gMainTable.stringTable : (table + currOffset));
|
||||
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UCNV_IO, ucnv_io_cleanup);
|
||||
|
||||
gAliasData = data;
|
||||
data=NULL;
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
|
||||
/* if a different thread set it first, then close the extra data */
|
||||
if(data!=NULL) {
|
||||
udata_close(data); /* NULL if it was set correctly */
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
umtx_initOnce(gAliasDataInitOnce, &initAliasData, *pErrorCode);
|
||||
return U_SUCCESS(*pErrorCode);
|
||||
}
|
||||
|
||||
static inline UBool
|
||||
|
@ -351,7 +337,7 @@ static uint32_t getTagNumber(const char *tagname) {
|
|||
|
||||
/* character types relevant for ucnv_compareNames() */
|
||||
enum {
|
||||
IGNORE,
|
||||
UIGNORE,
|
||||
ZERO,
|
||||
NONZERO,
|
||||
MINLETTER /* any values from here on are lowercase letter mappings */
|
||||
|
@ -369,7 +355,7 @@ static const uint8_t asciiTypes[128] = {
|
|||
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)IGNORE)
|
||||
#define GET_ASCII_TYPE(c) ((int8_t)(c) >= 0 ? asciiTypes[(uint8_t)c] : (uint8_t)UIGNORE)
|
||||
|
||||
/* character types for EBCDIC 80..FF */
|
||||
static const uint8_t ebcdicTypes[128] = {
|
||||
|
@ -383,7 +369,7 @@ static const uint8_t ebcdicTypes[128] = {
|
|||
ZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, NONZERO, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)IGNORE)
|
||||
#define GET_EBCDIC_TYPE(c) ((int8_t)(c) < 0 ? ebcdicTypes[(c)&0x7f] : (uint8_t)UIGNORE)
|
||||
|
||||
#if U_CHARSET_FAMILY==U_ASCII_FAMILY
|
||||
# define GET_CHAR_TYPE(c) GET_ASCII_TYPE(c)
|
||||
|
@ -404,7 +390,7 @@ ucnv_io_stripASCIIForCompare(char *dst, const char *name) {
|
|||
while ((c1 = *name++) != 0) {
|
||||
type = GET_ASCII_TYPE(c1);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
case UIGNORE:
|
||||
afterDigit = FALSE;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
|
@ -439,7 +425,7 @@ ucnv_io_stripEBCDICForCompare(char *dst, const char *name) {
|
|||
while ((c1 = *name++) != 0) {
|
||||
type = GET_EBCDIC_TYPE(c1);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
case UIGNORE:
|
||||
afterDigit = FALSE;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
|
@ -496,7 +482,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
|
|||
while ((c1 = *name1++) != 0) {
|
||||
type = GET_CHAR_TYPE(c1);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
case UIGNORE:
|
||||
afterDigit1 = FALSE;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
|
@ -520,7 +506,7 @@ ucnv_compareNames(const char *name1, const char *name2) {
|
|||
while ((c2 = *name2++) != 0) {
|
||||
type = GET_CHAR_TYPE(c2);
|
||||
switch (type) {
|
||||
case IGNORE:
|
||||
case UIGNORE:
|
||||
afterDigit2 = FALSE;
|
||||
continue; /* ignore all but letters and digits */
|
||||
case ZERO:
|
||||
|
|
|
@ -30,6 +30,7 @@ might have to #include some other header
|
|||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "putilimp.h"
|
||||
#include "uassert.h"
|
||||
#include "ucln_cmn.h"
|
||||
#include "ucmndata.h"
|
||||
#include "udatamem.h"
|
||||
|
@ -106,6 +107,7 @@ static UDataMemory *gCommonICUDataArray[10] = { NULL };
|
|||
static UBool gHaveTriedToLoadCommonData = FALSE; /* See extendICUData(). */
|
||||
|
||||
static UHashtable *gCommonDataCache = NULL; /* Global hash table of opened ICU data files. */
|
||||
static UInitOnce gCommonDataCacheInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
static UDataFileAccess gDataFileAccess = UDATA_DEFAULT_ACCESS;
|
||||
|
||||
|
@ -118,6 +120,7 @@ udata_cleanup(void)
|
|||
uhash_close(gCommonDataCache); /* Table owns the contents, and will delete them. */
|
||||
gCommonDataCache = NULL; /* Cleanup is not thread safe. */
|
||||
}
|
||||
gCommonDataCacheInitOnce.reset();
|
||||
|
||||
for (i = 0; i < LENGTHOF(gCommonICUDataArray) && gCommonICUDataArray[i] != NULL; ++i) {
|
||||
udata_close(gCommonICUDataArray[i]);
|
||||
|
@ -262,42 +265,26 @@ static void U_CALLCONV DataCacheElement_deleter(void *pDCEl) {
|
|||
uprv_free(pDCEl); /* delete 'this' */
|
||||
}
|
||||
|
||||
/* udata_getCacheHashTable()
|
||||
* Get the hash table used to store the data cache entries.
|
||||
* Lazy create it if it doesn't yet exist.
|
||||
*/
|
||||
static UHashtable *udata_getHashTable() {
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
UBool cacheIsInitialized;
|
||||
UHashtable *tHT = NULL;
|
||||
|
||||
UMTX_CHECK(NULL, (gCommonDataCache != NULL), cacheIsInitialized);
|
||||
|
||||
if (cacheIsInitialized) {
|
||||
return gCommonDataCache;
|
||||
static void udata_initHashTable() {
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
U_ASSERT(gCommonDataCache == NULL);
|
||||
gCommonDataCache = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
|
||||
if (U_FAILURE(err)) {
|
||||
// TODO: handle errors better.
|
||||
gCommonDataCache = NULL;
|
||||
}
|
||||
|
||||
tHT = uhash_open(uhash_hashChars, uhash_compareChars, NULL, &err);
|
||||
/* Check for null pointer. */
|
||||
if (tHT == NULL) {
|
||||
return NULL; /* TODO: Handle this error better. */
|
||||
}
|
||||
uhash_setValueDeleter(tHT, DataCacheElement_deleter);
|
||||
|
||||
umtx_lock(NULL);
|
||||
if (gCommonDataCache == NULL) {
|
||||
gCommonDataCache = tHT;
|
||||
tHT = NULL;
|
||||
if (gCommonDataCache != NULL) {
|
||||
uhash_setValueDeleter(gCommonDataCache, DataCacheElement_deleter);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UDATA, udata_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
if (tHT != NULL) {
|
||||
uhash_close(tHT);
|
||||
}
|
||||
}
|
||||
|
||||
if (U_FAILURE(err)) {
|
||||
return NULL; /* TODO: handle this error better. */
|
||||
}
|
||||
/* udata_getCacheHashTable()
|
||||
* Get the hash table used to store the data cache entries.
|
||||
* Lazy create it if it doesn't yet exist.
|
||||
*/
|
||||
static UHashtable *udata_getHashTable() {
|
||||
umtx_initOnce(gCommonDataCacheInitOnce, &udata_initHashTable);
|
||||
return gCommonDataCache;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1997-2012, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -18,152 +18,122 @@
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "umutex.h"
|
||||
|
||||
#include "unicode/utypes.h"
|
||||
#include "uassert.h"
|
||||
#include "cmemory.h"
|
||||
#include "ucln_cmn.h"
|
||||
|
||||
// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
|
||||
static UMutex globalMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
/*
|
||||
* ICU Mutex wrappers. Wrap operating system mutexes, giving the rest of ICU a
|
||||
* platform independent set of mutex operations. For internal ICU use only.
|
||||
*/
|
||||
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
/* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */
|
||||
# undef POSIX
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Windows Specific Definitions
|
||||
//
|
||||
// Note: Cygwin (and possibly others) have both WIN32 and POSIX.
|
||||
// Prefer Win32 in these cases. (Win32 comes ahead in the #if chain)
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined U_NO_PLATFORM_ATOMICS
|
||||
#error ICU on Win32 requires support for low level atomic operations.
|
||||
// Visual Studio, gcc, clang are OK. Shouldn't get here.
|
||||
#endif
|
||||
|
||||
|
||||
// This function is called when a test of a UInitOnce::fState reveals that
|
||||
// initialization has not completed, that we either need to call the
|
||||
// function on this thread, or wait for some other thread to complete.
|
||||
//
|
||||
// The actual call to the init function is made inline by template code
|
||||
// that knows the C++ types involved. This function returns TRUE if
|
||||
// the caller needs to call the Init function.
|
||||
//
|
||||
|
||||
U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) {
|
||||
for (;;) {
|
||||
int32_t previousState = InterlockedCompareExchange(
|
||||
&uio.fState, // Destination
|
||||
1, // Exchange Value
|
||||
0); // Compare value
|
||||
|
||||
if (previousState == 0) {
|
||||
return true; // Caller will next call the init function.
|
||||
// Current state == 1.
|
||||
} else if (previousState == 2) {
|
||||
// Another thread already completed the initialization.
|
||||
// We can simply return FALSE, indicating no
|
||||
// further action is needed by the caller.
|
||||
return FALSE;
|
||||
} else {
|
||||
// Another thread is currently running the initialization.
|
||||
// Wait until it completes.
|
||||
do {
|
||||
Sleep(1);
|
||||
previousState = umtx_loadAcquire(uio.fState);
|
||||
} while (previousState == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called by the thread that ran an initialization function,
|
||||
// just after completing the function.
|
||||
//
|
||||
// success: True: the inialization succeeded. No further calls to the init
|
||||
// function will be made.
|
||||
// False: the initializtion failed. The next call to umtx_initOnce()
|
||||
// will retry the initialization.
|
||||
|
||||
U_CAPI void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio, UBool success) {
|
||||
int32_t nextState = success? 2: 0;
|
||||
umtx_storeRelease(uio.fState, nextState);
|
||||
}
|
||||
|
||||
|
||||
static void winMutexInit(CRITICAL_SECTION *cs) {
|
||||
InitializeCriticalSection(cs);
|
||||
return;
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
umtx_lock(UMutex *mutex) {
|
||||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
CRITICAL_SECTION *cs = &mutex->fCS;
|
||||
umtx_initOnce(mutex->fInitOnce, winMutexInit, cs);
|
||||
EnterCriticalSection(cs);
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
umtx_unlock(UMutex* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
LeaveCriticalSection(&mutex->fCS);
|
||||
}
|
||||
|
||||
#elif U_PLATFORM_IMPLEMENTS_POSIX
|
||||
# define POSIX
|
||||
#else
|
||||
# undef POSIX
|
||||
#endif
|
||||
|
||||
#if defined(POSIX)
|
||||
# include <pthread.h> /* must be first, so that we get the multithread versions of things. */
|
||||
#endif /* POSIX */
|
||||
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define VC_EXTRALEAN
|
||||
# define NOUSER
|
||||
# define NOSERVICE
|
||||
# define NOIME
|
||||
# define NOMCX
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "umutex.h"
|
||||
#include "cmemory.h"
|
||||
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
|
||||
InterlockedCompareExchangePointer(dest, newval, oldval)
|
||||
|
||||
#elif defined(POSIX)
|
||||
#if (U_HAVE_GCC_ATOMICS == 1)
|
||||
#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
|
||||
__sync_val_compare_and_swap(dest, oldval, newval)
|
||||
#else
|
||||
#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
|
||||
mutexed_compare_and_swap(dest, newval, oldval)
|
||||
#endif
|
||||
|
||||
#else
|
||||
// Unknown platform. Note that user can still set mutex functions at run time.
|
||||
#define SYNC_COMPARE_AND_SWAP(dest, oldval, newval) \
|
||||
mutexed_compare_and_swap(dest, newval, oldval)
|
||||
#endif
|
||||
|
||||
static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval);
|
||||
|
||||
// The ICU global mutex. Used when ICU implementation code passes NULL for the mutex pointer.
|
||||
static UMutex globalMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
// Implementation mutex. Used for compare & swap when no intrinsic is available, and
|
||||
// for safe initialization of user defined mutexes.
|
||||
static UMutex implMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
// List of all user mutexes that have been initialized.
|
||||
// Used to allow us to destroy them when cleaning up ICU.
|
||||
// Normal platform mutexes are not kept track of in this way - they survive until the process is shut down.
|
||||
// Normal platfrom mutexes don't allocate storage, so not cleaning them up won't trigger memory leak complaints.
|
||||
//-------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Note: putting this list in allocated memory would be awkward to arrange, because memory allocations
|
||||
// are used as a flag to indicate that ICU has been initialized, and setting other ICU
|
||||
// override functions will no longer work.
|
||||
// POSIX specific definitions
|
||||
//
|
||||
static const int MUTEX_LIST_LIMIT = 100;
|
||||
static UMutex *gMutexList[MUTEX_LIST_LIMIT];
|
||||
static int gMutexListSize = 0;
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
||||
# include <pthread.h>
|
||||
|
||||
/*
|
||||
* User mutex implementation functions. If non-null, call back to these rather than
|
||||
* directly using the system (Posix or Windows) APIs. See u_setMutexFunctions().
|
||||
* (declarations are in uclean.h)
|
||||
*/
|
||||
static UMtxInitFn *pMutexInitFn = NULL;
|
||||
static UMtxFn *pMutexDestroyFn = NULL;
|
||||
static UMtxFn *pMutexLockFn = NULL;
|
||||
static UMtxFn *pMutexUnlockFn = NULL;
|
||||
static const void *gMutexContext = NULL;
|
||||
|
||||
|
||||
// Clean up (undo) the effects of u_setMutexFunctions().
|
||||
//
|
||||
static void usrMutexCleanup() {
|
||||
if (pMutexDestroyFn != NULL) {
|
||||
for (int i = 0; i < gMutexListSize; i++) {
|
||||
UMutex *m = gMutexList[i];
|
||||
U_ASSERT(m->fInitialized);
|
||||
(*pMutexDestroyFn)(gMutexContext, &m->fUserMutex);
|
||||
m->fInitialized = FALSE;
|
||||
}
|
||||
(*pMutexDestroyFn)(gMutexContext, &globalMutex.fUserMutex);
|
||||
(*pMutexDestroyFn)(gMutexContext, &implMutex.fUserMutex);
|
||||
}
|
||||
gMutexListSize = 0;
|
||||
pMutexInitFn = NULL;
|
||||
pMutexDestroyFn = NULL;
|
||||
pMutexLockFn = NULL;
|
||||
pMutexUnlockFn = NULL;
|
||||
gMutexContext = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* User mutex lock.
|
||||
*
|
||||
* User mutexes need to be initialized before they can be used. We use the impl mutex
|
||||
* to synchronize the initialization check. This could be sped up on platforms that
|
||||
* support alternate ways to safely check the initialization flag.
|
||||
*
|
||||
*/
|
||||
static void usrMutexLock(UMutex *mutex) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if (!(mutex == &implMutex || mutex == &globalMutex)) {
|
||||
umtx_lock(&implMutex);
|
||||
if (!mutex->fInitialized) {
|
||||
(*pMutexInitFn)(gMutexContext, &mutex->fUserMutex, &status);
|
||||
U_ASSERT(U_SUCCESS(status));
|
||||
mutex->fInitialized = TRUE;
|
||||
U_ASSERT(gMutexListSize < MUTEX_LIST_LIMIT);
|
||||
if (gMutexListSize < MUTEX_LIST_LIMIT) {
|
||||
gMutexList[gMutexListSize] = mutex;
|
||||
++gMutexListSize;
|
||||
}
|
||||
}
|
||||
umtx_unlock(&implMutex);
|
||||
}
|
||||
(*pMutexLockFn)(gMutexContext, &mutex->fUserMutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if defined(POSIX)
|
||||
|
||||
//
|
||||
// POSIX implementation of UMutex.
|
||||
//
|
||||
// Each UMutex has a corresponding pthread_mutex_t.
|
||||
// Each UMutex consists of a pthread_mutex_t.
|
||||
// All are statically initialized and ready for use.
|
||||
// There is no runtime mutex initialization code needed.
|
||||
|
||||
|
@ -172,17 +142,9 @@ umtx_lock(UMutex *mutex) {
|
|||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
if (pMutexLockFn) {
|
||||
usrMutexLock(mutex);
|
||||
} else {
|
||||
#if U_DEBUG
|
||||
// #if to avoid unused variable warnings in non-debug builds.
|
||||
int sysErr = pthread_mutex_lock(&mutex->fMutex);
|
||||
U_ASSERT(sysErr == 0);
|
||||
#else
|
||||
pthread_mutex_lock(&mutex->fMutex);
|
||||
#endif
|
||||
}
|
||||
int sysErr = pthread_mutex_lock(&mutex->fMutex);
|
||||
(void)sysErr; // Suppress unused variable warnings.
|
||||
U_ASSERT(sysErr == 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,292 +154,161 @@ umtx_unlock(UMutex* mutex)
|
|||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
if (pMutexUnlockFn) {
|
||||
(*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
|
||||
} else {
|
||||
#if U_DEBUG
|
||||
// #if to avoid unused variable warnings in non-debug builds.
|
||||
int sysErr = pthread_mutex_unlock(&mutex->fMutex);
|
||||
U_ASSERT(sysErr == 0);
|
||||
#else
|
||||
pthread_mutex_unlock(&mutex->fMutex);
|
||||
#endif
|
||||
}
|
||||
int sysErr = pthread_mutex_unlock(&mutex->fMutex);
|
||||
(void)sysErr; // Suppress unused variable warnings.
|
||||
U_ASSERT(sysErr == 0);
|
||||
}
|
||||
|
||||
#elif U_PLATFORM_HAS_WIN32_API
|
||||
static pthread_mutex_t initMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t initCondition = PTHREAD_COND_INITIALIZER;
|
||||
|
||||
|
||||
// This function is called when a test of a UInitOnce::fState reveals that
|
||||
// initialization has not completed, that we either need to call the
|
||||
// function on this thread, or wait for some other thread to complete.
|
||||
//
|
||||
// Windows implementation of UMutex.
|
||||
// The actual call to the init function is made inline by template code
|
||||
// that knows the C++ types involved. This function returns TRUE if
|
||||
// the caller needs to call the Init function.
|
||||
//
|
||||
// Each UMutex has a corresponding Windows CRITICAL_SECTION.
|
||||
// CRITICAL_SECTIONS must be initialized before use. This is done
|
||||
// with a InitOnceExcuteOnce operation.
|
||||
UBool umtx_initImplPreInit(UInitOnce &uio) {
|
||||
pthread_mutex_lock(&initMutex);
|
||||
int32_t state = uio.fState;
|
||||
if (state == 0) {
|
||||
umtx_storeRelease(uio.fState, 1);
|
||||
pthread_mutex_unlock(&initMutex);
|
||||
return true; // Caller will next call the init function.
|
||||
} else if (state == 2) {
|
||||
// Another thread already completed the initialization, in
|
||||
// a race with this thread. We can simply return FALSE, indicating no
|
||||
// further action is needed by the caller.
|
||||
pthread_mutex_unlock(&initMutex);
|
||||
return FALSE;
|
||||
} else {
|
||||
// Another thread is currently running the initialization.
|
||||
// Wait until it completes.
|
||||
U_ASSERT(state == 1);
|
||||
while (uio.fState == 1) {
|
||||
pthread_cond_wait(&initCondition, &initMutex);
|
||||
}
|
||||
UBool returnVal = uio.fState == 0;
|
||||
if (returnVal) {
|
||||
// Initialization that was running in another thread failed.
|
||||
// We will retry it in this thread.
|
||||
// (This is only used by SimpleSingleton)
|
||||
umtx_storeRelease(uio.fState, 1);
|
||||
}
|
||||
pthread_mutex_unlock(&initMutex);
|
||||
return returnVal;
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called by the thread that ran an initialization function,
|
||||
// just after completing the function.
|
||||
// Some threads may be waiting on the condition, requiring the broadcast wakeup.
|
||||
// Some threads may be racing to test the fState variable outside of the mutex,
|
||||
// requiring the use of store/release when changing its value.
|
||||
//
|
||||
// InitOnceExecuteOnce was introduced with Windows Vista. For now ICU
|
||||
// must support Windows XP, so we roll our own. ICU will switch to the
|
||||
// native Windows InitOnceExecuteOnce when possible.
|
||||
// success: True: the inialization succeeded. No further calls to the init
|
||||
// function will be made.
|
||||
// False: the initializtion failed. The next call to umtx_initOnce()
|
||||
// will retry the initialization.
|
||||
|
||||
typedef UBool (*U_PINIT_ONCE_FN) (
|
||||
U_INIT_ONCE *initOnce,
|
||||
void *parameter,
|
||||
void **context
|
||||
);
|
||||
|
||||
UBool u_InitOnceExecuteOnce(
|
||||
U_INIT_ONCE *initOnce,
|
||||
U_PINIT_ONCE_FN initFn,
|
||||
void *parameter,
|
||||
void **context) {
|
||||
for (;;) {
|
||||
long previousState = InterlockedCompareExchange(
|
||||
&initOnce->fState, // Destination,
|
||||
1, // Exchange Value
|
||||
0); // Compare value
|
||||
if (previousState == 2) {
|
||||
// Initialization was already completed.
|
||||
if (context != NULL) {
|
||||
*context = initOnce->fContext;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
if (previousState == 1) {
|
||||
// Initialization is in progress in some other thread.
|
||||
// Loop until it completes.
|
||||
Sleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Initialization needed. Execute the callback function to do it.
|
||||
U_ASSERT(previousState == 0);
|
||||
U_ASSERT(initOnce->fState == 1);
|
||||
UBool success = (*initFn)(initOnce, parameter, &initOnce->fContext);
|
||||
U_ASSERT(success); // ICU is not supporting the failure case.
|
||||
|
||||
// Assign the state indicating that initialization has completed.
|
||||
// Using InterlockedCompareExchange to do it ensures that all
|
||||
// threads will have a consistent view of memory.
|
||||
previousState = InterlockedCompareExchange(&initOnce->fState, 2, 1);
|
||||
U_ASSERT(previousState == 1);
|
||||
// Next loop iteration will see the initialization and return.
|
||||
}
|
||||
};
|
||||
|
||||
static UBool winMutexInit(U_INIT_ONCE *initOnce, void *param, void **context) {
|
||||
UMutex *mutex = static_cast<UMutex *>(param);
|
||||
U_ASSERT(sizeof(CRITICAL_SECTION) <= sizeof(mutex->fCS));
|
||||
InitializeCriticalSection((CRITICAL_SECTION *)mutex->fCS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* umtx_lock
|
||||
*/
|
||||
U_CAPI void U_EXPORT2
|
||||
umtx_lock(UMutex *mutex) {
|
||||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
if (pMutexLockFn) {
|
||||
usrMutexLock(mutex);
|
||||
} else {
|
||||
u_InitOnceExecuteOnce(&mutex->fInitOnce, winMutexInit, mutex, NULL);
|
||||
EnterCriticalSection((CRITICAL_SECTION *)mutex->fCS);
|
||||
}
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
umtx_unlock(UMutex* mutex)
|
||||
{
|
||||
if (mutex == NULL) {
|
||||
mutex = &globalMutex;
|
||||
}
|
||||
if (pMutexUnlockFn) {
|
||||
(*pMutexUnlockFn)(gMutexContext, &mutex->fUserMutex);
|
||||
} else {
|
||||
LeaveCriticalSection((CRITICAL_SECTION *)mutex->fCS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // Windows Implementation
|
||||
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u,
|
||||
UErrorCode *status) {
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can not set a mutex function to a NULL value */
|
||||
if (i==NULL || d==NULL || l==NULL || u==NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If ICU is not in an initial state, disallow this operation. */
|
||||
if (cmemory_inUse()) {
|
||||
*status = U_INVALID_STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
// Clean up any previously set user mutex functions.
|
||||
// It's possible to call u_setMutexFunctions() more than once without without explicitly cleaning up,
|
||||
// and the last call should take. Kind of a corner case, but it worked once, there is a test for
|
||||
// it, so we keep it working. The global and impl mutexes will have been created by the
|
||||
// previous u_setMutexFunctions(), and now need to be destroyed.
|
||||
|
||||
usrMutexCleanup();
|
||||
|
||||
/* Swap in the mutex function pointers. */
|
||||
pMutexInitFn = i;
|
||||
pMutexDestroyFn = d;
|
||||
pMutexLockFn = l;
|
||||
pMutexUnlockFn = u;
|
||||
gMutexContext = context;
|
||||
gMutexListSize = 0;
|
||||
|
||||
/* Initialize the global and impl mutexes. Safe to do at this point because
|
||||
* u_setMutexFunctions must be done in a single-threaded envioronment. Not thread safe.
|
||||
*/
|
||||
(*pMutexInitFn)(gMutexContext, &globalMutex.fUserMutex, status);
|
||||
globalMutex.fInitialized = TRUE;
|
||||
(*pMutexInitFn)(gMutexContext, &implMutex.fUserMutex, status);
|
||||
implMutex.fInitialized = TRUE;
|
||||
void umtx_initImplPostInit(UInitOnce &uio, UBool success) {
|
||||
int32_t nextState = success? 2: 0;
|
||||
pthread_mutex_lock(&initMutex);
|
||||
umtx_storeRelease(uio.fState, nextState);
|
||||
pthread_cond_broadcast(&initCondition);
|
||||
pthread_mutex_unlock(&initMutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* synchronized compare and swap function, for use when OS or compiler built-in
|
||||
* equivalents aren't available.
|
||||
*/
|
||||
static void *mutexed_compare_and_swap(void **dest, void *newval, void *oldval) {
|
||||
umtx_lock(&implMutex);
|
||||
void *temp = *dest;
|
||||
if (temp == oldval) {
|
||||
*dest = newval;
|
||||
}
|
||||
umtx_unlock(&implMutex);
|
||||
|
||||
return temp;
|
||||
void umtx_initOnceReset(UInitOnce &uio) {
|
||||
// Not a thread safe function, we can use an ordinary assignment.
|
||||
uio.fState = 0;
|
||||
}
|
||||
|
||||
// End of POSIX specific umutex implementation.
|
||||
|
||||
#else // Platform #define chain.
|
||||
|
||||
#error Unknown Platform
|
||||
|
||||
#endif // Platform #define chain.
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
//
|
||||
// Atomic Operations, out-of-line versions.
|
||||
// These are conditional, only defined if better versions
|
||||
// were not available for the platform.
|
||||
//
|
||||
// These versions are platform neutral.
|
||||
//
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
*
|
||||
* Atomic Increment and Decrement
|
||||
* umtx_atomic_inc
|
||||
* umtx_atomic_dec
|
||||
*
|
||||
*----------------------------------------------------------------*/
|
||||
|
||||
/* Pointers to user-supplied inc/dec functions. Null if no funcs have been set. */
|
||||
static UMtxAtomicFn *pIncFn = NULL;
|
||||
static UMtxAtomicFn *pDecFn = NULL;
|
||||
static const void *gIncDecContext = NULL;
|
||||
|
||||
#if defined (POSIX) && (U_HAVE_GCC_ATOMICS == 0)
|
||||
#if defined U_NO_PLATFORM_ATOMICS
|
||||
static UMutex gIncDecMutex = U_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
umtx_atomic_inc(int32_t *p) {
|
||||
int32_t retVal;
|
||||
if (pIncFn) {
|
||||
retVal = (*pIncFn)(gIncDecContext, p);
|
||||
} else {
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
retVal = InterlockedIncrement((LONG*)p);
|
||||
#elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
|
||||
retVal = OSAtomicIncrement32Barrier(p);
|
||||
#elif (U_HAVE_GCC_ATOMICS == 1)
|
||||
retVal = __sync_add_and_fetch(p, 1);
|
||||
#elif defined (POSIX)
|
||||
umtx_lock(&gIncDecMutex);
|
||||
retVal = ++(*p);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
#else
|
||||
/* Unknown Platform. */
|
||||
retVal = ++(*p);
|
||||
#endif
|
||||
}
|
||||
umtx_lock(&gIncDecMutex);
|
||||
retVal = ++(*p);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
umtx_atomic_dec(int32_t *p) {
|
||||
int32_t retVal;
|
||||
if (pDecFn) {
|
||||
retVal = (*pDecFn)(gIncDecContext, p);
|
||||
} else {
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
retVal = InterlockedDecrement((LONG*)p);
|
||||
#elif defined(USE_MAC_OS_ATOMIC_INCREMENT)
|
||||
retVal = OSAtomicDecrement32Barrier(p);
|
||||
#elif (U_HAVE_GCC_ATOMICS == 1)
|
||||
retVal = __sync_sub_and_fetch(p, 1);
|
||||
#elif defined (POSIX)
|
||||
umtx_lock(&gIncDecMutex);
|
||||
retVal = --(*p);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
#else
|
||||
/* Unknown Platform. */
|
||||
retVal = --(*p);
|
||||
#endif
|
||||
}
|
||||
umtx_lock(&gIncDecMutex);
|
||||
retVal = --(*p);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
umtx_loadAcquire(atomic_int32_t &var) {
|
||||
int32_t val = var;
|
||||
umtx_lock(&gIncDecMutex);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
return val;
|
||||
}
|
||||
|
||||
U_INTERNAL void U_EXPORT2
|
||||
umtx_storeRelease(atomic_int32_t &var, int32_t val) {
|
||||
umtx_lock(&gIncDecMutex);
|
||||
umtx_unlock(&gIncDecMutex);
|
||||
var = val;
|
||||
}
|
||||
|
||||
U_CAPI void U_EXPORT2
|
||||
u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *ip, UMtxAtomicFn *dp,
|
||||
UErrorCode *status) {
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
/* Can not set a mutex function to a NULL value */
|
||||
if (ip==NULL || dp==NULL) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return;
|
||||
}
|
||||
/* If ICU is not in an initial state, disallow this operation. */
|
||||
if (cmemory_inUse()) {
|
||||
*status = U_INVALID_STATE_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
pIncFn = ip;
|
||||
pDecFn = dp;
|
||||
gIncDecContext = context;
|
||||
|
||||
#if U_DEBUG
|
||||
{
|
||||
int32_t testInt = 0;
|
||||
U_ASSERT(umtx_atomic_inc(&testInt) == 1); /* Sanity Check. Do the functions work at all? */
|
||||
U_ASSERT(testInt == 1);
|
||||
U_ASSERT(umtx_atomic_dec(&testInt) == 0);
|
||||
U_ASSERT(testInt == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Deprecated functions for setting user mutexes.
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
U_DEPRECATED void U_EXPORT2
|
||||
u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *,
|
||||
UMtxFn *, UMtxFn *, UErrorCode *status) {
|
||||
if (U_SUCCESS(*status)) {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mutex Cleanup Function
|
||||
* Reset the mutex function callback pointers.
|
||||
* Called from the global ICU u_cleanup() function.
|
||||
*/
|
||||
U_CFUNC UBool umtx_cleanup(void) {
|
||||
/* Extra, do-nothing function call to suppress compiler warnings on platforms where
|
||||
* mutexed_compare_and_swap is not otherwise used. */
|
||||
void *pv = &globalMutex;
|
||||
mutexed_compare_and_swap(&pv, NULL, NULL);
|
||||
usrMutexCleanup();
|
||||
|
||||
pIncFn = NULL;
|
||||
pDecFn = NULL;
|
||||
gIncDecContext = NULL;
|
||||
|
||||
return TRUE;
|
||||
U_DEPRECATED void U_EXPORT2
|
||||
u_setAtomicIncDecFunctions(const void * /*context */, UMtxAtomicFn *, UMtxAtomicFn *,
|
||||
UErrorCode *status) {
|
||||
if (U_SUCCESS(*status)) {
|
||||
*status = U_UNSUPPORTED_ERROR;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
**********************************************************************
|
||||
* Copyright (C) 1997-2012, International Business Machines
|
||||
* Copyright (C) 1997-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
*
|
||||
|
@ -22,208 +22,346 @@
|
|||
#include "unicode/uclean.h"
|
||||
#include "putilimp.h"
|
||||
|
||||
/* For _ReadWriteBarrier(). */
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
/* For CRITICAL_SECTION */
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
#if 0
|
||||
/* TODO(andy): Why doesn't windows.h compile in all files? It does in some.
|
||||
* The intent was to include windows.h here, and have struct UMutex
|
||||
* have an embedded CRITICAL_SECTION when building on Windows.
|
||||
* The workaround is to put some char[] storage in UMutex instead,
|
||||
* avoiding the need to include windows.h everwhere this header is included.
|
||||
*/
|
||||
|
||||
// Forward Declarations
|
||||
struct UMutex;
|
||||
struct UInitOnce;
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Low Level Atomic Operations.
|
||||
* Compiler dependent. Not operating system dependent.
|
||||
*
|
||||
****************************************************************************/
|
||||
#if U_HAVE_STD_ATOMICS
|
||||
|
||||
// C++11 atomics are available.
|
||||
|
||||
#include <atomic>
|
||||
|
||||
typedef std::atomic<int32_t> atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
|
||||
|
||||
inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
|
||||
return var.load(std::memory_order_acquire);
|
||||
};
|
||||
|
||||
inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
|
||||
var.store(val, std::memory_order_release);
|
||||
};
|
||||
|
||||
inline int32_t umtx_atomic_inc(atomic_int32_t *var) {
|
||||
return var->fetch_add(1) + 1;
|
||||
}
|
||||
|
||||
inline int32_t umtx_atomic_dec(atomic_int32_t *var) {
|
||||
return var->fetch_sub(1) - 1;
|
||||
}
|
||||
|
||||
|
||||
#elif U_PLATFORM_HAS_WIN32_API
|
||||
|
||||
// MSVC compiler. Reads and writes of volatile variables have
|
||||
// acquire and release memory semantics, respectively.
|
||||
// This is a Microsoft extension, not standard C++ behavior.
|
||||
//
|
||||
// Update: can't use this because of MinGW, built with gcc.
|
||||
// Original plan was to use gcc atomics for MinGW, but they
|
||||
// aren't supported, so we fold MinGW into this path.
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define VC_EXTRALEAN
|
||||
# define NOUSER
|
||||
# define NOSERVICE
|
||||
# define NOIME
|
||||
# define NOMCX
|
||||
# include <windows.h>
|
||||
#endif /* 0 */
|
||||
#define U_WINDOWS_CRIT_SEC_SIZE 64
|
||||
#endif /* win32 */
|
||||
|
||||
#if U_PLATFORM_IS_DARWIN_BASED
|
||||
#if defined(__STRICT_ANSI__)
|
||||
#define UPRV_REMAP_INLINE
|
||||
#define inline
|
||||
#endif
|
||||
#include <libkern/OSAtomic.h>
|
||||
#define USE_MAC_OS_ATOMIC_INCREMENT 1
|
||||
#if defined(UPRV_REMAP_INLINE)
|
||||
#undef inline
|
||||
#undef UPRV_REMAP_INLINE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If we do not compile with dynamic_annotations.h then define
|
||||
* empty annotation macros.
|
||||
* See http://code.google.com/p/data-race-test/wiki/DynamicAnnotations
|
||||
*/
|
||||
#ifndef ANNOTATE_HAPPENS_BEFORE
|
||||
# define ANNOTATE_HAPPENS_BEFORE(obj)
|
||||
# define ANNOTATE_HAPPENS_AFTER(obj)
|
||||
# define ANNOTATE_UNPROTECTED_READ(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef UMTX_FULL_BARRIER
|
||||
# if U_HAVE_GCC_ATOMICS
|
||||
# define UMTX_FULL_BARRIER __sync_synchronize();
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1500
|
||||
/* From MSVC intrin.h. Use _ReadWriteBarrier() only on MSVC 9 and higher. */
|
||||
# define UMTX_FULL_BARRIER _ReadWriteBarrier();
|
||||
# elif U_PLATFORM_IS_DARWIN_BASED
|
||||
# define UMTX_FULL_BARRIER OSMemoryBarrier();
|
||||
# else
|
||||
# define UMTX_FULL_BARRIER \
|
||||
{ \
|
||||
umtx_lock(NULL); \
|
||||
umtx_unlock(NULL); \
|
||||
}
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
#endif
|
||||
# include <windows.h>
|
||||
|
||||
#ifndef UMTX_ACQUIRE_BARRIER
|
||||
# define UMTX_ACQUIRE_BARRIER UMTX_FULL_BARRIER
|
||||
#endif
|
||||
typedef volatile LONG atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
#ifndef UMTX_RELEASE_BARRIER
|
||||
# define UMTX_RELEASE_BARRIER UMTX_FULL_BARRIER
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
|
||||
return InterlockedCompareExchange(&var, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \def UMTX_CHECK
|
||||
* Encapsulates a safe check of an expression
|
||||
* for use with double-checked lazy inititialization.
|
||||
* Either memory barriers or mutexes are required, to prevent both the hardware
|
||||
* and the compiler from reordering operations across the check.
|
||||
* The expression must involve only a _single_ variable, typically
|
||||
* a possibly null pointer or a boolean that indicates whether some service
|
||||
* is initialized or not.
|
||||
* The setting of the variable involved in the test must be the last step of
|
||||
* the initialization process.
|
||||
*
|
||||
* @internal
|
||||
inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
|
||||
InterlockedExchange(&var, val);
|
||||
}
|
||||
|
||||
|
||||
inline int32_t umtx_atomic_inc(atomic_int32_t *var) {
|
||||
return InterlockedIncrement(var);
|
||||
}
|
||||
|
||||
inline int32_t umtx_atomic_dec(atomic_int32_t *var) {
|
||||
return InterlockedDecrement(var);
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
#elif U_HAVE_GCC_ATOMICS
|
||||
/*
|
||||
* gcc atomic ops. These are available on several other compilers as well.
|
||||
*/
|
||||
#define UMTX_CHECK(pMutex, expression, result) \
|
||||
{ \
|
||||
(result)=(expression); \
|
||||
UMTX_ACQUIRE_BARRIER; \
|
||||
typedef int32_t atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
#ifdef __cplusplus
|
||||
inline int32_t umtx_loadAcquire(atomic_int32_t &var) {
|
||||
int32_t val = var;
|
||||
__sync_synchronize();
|
||||
return val;
|
||||
}
|
||||
|
||||
inline void umtx_storeRelease(atomic_int32_t &var, int32_t val) {
|
||||
__sync_synchronize();
|
||||
var = val;
|
||||
}
|
||||
|
||||
inline int32_t umtx_atomic_inc(atomic_int32_t *p) {
|
||||
return __sync_add_and_fetch(p, 1);
|
||||
}
|
||||
|
||||
inline int32_t umtx_atomic_dec(atomic_int32_t *p) {
|
||||
return __sync_sub_and_fetch(p, 1);
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Unknown Platform. Use out-of-line functions, which in turn use mutexes.
|
||||
* Slow but correct.
|
||||
*/
|
||||
|
||||
#define U_NO_PLATFORM_ATOMICS
|
||||
|
||||
typedef int32_t atomic_int32_t;
|
||||
#define ATOMIC_INT32_T_INITIALIZER(val) val
|
||||
|
||||
#ifdef __cplusplus
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_loadAcquire(atomic_int32_t &var);
|
||||
|
||||
U_INTERNAL void U_EXPORT2 umtx_storeRelease(atomic_int32_t &var, int32_t val);
|
||||
#endif /* __cplusplus */
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_atomic_inc(atomic_int32_t *p);
|
||||
|
||||
U_INTERNAL int32_t U_EXPORT2 umtx_atomic_dec(atomic_int32_t *p);
|
||||
|
||||
#endif /* Low Level Atomic Ops Platfrom Chain */
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
*
|
||||
* UInitOnce Definitions.
|
||||
* These are platform neutral.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
struct UInitOnce {
|
||||
atomic_int32_t fState;
|
||||
UErrorCode fErrCode;
|
||||
#ifdef __cplusplus
|
||||
void reset() {fState = 0; fState=0;};
|
||||
UBool isReset() {return umtx_loadAcquire(fState) == 0;};
|
||||
// Note: isReset() is used by service registration code.
|
||||
// Thread safety of this usage needs review.
|
||||
#endif
|
||||
};
|
||||
typedef struct UInitOnce UInitOnce;
|
||||
#define U_INITONCE_INITIALIZER {ATOMIC_INT32_T_INITIALIZER(0), U_ZERO_ERROR}
|
||||
|
||||
#ifdef __cplusplus
|
||||
// TODO: get all ICU files using umutex converted to C++,
|
||||
// then remove the __cpluplus conditionals from this file.
|
||||
|
||||
U_CAPI UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
|
||||
U_CAPI void U_EXPORT2 umtx_initImplPostInit(UInitOnce &, UBool success);
|
||||
|
||||
template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (T::*fp)()) {
|
||||
if (umtx_loadAcquire(uio.fState) == 2) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* TODO: Replace all uses of UMTX_CHECK and surrounding code
|
||||
* with SimpleSingleton or TriStateSingleton, and remove UMTX_CHECK.
|
||||
*/
|
||||
if (umtx_initImplPreInit(uio)) {
|
||||
(obj->*fp)();
|
||||
umtx_initImplPostInit(uio, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Code within ICU that accesses shared static or global data should
|
||||
* instantiate a Mutex object while doing so. The unnamed global mutex
|
||||
* is used throughout ICU, so keep locking short and sweet.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* void Function(int arg1, int arg2)
|
||||
* {
|
||||
* static Object* foo; // Shared read-write object
|
||||
* umtx_lock(NULL); // Lock the ICU global mutex
|
||||
* foo->Method();
|
||||
* umtx_unlock(NULL);
|
||||
* }
|
||||
*
|
||||
* an alternative C++ mutex API is defined in the file common/mutex.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* UMutex - Mutexes for use by ICU implementation code.
|
||||
* Must be declared as static or globals. They cannot appear as members
|
||||
* of other objects.
|
||||
* UMutex structs must be initialized.
|
||||
* Example:
|
||||
* static UMutex = U_MUTEX_INITIALIZER;
|
||||
* The declaration of struct UMutex is platform dependent.
|
||||
*/
|
||||
// umtx_initOnce variant for plain functions, or static class functions.
|
||||
// No context parameter.
|
||||
inline void umtx_initOnce(UInitOnce &uio, void (*fp)()) {
|
||||
if (umtx_loadAcquire(uio.fState) == 2) {
|
||||
return;
|
||||
}
|
||||
if (umtx_initImplPreInit(uio)) {
|
||||
(*fp)();
|
||||
umtx_initImplPostInit(uio, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// umtx_initOnce variant for plain functions, or static class functions.
|
||||
// With ErrorCode, No context parameter.
|
||||
inline void umtx_initOnce(UInitOnce &uio, void (*fp)(UErrorCode &), UErrorCode &errCode) {
|
||||
if (U_FAILURE(errCode)) {
|
||||
return;
|
||||
}
|
||||
if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
|
||||
// We run the initialization.
|
||||
(*fp)(errCode);
|
||||
uio.fErrCode = errCode;
|
||||
umtx_initImplPostInit(uio, TRUE);
|
||||
} else {
|
||||
// Someone else already ran the initialization.
|
||||
if (U_FAILURE(uio.fErrCode)) {
|
||||
errCode = uio.fErrCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// umtx_initOnce variant for plain functions, or static class functions,
|
||||
// with a context parameter.
|
||||
template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T), T context) {
|
||||
if (umtx_loadAcquire(uio.fState) == 2) {
|
||||
return;
|
||||
}
|
||||
if (umtx_initImplPreInit(uio)) {
|
||||
(*fp)(context);
|
||||
umtx_initImplPostInit(uio, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// umtx_initOnce variant for plain functions, or static class functions,
|
||||
// with a context parameter and an error code.
|
||||
template<class T> void umtx_initOnce(UInitOnce &uio, void (*fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
|
||||
if (U_FAILURE(errCode)) {
|
||||
return;
|
||||
}
|
||||
if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
|
||||
// We run the initialization.
|
||||
(*fp)(context, errCode);
|
||||
uio.fErrCode = errCode;
|
||||
umtx_initImplPostInit(uio, TRUE);
|
||||
} else {
|
||||
// Someone else already ran the initialization.
|
||||
if (U_FAILURE(uio.fErrCode)) {
|
||||
errCode = uio.fErrCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
|
||||
/*************************************************************************************************
|
||||
*
|
||||
* Mutex Definitions. Platform Dependent, #if platform chain follows.
|
||||
* TODO: Add a C++11 version.
|
||||
* Need to convert all mutex using files to C++ first.
|
||||
*
|
||||
*************************************************************************************************/
|
||||
|
||||
#if U_PLATFORM_HAS_WIN32_API
|
||||
|
||||
/* U_INIT_ONCE mimics the windows API INIT_ONCE, which exists on Windows Vista and newer.
|
||||
* When ICU no longer needs to support older Windows platforms (XP) that do not have
|
||||
* a native INIT_ONCE, switch this implementation over to wrap the native Windows APIs.
|
||||
/* Windows Definitions.
|
||||
* Windows comes first in the platform chain.
|
||||
* Cygwin (and possibly others) have both WIN32 and POSIX APIs. Prefer Win32 in this case.
|
||||
*/
|
||||
typedef struct U_INIT_ONCE {
|
||||
long fState;
|
||||
void *fContext;
|
||||
} U_INIT_ONCE;
|
||||
#define U_INIT_ONCE_STATIC_INIT {0, NULL}
|
||||
|
||||
|
||||
/* For CRITICAL_SECTION */
|
||||
|
||||
/*
|
||||
* Note: there is an earlier include of windows.h in this file, but it is in
|
||||
* different conditionals.
|
||||
* This one is needed if we are using C++11 for atomic ops, but
|
||||
* win32 APIs for Critical Sections.
|
||||
*/
|
||||
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# define VC_EXTRALEAN
|
||||
# define NOUSER
|
||||
# define NOSERVICE
|
||||
# define NOIME
|
||||
# define NOMCX
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <windows.h>
|
||||
|
||||
|
||||
typedef struct UMutex {
|
||||
U_INIT_ONCE fInitOnce;
|
||||
UMTX fUserMutex;
|
||||
UBool fInitialized; /* Applies to fUserMutex only. */
|
||||
/* CRITICAL_SECTION fCS; */ /* See note above. Unresolved problems with including
|
||||
* Windows.h, which would allow using CRITICAL_SECTION
|
||||
* directly here. */
|
||||
char fCS[U_WINDOWS_CRIT_SEC_SIZE];
|
||||
UInitOnce fInitOnce;
|
||||
CRITICAL_SECTION fCS;
|
||||
} UMutex;
|
||||
|
||||
/* Initializer for a static UMUTEX. Deliberately contains no value for the
|
||||
* CRITICAL_SECTION.
|
||||
*/
|
||||
#define U_MUTEX_INITIALIZER {U_INIT_ONCE_STATIC_INIT, NULL, FALSE}
|
||||
#define U_MUTEX_INITIALIZER {U_INITONCE_INITIALIZER}
|
||||
|
||||
|
||||
|
||||
#elif U_PLATFORM_IMPLEMENTS_POSIX
|
||||
|
||||
/*
|
||||
* POSIX platform
|
||||
*/
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
struct UMutex {
|
||||
pthread_mutex_t fMutex;
|
||||
UMTX fUserMutex;
|
||||
UBool fInitialized;
|
||||
};
|
||||
#define U_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL, FALSE}
|
||||
typedef struct UMutex UMutex;
|
||||
#define U_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}
|
||||
|
||||
|
||||
#else
|
||||
/* Unknow platform type. */
|
||||
struct UMutex {
|
||||
void *fMutex;
|
||||
};
|
||||
#define U_MUTEX_INITIALIZER {NULL}
|
||||
|
||||
/*
|
||||
* Unknow platform type.
|
||||
* This is an error condition. ICU requires mutexes.
|
||||
*/
|
||||
|
||||
#error Unknown Platform.
|
||||
|
||||
#endif
|
||||
|
||||
#if (U_PLATFORM != U_PF_CYGWIN && U_PLATFORM != U_PF_MINGW) || defined(CYGWINMSVC)
|
||||
typedef struct UMutex UMutex;
|
||||
#endif
|
||||
|
||||
|
||||
/**************************************************************************************
|
||||
*
|
||||
* Mutex Implementation function declaratations.
|
||||
* Declarations are platform neutral.
|
||||
* Implementations, in umutex.cpp, are platform specific.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
/* Lock a mutex.
|
||||
* @param mutex The given mutex to be locked. Pass NULL to specify
|
||||
* the global ICU mutex. Recursive locks are an error
|
||||
* and may cause a deadlock on some platforms.
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 umtx_lock(UMutex* mutex);
|
||||
U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex);
|
||||
|
||||
/* Unlock a mutex.
|
||||
* @param mutex The given mutex to be unlocked. Pass NULL to specify
|
||||
* the global ICU mutex.
|
||||
*/
|
||||
U_CAPI void U_EXPORT2 umtx_unlock (UMutex* mutex);
|
||||
U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
|
||||
|
||||
/*
|
||||
* Atomic Increment and Decrement of an int32_t value.
|
||||
*
|
||||
* Return Values:
|
||||
* If the result of the operation is zero, the return zero.
|
||||
* If the result of the operation is not zero, the sign of returned value
|
||||
* is the same as the sign of the result, but the returned value itself may
|
||||
* be different from the result of the operation.
|
||||
*/
|
||||
U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *);
|
||||
U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *);
|
||||
|
||||
#endif /*_CMUTEX*/
|
||||
#endif /* UMUTEX_H */
|
||||
/*eof*/
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2011, International Business Machines
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -20,6 +20,7 @@
|
|||
#include "unicode/udata.h"
|
||||
#include "unicode/utf.h"
|
||||
#include "unicode/utf16.h"
|
||||
#include "uassert.h"
|
||||
#include "ustr_imp.h"
|
||||
#include "umutex.h"
|
||||
#include "cmemory.h"
|
||||
|
@ -102,7 +103,7 @@ typedef struct {
|
|||
|
||||
static UDataMemory *uCharNamesData=NULL;
|
||||
static UCharNames *uCharNames=NULL;
|
||||
static UErrorCode gLoadErrorCode=U_ZERO_ERROR;
|
||||
static UInitOnce gCharNamesInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
/*
|
||||
* Maximum length of character names (regular & 1.0).
|
||||
|
@ -168,6 +169,7 @@ static UBool U_CALLCONV unames_cleanup(void)
|
|||
if(uCharNames) {
|
||||
uCharNames = NULL;
|
||||
}
|
||||
gCharNamesInitOnce.reset();
|
||||
gMaxNameLength=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -187,52 +189,25 @@ isAcceptable(void * /*context*/,
|
|||
pInfo->formatVersion[0]==1);
|
||||
}
|
||||
|
||||
static void U_CALLCONV
|
||||
loadCharNames(UErrorCode &status) {
|
||||
U_ASSERT(uCharNamesData == NULL);
|
||||
U_ASSERT(uCharNames == NULL);
|
||||
|
||||
uCharNamesData = udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, &status);
|
||||
if(U_FAILURE(status)) {
|
||||
uCharNamesData = NULL;
|
||||
} else {
|
||||
uCharNames = (UCharNames *)udata_getMemory(uCharNamesData);
|
||||
}
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup);
|
||||
}
|
||||
|
||||
|
||||
static UBool
|
||||
isDataLoaded(UErrorCode *pErrorCode) {
|
||||
/* load UCharNames from file if necessary */
|
||||
UBool isCached;
|
||||
|
||||
/* do this because double-checked locking is broken */
|
||||
UMTX_CHECK(NULL, (uCharNames!=NULL), isCached);
|
||||
|
||||
if(!isCached) {
|
||||
UCharNames *names;
|
||||
UDataMemory *data;
|
||||
|
||||
/* check error code from previous attempt */
|
||||
if(U_FAILURE(gLoadErrorCode)) {
|
||||
*pErrorCode=gLoadErrorCode;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* open the data outside the mutex block */
|
||||
data=udata_openChoice(NULL, DATA_TYPE, DATA_NAME, isAcceptable, NULL, pErrorCode);
|
||||
if(U_FAILURE(*pErrorCode)) {
|
||||
gLoadErrorCode=*pErrorCode;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
names=(UCharNames *)udata_getMemory(data);
|
||||
|
||||
/* in the mutex block, set the data for this process */
|
||||
{
|
||||
umtx_lock(NULL);
|
||||
if(uCharNames==NULL) {
|
||||
uCharNamesData=data;
|
||||
uCharNames=names;
|
||||
data=NULL;
|
||||
names=NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_UNAMES, unames_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
|
||||
/* if a different thread set it first, then close the extra data */
|
||||
if(data!=NULL) {
|
||||
udata_close(data); /* NULL if it was set correctly */
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
umtx_initOnce(gCharNamesInitOnce, &loadCharNames, *pErrorCode);
|
||||
return U_SUCCESS(*pErrorCode);
|
||||
}
|
||||
|
||||
#define WRITE_CHAR(buffer, bufferLength, bufferPos, c) { \
|
||||
|
|
|
@ -43,6 +43,9 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Forward Declarations
|
||||
void U_CALLCONV locale_available_init();
|
||||
|
||||
/**
|
||||
* A <code>Locale</code> object represents a specific geographical, political,
|
||||
* or cultural region. An operation that requires a <code>Locale</code> to perform
|
||||
|
@ -738,6 +741,8 @@ private:
|
|||
* @internal
|
||||
*/
|
||||
friend Locale *locale_set_default_internal(const char *, UErrorCode& status);
|
||||
|
||||
friend void locale_available_init();
|
||||
};
|
||||
|
||||
inline UBool
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1996-2011, International Business Machines Corporation
|
||||
* Copyright (C) 1996-2013, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -484,7 +484,6 @@ private:
|
|||
UResourceBundle *fResource;
|
||||
void constructForLocale(const UnicodeString& path, const Locale& locale, UErrorCode& error);
|
||||
Locale *fLocale;
|
||||
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2009-2012, International Business Machines
|
||||
// Copyright (C) 2009-2013, International Business Machines
|
||||
// Corporation and others. All Rights Reserved.
|
||||
//
|
||||
// Copyright 2001 and onwards Google Inc.
|
||||
|
@ -183,7 +183,7 @@ class U_COMMON_API StringPiece : public UMemory {
|
|||
* Maximum integer, used as a default value for substring methods.
|
||||
* @stable ICU 4.2
|
||||
*/
|
||||
static const int32_t npos = 0x7fffffff;
|
||||
static const int32_t npos; // = 0x7fffffff;
|
||||
|
||||
/**
|
||||
* Returns a substring of this StringPiece.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 2001-2012, International Business Machines
|
||||
* Copyright (C) 2001-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
* file name: uclean.h
|
||||
|
@ -100,101 +100,6 @@ U_STABLE void U_EXPORT2
|
|||
u_cleanup(void);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An opaque pointer type that represents an ICU mutex.
|
||||
* For user-implemented mutexes, the value will typically point to a
|
||||
* struct or object that implements the mutex.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
typedef void *UMTX;
|
||||
|
||||
/**
|
||||
* Function Pointer type for a user supplied mutex initialization function.
|
||||
* The user-supplied function will be called by ICU whenever ICU needs to create a
|
||||
* new mutex. The function implementation should create a mutex, and store a pointer
|
||||
* to something that uniquely identifies the mutex into the UMTX that is supplied
|
||||
* as a paramter.
|
||||
* @param context user supplied value, obtained from from u_setMutexFunctions().
|
||||
* @param mutex Receives a pointer that identifies the new mutex.
|
||||
* The mutex init function must set the UMTX to a non-null value.
|
||||
* Subsequent calls by ICU to lock, unlock, or destroy a mutex will
|
||||
* identify the mutex by the UMTX value.
|
||||
* @param status Error status. Report errors back to ICU by setting this variable
|
||||
* with an error code.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCode* status);
|
||||
|
||||
|
||||
/**
|
||||
* Function Pointer type for a user supplied mutex functions.
|
||||
* One of the user-supplied functions with this signature will be called by ICU
|
||||
* whenever ICU needs to lock, unlock, or destroy a mutex.
|
||||
* @param context user supplied value, obtained from from u_setMutexFunctions().
|
||||
* @param mutex specify the mutex on which to operate.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex);
|
||||
|
||||
|
||||
/**
|
||||
* Set the functions that ICU will use for mutex operations
|
||||
* Use of this function is optional; by default (without this function), ICU will
|
||||
* directly access system functions for mutex operations
|
||||
* This function can only be used when ICU is in an initial, unused state, before
|
||||
* u_init() has been called.
|
||||
* @param context This pointer value will be saved, and then (later) passed as
|
||||
* a parameter to the user-supplied mutex functions each time they
|
||||
* are called.
|
||||
* @param init Pointer to a mutex initialization function. Must be non-null.
|
||||
* @param destroy Pointer to the mutex destroy function. Must be non-null.
|
||||
* @param lock pointer to the mutex lock function. Must be non-null.
|
||||
* @param unlock Pointer to the mutex unlock function. Must be non-null.
|
||||
* @param status Receives error values.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
U_STABLE void U_EXPORT2
|
||||
u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
/**
|
||||
* Pointer type for a user supplied atomic increment or decrement function.
|
||||
* @param context user supplied value, obtained from from u_setAtomicIncDecFunctions().
|
||||
* @param p Pointer to a 32 bit int to be incremented or decremented
|
||||
* @return The value of the variable after the inc or dec operation.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
|
||||
|
||||
/**
|
||||
* Set the functions that ICU will use for atomic increment and decrement of int32_t values.
|
||||
* Use of this function is optional; by default (without this function), ICU will
|
||||
* use its own internal implementation of atomic increment/decrement.
|
||||
* This function can only be used when ICU is in an initial, unused state, before
|
||||
* u_init() has been called.
|
||||
* @param context This pointer value will be saved, and then (later) passed as
|
||||
* a parameter to the increment and decrement functions each time they
|
||||
* are called. This function can only be called
|
||||
* @param inc Pointer to a function to do an atomic increment operation. Must be non-null.
|
||||
* @param dec Pointer to a function to do an atomic decrement operation. Must be non-null.
|
||||
* @param status Receives error values.
|
||||
* @stable ICU 2.8
|
||||
* @system
|
||||
*/
|
||||
U_STABLE void U_EXPORT2
|
||||
u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Pointer type for a user supplied memory allocation function.
|
||||
* @param context user supplied value, obtained from from u_setMemoryFunctions().
|
||||
|
@ -244,6 +149,108 @@ typedef void U_CALLCONV UMemFreeFn (const void *context, void *mem);
|
|||
U_STABLE void U_EXPORT2
|
||||
u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
/*********************************************************************************
|
||||
*
|
||||
* Deprecated Functions
|
||||
*
|
||||
* The following functions for user supplied mutexes are no longer supported.
|
||||
* Any attempt to use them will return a U_UNSUPPORTED_ERROR.
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
/**
|
||||
* An opaque pointer type that represents an ICU mutex.
|
||||
* For user-implemented mutexes, the value will typically point to a
|
||||
* struct or object that implements the mutex.
|
||||
* @deprecated ICU 52. This type is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
typedef void *UMTX;
|
||||
|
||||
/**
|
||||
* Function Pointer type for a user supplied mutex initialization function.
|
||||
* The user-supplied function will be called by ICU whenever ICU needs to create a
|
||||
* new mutex. The function implementation should create a mutex, and store a pointer
|
||||
* to something that uniquely identifies the mutex into the UMTX that is supplied
|
||||
* as a paramter.
|
||||
* @param context user supplied value, obtained from from u_setMutexFunctions().
|
||||
* @param mutex Receives a pointer that identifies the new mutex.
|
||||
* The mutex init function must set the UMTX to a non-null value.
|
||||
* Subsequent calls by ICU to lock, unlock, or destroy a mutex will
|
||||
* identify the mutex by the UMTX value.
|
||||
* @param status Error status. Report errors back to ICU by setting this variable
|
||||
* with an error code.
|
||||
* @deprecated ICU 52. This function is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
typedef void U_CALLCONV UMtxInitFn (const void *context, UMTX *mutex, UErrorCode* status);
|
||||
|
||||
|
||||
/**
|
||||
* Function Pointer type for a user supplied mutex functions.
|
||||
* One of the user-supplied functions with this signature will be called by ICU
|
||||
* whenever ICU needs to lock, unlock, or destroy a mutex.
|
||||
* @param context user supplied value, obtained from from u_setMutexFunctions().
|
||||
* @param mutex specify the mutex on which to operate.
|
||||
* @deprecated ICU 52. This function is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
typedef void U_CALLCONV UMtxFn (const void *context, UMTX *mutex);
|
||||
|
||||
|
||||
/**
|
||||
* Set the functions that ICU will use for mutex operations
|
||||
* Use of this function is optional; by default (without this function), ICU will
|
||||
* directly access system functions for mutex operations
|
||||
* This function can only be used when ICU is in an initial, unused state, before
|
||||
* u_init() has been called.
|
||||
* @param context This pointer value will be saved, and then (later) passed as
|
||||
* a parameter to the user-supplied mutex functions each time they
|
||||
* are called.
|
||||
* @param init Pointer to a mutex initialization function. Must be non-null.
|
||||
* @param destroy Pointer to the mutex destroy function. Must be non-null.
|
||||
* @param lock pointer to the mutex lock function. Must be non-null.
|
||||
* @param unlock Pointer to the mutex unlock function. Must be non-null.
|
||||
* @param status Receives error values.
|
||||
* @deprecated ICU 52. This function is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
U_DEPRECATED void U_EXPORT2
|
||||
u_setMutexFunctions(const void *context, UMtxInitFn *init, UMtxFn *destroy, UMtxFn *lock, UMtxFn *unlock,
|
||||
UErrorCode *status);
|
||||
|
||||
|
||||
/**
|
||||
* Pointer type for a user supplied atomic increment or decrement function.
|
||||
* @param context user supplied value, obtained from from u_setAtomicIncDecFunctions().
|
||||
* @param p Pointer to a 32 bit int to be incremented or decremented
|
||||
* @return The value of the variable after the inc or dec operation.
|
||||
* @deprecated ICU 52. This function is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
typedef int32_t U_CALLCONV UMtxAtomicFn(const void *context, int32_t *p);
|
||||
|
||||
/**
|
||||
* Set the functions that ICU will use for atomic increment and decrement of int32_t values.
|
||||
* Use of this function is optional; by default (without this function), ICU will
|
||||
* use its own internal implementation of atomic increment/decrement.
|
||||
* This function can only be used when ICU is in an initial, unused state, before
|
||||
* u_init() has been called.
|
||||
* @param context This pointer value will be saved, and then (later) passed as
|
||||
* a parameter to the increment and decrement functions each time they
|
||||
* are called. This function can only be called
|
||||
* @param inc Pointer to a function to do an atomic increment operation. Must be non-null.
|
||||
* @param dec Pointer to a function to do an atomic decrement operation. Must be non-null.
|
||||
* @param status Receives error values.
|
||||
* @deprecated ICU 52. This function is no longer supported.
|
||||
* @system
|
||||
*/
|
||||
U_DEPRECATED void U_EXPORT2
|
||||
u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *inc, UMtxAtomicFn *dec,
|
||||
UErrorCode *status);
|
||||
|
||||
#endif /* U_HIDE_SYSTEM_API */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
***************************************************************************
|
||||
* Copyright (C) 1999-2011, International Business Machines Corporation
|
||||
* Copyright (C) 1999-2013, International Business Machines Corporation
|
||||
* and others. All Rights Reserved.
|
||||
***************************************************************************
|
||||
* Date Name Description
|
||||
|
@ -22,6 +22,9 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Forward Declarations.
|
||||
void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
|
||||
|
||||
class BMPSet;
|
||||
class ParsePosition;
|
||||
class RBBIRuleScanner;
|
||||
|
@ -1586,6 +1589,7 @@ private:
|
|||
UnicodeString& rebuiltPat,
|
||||
UErrorCode& ec);
|
||||
|
||||
friend void UnicodeSet_initInclusion(int32_t src, UErrorCode &status);
|
||||
static const UnicodeSet* getInclusions(int32_t src, UErrorCode &status);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1999-2012, International Business Machines
|
||||
* Copyright (C) 1999-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -127,7 +127,11 @@ private:
|
|||
|
||||
U_CDECL_BEGIN
|
||||
|
||||
static UnicodeSet *INCLUSIONS[UPROPS_SRC_COUNT] = { NULL }; // cached getInclusions()
|
||||
struct Inclusion {
|
||||
UnicodeSet *fSet;
|
||||
UInitOnce fInitOnce;
|
||||
};
|
||||
static Inclusion gInclusions[UPROPS_SRC_COUNT]; // cached getInclusions()
|
||||
|
||||
STATIC_SIMPLE_SINGLETON(uni32Singleton);
|
||||
|
||||
|
@ -156,14 +160,13 @@ _set_addString(USet *set, const UChar *str, int32_t length) {
|
|||
* Cleanup function for UnicodeSet
|
||||
*/
|
||||
static UBool U_CALLCONV uset_cleanup(void) {
|
||||
int32_t i;
|
||||
|
||||
for(i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
|
||||
if (INCLUSIONS[i] != NULL) {
|
||||
delete INCLUSIONS[i];
|
||||
INCLUSIONS[i] = NULL;
|
||||
}
|
||||
for(int32_t i = UPROPS_SRC_NONE; i < UPROPS_SRC_COUNT; ++i) {
|
||||
Inclusion &in = gInclusions[i];
|
||||
delete in.fSet;
|
||||
in.fSet = NULL;
|
||||
in.fInitOnce.reset();
|
||||
}
|
||||
|
||||
UnicodeSetSingleton(uni32Singleton, NULL).deleteInstance();
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -173,105 +176,114 @@ U_CDECL_END
|
|||
U_NAMESPACE_BEGIN
|
||||
|
||||
/*
|
||||
Reduce excessive reallocation, and make it easier to detect initialization
|
||||
problems.
|
||||
Reduce excessive reallocation, and make it easier to detect initialization problems.
|
||||
Usually you don't see smaller sets than this for Unicode 5.0.
|
||||
*/
|
||||
#define DEFAULT_INCLUSION_CAPACITY 3072
|
||||
|
||||
const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
UBool needInit;
|
||||
UMTX_CHECK(NULL, (INCLUSIONS[src] == NULL), needInit);
|
||||
if (needInit) {
|
||||
UnicodeSet* incl = new UnicodeSet();
|
||||
USetAdder sa = {
|
||||
(USet *)incl,
|
||||
_set_add,
|
||||
_set_addRange,
|
||||
_set_addString,
|
||||
NULL, // don't need remove()
|
||||
NULL // don't need removeRange()
|
||||
};
|
||||
if (incl != NULL) {
|
||||
incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
|
||||
switch(src) {
|
||||
case UPROPS_SRC_CHAR:
|
||||
uchar_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_PROPSVEC:
|
||||
upropsvec_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_CHAR_AND_PROPSVEC:
|
||||
uchar_addPropertyStarts(&sa, &status);
|
||||
upropsvec_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
#if !UCONFIG_NO_NORMALIZATION
|
||||
case UPROPS_SRC_CASE_AND_NORM: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFC: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFKC: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFKC_CF: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFC_CANON_ITER: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addCanonIterPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case UPROPS_SRC_CASE:
|
||||
ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_BIDI:
|
||||
ubidi_addPropertyStarts(ubidi_getSingleton(), &sa, &status);
|
||||
break;
|
||||
default:
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
break;
|
||||
}
|
||||
if (U_SUCCESS(status)) {
|
||||
// Compact for caching
|
||||
incl->compact();
|
||||
umtx_lock(NULL);
|
||||
if (INCLUSIONS[src] == NULL) {
|
||||
INCLUSIONS[src] = incl;
|
||||
incl = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
|
||||
}
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
delete incl;
|
||||
} else {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
void U_CALLCONV UnicodeSet_initInclusion(int32_t src, UErrorCode &status) {
|
||||
// This function is invoked only via umtx_initOnce().
|
||||
// This function is a friend of class UnicodeSet.
|
||||
|
||||
U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
|
||||
UnicodeSet * &incl = gInclusions[src].fSet;
|
||||
U_ASSERT(incl == NULL);
|
||||
|
||||
incl = new UnicodeSet();
|
||||
if (incl == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
return INCLUSIONS[src];
|
||||
USetAdder sa = {
|
||||
(USet *)incl,
|
||||
_set_add,
|
||||
_set_addRange,
|
||||
_set_addString,
|
||||
NULL, // don't need remove()
|
||||
NULL // don't need removeRange()
|
||||
};
|
||||
|
||||
incl->ensureCapacity(DEFAULT_INCLUSION_CAPACITY, status);
|
||||
switch(src) {
|
||||
case UPROPS_SRC_CHAR:
|
||||
uchar_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_PROPSVEC:
|
||||
upropsvec_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_CHAR_AND_PROPSVEC:
|
||||
uchar_addPropertyStarts(&sa, &status);
|
||||
upropsvec_addPropertyStarts(&sa, &status);
|
||||
break;
|
||||
#if !UCONFIG_NO_NORMALIZATION
|
||||
case UPROPS_SRC_CASE_AND_NORM: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFC: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFKC: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFKCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFKC_CF: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFKC_CFImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UPROPS_SRC_NFC_CANON_ITER: {
|
||||
const Normalizer2Impl *impl=Normalizer2Factory::getNFCImpl(status);
|
||||
if(U_SUCCESS(status)) {
|
||||
impl->addCanonIterPropertyStarts(&sa, status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case UPROPS_SRC_CASE:
|
||||
ucase_addPropertyStarts(ucase_getSingleton(), &sa, &status);
|
||||
break;
|
||||
case UPROPS_SRC_BIDI:
|
||||
ubidi_addPropertyStarts(ubidi_getSingleton(), &sa, &status);
|
||||
break;
|
||||
default:
|
||||
status = U_INTERNAL_PROGRAM_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
delete incl;
|
||||
incl = NULL;
|
||||
return;
|
||||
}
|
||||
// Compact for caching
|
||||
incl->compact();
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USET, uset_cleanup);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const UnicodeSet* UnicodeSet::getInclusions(int32_t src, UErrorCode &status) {
|
||||
U_ASSERT(src >=0 && src<UPROPS_SRC_COUNT);
|
||||
Inclusion &i = gInclusions[src];
|
||||
umtx_initOnce(i.fInitOnce, &UnicodeSet_initInclusion, src, status);
|
||||
return i.fSet;
|
||||
}
|
||||
|
||||
|
||||
// Cache some sets for other services -------------------------------------- ***
|
||||
|
||||
U_CFUNC UnicodeSet *
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
* Copyright (C) 1999-2012, International Business Machines Corporation and
|
||||
* Copyright (C) 1999-2013, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
******************************************************************************
|
||||
*
|
||||
|
@ -118,11 +118,11 @@ operator+ (const UnicodeString &s1, const UnicodeString &s2) {
|
|||
|
||||
void
|
||||
UnicodeString::addRef()
|
||||
{ umtx_atomic_inc((int32_t *)fUnion.fFields.fArray - 1);}
|
||||
{ umtx_atomic_inc((atomic_int32_t *)fUnion.fFields.fArray - 1);}
|
||||
|
||||
int32_t
|
||||
UnicodeString::removeRef()
|
||||
{ return umtx_atomic_dec((int32_t *)fUnion.fFields.fArray - 1);}
|
||||
{ return umtx_atomic_dec((atomic_int32_t *)fUnion.fFields.fArray - 1);}
|
||||
|
||||
int32_t
|
||||
UnicodeString::refCount() const
|
||||
|
@ -1679,13 +1679,16 @@ UnicodeString::cloneArrayIfNeeded(int32_t newCapacity,
|
|||
// release the old array
|
||||
if(flags & kRefCounted) {
|
||||
// the array is refCounted; decrement and release if 0
|
||||
int32_t *pRefCount = ((int32_t *)oldArray - 1);
|
||||
atomic_int32_t *pRefCount = ((atomic_int32_t *)oldArray - 1);
|
||||
if(umtx_atomic_dec(pRefCount) == 0) {
|
||||
if(pBufferToDelete == 0) {
|
||||
uprv_free(pRefCount);
|
||||
// Note: cast to (void *) is needed with MSVC, where atomic_int32_t
|
||||
// is defined as volatile. (Volatile has useful non-standard behavior
|
||||
// with this compiler.)
|
||||
uprv_free((void *)pRefCount);
|
||||
} else {
|
||||
// the caller requested to delete it himself
|
||||
*pBufferToDelete = pRefCount;
|
||||
*pBufferToDelete = (int32_t *)pRefCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "ulocimp.h"
|
||||
#include "umutex.h"
|
||||
#include "putilimp.h"
|
||||
#include "uassert.h"
|
||||
|
||||
|
||||
/*
|
||||
|
@ -42,6 +43,7 @@ TODO: This cache should probably be removed when the deprecated code is
|
|||
completely removed.
|
||||
*/
|
||||
static UHashtable *cache = NULL;
|
||||
static UInitOnce gCacheInitOnce;
|
||||
|
||||
static UMutex resbMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -261,29 +263,19 @@ static UBool U_CALLCONV ures_cleanup(void)
|
|||
cache = NULL;
|
||||
}
|
||||
}
|
||||
gCacheInitOnce.reset();
|
||||
return (cache == NULL);
|
||||
}
|
||||
|
||||
/** INTERNAL: Initializes the cache for resources */
|
||||
static void createCache(UErrorCode &status) {
|
||||
U_ASSERT(cache == NULL);
|
||||
cache = uhash_open(hashEntry, compareEntries, NULL, &status);
|
||||
ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
|
||||
}
|
||||
|
||||
static void initCache(UErrorCode *status) {
|
||||
UBool makeCache = FALSE;
|
||||
UMTX_CHECK(&resbMutex, (cache == NULL), makeCache);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_FAILURE(*status)) {
|
||||
return;
|
||||
}
|
||||
umtx_lock(&resbMutex);
|
||||
if(cache == NULL) {
|
||||
cache = newCache;
|
||||
newCache = NULL;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_URES, ures_cleanup);
|
||||
}
|
||||
umtx_unlock(&resbMutex);
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
umtx_initOnce(gCacheInitOnce, &createCache, *status);
|
||||
}
|
||||
|
||||
/** INTERNAL: sets the name (locale) of the resource bundle to given name */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012, International Business Machines
|
||||
* Copyright (C) 2003-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -42,6 +42,7 @@ U_CDECL_BEGIN
|
|||
Static cache for already opened StringPrep profiles
|
||||
*/
|
||||
static UHashtable *SHARED_DATA_HASHTABLE = NULL;
|
||||
static UInitOnce gSharedDataInitOnce;
|
||||
|
||||
static UMutex usprepMutex = U_MUTEX_INITIALIZER;
|
||||
|
||||
|
@ -195,32 +196,25 @@ static UBool U_CALLCONV usprep_cleanup(void){
|
|||
SHARED_DATA_HASHTABLE = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
gSharedDataInitOnce.reset();
|
||||
return (SHARED_DATA_HASHTABLE == NULL);
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
/** Initializes the cache for resources */
|
||||
static void U_CALLCONV
|
||||
createCache(UErrorCode &status) {
|
||||
SHARED_DATA_HASHTABLE = uhash_open(hashEntry, compareEntries, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
SHARED_DATA_HASHTABLE = NULL;
|
||||
}
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
|
||||
}
|
||||
|
||||
static void
|
||||
initCache(UErrorCode *status) {
|
||||
UBool makeCache;
|
||||
UMTX_CHECK(&usprepMutex, (SHARED_DATA_HASHTABLE == NULL), makeCache);
|
||||
if(makeCache) {
|
||||
UHashtable *newCache = uhash_open(hashEntry, compareEntries, NULL, status);
|
||||
if (U_SUCCESS(*status)) {
|
||||
umtx_lock(&usprepMutex);
|
||||
if(SHARED_DATA_HASHTABLE == NULL) {
|
||||
SHARED_DATA_HASHTABLE = newCache;
|
||||
ucln_common_registerCleanup(UCLN_COMMON_USPREP, usprep_cleanup);
|
||||
newCache = NULL;
|
||||
}
|
||||
umtx_unlock(&usprepMutex);
|
||||
}
|
||||
if(newCache != NULL) {
|
||||
uhash_close(newCache);
|
||||
}
|
||||
}
|
||||
umtx_initOnce(gSharedDataInitOnce, &createCache, *status);
|
||||
}
|
||||
|
||||
static UBool U_CALLCONV
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2001-2011, International Business Machines
|
||||
* Copyright (C) 2001-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
******************************************************************************
|
||||
|
@ -735,9 +735,7 @@ uint16_t ForwardUTrie2StringIterator::next16() {
|
|||
|
||||
UTrie2 *UTrie2Singleton::getInstance(InstantiatorFn *instantiator, const void *context,
|
||||
UErrorCode &errorCode) {
|
||||
void *duplicate;
|
||||
UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, duplicate, errorCode);
|
||||
utrie2_close((UTrie2 *)duplicate);
|
||||
UTrie2 *instance=(UTrie2 *)singleton.getInstance(instantiator, context, errorCode);
|
||||
return instance;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## -*-makefile-*-
|
||||
## Linux-specific setup
|
||||
## Copyright (c) 1999-2012, International Business Machines Corporation and
|
||||
## Copyright (c) 1999-2013, International Business Machines Corporation and
|
||||
## others. All Rights Reserved.
|
||||
|
||||
## Commands to generate dependency files
|
||||
GEN_DEPS.c= $(CC) -E -MM $(DEFS) $(CPPFLAGS)
|
||||
GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS)
|
||||
GEN_DEPS.cc= $(CXX) -E -MM $(DEFS) $(CPPFLAGS) $(CXXFLAGS)
|
||||
|
||||
## Flags for position independent code
|
||||
SHAREDLIBCFLAGS = -fPIC
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/icuio.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -133,7 +133,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/icuio.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -176,7 +176,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/icuio.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -216,7 +216,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/icuio.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Copyright (C) 1998-2012, International Business Machines
|
||||
* Copyright (C) 1998-2013, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
*
|
||||
*******************************************************************************
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
#include "ucln_io.h"
|
||||
#include "mutex.h"
|
||||
#include "umutex.h"
|
||||
#include "unicode/ustring.h"
|
||||
#include "unicode/uloc.h"
|
||||
|
@ -42,27 +43,24 @@ static UBool U_CALLCONV locbund_cleanup(void) {
|
|||
}
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
static UMutex gLock = U_MUTEX_INITIALIZER;
|
||||
static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
|
||||
U_NAMESPACE_USE
|
||||
Mutex lock(&gLock);
|
||||
if (result->fNumberFormat[style-1] == NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UBool needsInit;
|
||||
|
||||
UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit);
|
||||
if (needsInit) {
|
||||
if (gPosixNumberFormat[style-1] == NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);
|
||||
|
||||
/* Cache upon first request. */
|
||||
if (U_SUCCESS(status)) {
|
||||
umtx_lock(NULL);
|
||||
gPosixNumberFormat[style-1] = formatAlias;
|
||||
ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
|
||||
umtx_unlock(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy the needed formatter. */
|
||||
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
|
||||
if (gPosixNumberFormat[style-1] != NULL) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
|
||||
}
|
||||
}
|
||||
return result->fNumberFormat[style-1];
|
||||
}
|
||||
|
|
|
@ -1,260 +1,264 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x86\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x86\Release/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
<TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x64\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x64\Release/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x86\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x86\Debug/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
<TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x64\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x64\Debug/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cal.c" />
|
||||
<ClCompile Include="uprint.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="uprint.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\common.vcxproj">
|
||||
<Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\i18n\i18n.vcxproj">
|
||||
<Project>{0178b127-6269-407d-b112-93877bb62776}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{F7659D77-09CF-4FE9-ACEE-927287AA9509}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\x86\Release\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\x64\Release\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\x86\Debug\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\x64\Debug\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\x86\Release/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x86\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x86\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x86\Release/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>.\x86\Release/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
<TypeLibraryName>.\x64\Release/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x64\Release/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x64\Release/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuuc.lib;icuin.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x64\Release/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ProgramDatabaseFile>.\x64\Release/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Midl>
|
||||
<TypeLibraryName>.\x86\Debug/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x86\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x86\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x86\Debug/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\x86\Debug/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
<TypeLibraryName>.\x64\Debug/cal.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN64;WIN32;_DEBUG;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/cal.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\x64\Debug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\x64\Debug/</ProgramDataBaseFileName>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>icuucd.lib;icuind.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>.\x64\Debug/cal.exe</OutputFile>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>../../../lib64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\x64\Debug/cal.pdb</ProgramDatabaseFile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cal.c">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="uprint.c">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="uprint.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\common.vcxproj">
|
||||
<Project>{73c0a65b-d1f2-4de1-b3a6-15dad2c23f3d}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\i18n\i18n.vcxproj">
|
||||
<Project>{0178b127-6269-407d-b112-93877bb62776}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 1997-2012, International Business Machines Corporation and
|
||||
* Copyright (c) 1997-2013, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/********************************************************************************
|
||||
|
@ -234,10 +234,6 @@ int main(int argc, const char* const argv[])
|
|||
|
||||
} /* End of loop that repeats the entire test, if requested. (Normally doesn't loop) */
|
||||
|
||||
if (ALLOCATION_COUNT > 0) {
|
||||
fprintf(stderr, "There were %d blocks leaked!\n", ALLOCATION_COUNT);
|
||||
nerrors++;
|
||||
}
|
||||
endTime = uprv_getRawUTCtime();
|
||||
diffTime = (int32_t)(endTime - startTime);
|
||||
printf("Elapsed Time: %02d:%02d:%02d.%03d\n",
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/cintltst.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -127,7 +127,7 @@
|
|||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/cintltst.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -164,7 +164,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/cintltst.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
@ -202,7 +202,7 @@
|
|||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/cintltst.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -270,10 +270,6 @@
|
|||
<ClCompile Include="ucnvseltst.c" />
|
||||
<ClCompile Include="ucsdetst.c" />
|
||||
<ClCompile Include="udatatst.c">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ccaltst.c" />
|
||||
<ClCompile Include="cdateintervalformattest.c" />
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/********************************************************************
|
||||
* COPYRIGHT:
|
||||
* Copyright (c) 2003-2009, International Business Machines Corporation and
|
||||
* Copyright (c) 2003-2013, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
********************************************************************/
|
||||
/*
|
||||
|
@ -29,8 +29,6 @@ typedef union {
|
|||
} ctest_AlignedMemory;
|
||||
|
||||
static void TestHeapFunctions(void);
|
||||
static void TestMutexFunctions(void);
|
||||
static void TestIncDecFunctions(void);
|
||||
|
||||
void addHeapMutexTest(TestNode **root);
|
||||
|
||||
|
@ -39,8 +37,6 @@ void
|
|||
addHeapMutexTest(TestNode** root)
|
||||
{
|
||||
addTest(root, &TestHeapFunctions, "hpmufn/TestHeapFunctions" );
|
||||
addTest(root, &TestMutexFunctions, "hpmufn/TestMutexFunctions" );
|
||||
addTest(root, &TestIncDecFunctions, "hpmufn/TestIncDecFunctions");
|
||||
}
|
||||
|
||||
static int32_t gMutexFailures = 0;
|
||||
|
@ -203,273 +199,3 @@ static void TestHeapFunctions() {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test u_setMutexFunctions()
|
||||
*/
|
||||
|
||||
int gTotalMutexesInitialized = 0; /* Total number of mutexes created */
|
||||
int gTotalMutexesActive = 0; /* Total mutexes created, but not destroyed */
|
||||
int gAccumulatedLocks = 0;
|
||||
const void *gMutexContext;
|
||||
|
||||
typedef struct DummyMutex {
|
||||
int fLockCount;
|
||||
int fMagic;
|
||||
} DummyMutex;
|
||||
|
||||
|
||||
static void U_CALLCONV myMutexInit(const void *context, UMTX *mutex, UErrorCode *status) {
|
||||
DummyMutex *theMutex;
|
||||
|
||||
TEST_STATUS(*status, U_ZERO_ERROR);
|
||||
theMutex = (DummyMutex *)malloc(sizeof(DummyMutex));
|
||||
theMutex->fLockCount = 0;
|
||||
theMutex->fMagic = 123456;
|
||||
gTotalMutexesInitialized++;
|
||||
gTotalMutexesActive++;
|
||||
gMutexContext = context;
|
||||
*mutex = theMutex;
|
||||
}
|
||||
|
||||
|
||||
static void U_CALLCONV myMutexDestroy(const void *context, UMTX *mutex) {
|
||||
DummyMutex *This = *(DummyMutex **)mutex;
|
||||
|
||||
gTotalMutexesActive--;
|
||||
TEST_ASSERT(This->fLockCount == 0);
|
||||
TEST_ASSERT(This->fMagic == 123456);
|
||||
This->fMagic = 0;
|
||||
This->fLockCount = 0;
|
||||
free(This);
|
||||
}
|
||||
|
||||
static void U_CALLCONV myMutexLock(const void *context, UMTX *mutex) {
|
||||
DummyMutex *This = *(DummyMutex **)mutex;
|
||||
|
||||
TEST_ASSERT(This->fMagic == 123456);
|
||||
This->fLockCount++;
|
||||
gAccumulatedLocks++;
|
||||
}
|
||||
|
||||
static void U_CALLCONV myMutexUnlock(const void *context, UMTX *mutex) {
|
||||
DummyMutex *This = *(DummyMutex **)mutex;
|
||||
|
||||
TEST_ASSERT(This->fMagic == 123456);
|
||||
This->fLockCount--;
|
||||
TEST_ASSERT(This->fLockCount >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void TestMutexFunctions() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UResourceBundle *rb = NULL;
|
||||
char *icuDataDir;
|
||||
|
||||
gMutexFailures = 0;
|
||||
|
||||
/* Save initial ICU state so that it can be restored later.
|
||||
* u_cleanup(), which is called in this test, resets ICU's state.
|
||||
*/
|
||||
icuDataDir = safeGetICUDataDirectory();
|
||||
|
||||
/* Verify that ICU can be cleaned up and reinitialized successfully.
|
||||
* Failure here usually means that some ICU service didn't clean up successfully,
|
||||
* probably because some earlier test accidently left something open. */
|
||||
ctest_resetICU();
|
||||
|
||||
/* Can not set mutex functions if ICU is already initialized */
|
||||
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_INVALID_STATE_ERROR);
|
||||
|
||||
/* Un-initialize ICU */
|
||||
u_cleanup();
|
||||
|
||||
/* Can not set Mutex functions with NULL values */
|
||||
status = U_ZERO_ERROR;
|
||||
u_setMutexFunctions(&gContext, NULL, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
status = U_ZERO_ERROR;
|
||||
u_setMutexFunctions(&gContext, myMutexInit, NULL, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
status = U_ZERO_ERROR;
|
||||
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, NULL, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
status = U_ZERO_ERROR;
|
||||
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, NULL, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
|
||||
/* u_setMutexFunctions() should work with null or non-null context pointer */
|
||||
status = U_ZERO_ERROR;
|
||||
u_setMutexFunctions(NULL, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
|
||||
|
||||
/* After reinitializing ICU, we should not be able to set the mutex funcs again. */
|
||||
status = U_ZERO_ERROR;
|
||||
u_setDataDirectory(icuDataDir);
|
||||
u_init(&status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
u_setMutexFunctions(&gContext, myMutexInit, myMutexDestroy, myMutexLock, myMutexUnlock, &status);
|
||||
TEST_STATUS(status, U_INVALID_STATE_ERROR);
|
||||
|
||||
/* Doing ICU operations should cause allocations to come through our test mutexes */
|
||||
gBlockCount = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
/*
|
||||
* Note: If we get assertion failures here because
|
||||
* uresbund.c:resbMutex's fMagic is wrong, check if ures_flushCache() did
|
||||
* flush and delete the cache. If it fails to empty the cache, it will not
|
||||
* delete it and ures_cleanup() will not destroy resbMutex.
|
||||
* That would leave a mutex from the default implementation which does not
|
||||
* pass this test implementation's assertions.
|
||||
*/
|
||||
rb = ures_open(NULL, "es", &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
TEST_ASSERT(gTotalMutexesInitialized > 0);
|
||||
TEST_ASSERT(gTotalMutexesActive > 0);
|
||||
|
||||
ures_close(rb);
|
||||
|
||||
/* Cleanup should destroy all of the mutexes. */
|
||||
ctest_resetICU();
|
||||
status = U_ZERO_ERROR;
|
||||
TEST_ASSERT(gTotalMutexesInitialized > 0);
|
||||
TEST_ASSERT(gTotalMutexesActive == 0);
|
||||
|
||||
|
||||
/* Additional ICU operations should no longer use our dummy test mutexes */
|
||||
gTotalMutexesInitialized = 0;
|
||||
gTotalMutexesActive = 0;
|
||||
u_init(&status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
rb = ures_open(NULL, "fr", &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
TEST_ASSERT(gTotalMutexesInitialized == 0);
|
||||
TEST_ASSERT(gTotalMutexesActive == 0);
|
||||
|
||||
ures_close(rb);
|
||||
free(icuDataDir);
|
||||
|
||||
if(gMutexFailures) {
|
||||
log_info("Note: these failures may be caused by ICU failing to initialize/uninitialize properly.\n");
|
||||
log_verbose("Check for prior tests which may not have closed all open resources. See the internal function ures_flushCache()\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Test Atomic Increment & Decrement Functions
|
||||
*/
|
||||
|
||||
int gIncCount = 0;
|
||||
int gDecCount = 0;
|
||||
const void *gIncDecContext;
|
||||
const void *gExpectedContext = &gIncDecContext;
|
||||
|
||||
|
||||
static int32_t U_CALLCONV myIncFunc(const void *context, int32_t *p) {
|
||||
int32_t retVal;
|
||||
TEST_ASSERT(context == gExpectedContext);
|
||||
gIncCount++;
|
||||
retVal = ++(*p);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static int32_t U_CALLCONV myDecFunc(const void *context, int32_t *p) {
|
||||
int32_t retVal;
|
||||
TEST_ASSERT(context == gExpectedContext);
|
||||
gDecCount++;
|
||||
retVal = --(*p);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void TestIncDecFunctions() {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t t = 1; /* random value to make sure that Inc/dec works */
|
||||
char *dataDir;
|
||||
|
||||
/* Save ICU's data dir and tracing functions so that they can be resored
|
||||
after cleanup and reinit. */
|
||||
dataDir = safeGetICUDataDirectory();
|
||||
|
||||
/* Verify that ICU can be cleaned up and reinitialized successfully.
|
||||
* Failure here usually means that some ICU service didn't clean up successfully,
|
||||
* probably because some earlier test accidently left something open. */
|
||||
ctest_resetICU();
|
||||
|
||||
/* Can not set mutex functions if ICU is already initialized */
|
||||
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
|
||||
TEST_STATUS(status, U_INVALID_STATE_ERROR);
|
||||
|
||||
/* Clean up ICU */
|
||||
u_cleanup();
|
||||
|
||||
/* Can not set functions with NULL values */
|
||||
status = U_ZERO_ERROR;
|
||||
u_setAtomicIncDecFunctions(&gIncDecContext, NULL, myDecFunc, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
status = U_ZERO_ERROR;
|
||||
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, NULL, &status);
|
||||
TEST_STATUS(status, U_ILLEGAL_ARGUMENT_ERROR);
|
||||
|
||||
/* u_setIncDecFunctions() should work with null or non-null context pointer */
|
||||
status = U_ZERO_ERROR;
|
||||
gExpectedContext = NULL;
|
||||
u_setAtomicIncDecFunctions(NULL, myIncFunc, myDecFunc, &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
gExpectedContext = &gIncDecContext;
|
||||
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
|
||||
|
||||
/* After reinitializing ICU, we should not be able to set the inc/dec funcs again. */
|
||||
status = U_ZERO_ERROR;
|
||||
u_setDataDirectory(dataDir);
|
||||
u_init(&status);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
gExpectedContext = &gIncDecContext;
|
||||
u_setAtomicIncDecFunctions(&gIncDecContext, myIncFunc, myDecFunc, &status);
|
||||
TEST_STATUS(status, U_INVALID_STATE_ERROR);
|
||||
|
||||
/* Doing ICU operations should cause our functions to be called */
|
||||
gIncCount = 0;
|
||||
gDecCount = 0;
|
||||
umtx_atomic_inc(&t);
|
||||
TEST_ASSERT(t == 2);
|
||||
umtx_atomic_dec(&t);
|
||||
TEST_ASSERT(t == 1);
|
||||
TEST_ASSERT(gIncCount > 0);
|
||||
TEST_ASSERT(gDecCount > 0);
|
||||
|
||||
|
||||
/* Cleanup should cancel use of our inc/dec functions. */
|
||||
/* Additional ICU operations should not use them */
|
||||
ctest_resetICU();
|
||||
gIncCount = 0;
|
||||
gDecCount = 0;
|
||||
status = U_ZERO_ERROR;
|
||||
u_setDataDirectory(dataDir);
|
||||
u_init(&status);
|
||||
TEST_ASSERT(gIncCount == 0);
|
||||
TEST_ASSERT(gDecCount == 0);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
umtx_atomic_inc(&t);
|
||||
umtx_atomic_dec(&t);
|
||||
TEST_STATUS(status, U_ZERO_ERROR);
|
||||
TEST_ASSERT(gIncCount == 0);
|
||||
TEST_ASSERT(gDecCount == 0);
|
||||
|
||||
free(dataDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -228,7 +228,9 @@
|
|||
<ClCompile Include="regiontst.cpp" />
|
||||
<ClCompile Include="ucharstrietest.cpp" />
|
||||
<ClCompile Include="itrbbi.cpp" />
|
||||
<ClCompile Include="rbbiapts.cpp" />
|
||||
<ClCompile Include="rbbiapts.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="rbbitst.cpp" />
|
||||
<ClCompile Include="itspoof.cpp" />
|
||||
<ClCompile Include="allcoll.cpp" />
|
||||
|
@ -258,10 +260,7 @@
|
|||
<ClCompile Include="uvectest.cpp" />
|
||||
<ClCompile Include="v32test.cpp" />
|
||||
<ClCompile Include="simplethread.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="strtest.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
|
@ -276,13 +275,17 @@
|
|||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tsputil.cpp" />
|
||||
<ClCompile Include="uobjtest.cpp" />
|
||||
<ClCompile Include="uobjtest.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="astrotst.cpp" />
|
||||
<ClCompile Include="calcasts.cpp" />
|
||||
<ClCompile Include="callimts.cpp" />
|
||||
<ClCompile Include="calregts.cpp" />
|
||||
<ClCompile Include="caltest.cpp" />
|
||||
<ClCompile Include="caltztst.cpp" />
|
||||
<ClCompile Include="caltztst.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="compactdecimalformattest.cpp" />
|
||||
<ClCompile Include="dadrcal.cpp" />
|
||||
<ClCompile Include="dadrfmt.cpp" />
|
||||
|
@ -322,11 +325,15 @@
|
|||
<ClCompile Include="tsnmfmt.cpp" />
|
||||
<ClCompile Include="tufmtts.cpp" />
|
||||
<ClCompile Include="tzbdtest.cpp" />
|
||||
<ClCompile Include="tzfmttst.cpp" />
|
||||
<ClCompile Include="tzfmttst.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tzoffloc.cpp" />
|
||||
<ClCompile Include="tzregts.cpp" />
|
||||
<ClCompile Include="tzrulets.cpp" />
|
||||
<ClCompile Include="tztest.cpp" />
|
||||
<ClCompile Include="tztest.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="windttst.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
|
@ -343,33 +350,46 @@
|
|||
<ClCompile Include="idnaref.cpp" />
|
||||
<ClCompile Include="nptrans.cpp" />
|
||||
<ClCompile Include="punyref.c" />
|
||||
<ClCompile Include="testidn.cpp" />
|
||||
<ClCompile Include="testidn.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="testidna.cpp" />
|
||||
<ClCompile Include="uts46test.cpp" />
|
||||
<ClCompile Include="aliastst.cpp" />
|
||||
<ClCompile Include="loctest.cpp" />
|
||||
<ClCompile Include="restest.cpp" />
|
||||
<ClCompile Include="restsnew.cpp" />
|
||||
<ClCompile Include="intltest.cpp" />
|
||||
<ClCompile Include="itmajor.cpp" />
|
||||
<ClCompile Include="itutil.cpp" />
|
||||
<ClCompile Include="intltest.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="itmajor.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="itutil.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="testutil.cpp" />
|
||||
<ClCompile Include="textfile.cpp" />
|
||||
<ClCompile Include="tokiter.cpp" />
|
||||
<ClCompile Include="winutil.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="canittst.cpp" />
|
||||
<ClCompile Include="normconf.cpp" />
|
||||
<ClCompile Include="tstnorm.cpp" />
|
||||
<ClCompile Include="tstnrapi.cpp" />
|
||||
<ClCompile Include="ucdtest.cpp" />
|
||||
<ClCompile Include="tstnorm.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tstnrapi.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ucdtest.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="usettest.cpp" />
|
||||
<ClCompile Include="regextst.cpp" />
|
||||
<ClCompile Include="icusvtst.cpp" />
|
||||
<ClCompile Include="icusvtst.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="citrtest.cpp" />
|
||||
<ClCompile Include="reptest.cpp" />
|
||||
<ClCompile Include="sfwdchit.cpp" />
|
||||
|
@ -541,4 +561,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "unicode/utrace.h"
|
||||
#include "unicode/uclean.h"
|
||||
#include "umutex.h"
|
||||
#include "putilimp.h"
|
||||
|
||||
/* NOTES:
|
||||
|
@ -122,7 +121,6 @@ int WARN_ON_MISSING_DATA = 0; /* Reduce data errs to warnings? */
|
|||
UTraceLevel ICU_TRACE = UTRACE_OFF; /* ICU tracing level */
|
||||
size_t MINIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Minimum library memory allocation window that will fail. */
|
||||
size_t MAXIMUM_MEMORY_SIZE_FAILURE = (size_t)-1; /* Maximum library memory allocation window that will fail. */
|
||||
int32_t ALLOCATION_COUNT = 0;
|
||||
static const char *ARGV_0 = "[ALL]";
|
||||
static const char *XML_FILE_NAME=NULL;
|
||||
static char XML_PREFIX[256];
|
||||
|
@ -874,7 +872,6 @@ static void *U_CALLCONV ctest_libMalloc(const void *context, size_t size) {
|
|||
if (MINIMUM_MEMORY_SIZE_FAILURE <= size && size <= MAXIMUM_MEMORY_SIZE_FAILURE) {
|
||||
return NULL;
|
||||
}
|
||||
umtx_atomic_inc(&ALLOCATION_COUNT);
|
||||
return malloc(size);
|
||||
}
|
||||
static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t size) {
|
||||
|
@ -885,16 +882,9 @@ static void *U_CALLCONV ctest_libRealloc(const void *context, void *mem, size_t
|
|||
/*free(mem);*/ /* Realloc doesn't free on failure. */
|
||||
return NULL;
|
||||
}
|
||||
if (mem == NULL) {
|
||||
/* New allocation. */
|
||||
umtx_atomic_inc(&ALLOCATION_COUNT);
|
||||
}
|
||||
return realloc(mem, size);
|
||||
}
|
||||
static void U_CALLCONV ctest_libFree(const void *context, void *mem) {
|
||||
if (mem != NULL) {
|
||||
umtx_atomic_dec(&ALLOCATION_COUNT);
|
||||
}
|
||||
free(mem);
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/genbrk.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/genbrk.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -175,7 +175,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/genbrk.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -214,7 +214,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/genbrk.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
|
|
@ -90,7 +90,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -120,7 +120,7 @@
|
|||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
|
@ -155,7 +155,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/gencfu.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -193,7 +193,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/gencfu.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/gencnval.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/gencnval.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -175,7 +175,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/gencnval.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -214,7 +214,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/gencnval.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release\gennorm2.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release\</AssemblerListingLocation>
|
||||
|
@ -131,7 +131,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug\</AssemblerListingLocation>
|
||||
|
@ -172,7 +172,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release\gennorm2.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release\</AssemblerListingLocation>
|
||||
|
@ -216,7 +216,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug\gennorm2.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug\</AssemblerListingLocation>
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/gensprep.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -132,7 +132,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/gensprep.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -174,7 +174,7 @@
|
|||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/gensprep.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
@ -213,7 +213,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/gensprep.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Debug/makeconv.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Debug/</AssemblerListingLocation>
|
||||
|
@ -134,7 +134,7 @@
|
|||
<PreprocessorDefinitions>WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x86\Release/makeconv.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x86\Release/</AssemblerListingLocation>
|
||||
|
@ -175,7 +175,7 @@
|
|||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Debug/makeconv.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Debug/</AssemblerListingLocation>
|
||||
|
@ -215,7 +215,7 @@
|
|||
<PreprocessorDefinitions>WIN64;WIN32;NDEBUG;_CRT_SECURE_NO_DEPRECATE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<DisableLanguageExtensions>true</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<PrecompiledHeaderOutputFile>.\x64\Release/makeconv.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\x64\Release/</AssemblerListingLocation>
|
||||
|
|
|
@ -266,7 +266,9 @@
|
|||
<ClCompile Include="pkg_icu.cpp" />
|
||||
<ClCompile Include="pkgitems.cpp" />
|
||||
<ClCompile Include="ppucd.cpp" />
|
||||
<ClCompile Include="swapimpl.cpp" />
|
||||
<ClCompile Include="swapimpl.cpp">
|
||||
<DisableLanguageExtensions>false</DisableLanguageExtensions>
|
||||
</ClCompile>
|
||||
<ClCompile Include="toolutil.cpp">
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</DisableLanguageExtensions>
|
||||
<DisableLanguageExtensions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</DisableLanguageExtensions>
|
||||
|
|
Loading…
Add table
Reference in a new issue