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