X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b331163bffd790ced0e88b73f44f86d49ccc48a5..a01113dcd0f39d5da295ef82785beff9ed86fe38:/icuSources/i18n/dtitvinf.cpp diff --git a/icuSources/i18n/dtitvinf.cpp b/icuSources/i18n/dtitvinf.cpp index 74f84882..c0a6980e 100644 --- a/icuSources/i18n/dtitvinf.cpp +++ b/icuSources/i18n/dtitvinf.cpp @@ -1,9 +1,11 @@ +// © 2016 and later: Unicode, Inc. and others. +// License & terms of use: http://www.unicode.org/copyright.html /******************************************************************************* -* Copyright (C) 2008-2015, International Business Machines Corporation and +* Copyright (C) 2008-2016, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * -* File DTITVINF.CPP +* File DTITVINF.CPP * ******************************************************************************* */ @@ -17,15 +19,17 @@ //#define DTITVINF_DEBUG 1 -#ifdef DTITVINF_DEBUG +#ifdef DTITVINF_DEBUG #include #endif +#include "cmemory.h" #include "cstring.h" #include "unicode/msgfmt.h" #include "unicode/uloc.h" #include "unicode/ures.h" #include "dtitv_impl.h" +#include "charstr.h" #include "hash.h" #include "gregoimp.h" #include "uresimp.h" @@ -37,7 +41,7 @@ U_NAMESPACE_BEGIN -#ifdef DTITVINF_DEBUG +#ifdef DTITVINF_DEBUG #define PRINTMESG(msg) { std::cout << "(" << __FILE__ << ":" << __LINE__ << ") " << msg << "\n"; } #endif @@ -56,9 +60,7 @@ static const UChar gSecondPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURL // default fall-back static const UChar gDefaultFallbackPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, RIGHT_CURLY_BRACKET, SPACE, EN_DASH, SPACE, LEFT_CURLY_BRACKET, DIGIT_ONE, RIGHT_CURLY_BRACKET, 0}; - - -DateIntervalInfo::DateIntervalInfo(UErrorCode& status) +DateIntervalInfo::DateIntervalInfo(UErrorCode& status) : fFallbackIntervalPattern(gDefaultFallbackPattern), fFirstDateInPtnIsLaterDate(false), fIntervalPatterns(NULL) @@ -83,7 +85,7 @@ DateIntervalInfo::setIntervalPattern(const UnicodeString& skeleton, UCalendarDateFields lrgDiffCalUnit, const UnicodeString& intervalPattern, UErrorCode& status) { - + if ( lrgDiffCalUnit == UCAL_HOUR_OF_DAY ) { setIntervalPatternInternally(skeleton, UCAL_AM_PM, intervalPattern, status); setIntervalPatternInternally(skeleton, UCAL_HOUR, intervalPattern, status); @@ -103,15 +105,15 @@ DateIntervalInfo::setFallbackIntervalPattern( if ( U_FAILURE(status) ) { return; } - int32_t firstPatternIndex = fallbackPattern.indexOf(gFirstPattern, - sizeof(gFirstPattern)/sizeof(gFirstPattern[0]), 0); - int32_t secondPatternIndex = fallbackPattern.indexOf(gSecondPattern, - sizeof(gSecondPattern)/sizeof(gSecondPattern[0]), 0); + int32_t firstPatternIndex = fallbackPattern.indexOf(gFirstPattern, + UPRV_LENGTHOF(gFirstPattern), 0); + int32_t secondPatternIndex = fallbackPattern.indexOf(gSecondPattern, + UPRV_LENGTHOF(gSecondPattern), 0); if ( firstPatternIndex == -1 || secondPatternIndex == -1 ) { status = U_ILLEGAL_ARGUMENT_ERROR; return; } - if ( firstPatternIndex > secondPatternIndex ) { + if ( firstPatternIndex > secondPatternIndex ) { fFirstDateInPtnIsLaterDate = true; } fFallbackIntervalPattern = fallbackPattern; @@ -125,7 +127,7 @@ DateIntervalInfo::DateIntervalInfo(const DateIntervalInfo& dtitvinf) { *this = dtitvinf; } - + DateIntervalInfo& @@ -133,14 +135,14 @@ DateIntervalInfo::operator=(const DateIntervalInfo& dtitvinf) { if ( this == &dtitvinf ) { return *this; } - + UErrorCode status = U_ZERO_ERROR; deleteHash(fIntervalPatterns); fIntervalPatterns = initHash(status); copyHash(dtitvinf.fIntervalPatterns, fIntervalPatterns, status); if ( U_FAILURE(status) ) { return *this; - } + } fFallbackIntervalPattern = dtitvinf.fFallbackIntervalPattern; fFirstDateInPtnIsLaterDate = dtitvinf.fFirstDateInPtnIsLaterDate; @@ -162,7 +164,7 @@ DateIntervalInfo::~DateIntervalInfo() { UBool DateIntervalInfo::operator==(const DateIntervalInfo& other) const { - UBool equal = ( + UBool equal = ( fFallbackIntervalPattern == other.fFallbackIntervalPattern && fFirstDateInPtnIsLaterDate == other.fFirstDateInPtnIsLaterDate ); @@ -182,7 +184,7 @@ DateIntervalInfo::getIntervalPattern(const UnicodeString& skeleton, if ( U_FAILURE(status) ) { return result; } - + const UnicodeString* patternsOfOneSkeleton = (UnicodeString*) fIntervalPatterns->get(skeleton); if ( patternsOfOneSkeleton != NULL ) { IntervalPatternIndex index = calendarFieldToIntervalIndex(field, status); @@ -212,158 +214,265 @@ DateIntervalInfo::getFallbackIntervalPattern(UnicodeString& result) const { #define ULOC_LOCALE_IDENTIFIER_CAPACITY (ULOC_FULLNAME_CAPACITY + 1 + ULOC_KEYWORD_AND_VALUES_CAPACITY) -void -DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& err) + +static const int32_t PATH_PREFIX_LENGTH = 17; +static const UChar PATH_PREFIX[] = {SOLIDUS, CAP_L, CAP_O, CAP_C, CAP_A, CAP_L, CAP_E, SOLIDUS, + LOW_C, LOW_A, LOW_L, LOW_E, LOW_N, LOW_D, LOW_A, LOW_R, SOLIDUS}; +static const int32_t PATH_SUFFIX_LENGTH = 16; +static const UChar PATH_SUFFIX[] = {SOLIDUS, LOW_I, LOW_N, LOW_T, LOW_E, LOW_R, LOW_V, LOW_A, + LOW_L, CAP_F, LOW_O, LOW_R, LOW_M, LOW_A, LOW_T, LOW_S}; + +/** + * Sink for enumerating all of the date interval skeletons. + */ +struct DateIntervalInfo::DateIntervalSink : public ResourceSink { + + // Output data + DateIntervalInfo &dateIntervalInfo; + + // Next calendar type + UnicodeString nextCalendarType; + + DateIntervalSink(DateIntervalInfo &diInfo, const char *currentCalendarType) + : dateIntervalInfo(diInfo), nextCalendarType(currentCalendarType, -1, US_INV) { } + virtual ~DateIntervalSink(); + + virtual void put(const char *key, ResourceValue &value, UBool /*noFallback*/, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + + // Iterate over all the calendar entries and only pick the 'intervalFormats' table. + ResourceTable dateIntervalData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t i = 0; dateIntervalData.getKeyAndValue(i, key, value); i++) { + if (uprv_strcmp(key, gIntervalDateTimePatternTag) != 0) { + continue; + } + + // Handle aliases and tables. Ignore the rest. + if (value.getType() == URES_ALIAS) { + // Get the calendar type for the alias path. + const UnicodeString &aliasPath = value.getAliasUnicodeString(errorCode); + if (U_FAILURE(errorCode)) { return; } + + nextCalendarType.remove(); + getCalendarTypeFromPath(aliasPath, nextCalendarType, errorCode); + + if (U_FAILURE(errorCode)) { + resetNextCalendarType(); + } + break; + + } else if (value.getType() == URES_TABLE) { + // Iterate over all the skeletons in the 'intervalFormat' table. + ResourceTable skeletonData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t j = 0; skeletonData.getKeyAndValue(j, key, value); j++) { + if (value.getType() == URES_TABLE) { + // Process the skeleton + processSkeletonTable(key, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } + break; + } + } + } + + /** + * Processes the patterns for a skeleton table + */ + void processSkeletonTable(const char *key, ResourceValue &value, UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + + // Iterate over all the patterns in the current skeleton table + const char *currentSkeleton = key; + ResourceTable patternData = value.getTable(errorCode); + if (U_FAILURE(errorCode)) { return; } + for (int32_t k = 0; patternData.getKeyAndValue(k, key, value); k++) { + if (value.getType() == URES_STRING) { + // Process the key + UCalendarDateFields calendarField = validateAndProcessPatternLetter(key); + + // If the calendar field has a valid value + if (calendarField < UCAL_FIELD_COUNT) { + // Set the interval pattern + setIntervalPatternIfAbsent(currentSkeleton, calendarField, value, errorCode); + if (U_FAILURE(errorCode)) { return; } + } + } + } + } + + /** + * Extracts the calendar type from the path. + */ + static void getCalendarTypeFromPath(const UnicodeString &path, UnicodeString &calendarType, + UErrorCode &errorCode) { + if (U_FAILURE(errorCode)) { return; } + + if (!path.startsWith(PATH_PREFIX, PATH_PREFIX_LENGTH) || !path.endsWith(PATH_SUFFIX, PATH_SUFFIX_LENGTH)) { + errorCode = U_INVALID_FORMAT_ERROR; + return; + } + + path.extractBetween(PATH_PREFIX_LENGTH, path.length() - PATH_SUFFIX_LENGTH, calendarType); + } + + /** + * Validates and processes the pattern letter + */ + UCalendarDateFields validateAndProcessPatternLetter(const char *patternLetter) { + // Check that patternLetter is just one letter + char c0; + if ((c0 = patternLetter[0]) != 0 && patternLetter[1] == 0) { + // Check that the pattern letter is accepted + if (c0 == 'G') { + return UCAL_ERA; + } else if (c0 == 'y') { + return UCAL_YEAR; + } else if (c0 == 'M') { + return UCAL_MONTH; + } else if (c0 == 'd') { + return UCAL_DATE; + } else if (c0 == 'a') { + return UCAL_AM_PM; + } else if (c0 == 'h' || c0 == 'H') { + return UCAL_HOUR; + } else if (c0 == 'm') { + return UCAL_MINUTE; + }// TODO(ticket:12190): Why icu4c doesn't accept the calendar field "s" but icu4j does? + } + return UCAL_FIELD_COUNT; + } + + /** + * Stores the interval pattern for the current skeleton in the internal data structure + * if it's not present. + */ + void setIntervalPatternIfAbsent(const char *currentSkeleton, UCalendarDateFields lrgDiffCalUnit, + const ResourceValue &value, UErrorCode &errorCode) { + // Check if the pattern has already been stored on the data structure + IntervalPatternIndex index = + dateIntervalInfo.calendarFieldToIntervalIndex(lrgDiffCalUnit, errorCode); + if (U_FAILURE(errorCode)) { return; } + + UnicodeString skeleton(currentSkeleton, -1, US_INV); + UnicodeString* patternsOfOneSkeleton = + (UnicodeString*)(dateIntervalInfo.fIntervalPatterns->get(skeleton)); + + if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) { + UnicodeString pattern = value.getUnicodeString(errorCode); + dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit, + pattern, errorCode); + } + } + + const UnicodeString &getNextCalendarType() { + return nextCalendarType; + } + + void resetNextCalendarType() { + nextCalendarType.setToBogus(); + } +}; + +// Virtual destructors must be defined out of line. +DateIntervalInfo::DateIntervalSink::~DateIntervalSink() {} + + + +void +DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) { - fIntervalPatterns = initHash(err); - if ( U_FAILURE(err) ) { - return; - } - const char *locName = locale.getName(); - char parentLocale[ULOC_FULLNAME_CAPACITY]; - uprv_strcpy(parentLocale, locName); - UErrorCode status = U_ZERO_ERROR; - Hashtable skeletonKeyPairs(FALSE, status); - if ( U_FAILURE(status) ) { + fIntervalPatterns = initHash(status); + if (U_FAILURE(status)) { return; - } - - // determine calendar type - const char * calendarTypeToUse = gGregorianTag; // initial default - char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well - char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; - // obtain a locale that always has the calendar key value that should be used - (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, + } + const char *locName = locale.getName(); + + // Get the correct calendar type + const char * calendarTypeToUse = gGregorianTag; // initial default + char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well + char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; + // obtain a locale that always has the calendar key value that should be used + (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, "calendar", "calendar", locName, NULL, FALSE, &status); - localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination - // now get the calendar key value from that locale - int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, ULOC_KEYWORDS_CAPACITY, &status); - if (U_SUCCESS(status) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { - calendarTypeToUse = calendarType; - } - status = U_ZERO_ERROR; - - do { - UResourceBundle *rb, *calBundle, *calTypeBundle, *itvDtPtnResource; - rb = ures_open(NULL, parentLocale, &status); - if ( U_FAILURE(status) ) { - break; + localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination + // now get the calendar key value from that locale + int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, + ULOC_KEYWORDS_CAPACITY, &status); + if (U_SUCCESS(status) && calendarTypeLen < ULOC_KEYWORDS_CAPACITY) { + calendarTypeToUse = calendarType; + } + status = U_ZERO_ERROR; + + // Instantiate the resource bundles + UResourceBundle *rb, *calBundle; + rb = ures_open(NULL, locName, &status); + if (U_FAILURE(status)) { + return; } - calBundle = ures_getByKey(rb, gCalendarTag, NULL, &status); - calTypeBundle = ures_getByKey(calBundle, calendarTypeToUse, NULL, &status); - itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, - gIntervalDateTimePatternTag, NULL, &status); + calBundle = ures_getByKeyWithFallback(rb, gCalendarTag, NULL, &status); - if ( U_SUCCESS(status) ) { - // look for fallback first, since it establishes the default order + + if (U_SUCCESS(status)) { + UResourceBundle *calTypeBundle, *itvDtPtnResource; + + // Get the fallback pattern const UChar* resStr; int32_t resStrLen = 0; - resStr = ures_getStringByKeyWithFallback(itvDtPtnResource, - gFallbackPatternTag, - &resStrLen, &status); + calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &status); + itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, + gIntervalDateTimePatternTag, NULL, &status); + resStr = ures_getStringByKeyWithFallback(itvDtPtnResource, gFallbackPatternTag, + &resStrLen, &status); if ( U_SUCCESS(status) ) { UnicodeString pattern = UnicodeString(TRUE, resStr, resStrLen); setFallbackIntervalPattern(pattern, status); } + ures_close(itvDtPtnResource); + ures_close(calTypeBundle); - int32_t size = ures_getSize(itvDtPtnResource); - int32_t index; - for ( index = 0; index < size; ++index ) { - LocalUResourceBundlePointer oneRes(ures_getByIndex(itvDtPtnResource, index, - NULL, &status)); - if ( U_SUCCESS(status) ) { - const char* skeleton = ures_getKey(oneRes.getAlias()); - if (skeleton == NULL) { - continue; - } - UnicodeString skeletonUniStr(skeleton, -1, US_INV); - if ( uprv_strcmp(skeleton, gFallbackPatternTag) == 0 ) { - continue; // fallback - } - LocalUResourceBundlePointer intervalPatterns(ures_getByKey( - itvDtPtnResource, skeleton, NULL, &status)); + // Instantiate the sink + DateIntervalSink sink(*this, calendarTypeToUse); + const UnicodeString &calendarTypeToUseUString = sink.getNextCalendarType(); + + // Already loaded calendar types + Hashtable loadedCalendarTypes(FALSE, status); - if ( U_FAILURE(status) ) { + if (U_SUCCESS(status)) { + while (!calendarTypeToUseUString.isBogus()) { + // Set an error when a loop is detected + if (loadedCalendarTypes.geti(calendarTypeToUseUString) == 1) { + status = U_INVALID_FORMAT_ERROR; break; } - if ( intervalPatterns == NULL ) { - continue; - } - const char* key; - int32_t ptnNum = ures_getSize(intervalPatterns.getAlias()); - int32_t ptnIndex; - for ( ptnIndex = 0; ptnIndex < ptnNum; ++ptnIndex ) { - UnicodeString pattern = - ures_getNextUnicodeString(intervalPatterns.getAlias(), &key, &status); - if ( U_FAILURE(status) ) { - break; - } - UnicodeString keyUniStr(key, -1, US_INV); - UnicodeString skeletonKeyPair(skeletonUniStr + keyUniStr); - if ( skeletonKeyPairs.geti(skeletonKeyPair) == 1 ) { - continue; - } - skeletonKeyPairs.puti(skeletonKeyPair, 1, status); - - UCalendarDateFields calendarField = UCAL_FIELD_COUNT; - if ( !uprv_strcmp(key, "y") ) { - calendarField = UCAL_YEAR; - } else if ( !uprv_strcmp(key, "M") ) { - calendarField = UCAL_MONTH; - } else if ( !uprv_strcmp(key, "d") ) { - calendarField = UCAL_DATE; - } else if ( !uprv_strcmp(key, "a") ) { - calendarField = UCAL_AM_PM; - } else if ( !uprv_strcmp(key, "h") || !uprv_strcmp(key, "H") ) { - calendarField = UCAL_HOUR; - } else if ( !uprv_strcmp(key, "m") ) { - calendarField = UCAL_MINUTE; - } - if ( calendarField != UCAL_FIELD_COUNT ) { - setIntervalPatternInternally(skeletonUniStr, calendarField, pattern,status); - } - } + // Register the calendar type to avoid loops + loadedCalendarTypes.puti(calendarTypeToUseUString, 1, status); + if (U_FAILURE(status)) { break; } + + // Get the calendar string + CharString calTypeBuffer; + calTypeBuffer.appendInvariantChars(calendarTypeToUseUString, status); + if (U_FAILURE(status)) { break; } + const char *calType = calTypeBuffer.data(); + + // Reset the next calendar type to load. + sink.resetNextCalendarType(); + + // Get all resources for this calendar type + ures_getAllItemsWithFallback(calBundle, calType, sink, status); } } } - ures_close(itvDtPtnResource); - ures_close(calTypeBundle); - ures_close(calBundle); - status = U_ZERO_ERROR; - // 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...) - int32_t locNameLen; - const UChar * parentUName = ures_getStringByKey(rb, "%%Parent", &locNameLen, &status); - if (U_SUCCESS(status) && status != U_USING_FALLBACK_WARNING && locNameLen < ULOC_FULLNAME_CAPACITY) { - u_UCharsToChars(parentUName, parentLocale, locNameLen + 1); - } 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; - } - uloc_getParent(curLocaleName, parentLocale, ULOC_FULLNAME_CAPACITY, &status); - if (U_FAILURE(err) || err == U_STRING_NOT_TERMINATED_WARNING) { - parentLocale[0] = 0; // just fallback to root, will cause us to stop - status = U_ZERO_ERROR; - } - } - // Now we can close the current locale bundle + // Close the opened resource bundles + ures_close(calBundle); 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 ); } - - void DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, UCalendarDateFields lrgDiffCalUnit, @@ -379,7 +488,7 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, patternsOfOneSkeleton = new UnicodeString[kIPI_MAX_INDEX]; emptyHash = true; } - + patternsOfOneSkeleton[index] = intervalPattern; if ( emptyHash == TRUE ) { fIntervalPatterns->put(skeleton, patternsOfOneSkeleton, status); @@ -388,21 +497,21 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, -void -DateIntervalInfo::parseSkeleton(const UnicodeString& skeleton, +void +DateIntervalInfo::parseSkeleton(const UnicodeString& skeleton, int32_t* skeletonFieldWidth) { const int8_t PATTERN_CHAR_BASE = 0x41; int32_t i; for ( i = 0; i < skeleton.length(); ++i ) { // it is an ASCII char in skeleton - int8_t ch = (int8_t)skeleton.charAt(i); + int8_t ch = (int8_t)skeleton.charAt(i); ++skeletonFieldWidth[ch - PATTERN_CHAR_BASE]; } } -UBool +UBool DateIntervalInfo::stringNumeric(int32_t fieldWidth, int32_t anotherFieldWidth, char patternLetter) { if ( patternLetter == 'M' ) { @@ -416,7 +525,7 @@ DateIntervalInfo::stringNumeric(int32_t fieldWidth, int32_t anotherFieldWidth, -const UnicodeString* +const UnicodeString* DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, int8_t& bestMatchDistanceInfo) const { #ifdef DTITVINF_DEBUG @@ -463,7 +572,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, // resource bundle only have time skeletons ending with 'v', // but not for time skeletons ending with 'z'. UBool replaceZWithV = false; - const UnicodeString* inputSkeleton = &skeleton; + const UnicodeString* inputSkeleton = &skeleton; UnicodeString copySkeleton; if ( skeleton.indexOf(CHAR_Z) != -1 ) { copySkeleton = skeleton; @@ -481,13 +590,13 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, // 2 means only z/v differs // -1 means having different field. bestMatchDistanceInfo = 0; - int8_t fieldLength = sizeof(skeletonFieldWidth)/sizeof(skeletonFieldWidth[0]); + int8_t fieldLength = UPRV_LENGTHOF(skeletonFieldWidth); int32_t pos = UHASH_FIRST; const UHashElement* elem = NULL; while ( (elem = fIntervalPatterns->nextElement(pos)) != NULL ) { const UHashTok keyTok = elem->key; - UnicodeString* skeleton = (UnicodeString*)keyTok.pointer; + UnicodeString* newSkeleton = (UnicodeString*)keyTok.pointer; #ifdef DTITVINF_DEBUG skeleton->extract(0, skeleton->length(), result, "UTF-8"); sprintf(mesg, "available skeletons: skeleton: %s; \n", result); @@ -497,9 +606,9 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, // clear skeleton field width int8_t i; for ( i = 0; i < fieldLength; ++i ) { - skeletonFieldWidth[i] = 0; + skeletonFieldWidth[i] = 0; } - parseSkeleton(*skeleton, skeletonFieldWidth); + parseSkeleton(*newSkeleton, skeletonFieldWidth); // calculate distance int32_t distance = 0; int8_t fieldDifference = 1; @@ -515,17 +624,17 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, } else if ( fieldWidth == 0 ) { fieldDifference = -1; distance += DIFFERENT_FIELD; - } else if (stringNumeric(inputFieldWidth, fieldWidth, + } else if (stringNumeric(inputFieldWidth, fieldWidth, (char)(i+BASE) ) ) { distance += STRING_NUMERIC_DIFFERENCE; } else { - distance += (inputFieldWidth > fieldWidth) ? - (inputFieldWidth - fieldWidth) : + distance += (inputFieldWidth > fieldWidth) ? + (inputFieldWidth - fieldWidth) : (fieldWidth - inputFieldWidth); } } if ( distance < bestDistance ) { - bestSkeleton = skeleton; + bestSkeleton = newSkeleton; bestDistance = distance; bestMatchDistanceInfo = fieldDifference; } @@ -543,7 +652,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, DateIntervalInfo::IntervalPatternIndex -DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, +DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, UErrorCode& status) { if ( U_FAILURE(status) ) { return kIPI_MAX_INDEX; @@ -586,7 +695,7 @@ DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, void -DateIntervalInfo::deleteHash(Hashtable* hTable) +DateIntervalInfo::deleteHash(Hashtable* hTable) { if ( hTable == NULL ) { return; @@ -602,7 +711,7 @@ DateIntervalInfo::deleteHash(Hashtable* hTable) } -U_CDECL_BEGIN +U_CDECL_BEGIN /** * set hash table value comparator @@ -613,7 +722,7 @@ U_CDECL_BEGIN */ static UBool U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2); -static UBool +static UBool U_CALLCONV dtitvinfHashTableValueComparator(UHashTok val1, UHashTok val2) { const UnicodeString* pattern1 = (UnicodeString*)val1.pointer; const UnicodeString* pattern2 = (UnicodeString*)val2.pointer; @@ -639,7 +748,7 @@ DateIntervalInfo::initHash(UErrorCode& status) { return NULL; } if ( U_FAILURE(status) ) { - delete hTable; + delete hTable; return NULL; } hTable->setValueComparator(dtitvinfHashTableValueComparator);