1 // Copyright (C) 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2016, International Business Machines Corporation 6 * and others. All Rights Reserved. 7 ********************************************************************/ 8 /******************************************************************************* 9 * 10 * File CNMDPTST.C 11 * 12 * Madhu Katragadda Creation 13 * Modification History: 14 * 15 * Date Name Description 16 * 06/24/99 helena Integrated Alan's NF enhancements and Java2 bug fixes 17 ******************************************************************************* 18 */ 19 20 /* C DEPTH TEST FOR NUMBER FORMAT */ 21 22 #include "unicode/utypes.h" 23 24 #if !UCONFIG_NO_FORMATTING 25 26 #include "unicode/ucurr.h" 27 #include "unicode/uloc.h" 28 #include "unicode/unum.h" 29 #include "unicode/ustring.h" 30 #include "unicode/putil.h" 31 #include "cintltst.h" 32 #include "cnmdptst.h" 33 #include "cmemory.h" 34 #include "cstring.h" 35 #include "ulist.h" 36 37 #define CHECK(status,str) if (U_FAILURE(status)) { log_err("FAIL: %s\n", str); return; } 38 39 void addNumFrDepTest(TestNode** root); 40 static void TestCurrencyPreEuro(void); 41 static void TestCurrencyObject(void); 42 43 void addNumFrDepTest(TestNode** root) 44 { 45 addTest(root, &TestPatterns, "tsformat/cnmdptst/TestPatterns"); 46 addTest(root, &TestQuotes, "tsformat/cnmdptst/TestQuotes"); 47 addTest(root, &TestExponential, "tsformat/cnmdptst/TestExponential"); 48 addTest(root, &TestCurrencySign, "tsformat/cnmdptst/TestCurrencySign"); 49 addTest(root, &TestCurrency, "tsformat/cnmdptst/TestCurrency"); 50 addTest(root, &TestCurrencyPreEuro, "tsformat/cnmdptst/TestCurrencyPreEuro"); 51 addTest(root, &TestCurrencyObject, "tsformat/cnmdptst/TestCurrencyObject"); 52 addTest(root, &TestRounding487, "tsformat/cnmdptst/TestRounding487"); 53 addTest(root, &TestDoubleAttribute, "tsformat/cnmdptst/TestDoubleAttribute"); 54 addTest(root, &TestSecondaryGrouping, "tsformat/cnmdptst/TestSecondaryGrouping"); 55 addTest(root, &TestCurrencyKeywords, "tsformat/cnmdptst/TestCurrencyKeywords"); 56 addTest(root, &TestRounding5350, "tsformat/cnmdptst/TestRounding5350"); 57 addTest(root, &TestGetKeywordValuesForLocale, "tsformat/cnmdptst/TestGetKeywordValuesForLocale"); 58 } 59 60 /*Test Various format patterns*/ 61 static void TestPatterns(void) 62 { 63 int32_t pat_length, i, lneed; 64 UNumberFormat *fmt; 65 UChar upat[5]; 66 UChar unewpat[5]; 67 UChar unum[5]; 68 UChar *unewp=NULL; 69 UChar *str=NULL; 70 UErrorCode status = U_ZERO_ERROR; 71 const char* pat[] = { "#.#", "#.", ".#", "#" }; 72 const char* newpat[] = { "#0.#", "#0.", "#.0", "#" }; 73 const char* num[] = { "0", "0.", ".0", "0" }; 74 75 log_verbose("\nTesting different format patterns\n"); 76 pat_length = UPRV_LENGTHOF(pat); 77 for (i=0; i < pat_length; ++i) 78 { 79 status = U_ZERO_ERROR; 80 u_uastrcpy(upat, pat[i]); 81 fmt= unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status); 82 if (U_FAILURE(status)) { 83 log_err_status(status, "FAIL: Number format constructor failed for pattern %s -> %s\n", pat[i], u_errorName(status)); 84 continue; 85 } 86 lneed=0; 87 lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status); 88 if(status==U_BUFFER_OVERFLOW_ERROR){ 89 status= U_ZERO_ERROR; 90 unewp=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 91 unum_toPattern(fmt, FALSE, unewp, lneed+1, &status); 92 } 93 if(U_FAILURE(status)){ 94 log_err("FAIL: Number format extracting the pattern failed for %s\n", pat[i]); 95 } 96 u_uastrcpy(unewpat, newpat[i]); 97 if(u_strcmp(unewp, unewpat) != 0) 98 log_err("FAIL: Pattern %s should be transmute to %s; %s seen instead\n", pat[i], newpat[i], austrdup(unewp) ); 99 100 lneed=0; 101 lneed=unum_format(fmt, 0, NULL, lneed, NULL, &status); 102 if(status==U_BUFFER_OVERFLOW_ERROR){ 103 status=U_ZERO_ERROR; 104 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 105 unum_format(fmt, 0, str, lneed+1, NULL, &status); 106 } 107 if(U_FAILURE(status)) { 108 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 109 } 110 u_uastrcpy(unum, num[i]); 111 if (u_strcmp(str, unum) != 0) 112 { 113 log_err("FAIL: Pattern %s should format zero as %s; %s Seen instead\n", pat[i], num[i], austrdup(str) ); 114 115 } 116 free(unewp); 117 free(str); 118 unum_close(fmt); 119 } 120 } 121 122 /* Test the handling of quotes*/ 123 static void TestQuotes(void) 124 { 125 int32_t lneed; 126 UErrorCode status=U_ZERO_ERROR; 127 UChar pat[15]; 128 UChar res[15]; 129 UChar *str=NULL; 130 UNumberFormat *fmt; 131 char tempBuf[256]; 132 log_verbose("\nTestting the handling of quotes in number format\n"); 133 u_uastrcpy(pat, "a'fo''o'b#"); 134 fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status); 135 if(U_FAILURE(status)){ 136 log_err_status(status, "Error in number format costruction using pattern \"a'fo''o'b#\" -> %s\n", u_errorName(status)); 137 } 138 lneed=0; 139 lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status); 140 if(status==U_BUFFER_OVERFLOW_ERROR){ 141 status=U_ZERO_ERROR; 142 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 143 unum_format(fmt, 123, str, lneed+1, NULL, &status); 144 } 145 if(U_FAILURE(status) || !str) { 146 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 147 return; 148 } 149 log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) ); 150 log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) ); 151 u_uastrcpy(res, "afo'ob123"); 152 if(u_strcmp(str, res) != 0) 153 log_err("FAIL: Expected afo'ob123"); 154 155 free(str); 156 unum_close(fmt); 157 158 159 u_uastrcpy(pat, ""); 160 u_uastrcpy(pat, "a''b#"); 161 162 163 fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status); 164 if(U_FAILURE(status)){ 165 log_err("Error in number format costruction using pattern \"a''b#\"\n"); 166 } 167 lneed=0; 168 lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status); 169 if(status==U_BUFFER_OVERFLOW_ERROR){ 170 status=U_ZERO_ERROR; 171 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 172 unum_format(fmt, 123, str, lneed+1, NULL, &status); 173 } 174 if(U_FAILURE(status)) { 175 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 176 } 177 log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) ); 178 log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) ); 179 u_uastrcpy(res, ""); 180 u_uastrcpy(res, "a'b123"); 181 if(u_strcmp(str, res) != 0) 182 log_err("FAIL: Expected a'b123\n"); 183 184 free(str); 185 unum_close(fmt); 186 } 187 188 /* Test exponential pattern*/ 189 static void TestExponential(void) 190 { 191 int32_t pat_length, val_length, lval_length; 192 int32_t ival, ilval, p, v, lneed; 193 UNumberFormat *fmt; 194 int32_t ppos; 195 UChar *upat; 196 UChar pattern[20]; 197 UChar *str=NULL; 198 UChar uvalfor[20], ulvalfor[20]; 199 char tempMsgBug[256]; 200 double a; 201 UErrorCode status = U_ZERO_ERROR; 202 #if U_PLATFORM == U_PF_OS390 203 static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 }; 204 #else 205 static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 }; 206 #endif 207 static const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" }; 208 static const int32_t lval[] = { 0, -1, 1, 123456789 }; 209 210 static const char* valFormat[] = 211 { 212 "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271", 213 "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272", 214 "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273", 215 "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]" 216 }; 217 static const char* lvalFormat[] = 218 { 219 "0E0", "-1E0", "1E0", "1.2346E8", 220 "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07", 221 "0E000", "-1E000", "1E000", "123.4568E006", 222 "0E0", "[1E0]", "1E0", "1.235E8" 223 }; 224 static const double valParse[] = 225 { 226 #if U_PLATFORM == U_PF_OS390 227 0.01234, 123460000, 1.23E75, -3.1416E-78, 228 0.01234, 123460000, 1.23E75, -3.1416E-78, 229 0.01234, 123456800, 1.23E75, -3.141593E-78, 230 0.01234, 123500000, 1.23E75, -3.142E-78 231 #else 232 /* We define the whole IEEE 754 number in the 4th column because 233 Visual Age 7 has a bug in rounding numbers. */ 234 0.01234, 123460000, 1.23E300, -3.1415999999999999E-271, 235 0.01234, 123460000, 1.23E300, -3.1415999999999999E-271, 236 0.01234, 123456800, 1.23E300, -3.1415929999999999E-271, 237 0.01234, 123500000, 1.23E300, -3.1420000000000001E-271 238 #endif 239 }; 240 static const int32_t lvalParse[] = 241 { 242 0, -1, 1, 123460000, 243 0, -1, 1, 123460000, 244 0, -1, 1, 123456800, 245 0, -1, 1, 123500000 246 }; 247 248 249 pat_length = UPRV_LENGTHOF(pat); 250 val_length = UPRV_LENGTHOF(val); 251 lval_length = UPRV_LENGTHOF(lval); 252 ival = 0; 253 ilval = 0; 254 for (p=0; p < pat_length; ++p) 255 { 256 upat=(UChar*)malloc(sizeof(UChar) * (strlen(pat[p])+1) ); 257 u_uastrcpy(upat, pat[p]); 258 fmt=unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status); 259 if (U_FAILURE(status)) { 260 log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status)); 261 continue; 262 } 263 lneed= u_strlen(upat) + 1; 264 unum_toPattern(fmt, FALSE, pattern, lneed, &status); 265 log_verbose("Pattern \" %s \" -toPattern-> \" %s \" \n", upat, u_austrcpy(tempMsgBug, pattern) ); 266 for (v=0; v<val_length; ++v) 267 { 268 /*format*/ 269 lneed=0; 270 lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status); 271 if(status==U_BUFFER_OVERFLOW_ERROR){ 272 status=U_ZERO_ERROR; 273 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 274 unum_formatDouble(fmt, val[v], str, lneed+1, NULL, &status); 275 } 276 if(U_FAILURE(status)) { 277 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 278 } 279 280 281 282 u_uastrcpy(uvalfor, valFormat[v+ival]); 283 if(u_strcmp(str, uvalfor) != 0) 284 log_verbose("FAIL: Expected %s ( %s )\n", valFormat[v+ival], u_austrcpy(tempMsgBug, uvalfor) ); 285 286 /*parsing*/ 287 ppos=0; 288 a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status); 289 if (ppos== u_strlen(str)) { 290 if (a != valParse[v+ival]) 291 log_err("FAIL: Expected: %e, Got: %g\n", valParse[v+ival], a); 292 } 293 else 294 log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a); 295 296 free(str); 297 } 298 for (v=0; v<lval_length; ++v) 299 { 300 /*format*/ 301 lneed=0; 302 lneed=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status); 303 if(status==U_BUFFER_OVERFLOW_ERROR){ 304 status=U_ZERO_ERROR; 305 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 306 unum_formatDouble(fmt, lval[v], str, lneed+1, NULL, &status); 307 } 308 if(U_FAILURE(status)) { 309 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 310 } 311 /*printf(" Format %e -> %s\n", lval[v], austrdup(str) );*/ 312 u_uastrcpy(ulvalfor, lvalFormat[v+ilval]); 313 if(u_strcmp(str, ulvalfor) != 0) 314 log_err("FAIL: Expected %s ( %s )\n", valFormat[v+ilval], austrdup(ulvalfor) ); 315 316 /*parsing*/ 317 ppos=0; 318 a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status); 319 if (ppos== u_strlen(str)) { 320 /*printf(" Parse -> %e\n", a);*/ 321 if (a != lvalParse[v+ilval]) 322 log_err("FAIL: Expected : %e\n", valParse[v+ival]); 323 } 324 else 325 log_err(" FAIL: Partial parse ( %d chars ) -> %e\n", ppos, a); 326 327 free(str); 328 329 } 330 ival += val_length; 331 ilval += lval_length; 332 unum_close(fmt); 333 free(upat); 334 } 335 } 336 337 /** 338 * Test the handling of the currency symbol in patterns. 339 */ 340 static void TestCurrencySign(void) 341 { 342 int32_t lneed; 343 UNumberFormat *fmt; 344 UChar *pattern=NULL; 345 UChar *str=NULL; 346 UChar *pat=NULL; 347 UChar *res=NULL; 348 UErrorCode status = U_ZERO_ERROR; 349 char tempBuf[256]; 350 351 pattern=(UChar*)malloc(sizeof(UChar) * (strlen("*#,##0.00;-*#,##0.00") + 1) ); 352 u_uastrcpy(pattern, "*#,##0.00;-*#,##0.00"); 353 pattern[0]=pattern[11]=0xa4; /* insert latin-1 currency symbol */ 354 fmt = unum_open(UNUM_IGNORE,pattern, u_strlen(pattern), "en_US",NULL, &status); 355 if(U_FAILURE(status)){ 356 log_err_status(status, "Error in number format construction with pattern \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status)); 357 } 358 lneed=0; 359 lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status); 360 if(status==U_BUFFER_OVERFLOW_ERROR){ 361 status=U_ZERO_ERROR; 362 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 363 unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status); 364 } 365 if(U_FAILURE(status)) { 366 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 367 } 368 lneed=0; 369 lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status); 370 if(status==U_BUFFER_OVERFLOW_ERROR){ 371 status=U_ZERO_ERROR; 372 pat=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 373 unum_formatDouble(fmt, FALSE, pat, lneed+1, NULL, &status); 374 } 375 log_verbose("Pattern \" %s \" \n", u_austrcpy(tempBuf, pat)); 376 log_verbose("Format 1234.56 -> %s\n", u_austrcpy(tempBuf, str) ); 377 if(U_SUCCESS(status) && str) { 378 res=(UChar*)malloc(sizeof(UChar) * (strlen("$1,234.56")+1) ); 379 u_uastrcpy(res, "$1,234.56"); 380 if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n"); 381 } else { 382 log_err_status(status, "Error formatting -> %s\n", u_errorName(status)); 383 } 384 free(str); 385 free(res); 386 free(pat); 387 388 lneed=0; 389 lneed=unum_formatDouble(fmt, -1234.56, NULL, lneed, NULL, &status); 390 if(status==U_BUFFER_OVERFLOW_ERROR){ 391 status=U_ZERO_ERROR; 392 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 393 unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status); 394 } 395 if(U_FAILURE(status)) { 396 log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) ); 397 } 398 if(str) { 399 res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) ); 400 u_uastrcpy(res, "-$1,234.56"); 401 if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n"); 402 free(str); 403 free(res); 404 } 405 406 unum_close(fmt); 407 free(pattern); 408 } 409 410 /** 411 * Test localized currency patterns. 412 */ 413 static void TestCurrency(void) 414 { 415 UNumberFormat *currencyFmt; 416 UChar *str; 417 int32_t lneed, i; 418 UFieldPosition pos; 419 UChar res[100]; 420 UErrorCode status = U_ZERO_ERROR; 421 const char* locale[]={"fr_CA", "de_DE_PREEURO", "fr_FR_PREEURO"}; 422 const char* result[]={"1,50\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"}; 423 log_verbose("\nTesting the number format with different currency patterns\n"); 424 for(i=0; i < 3; i++) 425 { 426 str=NULL; 427 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status); 428 429 if(U_FAILURE(status)){ 430 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", 431 myErrorName(status)); 432 } else { 433 lneed=0; 434 lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status); 435 if(status==U_BUFFER_OVERFLOW_ERROR){ 436 status=U_ZERO_ERROR; 437 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 438 pos.field = 0; 439 unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status); 440 } 441 442 if(U_FAILURE(status)) { 443 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); 444 } else { 445 u_unescape(result[i], res, (int32_t)strlen(result[i])+1); 446 447 if (u_strcmp(str, res) != 0){ 448 log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i], aescstrdup(str, -1), locale[i]); 449 } 450 } 451 } 452 453 unum_close(currencyFmt); 454 free(str); 455 } 456 } 457 /** 458 * Test localized currency patterns for PREEURO variants. 459 */ 460 static void TestCurrencyPreEuro(void) 461 { 462 UNumberFormat *currencyFmt; 463 UChar *str=NULL, *res=NULL; 464 int32_t lneed, i; 465 UFieldPosition pos; 466 UErrorCode status = U_ZERO_ERROR; 467 468 const char* locale[]={ 469 "ca_ES_PREEURO", "de_LU_PREEURO", "en_IE_PREEURO", "fi_FI_PREEURO", "fr_LU_PREEURO", "it_IT_PREEURO", 470 "pt_PT_PREEURO", "de_AT_PREEURO", "el_GR_PREEURO", "es_ES_PREEURO", "fr_BE_PREEURO", "ga_IE_PREEURO", 471 "nl_BE_PREEURO", "de_DE_PREEURO", "en_BE_PREEURO", "eu_ES_PREEURO", "fr_FR_PREEURO", "gl_ES_PREEURO", 472 "nl_NL_PREEURO", 473 }; 474 475 const char* result[]={ 476 "\\u20A7\\u00A02", "2\\u00A0F", "IEP1.50", "1,50\\u00A0mk", "2\\u00A0F", "ITL\\u00A02", 477 "1$50\\u00A0\\u200B", "\\u00F6S\\u00A01,50", "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB", "IEP1.50", 478 "1,50\\u00A0BEF", "1,50\\u00A0DM", "1,50\\u00A0BEF", "\\u20A7\\u00A02", "1,50\\u00A0F", "2\\u00A0\\u20A7", 479 "NLG\\u00A01,50" 480 }; 481 482 log_verbose("\nTesting the number format with different currency patterns\n"); 483 for(i=0; i < 19; i++) 484 { 485 char curID[256] = {0}; 486 uloc_canonicalize(locale[i], curID, 256, &status); 487 if(U_FAILURE(status)){ 488 log_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status)); 489 continue; 490 } 491 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status); 492 493 if(U_FAILURE(status)){ 494 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", 495 myErrorName(status)); 496 } else { 497 lneed=0; 498 lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status); 499 500 if(status==U_BUFFER_OVERFLOW_ERROR){ 501 status=U_ZERO_ERROR; 502 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 503 pos.field = 0; 504 unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status); 505 } 506 507 if(U_FAILURE(status)) { 508 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); 509 } else { 510 res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) ); 511 u_unescape(result[i],res,(int32_t)(strlen(result[i])+1)); 512 513 if (u_strcmp(str, res) != 0){ 514 log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]); 515 } 516 } 517 } 518 519 unum_close(currencyFmt); 520 free(str); 521 free(res); 522 } 523 } 524 525 /** 526 * Test currency "object" (we use this name to match the other C++ 527 * test name and the Jave name). Actually, test ISO currency code 528 * support in the C API. 529 */ 530 static void TestCurrencyObject(void) 531 { 532 UNumberFormat *currencyFmt; 533 UChar *str=NULL, *res=NULL; 534 int32_t lneed, i; 535 UFieldPosition pos; 536 UErrorCode status = U_ZERO_ERROR; 537 538 const char* locale[]={ 539 "fr_FR", 540 "fr_FR", 541 }; 542 543 const char* currency[]={ 544 "", 545 "JPY", 546 }; 547 548 const char* result[]={ 549 "1\\u00A0234,56\\u00A0\\u20AC", 550 "1\\u00A0235\\u00A0JPY", 551 }; 552 553 log_verbose("\nTesting the number format with different currency codes\n"); 554 for(i=0; i < 2; i++) 555 { 556 char cStr[20]={0}; 557 UChar isoCode[16]={0}; 558 currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status); 559 if(U_FAILURE(status)){ 560 log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n", 561 myErrorName(status)); 562 } else { 563 if (*currency[i]) { 564 u_uastrcpy(isoCode, currency[i]); 565 unum_setTextAttribute(currencyFmt, UNUM_CURRENCY_CODE, 566 isoCode, u_strlen(isoCode), &status); 567 568 if(U_FAILURE(status)) { 569 log_err("FAIL: can't set currency code %s\n", myErrorName(status) ); 570 } 571 } 572 573 unum_getTextAttribute(currencyFmt, UNUM_CURRENCY_CODE, 574 isoCode, sizeof(isoCode), &status); 575 576 if(U_FAILURE(status)) { 577 log_err("FAIL: can't get currency code %s\n", myErrorName(status) ); 578 } 579 580 u_UCharsToChars(isoCode,cStr,u_strlen(isoCode)); 581 log_verbose("ISO code %s\n", cStr); 582 if (*currency[i] && uprv_strcmp(cStr, currency[i])) { 583 log_err("FAIL: currency should be %s, but is %s\n", currency[i], cStr); 584 } 585 586 lneed=0; 587 lneed= unum_formatDouble(currencyFmt, 1234.56, NULL, lneed, NULL, &status); 588 if(status==U_BUFFER_OVERFLOW_ERROR){ 589 status=U_ZERO_ERROR; 590 str=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 591 pos.field = 0; 592 unum_formatDouble(currencyFmt, 1234.56, str, lneed+1, &pos, &status); 593 } 594 if(U_FAILURE(status)) { 595 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); 596 } else { 597 res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) ); 598 u_unescape(result[i],res, (int32_t)(strlen(result[i])+1)); 599 if (u_strcmp(str, res) != 0){ 600 log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]); 601 } 602 } 603 } 604 605 unum_close(currencyFmt); 606 free(str); 607 free(res); 608 } 609 } 610 611 /** 612 * Test proper rounding by the format method. 613 */ 614 static void TestRounding487(void) 615 { 616 UNumberFormat *nnf; 617 UErrorCode status = U_ZERO_ERROR; 618 /* this is supposed to open default date format, but later on it treats it like it is "en_US" 619 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ 620 /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */ 621 nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status); 622 623 if(U_FAILURE(status)){ 624 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status)); 625 } else { 626 roundingTest(nnf, 0.00159999, 4, "0.0016"); 627 roundingTest(nnf, 0.00995, 4, "0.01"); 628 629 roundingTest(nnf, 12.3995, 3, "12.4"); 630 631 roundingTest(nnf, 12.4999, 0, "12"); 632 roundingTest(nnf, - 19.5, 0, "-20"); 633 } 634 635 unum_close(nnf); 636 } 637 638 /*-------------------------------------*/ 639 640 static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected) 641 { 642 UChar *out = NULL; 643 UChar *res; 644 UFieldPosition pos; 645 UErrorCode status; 646 int32_t lneed; 647 status=U_ZERO_ERROR; 648 unum_setAttribute(nf, UNUM_MAX_FRACTION_DIGITS, maxFractionDigits); 649 lneed=0; 650 lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status); 651 if(status==U_BUFFER_OVERFLOW_ERROR){ 652 status=U_ZERO_ERROR; 653 out=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 654 pos.field=0; 655 unum_formatDouble(nf, x, out, lneed+1, &pos, &status); 656 } 657 if(U_FAILURE(status)) { 658 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); 659 } 660 /*Need to use log_verbose here. Problem with the float*/ 661 /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/ 662 res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) ); 663 u_uastrcpy(res, expected); 664 if (u_strcmp(out, res) != 0) 665 log_err("FAIL: Expected: %s or %s\n", expected, austrdup(res) ); 666 free(res); 667 if(out != NULL) { 668 free(out); 669 } 670 } 671 672 /* 673 * Testing unum_getDoubleAttribute and unum_setDoubleAttribute() 674 */ 675 static void TestDoubleAttribute(void) 676 { 677 double mydata[] = { 1.11, 22.22, 333.33, 4444.44, 55555.55, 666666.66, 7777777.77, 88888888.88, 999999999.99}; 678 double dvalue; 679 int i; 680 UErrorCode status=U_ZERO_ERROR; 681 UNumberFormatAttribute attr; 682 UNumberFormatStyle style= UNUM_DEFAULT; 683 UNumberFormat *def; 684 685 log_verbose("\nTesting get and set DoubleAttributes\n"); 686 def=unum_open(style, NULL,0,NULL,NULL, &status); 687 688 if (U_FAILURE(status)) { 689 log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status)); 690 } else { 691 attr=UNUM_ROUNDING_INCREMENT; 692 dvalue=unum_getDoubleAttribute(def, attr); 693 for (i = 0; i<9 ; i++) 694 { 695 dvalue = mydata[i]; 696 unum_setDoubleAttribute(def, attr, dvalue); 697 if(unum_getDoubleAttribute(def,attr)!=mydata[i]) 698 log_err("Fail: error in setting and getting double attributes for UNUM_ROUNDING_INCREMENT\n"); 699 else 700 log_verbose("Pass: setting and getting double attributes for UNUM_ROUNDING_INCREMENT works fine\n"); 701 } 702 } 703 704 unum_close(def); 705 } 706 707 /** 708 * Test the functioning of the secondary grouping value. 709 */ 710 static void TestSecondaryGrouping(void) { 711 UErrorCode status = U_ZERO_ERROR; 712 UNumberFormat *f = NULL, *g= NULL; 713 UNumberFormat *us = unum_open(UNUM_DECIMAL,NULL,0, "en_US", NULL,&status); 714 UFieldPosition pos; 715 UChar resultBuffer[512]; 716 int32_t l = 1876543210L; 717 UBool ok = TRUE; 718 UChar buffer[512]; 719 int32_t i; 720 UBool expectGroup = FALSE, isGroup = FALSE; 721 722 u_uastrcpy(buffer, "#,##,###"); 723 f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status); 724 if (U_FAILURE(status)) { 725 log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status)); 726 return; 727 } 728 729 pos.field = 0; 730 unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status); 731 u_uastrcpy(buffer, "12,34,56,789"); 732 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) 733 { 734 log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,34,56,789"); 735 } 736 if (pos.beginIndex != 0 && pos.endIndex != 12) { 737 log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex); 738 } 739 memset(resultBuffer,0, sizeof(UChar)*512); 740 unum_toPattern(f, FALSE, resultBuffer, 512, &status); 741 u_uastrcpy(buffer, "#,##,###"); 742 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) 743 { 744 log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,##,###"); 745 } 746 memset(resultBuffer,0, sizeof(UChar)*512); 747 u_uastrcpy(buffer, "#,###"); 748 unum_applyPattern(f, FALSE, buffer, -1,NULL,NULL); 749 if (U_FAILURE(status)) 750 { 751 log_err("Fail: applyPattern call failed\n"); 752 } 753 unum_setAttribute(f, UNUM_SECONDARY_GROUPING_SIZE, 4); 754 unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status); 755 u_uastrcpy(buffer, "12,3456,789"); 756 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) 757 { 758 log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,3456,789"); 759 } 760 memset(resultBuffer,0, sizeof(UChar)*512); 761 unum_toPattern(f, FALSE, resultBuffer, 512, &status); 762 u_uastrcpy(buffer, "#,####,###"); 763 if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status)) 764 { 765 log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,####,###"); 766 } 767 memset(resultBuffer,0, sizeof(UChar)*512); 768 g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status); 769 if (U_FAILURE(status)) 770 { 771 log_err("Fail: Cannot create UNumberFormat for \"hi_IN\" locale.\n"); 772 } 773 774 unum_format(g, l, resultBuffer, 512, &pos, &status); 775 unum_close(g); 776 /* expect "1,87,65,43,210", but with Hindi digits */ 777 /* 01234567890123 */ 778 if (u_strlen(resultBuffer) != 14) { 779 ok = FALSE; 780 } else { 781 for (i=0; i<u_strlen(resultBuffer); ++i) { 782 expectGroup = FALSE; 783 switch (i) { 784 case 1: 785 case 4: 786 case 7: 787 case 10: 788 expectGroup = TRUE; 789 break; 790 } 791 /* Later -- fix this to get the actual grouping */ 792 /* character from the resource bundle. */ 793 isGroup = (UBool)(resultBuffer[i] == 0x002C); 794 if (isGroup != expectGroup) { 795 ok = FALSE; 796 break; 797 } 798 } 799 } 800 if (!ok) { 801 log_err("FAIL Expected %s x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got %s\n", "1876543210L", resultBuffer); 802 } 803 unum_close(f); 804 unum_close(us); 805 } 806 807 static void TestCurrencyKeywords(void) 808 { 809 static const char * const currencies[] = { 810 "ADD", "ADP", "AED", "AFA", "AFN", "AIF", "ALK", "ALL", "ALV", "ALX", "AMD", 811 "ANG", "AOA", "AOK", "AON", "AOR", "AOS", "ARA", "ARM", "ARP", "ARS", "ATS", 812 "AUD", "AUP", "AWG", "AZM", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF", 813 "BEL", "BGL", "BGM", "BGN", "BGO", "BGX", "BHD", "BIF", "BMD", "BMP", "BND", 814 "BOB", "BOL", "BOP", "BOV", "BRB", "BRC", "BRE", "BRL", "BRN", "BRR", "BRZ", 815 "BSD", "BSP", "BTN", "BTR", "BUK", "BUR", "BWP", "BYB", "BYL", "BYR", "BZD", 816 "BZH", "CAD", "CDF", "CDG", "CDL", "CFF", "CHF", "CKD", "CLC", "CLE", "CLF", 817 "CLP", "CMF", "CNP", "CNX", "CNY", "COB", "COF", "COP", "CRC", "CSC", "CSK", 818 "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK", 819 "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB", 820 "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF", 821 "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP", 822 "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF", 823 "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP", 824 "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD", 825 "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO", 826 "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR", 827 "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF", 828 "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL", 829 "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP", 830 "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP", 831 "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG", 832 "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN", 833 "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP", 834 "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR", 835 "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK", 836 "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC", 837 "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS", 838 "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS", 839 "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD", 840 "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST", 841 "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR", 842 "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS", 843 "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR", 844 "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD" 845 }; 846 847 UErrorCode status = U_ZERO_ERROR; 848 int32_t i = 0, j = 0; 849 int32_t noLocales = uloc_countAvailable(); 850 char locale[256]; 851 char currLoc[256]; 852 UChar result[4]; 853 UChar currBuffer[256]; 854 855 856 for(i = 0; i < noLocales; i++) { 857 strcpy(currLoc, uloc_getAvailable(i)); 858 for(j = 0; j < UPRV_LENGTHOF(currencies); j++) { 859 strcpy(locale, currLoc); 860 strcat(locale, "@currency="); 861 strcat(locale, currencies[j]); 862 ucurr_forLocale(locale, result, 4, &status); 863 u_charsToUChars(currencies[j], currBuffer, 3); 864 currBuffer[3] = 0; 865 if(u_strcmp(currBuffer, result) != 0) { 866 log_err("Didn't get the right currency for %s\n", locale); 867 } 868 } 869 870 } 871 } 872 873 static void TestGetKeywordValuesForLocale(void) { 874 #define PREFERRED_SIZE 15 875 #define MAX_NUMBER_OF_KEYWORDS 4 876 const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = { 877 { "root", "USD", "USN", NULL }, 878 { "und", "USD", "USN", NULL }, 879 /* { "und_ZZ", "USD", NULL, NULL }, -- temporarily remove as this locale now has 15 entries */ 880 { "en_US", "USD", "USN", NULL }, 881 { "en_029", "USD", "USN", NULL }, 882 { "en_TH", "THB", NULL, NULL }, 883 { "de", "EUR", NULL, NULL }, 884 { "de_DE", "EUR", NULL, NULL }, 885 { "ar", "EGP", NULL, NULL }, 886 { "ar_PS", "ILS", "JOD", NULL }, 887 { "en@currency=CAD", "USD", "USN", NULL }, 888 { "fr@currency=zzz", "EUR", NULL, NULL }, 889 { "de_DE@currency=DEM", "EUR", NULL, NULL }, 890 { "en_US@rg=THZZZZ", "THB", NULL, NULL }, 891 { "de@rg=USZZZZ", "USD", "USN", NULL }, 892 { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL }, 893 }; 894 const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = { 895 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1 896 }; 897 /* ucurr_forLocale results for same locales; "" if no result expected */ 898 const char *FORLOCALE[PREFERRED_SIZE] = { 899 "", "", "USD", "", 900 "THB", "", "EUR", "", 901 "ILS", "CAD", "ZZZ", "DEM", 902 "THB", "USD", "CAD" 903 }; 904 UErrorCode status = U_ZERO_ERROR; 905 int32_t i, j, size; 906 UEnumeration *pref, *all; 907 const char *loc = NULL; 908 UBool matchPref, matchAll; 909 const char *value = NULL; 910 int32_t valueLength = 0; 911 912 UList *ALLList = NULL; 913 914 UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status); 915 if (ALL == NULL) { 916 log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status)); 917 return; 918 } 919 920 for (i = 0; i < PREFERRED_SIZE; i++) { 921 UChar getCurrU[4]; 922 int32_t getCurrLen; 923 924 status = U_ZERO_ERROR; 925 pref = NULL; 926 all = NULL; 927 loc = PREFERRED[i][0]; 928 pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status); 929 matchPref = FALSE; 930 matchAll = FALSE; 931 932 size = uenum_count(pref, &status); 933 934 if (size == EXPECTED_SIZE[i]) { 935 matchPref = TRUE; 936 for (j = 0; j < size; j++) { 937 if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) { 938 if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) { 939 log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]); 940 941 matchPref = FALSE; 942 break; 943 } 944 } else { 945 matchPref = FALSE; 946 log_err("ERROR getting keyword value for locale \"%s\"\n", loc); 947 break; 948 } 949 } 950 } else { 951 log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]); 952 } 953 954 if (!matchPref) { 955 log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc); 956 break; 957 } 958 uenum_close(pref); 959 960 all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status); 961 962 size = uenum_count(all, &status); 963 964 if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) { 965 matchAll = TRUE; 966 ALLList = ulist_getListFromEnum(ALL); 967 for (j = 0; j < size; j++) { 968 if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) { 969 if (!ulist_containsString(ALLList, value, uprv_strlen(value))) { 970 log_err("Locale %s have %s not in ALL\n", loc, value); 971 matchAll = FALSE; 972 break; 973 } 974 } else { 975 matchAll = FALSE; 976 log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc); 977 break; 978 } 979 } 980 if (!matchAll) { 981 log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc); 982 } 983 } else { 984 if(U_FAILURE(status)) { 985 log_err("ERROR: %s\n", u_errorName(status)); 986 } else if(size!=uenum_count(ALL, &status)) { 987 log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status)); 988 } 989 } 990 991 uenum_close(all); 992 993 status = U_ZERO_ERROR; 994 getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status); 995 if(U_FAILURE(status)) { 996 if (FORLOCALE[i][0] != 0) { 997 log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status)); 998 } 999 } else if (getCurrLen != 3) { 1000 if (FORLOCALE[i][0] != 0 || getCurrLen != -1) { 1001 log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen); 1002 } 1003 } else { 1004 char getCurrB[4]; 1005 u_UCharsToChars(getCurrU, getCurrB, 4); 1006 if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) { 1007 log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB); 1008 } 1009 } 1010 } 1011 1012 uenum_close(ALL); 1013 1014 } 1015 1016 /** 1017 * Test proper handling of rounding modes. 1018 */ 1019 static void TestRounding5350(void) 1020 { 1021 UNumberFormat *nnf; 1022 UErrorCode status = U_ZERO_ERROR; 1023 /* this is supposed to open default date format, but later on it treats it like it is "en_US" 1024 - very bad if you try to run the tests on machine where default locale is NOT "en_US" */ 1025 /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */ 1026 nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status); 1027 1028 if(U_FAILURE(status)){ 1029 log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status)); 1030 return; 1031 } 1032 1033 unum_setAttribute(nnf, UNUM_MAX_FRACTION_DIGITS, 2); 1034 roundingTest2(nnf, -0.125, UNUM_ROUND_CEILING, "-0.12"); 1035 roundingTest2(nnf, -0.125, UNUM_ROUND_FLOOR, "-0.13"); 1036 roundingTest2(nnf, -0.125, UNUM_ROUND_DOWN, "-0.12"); 1037 roundingTest2(nnf, -0.125, UNUM_ROUND_UP, "-0.13"); 1038 roundingTest2(nnf, 0.125, UNUM_FOUND_HALFEVEN, "0.12"); 1039 roundingTest2(nnf, 0.135, UNUM_ROUND_HALFDOWN, "0.13"); 1040 roundingTest2(nnf, 0.125, UNUM_ROUND_HALFUP, "0.13"); 1041 roundingTest2(nnf, 0.135, UNUM_FOUND_HALFEVEN, "0.14"); 1042 /* The following are exactly represented, and shouldn't round */ 1043 roundingTest2(nnf, 1.00, UNUM_ROUND_UP, "1"); 1044 roundingTest2(nnf, 24.25, UNUM_ROUND_UP, "24.25"); 1045 roundingTest2(nnf, 24.25, UNUM_ROUND_CEILING, "24.25"); 1046 roundingTest2(nnf, -24.25, UNUM_ROUND_UP, "-24.25"); 1047 1048 /* Differences pretty far out there */ 1049 roundingTest2(nnf, 1.0000001, UNUM_ROUND_CEILING, "1.01"); 1050 roundingTest2(nnf, 1.0000001, UNUM_ROUND_FLOOR, "1"); 1051 roundingTest2(nnf, 1.0000001, UNUM_ROUND_DOWN, "1"); 1052 roundingTest2(nnf, 1.0000001, UNUM_ROUND_UP, "1.01"); 1053 roundingTest2(nnf, 1.0000001, UNUM_FOUND_HALFEVEN, "1"); 1054 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFDOWN, "1"); 1055 roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFUP, "1"); 1056 1057 roundingTest2(nnf, -1.0000001, UNUM_ROUND_CEILING, "-1"); 1058 roundingTest2(nnf, -1.0000001, UNUM_ROUND_FLOOR, "-1.01"); 1059 roundingTest2(nnf, -1.0000001, UNUM_ROUND_DOWN, "-1"); 1060 roundingTest2(nnf, -1.0000001, UNUM_ROUND_UP, "-1.01"); 1061 roundingTest2(nnf, -1.0000001, UNUM_FOUND_HALFEVEN, "-1"); 1062 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFDOWN, "-1"); 1063 roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFUP, "-1"); 1064 1065 unum_close(nnf); 1066 } 1067 1068 /*-------------------------------------*/ 1069 1070 static void roundingTest2(UNumberFormat* nf, double x, int32_t roundingMode, const char* expected) 1071 { 1072 UChar *out = NULL; 1073 UChar *res; 1074 UFieldPosition pos; 1075 UErrorCode status; 1076 int32_t lneed; 1077 status=U_ZERO_ERROR; 1078 unum_setAttribute(nf, UNUM_ROUNDING_MODE, roundingMode); 1079 lneed=0; 1080 lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status); 1081 if(status==U_BUFFER_OVERFLOW_ERROR){ 1082 status=U_ZERO_ERROR; 1083 out=(UChar*)malloc(sizeof(UChar) * (lneed+1) ); 1084 pos.field=0; 1085 unum_formatDouble(nf, x, out, lneed+1, &pos, &status); 1086 } 1087 if(U_FAILURE(status)) { 1088 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) ); 1089 } 1090 /*Need to use log_verbose here. Problem with the float*/ 1091 /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/ 1092 res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) ); 1093 u_uastrcpy(res, expected); 1094 if (u_strcmp(out, res) != 0) 1095 log_err("FAIL: Expected: \"%s\" Got: \"%s\"\n", expected, austrdup(out) ); 1096 free(res); 1097 if(out != NULL) { 1098 free(out); 1099 } 1100 } 1101 1102 #endif /* #if !UCONFIG_NO_FORMATTING */ 1103