Example #1
0
U_CDECL_END


static U_INLINE UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
    if (result->fNumberFormat[style-1] == NULL) {
        UErrorCode status = U_ZERO_ERROR;
        UBool needsInit;

        UMTX_CHECK(NULL, gPosixNumberFormat[style-1] == NULL, needsInit);
        if (needsInit) {
            UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);

            /* Cache upon first request. */
            if (U_SUCCESS(status)) {
                umtx_lock(NULL);
                gPosixNumberFormat[style-1] = formatAlias;
                ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
                umtx_unlock(NULL);
            }
        }

        /* Copy the needed formatter. */
        result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
    }
    return result->fNumberFormat[style-1];
}
/*
PAL Function:
GetLocaleInfoGroupingSizes

Obtains grouping sizes for decimal and currency
Returns 1 for success, 0 otherwise
*/
extern "C" int32_t GlobalizationNative_GetLocaleInfoGroupingSizes(
    const UChar* localeName, LocaleNumberData localeGroupingData, int32_t* primaryGroupSize, int32_t* secondaryGroupSize)
{
    UErrorCode status = U_ZERO_ERROR;
    char locale[ULOC_FULLNAME_CAPACITY];
    GetLocale(localeName, locale, ULOC_FULLNAME_CAPACITY, false, &status);

    if (U_FAILURE(status))
    {
        return UErrorCodeToBool(U_ILLEGAL_ARGUMENT_ERROR);
    }

    UNumberFormatStyle style;
    switch (localeGroupingData)
    {
    case Digit:
        style = UNUM_DECIMAL;
        break;
    case Monetary:
        style = UNUM_CURRENCY;
        break;
    default:
        return UErrorCodeToBool(U_UNSUPPORTED_ERROR);
    }

    UNumberFormat* numformat = unum_open(style, NULL, 0, locale, NULL, &status);
    if (U_SUCCESS(status))
    {
        *primaryGroupSize = unum_getAttribute(numformat, UNUM_GROUPING_SIZE);
        *secondaryGroupSize = unum_getAttribute(numformat, UNUM_SECONDARY_GROUPING_SIZE);
        unum_close(numformat);
    }

    return UErrorCodeToBool(status);
}
Example #3
0
static jint openRBNFImpl2(JNIEnv* env, jclass clazz, 
        jstring rule, jstring locale) {

    // LOGI("ENTER openRBNFImpl2");

    // the errorcode returned by unum_open
    UErrorCode status = U_ZERO_ERROR;

    // prepare the pattern string for the call to unum_open
    const UChar *ruleChars = env->GetStringChars(rule, NULL);
    int ruleLen = env->GetStringLength(rule);

    // prepare the locale string for the call to unum_open
    const char *localeChars = env->GetStringUTFChars(locale, NULL);

    // open a rule based number format
    UNumberFormat *fmt = unum_open(UNUM_PATTERN_RULEBASED, ruleChars, ruleLen, 
                localeChars, NULL, &status);

    // release the allocated strings
    env->ReleaseStringChars(rule, ruleChars);
    env->ReleaseStringUTFChars(locale, localeChars);

    // check for an error
    if ( icuError(env, status) != FALSE) {
        return 0;
    }

    // return the handle to the number format
    return (long) fmt;

}
Example #4
0
/*Test Various format patterns*/
static void TestPatterns(void)
{
    int32_t pat_length, i, lneed;
    UNumberFormat *fmt;
    UChar upat[5];
    UChar unewpat[5];
    UChar unum[5];
    UChar *unewp=NULL;
    UChar *str=NULL;
    UErrorCode status = U_ZERO_ERROR;
    const char* pat[]    = { "#.#", "#.", ".#", "#" };
    const char* newpat[] = { "0.#", "0.", "#.0", "0" };
    const char* num[]    = { "0",   "0.", ".0", "0" };

    log_verbose("\nTesting different format patterns\n");
    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_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);
        if(status==U_BUFFER_OVERFLOW_ERROR){
            status= U_ZERO_ERROR;
            unewp=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
            unum_toPattern(fmt, FALSE, unewp, lneed+1, &status);
        }
        if(U_FAILURE(status)){
            log_err("FAIL: Number format extracting the pattern failed for %s\n", pat[i]);
        }
        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){
            status=U_ZERO_ERROR;
            str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
            unum_format(fmt, 0, str, lneed+1,  NULL, &status);
        }
        if(U_FAILURE(status)) {
            log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
        }
        u_uastrcpy(unum, num[i]);
        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);
        unum_close(fmt);
    }
}
Example #5
0
/*
 * Testing unum_getDoubleAttribute and  unum_setDoubleAttribute()
 */
static void TestDoubleAttribute(void)
{
    double mydata[] = { 1.11, 22.22, 333.33, 4444.44, 55555.55, 666666.66, 7777777.77, 88888888.88, 999999999.99};
    double dvalue;
    int i;
    UErrorCode status=U_ZERO_ERROR;
    UNumberFormatAttribute attr;
    UNumberFormatStyle style= UNUM_DEFAULT;
    UNumberFormat *def;

    log_verbose("\nTesting get and set DoubleAttributes\n");
    def=unum_open(style, NULL,0,NULL,NULL, &status);

    if (U_FAILURE(status)) {
        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];
            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");
            else
                log_verbose("Pass: setting and getting double attributes for UNUM_ROUNDING_INCREMENT works fine\n");
        }
    }

    unum_close(def);
}
Example #6
0
static void TestFractionDigitOverride(void) {
    UErrorCode status = U_ZERO_ERROR;
    UNumberFormat *fmt = unum_open(UNUM_CURRENCY, NULL, 0, "hu_HU", NULL, &status);
    UChar buffer[256];
    UChar expectedBuf[256];
    const char expectedFirst[] = "123\\u00A0Ft";
    const char expectedSecond[] = "123,46\\u00A0Ft";
    const char expectedThird[] = "123,456\\u00A0Ft";
    if (U_FAILURE(status)) {
       log_data_err("Error: unum_open returned %s (Are you missing data?)\n", myErrorName(status));
       return;
    }
    /* Make sure that you can format normal fraction digits. */
    unum_formatDouble(fmt, 123.456, buffer, sizeof(buffer)/sizeof(buffer[0]), NULL, &status);
    u_unescape(expectedFirst, expectedBuf, strlen(expectedFirst)+1);
    if (u_strcmp(buffer, expectedBuf) != 0) {
       log_err("Error: unum_formatDouble didn't return %s\n", expectedFirst);
    }
    /* Make sure that you can format 2 fraction digits. */
    unum_setAttribute(fmt, UNUM_FRACTION_DIGITS, 2);
    unum_formatDouble(fmt, 123.456, buffer, sizeof(buffer)/sizeof(buffer[0]), NULL, &status);
    u_unescape(expectedSecond, expectedBuf, strlen(expectedSecond)+1);
    if (u_strcmp(buffer, expectedBuf) != 0) {
       log_err("Error: unum_formatDouble didn't return %s\n", expectedSecond);
    }
    /* Make sure that you can format more fraction digits. */
    unum_setAttribute(fmt, UNUM_FRACTION_DIGITS, 3);
    unum_formatDouble(fmt, 123.456, buffer, sizeof(buffer)/sizeof(buffer[0]), NULL, &status);
    u_unescape(expectedThird, expectedBuf, strlen(expectedThird)+1);
    if (u_strcmp(buffer, expectedBuf) != 0) {
       log_err("Error: unum_formatDouble didn't return %s\n", expectedThird);
    }
    unum_close(fmt);
}
Example #7
0
void ICULocale::initializeDecimalFormat()
{
    if (m_didCreateDecimalFormat)
        return;
    m_didCreateDecimalFormat = true;
    UErrorCode status = U_ZERO_ERROR;
    m_numberFormat = unum_open(UNUM_DECIMAL, 0, 0, m_locale.data(), 0, &status);
    if (!U_SUCCESS(status))
        return;

    setDecimalSymbol(0, UNUM_ZERO_DIGIT_SYMBOL);
    setDecimalSymbol(1, UNUM_ONE_DIGIT_SYMBOL);
    setDecimalSymbol(2, UNUM_TWO_DIGIT_SYMBOL);
    setDecimalSymbol(3, UNUM_THREE_DIGIT_SYMBOL);
    setDecimalSymbol(4, UNUM_FOUR_DIGIT_SYMBOL);
    setDecimalSymbol(5, UNUM_FIVE_DIGIT_SYMBOL);
    setDecimalSymbol(6, UNUM_SIX_DIGIT_SYMBOL);
    setDecimalSymbol(7, UNUM_SEVEN_DIGIT_SYMBOL);
    setDecimalSymbol(8, UNUM_EIGHT_DIGIT_SYMBOL);
    setDecimalSymbol(9, UNUM_NINE_DIGIT_SYMBOL);
    setDecimalSymbol(DecimalSeparatorIndex, UNUM_DECIMAL_SEPARATOR_SYMBOL);
    setDecimalSymbol(GroupSeparatorIndex, UNUM_GROUPING_SEPARATOR_SYMBOL);
    setDecimalTextAttribute(m_positivePrefix, UNUM_POSITIVE_PREFIX);
    setDecimalTextAttribute(m_positiveSuffix, UNUM_POSITIVE_SUFFIX);
    setDecimalTextAttribute(m_negativePrefix, UNUM_NEGATIVE_PREFIX);
    setDecimalTextAttribute(m_negativeSuffix, UNUM_NEGATIVE_SUFFIX);
    ASSERT(!m_positivePrefix.isEmpty() || !m_positiveSuffix.isEmpty() || !m_negativePrefix.isEmpty() || !m_negativeSuffix.isEmpty());
}
Example #8
0
void capi() {
    UNumberFormat *fmt;
    UErrorCode status = U_ZERO_ERROR;
    /* The string "987654321.123" as UChars */
    UChar str[] = { 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33,
                    0x32, 0x31, 0x30, 0x2E, 0x31, 0x32, 0x33, 0 };
    UChar buf[256];
    int32_t needed;
    double a;
    
    /* Create a formatter for the US locale */
    fmt = unum_open(
          UNUM_DECIMAL,      /* style         */
          0,                 /* pattern       */
          0,                 /* patternLength */
          "en_US",           /* locale        */
          0,                 /* parseErr      */
          &status);
    if (U_FAILURE(status)) {
        printf("FAIL: unum_open\n");
        exit(1);
    }

    /* Use the formatter to parse a number.  When using the C API,
       we have to specify whether we want a double or a long in advance.

       We pass in NULL for the position pointer in order to get the
       default behavior which is to parse from the start. */
    a = unum_parseDouble(fmt, str, u_strlen(str), NULL, &status);
    if (U_FAILURE(status)) {
        printf("FAIL: unum_parseDouble\n");
        exit(1);
    }

    /* Show the result */
    printf("unum_parseDouble(\"");
    uprintf(str);
    printf("\") => %g\n", a);

    /* Use the formatter to format the same number back into a string
       in the US locale.  The return value is the buffer size needed.
       We're pretty sure we have enough space, but in a production
       application one would check this value.

       We pass in NULL for the UFieldPosition pointer because we don't
       care to receive that data. */
    needed = unum_formatDouble(fmt, a, buf, 256, NULL, &status);
    if (U_FAILURE(status)) {
        printf("FAIL: format_parseDouble\n");
        exit(1);
    }

    /* Show the result */
    printf("unum_formatDouble(%g) => \"", a);
    uprintf(buf);
    printf("\"\n");

    /* Release the storage used by the formatter */
    unum_close(fmt);
}
Example #9
0
void LocaleICU::initializeLocaleData()
{
    if (m_didCreateDecimalFormat)
        return;
    m_didCreateDecimalFormat = true;
    UErrorCode status = U_ZERO_ERROR;
    m_numberFormat = unum_open(UNUM_DECIMAL, 0, 0, m_locale.data(), 0, &status);
    if (!U_SUCCESS(status))
        return;

    Vector<String, DecimalSymbolsSize> symbols;
    symbols.append(decimalSymbol(UNUM_ZERO_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_ONE_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_TWO_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_THREE_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_FOUR_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_FIVE_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_SIX_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_SEVEN_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_EIGHT_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_NINE_DIGIT_SYMBOL));
    symbols.append(decimalSymbol(UNUM_DECIMAL_SEPARATOR_SYMBOL));
    symbols.append(decimalSymbol(UNUM_GROUPING_SEPARATOR_SYMBOL));
    ASSERT(symbols.size() == DecimalSymbolsSize);
    setLocaleData(symbols, decimalTextAttribute(UNUM_POSITIVE_PREFIX), decimalTextAttribute(UNUM_POSITIVE_SUFFIX), decimalTextAttribute(UNUM_NEGATIVE_PREFIX), decimalTextAttribute(UNUM_NEGATIVE_SUFFIX));
}
Example #10
0
U_CAPI UNumberFormat *
u_locbund_getNumberFormat(ULocaleBundle *bundle, UNumberFormatStyle style)
{
    UNumberFormat *formatAlias = NULL;
    if (style > UNUM_IGNORE) {
        formatAlias = bundle->fNumberFormat[style-1];
        if (formatAlias == NULL) {
            if (bundle->isInvariantLocale) {
                formatAlias = copyInvariantFormatter(bundle, style);
            }
            else {
                UErrorCode status = U_ZERO_ERROR;
                formatAlias = unum_open(style, NULL, 0, bundle->fLocale, NULL, &status);
                if (U_FAILURE(status)) {
                    unum_close(formatAlias);
                    formatAlias = NULL;
                }
                else {
                    bundle->fNumberFormat[style-1] = formatAlias;
                }
            }
        }
    }
    return formatAlias;
}
/*
Function:
GetLocaleInfoDecimalFormatSymbol

Obtains the value of a DecimalFormatSymbols
*/
static UErrorCode GetLocaleInfoDecimalFormatSymbol(const char* locale,
                                                   UNumberFormatSymbol symbol,
                                                   UChar* value,
                                                   int32_t valueLength)
{
    UErrorCode status = U_ZERO_ERROR;
    UNumberFormat* pFormat = unum_open(UNUM_DECIMAL, NULL, 0, locale, NULL, &status);
    unum_getSymbol(pFormat, symbol, value, valueLength, &status);
    unum_close(pFormat);
    return status;
}
Example #12
0
/**
 * 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);
}
Example #13
0
/*
Function:
GetLocaleInfoDecimalFormatSymbol

Obtains the value of a DecimalFormatSymbols
*/
UErrorCode
GetLocaleInfoDecimalFormatSymbol(const char* locale, UNumberFormatSymbol symbol, UChar* value, int32_t valueLength)
{
    UErrorCode status = U_ZERO_ERROR;
    UNumberFormat* pFormat = unum_open(UNUM_DECIMAL, nullptr, 0, locale, nullptr, &status);
    UNumberFormatHolder formatHolder(pFormat, status);

    if (U_FAILURE(status))
    {
        return status;
    }

    unum_getSymbol(pFormat, symbol, value, valueLength, &status);

    return status;
}
Example #14
0
/* {{{ */
static int numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_constructor)
{
	const char* locale;
	char*       pattern = NULL;
	size_t      locale_len = 0, pattern_len = 0;
	zend_long   style;
	UChar*      spattern     = NULL;
	int32_t     spattern_len = 0;
	int         zpp_flags = is_constructor ? ZEND_PARSE_PARAMS_THROW : 0;
	FORMATTER_METHOD_INIT_VARS;

	/* Parse parameters. */
	if( zend_parse_parameters_ex( zpp_flags, ZEND_NUM_ARGS(), "sl|s",
		&locale, &locale_len, &style, &pattern, &pattern_len ) == FAILURE )
	{
		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"numfmt_create: unable to parse input parameters", 0 );
		return FAILURE;
	}

	INTL_CHECK_LOCALE_LEN_OR_FAILURE(locale_len);
	object = return_value;
	FORMATTER_METHOD_FETCH_OBJECT_NO_CHECK;

	/* Convert pattern (if specified) to UTF-16. */
	if(pattern && pattern_len) {
		intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo));
		INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16");
	}

	if(locale_len == 0) {
		locale = intl_locale_get_default();
	}

	/* Create an ICU number formatter. */
	FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo));

	if(spattern) {
		efree(spattern);
	}

	INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed");
	return SUCCESS;
}
Example #15
0
/**
 * Test localized currency patterns.
 */
static void TestCurrency(void)
{
    UNumberFormat *currencyFmt;
    UChar *str;
    int32_t lneed, i;
    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\\u00a0$", "1,50\\u00a0DM", "1,50\\u00a0F"};
    log_verbose("\nTesting the number format with different currency patterns\n");
    for(i=0; i < 3; i++)
    {
        str=NULL;
        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 {
            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 {
                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);
    }
}
Example #16
0
/* {{{ */
static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
	char*       locale;
	char*       pattern = NULL;
	int         locale_len = 0, pattern_len = 0;
	long        style;
	UChar*      spattern     = NULL;
	int         spattern_len = 0;
	FORMATTER_METHOD_INIT_VARS;

	/* Parse parameters. */
	if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sl|s",
		&locale, &locale_len, &style, &pattern, &pattern_len ) == FAILURE )
	{
		intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
			"numfmt_create: unable to parse input parameters", 0 TSRMLS_CC );
		zval_dtor(return_value);
		RETURN_NULL();
	}

	INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
	object = return_value;
	FORMATTER_METHOD_FETCH_OBJECT;

	/* Convert pattern (if specified) to UTF-16. */
	if(pattern && pattern_len) {
		intl_convert_utf8_to_utf16(&spattern, &spattern_len, pattern, pattern_len, &INTL_DATA_ERROR_CODE(nfo));
		INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: error converting pattern to UTF-16");
	}

	if(locale_len == 0) {
		locale = INTL_G(default_locale);
	}

	/* Create an ICU number formatter. */
	FORMATTER_OBJECT(nfo) = unum_open(style, spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(nfo));

	if(spattern) {
		efree(spattern);
	}

	INTL_CTOR_CHECK_STATUS(nfo, "numfmt_create: number formatter creation failed");
}
Example #17
0
static inline UNumberFormat * copyInvariantFormatter(ULocaleBundle *result, UNumberFormatStyle style) {
    U_NAMESPACE_USE
    Mutex lock(&gLock);
    if (result->fNumberFormat[style-1] == NULL) {
        if (gPosixNumberFormat[style-1] == NULL) {
            UErrorCode status = U_ZERO_ERROR;
            UNumberFormat *formatAlias = unum_open(style, NULL, 0, "en_US_POSIX", NULL, &status);
            if (U_SUCCESS(status)) {
                gPosixNumberFormat[style-1] = formatAlias;
                ucln_io_registerCleanup(UCLN_IO_LOCBUND, locbund_cleanup);
            }
        }
        /* Copy the needed formatter. */
        if (gPosixNumberFormat[style-1] != NULL) {
            UErrorCode status = U_ZERO_ERROR;
            result->fNumberFormat[style-1] = unum_clone(gPosixNumberFormat[style-1], &status);
        }
    }
    return result->fNumberFormat[style-1];
}
/*
Function:
GetPercentPositivePattern

Implementation of NumberFormatInfo.PercentPositivePattern.
Returns the pattern index.
*/
int GetPercentPositivePattern(const char* locale)
{
    const int DEFAULT_VALUE = 0;
    static const char* Patterns[] = {"n %", "n%", "%n", "% n"};
    UErrorCode status = U_ZERO_ERROR;

    UNumberFormat* pFormat = unum_open(UNUM_PERCENT, nullptr, 0, locale, nullptr, &status);
    UNumberFormatHolder formatHolder(pFormat, status);

    assert(U_SUCCESS(status));

    if (U_SUCCESS(status))
    {
        int value = GetNumericPattern(pFormat, Patterns, ARRAY_LENGTH(Patterns), false);
        if (value >= 0)
        {
            return value;
        }
    }

    return DEFAULT_VALUE;
}
Example #19
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;
}
/*
Function:
GetNumberNegativePattern

Implementation of NumberFormatInfo.NumberNegativePattern.
Returns the pattern index.
*/
int GetNumberNegativePattern(const char* locale)
{
    const int DEFAULT_VALUE = 1;
    static const char* Patterns[] = {"(n)", "-n", "- n", "n-", "n -"};
    UErrorCode status = U_ZERO_ERROR;

    UNumberFormat* pFormat = unum_open(UNUM_DECIMAL, nullptr, 0, locale, nullptr, &status);
    UNumberFormatHolder formatHolder(pFormat, status);

    assert(U_SUCCESS(status));

    if (U_SUCCESS(status))
    {
        int value = GetNumericPattern(pFormat, Patterns, ARRAY_LENGTH(Patterns), true);
        if (value >= 0)
        {
            return value;
        }
    }

    return DEFAULT_VALUE;
}
Example #21
0
/**
 * Test proper rounding by the format method.
 */
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"
     - 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));
    } 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);
}
Example #22
0
static void TestPrefixSuffix(void) {
    int32_t	pos;
    UErrorCode status;
    double result1 = 0.0, result2 = 0.0;
    UNumberFormat* parser;
    UChar buffer[4];
    static const UChar TEST_NUMBER[] = {0x0024,0x0031,0x0032,0x002E,0x0030,0x0030,0}; /* $12.00 */
    static const UChar NEG_PREFIX[] = {0x005B,0}; /* "[" */
    static const UChar NEG_SUFFIX[] = {0x005D,0}; /* "]" */


	status = U_ZERO_ERROR;
	parser = unum_open(UNUM_CURRENCY, NULL, -1, "en_US", NULL, &status);
    if (U_FAILURE(status)) {
       log_data_err("Error: unum_open returned %s (Are you missing data?)\n", u_errorName(status));
       return;
    }

	pos = 0;
	status = U_ZERO_ERROR;
	result1 = unum_parseDoubleCurrency(parser, TEST_NUMBER, -1, &pos, buffer, &status);

	unum_setTextAttribute(parser, UNUM_NEGATIVE_SUFFIX, NEG_SUFFIX, -1, &status);
	unum_setTextAttribute(parser, UNUM_NEGATIVE_PREFIX, NEG_PREFIX, -1, &status);
    if (U_FAILURE(status)) {
       log_err("Error: unum_setTextAttribute returned %s\n", u_errorName(status));
       return;
    }

	pos = 0;
	result2 = unum_parseDoubleCurrency(parser, TEST_NUMBER, -1, &pos, buffer, &status);
    if (result1 != result2 || U_FAILURE(status)) {
       log_err("Error: unum_parseDoubleCurrency didn't return the same value for same string %f %f %s\n",
           result1, result2, u_errorName(status));
    }
    unum_close(parser);
}
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
}
void IntlNumberFormat::initializeNumberFormat(ExecState& state, JSValue locales, JSValue optionsValue)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // 11.1.2 InitializeNumberFormat (numberFormat, locales, options) (ECMA-402)
    // https://tc39.github.io/ecma402/#sec-initializenumberformat

    auto requestedLocales = canonicalizeLocaleList(state, locales);
    RETURN_IF_EXCEPTION(scope, void());

    JSObject* options;
    if (optionsValue.isUndefined())
        options = constructEmptyObject(&state, state.lexicalGlobalObject()->nullPrototypeObjectStructure());
    else {
        options = optionsValue.toObject(&state);
        RETURN_IF_EXCEPTION(scope, void());
    }

    HashMap<String, String> opt;

    String matcher = intlStringOption(state, options, vm.propertyNames->localeMatcher, { "lookup", "best fit" }, "localeMatcher must be either \"lookup\" or \"best fit\"", "best fit");
    RETURN_IF_EXCEPTION(scope, void());
    opt.add("localeMatcher"_s, matcher);

    auto& availableLocales = state.jsCallee()->globalObject(vm)->intlNumberFormatAvailableLocales();
    auto result = resolveLocale(state, availableLocales, requestedLocales, opt, relevantNumberExtensionKeys, WTF_ARRAY_LENGTH(relevantNumberExtensionKeys), IntlNFInternal::localeData);

    m_locale = result.get("locale"_s);
    if (m_locale.isEmpty()) {
        throwTypeError(&state, scope, "failed to initialize NumberFormat due to invalid locale"_s);
        return;
    }

    m_numberingSystem = result.get("nu"_s);

    String styleString = intlStringOption(state, options, Identifier::fromString(&vm, "style"), { "decimal", "percent", "currency" }, "style must be either \"decimal\", \"percent\", or \"currency\"", "decimal");
    RETURN_IF_EXCEPTION(scope, void());
    if (styleString == "decimal")
        m_style = Style::Decimal;
    else if (styleString == "percent")
        m_style = Style::Percent;
    else if (styleString == "currency")
        m_style = Style::Currency;
    else
        ASSERT_NOT_REACHED();

    String currency = intlStringOption(state, options, Identifier::fromString(&vm, "currency"), { }, nullptr, nullptr);
    RETURN_IF_EXCEPTION(scope, void());
    if (!currency.isNull()) {
        if (currency.length() != 3 || !currency.isAllSpecialCharacters<isASCIIAlpha>()) {
            throwException(&state, scope, createRangeError(&state, "currency is not a well-formed currency code"_s));
            return;
        }
    }

    unsigned currencyDigits = 0;
    if (m_style == Style::Currency) {
        if (currency.isNull()) {
            throwTypeError(&state, scope, "currency must be a string"_s);
            return;
        }

        currency = currency.convertToASCIIUppercase();
        m_currency = currency;
        currencyDigits = computeCurrencyDigits(currency);
    }

    String currencyDisplayString = intlStringOption(state, options, Identifier::fromString(&vm, "currencyDisplay"), { "code", "symbol", "name" }, "currencyDisplay must be either \"code\", \"symbol\", or \"name\"", "symbol");
    RETURN_IF_EXCEPTION(scope, void());
    if (m_style == Style::Currency) {
        if (currencyDisplayString == "code")
            m_currencyDisplay = CurrencyDisplay::Code;
        else if (currencyDisplayString == "symbol")
            m_currencyDisplay = CurrencyDisplay::Symbol;
        else if (currencyDisplayString == "name")
            m_currencyDisplay = CurrencyDisplay::Name;
        else
            ASSERT_NOT_REACHED();
    }

    unsigned minimumIntegerDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "minimumIntegerDigits"), 1, 21, 1);
    RETURN_IF_EXCEPTION(scope, void());
    m_minimumIntegerDigits = minimumIntegerDigits;

    unsigned minimumFractionDigitsDefault = (m_style == Style::Currency) ? currencyDigits : 0;

    unsigned minimumFractionDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "minimumFractionDigits"), 0, 20, minimumFractionDigitsDefault);
    RETURN_IF_EXCEPTION(scope, void());
    m_minimumFractionDigits = minimumFractionDigits;

    unsigned maximumFractionDigitsDefault;
    if (m_style == Style::Currency)
        maximumFractionDigitsDefault = std::max(minimumFractionDigits, currencyDigits);
    else if (m_style == Style::Percent)
        maximumFractionDigitsDefault = minimumFractionDigits;
    else
        maximumFractionDigitsDefault = std::max(minimumFractionDigits, 3u);

    unsigned maximumFractionDigits = intlNumberOption(state, options, Identifier::fromString(&vm, "maximumFractionDigits"), minimumFractionDigits, 20, maximumFractionDigitsDefault);
    RETURN_IF_EXCEPTION(scope, void());
    m_maximumFractionDigits = maximumFractionDigits;

    JSValue minimumSignificantDigitsValue = options->get(&state, Identifier::fromString(&vm, "minimumSignificantDigits"));
    RETURN_IF_EXCEPTION(scope, void());

    JSValue maximumSignificantDigitsValue = options->get(&state, Identifier::fromString(&vm, "maximumSignificantDigits"));
    RETURN_IF_EXCEPTION(scope, void());

    if (!minimumSignificantDigitsValue.isUndefined() || !maximumSignificantDigitsValue.isUndefined()) {
        unsigned minimumSignificantDigits = intlDefaultNumberOption(state, minimumSignificantDigitsValue, Identifier::fromString(&vm, "minimumSignificantDigits"), 1, 21, 1);
        RETURN_IF_EXCEPTION(scope, void());
        unsigned maximumSignificantDigits = intlDefaultNumberOption(state, maximumSignificantDigitsValue, Identifier::fromString(&vm, "maximumSignificantDigits"), minimumSignificantDigits, 21, 21);
        RETURN_IF_EXCEPTION(scope, void());
        m_minimumSignificantDigits = minimumSignificantDigits;
        m_maximumSignificantDigits = maximumSignificantDigits;
    }

    bool usesFallback;
    bool useGrouping = intlBooleanOption(state, options, Identifier::fromString(&vm, "useGrouping"), usesFallback);
    if (usesFallback)
        useGrouping = true;
    RETURN_IF_EXCEPTION(scope, void());
    m_useGrouping = useGrouping;

    UNumberFormatStyle style = UNUM_DEFAULT;
    switch (m_style) {
    case Style::Decimal:
        style = UNUM_DECIMAL;
        break;
    case Style::Percent:
        style = UNUM_PERCENT;
        break;
    case Style::Currency:
        switch (m_currencyDisplay) {
        case CurrencyDisplay::Code:
            style = UNUM_CURRENCY_ISO;
            break;
        case CurrencyDisplay::Symbol:
            style = UNUM_CURRENCY;
            break;
        case CurrencyDisplay::Name:
            style = UNUM_CURRENCY_PLURAL;
            break;
        default:
            ASSERT_NOT_REACHED();
        }
        break;
    default:
        ASSERT_NOT_REACHED();
    }

    UErrorCode status = U_ZERO_ERROR;
    m_numberFormat = std::unique_ptr<UNumberFormat, UNumberFormatDeleter>(unum_open(style, nullptr, 0, m_locale.utf8().data(), nullptr, &status));
    if (U_FAILURE(status)) {
        throwTypeError(&state, scope, "failed to initialize NumberFormat"_s);
        return;
    }

    if (m_style == Style::Currency) {
        unum_setTextAttribute(m_numberFormat.get(), UNUM_CURRENCY_CODE, StringView(m_currency).upconvertedCharacters(), m_currency.length(), &status);
        if (U_FAILURE(status)) {
            throwTypeError(&state, scope, "failed to initialize NumberFormat"_s);
            return;
        }
    }
    if (!m_minimumSignificantDigits) {
        unum_setAttribute(m_numberFormat.get(), UNUM_MIN_INTEGER_DIGITS, m_minimumIntegerDigits);
        unum_setAttribute(m_numberFormat.get(), UNUM_MIN_FRACTION_DIGITS, m_minimumFractionDigits);
        unum_setAttribute(m_numberFormat.get(), UNUM_MAX_FRACTION_DIGITS, m_maximumFractionDigits);
    } else {
        unum_setAttribute(m_numberFormat.get(), UNUM_SIGNIFICANT_DIGITS_USED, true);
        unum_setAttribute(m_numberFormat.get(), UNUM_MIN_SIGNIFICANT_DIGITS, m_minimumSignificantDigits);
        unum_setAttribute(m_numberFormat.get(), UNUM_MAX_SIGNIFICANT_DIGITS, m_maximumSignificantDigits);
    }
    unum_setAttribute(m_numberFormat.get(), UNUM_GROUPING_USED, m_useGrouping);
    unum_setAttribute(m_numberFormat.get(), UNUM_ROUNDING_MODE, UNUM_ROUND_HALFUP);

    m_initializedNumberFormat = true;
}
Example #25
0
/* Test the handling of quotes*/
static void TestQuotes(void)
{
    int32_t lneed;
    UErrorCode status=U_ZERO_ERROR;
    UChar pat[15];
    UChar res[15];
    UChar *str=NULL;
    UNumberFormat *fmt;
    char tempBuf[256];
    log_verbose("\nTestting the handling of quotes in number format\n");
    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_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);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        unum_format(fmt, 123, str, lneed+1,  NULL, &status);
    }
    if(U_FAILURE(status) || !str) {
        log_err_status(status, "Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
        return;
    }
    log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) );
    log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) );
    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");
    }
    lneed=0;
    lneed=unum_format(fmt, 123, NULL, lneed, NULL, &status);
    if(status==U_BUFFER_OVERFLOW_ERROR){
        status=U_ZERO_ERROR;
        str=(UChar*)malloc(sizeof(UChar) * (lneed+1) );
        unum_format(fmt, 123, str, lneed+1,  NULL, &status);
    }
    if(U_FAILURE(status)) {
        log_err("Error in formatting using unum_format(.....): %s\n", myErrorName(status) );
    }
    log_verbose("Pattern \"%s\" \n", u_austrcpy(tempBuf, pat) );
    log_verbose("Format 123 -> %s\n", u_austrcpy(tempBuf, str) );
    u_uastrcpy(res, "");
    u_uastrcpy(res, "a'b123");
    if(u_strcmp(str, res) != 0)
        log_err("FAIL: Expected a'b123\n");

    free(str);
    unum_close(fmt);
}
Example #26
0
/**
 * Test the functioning of the secondary grouping value.
 */
static void TestSecondaryGrouping(void) {
    UErrorCode status = U_ZERO_ERROR;
    UNumberFormat *f = NULL, *g= NULL;
    UNumberFormat *us = unum_open(UNUM_DECIMAL,NULL,0, "en_US", NULL,&status);
    UFieldPosition pos;
    UChar resultBuffer[512];
    int32_t l = 1876543210L;
    UBool ok = TRUE;
    UChar buffer[512];
    int32_t i;
    UBool expectGroup = FALSE, isGroup = FALSE;

    u_uastrcpy(buffer, "#,##,###");
    f = unum_open(UNUM_IGNORE,buffer, -1, "en_US",NULL, &status);
    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", 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, "#,##,##0");
    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
    {
        log_err("Fail: toPattern() got %s, expected %s\n", austrdup(resultBuffer), "#,##,##0");
    }
    memset(resultBuffer,0, sizeof(UChar)*512);
    u_uastrcpy(buffer, "#,###");
    unum_applyPattern(f, FALSE, buffer, -1,NULL,NULL);
    if (U_FAILURE(status))
    {
        log_err("Fail: applyPattern call failed\n");
    }
    unum_setAttribute(f, UNUM_SECONDARY_GROUPING_SIZE, 4);
    unum_format(f, (int32_t)123456789L, resultBuffer, 512 , &pos, &status);
    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", austrdup(resultBuffer), "12,3456,789");
    }
    memset(resultBuffer,0, sizeof(UChar)*512);
    unum_toPattern(f, FALSE, resultBuffer, 512, &status);
    u_uastrcpy(buffer, "#,####,##0");
    if ((u_strcmp(resultBuffer, buffer) != 0) || U_FAILURE(status))
    {
        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);
    if (U_FAILURE(status))
    {
        log_err("Fail: Cannot create UNumberFormat for \"hi_IN\" locale.\n");
    }

    unum_format(g, l, resultBuffer, 512, &pos, &status);
    unum_close(g);
    /* expect "1,87,65,43,210", but with Hindi digits */
    /*         01234567890123                         */
    if (u_strlen(resultBuffer) != 14) {
        ok = FALSE;
    } else {
        for (i=0; i<u_strlen(resultBuffer); ++i) {
            expectGroup = FALSE;
            switch (i) {
            case 1:
            case 4:
            case 7:
            case 10:
                expectGroup = TRUE;
                break;
            }
            /* Later -- fix this to get the actual grouping */
            /* character from the resource bundle.          */
            isGroup = (UBool)(resultBuffer[i] == 0x002C);
            if (isGroup != expectGroup) {
                ok = FALSE;
                break;
            }
        }
    }
    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);
}
Example #27
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);
    }
}
Example #28
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);
}
Example #29
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);
    }
}
Example #30
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);
    }
}