mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
ICU-12763 Add uplrules_selectWithFormat and PluralRules::select that take & use [U]NumberFormat
X-SVN-Rev: 39591
This commit is contained in:
parent
183b124712
commit
47e1aaaf14
5 changed files with 135 additions and 20 deletions
|
@ -17,6 +17,8 @@
|
|||
#include "unicode/plurrule.h"
|
||||
#include "unicode/upluralrules.h"
|
||||
#include "unicode/ures.h"
|
||||
#include "unicode/numfmt.h"
|
||||
#include "unicode/decimfmt.h"
|
||||
#include "charstr.h"
|
||||
#include "cmemory.h"
|
||||
#include "cstring.h"
|
||||
|
@ -36,7 +38,6 @@
|
|||
#include "digitinterval.h"
|
||||
#include "visibledigits.h"
|
||||
|
||||
|
||||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
@ -246,6 +247,24 @@ PluralRules::select(double number) const {
|
|||
return select(FixedDecimal(number));
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
PluralRules::select(const Formattable& obj, const NumberFormat& fmt) const {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(&fmt);
|
||||
if (decFmt != NULL) {
|
||||
VisibleDigitsWithExponent digits;
|
||||
decFmt->initVisibleDigitsWithExponent(obj, digits, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return select(digits);
|
||||
}
|
||||
}
|
||||
double number = obj.getDouble(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
return select(number);
|
||||
}
|
||||
return getKeywordOther();
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
PluralRules::select(const FixedDecimal &number) const {
|
||||
if (mRules == NULL) {
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
|
||||
#include "unicode/format.h"
|
||||
#include "unicode/upluralrules.h"
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
#include "unicode/numfmt.h"
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
/**
|
||||
* Value returned by PluralRules::getUniqueKeywordValue() when there is no
|
||||
|
@ -345,6 +348,19 @@ public:
|
|||
UnicodeString select(double number) const;
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Given a number and a format, returns the keyword of the first applicable
|
||||
* rule for this PluralRules object.
|
||||
* Note: This internal preview interface may be removed in the future if
|
||||
* an architecturally cleaner solution reaches stable status.
|
||||
* @param obj The numeric object for which the rule should be determined.
|
||||
* @param fmt The NumberFormat specifying how the number will be formatted
|
||||
* (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
|
||||
* @return The keyword of the selected rule.
|
||||
* @internal ICU 59 technology preview, may be removed in the future
|
||||
*/
|
||||
UnicodeString select(const Formattable& obj, const NumberFormat& fmt) const;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#if !UCONFIG_NO_FORMATTING
|
||||
|
||||
#include "unicode/localpointer.h"
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
#include "unicode/unum.h"
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
/**
|
||||
* \file
|
||||
|
@ -144,6 +147,33 @@ uplrules_select(const UPluralRules *uplrules,
|
|||
UChar *keyword, int32_t capacity,
|
||||
UErrorCode *status);
|
||||
|
||||
#ifndef U_HIDE_INTERNAL_API
|
||||
/**
|
||||
* Given a number, returns the keyword of the first rule that applies to the
|
||||
* number, according to the UPluralRules object and given the number format
|
||||
* specified by the UNumberFormat object.
|
||||
* Note: This internal preview interface may be removed in the future if
|
||||
* an architecturally cleaner solution reaches stable status.
|
||||
* @param uplrules The UPluralRules object specifying the rules.
|
||||
* @param number The number for which the rule has to be determined.
|
||||
* @param fmt The UNumberFormat specifying how the number will be formatted
|
||||
* (this can affect the plural form, e.g. "1 dollar" vs "1.0 dollars").
|
||||
* If this is NULL, the function behaves like uplrules_select.
|
||||
* @param keyword The keyword of the rule that applies to number.
|
||||
* @param capacity The capacity of the keyword buffer.
|
||||
* @param status A pointer to a UErrorCode to receive any errors.
|
||||
* @return The length of keyword.
|
||||
* @internal ICU 59 technology preview, may be removed in the future
|
||||
*/
|
||||
U_INTERNAL int32_t U_EXPORT2
|
||||
uplrules_selectWithFormat(const UPluralRules *uplrules,
|
||||
double number,
|
||||
const UNumberFormat *fmt,
|
||||
UChar *keyword, int32_t capacity,
|
||||
UErrorCode *status);
|
||||
|
||||
#endif /* U_HIDE_INTERNAL_API */
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "unicode/plurrule.h"
|
||||
#include "unicode/locid.h"
|
||||
#include "unicode/unistr.h"
|
||||
#include "unicode/unum.h"
|
||||
#include "unicode/numfmt.h"
|
||||
|
||||
U_NAMESPACE_USE
|
||||
|
||||
|
@ -54,5 +56,25 @@ uplrules_select(const UPluralRules *uplrules,
|
|||
return result.extract(keyword, capacity, *status);
|
||||
}
|
||||
|
||||
U_CAPI int32_t U_EXPORT2
|
||||
uplrules_selectWithFormat(const UPluralRules *uplrules,
|
||||
double number,
|
||||
const UNumberFormat *fmt,
|
||||
UChar *keyword, int32_t capacity,
|
||||
UErrorCode *status)
|
||||
{
|
||||
if (U_FAILURE(*status)) {
|
||||
return 0;
|
||||
}
|
||||
const PluralRules* plrules = reinterpret_cast<const PluralRules*>(uplrules);
|
||||
const NumberFormat* nf = reinterpret_cast<const NumberFormat*>(fmt);
|
||||
if (plrules == NULL || nf == NULL || ((keyword == NULL)? capacity != 0 : capacity < 0)) {
|
||||
*status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return 0;
|
||||
}
|
||||
Formattable obj(number);
|
||||
UnicodeString result = plrules->select(obj, *nf);
|
||||
return result.extract(keyword, capacity, *status);
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -32,31 +32,34 @@ typedef struct {
|
|||
const char * locale;
|
||||
double number;
|
||||
const char * keywordExpected;
|
||||
const char * keywordExpectedForDecimals;
|
||||
} PluralRulesTestItem;
|
||||
|
||||
/* Just a small set of tests for now, other functionality is tested in the C++ tests */
|
||||
static const PluralRulesTestItem testItems[] = {
|
||||
{ "en", 0, "other" },
|
||||
{ "en", 0.5, "other" },
|
||||
{ "en", 1, "one" },
|
||||
{ "en", 1.5, "other" },
|
||||
{ "en", 2, "other" },
|
||||
{ "fr", 0, "one" },
|
||||
{ "fr", 0.5, "one" },
|
||||
{ "fr", 1, "one" },
|
||||
{ "fr", 1.5, "one" },
|
||||
{ "fr", 2, "other" },
|
||||
{ "ru", 0, "many" },
|
||||
{ "ru", 0.5, "other" },
|
||||
{ "ru", 1, "one" },
|
||||
{ "ru", 1.5, "other" },
|
||||
{ "ru", 2, "few" },
|
||||
{ "ru", 5, "many" },
|
||||
{ "ru", 10, "many" },
|
||||
{ "ru", 11, "many" },
|
||||
{ NULL, 0, NULL }
|
||||
{ "en", 0, "other", "other" },
|
||||
{ "en", 0.5, "other", "other" },
|
||||
{ "en", 1, "one", "other" },
|
||||
{ "en", 1.5, "other", "other" },
|
||||
{ "en", 2, "other", "other" },
|
||||
{ "fr", 0, "one", "one" },
|
||||
{ "fr", 0.5, "one", "one" },
|
||||
{ "fr", 1, "one", "one" },
|
||||
{ "fr", 1.5, "one", "one" },
|
||||
{ "fr", 2, "other", "other" },
|
||||
{ "ru", 0, "many", "other" },
|
||||
{ "ru", 0.5, "other", "other" },
|
||||
{ "ru", 1, "one", "other" },
|
||||
{ "ru", 1.5, "other", "other" },
|
||||
{ "ru", 2, "few", "other" },
|
||||
{ "ru", 5, "many", "other" },
|
||||
{ "ru", 10, "many", "other" },
|
||||
{ "ru", 11, "many", "other" },
|
||||
{ NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static const UChar twoDecimalPat[] = { 0x23,0x30,0x2E,0x30,0x30,0 }; /* "#0.00" */
|
||||
|
||||
enum {
|
||||
kKeywordBufLen = 32
|
||||
};
|
||||
|
@ -69,6 +72,7 @@ static void TestPluralRules()
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UPluralRules* uplrules = uplrules_open(testItemPtr->locale, &status);
|
||||
if ( U_SUCCESS(status) ) {
|
||||
UNumberFormat* unumfmt;
|
||||
UChar keyword[kKeywordBufLen];
|
||||
UChar keywordExpected[kKeywordBufLen];
|
||||
int32_t keywdLen = uplrules_select(uplrules, testItemPtr->number, keyword, kKeywordBufLen, &status);
|
||||
|
@ -86,6 +90,30 @@ static void TestPluralRules()
|
|||
log_err("FAIL: uplrules_select for locale %s, number %.1f: %s\n",
|
||||
testItemPtr->locale, testItemPtr->number, myErrorName(status) );
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
unumfmt = unum_open(UNUM_PATTERN_DECIMAL, twoDecimalPat, -1, testItemPtr->locale, NULL, &status);
|
||||
if ( U_SUCCESS(status) ) {
|
||||
keywdLen = uplrules_selectWithFormat(uplrules, testItemPtr->number, unumfmt, keyword, kKeywordBufLen, &status);
|
||||
if (keywdLen >= kKeywordBufLen) {
|
||||
keyword[kKeywordBufLen-1] = 0;
|
||||
}
|
||||
if ( U_SUCCESS(status) ) {
|
||||
u_unescape(testItemPtr->keywordExpectedForDecimals, keywordExpected, kKeywordBufLen);
|
||||
if ( u_strcmp(keyword, keywordExpected) != 0 ) {
|
||||
char bcharBuf[kKeywordBufLen];
|
||||
log_data_err("ERROR: uplrules_selectWithFormat for locale %s, number %.1f: expect %s, get %s\n",
|
||||
testItemPtr->locale, testItemPtr->number, testItemPtr->keywordExpectedForDecimals, u_austrcpy(bcharBuf,keyword) );
|
||||
}
|
||||
} else {
|
||||
log_err("FAIL: uplrules_selectWithFormat for locale %s, number %.1f: %s\n",
|
||||
testItemPtr->locale, testItemPtr->number, myErrorName(status) );
|
||||
}
|
||||
unum_close(unumfmt);
|
||||
} else {
|
||||
log_err("FAIL: unum_open for locale %s: %s\n", testItemPtr->locale, myErrorName(status) );
|
||||
}
|
||||
|
||||
uplrules_close(uplrules);
|
||||
} else {
|
||||
log_err("FAIL: uplrules_open for locale %s: %s\n", testItemPtr->locale, myErrorName(status) );
|
||||
|
|
Loading…
Add table
Reference in a new issue