Bug Summary

File:out/../deps/icu-small/source/i18n/unum.cpp
Warning:line 738, column 9
Called C++ object pointer is null

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 unum.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/unum.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) 1996-2015, International Business Machines
6* Corporation and others. All Rights Reserved.
7*******************************************************************************
8* Modification History:
9*
10* Date Name Description
11* 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes
12*******************************************************************************
13*/
14
15#include "unicode/utypes.h"
16
17#if !UCONFIG_NO_FORMATTING0
18
19#include "unicode/unum.h"
20
21#include "unicode/uloc.h"
22#include "unicode/numfmt.h"
23#include "unicode/decimfmt.h"
24#include "unicode/rbnf.h"
25#include "unicode/compactdecimalformat.h"
26#include "unicode/ustring.h"
27#include "unicode/fmtable.h"
28#include "unicode/dcfmtsym.h"
29#include "unicode/curramt.h"
30#include "unicode/localpointer.h"
31#include "unicode/udisplaycontext.h"
32#include "uassert.h"
33#include "cpputils.h"
34#include "cstring.h"
35
36
37U_NAMESPACE_USEusing namespace icu_71;
38
39
40U_CAPIextern "C" UNumberFormat* U_EXPORT2
41unum_openunum_open_71( UNumberFormatStyle style,
42 const UChar* pattern,
43 int32_t patternLength,
44 const char* locale,
45 UParseError* parseErr,
46 UErrorCode* status) {
47 if(U_FAILURE(*status)) {
48 return NULL__null;
49 }
50
51 NumberFormat *retVal = NULL__null;
52
53 switch(style) {
54 case UNUM_DECIMAL:
55 case UNUM_CURRENCY:
56 case UNUM_PERCENT:
57 case UNUM_SCIENTIFIC:
58 case UNUM_CURRENCY_ISO:
59 case UNUM_CURRENCY_PLURAL:
60 case UNUM_CURRENCY_ACCOUNTING:
61 case UNUM_CASH_CURRENCY:
62 case UNUM_CURRENCY_STANDARD:
63 retVal = NumberFormat::createInstance(Locale(locale), style, *status);
64 break;
65
66 case UNUM_PATTERN_DECIMAL: {
67 UParseError tErr;
68 /* UnicodeString can handle the case when patternLength = -1. */
69 const UnicodeString pat(pattern, patternLength);
70
71 if(parseErr==NULL__null){
72 parseErr = &tErr;
73 }
74
75 DecimalFormatSymbols *syms = new DecimalFormatSymbols(Locale(locale), *status);
76 if(syms == NULL__null) {
77 *status = U_MEMORY_ALLOCATION_ERROR;
78 return NULL__null;
79 }
80 if (U_FAILURE(*status)) {
81 delete syms;
82 return NULL__null;
83 }
84
85 retVal = new DecimalFormat(pat, syms, *parseErr, *status);
86 if(retVal == NULL__null) {
87 delete syms;
88 }
89 } break;
90
91#if U_HAVE_RBNF1
92 case UNUM_PATTERN_RULEBASED: {
93 UParseError tErr;
94 /* UnicodeString can handle the case when patternLength = -1. */
95 const UnicodeString pat(pattern, patternLength);
96
97 if(parseErr==NULL__null){
98 parseErr = &tErr;
99 }
100
101 retVal = new RuleBasedNumberFormat(pat, Locale(locale), *parseErr, *status);
102 } break;
103
104 case UNUM_SPELLOUT:
105 retVal = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale(locale), *status);
106 break;
107
108 case UNUM_ORDINAL:
109 retVal = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale(locale), *status);
110 break;
111
112 case UNUM_DURATION:
113 retVal = new RuleBasedNumberFormat(URBNF_DURATION, Locale(locale), *status);
114 break;
115
116 case UNUM_NUMBERING_SYSTEM:
117 retVal = new RuleBasedNumberFormat(URBNF_NUMBERING_SYSTEM, Locale(locale), *status);
118 break;
119#endif
120
121 case UNUM_DECIMAL_COMPACT_SHORT:
122 retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_SHORT, *status);
123 break;
124
125 case UNUM_DECIMAL_COMPACT_LONG:
126 retVal = CompactDecimalFormat::createInstance(Locale(locale), UNUM_LONG, *status);
127 break;
128
129 default:
130 *status = U_UNSUPPORTED_ERROR;
131 return NULL__null;
132 }
133
134 if(retVal == NULL__null && U_SUCCESS(*status)) {
135 *status = U_MEMORY_ALLOCATION_ERROR;
136 }
137
138 if (U_FAILURE(*status) && retVal != NULL__null) {
139 delete retVal;
140 retVal = NULL__null;
141 }
142
143 return reinterpret_cast<UNumberFormat *>(retVal);
144}
145
146U_CAPIextern "C" void U_EXPORT2
147unum_closeunum_close_71(UNumberFormat* fmt)
148{
149 delete (NumberFormat*) fmt;
150}
151
152U_CAPIextern "C" UNumberFormat* U_EXPORT2
153unum_cloneunum_clone_71(const UNumberFormat *fmt,
154 UErrorCode *status)
155{
156 if(U_FAILURE(*status))
157 return 0;
158
159 Format *res = 0;
160 const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
161 const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
162 if (df != NULL__null) {
163 res = df->clone();
164 } else {
165 const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
166 U_ASSERT(rbnf != NULL)(void)0;
167 res = rbnf->clone();
168 }
169
170 if(res == 0) {
171 *status = U_MEMORY_ALLOCATION_ERROR;
172 return 0;
173 }
174
175 return (UNumberFormat*) res;
176}
177
178U_CAPIextern "C" int32_t U_EXPORT2
179unum_formatunum_format_71( const UNumberFormat* fmt,
180 int32_t number,
181 UChar* result,
182 int32_t resultLength,
183 UFieldPosition *pos,
184 UErrorCode* status)
185{
186 return unum_formatInt64unum_formatInt64_71(fmt, number, result, resultLength, pos, status);
187}
188
189U_CAPIextern "C" int32_t U_EXPORT2
190unum_formatInt64unum_formatInt64_71(const UNumberFormat* fmt,
191 int64_t number,
192 UChar* result,
193 int32_t resultLength,
194 UFieldPosition *pos,
195 UErrorCode* status)
196{
197 if(U_FAILURE(*status))
198 return -1;
199
200 UnicodeString res;
201 if(!(result==NULL__null && resultLength==0)) {
202 // NULL destination for pure preflighting: empty dummy string
203 // otherwise, alias the destination buffer
204 res.setTo(result, 0, resultLength);
205 }
206
207 FieldPosition fp;
208
209 if(pos != 0)
210 fp.setField(pos->field);
211
212 ((const NumberFormat*)fmt)->format(number, res, fp, *status);
213
214 if(pos != 0) {
215 pos->beginIndex = fp.getBeginIndex();
216 pos->endIndex = fp.getEndIndex();
217 }
218
219 return res.extract(result, resultLength, *status);
220}
221
222U_CAPIextern "C" int32_t U_EXPORT2
223unum_formatDoubleunum_formatDouble_71( const UNumberFormat* fmt,
224 double number,
225 UChar* result,
226 int32_t resultLength,
227 UFieldPosition *pos, /* 0 if ignore */
228 UErrorCode* status)
229{
230
231 if(U_FAILURE(*status)) return -1;
232
233 UnicodeString res;
234 if(!(result==NULL__null && resultLength==0)) {
235 // NULL destination for pure preflighting: empty dummy string
236 // otherwise, alias the destination buffer
237 res.setTo(result, 0, resultLength);
238 }
239
240 FieldPosition fp;
241
242 if(pos != 0)
243 fp.setField(pos->field);
244
245 ((const NumberFormat*)fmt)->format(number, res, fp, *status);
246
247 if(pos != 0) {
248 pos->beginIndex = fp.getBeginIndex();
249 pos->endIndex = fp.getEndIndex();
250 }
251
252 return res.extract(result, resultLength, *status);
253}
254
255U_CAPIextern "C" int32_t U_EXPORT2
256unum_formatDoubleForFieldsunum_formatDoubleForFields_71(const UNumberFormat* format,
257 double number,
258 UChar* result,
259 int32_t resultLength,
260 UFieldPositionIterator* fpositer,
261 UErrorCode* status)
262{
263 if (U_FAILURE(*status))
264 return -1;
265
266 if (result == NULL__null ? resultLength != 0 : resultLength < 0) {
267 *status = U_ILLEGAL_ARGUMENT_ERROR;
268 return -1;
269 }
270
271 UnicodeString res;
272 if (result != NULL__null) {
273 // NULL destination for pure preflighting: empty dummy string
274 // otherwise, alias the destination buffer
275 res.setTo(result, 0, resultLength);
276 }
277
278 ((const NumberFormat*)format)->format(number, res, (FieldPositionIterator*)fpositer, *status);
279
280 return res.extract(result, resultLength, *status);
281}
282
283U_CAPIextern "C" int32_t U_EXPORT2
284unum_formatDecimalunum_formatDecimal_71(const UNumberFormat* fmt,
285 const char * number,
286 int32_t length,
287 UChar* result,
288 int32_t resultLength,
289 UFieldPosition *pos, /* 0 if ignore */
290 UErrorCode* status) {
291
292 if(U_FAILURE(*status)) {
293 return -1;
294 }
295 if ((result == NULL__null && resultLength != 0) || resultLength < 0) {
296 *status = U_ILLEGAL_ARGUMENT_ERROR;
297 return -1;
298 }
299
300 FieldPosition fp;
301 if(pos != 0) {
302 fp.setField(pos->field);
303 }
304
305 if (length < 0) {
306 length = static_cast<int32_t>(uprv_strlen(number):: strlen(number));
307 }
308 StringPiece numSP(number, length);
309 Formattable numFmtbl(numSP, *status);
310
311 UnicodeString resultStr;
312 if (resultLength > 0) {
313 // Alias the destination buffer.
314 resultStr.setTo(result, 0, resultLength);
315 }
316 ((const NumberFormat*)fmt)->format(numFmtbl, resultStr, fp, *status);
317 if(pos != 0) {
318 pos->beginIndex = fp.getBeginIndex();
319 pos->endIndex = fp.getEndIndex();
320 }
321 return resultStr.extract(result, resultLength, *status);
322}
323
324
325
326
327U_CAPIextern "C" int32_t U_EXPORT2
328unum_formatDoubleCurrencyunum_formatDoubleCurrency_71(const UNumberFormat* fmt,
329 double number,
330 UChar* currency,
331 UChar* result,
332 int32_t resultLength,
333 UFieldPosition* pos, /* ignored if 0 */
334 UErrorCode* status) {
335 if (U_FAILURE(*status)) return -1;
336
337 UnicodeString res;
338 if (!(result==NULL__null && resultLength==0)) {
339 // NULL destination for pure preflighting: empty dummy string
340 // otherwise, alias the destination buffer
341 res.setTo(result, 0, resultLength);
342 }
343
344 FieldPosition fp;
345 if (pos != 0) {
346 fp.setField(pos->field);
347 }
348 CurrencyAmount *tempCurrAmnt = new CurrencyAmount(number, currency, *status);
349 // Check for null pointer.
350 if (tempCurrAmnt == NULL__null) {
351 *status = U_MEMORY_ALLOCATION_ERROR;
352 return -1;
353 }
354 Formattable n(tempCurrAmnt);
355 ((const NumberFormat*)fmt)->format(n, res, fp, *status);
356
357 if (pos != 0) {
358 pos->beginIndex = fp.getBeginIndex();
359 pos->endIndex = fp.getEndIndex();
360 }
361
362 return res.extract(result, resultLength, *status);
363}
364
365static void
366parseRes(Formattable& res,
367 const UNumberFormat* fmt,
368 const UChar* text,
369 int32_t textLength,
370 int32_t *parsePos /* 0 = start */,
371 UErrorCode *status)
372{
373 if(U_FAILURE(*status))
374 return;
375
376 const UnicodeString src((UBool)(textLength == -1), text, textLength);
377 ParsePosition pp;
378
379 if(parsePos != 0)
380 pp.setIndex(*parsePos);
381
382 ((const NumberFormat*)fmt)->parse(src, res, pp);
383
384 if(pp.getErrorIndex() != -1) {
385 *status = U_PARSE_ERROR;
386 if(parsePos != 0) {
387 *parsePos = pp.getErrorIndex();
388 }
389 } else if(parsePos != 0) {
390 *parsePos = pp.getIndex();
391 }
392}
393
394U_CAPIextern "C" int32_t U_EXPORT2
395unum_parseunum_parse_71( const UNumberFormat* fmt,
396 const UChar* text,
397 int32_t textLength,
398 int32_t *parsePos /* 0 = start */,
399 UErrorCode *status)
400{
401 Formattable res;
402 parseRes(res, fmt, text, textLength, parsePos, status);
403 return res.getLong(*status);
404}
405
406U_CAPIextern "C" int64_t U_EXPORT2
407unum_parseInt64unum_parseInt64_71( const UNumberFormat* fmt,
408 const UChar* text,
409 int32_t textLength,
410 int32_t *parsePos /* 0 = start */,
411 UErrorCode *status)
412{
413 Formattable res;
414 parseRes(res, fmt, text, textLength, parsePos, status);
415 return res.getInt64(*status);
416}
417
418U_CAPIextern "C" double U_EXPORT2
419unum_parseDoubleunum_parseDouble_71( const UNumberFormat* fmt,
420 const UChar* text,
421 int32_t textLength,
422 int32_t *parsePos /* 0 = start */,
423 UErrorCode *status)
424{
425 Formattable res;
426 parseRes(res, fmt, text, textLength, parsePos, status);
427 return res.getDouble(*status);
428}
429
430U_CAPIextern "C" int32_t U_EXPORT2
431unum_parseDecimalunum_parseDecimal_71(const UNumberFormat* fmt,
432 const UChar* text,
433 int32_t textLength,
434 int32_t *parsePos /* 0 = start */,
435 char *outBuf,
436 int32_t outBufLength,
437 UErrorCode *status)
438{
439 if (U_FAILURE(*status)) {
440 return -1;
441 }
442 if ((outBuf == NULL__null && outBufLength != 0) || outBufLength < 0) {
443 *status = U_ILLEGAL_ARGUMENT_ERROR;
444 return -1;
445 }
446 Formattable res;
447 parseRes(res, fmt, text, textLength, parsePos, status);
448 StringPiece sp = res.getDecimalNumber(*status);
449 if (U_FAILURE(*status)) {
450 return -1;
451 } else if (sp.size() > outBufLength) {
452 *status = U_BUFFER_OVERFLOW_ERROR;
453 } else if (sp.size() == outBufLength) {
454 uprv_strncpy(outBuf, sp.data(), sp.size()):: strncpy(outBuf, sp.data(), sp.size());
455 *status = U_STRING_NOT_TERMINATED_WARNING;
456 } else {
457 U_ASSERT(outBufLength > 0)(void)0;
458 uprv_strcpy(outBuf, sp.data()):: strcpy(outBuf, sp.data());
459 }
460 return sp.size();
461}
462
463U_CAPIextern "C" double U_EXPORT2
464unum_parseDoubleCurrencyunum_parseDoubleCurrency_71(const UNumberFormat* fmt,
465 const UChar* text,
466 int32_t textLength,
467 int32_t* parsePos, /* 0 = start */
468 UChar* currency,
469 UErrorCode* status) {
470 double doubleVal = 0.0;
471 currency[0] = 0;
472 if (U_FAILURE(*status)) {
473 return doubleVal;
474 }
475 const UnicodeString src((UBool)(textLength == -1), text, textLength);
476 ParsePosition pp;
477 if (parsePos != NULL__null) {
478 pp.setIndex(*parsePos);
479 }
480 *status = U_PARSE_ERROR; // assume failure, reset if succeed
481 LocalPointer<CurrencyAmount> currAmt(((const NumberFormat*)fmt)->parseCurrency(src, pp));
482 if (pp.getErrorIndex() != -1) {
483 if (parsePos != NULL__null) {
484 *parsePos = pp.getErrorIndex();
485 }
486 } else {
487 if (parsePos != NULL__null) {
488 *parsePos = pp.getIndex();
489 }
490 if (pp.getIndex() > 0) {
491 *status = U_ZERO_ERROR;
492 u_strcpyu_strcpy_71(currency, currAmt->getISOCurrency());
493 doubleVal = currAmt->getNumber().getDouble(*status);
494 }
495 }
496 return doubleVal;
497}
498
499U_CAPIextern "C" const char* U_EXPORT2
500unum_getAvailableunum_getAvailable_71(int32_t index)
501{
502 return uloc_getAvailableuloc_getAvailable_71(index);
503}
504
505U_CAPIextern "C" int32_t U_EXPORT2
506unum_countAvailableunum_countAvailable_71()
507{
508 return uloc_countAvailableuloc_countAvailable_71();
509}
510
511U_CAPIextern "C" int32_t U_EXPORT2
512unum_getAttributeunum_getAttribute_71(const UNumberFormat* fmt,
513 UNumberFormatAttribute attr)
514{
515 const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
516 if (attr == UNUM_LENIENT_PARSE) {
517 // Supported for all subclasses
518 return nf->isLenient();
519 }
520 else if (attr == UNUM_MAX_INTEGER_DIGITS) {
521 return nf->getMaximumIntegerDigits();
522 }
523 else if (attr == UNUM_MIN_INTEGER_DIGITS) {
524 return nf->getMinimumIntegerDigits();
525 }
526 else if (attr == UNUM_INTEGER_DIGITS) {
527 // TODO: what should this return?
528 return nf->getMinimumIntegerDigits();
529 }
530 else if (attr == UNUM_MAX_FRACTION_DIGITS) {
531 return nf->getMaximumFractionDigits();
532 }
533 else if (attr == UNUM_MIN_FRACTION_DIGITS) {
534 return nf->getMinimumFractionDigits();
535 }
536 else if (attr == UNUM_FRACTION_DIGITS) {
537 // TODO: what should this return?
538 return nf->getMinimumFractionDigits();
539 }
540 else if (attr == UNUM_ROUNDING_MODE) {
541 return nf->getRoundingMode();
542 }
543
544 // The remaining attributes are only supported for DecimalFormat
545 const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
546 if (df != NULL__null) {
547 UErrorCode ignoredStatus = U_ZERO_ERROR;
548 return df->getAttribute(attr, ignoredStatus);
549 }
550
551 return -1;
552}
553
554U_CAPIextern "C" void U_EXPORT2
555unum_setAttributeunum_setAttribute_71( UNumberFormat* fmt,
556 UNumberFormatAttribute attr,
557 int32_t newValue)
558{
559 NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
560 if (attr == UNUM_LENIENT_PARSE) {
561 // Supported for all subclasses
562 // keep this here as the class may not be a DecimalFormat
563 return nf->setLenient(newValue != 0);
564 }
565 else if (attr == UNUM_MAX_INTEGER_DIGITS) {
566 return nf->setMaximumIntegerDigits(newValue);
567 }
568 else if (attr == UNUM_MIN_INTEGER_DIGITS) {
569 return nf->setMinimumIntegerDigits(newValue);
570 }
571 else if (attr == UNUM_INTEGER_DIGITS) {
572 nf->setMinimumIntegerDigits(newValue);
573 return nf->setMaximumIntegerDigits(newValue);
574 }
575 else if (attr == UNUM_MAX_FRACTION_DIGITS) {
576 return nf->setMaximumFractionDigits(newValue);
577 }
578 else if (attr == UNUM_MIN_FRACTION_DIGITS) {
579 return nf->setMinimumFractionDigits(newValue);
580 }
581 else if (attr == UNUM_FRACTION_DIGITS) {
582 nf->setMinimumFractionDigits(newValue);
583 return nf->setMaximumFractionDigits(newValue);
584 }
585 else if (attr == UNUM_ROUNDING_MODE) {
586 return nf->setRoundingMode((NumberFormat::ERoundingMode)newValue);
587 }
588
589 // The remaining attributes are only supported for DecimalFormat
590 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
591 if (df != NULL__null) {
592 UErrorCode ignoredStatus = U_ZERO_ERROR;
593 df->setAttribute(attr, newValue, ignoredStatus);
594 }
595}
596
597U_CAPIextern "C" double U_EXPORT2
598unum_getDoubleAttributeunum_getDoubleAttribute_71(const UNumberFormat* fmt,
599 UNumberFormatAttribute attr)
600{
601 const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
602 const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
603 if (df != NULL__null && attr == UNUM_ROUNDING_INCREMENT) {
604 return df->getRoundingIncrement();
605 } else {
606 return -1.0;
607 }
608}
609
610U_CAPIextern "C" void U_EXPORT2
611unum_setDoubleAttributeunum_setDoubleAttribute_71( UNumberFormat* fmt,
612 UNumberFormatAttribute attr,
613 double newValue)
614{
615 NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
616 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
617 if (df != NULL__null && attr == UNUM_ROUNDING_INCREMENT) {
618 df->setRoundingIncrement(newValue);
619 }
620}
621
622U_CAPIextern "C" int32_t U_EXPORT2
623unum_getTextAttributeunum_getTextAttribute_71(const UNumberFormat* fmt,
624 UNumberFormatTextAttribute tag,
625 UChar* result,
626 int32_t resultLength,
627 UErrorCode* status)
628{
629 if(U_FAILURE(*status))
630 return -1;
631
632 UnicodeString res;
633 if(!(result==NULL__null && resultLength==0)) {
634 // NULL destination for pure preflighting: empty dummy string
635 // otherwise, alias the destination buffer
636 res.setTo(result, 0, resultLength);
637 }
638
639 const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
640 const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
641 if (df != NULL__null) {
642 switch(tag) {
643 case UNUM_POSITIVE_PREFIX:
644 df->getPositivePrefix(res);
645 break;
646
647 case UNUM_POSITIVE_SUFFIX:
648 df->getPositiveSuffix(res);
649 break;
650
651 case UNUM_NEGATIVE_PREFIX:
652 df->getNegativePrefix(res);
653 break;
654
655 case UNUM_NEGATIVE_SUFFIX:
656 df->getNegativeSuffix(res);
657 break;
658
659 case UNUM_PADDING_CHARACTER:
660 res = df->getPadCharacterString();
661 break;
662
663 case UNUM_CURRENCY_CODE:
664 res = UnicodeString(df->getCurrency());
665 break;
666
667 default:
668 *status = U_UNSUPPORTED_ERROR;
669 return -1;
670 }
671 } else {
672 const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
673 U_ASSERT(rbnf != NULL)(void)0;
674 if (tag == UNUM_DEFAULT_RULESET) {
675 res = rbnf->getDefaultRuleSetName();
676 } else if (tag == UNUM_PUBLIC_RULESETS) {
677 int32_t count = rbnf->getNumberOfRuleSetNames();
678 for (int i = 0; i < count; ++i) {
679 res += rbnf->getRuleSetName(i);
680 res += (UChar)0x003b; // semicolon
681 }
682 } else {
683 *status = U_UNSUPPORTED_ERROR;
684 return -1;
685 }
686 }
687
688 return res.extract(result, resultLength, *status);
689}
690
691U_CAPIextern "C" void U_EXPORT2
692unum_setTextAttributeunum_setTextAttribute_71( UNumberFormat* fmt,
693 UNumberFormatTextAttribute tag,
694 const UChar* newValue,
695 int32_t newValueLength,
696 UErrorCode *status)
697{
698 if(U_FAILURE(*status))
1
Taking false branch
699 return;
700
701 UnicodeString val(newValue, newValueLength);
702 NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
2
'nf' initialized here
703 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
704 if (df != NULL__null) {
3
Assuming 'df' is equal to NULL
4
Taking false branch
705 switch(tag) {
706 case UNUM_POSITIVE_PREFIX:
707 df->setPositivePrefix(val);
708 break;
709
710 case UNUM_POSITIVE_SUFFIX:
711 df->setPositiveSuffix(val);
712 break;
713
714 case UNUM_NEGATIVE_PREFIX:
715 df->setNegativePrefix(val);
716 break;
717
718 case UNUM_NEGATIVE_SUFFIX:
719 df->setNegativeSuffix(val);
720 break;
721
722 case UNUM_PADDING_CHARACTER:
723 df->setPadCharacter(val);
724 break;
725
726 case UNUM_CURRENCY_CODE:
727 df->setCurrency(val.getTerminatedBuffer(), *status);
728 break;
729
730 default:
731 *status = U_UNSUPPORTED_ERROR;
732 break;
733 }
734 } else {
735 RuleBasedNumberFormat* rbnf = dynamic_cast<RuleBasedNumberFormat*>(nf);
5
'rbnf' initialized to a null pointer value
736 U_ASSERT(rbnf != NULL)(void)0;
737 if (tag == UNUM_DEFAULT_RULESET) {
6
Assuming 'tag' is equal to UNUM_DEFAULT_RULESET
7
Taking true branch
738 rbnf->setDefaultRuleSet(val, *status);
8
Called C++ object pointer is null
739 } else {
740 *status = U_UNSUPPORTED_ERROR;
741 }
742 }
743}
744
745U_CAPIextern "C" int32_t U_EXPORT2
746unum_toPatternunum_toPattern_71( const UNumberFormat* fmt,
747 UBool isPatternLocalized,
748 UChar* result,
749 int32_t resultLength,
750 UErrorCode* status)
751{
752 if(U_FAILURE(*status))
753 return -1;
754
755 UnicodeString pat;
756 if(!(result==NULL__null && resultLength==0)) {
757 // NULL destination for pure preflighting: empty dummy string
758 // otherwise, alias the destination buffer
759 pat.setTo(result, 0, resultLength);
760 }
761
762 const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
763 const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
764 if (df != NULL__null) {
765 if(isPatternLocalized)
766 df->toLocalizedPattern(pat);
767 else
768 df->toPattern(pat);
769 } else {
770 const RuleBasedNumberFormat* rbnf = dynamic_cast<const RuleBasedNumberFormat*>(nf);
771 U_ASSERT(rbnf != NULL)(void)0;
772 pat = rbnf->getRules();
773 }
774 return pat.extract(result, resultLength, *status);
775}
776
777U_CAPIextern "C" int32_t U_EXPORT2
778unum_getSymbolunum_getSymbol_71(const UNumberFormat *fmt,
779 UNumberFormatSymbol symbol,
780 UChar *buffer,
781 int32_t size,
782 UErrorCode *status)
783{
784 if(status==NULL__null || U_FAILURE(*status)) {
785 return 0;
786 }
787 if(fmt==NULL__null || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT) {
788 *status=U_ILLEGAL_ARGUMENT_ERROR;
789 return 0;
790 }
791 const NumberFormat *nf = reinterpret_cast<const NumberFormat *>(fmt);
792 const DecimalFormat *dcf = dynamic_cast<const DecimalFormat *>(nf);
793 if (dcf == NULL__null) {
794 *status = U_UNSUPPORTED_ERROR;
795 return 0;
796 }
797
798 return dcf->
799 getDecimalFormatSymbols()->
800 getConstSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol).
801 extract(buffer, size, *status);
802}
803
804U_CAPIextern "C" void U_EXPORT2
805unum_setSymbolunum_setSymbol_71(UNumberFormat *fmt,
806 UNumberFormatSymbol symbol,
807 const UChar *value,
808 int32_t length,
809 UErrorCode *status)
810{
811 if(status==NULL__null || U_FAILURE(*status)) {
812 return;
813 }
814 if(fmt==NULL__null || symbol< 0 || symbol>=UNUM_FORMAT_SYMBOL_COUNT || value==NULL__null || length<-1) {
815 *status=U_ILLEGAL_ARGUMENT_ERROR;
816 return;
817 }
818 NumberFormat *nf = reinterpret_cast<NumberFormat *>(fmt);
819 DecimalFormat *dcf = dynamic_cast<DecimalFormat *>(nf);
820 if (dcf == NULL__null) {
821 *status = U_UNSUPPORTED_ERROR;
822 return;
823 }
824
825 DecimalFormatSymbols symbols(*dcf->getDecimalFormatSymbols());
826 symbols.setSymbol((DecimalFormatSymbols::ENumberFormatSymbol)symbol,
827 UnicodeString(value, length)); /* UnicodeString can handle the case when length = -1. */
828 dcf->setDecimalFormatSymbols(symbols);
829}
830
831U_CAPIextern "C" void U_EXPORT2
832unum_applyPatternunum_applyPattern_71( UNumberFormat *fmt,
833 UBool localized,
834 const UChar *pattern,
835 int32_t patternLength,
836 UParseError *parseError,
837 UErrorCode* status)
838{
839 UErrorCode tStatus = U_ZERO_ERROR;
840 UParseError tParseError;
841
842 if(parseError == NULL__null){
843 parseError = &tParseError;
844 }
845
846 if(status==NULL__null){
847 status = &tStatus;
848 }
849
850 int32_t len = (patternLength == -1 ? u_strlenu_strlen_71(pattern) : patternLength);
851 const UnicodeString pat((UChar*)pattern, len, len);
852
853 // Verify if the object passed is a DecimalFormat object
854 NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
855 DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
856 if (df != NULL__null) {
857 if(localized) {
858 df->applyLocalizedPattern(pat,*parseError, *status);
859 } else {
860 df->applyPattern(pat,*parseError, *status);
861 }
862 } else {
863 *status = U_UNSUPPORTED_ERROR;
864 return;
865 }
866}
867
868U_CAPIextern "C" const char* U_EXPORT2
869unum_getLocaleByTypeunum_getLocaleByType_71(const UNumberFormat *fmt,
870 ULocDataLocaleType type,
871 UErrorCode* status)
872{
873 if (fmt == NULL__null) {
874 if (U_SUCCESS(*status)) {
875 *status = U_ILLEGAL_ARGUMENT_ERROR;
876 }
877 return NULL__null;
878 }
879 return ((const Format*)fmt)->getLocaleID(type, *status);
880}
881
882U_CAPIextern "C" void U_EXPORT2
883unum_setContextunum_setContext_71(UNumberFormat* fmt, UDisplayContext value, UErrorCode* status)
884{
885 if (U_FAILURE(*status)) {
886 return;
887 }
888 ((NumberFormat*)fmt)->setContext(value, *status);
889 return;
890}
891
892U_CAPIextern "C" UDisplayContext U_EXPORT2
893unum_getContextunum_getContext_71(const UNumberFormat *fmt, UDisplayContextType type, UErrorCode* status)
894{
895 if (U_FAILURE(*status)) {
896 return (UDisplayContext)0;
897 }
898 return ((const NumberFormat*)fmt)->getContext(type, *status);
899}
900
901U_CAPIextern "C" UFormattable * U_EXPORT2
902unum_parseToUFormattableunum_parseToUFormattable_71(const UNumberFormat* fmt,
903 UFormattable *result,
904 const UChar* text,
905 int32_t textLength,
906 int32_t* parsePos, /* 0 = start */
907 UErrorCode* status) {
908 UFormattable *newFormattable = NULL__null;
909 if (U_FAILURE(*status)) return result;
910 if (fmt == NULL__null || (text==NULL__null && textLength!=0)) {
911 *status = U_ILLEGAL_ARGUMENT_ERROR;
912 return result;
913 }
914 if (result == NULL__null) { // allocate if not allocated.
915 newFormattable = result = ufmt_openufmt_open_71(status);
916 }
917 parseRes(*(Formattable::fromUFormattable(result)), fmt, text, textLength, parsePos, status);
918 if (U_FAILURE(*status) && newFormattable != NULL__null) {
919 ufmt_closeufmt_close_71(newFormattable);
920 result = NULL__null; // deallocate if there was a parse error
921 }
922 return result;
923}
924
925U_CAPIextern "C" int32_t U_EXPORT2
926unum_formatUFormattableunum_formatUFormattable_71(const UNumberFormat* fmt,
927 const UFormattable *number,
928 UChar *result,
929 int32_t resultLength,
930 UFieldPosition *pos, /* ignored if 0 */
931 UErrorCode *status) {
932 if (U_FAILURE(*status)) {
933 return 0;
934 }
935 if (fmt == NULL__null || number==NULL__null ||
936 (result==NULL__null ? resultLength!=0 : resultLength<0)) {
937 *status = U_ILLEGAL_ARGUMENT_ERROR;
938 return 0;
939 }
940 UnicodeString res(result, 0, resultLength);
941
942 FieldPosition fp;
943
944 if(pos != 0)
945 fp.setField(pos->field);
946
947 ((const NumberFormat*)fmt)->format(*(Formattable::fromUFormattable(number)), res, fp, *status);
948
949 if(pos != 0) {
950 pos->beginIndex = fp.getBeginIndex();
951 pos->endIndex = fp.getEndIndex();
952 }
953
954 return res.extract(result, resultLength, *status);
955}
956
957#endif /* #if !UCONFIG_NO_FORMATTING */