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); }
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); }
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; }
/* 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); }
/*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); } }
/* * 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); }
LocaleICU::~LocaleICU() { unum_close(m_numberFormat); udat_close(m_shortDateFormat); udat_close(m_mediumTimeFormat); udat_close(m_shortTimeFormat); }
LocaleICU::~LocaleICU() { unum_close(m_numberFormat); udat_close(m_shortDateFormat); #if ENABLE(INPUT_MULTIPLE_FIELDS_UI) udat_close(m_mediumTimeFormat); udat_close(m_shortTimeFormat); #endif }
U_CDECL_BEGIN static UBool U_CALLCONV locbund_cleanup(void) { int32_t style; for (style = 0; style < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; style++) { unum_close(gPosixNumberFormat[style]); gPosixNumberFormat[style] = NULL; } return TRUE; }
/* 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; }
/** * 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); }
U_CAPI void u_locbund_close(ULocaleBundle *bundle) { int32_t styleIdx; uprv_free(bundle->fLocale); for (styleIdx = 0; styleIdx < ULOCALEBUNDLE_NUMBERFORMAT_COUNT; styleIdx++) { if (bundle->fNumberFormat[styleIdx]) { unum_close(bundle->fNumberFormat[styleIdx]); } } uprv_memset(bundle, 0, sizeof(ULocaleBundle)); /* uprv_free(bundle);*/ }
/** * 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); } }
/** * 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); }
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 sweep() override { if (m_formatter) { unum_close(m_formatter); m_formatter = nullptr; } }
ICULocale::~ICULocale() { unum_close(m_numberFormat); udat_close(m_shortDateFormat); }
/** * 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); }
/* Print out a calendar for c's current month */ static void print_month(UCalendar *c, UChar *days [], UBool useLongNames, int32_t fdow, UErrorCode *status) { int32_t width, pad, i, day; int32_t lens [DAY_COUNT]; int32_t firstday, current; UNumberFormat *nfmt; UDateFormat *dfmt; UChar s [BUF_SIZE]; const UChar *pat = (useLongNames ? sLongPat : sShortPat); int32_t len = (useLongNames ? 9 : 8); if(U_FAILURE(*status)) return; /* ========== Generate the header containing the month and year */ /* Open a formatter with a month and year only pattern */ dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len,status); /* Format the date */ udat_format(dfmt, ucal_getMillis(c, status), s, BUF_SIZE, 0, status); /* ========== Get the day names */ get_days(dfmt, days, useLongNames, fdow, status); /* ========== Print the header */ /* Calculate widths for justification */ width = 6; /* 6 spaces, 1 between each day name */ for(i = 0; i < DAY_COUNT; ++i) { lens[i] = u_strlen(days[i]); width += lens[i]; } /* Print the header, centered among the day names */ pad = width - u_strlen(s); indent(pad / 2, stdout); uprint(s, stdout, status); putc('\n', stdout); /* ========== Print the day names */ print_days(days, stdout, status); putc('\n', stdout); /* ========== Print the calendar */ /* Get the first of the month */ ucal_set(c, UCAL_DATE, 1); firstday = ucal_get(c, UCAL_DAY_OF_WEEK, status); /* The day of the week for the first day of the month is based on 1-based days of the week, which were also reordered when placed in the days array. Account for this here by offsetting by the first day of the week for the locale, which is also 1-based. */ firstday -= fdow; /* Open the formatter */ nfmt = unum_open(UNUM_DECIMAL, NULL,0,NULL,NULL, status); /* Indent the correct number of spaces for the first week */ current = firstday; if(current < 0) { current += 7; } for(i = 0; i < current; ++i) indent(lens[i] + 1, stdout); /* Finally, print out the days */ day = ucal_get(c, UCAL_DATE, status); do { /* Format the current day string */ unum_format(nfmt, day, s, BUF_SIZE, 0, status); /* Calculate the justification and indent */ pad = lens[current] - u_strlen(s); indent(pad, stdout); /* Print the day number out, followed by a space */ uprint(s, stdout, status); putc(' ', stdout); /* Update the current day */ ++current; current %= DAY_COUNT; /* If we're at day 0 (first day of the week), insert a newline */ if(current == 0) { putc('\n', stdout); } /* Go to the next day */ ucal_add(c, UCAL_DATE, 1, status); day = ucal_get(c, UCAL_DATE, status); } while(day != 1); /* Output a trailing newline */ putc('\n', stdout); /* Clean up */ free_days(days); unum_close(nfmt); udat_close(dfmt); }
/* Print out a calendar for c's current year */ static void print_year(UCalendar *c, UChar *days [], UChar *months [], UBool useLongNames, int32_t fdow, UErrorCode *status) { int32_t width, pad, i, j; int32_t lens [DAY_COUNT]; UNumberFormat *nfmt; UDateFormat *dfmt; UChar s [BUF_SIZE]; const UChar pat [] = { 0x0079, 0x0079, 0x0079, 0x0079 }; int32_t len = 4; UCalendar *left_cal, *right_cal; int32_t left_day, right_day; int32_t left_firstday, right_firstday, left_current, right_current; int32_t left_month, right_month; if(U_FAILURE(*status)) return; /* Alias */ left_cal = c; /* ========== Generate the header containing the year (only) */ /* Open a formatter with a month and year only pattern */ dfmt = udat_open(UDAT_IGNORE,UDAT_IGNORE,NULL,NULL,0,pat, len, status); /* Format the date */ udat_format(dfmt, ucal_getMillis(left_cal, status), s, BUF_SIZE, 0, status); /* ========== Get the month and day names */ get_days(dfmt, days, useLongNames, fdow, status); get_months(dfmt, months, useLongNames, status); /* ========== Print the header, centered */ /* Calculate widths for justification */ width = 6; /* 6 spaces, 1 between each day name */ for(i = 0; i < DAY_COUNT; ++i) { lens[i] = u_strlen(days[i]); width += lens[i]; } /* width is the width for 1 calendar; we are displaying in 2 cols with MARGIN_WIDTH spaces between months */ /* Print the header, centered among the day names */ pad = 2 * width + MARGIN_WIDTH - u_strlen(s); indent(pad / 2, stdout); uprint(s, stdout, status); putc('\n', stdout); putc('\n', stdout); /* Generate a copy of the calendar to use */ right_cal = ucal_open(0, -1, uloc_getDefault(), UCAL_TRADITIONAL, status); ucal_setMillis(right_cal, ucal_getMillis(left_cal, status), status); /* Open the formatter */ nfmt = unum_open(UNUM_DECIMAL,NULL, 0,NULL,NULL, status); /* ========== Calculate and display the months, two at a time */ for(i = 0; i < MONTH_COUNT - 1; i += 2) { /* Print the month names for the two current months */ pad = width - u_strlen(months[i]); indent(pad / 2, stdout); uprint(months[i], stdout, status); indent(pad / 2 + MARGIN_WIDTH, stdout); pad = width - u_strlen(months[i + 1]); indent(pad / 2, stdout); uprint(months[i + 1], stdout, status); putc('\n', stdout); /* Print the day names, twice */ print_days(days, stdout, status); indent(MARGIN_WIDTH, stdout); print_days(days, stdout, status); putc('\n', stdout); /* Setup the two calendars */ ucal_set(left_cal, UCAL_MONTH, i); ucal_set(left_cal, UCAL_DATE, 1); ucal_set(right_cal, UCAL_MONTH, i + 1); ucal_set(right_cal, UCAL_DATE, 1); left_firstday = ucal_get(left_cal, UCAL_DAY_OF_WEEK, status); right_firstday = ucal_get(right_cal, UCAL_DAY_OF_WEEK, status); /* The day of the week for the first day of the month is based on 1-based days of the week. However, the days were reordered when placed in the days array. Account for this here by offsetting by the first day of the week for the locale, which is also 1-based. */ /* We need to mod by DAY_COUNT since fdow can be > firstday. IE, if fdow = 2 = Monday (like in France) and the first day of the month is a 1 = Sunday, we want firstday to be 6, not -1 */ left_firstday += (DAY_COUNT - fdow); left_firstday %= DAY_COUNT; right_firstday += (DAY_COUNT - fdow); right_firstday %= DAY_COUNT; left_current = left_firstday; right_current = right_firstday; left_day = ucal_get(left_cal, UCAL_DATE, status); right_day = ucal_get(right_cal, UCAL_DATE, status); left_month = ucal_get(left_cal, UCAL_MONTH, status); right_month = ucal_get(right_cal, UCAL_MONTH, status); /* Finally, print out the days */ while(left_month == i || right_month == i + 1) { /* If the left month is finished printing, but the right month still has days to be printed, indent the width of the days strings and reset the left calendar's current day to 0 */ if(left_month != i && right_month == i + 1) { indent(width + 1, stdout); left_current = 0; } while(left_month == i) { /* If the day is the first, indent the correct number of spaces for the first week */ if(left_day == 1) { for(j = 0; j < left_current; ++j) indent(lens[j] + 1, stdout); } /* Format the current day string */ unum_format(nfmt, left_day, s, BUF_SIZE, 0, status); /* Calculate the justification and indent */ pad = lens[left_current] - u_strlen(s); indent(pad, stdout); /* Print the day number out, followed by a space */ uprint(s, stdout, status); putc(' ', stdout); /* Update the current day */ ++left_current; left_current %= DAY_COUNT; /* Go to the next day */ ucal_add(left_cal, UCAL_DATE, 1, status); left_day = ucal_get(left_cal, UCAL_DATE, status); /* Determine the month */ left_month = ucal_get(left_cal, UCAL_MONTH, status); /* If we're at day 0 (first day of the week), break and go to the next month */ if(left_current == 0) { break; } }; /* If the current day isn't 0, indent to make up for missing days at the end of the month */ if(left_current != 0) { for(j = left_current; j < DAY_COUNT; ++j) indent(lens[j] + 1, stdout); } /* Indent between the two months */ indent(MARGIN_WIDTH, stdout); while(right_month == i + 1) { /* If the day is the first, indent the correct number of spaces for the first week */ if(right_day == 1) { for(j = 0; j < right_current; ++j) indent(lens[j] + 1, stdout); } /* Format the current day string */ unum_format(nfmt, right_day, s, BUF_SIZE, 0, status); /* Calculate the justification and indent */ pad = lens[right_current] - u_strlen(s); indent(pad, stdout); /* Print the day number out, followed by a space */ uprint(s, stdout, status); putc(' ', stdout); /* Update the current day */ ++right_current; right_current %= DAY_COUNT; /* Go to the next day */ ucal_add(right_cal, UCAL_DATE, 1, status); right_day = ucal_get(right_cal, UCAL_DATE, status); /* Determine the month */ right_month = ucal_get(right_cal, UCAL_MONTH, status); /* If we're at day 0 (first day of the week), break out */ if(right_current == 0) { break; } }; /* Output a newline */ putc('\n', stdout); } /* Output a trailing newline */ putc('\n', stdout); } /* Clean up */ free_months(months); free_days(days); udat_close(dfmt); unum_close(nfmt); ucal_close(right_cal); }
/** * 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); } }
/** * 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); } }
/** * 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); }
/* 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); } }
/* 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); }
/** * 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); }
void IntlNumberFormat::UNumberFormatDeleter::operator()(UNumberFormat* numberFormat) const { if (numberFormat) unum_close(numberFormat); }
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 }
/* PAL Function: GetLocaleInfoInt Obtains integer locale information Returns 1 for success, 0 otherwise */ extern "C" int32_t GlobalizationNative_GetLocaleInfoInt( const UChar* localeName, LocaleNumberData localeNumberData, int32_t* value) { 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); } switch (localeNumberData) { case LanguageId: *value = uloc_getLCID(locale); break; case MeasurementSystem: status = GetMeasurementSystem(locale, value); break; case FractionalDigitsCount: { UNumberFormat* numformat = unum_open(UNUM_DECIMAL, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); unum_close(numformat); } break; } case NegativeNumberFormat: *value = GetNumberNegativePattern(locale); break; case MonetaryFractionalDigitsCount: { UNumberFormat* numformat = unum_open(UNUM_CURRENCY, NULL, 0, locale, NULL, &status); if (U_SUCCESS(status)) { *value = unum_getAttribute(numformat, UNUM_MAX_FRACTION_DIGITS); unum_close(numformat); } break; } case PositiveMonetaryNumberFormat: *value = GetCurrencyPositivePattern(locale); break; case NegativeMonetaryNumberFormat: *value = GetCurrencyNegativePattern(locale); break; case FirstWeekOfYear: { // corresponds to DateTimeFormat.CalendarWeekRule UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) { // values correspond to LOCALE_IFIRSTWEEKOFYEAR int minDaysInWeek = ucal_getAttribute(pCal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK); if (minDaysInWeek == 1) { *value = CalendarWeekRule::FirstDay; } else if (minDaysInWeek == 7) { *value = CalendarWeekRule::FirstFullWeek; } else if (minDaysInWeek >= 4) { *value = CalendarWeekRule::FirstFourDayWeek; } else { status = U_UNSUPPORTED_ERROR; } } break; } case ReadingLayout: { // coresponds to values 0 and 1 in LOCALE_IREADINGLAYOUT (values 2 and 3 not // used in coreclr) // 0 - Left to right (such as en-US) // 1 - Right to left (such as arabic locales) ULayoutType orientation = uloc_getCharacterOrientation(locale, &status); // alternative implementation in ICU 54+ is uloc_isRightToLeft() which // also supports script tags in locale if (U_SUCCESS(status)) { *value = (orientation == ULOC_LAYOUT_RTL) ? 1 : 0; } break; } case FirstDayofWeek: { UCalendar* pCal = ucal_open(nullptr, 0, locale, UCAL_TRADITIONAL, &status); UCalendarHolder calHolder(pCal, status); if (U_SUCCESS(status)) { *value = ucal_getAttribute(pCal, UCAL_FIRST_DAY_OF_WEEK) - 1; // .NET is 0-based and ICU is 1-based } break; } case NegativePercentFormat: *value = GetPercentNegativePattern(locale); break; case PositivePercentFormat: *value = GetPercentPositivePattern(locale); break; default: status = U_UNSUPPORTED_ERROR; assert(false); break; } return UErrorCodeToBool(status); }