ICU-7727 When collecting data, use real parent (per %%Parent if present) instead of just truncating name

X-SVN-Rev: 31491
This commit is contained in:
Peter Edberg 2012-02-23 10:06:47 +00:00
parent c422bcd481
commit 9fb2e3ac79
3 changed files with 111 additions and 73 deletions

View File

@ -1491,6 +1491,7 @@ zh_Hant{
yyyyMEd{"Gy/M/dE"} yyyyMEd{"Gy/M/dE"}
yyyyMMM{"Gy年M月"} yyyyMMM{"Gy年M月"}
yyyyMMMEd{"Gy年M月d日E"} yyyyMMMEd{"Gy年M月d日E"}
yyyyMMMd{"Gy年M月d日"}
yyyyMd{"Gy/M/d"} yyyyMd{"Gy/M/d"}
yyyyQQQ{"Gy QQQ"} yyyyQQQ{"Gy QQQ"}
} }

View File

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (C) 2008-2011, International Business Machines Corporation and * Copyright (C) 2008-2012, International Business Machines Corporation and
* others. All Rights Reserved. * others. All Rights Reserved.
******************************************************************************* *******************************************************************************
* *
@ -247,6 +247,9 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& err)
do { do {
UResourceBundle *rb, *calBundle, *calTypeBundle, *itvDtPtnResource; UResourceBundle *rb, *calBundle, *calTypeBundle, *itvDtPtnResource;
rb = ures_open(NULL, parentLocale, &status); rb = ures_open(NULL, parentLocale, &status);
if ( U_FAILURE(status) ) {
break;
}
calBundle = ures_getByKey(rb, gCalendarTag, NULL, &status); calBundle = ures_getByKey(rb, gCalendarTag, NULL, &status);
calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &status); calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &status);
itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle,
@ -327,11 +330,34 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& err)
ures_close(itvDtPtnResource); ures_close(itvDtPtnResource);
ures_close(calTypeBundle); ures_close(calTypeBundle);
ures_close(calBundle); ures_close(calBundle);
ures_close(rb);
status = U_ZERO_ERROR; status = U_ZERO_ERROR;
locNameLen = uloc_getParent(parentLocale, parentLocale, // Find the name of the appropriate parent locale (from %%Parent if present, else
ULOC_FULLNAME_CAPACITY,&status); // uloc_getParent on the actual locale name)
} while ( locNameLen > 0 ); // (It would be nice to have a ures function that did this...)
const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &status);
if (U_SUCCESS(status) && status != U_USING_FALLBACK_WARNING) {
u_austrncpy(parentLocale, parentUName, ULOC_FULLNAME_CAPACITY); // Should work on EBCDIC too?
} else {
status = U_ZERO_ERROR;
// Get the actual name of the current locale being used
const char *curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &status);
if ( U_FAILURE(status) ) {
curLocaleName = parentLocale;
status = U_ZERO_ERROR;
}
locNameLen = uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &status);
if ( U_FAILURE(status) ) {
parentLocale[0] = 0; // just fallback to root, will cause us to stop
status = U_ZERO_ERROR;
}
}
// Now we can close the current locale bundle
ures_close(rb);
// If the new current locale is root, then stop
// (unlike for DateTimePatternGenerator, DateIntervalFormat does not go all the way up
// to root to find additional data for non-root locales)
} while ( parentLocale[0] != 0 && uprv_strcmp(parentLocale,"root")!=0 );
} }

View File

@ -607,87 +607,98 @@ DateTimePatternGenerator::addCLDRData(const Locale& locale, UErrorCode& err) {
ures_close(fBundle); ures_close(fBundle);
// add available formats // add available formats
UBool firstTimeThrough = TRUE;
char parentLocale[ULOC_FULLNAME_CAPACITY];
err = U_ZERO_ERROR; err = U_ZERO_ERROR;
initHashtable(err); initHashtable(err);
patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAvailableFormatsTag, NULL, &err); while (TRUE) {
if (U_SUCCESS(err)) { // At the start of the loop:
int32_t numberKeys = ures_getSize(patBundle); // - rb is the open resource bundle for the current locale being processed,
int32_t len; // whose actual name is in curLocaleName.
const UChar *retPattern; // - if U_SUCCESS(err), then calBundle and calTypeBundle are open;
key=NULL; // process contents of calTypeBundle, then close calBundle and calTypeBundle.
#if defined(U_USE_ASCII_BUNDLE_ITERATOR)
UResourceBundleAIterator aiter;
ures_a_open(&aiter, patBundle, &err);
#endif
for(i=0; i<numberKeys; ++i) {
#if defined(U_USE_ASCII_BUNDLE_ITERATOR)
retPattern=ures_a_getNextString(&aiter, &len, &key, &err);
#else
retPattern=ures_getNextString(patBundle, &len, &key, &err);
#endif
UnicodeString format=UnicodeString(retPattern);
UnicodeString retKey=UnicodeString(key, -1, US_INV);
setAvailableFormat(retKey, err);
// Add pattern with its associated skeleton. Override any duplicate derived from std patterns,
// but not a previous availableFormats entry:
addPatternWithSkeleton(format, &retKey, TRUE, conflictingPattern, err);
}
#if defined(U_USE_ASCII_BUNDLE_ITERATOR)
ures_a_close(&aiter);
#endif
}
ures_close(patBundle);
ures_close(calTypeBundle);
ures_close(calBundle);
ures_close(rb);
err = U_ZERO_ERROR;
char parentLocale[50];
int32_t localeNameLen=0;
uprv_strcpy(parentLocale, curLocaleName);
while((localeNameLen=uloc_getParent(parentLocale, parentLocale, 50, &err))>=0 ) {
rb = ures_open(NULL, parentLocale, &err);
curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err);
uprv_strcpy(parentLocale, curLocaleName);
calBundle = ures_getByKey(rb, DT_DateTimeCalendarTag, NULL, &err);
calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &err);
patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAvailableFormatsTag, NULL, &err);
if (U_SUCCESS(err)) { if (U_SUCCESS(err)) {
int32_t numberKeys = ures_getSize(patBundle); // process contents of calTypeBundle
int32_t len; patBundle = ures_getByKeyWithFallback(calTypeBundle, DT_DateTimeAvailableFormatsTag, NULL, &err);
const UChar *retPattern; if (U_SUCCESS(err)) {
key=NULL; int32_t numberKeys = ures_getSize(patBundle);
int32_t len;
const UChar *retPattern;
key=NULL;
#if defined(U_USE_ASCII_BUNDLE_ITERATOR) #if defined(U_USE_ASCII_BUNDLE_ITERATOR)
UResourceBundleAIterator aiter; UResourceBundleAIterator aiter;
ures_a_open(&aiter, patBundle, &err); ures_a_open(&aiter, patBundle, &err);
#endif #endif
for(i=0; i<numberKeys; ++i) { for(i=0; i<numberKeys; ++i) {
#if defined(U_USE_ASCII_BUNDLE_ITERATOR) #if defined(U_USE_ASCII_BUNDLE_ITERATOR)
retPattern=ures_a_getNextString(&aiter, &len, &key, &err); retPattern=ures_a_getNextString(&aiter, &len, &key, &err);
#else #else
retPattern=ures_getNextString(patBundle, &len, &key, &err); retPattern=ures_getNextString(patBundle, &len, &key, &err);
#endif #endif
UnicodeString format=UnicodeString(retPattern); UnicodeString format=UnicodeString(retPattern);
UnicodeString retKey=UnicodeString(key, -1, US_INV); UnicodeString retKey=UnicodeString(key, -1, US_INV);
if ( !isAvailableFormatSet(retKey) ) { if ( firstTimeThrough || !isAvailableFormatSet(retKey) ) {
setAvailableFormat(retKey, err); setAvailableFormat(retKey, err);
// Add pattern with its associated skeleton. Override any duplicate derived from std patterns, // Add pattern with its associated skeleton. Override any duplicate derived from std patterns,
// but not a previous availableFormats entry: // but not a previous availableFormats entry:
addPatternWithSkeleton(format, &retKey, TRUE, conflictingPattern, err); addPatternWithSkeleton(format, &retKey, TRUE, conflictingPattern, err);
}
} }
}
#if defined(U_USE_ASCII_BUNDLE_ITERATOR) #if defined(U_USE_ASCII_BUNDLE_ITERATOR)
ures_a_close(&aiter); ures_a_close(&aiter);
#endif #endif
ures_close(patBundle);
}
firstTimeThrough = FALSE;
// close calBundle and calTypeBundle
ures_close(calTypeBundle);
ures_close(calBundle);
} }
err = U_ZERO_ERROR; // reset; if this locale lacks the necessary data, need to keep checking up to root. if (uprv_strcmp(curLocaleName,"root")==0 || uprv_strlen(curLocaleName)==0) {
ures_close(patBundle); // we just finished handling root, nothing more to check
ures_close(calTypeBundle); ures_close(rb);
ures_close(calBundle);
ures_close(rb);
if (localeNameLen==0) {
break; break;
} }
// Find the name of the appropriate parent locale (from %%Parent if present, else
// uloc_getParent on the actual locale name)
// (It would be nice to have a ures function that did this...)
err = U_ZERO_ERROR;
int32_t locNameLen;
const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &err);
if (U_SUCCESS(err) && err != U_USING_FALLBACK_WARNING) {
u_austrncpy(parentLocale, parentUName, ULOC_FULLNAME_CAPACITY); // Should work on EBCDIC too?
} else {
err = U_ZERO_ERROR;
locNameLen = uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &err);
if ( U_FAILURE(err) ) {
// just fallback to root, since we are not already there
parentLocale[0] = 0;
err = U_ZERO_ERROR;
}
}
// Close current locale bundle
ures_close(rb);
// And open its parent, which becomes the new current locale being processed
rb = ures_open(NULL, parentLocale, &err);
if ( U_FAILURE(err) ) {
err = U_ZERO_ERROR;
break;
}
// Get the name of the parent / new current locale
curLocaleName=ures_getLocaleByType(rb, ULOC_ACTUAL_LOCALE, &err);
if ( U_FAILURE(err) ) {
curLocaleName = parentLocale;
err = U_ZERO_ERROR;
}
// Open calBundle and calTypeBundle
calBundle = ures_getByKeyWithFallback(rb, DT_DateTimeCalendarTag, NULL, &err);
if (U_SUCCESS(err)) {
calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &err);
if ( U_FAILURE(err) ) {
ures_close(calBundle);
}
}
// Go to the top of the loop to process contents of calTypeBundle
} }
if (hackPattern.length()>0) { if (hackPattern.length()>0) {