Bug Summary

File:out/../deps/icu-small/source/i18n/ucol_sit.cpp
Warning:line 362, column 25
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ucol_sit.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D U_COMMON_IMPLEMENTATION=1 -D U_I18N_IMPLEMENTATION=1 -D U_IO_IMPLEMENTATION=1 -D U_TOOLUTIL_IMPLEMENTATION=1 -D U_ATTRIBUTE_DEPRECATED= -D _CRT_SECURE_NO_DEPRECATE= -D U_STATIC_IMPLEMENTATION=1 -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/icu-small/source/common -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/tools/toolutil -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-deprecated-declarations -Wno-strict-aliasing -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/icu-small/source/i18n/ucol_sit.cpp
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#include "unicode/stringpiece.h"
28#include "charstr.h"
29
30U_NAMESPACE_USEusing namespace icu_71;
31
32#ifdef UCOL_TRACE_SIT
33# include <stdio.h>
34#endif
35
36#if !UCONFIG_NO_COLLATION0
37
38#include "unicode/tblcoll.h"
39
40enum OptionsList {
41 UCOL_SIT_LANGUAGE = 0,
42 UCOL_SIT_SCRIPT = 1,
43 UCOL_SIT_REGION = 2,
44 UCOL_SIT_VARIANT = 3,
45 UCOL_SIT_KEYWORD = 4,
46 UCOL_SIT_PROVIDER = 5,
47 UCOL_SIT_LOCELEMENT_MAX = UCOL_SIT_PROVIDER, /* the last element that's part of LocElements */
48
49 UCOL_SIT_BCP47,
50 UCOL_SIT_STRENGTH,
51 UCOL_SIT_CASE_LEVEL,
52 UCOL_SIT_CASE_FIRST,
53 UCOL_SIT_NUMERIC_COLLATION,
54 UCOL_SIT_ALTERNATE_HANDLING,
55 UCOL_SIT_NORMALIZATION_MODE,
56 UCOL_SIT_FRENCH_COLLATION,
57 UCOL_SIT_HIRAGANA_QUATERNARY,
58 UCOL_SIT_VARIABLE_TOP,
59 UCOL_SIT_VARIABLE_TOP_VALUE,
60 UCOL_SIT_ITEMS_COUNT
61};
62
63/* option starters chars. */
64static const char alternateHArg = 'A';
65static const char variableTopValArg = 'B';
66static const char caseFirstArg = 'C';
67static const char numericCollArg = 'D';
68static const char caseLevelArg = 'E';
69static const char frenchCollArg = 'F';
70static const char hiraganaQArg = 'H';
71static const char keywordArg = 'K';
72static const char languageArg = 'L';
73static const char normArg = 'N';
74static const char providerArg = 'P';
75static const char regionArg = 'R';
76static const char strengthArg = 'S';
77static const char variableTopArg = 'T';
78static const char variantArg = 'V';
79static const char RFC3066Arg = 'X';
80static const char scriptArg = 'Z';
81
82static const char collationKeyword[] = "@collation=";
83static const char providerKeyword[] = "@sp=";
84
85
86static const int32_t locElementCount = UCOL_SIT_LOCELEMENT_MAX+1;
87static const int32_t locElementCapacity = 32;
88static const int32_t loc3066Capacity = 256;
89static const int32_t internalBufferSize = 512;
90
91/* structure containing specification of a collator. Initialized
92 * from a short string. Also used to construct a short string from a
93 * collator instance
94 */
95struct CollatorSpec {
96 inline CollatorSpec();
97
98 CharString locElements[locElementCount];
99 CharString locale;
100 UColAttributeValue options[UCOL_ATTRIBUTE_COUNT];
101 uint32_t variableTopValue;
102 UChar variableTopString[locElementCapacity];
103 int32_t variableTopStringLen;
104 UBool variableTopSet;
105 CharString entries[UCOL_SIT_ITEMS_COUNT];
106};
107
108CollatorSpec::CollatorSpec() :
109locale(),
110variableTopValue(0),
111variableTopString(),
112variableTopSet(FALSE0)
113 {
114 // set collation options to default
115 for(int32_t i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {
116 options[i] = UCOL_DEFAULT;
117 }
118}
119
120
121/* structure for converting between character attribute
122 * representation and real collation attribute value.
123 */
124struct AttributeConversion {
125 char letter;
126 UColAttributeValue value;
127};
128
129static const AttributeConversion conversions[12] = {
130 { '1', UCOL_PRIMARY },
131 { '2', UCOL_SECONDARY },
132 { '3', UCOL_TERTIARY },
133 { '4', UCOL_QUATERNARY },
134 { 'D', UCOL_DEFAULT },
135 { 'I', UCOL_IDENTICAL },
136 { 'L', UCOL_LOWER_FIRST },
137 { 'N', UCOL_NON_IGNORABLE },
138 { 'O', UCOL_ON },
139 { 'S', UCOL_SHIFTED },
140 { 'U', UCOL_UPPER_FIRST },
141 { 'X', UCOL_OFF }
142};
143
144
145static UColAttributeValue
146ucol_sit_letterToAttributeValue(char letter, UErrorCode *status) {
147 uint32_t i = 0;
148 for(i = 0; i < UPRV_LENGTHOF(conversions)(int32_t)(sizeof(conversions)/sizeof((conversions)[0])); i++) {
149 if(conversions[i].letter == letter) {
150 return conversions[i].value;
151 }
152 }
153 *status = U_ILLEGAL_ARGUMENT_ERROR;
154#ifdef UCOL_TRACE_SIT
155 fprintf(stderrstderr, "%s:%d: unknown letter %c: %s\n", __FILE__"../deps/icu-small/source/i18n/ucol_sit.cpp", __LINE__155, letter, u_errorNameu_errorName_71(*status));
156#endif
157 return UCOL_DEFAULT;
158}
159
160/* function prototype for functions used to parse a short string */
161U_CDECL_BEGINextern "C" {
162typedef const char* U_CALLCONV
163ActionFunction(CollatorSpec *spec, uint32_t value1, const char* string,
164 UErrorCode *status);
165U_CDECL_END}
166
167U_CDECL_BEGINextern "C" {
168static const char* U_CALLCONV
169_processLocaleElement(CollatorSpec *spec, uint32_t value, const char* string,
170 UErrorCode *status)
171{
172 do {
173 if(value == UCOL_SIT_LANGUAGE || value == UCOL_SIT_KEYWORD || value == UCOL_SIT_PROVIDER) {
174 spec->locElements[value].append(uprv_toloweruprv_asciitolower_71(*string), *status);
175 } else {
176 spec->locElements[value].append(*string, *status);
177 }
178 } while(*(++string) != '_' && *string && U_SUCCESS(*status));
179 // don't skip the underscore at the end
180 return string;
181}
182U_CDECL_END}
183
184U_CDECL_BEGINextern "C" {
185static const char* U_CALLCONV
186_processRFC3066Locale(CollatorSpec *spec, uint32_t, const char* string,
187 UErrorCode *status)
188{
189 char terminator = *string;
190 string++;
191 const char *end = uprv_strchr(string+1, terminator):: strchr(string+1, terminator);
192 if(end == NULL__null || end - string >= loc3066Capacity) {
193 *status = U_BUFFER_OVERFLOW_ERROR;
194 return string;
195 } else {
196 spec->locale.copyFrom(CharString(string, static_cast<int32_t>(end-string), *status), *status);
197 return end+1;
198 }
199}
200
201U_CDECL_END}
202
203U_CDECL_BEGINextern "C" {
204static const char* U_CALLCONV
205_processCollatorOption(CollatorSpec *spec, uint32_t option, const char* string,
206 UErrorCode *status)
207{
208 spec->options[option] = ucol_sit_letterToAttributeValue(*string, status);
209 if((*(++string) != '_' && *string) || U_FAILURE(*status)) {
210#ifdef UCOL_TRACE_SIT
211 fprintf(stderrstderr, "%s:%d: unknown collator option at '%s': %s\n", __FILE__"../deps/icu-small/source/i18n/ucol_sit.cpp", __LINE__211, string, u_errorNameu_errorName_71(*status));
212#endif
213 *status = U_ILLEGAL_ARGUMENT_ERROR;
214 }
215 return string;
216}
217U_CDECL_END}
218
219
220static UChar
221readHexCodeUnit(const char **string, UErrorCode *status)
222{
223 UChar result = 0;
224 int32_t value = 0;
225 char c;
226 int32_t noDigits = 0;
227 while((c = **string) != 0 && noDigits < 4) {
228 if( c >= '0' && c <= '9') {
229 value = c - '0';
230 } else if ( c >= 'a' && c <= 'f') {
231 value = c - 'a' + 10;
232 } else if ( c >= 'A' && c <= 'F') {
233 value = c - 'A' + 10;
234 } else {
235 *status = U_ILLEGAL_ARGUMENT_ERROR;
236#ifdef UCOL_TRACE_SIT
237 fprintf(stderrstderr, "%s:%d: Bad hex char at '%s': %s\n", __FILE__"../deps/icu-small/source/i18n/ucol_sit.cpp", __LINE__237, *string, u_errorNameu_errorName_71(*status));
238#endif
239 return 0;
240 }
241 result = (result << 4) | (UChar)value;
242 noDigits++;
243 (*string)++;
244 }
245 // if the string was terminated before we read 4 digits, set an error
246 if(noDigits < 4) {
247 *status = U_ILLEGAL_ARGUMENT_ERROR;
248#ifdef UCOL_TRACE_SIT
249 fprintf(stderrstderr, "%s:%d: Short (only %d digits, wanted 4) at '%s': %s\n", __FILE__"../deps/icu-small/source/i18n/ucol_sit.cpp", __LINE__249, noDigits,*string, u_errorNameu_errorName_71(*status));
250#endif
251 }
252 return result;
253}
254
255U_CDECL_BEGINextern "C" {
256static const char* U_CALLCONV
257_processVariableTop(CollatorSpec *spec, uint32_t value1, const char* string, UErrorCode *status)
258{
259 // get four digits
260 int32_t i = 0;
261 if(!value1) {
262 while(U_SUCCESS(*status) && i < locElementCapacity && *string != 0 && *string != '_') {
263 spec->variableTopString[i++] = readHexCodeUnit(&string, status);
264 }
265 spec->variableTopStringLen = i;
266 if(i == locElementCapacity && *string != 0 && *string != '_') {
267 *status = U_BUFFER_OVERFLOW_ERROR;
268 }
269 } else {
270 spec->variableTopValue = readHexCodeUnit(&string, status);
271 }
272 if(U_SUCCESS(*status)) {
273 spec->variableTopSet = TRUE1;
274 }
275 return string;
276}
277U_CDECL_END}
278
279
280/* Table for parsing short strings */
281struct ShortStringOptions {
282 char optionStart;
283 ActionFunction *action;
284 uint32_t attr;
285};
286
287static const ShortStringOptions options[UCOL_SIT_ITEMS_COUNT] =
288{
289/* 10 ALTERNATE_HANDLING */ {alternateHArg, _processCollatorOption, UCOL_ALTERNATE_HANDLING }, // alternate N, S, D
290/* 15 VARIABLE_TOP_VALUE */ {variableTopValArg, _processVariableTop, 1 },
291/* 08 CASE_FIRST */ {caseFirstArg, _processCollatorOption, UCOL_CASE_FIRST }, // case first L, U, X, D
292/* 09 NUMERIC_COLLATION */ {numericCollArg, _processCollatorOption, UCOL_NUMERIC_COLLATION }, // codan O, X, D
293/* 07 CASE_LEVEL */ {caseLevelArg, _processCollatorOption, UCOL_CASE_LEVEL }, // case level O, X, D
294/* 12 FRENCH_COLLATION */ {frenchCollArg, _processCollatorOption, UCOL_FRENCH_COLLATION }, // french O, X, D
295/* 13 HIRAGANA_QUATERNARY] */ {hiraganaQArg, _processCollatorOption, UCOL_HIRAGANA_QUATERNARY_MODE }, // hiragana O, X, D
296/* 04 KEYWORD */ {keywordArg, _processLocaleElement, UCOL_SIT_KEYWORD }, // keyword
297/* 00 LANGUAGE */ {languageArg, _processLocaleElement, UCOL_SIT_LANGUAGE }, // language
298/* 11 NORMALIZATION_MODE */ {normArg, _processCollatorOption, UCOL_NORMALIZATION_MODE }, // norm O, X, D
299/* 02 REGION */ {regionArg, _processLocaleElement, UCOL_SIT_REGION }, // region
300/* 06 STRENGTH */ {strengthArg, _processCollatorOption, UCOL_STRENGTH }, // strength 1, 2, 3, 4, I, D
301/* 14 VARIABLE_TOP */ {variableTopArg, _processVariableTop, 0 },
302/* 03 VARIANT */ {variantArg, _processLocaleElement, UCOL_SIT_VARIANT }, // variant
303/* 05 RFC3066BIS */ {RFC3066Arg, _processRFC3066Locale, 0 }, // rfc3066bis locale name
304/* 01 SCRIPT */ {scriptArg, _processLocaleElement, UCOL_SIT_SCRIPT }, // script
305/* PROVIDER */ {providerArg, _processLocaleElement, UCOL_SIT_PROVIDER }
306};
307
308
309static
310const char* ucol_sit_readOption(const char *start, CollatorSpec *spec,
311 UErrorCode *status)
312{
313 int32_t i = 0;
314
315 for(i = 0; i < UCOL_SIT_ITEMS_COUNT; i++) {
316 if(*start == options[i].optionStart) {
317 const char* end = options[i].action(spec, options[i].attr, start+1, status);
318#ifdef UCOL_TRACE_SIT
319 fprintf(stderrstderr, "***Set %d to %s...\n", i, start);
320#endif
321 // assume 'start' does not go away through all this
322 spec->entries[i].copyFrom(CharString(start, (int32_t)(end - start), *status), *status);
323 return end;
324 }
325 }
326 *status = U_ILLEGAL_ARGUMENT_ERROR;
327#ifdef UCOL_TRACE_SIT
328 fprintf(stderrstderr, "%s:%d: Unknown option at '%s': %s\n", __FILE__"../deps/icu-small/source/i18n/ucol_sit.cpp", __LINE__328, start, u_errorNameu_errorName_71(*status));
329#endif
330 return start;
331}
332
333static const char*
334ucol_sit_readSpecs(CollatorSpec *s, const char *string,
335 UParseError *parseError, UErrorCode *status)
336{
337 const char *definition = string;
338 while(U_SUCCESS(*status) && *string) {
339 string = ucol_sit_readOption(string, s, status);
340 // advance over '_'
341 while(*string && *string == '_') {
342 string++;
343 }
344 }
345 if(U_FAILURE(*status)) {
346 parseError->offset = (int32_t)(string - definition);
347 }
348 return string;
349}
350
351static
352int32_t ucol_sit_dumpSpecs(CollatorSpec *s, char *destination, int32_t capacity, UErrorCode *status)
353{
354 int32_t i = 0, j = 0;
355 int32_t len = 0;
356 char optName;
357 if(U_SUCCESS(*status)) {
8
Taking true branch
358 for(i = 0; i < UCOL_SIT_ITEMS_COUNT; i++) {
9
Loop condition is true. Entering loop body
17
Loop condition is true. Entering loop body
359 if(!s->entries[i].isEmpty()) {
10
Taking true branch
18
Taking true branch
360 if(len
10.1
'len' is 0
) {
11
Taking false branch
19
Assuming 'len' is not equal to 0
20
Taking true branch
361 if(len < capacity) {
21
Assuming 'len' is < 'capacity'
22
Taking true branch
362 uprv_strcat(destination, "_"):: strcat(destination, "_");
23
Null pointer passed to 1st parameter expecting 'nonnull'
363 }
364 len++;
365 }
366 optName = s->entries[i][0];
367 if(optName == languageArg || optName == regionArg || optName == variantArg || optName == keywordArg) {
12
Assuming 'optName' is not equal to 'languageArg'
13
Assuming 'optName' is not equal to 'regionArg'
14
Assuming 'optName' is not equal to 'variantArg'
15
Assuming 'optName' is not equal to 'keywordArg'
16
Taking false branch
368 for(j = 0; j < s->entries[i].length(); j++) {
369 if(len + j < capacity) {
370 destination[len+j] = uprv_toupperuprv_toupper_71(s->entries[i][j]);
371 }
372 }
373 len += s->entries[i].length();
374 } else {
375 len += s->entries[i].extract(destination + len, capacity - len, *status);
376 }
377 }
378 }
379 return len;
380 } else {
381 return 0;
382 }
383}
384
385static void
386ucol_sit_calculateWholeLocale(CollatorSpec *s, UErrorCode &status) {
387 // put the locale together, unless we have a done
388 // locale
389 if(s->locale.isEmpty()) {
390 // first the language
391 s->locale.append(s->locElements[UCOL_SIT_LANGUAGE], status);
392 // then the script, if present
393 if(!s->locElements[UCOL_SIT_SCRIPT].isEmpty()) {
394 s->locale.append("_", status);
395 s->locale.append(s->locElements[UCOL_SIT_SCRIPT], status);
396 }
397 // then the region, if present
398 if(!s->locElements[UCOL_SIT_REGION].isEmpty()) {
399 s->locale.append("_", status);
400 s->locale.append(s->locElements[UCOL_SIT_REGION], status);
401 } else if(!s->locElements[UCOL_SIT_VARIANT].isEmpty()) { // if there is a variant, we need an underscore
402 s->locale.append("_", status);
403 }
404 // add variant, if there
405 if(!s->locElements[UCOL_SIT_VARIANT].isEmpty()) {
406 s->locale.append("_", status);
407 s->locale.append(s->locElements[UCOL_SIT_VARIANT], status);
408 }
409
410 // if there is a collation keyword, add that too
411 if(!s->locElements[UCOL_SIT_KEYWORD].isEmpty()) {
412 s->locale.append(collationKeyword, status);
413 s->locale.append(s->locElements[UCOL_SIT_KEYWORD], status);
414 }
415
416 // if there is a provider keyword, add that too
417 if(!s->locElements[UCOL_SIT_PROVIDER].isEmpty()) {
418 s->locale.append(providerKeyword, status);
419 s->locale.append(s->locElements[UCOL_SIT_PROVIDER], status);
420 }
421 }
422}
423
424
425U_CAPIextern "C" void U_EXPORT2
426ucol_prepareShortStringOpenucol_prepareShortStringOpen_71( const char *definition,
427 UBool,
428 UParseError *parseError,
429 UErrorCode *status)
430{
431 if(U_FAILURE(*status)) return;
432
433 UParseError internalParseError;
434
435 if(!parseError) {
436 parseError = &internalParseError;
437 }
438 parseError->line = 0;
439 parseError->offset = 0;
440 parseError->preContext[0] = 0;
441 parseError->postContext[0] = 0;
442
443
444 // first we want to pick stuff out of short string.
445 // we'll end up with an UCA version, locale and a bunch of
446 // settings
447
448 // analyse the string in order to get everything we need.
449 CollatorSpec s;
450 ucol_sit_readSpecs(&s, definition, parseError, status);
451 ucol_sit_calculateWholeLocale(&s, *status);
452
453 char buffer[internalBufferSize];
454 uprv_memset(buffer, 0, internalBufferSize):: memset(buffer, 0, internalBufferSize);
455 uloc_canonicalizeuloc_canonicalize_71(s.locale.data(), buffer, internalBufferSize, status);
456
457 UResourceBundle *b = ures_openures_open_71(U_ICUDATA_COLL"icudt" "71" "l" "-" "coll", buffer, status);
458 /* we try to find stuff from keyword */
459 UResourceBundle *collations = ures_getByKeyures_getByKey_71(b, "collations", NULL__null, status);
460 UResourceBundle *collElem = NULL__null;
461 char keyBuffer[256];
462 // if there is a keyword, we pick it up and try to get elements
463 int32_t keyLen = uloc_getKeywordValueuloc_getKeywordValue_71(buffer, "collation", keyBuffer, sizeof(keyBuffer), status);
464 // Treat too long a value as no keyword.
465 if(keyLen >= (int32_t)sizeof(keyBuffer)) {
466 keyLen = 0;
467 *status = U_ZERO_ERROR;
468 }
469 if(keyLen == 0) {
470 // no keyword
471 // we try to find the default setting, which will give us the keyword value
472 UResourceBundle *defaultColl = ures_getByKeyWithFallbackures_getByKeyWithFallback_71(collations, "default", NULL__null, status);
473 if(U_SUCCESS(*status)) {
474 int32_t defaultKeyLen = 0;
475 const UChar *defaultKey = ures_getStringures_getString_71(defaultColl, &defaultKeyLen, status);
476 u_UCharsToCharsu_UCharsToChars_71(defaultKey, keyBuffer, defaultKeyLen);
477 keyBuffer[defaultKeyLen] = 0;
478 } else {
479 *status = U_INTERNAL_PROGRAM_ERROR;
480 return;
481 }
482 ures_closeures_close_71(defaultColl);
483 }
484 collElem = ures_getByKeyWithFallbackures_getByKeyWithFallback_71(collations, keyBuffer, collElem, status);
485 ures_closeures_close_71(collElem);
486 ures_closeures_close_71(collations);
487 ures_closeures_close_71(b);
488}
489
490
491U_CAPIextern "C" UCollator* U_EXPORT2
492ucol_openFromShortStringucol_openFromShortString_71( const char *definition,
493 UBool forceDefaults,
494 UParseError *parseError,
495 UErrorCode *status)
496{
497 UTRACE_ENTRY_OC(UTRACE_UCOL_OPEN_FROM_SHORT_STRING);
498 UTRACE_DATA1(UTRACE_INFO, "short string = \"%s\"", definition);
499
500 if(U_FAILURE(*status)) return 0;
501
502 UParseError internalParseError;
503
504 if(!parseError) {
505 parseError = &internalParseError;
506 }
507 parseError->line = 0;
508 parseError->offset = 0;
509 parseError->preContext[0] = 0;
510 parseError->postContext[0] = 0;
511
512
513 // first we want to pick stuff out of short string.
514 // we'll end up with an UCA version, locale and a bunch of
515 // settings
516
517 // analyse the string in order to get everything we need.
518 const char *string = definition;
519 CollatorSpec s;
520 string = ucol_sit_readSpecs(&s, definition, parseError, status);
521 ucol_sit_calculateWholeLocale(&s, *status);
522
523 char buffer[internalBufferSize];
524 uprv_memset(buffer, 0, internalBufferSize):: memset(buffer, 0, internalBufferSize);
525#ifdef UCOL_TRACE_SIT
526 fprintf(stderrstderr, "DEF %s, DATA %s, ERR %s\n", definition, s.locale.data(), u_errorNameu_errorName_71(*status));
527#endif
528 uloc_canonicalizeuloc_canonicalize_71(s.locale.data(), buffer, internalBufferSize, status);
529
530 UCollator *result = ucol_openucol_open_71(buffer, status);
531 int32_t i = 0;
532
533 for(i = 0; i < UCOL_ATTRIBUTE_COUNT; i++) {
534 if(s.options[i] != UCOL_DEFAULT) {
535 if(forceDefaults || ucol_getAttributeucol_getAttribute_71(result, (UColAttribute)i, status) != s.options[i]) {
536 ucol_setAttributeucol_setAttribute_71(result, (UColAttribute)i, s.options[i], status);
537 }
538
539 if(U_FAILURE(*status)) {
540 parseError->offset = (int32_t)(string - definition);
541 ucol_closeucol_close_71(result);
542 return NULL__null;
543 }
544
545 }
546 }
547 if(s.variableTopSet) {
548 if(s.variableTopString[0]) {
549 ucol_setVariableTopucol_setVariableTop_71(result, s.variableTopString, s.variableTopStringLen, status);
550 } else { // we set by value, using 'B'
551 ucol_restoreVariableTopucol_restoreVariableTop_71(result, s.variableTopValue, status);
552 }
553 }
554
555
556 if(U_FAILURE(*status)) { // here it can only be a bogus value
557 ucol_closeucol_close_71(result);
558 result = NULL__null;
559 }
560
561 UTRACE_EXIT_PTR_STATUS(result, *status);
562 return result;
563}
564
565
566U_CAPIextern "C" int32_t U_EXPORT2
567ucol_getShortDefinitionStringucol_getShortDefinitionString_71(const UCollator *coll,
568 const char *locale,
569 char *dst,
570 int32_t capacity,
571 UErrorCode *status)
572{
573 if(U_FAILURE(*status)) return 0;
574 if(coll == NULL__null) {
575 *status = U_ILLEGAL_ARGUMENT_ERROR;
576 return 0;
577 }
578 return ((icu::Collator*)coll)->internalGetShortDefinitionString(locale,dst,capacity,*status);
579}
580
581U_CAPIextern "C" int32_t U_EXPORT2
582ucol_normalizeShortDefinitionStringucol_normalizeShortDefinitionString_71(const char *definition,
583 char *destination,
584 int32_t capacity,
585 UParseError *parseError,
586 UErrorCode *status)
587{
588
589 if(U_FAILURE(*status)) {
1
Taking false branch
590 return 0;
591 }
592
593 if(destination) {
2
Assuming 'destination' is null
3
Taking false branch
594 uprv_memset(destination, 0, capacity*sizeof(char)):: memset(destination, 0, capacity*sizeof(char));
595 }
596
597 UParseError pe;
598 if(!parseError) {
4
Assuming 'parseError' is non-null
5
Taking false branch
599 parseError = &pe;
600 }
601
602 // validate
603 CollatorSpec s;
604 ucol_sit_readSpecs(&s, definition, parseError, status);
605 return ucol_sit_dumpSpecs(&s, destination, capacity, status);
6
Passing null pointer value via 2nd parameter 'destination'
7
Calling 'ucol_sit_dumpSpecs'
606}
607
608/**
609 * Get a set containing the contractions defined by the collator. The set includes
610 * both the UCA contractions and the contractions defined by the collator
611 * @param coll collator
612 * @param conts the set to hold the result
613 * @param status to hold the error code
614 * @return the size of the contraction set
615 */
616U_CAPIextern "C" int32_t U_EXPORT2
617ucol_getContractionsucol_getContractions_71( const UCollator *coll,
618 USet *contractions,
619 UErrorCode *status)
620{
621 ucol_getContractionsAndExpansionsucol_getContractionsAndExpansions_71(coll, contractions, NULL__null, FALSE0, status);
622 return uset_getItemCountuset_getItemCount_71(contractions);
623}
624
625/**
626 * Get a set containing the expansions defined by the collator. The set includes
627 * both the UCA expansions and the expansions defined by the tailoring
628 * @param coll collator
629 * @param conts the set to hold the result
630 * @param addPrefixes add the prefix contextual elements to contractions
631 * @param status to hold the error code
632 *
633 * @draft ICU 3.4
634 */
635U_CAPIextern "C" void U_EXPORT2
636ucol_getContractionsAndExpansionsucol_getContractionsAndExpansions_71( const UCollator *coll,
637 USet *contractions,
638 USet *expansions,
639 UBool addPrefixes,
640 UErrorCode *status)
641{
642 if(U_FAILURE(*status)) {
643 return;
644 }
645 if(coll == NULL__null) {
646 *status = U_ILLEGAL_ARGUMENT_ERROR;
647 return;
648 }
649 const icu::RuleBasedCollator *rbc = icu::RuleBasedCollator::rbcFromUCollator(coll);
650 if(rbc == NULL__null) {
651 *status = U_UNSUPPORTED_ERROR;
652 return;
653 }
654 rbc->internalGetContractionsAndExpansions(
655 icu::UnicodeSet::fromUSet(contractions),
656 icu::UnicodeSet::fromUSet(expansions),
657 addPrefixes, *status);
658}
659#endif