ICU-12973 Enable UWP version of ICU to use Environment variable ICU_ENABLE_TENTATIVE_ERA for testing placeholder names (#124)
- Enable UWP version of ICU to use Environment variable ICU_ENABLE_TENTATIVE_ERA for testing placeholder era names. - Use LocalArray<int32_t> for the Era Start Dates to simply memory management, so that goto can be removed. - Also fix some minor typos in header file.
This commit is contained in:
parent
ce92011aff
commit
4a8b474e77
@ -99,13 +99,13 @@ static int32_t compareEncodedDateWithYMD(int encoded, int year, int month, int d
|
||||
}
|
||||
}
|
||||
|
||||
EraRules::EraRules(int32_t *startDates, int32_t numEras)
|
||||
: startDates(startDates), numEras(numEras) {
|
||||
EraRules::EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEras)
|
||||
: numEras(numEras) {
|
||||
startDates.moveFrom(eraStartDates);
|
||||
initCurrentEra();
|
||||
}
|
||||
|
||||
EraRules::~EraRules() {
|
||||
uprv_free(startDates);
|
||||
}
|
||||
|
||||
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) {
|
||||
@ -124,33 +124,32 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
||||
int32_t numEras = ures_getSize(rb.getAlias());
|
||||
int32_t firstTentativeIdx = MAX_INT32;
|
||||
|
||||
int32_t *startDates = (int32_t*)uprv_malloc(numEras * sizeof(int32_t));
|
||||
if (startDates == nullptr) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
LocalArray<int32_t> startDates(new int32_t[numEras], status);
|
||||
if (U_FAILURE(status)) {
|
||||
return nullptr;
|
||||
}
|
||||
uprv_memset(startDates, 0, numEras * sizeof(int32_t));
|
||||
uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t));
|
||||
|
||||
while (ures_hasNext(rb.getAlias())) {
|
||||
LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
|
||||
if (U_FAILURE(status)) {
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
|
||||
char *endp;
|
||||
int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
|
||||
if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
if (eraIdx < 0 || eraIdx >= numEras) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
if (isSet(startDates[eraIdx])) {
|
||||
// start date of the index was already set
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UBool hasName = TRUE;
|
||||
@ -159,17 +158,17 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
||||
while (ures_hasNext(eraRuleRes.getAlias())) {
|
||||
LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
|
||||
if (U_FAILURE(status)) {
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
const char *key = ures_getKey(res.getAlias());
|
||||
if (uprv_strcmp(key, "start") == 0) {
|
||||
const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
|
||||
} else if (uprv_strcmp(key, "named") == 0) {
|
||||
@ -193,20 +192,20 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
||||
// This implementation does not support end only rule for eras other than
|
||||
// the first one.
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
U_ASSERT(eraIdx == 0);
|
||||
startDates[eraIdx] = MIN_ENCODED_START;
|
||||
} else {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasName) {
|
||||
if (eraIdx >= firstTentativeIdx) {
|
||||
status = U_INVALID_FORMAT_ERROR;
|
||||
goto error;
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
if (eraIdx < firstTentativeIdx) {
|
||||
@ -226,10 +225,6 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
return result;
|
||||
|
||||
error:
|
||||
uprv_free(startDates);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EraRules::getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const {
|
||||
|
@ -12,6 +12,16 @@
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
// Export an explicit template instantiation of LocalArray used as a data member of EraRules.
|
||||
// When building DLLs for Windows this is required even though no direct access leaks out of the i18n library.
|
||||
// See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
|
||||
#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
|
||||
// Ignore warning 4661 as LocalPointerBase does not use operator== or operator!=
|
||||
#pragma warning(suppress: 4661)
|
||||
template class U_I18N_API LocalPointerBase<int32_t>;
|
||||
template class U_I18N_API LocalArray<int32_t>;
|
||||
#endif
|
||||
|
||||
class U_I18N_API EraRules : public UMemory {
|
||||
public:
|
||||
~EraRules();
|
||||
@ -66,11 +76,11 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
EraRules(int32_t *startDates, int32_t numEra);
|
||||
EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEra);
|
||||
|
||||
void initCurrentEra();
|
||||
|
||||
int32_t *startDates;
|
||||
LocalArray<int32_t> startDates;
|
||||
int32_t numEras;
|
||||
int32_t currentEra;
|
||||
};
|
||||
|
@ -59,11 +59,19 @@ static void U_CALLCONV initializeEras(UErrorCode &status) {
|
||||
// By default, such tentative era is disabled.
|
||||
|
||||
// 1. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
|
||||
// 2. Windows registry (TBD)
|
||||
|
||||
UBool includeTentativeEra = FALSE;
|
||||
|
||||
#if U_PLATFORM_HAS_WINUWP_API == 0
|
||||
#if U_PLATFORM_HAS_WINUWP_API == 1
|
||||
// UWP doesn't allow access to getenv(), but we can call GetEnvironmentVariableW to do the same thing.
|
||||
UChar varName[26] = {};
|
||||
u_charsToUChars(TENTATIVE_ERA_VAR_NAME, varName, static_cast<int32_t>(uprv_strlen(TENTATIVE_ERA_VAR_NAME)));
|
||||
WCHAR varValue[5] = {};
|
||||
DWORD ret = GetEnvironmentVariableW(reinterpret_cast<WCHAR*>(varName), varValue, UPRV_LENGTHOF(varValue));
|
||||
if ((ret == 4) && (_wcsicmp(varValue, L"true") == 0)) {
|
||||
includeTentativeEra = TRUE;
|
||||
}
|
||||
#else
|
||||
char *envVarVal = getenv(TENTATIVE_ERA_VAR_NAME);
|
||||
if (envVarVal != NULL && uprv_stricmp(envVarVal, "true") == 0) {
|
||||
includeTentativeEra = TRUE;
|
||||
|
@ -130,7 +130,7 @@ class BasicTimeZone;
|
||||
*
|
||||
* **Note:** for some non-Gregorian calendars, different
|
||||
* fields may be necessary for complete disambiguation. For example, a full
|
||||
* specification of the historial Arabic astronomical calendar requires year,
|
||||
* specification of the historical Arabic astronomical calendar requires year,
|
||||
* month, day-of-month *and* day-of-week in some cases.
|
||||
*
|
||||
* **Note:** There are certain possible ambiguities in
|
||||
@ -886,7 +886,7 @@ public:
|
||||
/**
|
||||
* Sets the behavior for handling wall time repeating multiple times
|
||||
* at negative time zone offset transitions. For example, 1:30 AM on
|
||||
* November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice;
|
||||
* November 6, 2011 in US Eastern time (America/New_York) occurs twice;
|
||||
* 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>UCAL_WALLTIME_FIRST</code>
|
||||
* is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
|
||||
* (first occurrence). When <code>UCAL_WALLTIME_LAST</code> is used, it will be
|
||||
@ -2152,7 +2152,7 @@ private:
|
||||
TimeZone* fZone;
|
||||
|
||||
/**
|
||||
* Option for rpeated wall time
|
||||
* Option for repeated wall time
|
||||
* @see #setRepeatedWallTimeOption
|
||||
*/
|
||||
UCalendarWallTimeOption fRepeatedWallTime;
|
||||
@ -2437,7 +2437,7 @@ private:
|
||||
BasicTimeZone* getBasicTimeZone() const;
|
||||
|
||||
/**
|
||||
* Find the previous zone transtion near the given time.
|
||||
* Find the previous zone transition near the given time.
|
||||
* @param base The base time, inclusive
|
||||
* @param transitionTime Receives the result time
|
||||
* @param status The error status
|
||||
|
Loading…
Reference in New Issue
Block a user