]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/cintltst/cnmdptst.c
ICU-64232.0.1.tar.gz
[apple/icu.git] / icuSources / test / cintltst / cnmdptst.c
index 24982323adee8f402294579c1c6213f6feddc603..1af298e1d85c7834e32be91465152dfd2c36f70b 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /********************************************************************
- * COPYRIGHT: 
- * Copyright (c) 1997-2006, International Business Machines Corporation
+ * COPYRIGHT:
+ * Copyright (c) 1997-2016, International Business Machines Corporation
  * and others. All Rights Reserved.
  ********************************************************************/
 /*******************************************************************************
 #include "unicode/uloc.h"
 #include "unicode/unum.h"
 #include "unicode/ustring.h"
+#include "unicode/putil.h"
 #include "cintltst.h"
 #include "cnmdptst.h"
 #include "cmemory.h"
 #include "cstring.h"
+#include "ulist.h"
 
 #define CHECK(status,str) if (U_FAILURE(status)) { log_err("FAIL: %s\n", str); return; }
 
 void addNumFrDepTest(TestNode** root);
-static void TestCurrencyPreEuro(void);
 static void TestCurrencyObject(void);
 
 void addNumFrDepTest(TestNode** root)
@@ -43,12 +46,13 @@ void addNumFrDepTest(TestNode** root)
   addTest(root, &TestExponential, "tsformat/cnmdptst/TestExponential");
   addTest(root, &TestCurrencySign, "tsformat/cnmdptst/TestCurrencySign");
   addTest(root, &TestCurrency,  "tsformat/cnmdptst/TestCurrency");
-  addTest(root, &TestCurrencyPreEuro,  "tsformat/cnmdptst/TestCurrencyPreEuro");
   addTest(root, &TestCurrencyObject,  "tsformat/cnmdptst/TestCurrencyObject");
   addTest(root, &TestRounding487, "tsformat/cnmdptst/TestRounding487");
   addTest(root, &TestDoubleAttribute, "tsformat/cnmdptst/TestDoubleAttribute");
   addTest(root, &TestSecondaryGrouping, "tsformat/cnmdptst/TestSecondaryGrouping");
   addTest(root, &TestCurrencyKeywords, "tsformat/cnmdptst/TestCurrencyKeywords");
+  addTest(root, &TestRounding5350, "tsformat/cnmdptst/TestRounding5350");
+  addTest(root, &TestGetKeywordValuesForLocale, "tsformat/cnmdptst/TestGetKeywordValuesForLocale");
 }
 
 /*Test Various format patterns*/
@@ -63,19 +67,19 @@ static void TestPatterns(void)
     UChar *str=NULL;
     UErrorCode status = U_ZERO_ERROR;
     const char* pat[]    = { "#.#", "#.", ".#", "#" };
-    const char* newpat[] = { "#0.#", "#0.", "#.0", "#" };
+    const char* newpat[] = { "0.#", "0.", "#.0", "0" };
     const char* num[]    = { "0",   "0.", ".0", "0" };
-    
+
     log_verbose("\nTesting different format patterns\n");
-    pat_length = sizeof(pat) / sizeof(pat[0]);
+    pat_length = UPRV_LENGTHOF(pat);
     for (i=0; i < pat_length; ++i)
     {
         status = U_ZERO_ERROR;
         u_uastrcpy(upat, pat[i]);
         fmt= unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status);
         if (U_FAILURE(status)) {
-            log_err("FAIL: Number format constructor failed for pattern %s\n", pat[i]);
-            continue; 
+            log_err_status(status, "FAIL: Number format constructor failed for pattern %s -> %s\n", pat[i], u_errorName(status));
+            continue;
         }
         lneed=0;
         lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status);
@@ -90,7 +94,7 @@ static void TestPatterns(void)
         u_uastrcpy(unewpat, newpat[i]);
         if(u_strcmp(unewp, unewpat) != 0)
             log_err("FAIL: Pattern  %s should be transmute to %s; %s seen instead\n", pat[i], newpat[i],  austrdup(unewp) );
-        
+
         lneed=0;
         lneed=unum_format(fmt, 0, NULL, lneed, NULL, &status);
         if(status==U_BUFFER_OVERFLOW_ERROR){
@@ -105,7 +109,7 @@ static void TestPatterns(void)
         if (u_strcmp(str, unum) != 0)
         {
             log_err("FAIL: Pattern %s should format zero as %s; %s Seen instead\n", pat[i], num[i], austrdup(str) );
-            
+
         }
         free(unewp);
         free(str);
@@ -127,7 +131,7 @@ static void TestQuotes(void)
     u_uastrcpy(pat, "a'fo''o'b#");
     fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status);
     if(U_FAILURE(status)){
-        log_err("Error in number format costruction using pattern \"a'fo''o'b#\"\n");
+        log_err_status(status, "Error in number format costruction using pattern \"a'fo''o'b#\" -> %s\n", u_errorName(status));
     }
     lneed=0;
     lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status);
@@ -137,7 +141,7 @@ static void TestQuotes(void)
         unum_format(fmt, 123, str, lneed+1,  NULL, &status);
     }
     if(U_FAILURE(status) || !str) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
         return;
     }
     log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) );
@@ -145,15 +149,15 @@ static void TestQuotes(void)
     u_uastrcpy(res, "afo'ob123");
     if(u_strcmp(str, res) != 0)
         log_err("FAIL: Expected afo'ob123");
-    
+
     free(str);
     unum_close(fmt);
-    
-    
+
+
     u_uastrcpy(pat, "");
     u_uastrcpy(pat, "a''b#");
-    
-    
+
+
     fmt =unum_open(UNUM_IGNORE,pat, u_strlen(pat), "en_US",NULL, &status);
     if(U_FAILURE(status)){
         log_err("Error in number format costruction using pattern \"a''b#\"\n");
@@ -174,7 +178,7 @@ static void TestQuotes(void)
     u_uastrcpy(res, "a'b123");
     if(u_strcmp(str, res) != 0)
         log_err("FAIL: Expected a'b123\n");
-    
+
     free(str);
     unum_close(fmt);
 }
@@ -193,14 +197,14 @@ static void TestExponential(void)
     char tempMsgBug[256];
     double a;
     UErrorCode status = U_ZERO_ERROR;
-#ifdef OS390
+#if U_PLATFORM == U_PF_OS390
     static const double val[] = { 0.01234, 123456789, 1.23e75, -3.141592653e-78 };
 #else
     static const double val[] = { 0.01234, 123456789, 1.23e300, -3.141592653e-271 };
 #endif
     static const char* pat[] = { "0.####E0", "00.000E00", "##0.######E000", "0.###E0;[0.###E0]" };
     static const int32_t lval[] = { 0, -1, 1, 123456789 };
-    
+
     static const char* valFormat[] =
     {
         "1.234E-2", "1.2346E8", "1.23E300", "-3.1416E-271",
@@ -217,7 +221,7 @@ static void TestExponential(void)
     };
     static const double valParse[] =
     {
-#ifdef OS390
+#if U_PLATFORM == U_PF_OS390
         0.01234, 123460000, 1.23E75, -3.1416E-78,
         0.01234, 123460000, 1.23E75, -3.1416E-78,
         0.01234, 123456800, 1.23E75, -3.141593E-78,
@@ -238,11 +242,11 @@ static void TestExponential(void)
             0, -1, 1, 123456800,
             0, -1, 1, 123500000
     };
-    
-    
-    pat_length = sizeof(pat) / sizeof(pat[0]);
-    val_length = sizeof(val) / sizeof(val[0]);
-    lval_length = sizeof(lval) / sizeof(lval[0]);
+
+
+    pat_length = UPRV_LENGTHOF(pat);
+    val_length = UPRV_LENGTHOF(val);
+    lval_length = UPRV_LENGTHOF(lval);
     ival = 0;
     ilval = 0;
     for (p=0; p < pat_length; ++p)
@@ -250,9 +254,9 @@ static void TestExponential(void)
         upat=(UChar*)malloc(sizeof(UChar) * (strlen(pat[p])+1) );
         u_uastrcpy(upat, pat[p]);
         fmt=unum_open(UNUM_IGNORE,upat, u_strlen(upat), "en_US",NULL, &status);
-        if (U_FAILURE(status)) { 
-            log_err("FAIL: Bad status returned by Number format construction with pattern %s\n, pat[i]"); 
-            continue; 
+        if (U_FAILURE(status)) {
+            log_err_status(status, "FAIL: Bad status returned by Number format construction with pattern %s -> %s\n", pat[p], u_errorName(status));
+            continue;
         }
         lneed= u_strlen(upat) + 1;
         unum_toPattern(fmt, FALSE, pattern, lneed, &status);
@@ -260,7 +264,7 @@ static void TestExponential(void)
         for (v=0; v<val_length; ++v)
         {
             /*format*/
-            lneed=0; 
+            lneed=0;
             lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status);
             if(status==U_BUFFER_OVERFLOW_ERROR){
                 status=U_ZERO_ERROR;
@@ -270,13 +274,13 @@ static void TestExponential(void)
             if(U_FAILURE(status)) {
                 log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
             }
-            
-            
-            
+
+
+
             u_uastrcpy(uvalfor, valFormat[v+ival]);
             if(u_strcmp(str, uvalfor) != 0)
                 log_verbose("FAIL: Expected %s ( %s )\n", valFormat[v+ival], u_austrcpy(tempMsgBug, uvalfor) );
-            
+
             /*parsing*/
             ppos=0;
             a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
@@ -286,13 +290,13 @@ static void TestExponential(void)
             }
             else
                 log_err(" FAIL: Partial parse (  %d  chars ) ->  %e\n",  ppos, a);
-            
+
             free(str);
         }
         for (v=0; v<lval_length; ++v)
         {
             /*format*/
-            lneed=0; 
+            lneed=0;
             lneed=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status);
             if(status==U_BUFFER_OVERFLOW_ERROR){
                 status=U_ZERO_ERROR;
@@ -306,7 +310,7 @@ static void TestExponential(void)
             u_uastrcpy(ulvalfor, lvalFormat[v+ilval]);
             if(u_strcmp(str, ulvalfor) != 0)
                 log_err("FAIL: Expected %s ( %s )\n", valFormat[v+ilval], austrdup(ulvalfor) );
-            
+
             /*parsing*/
             ppos=0;
             a=unum_parseDouble(fmt, str, u_strlen(str), &ppos, &status);
@@ -317,9 +321,9 @@ static void TestExponential(void)
             }
             else
                 log_err(" FAIL: Partial parse (  %d  chars ) ->  %e\n",  ppos, a);
-            
+
             free(str);
-            
+
         }
         ival += val_length;
         ilval += lval_length;
@@ -341,15 +345,15 @@ static void TestCurrencySign(void)
     UChar *res=NULL;
     UErrorCode status = U_ZERO_ERROR;
     char tempBuf[256];
-    
+
     pattern=(UChar*)malloc(sizeof(UChar) * (strlen("*#,##0.00;-*#,##0.00") + 1) );
     u_uastrcpy(pattern, "*#,##0.00;-*#,##0.00");
     pattern[0]=pattern[11]=0xa4; /* insert latin-1 currency symbol */
     fmt = unum_open(UNUM_IGNORE,pattern, u_strlen(pattern), "en_US",NULL, &status);
     if(U_FAILURE(status)){
-        log_err("Error in number format construction with pattern  \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" \n");
+        log_err_status(status, "Error in number format construction with pattern  \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status));
     }
-    lneed=0; 
+    lneed=0;
     lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status);
     if(status==U_BUFFER_OVERFLOW_ERROR){
         status=U_ZERO_ERROR;
@@ -357,7 +361,7 @@ static void TestCurrencySign(void)
         unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status);
     }
     if(U_FAILURE(status)) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
     }
     lneed=0;
     lneed=unum_toPattern(fmt, FALSE, NULL, lneed, &status);
@@ -371,15 +375,15 @@ static void TestCurrencySign(void)
     if(U_SUCCESS(status) && str) {
         res=(UChar*)malloc(sizeof(UChar) * (strlen("$1,234.56")+1) );
         u_uastrcpy(res, "$1,234.56");
-        if (u_strcmp(str, res) !=0) log_err("FAIL: Expected $1,234.56\n");
+        if (u_strcmp(str, res) !=0) log_data_err("FAIL: Expected $1,234.56\n");
     } else {
-        log_err("Error formatting\n");
+        log_err_status(status, "Error formatting -> %s\n", u_errorName(status));
     }
     free(str);
     free(res);
     free(pat);
-    
-    lneed=0; 
+
+    lneed=0;
     lneed=unum_formatDouble(fmt, -1234.56, NULL, lneed, NULL, &status);
     if(status==U_BUFFER_OVERFLOW_ERROR){
         status=U_ZERO_ERROR;
@@ -387,17 +391,17 @@ static void TestCurrencySign(void)
         unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status);
     }
     if(U_FAILURE(status)) {
-        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
+        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
     }
     if(str) {
         res=(UChar*)malloc(sizeof(UChar) * (strlen("-$1,234.56")+1) );
         u_uastrcpy(res, "-$1,234.56");
-        if (u_strcmp(str, res) != 0) log_err("FAIL: Expected -$1,234.56\n");
+        if (u_strcmp(str, res) != 0) log_data_err("FAIL: Expected -$1,234.56\n");
         free(str);
         free(res);
     }
-    
-    unum_close(fmt);  
+
+    unum_close(fmt);
     free(pattern);
 }
 
@@ -412,8 +416,8 @@ static void TestCurrency(void)
     UFieldPosition pos;
     UChar res[100];
     UErrorCode status = U_ZERO_ERROR;
-    const char* locale[]={"fr_CA", "de_DE_PREEURO", "fr_FR_PREEURO"};
-    const char* result[]={"1,50 $", "1,50 DM", "1,50 F"};
+    const char* locale[]={"fr_CA", "de_DE@currency=DEM", "fr_FR@currency=FRF"};
+    const char* result[]={"1,50\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"};
     log_verbose("\nTesting the number format with different currency patterns\n");
     for(i=0; i < 3; i++)
     {
@@ -421,7 +425,7 @@ static void TestCurrency(void)
         currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
 
         if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
+            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
                 myErrorName(status));
         } else {
             lneed=0;
@@ -436,7 +440,7 @@ static void TestCurrency(void)
             if(U_FAILURE(status)) {
                 log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
             } else {
-                u_charsToUChars(result[i], res, (int32_t)strlen(result[i])+1);
+                u_unescape(result[i], res, (int32_t)strlen(result[i])+1);
 
                 if (u_strcmp(str, res) != 0){
                     log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i], aescstrdup(str, -1), locale[i]);
@@ -448,73 +452,6 @@ static void TestCurrency(void)
         free(str);
     }
 }
-/**
- * Test localized currency patterns for PREEURO variants.
- */
-static void TestCurrencyPreEuro(void)
-{
-    UNumberFormat *currencyFmt;
-    UChar *str=NULL, *res=NULL;
-    int32_t lneed, i;
-    UFieldPosition pos;
-    UErrorCode status = U_ZERO_ERROR;
-    
-    const char* locale[]={
-        "ca_ES_PREEURO",  "de_LU_PREEURO",  "en_IE_PREEURO",              "fi_FI_PREEURO",  "fr_LU_PREEURO",  "it_IT_PREEURO",  
-        "pt_PT_PREEURO",  "de_AT_PREEURO",  "el_GR_PREEURO",              "es_ES_PREEURO",  "fr_BE_PREEURO",  "ga_IE_PREEURO",  
-        "nl_BE_PREEURO",  "de_DE_PREEURO",  "en_BE_PREEURO",              "eu_ES_PREEURO",  "fr_FR_PREEURO",  "gl_ES_PREEURO",  
-        "nl_NL_PREEURO",
-    };
-    
-    const char* result[]={
-        "\\u20A7 2",      "2 F",            "\\u00A31.50",                "1,50 mk",        "2 F",         "\\u20A4 2", 
-        "1$50 Esc.",      "\\u00F6S 1,50",  "1,50 \\u0394\\u03C1\\u03C7", "2 \\u20A7",      "1,50 FB",        "\\u00a31.50", 
-        "1,50 BF",        "1,50 DM",        "1,50 BF",                    "\\u20A7 2",      "1,50 F",         "\\u20A7 2", 
-        "fl 1,50"
-    };
-    
-    log_verbose("\nTesting the number format with different currency patterns\n");
-    for(i=0; i < 19; i++)
-    {
-        char curID[256] = {0};
-        uloc_canonicalize(locale[i], curID, 256, &status);
-        if(U_FAILURE(status)){
-            log_err("Could not canonicalize %s. Error: %s \n", locale[i], u_errorName(status));
-            continue;
-        }
-        currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status);
-
-        if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
-                myErrorName(status));
-        } else {
-            lneed=0;
-            lneed= unum_formatDouble(currencyFmt, 1.50, NULL, lneed, NULL, &status);
-
-            if(status==U_BUFFER_OVERFLOW_ERROR){
-                status=U_ZERO_ERROR;
-                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
-                pos.field = 0;
-                unum_formatDouble(currencyFmt, 1.50, str, lneed+1, &pos, &status);
-            }
-
-            if(U_FAILURE(status)) {
-                log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
-            } else {
-                res=(UChar*)malloc(sizeof(UChar) * (strlen(result[i])+1) );
-                u_unescape(result[i],res,(int32_t)(strlen(result[i])+1));
-
-                if (u_strcmp(str, res) != 0){
-                    log_err("FAIL: Expected %s Got: %s for locale: %s\n", result[i],aescstrdup(str, -1),locale[i]);
-                }
-            }
-        }
-            
-        unum_close(currencyFmt);
-        free(str);
-        free(res);
-    }
-}
 
 /**
  * Test currency "object" (we use this name to match the other C++
@@ -528,22 +465,22 @@ static void TestCurrencyObject(void)
     int32_t lneed, i;
     UFieldPosition pos;
     UErrorCode status = U_ZERO_ERROR;
-    
+
     const char* locale[]={
         "fr_FR",
-            "fr_FR",
+        "fr_FR",
     };
-    
+
     const char* currency[]={
         "",
-            "JPY",
+        "JPY",
     };
-    
+
     const char* result[]={
-        "1\\u00A0234,56 \\u20AC",
-            "1\\u00A0235 \\u00A5",
+        "1\\u202F234,56\\u00A0\\u20AC",
+        "1\\u202F235\\u00A0JPY",
     };
-    
+
     log_verbose("\nTesting the number format with different currency codes\n");
     for(i=0; i < 2; i++)
     {
@@ -551,7 +488,7 @@ static void TestCurrencyObject(void)
         UChar isoCode[16]={0};
         currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
         if(U_FAILURE(status)){
-            log_err("Error in the construction of number format with style currency:\n%s\n",
+            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\n",
                 myErrorName(status));
         } else {
             if (*currency[i]) {
@@ -576,7 +513,7 @@ static void TestCurrencyObject(void)
             if (*currency[i] && uprv_strcmp(cStr, currency[i])) {
                 log_err("FAIL: currency should be %s, but is %s\n", currency[i], cStr);
             }
-            
+
             lneed=0;
             lneed= unum_formatDouble(currencyFmt, 1234.56, NULL, lneed, NULL, &status);
             if(status==U_BUFFER_OVERFLOW_ERROR){
@@ -595,7 +532,7 @@ static void TestCurrencyObject(void)
                 }
             }
         }
-        
+
         unum_close(currencyFmt);
         free(str);
         free(res);
@@ -609,28 +546,28 @@ static void TestRounding487(void)
 {
     UNumberFormat *nnf;
     UErrorCode status = U_ZERO_ERROR;
-    /* this is supposed to open default date format, but later on it treats it like it is "en_US" 
+    /* this is supposed to open default date format, but later on it treats it like it is "en_US"
      - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
     /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
     nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
 
     if(U_FAILURE(status)){
-        log_err("FAIL: failure in the construction of number format: %s\n", myErrorName(status));
+        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
     } else {
         roundingTest(nnf, 0.00159999, 4, "0.0016");
         roundingTest(nnf, 0.00995, 4, "0.01");
-        
+
         roundingTest(nnf, 12.3995, 3, "12.4");
-        
+
         roundingTest(nnf, 12.4999, 0, "12");
         roundingTest(nnf, - 19.5, 0, "-20");
     }
 
     unum_close(nnf);
 }
+
 /*-------------------------------------*/
+
 static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits, const char* expected)
 {
     UChar *out = NULL;
@@ -664,7 +601,7 @@ static void roundingTest(UNumberFormat* nf, double x, int32_t maxFractionDigits,
 }
 
 /*
- * Testing unum_getDoubleAttribute and  unum_setDoubleAttribute() 
+ * Testing unum_getDoubleAttribute and  unum_setDoubleAttribute()
  */
 static void TestDoubleAttribute(void)
 {
@@ -680,13 +617,13 @@ static void TestDoubleAttribute(void)
     def=unum_open(style, NULL,0,NULL,NULL, &status);
 
     if (U_FAILURE(status)) {
-        log_err("Fail: error creating a default number formatter\n");
+        log_data_err("Fail: error creating a default number formatter -> %s (Are you missing data?)\n", u_errorName(status));
     } else {
         attr=UNUM_ROUNDING_INCREMENT;
         dvalue=unum_getDoubleAttribute(def, attr);
         for (i = 0; i<9 ; i++)
         {
-            dvalue = mydata[i]; 
+            dvalue = mydata[i];
             unum_setDoubleAttribute(def, attr, dvalue);
             if(unum_getDoubleAttribute(def,attr)!=mydata[i])
                 log_err("Fail: error in setting and getting double attributes for UNUM_ROUNDING_INCREMENT\n");
@@ -715,24 +652,27 @@ static void TestSecondaryGrouping(void) {
 
     u_uastrcpy(buffer, "#,##,###");
     f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status);
-    CHECK(status, "DecimalFormat ct");
+    if (U_FAILURE(status)) {
+        log_data_err("Error DecimalFormat ct -> %s (Are you missing data?)\n", u_errorName(status));
+        return;
+    }
 
     pos.field = 0;
     unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
     u_uastrcpy(buffer, "12,34,56,789");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,34,56,789");
+        log_err("Fail: Formatting \"#,##,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,34,56,789");
     }
     if (pos.beginIndex != 0 && pos.endIndex != 12) {
         log_err("Fail: Formatting \"#,##,###\" pattern pos = (%d, %d) expected pos = (0, 12)\n", pos.beginIndex, pos.endIndex);
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     unum_toPattern(f, FALSE, resultBuffer, 512, &status);
-    u_uastrcpy(buffer, "#,##,###");
+    u_uastrcpy(buffer, "#,##,##0");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,##,###");
+        log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,##,##0");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     u_uastrcpy(buffer, "#,###");
@@ -746,14 +686,14 @@ static void TestSecondaryGrouping(void) {
     u_uastrcpy(buffer, "12,3456,789");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", resultBuffer, "12,3456,789");
+        log_err("Fail: Formatting \"#,###\" pattern with 123456789 got %s, expected %s\n", austrdup(resultBuffer), "12,3456,789");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     unum_toPattern(f, FALSE, resultBuffer, 512, &status);
-    u_uastrcpy(buffer, "#,####,###");
+    u_uastrcpy(buffer, "#,####,##0");
     if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
     {
-        log_err("Fail: toPattern() got %s, expected %s\n", resultBuffer, "#,####,###");
+        log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,####,##0");
     }
     memset(resultBuffer,0, sizeof(UChar)*512);
     g = unum_open(UNUM_DECIMAL, NULL,0,"hi_IN",NULL, &status);
@@ -790,14 +730,14 @@ static void TestSecondaryGrouping(void) {
     }
     if (!ok) {
         log_err("FAIL  Expected %s x hi_IN -> \"1,87,65,43,210\" (with Hindi digits), got %s\n", "1876543210L", resultBuffer);
-    } 
+    }
     unum_close(f);
     unum_close(us);
 }
 
 static void TestCurrencyKeywords(void)
 {
-    static const char *currencies[] = { 
+    static const char * const currencies[] = {
         "ADD", "ADP", "AED", "AFA", "AFN", "AIF", "ALK", "ALL", "ALV", "ALX", "AMD",
         "ANG", "AOA", "AOK", "AON", "AOR", "AOS", "ARA", "ARM", "ARP", "ARS", "ATS",
         "AUD", "AUP", "AWG", "AZM", "BAD", "BAM", "BAN", "BBD", "BDT", "BEC", "BEF",
@@ -806,35 +746,35 @@ static void TestCurrencyKeywords(void)
         "BSD", "BSP", "BTN", "BTR", "BUK", "BUR", "BWP", "BYB", "BYL", "BYR", "BZD",
         "BZH", "CAD", "CDF", "CDG", "CDL", "CFF", "CHF", "CKD", "CLC", "CLE", "CLF",
         "CLP", "CMF", "CNP", "CNX", "CNY", "COB", "COF", "COP", "CRC", "CSC", "CSK",
-        "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK", 
-        "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB", 
-        "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF", 
-        "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP", 
-        "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF", 
-        "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP", 
-        "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD", 
-        "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO", 
-        "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR", 
-        "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF", 
-        "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL", 
-        "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP", 
-        "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP", 
-        "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG", 
-        "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN", 
-        "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP", 
-        "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR", 
-        "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK", 
-        "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC", 
-        "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS", 
-        "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS", 
-        "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD", 
-        "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST", 
-        "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR", 
-        "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS", 
-        "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR", 
+        "CUP", "CUX", "CVE", "CWG", "CYP", "CZK", "DDM", "DEM", "DES", "DJF", "DKK",
+        "DOP", "DZD", "DZF", "DZG", "ECS", "ECV", "EEK", "EGP", "ERN", "ESP", "ETB",
+        "ETD", "EUR", "FIM", "FIN", "FJD", "FJP", "FKP", "FOK", "FRF", "FRG", "GAF",
+        "GBP", "GEK", "GEL", "GHC", "GHO", "GHP", "GHR", "GIP", "GLK", "GMD", "GMP",
+        "GNF", "GNI", "GNS", "GPF", "GQE", "GQF", "GQP", "GRD", "GRN", "GTQ", "GUF",
+        "GWE", "GWM", "GWP", "GYD", "HKD", "HNL", "HRD", "HRK", "HTG", "HUF", "IBP",
+        "IDG", "IDJ", "IDN", "IDR", "IEP", "ILL", "ILP", "ILS", "IMP", "INR", "IQD",
+        "IRR", "ISK", "ITL", "JEP", "JMD", "JMP", "JOD", "JPY", "KES", "KGS", "KHO",
+        "KHR", "KID", "KMF", "KPP", "KPW", "KRH", "KRO", "KRW", "KWD", "KYD", "KZR",
+        "KZT", "LAK", "LBP", "LIF", "LKR", "LNR", "LRD", "LSL", "LTL", "LTT", "LUF",
+        "LVL", "LVR", "LYB", "LYD", "LYP", "MAD", "MAF", "MCF", "MCG", "MDC", "MDL",
+        "MDR", "MGA", "MGF", "MHD", "MKD", "MKN", "MLF", "MMK", "MMX", "MNT", "MOP",
+        "MQF", "MRO", "MTL", "MTP", "MUR", "MVP", "MVR", "MWK", "MWP", "MXN", "MXP",
+        "MXV", "MYR", "MZE", "MZM", "NAD", "NCF", "NGN", "NGP", "NHF", "NIC", "NIG",
+        "NIO", "NLG", "NOK", "NPR", "NZD", "NZP", "OMR", "OMS", "PAB", "PDK", "PDN",
+        "PDR", "PEI", "PEN", "PES", "PGK", "PHP", "PKR", "PLN", "PLX", "PLZ", "PSP",
+        "PTC", "PTE", "PYG", "QAR", "REF", "ROL", "RON", "RUB", "RUR", "RWF", "SAR",
+        "SAS", "SBD", "SCR", "SDD", "SDP", "SEK", "SGD", "SHP", "SIB", "SIT", "SKK",
+        "SLL", "SML", "SOS", "SQS", "SRG", "SSP", "STD", "STE", "SUN", "SUR", "SVC",
+        "SYP", "SZL", "TCC", "TDF", "THB", "TJR", "TJS", "TMM", "TND", "TOP", "TOS",
+        "TPE", "TPP", "TRL", "TTD", "TTO", "TVD", "TWD", "TZS", "UAH", "UAK", "UGS",
+        "UGX", "USD", "USN", "USS", "UYF", "UYP", "UYU", "UZC", "UZS", "VAL", "VDD",
+        "VDN", "VDP", "VEB", "VGD", "VND", "VNN", "VNR", "VNS", "VUV", "WSP", "WST",
+        "XAD", "XAF", "XAM", "XAU", "XBA", "XBB", "XBC", "XBD", "XCD", "XCF", "XDR",
+        "XEF", "XEU", "XFO", "XFU", "XID", "XMF", "XNF", "XOF", "XPF", "XPS", "XSS",
+        "XTR", "YDD", "YEI", "YER", "YUD", "YUF", "YUG", "YUM", "YUN", "YUO", "YUR",
         "ZAL", "ZAP", "ZAR", "ZMK", "ZMP", "ZRN", "ZRZ", "ZWD"
     };
-    
+
     UErrorCode status = U_ZERO_ERROR;
     int32_t i = 0, j = 0;
     int32_t noLocales = uloc_countAvailable();
@@ -842,11 +782,11 @@ static void TestCurrencyKeywords(void)
     char currLoc[256];
     UChar result[4];
     UChar currBuffer[256];
-    
-    
+
+
     for(i = 0; i < noLocales; i++) {
         strcpy(currLoc, uloc_getAvailable(i));
-        for(j = 0; j < sizeof(currencies)/sizeof(currencies[0]); j++) {
+        for(j = 0; j < UPRV_LENGTHOF(currencies); j++) {
             strcpy(locale, currLoc);
             strcat(locale, "@currency=");
             strcat(locale, currencies[j]);
@@ -857,7 +797,236 @@ static void TestCurrencyKeywords(void)
                 log_err("Didn't get the right currency for %s\n", locale);
             }
         }
+
+    }
+}
+
+static void TestGetKeywordValuesForLocale(void) {
+#define PREFERRED_SIZE 15
+#define MAX_NUMBER_OF_KEYWORDS 4
+    const char *PREFERRED[PREFERRED_SIZE][MAX_NUMBER_OF_KEYWORDS] = {
+            { "root",               "USD", "USN", NULL },
+            { "und",                "USD", "USN", NULL },
+ /*           { "und_ZZ",             "USD", NULL, NULL },  -- temporarily remove as this locale now has 15 entries */
+            { "en_US",              "USD", "USN", NULL },
+            { "en_029",             "USD", "USN", NULL },
+            { "en_TH",              "THB", NULL, NULL },
+            { "de",                 "EUR", NULL, NULL },
+            { "de_DE",              "EUR", NULL, NULL },
+            { "ar",                 "EGP", NULL, NULL },
+            { "ar_PS",              "ILS", "JOD", NULL },
+            { "en@currency=CAD",    "USD", "USN", NULL },
+            { "fr@currency=zzz",    "EUR", NULL, NULL },
+            { "de_DE@currency=DEM", "EUR", NULL, NULL },
+            { "en_US@rg=THZZZZ",    "THB", NULL, NULL },
+            { "de@rg=USZZZZ",       "USD", "USN", NULL },
+            { "en_US@currency=CAD;rg=THZZZZ", "THB", NULL, NULL },
+    };
+    const int32_t EXPECTED_SIZE[PREFERRED_SIZE] = {
+            2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1
+    };
+    /* ucurr_forLocale results for same locales; "" if no result expected */
+    const char *FORLOCALE[PREFERRED_SIZE] = {
+            "",    "",    "USD", "",
+            "THB", "",    "EUR", "",
+            "ILS", "CAD", "ZZZ", "DEM",
+            "THB", "USD", "CAD"
+    };
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t i, j, size;
+    UEnumeration *pref, *all;
+    const char *loc = NULL;
+    UBool matchPref, matchAll;
+    const char *value = NULL;
+    int32_t valueLength = 0;
+    
+    UList *ALLList = NULL;
+    
+    UEnumeration *ALL = ucurr_getKeywordValuesForLocale("currency", uloc_getDefault(), FALSE, &status);
+    if (ALL == NULL) {
+        log_err_status(status, "ERROR getting keyword value for default locale. -> %s\n", u_errorName(status));
+        return;
+    }
+    
+    for (i = 0; i < PREFERRED_SIZE; i++) {
+        UChar getCurrU[4];
+        int32_t getCurrLen;
+
+        status = U_ZERO_ERROR;
+        pref = NULL;
+        all = NULL;
+        loc = PREFERRED[i][0];
+        pref = ucurr_getKeywordValuesForLocale("currency", loc, TRUE, &status);
+        matchPref = FALSE;
+        matchAll = FALSE;
+        
+        size = uenum_count(pref, &status);
+        
+        if (size == EXPECTED_SIZE[i]) {
+            matchPref = TRUE;
+            for (j = 0; j < size; j++) {
+                if ((value = uenum_next(pref, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
+                    if (uprv_strcmp(value, PREFERRED[i][j+1]) != 0) {
+                        log_err("ERROR: locale %s got keywords #%d %s expected %s\n", loc, j, value, PREFERRED[i][j+1]);
+
+                        matchPref = FALSE;
+                        break;
+                    }
+                } else {
+                    matchPref = FALSE;
+                    log_err("ERROR getting keyword value for locale \"%s\"\n", loc);
+                    break;
+                }
+            }
+        } else {
+            log_err("FAIL: size of locale \"%s\" %d does not match expected size %d\n", loc, size, EXPECTED_SIZE[i]);
+        }
+        
+        if (!matchPref) {
+            log_err("FAIL: Preferred values for locale \"%s\" does not match expected.\n", loc);
+            break;
+        }
+        uenum_close(pref);
+        
+        all = ucurr_getKeywordValuesForLocale("currency", loc, FALSE, &status);
+        
+        size = uenum_count(all, &status);
         
+        if (U_SUCCESS(status) && size == uenum_count(ALL, &status)) {
+            matchAll = TRUE;
+            ALLList = ulist_getListFromEnum(ALL);
+            for (j = 0; j < size; j++) {
+                if ((value = uenum_next(all, &valueLength, &status)) != NULL && U_SUCCESS(status)) {
+                    if (!ulist_containsString(ALLList, value, (int32_t)uprv_strlen(value))) {
+                        log_err("Locale %s have %s not in ALL\n", loc, value);
+                        matchAll = FALSE;
+                        break;
+                    }
+                } else {
+                    matchAll = FALSE;
+                    log_err("ERROR getting \"all\" keyword value for locale \"%s\"\n", loc);
+                    break;
+                }
+            }
+           if (!matchAll) {
+            log_err("FAIL: All values for locale \"%s\" does not match expected.\n", loc);
+           }
+        } else {
+            if(U_FAILURE(status)) {
+               log_err("ERROR: %s\n", u_errorName(status));
+            } else if(size!=uenum_count(ALL, &status)) {
+               log_err("ERROR: got size of %d, wanted %d\n", size, uenum_count(ALL, &status));
+            }
+        }
+        
+        uenum_close(all);
+        
+        status = U_ZERO_ERROR;
+        getCurrLen = ucurr_forLocale(loc, getCurrU, 4, &status);
+        if(U_FAILURE(status)) {
+            if (FORLOCALE[i][0] != 0) {
+                log_err("ERROR: ucurr_forLocale %s, status %s\n", loc, u_errorName(status));
+            }
+        } else if (getCurrLen != 3) {
+            if (FORLOCALE[i][0] != 0 || getCurrLen != -1) {
+                log_err("ERROR: ucurr_forLocale %s, returned len %d\n", loc, getCurrLen);
+            }
+        } else {
+            char getCurrB[4];
+            u_UCharsToChars(getCurrU, getCurrB, 4);
+            if ( uprv_strncmp(getCurrB, FORLOCALE[i], 4) != 0 ) {
+                log_err("ERROR: ucurr_forLocale %s, expected %s, got %s\n", loc, FORLOCALE[i], getCurrB);
+            }
+        }
+    }
+    
+    uenum_close(ALL);
+    
+}
+
+/**
+ * Test proper handling of rounding modes.
+ */
+static void TestRounding5350(void)
+{
+    UNumberFormat *nnf;
+    UErrorCode status = U_ZERO_ERROR;
+    /* this is supposed to open default date format, but later on it treats it like it is "en_US"
+     - very bad if you try to run the tests on machine where default locale is NOT "en_US" */
+    /* nnf = unum_open(UNUM_DEFAULT, NULL, &status); */
+    nnf = unum_open(UNUM_DEFAULT, NULL,0,"en_US",NULL, &status);
+
+    if(U_FAILURE(status)){
+        log_data_err("FAIL: failure in the construction of number format: %s (Are you missing data?)\n", myErrorName(status));
+        return;
+    }
+
+    unum_setAttribute(nnf, UNUM_MAX_FRACTION_DIGITS, 2);
+    roundingTest2(nnf, -0.125, UNUM_ROUND_CEILING, "-0.12");
+    roundingTest2(nnf, -0.125, UNUM_ROUND_FLOOR, "-0.13");
+    roundingTest2(nnf, -0.125, UNUM_ROUND_DOWN, "-0.12");
+    roundingTest2(nnf, -0.125, UNUM_ROUND_UP, "-0.13");
+    roundingTest2(nnf, 0.125, UNUM_FOUND_HALFEVEN, "0.12");
+    roundingTest2(nnf, 0.135, UNUM_ROUND_HALFDOWN, "0.13");
+    roundingTest2(nnf, 0.125, UNUM_ROUND_HALFUP, "0.13");
+    roundingTest2(nnf, 0.135, UNUM_FOUND_HALFEVEN, "0.14");
+    /* The following are exactly represented, and shouldn't round */
+    roundingTest2(nnf, 1.00, UNUM_ROUND_UP, "1");
+    roundingTest2(nnf, 24.25, UNUM_ROUND_UP, "24.25");
+    roundingTest2(nnf, 24.25, UNUM_ROUND_CEILING, "24.25");
+    roundingTest2(nnf, -24.25, UNUM_ROUND_UP, "-24.25");
+
+    /* Differences pretty far out there */
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_CEILING, "1.01");
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_FLOOR, "1");
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_DOWN, "1");
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_UP, "1.01");
+    roundingTest2(nnf, 1.0000001, UNUM_FOUND_HALFEVEN, "1");
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFDOWN, "1");
+    roundingTest2(nnf, 1.0000001, UNUM_ROUND_HALFUP, "1");
+
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_CEILING, "-1");
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_FLOOR, "-1.01");
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_DOWN, "-1");
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_UP, "-1.01");
+    roundingTest2(nnf, -1.0000001, UNUM_FOUND_HALFEVEN, "-1");
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFDOWN, "-1");
+    roundingTest2(nnf, -1.0000001, UNUM_ROUND_HALFUP, "-1");
+
+    unum_close(nnf);
+}
+
+/*-------------------------------------*/
+
+static void roundingTest2(UNumberFormat* nf, double x, int32_t roundingMode, const char* expected)
+{
+    UChar *out = NULL;
+    UChar *res;
+    UFieldPosition pos;
+    UErrorCode status;
+    int32_t lneed;
+    status=U_ZERO_ERROR;
+    unum_setAttribute(nf, UNUM_ROUNDING_MODE, roundingMode);
+    lneed=0;
+    lneed=unum_formatDouble(nf, x, NULL, lneed, NULL, &status);
+    if(status==U_BUFFER_OVERFLOW_ERROR){
+        status=U_ZERO_ERROR;
+        out=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
+        pos.field=0;
+        unum_formatDouble(nf, x, out, lneed+1, &pos, &status);
+    }
+    if(U_FAILURE(status)) {
+        log_err("Error in formatting using unum_formatDouble(.....): %s\n", myErrorName(status) );
+    }
+    /*Need to use log_verbose here. Problem with the float*/
+    /*printf("%f format with %d fraction digits to %s\n", x, maxFractionDigits, austrdup(out) );*/
+    res=(UChar*)malloc(sizeof(UChar) * (strlen(expected)+1) );
+    u_uastrcpy(res, expected);
+    if (u_strcmp(out, res) != 0)
+        log_err("FAIL: Expected: \"%s\"  Got: \"%s\"\n", expected, austrdup(out) );
+    free(res);
+    if(out != NULL) {
+        free(out);
     }
 }