diff --git a/icu4c/source/i18n/ucol.cpp b/icu4c/source/i18n/ucol.cpp index daeb658b55..e4aaea589a 100644 --- a/icu4c/source/i18n/ucol.cpp +++ b/icu4c/source/i18n/ucol.cpp @@ -955,6 +955,7 @@ uint32_t getSpecialCE(const UCollator *coll, uint32_t CE, collIterate *source, U if (CE == UCOL_NOT_FOUND && firstFound != UCOL_NOT_FOUND) { CE = firstFound; firstFound = UCOL_NOT_FOUND; + source->pos--; /* spit out yet another char, which led us in this contraction */ } } break; @@ -986,6 +987,7 @@ uint32_t getSpecialCE(const UCollator *coll, uint32_t CE, collIterate *source, U if(firstFound != UCOL_NOT_FOUND) { CE = firstFound; firstFound = UCOL_NOT_FOUND; + source->pos--; /* spit out yet another char, which led us in this contraction */ break; } } else if(isContraction(CE)) { /* fix for the bug. Other places need to be checked */ diff --git a/icu4c/source/i18n/ucol_cnt.cpp b/icu4c/source/i18n/ucol_cnt.cpp index 2071bc1108..e5619695bb 100644 --- a/icu4c/source/i18n/ucol_cnt.cpp +++ b/icu4c/source/i18n/ucol_cnt.cpp @@ -360,3 +360,36 @@ uint32_t uprv_cnttab_getCE(CntTable *table, uint32_t element, int32_t position, return tbl->CEs[position]; } } + +uint32_t uprv_cnttab_changeContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t newCE, UBool forward, UErrorCode *status) { + + element &= 0xFFFFFF; + ContractionTable *tbl = NULL; + + if(U_FAILURE(*status)) { + return 0; + } + + if((element == 0xFFFFFF) || (tbl = table->elements[element]) == NULL) { + return 0; + } + + if(forward == FALSE) { + tbl = tbl->reversed; + } + + int32_t position = 0; + + while(codePoint > tbl->codePoints[position]) { + position++; + if(position > tbl->position) { + return UCOL_NOT_FOUND; + } + } + if (codePoint == tbl->codePoints[position]) { + tbl->CEs[position] = newCE; + return element; + } else { + return UCOL_NOT_FOUND; + } +} diff --git a/icu4c/source/i18n/ucol_cnt.h b/icu4c/source/i18n/ucol_cnt.h index a9a47fdde1..92ae26116a 100644 --- a/icu4c/source/i18n/ucol_cnt.h +++ b/icu4c/source/i18n/ucol_cnt.h @@ -71,5 +71,6 @@ uint32_t uprv_cnttab_changeLastCE(CntTable *table, uint32_t element, uint32_t va uint32_t uprv_cnttab_findCP(CntTable *table, uint32_t element, UChar codePoint, UBool forward, UErrorCode *status); uint32_t uprv_cnttab_getCE(CntTable *table, uint32_t element, int32_t position, UBool forward, UErrorCode *status); +uint32_t uprv_cnttab_changeContraction(CntTable *table, uint32_t element, UChar codePoint, uint32_t newCE, UBool forward, UErrorCode *status); #endif diff --git a/icu4c/source/i18n/ucol_elm.cpp b/icu4c/source/i18n/ucol_elm.cpp index 4c1bd662ea..51693f7327 100644 --- a/icu4c/source/i18n/ucol_elm.cpp +++ b/icu4c/source/i18n/ucol_elm.cpp @@ -405,7 +405,13 @@ uint32_t uprv_uca_processContraction(CntTable *contractions, UCAElements *elemen /* end of recursion */ if(element->cSize == 1) { - return element->mapCE; + if(isContraction(existingCE)) { + uprv_cnttab_changeContraction(contractions, existingCE, 0, element->mapCE, forward, status); + uprv_cnttab_changeContraction(contractions, existingCE, 0xFFFF, element->mapCE, forward, status); + return existingCE; + } else { + return element->mapCE; /*can't do just that. existingCe might be a contraction, meaning that we need to do another step */ + } } /* this recursion currently feeds on the only element we have... We will have to copy it in order to accomodate */