-U_CAPI UColAttributeValue U_EXPORT2
-ucol_getAttributeOrDefault(const UCollator *coll, UColAttribute attr, UErrorCode *status)
-{
- if(U_FAILURE(*status) || coll == NULL) {
- return UCOL_DEFAULT;
- }
- switch(attr) {
- case UCOL_NUMERIC_COLLATION:
- return coll->numericCollationisDefault?UCOL_DEFAULT:coll->numericCollation;
- case UCOL_HIRAGANA_QUATERNARY_MODE:
- return coll->hiraganaQisDefault?UCOL_DEFAULT:coll->hiraganaQ;
- case UCOL_FRENCH_COLLATION: /* attribute for direction of secondary weights*/
- return coll->frenchCollationisDefault?UCOL_DEFAULT:coll->frenchCollation;
- case UCOL_ALTERNATE_HANDLING: /* attribute for handling variable elements*/
- return coll->alternateHandlingisDefault?UCOL_DEFAULT:coll->alternateHandling;
- case UCOL_CASE_FIRST: /* who goes first, lower case or uppercase */
- return coll->caseFirstisDefault?UCOL_DEFAULT:coll->caseFirst;
- case UCOL_CASE_LEVEL: /* do we have an extra case level */
- return coll->caseLevelisDefault?UCOL_DEFAULT:coll->caseLevel;
- case UCOL_NORMALIZATION_MODE: /* attribute for normalization */
- return coll->normalizationModeisDefault?UCOL_DEFAULT:coll->normalizationMode;
- case UCOL_STRENGTH: /* attribute for strength */
- return coll->strengthisDefault?UCOL_DEFAULT:coll->strength;
- case UCOL_ATTRIBUTE_COUNT:
- default:
- *status = U_ILLEGAL_ARGUMENT_ERROR;
-#ifdef UCOL_TRACE_SIT
- fprintf(stderr, "%s:%d: Unknown attr value '%d': %s\n", __FILE__, __LINE__, (int)attr, u_errorName(*status));
-#endif
- break;
- }
- return UCOL_DEFAULT;
-}
-
-
-struct contContext {
- const UCollator *coll;
- USet *conts;
- USet *expansions;
- USet *removedContractions;
- UBool addPrefixes;
- UErrorCode *status;
-};
-
-
-
-static void
-addSpecial(contContext *context, UChar *buffer, int32_t bufLen,
- uint32_t CE, int32_t leftIndex, int32_t rightIndex, UErrorCode *status)
-{
- const UCollator *coll = context->coll;
- USet *contractions = context->conts;
- USet *expansions = context->expansions;
- UBool addPrefixes = context->addPrefixes;
-
- const UChar *UCharOffset = (UChar *)coll->image+getContractOffset(CE);
- uint32_t newCE = *(coll->contractionCEs + (UCharOffset - coll->contractionIndex));
- // we might have a contraction that ends from previous level
- if(newCE != UCOL_NOT_FOUND) {
- if(isSpecial(CE) && getCETag(CE) == CONTRACTION_TAG && isSpecial(newCE) && getCETag(newCE) == SPEC_PROC_TAG && addPrefixes) {
- addSpecial(context, buffer, bufLen, newCE, leftIndex, rightIndex, status);
- }
- if(contractions && rightIndex-leftIndex > 1) {
- uset_addString(contractions, buffer+leftIndex, rightIndex-leftIndex);
- if(expansions && isSpecial(CE) && getCETag(CE) == EXPANSION_TAG) {
- uset_addString(expansions, buffer+leftIndex, rightIndex-leftIndex);
- }
- }
- }
-
- UCharOffset++;
- // check whether we're doing contraction or prefix
- if(getCETag(CE) == SPEC_PROC_TAG && addPrefixes) {
- if(leftIndex == 0) {
- *status = U_INTERNAL_PROGRAM_ERROR;
- return;
- }
- --leftIndex;
- while(*UCharOffset != 0xFFFF) {
- newCE = *(coll->contractionCEs + (UCharOffset - coll->contractionIndex));
- buffer[leftIndex] = *UCharOffset;
- if(isSpecial(newCE) && (getCETag(newCE) == CONTRACTION_TAG || getCETag(newCE) == SPEC_PROC_TAG)) {
- addSpecial(context, buffer, bufLen, newCE, leftIndex, rightIndex, status);
- } else {
- if(contractions) {
- uset_addString(contractions, buffer+leftIndex, rightIndex-leftIndex);
- }
- if(expansions && isSpecial(newCE) && getCETag(newCE) == EXPANSION_TAG) {
- uset_addString(expansions, buffer+leftIndex, rightIndex-leftIndex);
- }
- }
- UCharOffset++;
- }
- } else if(getCETag(CE) == CONTRACTION_TAG) {
- if(rightIndex == bufLen-1) {
- *status = U_INTERNAL_PROGRAM_ERROR;
- return;
- }
- while(*UCharOffset != 0xFFFF) {
- newCE = *(coll->contractionCEs + (UCharOffset - coll->contractionIndex));
- buffer[rightIndex] = *UCharOffset;
- if(isSpecial(newCE) && (getCETag(newCE) == CONTRACTION_TAG || getCETag(newCE) == SPEC_PROC_TAG)) {
- addSpecial(context, buffer, bufLen, newCE, leftIndex, rightIndex+1, status);
- } else {
- if(contractions) {
- uset_addString(contractions, buffer+leftIndex, rightIndex+1-leftIndex);
- }
- if(expansions && isSpecial(newCE) && getCETag(newCE) == EXPANSION_TAG) {
- uset_addString(expansions, buffer+leftIndex, rightIndex+1-leftIndex);
- }
- }
- UCharOffset++;
- }
- }
-
-}
-
-U_CDECL_BEGIN
-static UBool U_CALLCONV
-_processSpecials(const void *context, UChar32 start, UChar32 limit, uint32_t CE)
-{
- UErrorCode *status = ((contContext *)context)->status;
- USet *expansions = ((contContext *)context)->expansions;
- USet *removed = ((contContext *)context)->removedContractions;
- UBool addPrefixes = ((contContext *)context)->addPrefixes;
- UChar contraction[internalBufferSize];
- if(isSpecial(CE)) {
- if(((getCETag(CE) == SPEC_PROC_TAG && addPrefixes) || getCETag(CE) == CONTRACTION_TAG)) {
- while(start < limit && U_SUCCESS(*status)) {
- // if there are suppressed contractions, we don't
- // want to add them.
- if(removed && uset_contains(removed, start)) {
- start++;
- continue;
- }
- // we start our contraction from middle, since we don't know if it
- // will grow toward right or left
- contraction[internalBufferSize/2] = (UChar)start;
- addSpecial(((contContext *)context), contraction, internalBufferSize, CE, internalBufferSize/2, internalBufferSize/2+1, status);
- start++;
- }
- } else if(expansions && getCETag(CE) == EXPANSION_TAG) {
- while(start < limit && U_SUCCESS(*status)) {
- uset_add(expansions, start++);
- }
- }
- }
- if(U_FAILURE(*status)) {
- return FALSE;
- } else {
- return TRUE;
- }
-}
-
-U_CDECL_END
-
-
-