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