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