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)
|
EraRules::EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEras)
|
||||||
: startDates(startDates), numEras(numEras) {
|
: numEras(numEras) {
|
||||||
|
startDates.moveFrom(eraStartDates);
|
||||||
initCurrentEra();
|
initCurrentEra();
|
||||||
}
|
}
|
||||||
|
|
||||||
EraRules::~EraRules() {
|
EraRules::~EraRules() {
|
||||||
uprv_free(startDates);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) {
|
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 numEras = ures_getSize(rb.getAlias());
|
||||||
int32_t firstTentativeIdx = MAX_INT32;
|
int32_t firstTentativeIdx = MAX_INT32;
|
||||||
|
|
||||||
int32_t *startDates = (int32_t*)uprv_malloc(numEras * sizeof(int32_t));
|
LocalArray<int32_t> startDates(new int32_t[numEras], status);
|
||||||
if (startDates == nullptr) {
|
if (U_FAILURE(status)) {
|
||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
uprv_memset(startDates, 0, numEras * sizeof(int32_t));
|
uprv_memset(startDates.getAlias(), 0 , numEras * sizeof(int32_t));
|
||||||
|
|
||||||
while (ures_hasNext(rb.getAlias())) {
|
while (ures_hasNext(rb.getAlias())) {
|
||||||
LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
|
LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
|
const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
|
||||||
char *endp;
|
char *endp;
|
||||||
int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
|
int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
|
||||||
if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
|
if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (eraIdx < 0 || eraIdx >= numEras) {
|
if (eraIdx < 0 || eraIdx >= numEras) {
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (isSet(startDates[eraIdx])) {
|
if (isSet(startDates[eraIdx])) {
|
||||||
// start date of the index was already set
|
// start date of the index was already set
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
UBool hasName = TRUE;
|
UBool hasName = TRUE;
|
||||||
@ -159,17 +158,17 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
|||||||
while (ures_hasNext(eraRuleRes.getAlias())) {
|
while (ures_hasNext(eraRuleRes.getAlias())) {
|
||||||
LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
|
LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const char *key = ures_getKey(res.getAlias());
|
const char *key = ures_getKey(res.getAlias());
|
||||||
if (uprv_strcmp(key, "start") == 0) {
|
if (uprv_strcmp(key, "start") == 0) {
|
||||||
const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
|
const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
|
||||||
if (U_FAILURE(status)) {
|
if (U_FAILURE(status)) {
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
|
if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
|
startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
|
||||||
} else if (uprv_strcmp(key, "named") == 0) {
|
} 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
|
// This implementation does not support end only rule for eras other than
|
||||||
// the first one.
|
// the first one.
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
U_ASSERT(eraIdx == 0);
|
U_ASSERT(eraIdx == 0);
|
||||||
startDates[eraIdx] = MIN_ENCODED_START;
|
startDates[eraIdx] = MIN_ENCODED_START;
|
||||||
} else {
|
} else {
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasName) {
|
if (hasName) {
|
||||||
if (eraIdx >= firstTentativeIdx) {
|
if (eraIdx >= firstTentativeIdx) {
|
||||||
status = U_INVALID_FORMAT_ERROR;
|
status = U_INVALID_FORMAT_ERROR;
|
||||||
goto error;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (eraIdx < firstTentativeIdx) {
|
if (eraIdx < firstTentativeIdx) {
|
||||||
@ -226,10 +225,6 @@ EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEr
|
|||||||
status = U_MEMORY_ALLOCATION_ERROR;
|
status = U_MEMORY_ALLOCATION_ERROR;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
error:
|
|
||||||
uprv_free(startDates);
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EraRules::getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const {
|
void EraRules::getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const {
|
||||||
|
@ -12,6 +12,16 @@
|
|||||||
|
|
||||||
U_NAMESPACE_BEGIN
|
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 {
|
class U_I18N_API EraRules : public UMemory {
|
||||||
public:
|
public:
|
||||||
~EraRules();
|
~EraRules();
|
||||||
@ -66,11 +76,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EraRules(int32_t *startDates, int32_t numEra);
|
EraRules(LocalArray<int32_t>& eraStartDates, int32_t numEra);
|
||||||
|
|
||||||
void initCurrentEra();
|
void initCurrentEra();
|
||||||
|
|
||||||
int32_t *startDates;
|
LocalArray<int32_t> startDates;
|
||||||
int32_t numEras;
|
int32_t numEras;
|
||||||
int32_t currentEra;
|
int32_t currentEra;
|
||||||
};
|
};
|
||||||
|
@ -59,11 +59,19 @@ static void U_CALLCONV initializeEras(UErrorCode &status) {
|
|||||||
// By default, such tentative era is disabled.
|
// By default, such tentative era is disabled.
|
||||||
|
|
||||||
// 1. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
|
// 1. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
|
||||||
// 2. Windows registry (TBD)
|
|
||||||
|
|
||||||
UBool includeTentativeEra = FALSE;
|
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);
|
char *envVarVal = getenv(TENTATIVE_ERA_VAR_NAME);
|
||||||
if (envVarVal != NULL && uprv_stricmp(envVarVal, "true") == 0) {
|
if (envVarVal != NULL && uprv_stricmp(envVarVal, "true") == 0) {
|
||||||
includeTentativeEra = TRUE;
|
includeTentativeEra = TRUE;
|
||||||
|
@ -130,7 +130,7 @@ class BasicTimeZone;
|
|||||||
*
|
*
|
||||||
* **Note:** for some non-Gregorian calendars, different
|
* **Note:** for some non-Gregorian calendars, different
|
||||||
* fields may be necessary for complete disambiguation. For example, a full
|
* 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.
|
* month, day-of-month *and* day-of-week in some cases.
|
||||||
*
|
*
|
||||||
* **Note:** There are certain possible ambiguities in
|
* **Note:** There are certain possible ambiguities in
|
||||||
@ -886,7 +886,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Sets the behavior for handling wall time repeating multiple times
|
* Sets the behavior for handling wall time repeating multiple times
|
||||||
* at negative time zone offset transitions. For example, 1:30 AM on
|
* 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>
|
* 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
|
* 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
|
* (first occurrence). When <code>UCAL_WALLTIME_LAST</code> is used, it will be
|
||||||
@ -2152,7 +2152,7 @@ private:
|
|||||||
TimeZone* fZone;
|
TimeZone* fZone;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Option for rpeated wall time
|
* Option for repeated wall time
|
||||||
* @see #setRepeatedWallTimeOption
|
* @see #setRepeatedWallTimeOption
|
||||||
*/
|
*/
|
||||||
UCalendarWallTimeOption fRepeatedWallTime;
|
UCalendarWallTimeOption fRepeatedWallTime;
|
||||||
@ -2437,7 +2437,7 @@ private:
|
|||||||
BasicTimeZone* getBasicTimeZone() const;
|
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 base The base time, inclusive
|
||||||
* @param transitionTime Receives the result time
|
* @param transitionTime Receives the result time
|
||||||
* @param status The error status
|
* @param status The error status
|
||||||
|
Loading…
Reference in New Issue
Block a user