Esempio n. 1
0
static UChar* myNumformat(const UNumberFormat* numfor, double d)
{
    UChar *result2=NULL;
    int32_t resultlength, resultlengthneeded;
    UErrorCode status = U_ZERO_ERROR;
    
    resultlength=0;
    resultlengthneeded=unum_formatDouble(numfor, d, NULL, resultlength, NULL, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR)
    {
        status=U_ZERO_ERROR;
        resultlength=resultlengthneeded+1;
        /*result2=(UChar*)malloc(sizeof(UChar) * resultlength);*/ /* this leaks */
        result2=(UChar*)ctst_malloc(sizeof(UChar) * resultlength); /*this won't*/
        unum_formatDouble(numfor, d, result2, resultlength, NULL, &status);
    }
    if(U_FAILURE(status))
    {
        log_err("FAIL: Error in formatting using unum_format(.....) %s\n", myErrorName(status) );
        return 0;
    }
    
    return result2;
}
Esempio n. 2
0
int icu_format_number(lua_State *L) {
  double a = luaL_checknumber(L, 1);
  /* See http://www.unicode.org/repos/cldr/tags/latest/common/bcp47/number.xml
     for valid system names */
  const char* system = luaL_checkstring(L, 2);
  char locale[18]; // "@numbers=12345678";
  UChar buf[256];
  char utf8[256];
  int32_t needed;
  UErrorCode status = U_ZERO_ERROR;

  snprintf(locale, 18, "@numbers=%s", system);
  UNumberFormat* fmt = unum_open(UNUM_DECIMAL, 0, 0, locale, 0, &status);
  if(U_FAILURE(status)) {
    luaL_error(L, "Locale %s unavailable: %s", locale, u_errorName(status));
  }
  needed = unum_formatDouble(fmt, a, buf, 256, NULL, &status);
  assert(!U_FAILURE(status));
  u_austrncpy(utf8, buf, 256);
  lua_pushstring(L, utf8);
  return 1;
}
void
IntlTestNumberFormatAPI::testRegistration()
{
#if !UCONFIG_NO_SERVICE
    UErrorCode status = U_ZERO_ERROR;

    NumberFormat* f0 = NumberFormat::createInstance(SWAP_LOC, status);
    NumberFormat* f1 = NumberFormat::createInstance(SRC_LOC, status);
    NumberFormat* f2 = NumberFormat::createCurrencyInstance(SRC_LOC, status);
    URegistryKey key = NumberFormat::registerFactory(new NFTestFactory(), status);
    NumberFormat* f3 = NumberFormat::createCurrencyInstance(SRC_LOC, status);
    NumberFormat* f3a = NumberFormat::createCurrencyInstance(SRC_LOC, status);
    NumberFormat* f4 = NumberFormat::createInstance(SRC_LOC, status);

    StringEnumeration* locs = NumberFormat::getAvailableLocales();

    UNumberFormat* uf3 = unum_open(UNUM_CURRENCY, NULL, 0, SRC_LOC.getName(),NULL, &status);
    UNumberFormat* uf4 = unum_open(UNUM_DEFAULT, NULL, 0, SRC_LOC.getName(), NULL, &status);

    const UnicodeString* res;
    for (res = locs->snext(status); res; res = locs->snext(status)) {
        logln(*res); // service is still in synch
    }

    NumberFormat::unregister(key, status); // restore for other tests
    NumberFormat* f5 = NumberFormat::createCurrencyInstance(SRC_LOC, status);
    UNumberFormat* uf5 = unum_open(UNUM_CURRENCY, NULL, 0, SRC_LOC.getName(),NULL, &status);

    if (U_FAILURE(status)) {
        dataerrln("Error creating instnaces.");
        return;
    } else {
        float n = 1234.567f;
        UnicodeString res0, res1, res2, res3, res4, res5;
        UChar ures3[50];
        UChar ures4[50];
        UChar ures5[50];

        f0->format(n, res0);
        f1->format(n, res1);
        f2->format(n, res2);
        f3->format(n, res3);
        f4->format(n, res4);
        f5->format(n, res5);

        unum_formatDouble(uf3, n, ures3, 50, NULL, &status);
        unum_formatDouble(uf4, n, ures4, 50, NULL, &status);
        unum_formatDouble(uf5, n, ures5, 50, NULL, &status);

        logln((UnicodeString)"f0 swap int: " + res0);
        logln((UnicodeString)"f1 src int: " + res1);
        logln((UnicodeString)"f2 src cur: " + res2);
        logln((UnicodeString)"f3 reg cur: " + res3);
        logln((UnicodeString)"f4 reg int: " + res4);
        logln((UnicodeString)"f5 unreg cur: " + res5);
        log("uf3 reg cur: ");
        logln(ures3);
        log("uf4 reg int: ");
        logln(ures4);
        log("uf5 ureg cur: ");
        logln(ures5);

        if (f3 == f3a) {
            errln("did not get new instance from service");
        } else {
            delete f3a;
        }
        if (res3 != res0) {
            errln("registered service did not match");
        }
        if (res4 != res1) {
            errln("registered service did not inherit");
        }
        if (res5 != res2) {
            errln("unregistered service did not match original");
        }

        if (res0 != ures3) {
            errln("registered service did not match / unum");
        }
        if (res1 != ures4) {
            errln("registered service did not inherit / unum");
        }
        if (res2 != ures5) {
            errln("unregistered service did not match original / unum");
        }
    }

    unum_close(uf5);
    delete f5;
    unum_close(uf4);
    unum_close(uf3);
    delete f4;
    delete f3;
    delete f2;
    delete f1;
    delete f0;

    for (res = locs->snext(status); res; res = locs->snext(status)) {
        errln(*res); // service should be out of synch
    }

    locs->reset(status); // now in synch again, we hope
    for (res = locs->snext(status); res; res = locs->snext(status)) {
        logln(*res);
    }

    delete locs;
#endif
}
Esempio n. 4
0
int32_t
u_sprintf_percent_handler(u_localized_string *output,
                          const u_sprintf_spec_info     *info,
                          const ufmt_args            *args)
{
    double        num         = (double) (args[0].doubleValue);
    UNumberFormat        *format;
    UChar            result        [USPRINTF_BUFFER_SIZE];
    int32_t        minDecimalDigits;
    int32_t        maxDecimalDigits;
    UErrorCode        status        = U_ZERO_ERROR;


    /* mask off any necessary bits */
    /*  if(! info->fIsLongDouble)
    num &= DBL_MAX;*/

    /* get the formatter */
    format = u_locbund_getPercentFormat(output->fBundle);

    /* handle error */
    if(format == 0)
        return 0;

    /* set the appropriate flags on the formatter */

    /* clone the stream's bundle if it isn't owned */
    if(! output->fOwnBundle) {
        output->fBundle     = u_locbund_clone(output->fBundle);
        output->fOwnBundle     = TRUE;
        format           = u_locbund_getPercentFormat(output->fBundle);
    }

    /* set the number of decimal digits */

    /* save the formatter's state */
    minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
    maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);

    if(info->fPrecision != -1) {
        /* set the # of decimal digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
    }
    else if(info->fPrecision == 0 && ! info->fAlt) {
        /* no decimal point in this case */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 0);
    }
    else if(info->fAlt) {
        /* '#' means always show decimal point */
        /* copy of printf behavior on Solaris - '#' shows 6 digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }
    else {
        /* # of decimal digits is 6 if precision not specified */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }

    /* set whether to show the sign */
    u_sprintf_set_sign(format, info, &status);

    /* format the number */
    unum_formatDouble(format, num, result, USPRINTF_BUFFER_SIZE, 0, &status);

    /* restore the number format */
    unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
    unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);

    return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
}
Esempio n. 5
0
int32_t
u_sprintf_scientific_handler(u_localized_string *output,
                             const u_sprintf_spec_info     *info,
                             const ufmt_args            *args)
{
    double        num         = (double) (args[0].doubleValue);
    UNumberFormat        *format;
    UChar            result        [USPRINTF_BUFFER_SIZE];
    int32_t        minDecimalDigits;
    int32_t        maxDecimalDigits;
    UErrorCode        status        = U_ZERO_ERROR;
    UChar srcExpBuf[USPRINTF_SYMBOL_BUFFER_SIZE];
    int32_t srcLen, expLen;
    UChar expBuf[USPRINTF_SYMBOL_BUFFER_SIZE];


    /* mask off any necessary bits */
    /*  if(! info->fIsLongDouble)
    num &= DBL_MAX;*/

    /* get the formatter */
    format = u_locbund_getScientificFormat(output->fBundle);

    /* handle error */
    if(format == 0)
        return 0;

    /* set the appropriate flags on the formatter */

    /* clone the stream's bundle if it isn't owned */
    if(! output->fOwnBundle) {
        output->fBundle     = u_locbund_clone(output->fBundle);
        output->fOwnBundle  = TRUE;
        format              = u_locbund_getScientificFormat(output->fBundle);
    }

    srcLen = unum_getSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        srcExpBuf,
        sizeof(srcExpBuf),
        &status);

    /* Upper/lower case the e */
    if (info->fSpec == (UChar)0x65 /* e */) {
        expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            output->fBundle->fLocale,
            &status);
    }
    else {
        expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            output->fBundle->fLocale,
            &status);
    }

    unum_setSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        expBuf,
        expLen,
        &status);

    /* set the number of decimal digits */

    /* save the formatter's state */
    minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
    maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);

    if(info->fPrecision != -1) {
        /* set the # of decimal digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
    }
    else if(info->fPrecision == 0 && ! info->fAlt) {
        /* no decimal point in this case */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 0);
    }
    else if(info->fAlt) {
        /* '#' means always show decimal point */
        /* copy of printf behavior on Solaris - '#' shows 6 digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }
    else {
        /* # of decimal digits is 6 if precision not specified */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }

    /* set whether to show the sign */
    u_sprintf_set_sign(format, info, &status);

    /* format the number */
    unum_formatDouble(format, num, result, USPRINTF_BUFFER_SIZE, 0, &status);

    /* restore the number format */
    unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
    unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);

    /* Since we clone the fBundle and we're only using the scientific
       format, we don't need to save the old exponent value. */
    /*unum_setSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        srcExpBuf,
        srcLen,
        &status);*/

    return u_sprintf_pad_and_justify(output, info, result, u_strlen(result));
}
Esempio n. 6
0
/**
 * Test currency "object" (we use this name to match the other C++
 * test name and the Jave name).  Actually, test ISO currency code
 * support in the C API.
 */
static void TestCurrencyObject(void)
{
    UNumberFormat *currencyFmt;
    UChar *str=NULL, *res=NULL;
    int32_t lneed, i;
    UFieldPosition pos;
    UErrorCode status = U_ZERO_ERROR;

    const char* locale[]={
        "fr_FR",
        "fr_FR",
    };

    const char* currency[]={
        "",
        "JPY",
    };

    const char* result[]={
        "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++)
    {
        char cStr[20]={0};
        UChar isoCode[16]={0};
        currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,locale[i],NULL, &status);
        if(U_FAILURE(status)){
            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]) {
                u_uastrcpy(isoCode, currency[i]);
                unum_setTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
                    isoCode, u_strlen(isoCode), &status);

                if(U_FAILURE(status)) {
                    log_err("FAIL: can't set currency code %s\n", myErrorName(status) );
                }
            }

            unum_getTextAttribute(currencyFmt, UNUM_CURRENCY_CODE,
                isoCode, sizeof(isoCode), &status);

            if(U_FAILURE(status)) {
                log_err("FAIL: can't get currency code %s\n", myErrorName(status) );
            }

            u_UCharsToChars(isoCode,cStr,u_strlen(isoCode));
            log_verbose("ISO code %s\n", cStr);
            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){
                status=U_ZERO_ERROR;
                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
                pos.field = 0;
                unum_formatDouble(currencyFmt, 1234.56, 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);
    }
}
Esempio n. 7
0
/**
 * 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\\u00A02", "2\\u00A0F",            "IEP\\u00A01.50",                      "1,50\\u00A0mk",   "2\\u00A0F",         "ITL\\u00A02",
        "1$50\\u00A0\\u200B", "\\u00F6S\\u00A01,50",  "1,50\\u00A0\\u0394\\u03C1\\u03C7", "2\\u00A0\\u20A7", "1,50\\u00A0FB",     "IEP\\u00A01.50",
        "BEF\\u00A01,50",   "1,50\\u00A0DM",        "1,50\\u00A0BEF",                    "\\u20A7\\u00A02", "1,50\\u00A0F",      "2\\u00A0\\u20A7",
        "NLG\\u00A01,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_data_err("Could not canonicalize %s. Error: %s (Are you missing data?)\n", locale[i], u_errorName(status));
            continue;
        }
        currencyFmt = unum_open(UNUM_CURRENCY, NULL,0,curID,NULL, &status);

        if(U_FAILURE(status)){
            log_data_err("Error in the construction of number format with style currency: %s (Are you missing data?)\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);
    }
}
Esempio n. 8
0
/**
 * Test the handling of the currency symbol in patterns.
 */
static void TestCurrencySign(void)
{
    int32_t lneed;
    UNumberFormat *fmt;
    UChar *pattern=NULL;
    UChar *str=NULL;
    UChar *pat=NULL;
    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_status(status, "Error in number format construction with pattern  \"\\xA4#,##0.00;-\\xA4#,##0.00\\\" -> %s\n", u_errorName(status));
    }
    lneed=0;
    lneed=unum_formatDouble(fmt, 1234.56, NULL, lneed, NULL, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        unum_formatDouble(fmt, 1234.56, str, lneed+1, NULL, &status);
    }
    if(U_FAILURE(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);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        pat=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        unum_formatDouble(fmt, FALSE, pat, lneed+1, NULL, &status);
    }
    log_verbose("Pattern \" %s \" \n", u_austrcpy(tempBuf, pat));
    log_verbose("Format 1234.56 -> %s\n", u_austrcpy(tempBuf, str) );
    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_data_err("FAIL: Expected $1,234.56\n");
    } else {
        log_err_status(status, "Error formatting -> %s\n", u_errorName(status));
    }
    free(str);
    free(res);
    free(pat);

    lneed=0;
    lneed=unum_formatDouble(fmt, -1234.56, NULL, lneed, NULL, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        unum_formatDouble(fmt, -1234.56, str, lneed+1, NULL, &status);
    }
    if(U_FAILURE(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_data_err("FAIL: Expected -$1,234.56\n");
        free(str);
        free(res);
    }

    unum_close(fmt);
    free(pattern);
}
Esempio n. 9
0
/* Test exponential pattern*/
static void TestExponential(void)
{
    int32_t pat_length, val_length, lval_length;
    int32_t ival, ilval, p, v, lneed;
    UNumberFormat *fmt;
    int32_t ppos;
    UChar *upat;
    UChar pattern[20];
    UChar *str=NULL;
    UChar uvalfor[20], ulvalfor[20];
    char tempMsgBug[256];
    double a;
    UErrorCode status = U_ZERO_ERROR;
#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",
        "12.340E-03", "12.346E07", "12.300E299", "-31.416E-272",
        "12.34E-003", "123.4568E006", "1.23E300", "-314.1593E-273",
        "1.234E-2", "1.235E8", "1.23E300", "[3.142E-271]"
    };
    static const char* lvalFormat[] =
    {
        "0E0", "-1E0", "1E0", "1.2346E8",
        "00.000E00", "-10.000E-01", "10.000E-01", "12.346E07",
        "0E000", "-1E000", "1E000", "123.4568E006",
        "0E0", "[1E0]", "1E0", "1.235E8"
    };
    static const double valParse[] =
    {
#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,
        0.01234, 123500000, 1.23E75, -3.142E-78
#else
        /* We define the whole IEEE 754 number in the 4th column because
        Visual Age 7 has a bug in rounding numbers. */
        0.01234, 123460000, 1.23E300, -3.1415999999999999E-271,
        0.01234, 123460000, 1.23E300, -3.1415999999999999E-271,
        0.01234, 123456800, 1.23E300, -3.1415929999999999E-271,
        0.01234, 123500000, 1.23E300, -3.1420000000000001E-271
#endif
    };
    static const int32_t lvalParse[] =
    {
        0, -1, 1, 123460000,
            0, -1, 1, 123460000,
            0, -1, 1, 123456800,
            0, -1, 1, 123500000
    };


    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)
    {
        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_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);
        log_verbose("Pattern \" %s \" -toPattern-> \" %s \" \n", upat, u_austrcpy(tempMsgBug, pattern) );
        for (v=0; v<val_length; ++v)
        {
            /*format*/
            lneed=0;
            lneed=unum_formatDouble(fmt, val[v], NULL, lneed, NULL, &status);
            if(status==U_BUFFER_OVERFLOW_ERROR){
                status=U_ZERO_ERROR;
                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
                unum_formatDouble(fmt, val[v], str, lneed+1,  NULL, &status);
            }
            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);
            if (ppos== u_strlen(str)) {
                if (a != valParse[v+ival])
                    log_err("FAIL: Expected: %e, Got: %g\n", valParse[v+ival], a);
            }
            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=unum_formatDouble(fmt, lval[v], NULL, lneed, NULL, &status);
            if(status==U_BUFFER_OVERFLOW_ERROR){
                status=U_ZERO_ERROR;
                str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
                unum_formatDouble(fmt, lval[v], str, lneed+1,  NULL, &status);
            }
            if(U_FAILURE(status)) {
                log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
            }
            /*printf(" Format %e -> %s\n",  lval[v], austrdup(str) );*/
            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);
            if (ppos== u_strlen(str)) {
                /*printf(" Parse -> %e\n",  a);*/
                if (a != lvalParse[v+ilval])
                    log_err("FAIL: Expected : %e\n", valParse[v+ival]);
            }
            else
                log_err(" FAIL: Partial parse (  %d  chars ) ->  %e\n",  ppos, a);

            free(str);

        }
        ival += val_length;
        ilval += lval_length;
        unum_close(fmt);
        free(upat);
    }
}
static int32_t
u_printf_spellout_handler(const u_printf_stream_handler *handler,
                          void                          *context,
                          ULocaleBundle                 *formatBundle,
                          const u_printf_spec_info      *info,
                          const ufmt_args               *args)
{
    double          num         = (double) (args[0].doubleValue);
    UNumberFormat   *format;
    UChar           result[UPRINTF_BUFFER_SIZE];
    UChar           prefixBuffer[UPRINTF_BUFFER_SIZE];
    int32_t         prefixBufferLen = sizeof(prefixBuffer);
    int32_t         minDecimalDigits;
    int32_t         maxDecimalDigits;
    int32_t         resultLen;
    UErrorCode      status        = U_ZERO_ERROR;

    prefixBuffer[0] = 0;

    /* mask off any necessary bits */
    /*  if(! info->fIsLongDouble)
    num &= DBL_MAX;*/

    /* get the formatter */
    format = u_locbund_getNumberFormat(formatBundle, UNUM_SPELLOUT);

    /* handle error */
    if(format == 0)
        return 0;

    /* save the formatter's state */
    minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
    maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);

    /* set the appropriate flags and number of decimal digits on the formatter */
    if(info->fPrecision != -1) {
        /* set the # of decimal digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
    }
    else if(info->fAlt) {
        /* '#' means always show decimal point */
        /* copy of printf behavior on Solaris - '#' shows 6 digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }
    else {
        /* # of decimal digits is 6 if precision not specified */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }

    /* set whether to show the sign */
    if (info->fShowSign) {
        u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status);
    }

    /* format the number */
    resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);

    if (U_FAILURE(status)) {
        resultLen = 0;
    }

    /* restore the number format */
    /* TODO: Is this needed? */
    unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
    unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);

    if (info->fShowSign) {
        /* Reset back to original value regardless of what the error was */
        UErrorCode localStatus = U_ZERO_ERROR;
        u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus);
    }

    return handler->pad_and_justify(context, info, result, resultLen);
}
static int32_t
u_printf_scientific_handler(const u_printf_stream_handler  *handler,
                            void                           *context,
                            ULocaleBundle                  *formatBundle,
                            const u_printf_spec_info       *info,
                            const ufmt_args                *args)
{
    double          num         = (double) (args[0].doubleValue);
    UNumberFormat   *format;
    UChar           result[UPRINTF_BUFFER_SIZE];
    UChar           prefixBuffer[UPRINTF_BUFFER_SIZE];
    int32_t         prefixBufferLen = sizeof(prefixBuffer);
    int32_t         minDecimalDigits;
    int32_t         maxDecimalDigits;
    UErrorCode      status        = U_ZERO_ERROR;
    UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
    int32_t srcLen, expLen;
    int32_t resultLen;
    UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE];

    prefixBuffer[0] = 0;

    /* mask off any necessary bits */
    /*  if(! info->fIsLongDouble)
    num &= DBL_MAX;*/

    /* get the formatter */
    format = u_locbund_getNumberFormat(formatBundle, UNUM_SCIENTIFIC);

    /* handle error */
    if(format == 0)
        return 0;

    /* set the appropriate flags on the formatter */

    srcLen = unum_getSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        srcExpBuf,
        sizeof(srcExpBuf),
        &status);

    /* Upper/lower case the e */
    if (info->fSpec == (UChar)0x65 /* e */) {
        expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            formatBundle->fLocale,
            &status);
    }
    else {
        expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
            srcExpBuf, srcLen,
            formatBundle->fLocale,
            &status);
    }

    unum_setSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        expBuf,
        expLen,
        &status);

    /* save the formatter's state */
    minDecimalDigits = unum_getAttribute(format, UNUM_MIN_FRACTION_DIGITS);
    maxDecimalDigits = unum_getAttribute(format, UNUM_MAX_FRACTION_DIGITS);

    /* set the appropriate flags and number of decimal digits on the formatter */
    if(info->fPrecision != -1) {
        /* set the # of decimal digits */
        if (info->fOrigSpec == (UChar)0x65 /* e */ || info->fOrigSpec == (UChar)0x45 /* E */) {
            unum_setAttribute(format, UNUM_FRACTION_DIGITS, info->fPrecision);
        }
        else {
            unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, 1);
            unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, info->fPrecision);
        }
    }
    else if(info->fAlt) {
        /* '#' means always show decimal point */
        /* copy of printf behavior on Solaris - '#' shows 6 digits */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }
    else {
        /* # of decimal digits is 6 if precision not specified */
        unum_setAttribute(format, UNUM_FRACTION_DIGITS, 6);
    }

    /* set whether to show the sign */
    if (info->fShowSign) {
        u_printf_set_sign(format, info, prefixBuffer, &prefixBufferLen, &status);
    }

    /* format the number */
    resultLen = unum_formatDouble(format, num, result, UPRINTF_BUFFER_SIZE, 0, &status);

    if (U_FAILURE(status)) {
        resultLen = 0;
    }

    /* restore the number format */
    /* TODO: Is this needed? */
    unum_setAttribute(format, UNUM_MIN_FRACTION_DIGITS, minDecimalDigits);
    unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, maxDecimalDigits);

    /* Since we're the only one using the scientific
       format, we don't need to save the old exponent value. */
    /*unum_setSymbol(format,
        UNUM_EXPONENTIAL_SYMBOL,
        srcExpBuf,
        srcLen,
        &status);*/

    if (info->fShowSign) {
        /* Reset back to original value regardless of what the error was */
        UErrorCode localStatus = U_ZERO_ERROR;
        u_printf_reset_sign(format, info, prefixBuffer, &prefixBufferLen, &localStatus);
    }

    return handler->pad_and_justify(context, info, result, resultLen);
}
Esempio n. 12
0
/**
 *  call-seq:
 *     23874.localize(:decimal, 'es_ES') => 23.874
 */
VALUE rb_numeric_localize(int argc, VALUE *argv, VALUE self)
{
	VALUE style, options;
	UNumberFormatStyle formatStyle;
	char *locale = NULL;

	UNumberFormat *format;
	UErrorCode status;

	UChar result[256];
	/* arguments */
	rb_scan_args(argc, argv, "02", &style, &options);
	if (style == Qnil) {
		formatStyle = UNUM_DECIMAL;
	} else {
		ID style_ID;

		Check_Type(style, T_SYMBOL);
		style_ID = SYM2ID(style);
		if (style_ID == rb_intern("decimal")) {
			formatStyle = UNUM_DECIMAL;
		} else if (style_ID == rb_intern("currency")) {
			formatStyle = UNUM_CURRENCY;
		} else if (style_ID == rb_intern("percent")) {
			formatStyle = UNUM_PERCENT;
		} else if (style_ID == rb_intern("scientific")) {
			formatStyle = UNUM_SCIENTIFIC;
		} else if (style_ID == rb_intern("spellout")) {
			formatStyle = UNUM_SPELLOUT;
		} else {
			rb_raise(rb_eArgError, "unsupported format style %s", rb_id2name(style_ID));
		}
	}
	if (options != Qnil) {
		VALUE rb_locale;

		Check_Type(options, T_HASH);
		rb_locale = rb_hash_aref(options, ID2SYM(rb_intern("locale")));
		if (rb_locale != Qnil) {
			locale = StringValuePtr(rb_locale);
		}
	}
	/* formatter */
	status = U_ZERO_ERROR;
    format = unum_open(formatStyle, NULL, 0, locale, NULL, &status);
    RAISE_ON_ERROR(status);
    /* set format attributes */
	if (options != Qnil) {
		VALUE currency, precision, round_mode, round_increment;

		switch (formatStyle) {
			case UNUM_CURRENCY:
				currency = rb_hash_aref(options, ID2SYM(rb_intern("currency")));
				if (currency != Qnil) {
					UChar *uStr;
					int32_t uStrLen;

					uStr = u_strFromRString(currency, &uStrLen);
					status = U_ZERO_ERROR;
					unum_setTextAttribute(format, UNUM_CURRENCY_CODE, uStr, uStrLen, &status);
					RAISE_ON_ERROR(status);
				}
			case UNUM_DECIMAL:
				/* precision */
				precision = rb_hash_aref(options, ID2SYM(rb_intern("precision")));
				if (precision != Qnil) {
					Check_Type(precision, T_FIXNUM);
					status = U_ZERO_ERROR;
					unum_setAttribute(format, UNUM_FRACTION_DIGITS, NUM2INT(precision));
					RAISE_ON_ERROR(status);
				}

				round_mode = rb_hash_aref(options, ID2SYM(rb_intern("round_mode")));
				if (round_mode != Qnil) {
					ID round_mode_ID;
					UNumberFormatRoundingMode rounding_mode;

					Check_Type(round_mode, T_SYMBOL);
					round_mode_ID = SYM2ID(round_mode);
					if (round_mode_ID == rb_intern("ceil")) {
						rounding_mode = UNUM_ROUND_CEILING;
					} else if (round_mode_ID == rb_intern("floor")) {
						rounding_mode = UNUM_ROUND_FLOOR;
					} else if (round_mode_ID == rb_intern("down")) {
						rounding_mode = UNUM_ROUND_DOWN;
					} else if (round_mode_ID == rb_intern("up")) {
						rounding_mode = UNUM_ROUND_UP;
					} else if (round_mode_ID == rb_intern("halfeven")) {
						rounding_mode = UNUM_FOUND_HALFEVEN;
					} else if (round_mode_ID == rb_intern("halfdown")) {
						rounding_mode = UNUM_ROUND_HALFDOWN;
					} else if (round_mode_ID == rb_intern("halfup")) {
						rounding_mode = UNUM_ROUND_HALFUP;
					} else {
						rb_raise(rb_eArgError, "unsupported rounding mode '%s'", rb_id2name(round_mode_ID));
					}
					status = U_ZERO_ERROR;
					unum_setAttribute(format, UNUM_ROUNDING_MODE, rounding_mode);
					RAISE_ON_ERROR(status);
				}
				round_increment = rb_hash_aref(options, ID2SYM(rb_intern("round_increment")));
				if (round_increment != Qnil) {
					Check_Type(round_increment, T_FLOAT);
					status = U_ZERO_ERROR;
					unum_setDoubleAttribute(format, UNUM_ROUNDING_INCREMENT, NUM2DBL(round_increment));
					RAISE_ON_ERROR(status);
				}
		}
	}
	/* format */
	status = U_ZERO_ERROR;
    switch (TYPE(self)) {
    	case T_FIXNUM:
    		unum_format(format, NUM2INT(self), result, 256, NULL, &status);
    		break;
    	case T_FLOAT:
    		unum_formatDouble(format, NUM2DBL(self), result, 256, NULL, &status);
    		break;
    	case T_BIGNUM:
			unum_formatInt64(format, rb_big2ll(self), result, 256, NULL, &status);
    		break;

    }
    RAISE_ON_ERROR(status);
    /* free resources */
    unum_close(format);

    return u_strToRString(result, -1);
}