LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - ucol_sit.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 223 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : *   Copyright (C) 2004-2016, International Business Machines
       6             : *   Corporation and others.  All Rights Reserved.
       7             : *******************************************************************************
       8             : *   file name:  ucol_sit.cpp
       9             : *   encoding:   UTF-8
      10             : *   tab size:   8 (not used)
      11             : *   indentation:4
      12             : *
      13             : * Modification history
      14             : * Date        Name      Comments
      15             : * 03/12/2004  weiv      Creation
      16             : */
      17             : 
      18             : #include "unicode/ustring.h"
      19             : #include "unicode/udata.h"
      20             : #include "unicode/utf16.h"
      21             : #include "utracimp.h"
      22             : #include "ucol_imp.h"
      23             : #include "cmemory.h"
      24             : #include "cstring.h"
      25             : #include "uresimp.h"
      26             : #include "unicode/coll.h"
      27             : 
      28             : #ifdef UCOL_TRACE_SIT
      29             : # include <stdio.h>
      30             : #endif
      31             : 
      32             : #if !UCONFIG_NO_COLLATION
      33             : 
      34             : #include "unicode/tblcoll.h"
      35             : 
      36             : enum OptionsList {
      37             :     UCOL_SIT_LANGUAGE = 0,
      38             :     UCOL_SIT_SCRIPT   = 1,
      39             :     UCOL_SIT_REGION   = 2,
      40             :     UCOL_SIT_VARIANT  = 3,
      41             :     UCOL_SIT_KEYWORD  = 4,
      42             :     UCOL_SIT_PROVIDER = 5,
      43             :     UCOL_SIT_LOCELEMENT_MAX = UCOL_SIT_PROVIDER, /* the last element that's part of LocElements */
      44             : 
      45             :     UCOL_SIT_BCP47,
      46             :     UCOL_SIT_STRENGTH,
      47             :     UCOL_SIT_CASE_LEVEL,
      48             :     UCOL_SIT_CASE_FIRST,
      49             :     UCOL_SIT_NUMERIC_COLLATION,
      50             :     UCOL_SIT_ALTERNATE_HANDLING,
      51             :     UCOL_SIT_NORMALIZATION_MODE,
      52             :     UCOL_SIT_FRENCH_COLLATION,
      53             :     UCOL_SIT_HIRAGANA_QUATERNARY,
      54             :     UCOL_SIT_VARIABLE_TOP,
      55             :     UCOL_SIT_VARIABLE_TOP_VALUE,
      56             :     UCOL_SIT_ITEMS_COUNT
      57             : };
      58             : 
      59             : /* option starters chars. */
      60             : static const char alternateHArg     = 'A';
      61             : static const char variableTopValArg = 'B';
      62             : static const char caseFirstArg      = 'C';
      63             : static const char numericCollArg    = 'D';
      64             : static const char caseLevelArg      = 'E';
      65             : static const char frenchCollArg     = 'F';
      66             : static const char hiraganaQArg      = 'H';
      67             : static const char keywordArg        = 'K';
      68             : static const char languageArg       = 'L';
      69             : static const char normArg           = 'N';
      70             : static const char providerArg       = 'P';
      71             : static const char regionArg         = 'R';
      72             : static const char strengthArg       = 'S';
      73             : static const char variableTopArg    = 'T';
      74             : static const char variantArg        = 'V';
      75             : static const char RFC3066Arg        = 'X';
      76             : static const char scriptArg         = 'Z';
      77             : 
      78             : static const char collationKeyword[]  = "@collation=";
      79             : static const char providerKeyword[]  = "@sp=";
      80             : 
      81             : 
      82             : static const int32_t locElementCount = UCOL_SIT_LOCELEMENT_MAX+1;
      83             : static const int32_t locElementCapacity = 32;
      84             : static const int32_t loc3066Capacity = 256;
      85             : static const int32_t locProviderCapacity = 10;
      86             : static const int32_t internalBufferSize = 512;
      87             : 
      88             : /* structure containing specification of a collator. Initialized
      89             :  * from a short string. Also used to construct a short string from a
      90             :  * collator instance
      91             :  */
      92             : struct CollatorSpec {
      93             :     char locElements[locElementCount][locElementCapacity];
      94             :     char locale[loc3066Capacity];
      95             :     char provider[locProviderCapacity];
      96             :     UColAttributeValue options[UCOL_ATTRIBUTE_COUNT];
      97             :     uint32_t variableTopValue;
      98             :     UChar variableTopString[locElementCapacity];
      99             :     int32_t variableTopStringLen;
     100             :     UBool variableTopSet;
     101             :     struct {
     102             :         const char *start;
     103             :         int32_t len;
     104             :     } entries[UCOL_SIT_ITEMS_COUNT];
     105             : };
     106             : 
     107             : 
     108             : /* structure for converting between character attribute
     109             :  * representation and real collation attribute value.
     110             :  */
     111             : struct AttributeConversion {
     112             :     char letter;
     113             :     UColAttributeValue value;
     114             : };
     115             : 
     116             : static const AttributeConversion conversions[12] = {
     117             :     { '1', UCOL_PRIMARY },
     118             :     { '2', UCOL_SECONDARY },
     119             :     { '3', UCOL_TERTIARY },
     120             :     { '4', UCOL_QUATERNARY },
     121             :     { 'D', UCOL_DEFAULT },
     122             :     { 'I', UCOL_IDENTICAL },
     123             :     { 'L', UCOL_LOWER_FIRST },
     124             :     { 'N', UCOL_NON_IGNORABLE },
     125             :     { 'O', UCOL_ON },
     126             :     { 'S', UCOL_SHIFTED },
     127             :     { 'U', UCOL_UPPER_FIRST },
     128             :     { 'X', UCOL_OFF }
     129             : };
     130             : 
     131             : 
     132             : static UColAttributeValue
     133           0 : ucol_sit_letterToAttributeValue(char letter, UErrorCode *status) {
     134           0 :     uint32_t i = 0;
     135           0 :     for(i = 0; i < UPRV_LENGTHOF(conversions); i++) {
     136           0 :         if(conversions[i].letter == letter) {
     137           0 :             return conversions[i].value;
     138             :         }
     139             :     }
     140           0 :     *status = U_ILLEGAL_ARGUMENT_ERROR;
     141             : #ifdef UCOL_TRACE_SIT
     142             :     fprintf(stderr, "%s:%d: unknown letter %c: %s\n", __FILE__, __LINE__, letter, u_errorName(*status));
     143             : #endif    
     144           0 :     return UCOL_DEFAULT;
     145             : }
     146             : 
     147             : /* function prototype for functions used to parse a short string */
     148             : U_CDECL_BEGIN
     149             : typedef const char* U_CALLCONV
     150             : ActionFunction(CollatorSpec *spec, uint32_t value1, const char* string,
     151             :                UErrorCode *status);
     152             : U_CDECL_END
     153             : 
     154             : U_CDECL_BEGIN
     155             : static const char* U_CALLCONV
     156           0 : _processLocaleElement(CollatorSpec *spec, uint32_t value, const char* string,
     157             :                       UErrorCode *status)
     158             : {
     159           0 :     int32_t len = 0;
     160           0 :     do {
     161           0 :         if(value == UCOL_SIT_LANGUAGE || value == UCOL_SIT_KEYWORD || value == UCOL_SIT_PROVIDER) {
     162           0 :             spec->locElements[value][len++] = uprv_tolower(*string);
     163             :         } else {
     164           0 :             spec->locElements[value][len++] = *string;
     165             :         }
     166           0 :     } while(*(++string) != '_' && *string && len < locElementCapacity);
     167           0 :     if(len >= locElementCapacity) {
     168           0 :         *status = U_BUFFER_OVERFLOW_ERROR;
     169           0 :         return string;
     170             :     }
     171             :     // don't skip the underscore at the end
     172           0 :     return string;
     173             : }
     174             : U_CDECL_END
     175             : 
     176             : U_CDECL_BEGIN
     177             : static const char* U_CALLCONV
     178           0 : _processRFC3066Locale(CollatorSpec *spec, uint32_t, const char* string,
     179             :                       UErrorCode *status)
     180             : {
     181           0 :     char terminator = *string;
     182           0 :     string++;
     183           0 :     const char *end = uprv_strchr(string+1, terminator);
     184           0 :     if(end == NULL || end - string >= loc3066Capacity) {
     185           0 :         *status = U_BUFFER_OVERFLOW_ERROR;
     186           0 :         return string;
     187             :     } else {
     188           0 :         uprv_strncpy(spec->locale, string, end-string);
     189           0 :         return end+1;
     190             :     }
     191             : }
     192             : 
     193             : U_CDECL_END
     194             : 
     195             : U_CDECL_BEGIN
     196             : static const char* U_CALLCONV
     197           0 : _processCollatorOption(CollatorSpec *spec, uint32_t option, const char* string,
     198             :                        UErrorCode *status)
     199             : {
     200           0 :     spec->options[option] = ucol_sit_letterToAttributeValue(*string, status);
     201           0 :     if((*(++string) != '_' && *string) || U_FAILURE(*status)) {
     202             : #ifdef UCOL_TRACE_SIT
     203             :     fprintf(stderr, "%s:%d: unknown collator option at '%s': %s\n", __FILE__, __LINE__, string, u_errorName(*status));
     204             : #endif    
     205           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     206             :     }
     207           0 :     return string;
     208             : }
     209             : U_CDECL_END
     210             : 
     211             : 
     212             : static UChar
     213           0 : readHexCodeUnit(const char **string, UErrorCode *status)
     214             : {
     215           0 :     UChar result = 0;
     216           0 :     int32_t value = 0;
     217             :     char c;
     218           0 :     int32_t noDigits = 0;
     219           0 :     while((c = **string) != 0 && noDigits < 4) {
     220           0 :         if( c >= '0' && c <= '9') {
     221           0 :             value = c - '0';
     222           0 :         } else if ( c >= 'a' && c <= 'f') {
     223           0 :             value = c - 'a' + 10;
     224           0 :         } else if ( c >= 'A' && c <= 'F') {
     225           0 :             value = c - 'A' + 10;
     226             :         } else {
     227           0 :             *status = U_ILLEGAL_ARGUMENT_ERROR;
     228             : #ifdef UCOL_TRACE_SIT
     229             :             fprintf(stderr, "%s:%d: Bad hex char at '%s': %s\n", __FILE__, __LINE__, *string, u_errorName(*status));
     230             : #endif    
     231           0 :             return 0;
     232             :         }
     233           0 :         result = (result << 4) | (UChar)value;
     234           0 :         noDigits++;
     235           0 :         (*string)++;
     236             :     }
     237             :     // if the string was terminated before we read 4 digits, set an error
     238           0 :     if(noDigits < 4) {
     239           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     240             : #ifdef UCOL_TRACE_SIT
     241             :         fprintf(stderr, "%s:%d: Short (only %d digits, wanted 4) at '%s': %s\n", __FILE__, __LINE__, noDigits,*string, u_errorName(*status));
     242             : #endif    
     243             :     }
     244           0 :     return result;
     245             : }
     246             : 
     247             : U_CDECL_BEGIN
     248             : static const char* U_CALLCONV
     249           0 : _processVariableTop(CollatorSpec *spec, uint32_t value1, const char* string, UErrorCode *status)
     250             : {
     251             :     // get four digits
     252           0 :     int32_t i = 0;
     253           0 :     if(!value1) {
     254           0 :         while(U_SUCCESS(*status) && i < locElementCapacity && *string != 0 && *string != '_') {
     255           0 :             spec->variableTopString[i++] = readHexCodeUnit(&string, status);
     256             :         }
     257           0 :         spec->variableTopStringLen = i;
     258           0 :         if(i == locElementCapacity && *string != 0 && *string != '_') {
     259           0 :             *status = U_BUFFER_OVERFLOW_ERROR;
     260             :         }
     261             :     } else {
     262           0 :         spec->variableTopValue = readHexCodeUnit(&string, status);
     263             :     }
     264           0 :     if(U_SUCCESS(*status)) {
     265           0 :         spec->variableTopSet = TRUE;
     266             :     }
     267           0 :     return string;
     268             : }
     269             : U_CDECL_END
     270             : 
     271             : 
     272             : /* Table for parsing short strings */
     273             : struct ShortStringOptions {
     274             :     char optionStart;
     275             :     ActionFunction *action;
     276             :     uint32_t attr;
     277             : };
     278             : 
     279             : static const ShortStringOptions options[UCOL_SIT_ITEMS_COUNT] =
     280             : {
     281             : /* 10 ALTERNATE_HANDLING */   {alternateHArg,     _processCollatorOption, UCOL_ALTERNATE_HANDLING }, // alternate  N, S, D
     282             : /* 15 VARIABLE_TOP_VALUE */   {variableTopValArg, _processVariableTop,    1 },
     283             : /* 08 CASE_FIRST */           {caseFirstArg,      _processCollatorOption, UCOL_CASE_FIRST }, // case first L, U, X, D
     284             : /* 09 NUMERIC_COLLATION */    {numericCollArg,    _processCollatorOption, UCOL_NUMERIC_COLLATION }, // codan      O, X, D
     285             : /* 07 CASE_LEVEL */           {caseLevelArg,      _processCollatorOption, UCOL_CASE_LEVEL }, // case level O, X, D
     286             : /* 12 FRENCH_COLLATION */     {frenchCollArg,     _processCollatorOption, UCOL_FRENCH_COLLATION }, // french     O, X, D
     287             : /* 13 HIRAGANA_QUATERNARY] */ {hiraganaQArg,      _processCollatorOption, UCOL_HIRAGANA_QUATERNARY_MODE }, // hiragana   O, X, D
     288             : /* 04 KEYWORD */              {keywordArg,        _processLocaleElement,  UCOL_SIT_KEYWORD }, // keyword
     289             : /* 00 LANGUAGE */             {languageArg,       _processLocaleElement,  UCOL_SIT_LANGUAGE }, // language
     290             : /* 11 NORMALIZATION_MODE */   {normArg,           _processCollatorOption, UCOL_NORMALIZATION_MODE }, // norm       O, X, D
     291             : /* 02 REGION */               {regionArg,         _processLocaleElement,  UCOL_SIT_REGION }, // region
     292             : /* 06 STRENGTH */             {strengthArg,       _processCollatorOption, UCOL_STRENGTH }, // strength   1, 2, 3, 4, I, D
     293             : /* 14 VARIABLE_TOP */         {variableTopArg,    _processVariableTop,    0 },
     294             : /* 03 VARIANT */              {variantArg,        _processLocaleElement,  UCOL_SIT_VARIANT }, // variant
     295             : /* 05 RFC3066BIS */           {RFC3066Arg,        _processRFC3066Locale,  0 }, // rfc3066bis locale name
     296             : /* 01 SCRIPT */               {scriptArg,         _processLocaleElement,  UCOL_SIT_SCRIPT },  // script
     297             : /*    PROVIDER */             {providerArg,       _processLocaleElement, UCOL_SIT_PROVIDER }
     298             : };
     299             : 
     300             : 
     301             : static
     302           0 : const char* ucol_sit_readOption(const char *start, CollatorSpec *spec,
     303             :                             UErrorCode *status)
     304             : {
     305           0 :   int32_t i = 0;
     306             : 
     307           0 :   for(i = 0; i < UCOL_SIT_ITEMS_COUNT; i++) {
     308           0 :       if(*start == options[i].optionStart) {
     309           0 :           spec->entries[i].start = start;
     310           0 :           const char* end = options[i].action(spec, options[i].attr, start+1, status);
     311           0 :           spec->entries[i].len = (int32_t)(end - start);
     312           0 :           return end;
     313             :       }
     314             :   }
     315           0 :   *status = U_ILLEGAL_ARGUMENT_ERROR;
     316             : #ifdef UCOL_TRACE_SIT
     317             :   fprintf(stderr, "%s:%d: Unknown option at '%s': %s\n", __FILE__, __LINE__, start, u_errorName(*status));
     318             : #endif
     319           0 :   return start;
     320             : }
     321             : 
     322             : static
     323           0 : void ucol_sit_initCollatorSpecs(CollatorSpec *spec)
     324             : {
     325             :     // reset everything
     326           0 :     uprv_memset(spec, 0, sizeof(CollatorSpec));
     327             :     // set collation options to default
     328           0 :     int32_t i = 0;
     329           0 :     for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {
     330           0 :         spec->options[i] = UCOL_DEFAULT;
     331             :     }
     332           0 : }
     333             : 
     334             : static const char*
     335           0 : ucol_sit_readSpecs(CollatorSpec *s, const char *string,
     336             :                         UParseError *parseError, UErrorCode *status)
     337             : {
     338           0 :     const char *definition = string;
     339           0 :     while(U_SUCCESS(*status) && *string) {
     340           0 :         string = ucol_sit_readOption(string, s, status);
     341             :         // advance over '_'
     342           0 :         while(*string && *string == '_') {
     343           0 :             string++;
     344             :         }
     345             :     }
     346           0 :     if(U_FAILURE(*status)) {
     347           0 :         parseError->offset = (int32_t)(string - definition);
     348             :     }
     349           0 :     return string;
     350             : }
     351             : 
     352             : static
     353           0 : int32_t ucol_sit_dumpSpecs(CollatorSpec *s, char *destination, int32_t capacity, UErrorCode *status)
     354             : {
     355           0 :     int32_t i = 0, j = 0;
     356           0 :     int32_t len = 0;
     357             :     char optName;
     358           0 :     if(U_SUCCESS(*status)) {
     359           0 :         for(i = 0; i < UCOL_SIT_ITEMS_COUNT; i++) {
     360           0 :             if(s->entries[i].start) {
     361           0 :                 if(len) {
     362           0 :                     if(len < capacity) {
     363           0 :                         uprv_strcat(destination, "_");
     364             :                     }
     365           0 :                     len++;
     366             :                 }
     367           0 :                 optName = *(s->entries[i].start);
     368           0 :                 if(optName == languageArg || optName == regionArg || optName == variantArg || optName == keywordArg) {
     369           0 :                     for(j = 0; j < s->entries[i].len; j++) {
     370           0 :                         if(len + j < capacity) {
     371           0 :                             destination[len+j] = uprv_toupper(*(s->entries[i].start+j));
     372             :                         }
     373             :                     }
     374           0 :                     len += s->entries[i].len;
     375             :                 } else {
     376           0 :                     len += s->entries[i].len;
     377           0 :                     if(len < capacity) {
     378           0 :                         uprv_strncat(destination,s->entries[i].start, s->entries[i].len);
     379             :                     }
     380             :                 }
     381             :             }
     382             :         }
     383           0 :         return len;
     384             :     } else {
     385           0 :         return 0;
     386             :     }
     387             : }
     388             : 
     389             : static void
     390           0 : ucol_sit_calculateWholeLocale(CollatorSpec *s) {
     391             :     // put the locale together, unless we have a done
     392             :     // locale
     393           0 :     if(s->locale[0] == 0) {
     394             :         // first the language
     395           0 :         uprv_strcat(s->locale, s->locElements[UCOL_SIT_LANGUAGE]);
     396             :         // then the script, if present
     397           0 :         if(*(s->locElements[UCOL_SIT_SCRIPT])) {
     398           0 :             uprv_strcat(s->locale, "_");
     399           0 :             uprv_strcat(s->locale, s->locElements[UCOL_SIT_SCRIPT]);
     400             :         }
     401             :         // then the region, if present
     402           0 :         if(*(s->locElements[UCOL_SIT_REGION])) {
     403           0 :             uprv_strcat(s->locale, "_");
     404           0 :             uprv_strcat(s->locale, s->locElements[UCOL_SIT_REGION]);
     405           0 :         } else if(*(s->locElements[UCOL_SIT_VARIANT])) { // if there is a variant, we need an underscore
     406           0 :             uprv_strcat(s->locale, "_");
     407             :         }
     408             :         // add variant, if there
     409           0 :         if(*(s->locElements[UCOL_SIT_VARIANT])) {
     410           0 :             uprv_strcat(s->locale, "_");
     411           0 :             uprv_strcat(s->locale, s->locElements[UCOL_SIT_VARIANT]);
     412             :         }
     413             : 
     414             :         // if there is a collation keyword, add that too
     415           0 :         if(*(s->locElements[UCOL_SIT_KEYWORD])) {
     416           0 :             uprv_strcat(s->locale, collationKeyword);
     417           0 :             uprv_strcat(s->locale, s->locElements[UCOL_SIT_KEYWORD]);
     418             :         }
     419             : 
     420             :         // if there is a provider keyword, add that too
     421           0 :         if(*(s->locElements[UCOL_SIT_PROVIDER])) {
     422           0 :             uprv_strcat(s->locale, providerKeyword);
     423           0 :             uprv_strcat(s->locale, s->locElements[UCOL_SIT_PROVIDER]);
     424             :         }
     425             :     }
     426           0 : }
     427             : 
     428             : 
     429             : U_CAPI void U_EXPORT2
     430           0 : ucol_prepareShortStringOpen( const char *definition,
     431             :                           UBool,
     432             :                           UParseError *parseError,
     433             :                           UErrorCode *status)
     434             : {
     435           0 :     if(U_FAILURE(*status)) return;
     436             : 
     437             :     UParseError internalParseError;
     438             : 
     439           0 :     if(!parseError) {
     440           0 :         parseError = &internalParseError;
     441             :     }
     442           0 :     parseError->line = 0;
     443           0 :     parseError->offset = 0;
     444           0 :     parseError->preContext[0] = 0;
     445           0 :     parseError->postContext[0] = 0;
     446             : 
     447             : 
     448             :     // first we want to pick stuff out of short string.
     449             :     // we'll end up with an UCA version, locale and a bunch of
     450             :     // settings
     451             : 
     452             :     // analyse the string in order to get everything we need.
     453             :     CollatorSpec s;
     454           0 :     ucol_sit_initCollatorSpecs(&s);
     455           0 :     ucol_sit_readSpecs(&s, definition, parseError, status);
     456           0 :     ucol_sit_calculateWholeLocale(&s);
     457             : 
     458             :     char buffer[internalBufferSize];
     459           0 :     uprv_memset(buffer, 0, internalBufferSize);
     460           0 :     uloc_canonicalize(s.locale, buffer, internalBufferSize, status);
     461             : 
     462           0 :     UResourceBundle *b = ures_open(U_ICUDATA_COLL, buffer, status);
     463             :     /* we try to find stuff from keyword */
     464           0 :     UResourceBundle *collations = ures_getByKey(b, "collations", NULL, status);
     465           0 :     UResourceBundle *collElem = NULL;
     466             :     char keyBuffer[256];
     467             :     // if there is a keyword, we pick it up and try to get elements
     468           0 :     if(!uloc_getKeywordValue(buffer, "collation", keyBuffer, 256, status)) {
     469             :       // no keyword. we try to find the default setting, which will give us the keyword value
     470           0 :       UResourceBundle *defaultColl = ures_getByKeyWithFallback(collations, "default", NULL, status);
     471           0 :       if(U_SUCCESS(*status)) {
     472           0 :         int32_t defaultKeyLen = 0;
     473           0 :         const UChar *defaultKey = ures_getString(defaultColl, &defaultKeyLen, status);
     474           0 :         u_UCharsToChars(defaultKey, keyBuffer, defaultKeyLen);
     475           0 :         keyBuffer[defaultKeyLen] = 0;
     476             :       } else {
     477           0 :         *status = U_INTERNAL_PROGRAM_ERROR;
     478           0 :         return;
     479             :       }
     480           0 :       ures_close(defaultColl);
     481             :     }
     482           0 :     collElem = ures_getByKeyWithFallback(collations, keyBuffer, collElem, status);
     483           0 :     ures_close(collElem);
     484           0 :     ures_close(collations);
     485           0 :     ures_close(b);
     486             : }
     487             : 
     488             : 
     489             : U_CAPI UCollator* U_EXPORT2
     490           0 : ucol_openFromShortString( const char *definition,
     491             :                           UBool forceDefaults,
     492             :                           UParseError *parseError,
     493             :                           UErrorCode *status)
     494             : {
     495             :     UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN_FROM_SHORT_STRING);
     496             :     UTRACE_DATA1(UTRACE_INFO, "short string = \"%s\"", definition);
     497             : 
     498           0 :     if(U_FAILURE(*status)) return 0;
     499             : 
     500             :     UParseError internalParseError;
     501             : 
     502           0 :     if(!parseError) {
     503           0 :         parseError = &internalParseError;
     504             :     }
     505           0 :     parseError->line = 0;
     506           0 :     parseError->offset = 0;
     507           0 :     parseError->preContext[0] = 0;
     508           0 :     parseError->postContext[0] = 0;
     509             : 
     510             : 
     511             :     // first we want to pick stuff out of short string.
     512             :     // we'll end up with an UCA version, locale and a bunch of
     513             :     // settings
     514             : 
     515             :     // analyse the string in order to get everything we need.
     516           0 :     const char *string = definition;
     517             :     CollatorSpec s;
     518           0 :     ucol_sit_initCollatorSpecs(&s);
     519           0 :     string = ucol_sit_readSpecs(&s, definition, parseError, status);
     520           0 :     ucol_sit_calculateWholeLocale(&s);
     521             : 
     522             :     char buffer[internalBufferSize];
     523           0 :     uprv_memset(buffer, 0, internalBufferSize);
     524           0 :     uloc_canonicalize(s.locale, buffer, internalBufferSize, status);
     525             : 
     526           0 :     UCollator *result = ucol_open(buffer, status);
     527           0 :     int32_t i = 0;
     528             : 
     529           0 :     for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {
     530           0 :         if(s.options[i] != UCOL_DEFAULT) {
     531           0 :             if(forceDefaults || ucol_getAttribute(result, (UColAttribute)i, status) != s.options[i]) {
     532           0 :                 ucol_setAttribute(result, (UColAttribute)i, s.options[i], status);
     533             :             }
     534             : 
     535           0 :             if(U_FAILURE(*status)) {
     536           0 :                 parseError->offset = (int32_t)(string - definition);
     537           0 :                 ucol_close(result);
     538           0 :                 return NULL;
     539             :             }
     540             : 
     541             :         }
     542             :     }
     543           0 :     if(s.variableTopSet) {
     544           0 :         if(s.variableTopString[0]) {
     545           0 :             ucol_setVariableTop(result, s.variableTopString, s.variableTopStringLen, status);
     546             :         } else { // we set by value, using 'B'
     547           0 :             ucol_restoreVariableTop(result, s.variableTopValue, status);
     548             :         }
     549             :     }
     550             : 
     551             : 
     552           0 :     if(U_FAILURE(*status)) { // here it can only be a bogus value
     553           0 :         ucol_close(result);
     554           0 :         result = NULL;
     555             :     }
     556             : 
     557             :     UTRACE_EXIT_PTR_STATUS(result, *status);
     558           0 :     return result;
     559             : }
     560             : 
     561             : 
     562             : U_CAPI int32_t U_EXPORT2
     563           0 : ucol_getShortDefinitionString(const UCollator *coll,
     564             :                               const char *locale,
     565             :                               char *dst,
     566             :                               int32_t capacity,
     567             :                               UErrorCode *status)
     568             : {
     569           0 :     if(U_FAILURE(*status)) return 0;
     570           0 :     if(coll == NULL) {
     571           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     572           0 :         return 0;
     573             :     }
     574           0 :     return ((icu::Collator*)coll)->internalGetShortDefinitionString(locale,dst,capacity,*status);
     575             : }
     576             : 
     577             : U_CAPI int32_t U_EXPORT2
     578           0 : ucol_normalizeShortDefinitionString(const char *definition,
     579             :                                     char *destination,
     580             :                                     int32_t capacity,
     581             :                                     UParseError *parseError,
     582             :                                     UErrorCode *status)
     583             : {
     584             : 
     585           0 :     if(U_FAILURE(*status)) {
     586           0 :         return 0;
     587             :     }
     588             : 
     589           0 :     if(destination) {
     590           0 :         uprv_memset(destination, 0, capacity*sizeof(char));
     591             :     }
     592             : 
     593             :     UParseError pe;
     594           0 :     if(!parseError) {
     595           0 :         parseError = &pe;
     596             :     }
     597             : 
     598             :     // validate
     599             :     CollatorSpec s;
     600           0 :     ucol_sit_initCollatorSpecs(&s);
     601           0 :     ucol_sit_readSpecs(&s, definition, parseError, status);
     602           0 :     return ucol_sit_dumpSpecs(&s, destination, capacity, status);
     603             : }
     604             : 
     605             : /**
     606             :  * Get a set containing the contractions defined by the collator. The set includes
     607             :  * both the UCA contractions and the contractions defined by the collator
     608             :  * @param coll collator
     609             :  * @param conts the set to hold the result
     610             :  * @param status to hold the error code
     611             :  * @return the size of the contraction set
     612             :  */
     613             : U_CAPI int32_t U_EXPORT2
     614           0 : ucol_getContractions( const UCollator *coll,
     615             :                   USet *contractions,
     616             :                   UErrorCode *status)
     617             : {
     618           0 :   ucol_getContractionsAndExpansions(coll, contractions, NULL, FALSE, status);
     619           0 :   return uset_getItemCount(contractions);
     620             : }
     621             : 
     622             : /**
     623             :  * Get a set containing the expansions defined by the collator. The set includes
     624             :  * both the UCA expansions and the expansions defined by the tailoring
     625             :  * @param coll collator
     626             :  * @param conts the set to hold the result
     627             :  * @param addPrefixes add the prefix contextual elements to contractions
     628             :  * @param status to hold the error code
     629             :  *
     630             :  * @draft ICU 3.4
     631             :  */
     632             : U_CAPI void U_EXPORT2
     633           0 : ucol_getContractionsAndExpansions( const UCollator *coll,
     634             :                   USet *contractions,
     635             :                   USet *expansions,
     636             :                   UBool addPrefixes,
     637             :                   UErrorCode *status)
     638             : {
     639           0 :     if(U_FAILURE(*status)) {
     640           0 :         return;
     641             :     }
     642           0 :     if(coll == NULL) {
     643           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     644           0 :         return;
     645             :     }
     646           0 :     const icu::RuleBasedCollator *rbc = icu::RuleBasedCollator::rbcFromUCollator(coll);
     647           0 :     if(rbc == NULL) {
     648           0 :         *status = U_UNSUPPORTED_ERROR;
     649           0 :         return;
     650             :     }
     651           0 :     rbc->internalGetContractionsAndExpansions(
     652             :             icu::UnicodeSet::fromUSet(contractions),
     653             :             icu::UnicodeSet::fromUSet(expansions),
     654           0 :             addPrefixes, *status);
     655             : }
     656             : #endif

Generated by: LCOV version 1.13