Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Unified Diff: source/i18n/rbnf.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/i18n/quantityformatter.cpp ('k') | source/i18n/rbt_data.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/i18n/rbnf.cpp
diff --git a/source/i18n/rbnf.cpp b/source/i18n/rbnf.cpp
index 682d449f38a6a6c53cc3ef29d7f2e593cb9b84cb..bdfd71a4dc387fca1d7b3a6412b88d6d6ced1b79 100644
--- a/source/i18n/rbnf.cpp
+++ b/source/i18n/rbnf.cpp
@@ -1,10 +1,11 @@
/*
*******************************************************************************
-* Copyright (C) 1997-2013, International Business Machines Corporation
+* Copyright (C) 1997-2014, International Business Machines Corporation
* and others. All Rights Reserved.
*******************************************************************************
*/
+#include "unicode/utypes.h"
#include "utypeinfo.h" // for 'typeid' to work
#include "unicode/rbnf.h"
@@ -12,6 +13,7 @@
#if U_HAVE_RBNF
#include "unicode/normlzr.h"
+#include "unicode/plurfmt.h"
#include "unicode/tblcoll.h"
#include "unicode/uchar.h"
#include "unicode/ucol.h"
@@ -21,6 +23,8 @@
#include "unicode/ustring.h"
#include "unicode/utf16.h"
#include "unicode/udata.h"
+#include "unicode/udisplaycontext.h"
+#include "unicode/brkiter.h"
#include "nfrs.h"
#include "cmemory.h"
@@ -29,9 +33,9 @@
#include "uresimp.h"
// debugging
-// #define DEBUG
+// #define RBNF_DEBUG
-#ifdef DEBUG
+#ifdef RBNF_DEBUG
#include "stdio.h"
#endif
@@ -324,10 +328,12 @@ private:
UChar* nextString(void);
};
-#ifdef DEBUG
+#ifdef RBNF_DEBUG
#define ERROR(msg) parseError(msg); return NULL;
+#define EXPLANATION_ARG explanationArg
#else
#define ERROR(msg) parseError(NULL); return NULL;
+#define EXPLANATION_ARG
#endif
@@ -525,8 +531,8 @@ LocDataParser::nextString() {
return result;
}
-void
-LocDataParser::parseError(const char* /*str*/) {
+void LocDataParser::parseError(const char* EXPLANATION_ARG)
+{
if (!data) {
return;
}
@@ -551,14 +557,14 @@ LocDataParser::parseError(const char* /*str*/) {
pe.postContext[limit-p] = 0;
pe.offset = (int32_t)(p - data);
-#ifdef DEBUG
- fprintf(stderr, "%s at or near character %d: ", str, p-data);
+#ifdef RBNF_DEBUG
+ fprintf(stderr, "%s at or near character %ld: ", EXPLANATION_ARG, p-data);
UnicodeString msg;
msg.append(start, p - start);
msg.append((UChar)0x002f); /* SOLIDUS/SLASH */
msg.append(p, limit-p);
- msg.append("'");
+ msg.append(UNICODE_STRING_SIMPLE("'"));
char buf[128];
int32_t len = msg.extract(0, msg.length(), buf, 128);
@@ -658,6 +664,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status);
init(description, locinfo, perror, status);
@@ -676,6 +686,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status);
init(description, locinfo, perror, status);
@@ -694,6 +708,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
init(description, info, perror, status);
}
@@ -711,6 +729,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
init(description, NULL, perror, status);
}
@@ -729,6 +751,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
init(description, NULL, perror, status);
}
@@ -744,6 +770,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale&
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
if (U_FAILURE(status)) {
return;
@@ -804,6 +834,10 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
+ , capitalizationInfoSet(FALSE)
+ , capitalizationForUIListMenu(FALSE)
+ , capitalizationForStandAlone(FALSE)
+ , capitalizationBrkIter(NULL)
{
this->operator=(rhs);
}
@@ -813,14 +847,26 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs)
RuleBasedNumberFormat&
RuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs)
{
+ if (this == &rhs) {
+ return *this;
+ }
+ NumberFormat::operator=(rhs);
UErrorCode status = U_ZERO_ERROR;
dispose();
locale = rhs.locale;
lenient = rhs.lenient;
- UnicodeString rules = rhs.getRules();
UParseError perror;
- init(rules, rhs.localizations ? rhs.localizations->ref() : NULL, perror, status);
+ init(rhs.originalDescription, rhs.localizations ? rhs.localizations->ref() : NULL, perror, status);
+ setDecimalFormatSymbols(*rhs.getDecimalFormatSymbols());
+ setDefaultRuleSet(rhs.getDefaultRuleSetName(), status);
+
+ capitalizationInfoSet = rhs.capitalizationInfoSet;
+ capitalizationForUIListMenu = rhs.capitalizationForUIListMenu;
+ capitalizationForStandAlone = rhs.capitalizationForStandAlone;
+#if !UCONFIG_NO_BREAK_ITERATION
+ capitalizationBrkIter = (rhs.capitalizationBrkIter!=NULL)? rhs.capitalizationBrkIter->clone(): NULL;
+#endif
return *this;
}
@@ -833,23 +879,7 @@ RuleBasedNumberFormat::~RuleBasedNumberFormat()
Format*
RuleBasedNumberFormat::clone(void) const
{
- RuleBasedNumberFormat * result = NULL;
- UnicodeString rules = getRules();
- UErrorCode status = U_ZERO_ERROR;
- UParseError perror;
- result = new RuleBasedNumberFormat(rules, localizations, locale, perror, status);
- /* test for NULL */
- if (result == 0) {
- status = U_MEMORY_ALLOCATION_ERROR;
- return 0;
- }
- if (U_FAILURE(status)) {
- delete result;
- result = 0;
- } else {
- result->lenient = lenient;
- }
- return result;
+ return new RuleBasedNumberFormat(*this);
}
UBool
@@ -861,6 +891,9 @@ RuleBasedNumberFormat::operator==(const Format& other) const
if (typeid(*this) == typeid(other)) {
const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other;
+ // test for capitalization info equality is adequately handled
+ // by the NumberFormat test for fCapitalizationContext equality;
+ // the info here is just derived from that.
if (locale == rhs.locale &&
lenient == rhs.lenient &&
(localizations == NULL
@@ -1032,7 +1065,12 @@ RuleBasedNumberFormat::format(int32_t number,
UnicodeString& toAppendTo,
FieldPosition& /* pos */) const
{
- if (defaultRuleSet) defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length());
+ if (defaultRuleSet) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t startPos = toAppendTo.length();
+ defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length(), status);
+ adjustForCapitalizationContext(startPos, toAppendTo);
+ }
return toAppendTo;
}
@@ -1042,7 +1080,12 @@ RuleBasedNumberFormat::format(int64_t number,
UnicodeString& toAppendTo,
FieldPosition& /* pos */) const
{
- if (defaultRuleSet) defaultRuleSet->format(number, toAppendTo, toAppendTo.length());
+ if (defaultRuleSet) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t startPos = toAppendTo.length();
+ defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
+ adjustForCapitalizationContext(startPos, toAppendTo);
+ }
return toAppendTo;
}
@@ -1052,6 +1095,7 @@ RuleBasedNumberFormat::format(double number,
UnicodeString& toAppendTo,
FieldPosition& /* pos */) const
{
+ int32_t startPos = toAppendTo.length();
// Special case for NaN; adapted from what DecimalFormat::_format( double number,...) does.
if (uprv_isNaN(number)) {
DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBasedNumberFormat internal
@@ -1059,9 +1103,10 @@ RuleBasedNumberFormat::format(double number,
toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNSymbol);
}
} else if (defaultRuleSet) {
- defaultRuleSet->format(number, toAppendTo, toAppendTo.length());
+ UErrorCode status = U_ZERO_ERROR;
+ defaultRuleSet->format(number, toAppendTo, toAppendTo.length(), status);
}
- return toAppendTo;
+ return adjustForCapitalizationContext(startPos, toAppendTo);
}
@@ -1080,7 +1125,9 @@ RuleBasedNumberFormat::format(int32_t number,
} else {
NFRuleSet *rs = findRuleSet(ruleSetName, status);
if (rs) {
- rs->format((int64_t)number, toAppendTo, toAppendTo.length());
+ int32_t startPos = toAppendTo.length();
+ rs->format((int64_t)number, toAppendTo, toAppendTo.length(), status);
+ adjustForCapitalizationContext(startPos, toAppendTo);
}
}
}
@@ -1102,7 +1149,9 @@ RuleBasedNumberFormat::format(int64_t number,
} else {
NFRuleSet *rs = findRuleSet(ruleSetName, status);
if (rs) {
- rs->format(number, toAppendTo, toAppendTo.length());
+ int32_t startPos = toAppendTo.length();
+ rs->format(number, toAppendTo, toAppendTo.length(), status);
+ adjustForCapitalizationContext(startPos, toAppendTo);
}
}
}
@@ -1124,13 +1173,39 @@ RuleBasedNumberFormat::format(double number,
} else {
NFRuleSet *rs = findRuleSet(ruleSetName, status);
if (rs) {
- rs->format(number, toAppendTo, toAppendTo.length());
+ int32_t startPos = toAppendTo.length();
+ rs->format(number, toAppendTo, toAppendTo.length(), status);
+ adjustForCapitalizationContext(startPos, toAppendTo);
}
}
}
return toAppendTo;
}
+UnicodeString&
+RuleBasedNumberFormat::adjustForCapitalizationContext(int32_t startPos,
+ UnicodeString& currentResult) const
+{
+#if !UCONFIG_NO_BREAK_ITERATION
+ if (startPos==0 && currentResult.length() > 0) {
+ // capitalize currentResult according to context
+ UChar32 ch = currentResult.char32At(0);
+ UErrorCode status = U_ZERO_ERROR;
+ UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status);
+ if ( u_islower(ch) && U_SUCCESS(status) && capitalizationBrkIter!= NULL &&
+ ( capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
+ (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitalizationForUIListMenu) ||
+ (capitalizationContext==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && capitalizationForStandAlone)) ) {
+ // titlecase first word of currentResult, here use sentence iterator unlike current implementations
+ // in LocaleDisplayNamesImpl::adjustForUsageAndContext and RelativeDateFormat::format
+ currentResult.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ }
+ }
+#endif
+ return currentResult;
+}
+
+
void
RuleBasedNumberFormat::parse(const UnicodeString& text,
Formattable& result,
@@ -1429,6 +1504,55 @@ RuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* locali
} else {
defaultRuleSet = getDefaultRuleSet();
}
+ originalDescription = rules;
+}
+
+// override the NumberFormat implementation in order to
+// lazily initialize relevant items
+void
+RuleBasedNumberFormat::setContext(UDisplayContext value, UErrorCode& status)
+{
+ NumberFormat::setContext(value, status);
+ if (U_SUCCESS(status)) {
+ if (!capitalizationInfoSet &&
+ (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE)) {
+ initCapitalizationContextInfo(locale);
+ capitalizationInfoSet = TRUE;
+ }
+#if !UCONFIG_NO_BREAK_ITERATION
+ if ( capitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
+ (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitalizationForUIListMenu) ||
+ (value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && capitalizationForStandAlone)) ) {
+ UErrorCode status = U_ZERO_ERROR;
+ capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status);
+ if (U_FAILURE(status)) {
+ delete capitalizationBrkIter;
+ capitalizationBrkIter = NULL;
+ }
+ }
+#endif
+ }
+}
+
+void
+RuleBasedNumberFormat::initCapitalizationContextInfo(const Locale& thelocale)
+{
+#if !UCONFIG_NO_BREAK_ITERATION
+ const char * localeID = (thelocale != NULL)? thelocale.getBaseName(): NULL;
+ UErrorCode status = U_ZERO_ERROR;
+ UResourceBundle *rb = ures_open(NULL, localeID, &status);
+ rb = ures_getByKeyWithFallback(rb, "contextTransforms", rb, &status);
+ rb = ures_getByKeyWithFallback(rb, "number-spellout", rb, &status);
+ if (U_SUCCESS(status) && rb != NULL) {
+ int32_t len = 0;
+ const int32_t * intVector = ures_getIntVector(rb, &len, &status);
+ if (U_SUCCESS(status) && intVector != NULL && len >= 2) {
+ capitalizationForUIListMenu = intVector[0];
+ capitalizationForStandAlone = intVector[1];
+ }
+ }
+ ures_close(rb);
+#endif
}
void
@@ -1498,6 +1622,11 @@ RuleBasedNumberFormat::dispose()
delete lenientParseRules;
lenientParseRules = NULL;
+#if !UCONFIG_NO_BREAK_ITERATION
+ delete capitalizationBrkIter;
+ capitalizationBrkIter = NULL;
+#endif
+
if (localizations) localizations = localizations->unref();
}
@@ -1512,7 +1641,7 @@ RuleBasedNumberFormat::dispose()
* @return The collator to use for lenient parsing, or null if lenient parsing
* is turned off.
*/
-Collator*
+const RuleBasedCollator*
RuleBasedNumberFormat::getCollator() const
{
#if !UCONFIG_NO_COLLATION
@@ -1520,7 +1649,7 @@ RuleBasedNumberFormat::getCollator() const
return NULL;
}
- // lazy-evaulate the collator
+ // lazy-evaluate the collator
if (collator == NULL && lenient) {
// create a default collator based on the formatter's locale,
// then pull out that collator's rules, append any additional
@@ -1539,7 +1668,7 @@ RuleBasedNumberFormat::getCollator() const
newCollator = new RuleBasedCollator(rules, status);
// Exit if newCollator could not be created.
if (newCollator == NULL) {
- return NULL;
+ return NULL;
}
} else {
temp = NULL;
@@ -1618,6 +1747,14 @@ RuleBasedNumberFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbo
adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols));
}
+PluralFormat *
+RuleBasedNumberFormat::createPluralFormat(UPluralType pluralType,
+ const UnicodeString &pattern,
+ UErrorCode& status) const
+{
+ return new PluralFormat(locale, pluralType, pattern, status);
+}
+
U_NAMESPACE_END
/* U_HAVE_RBNF */
« no previous file with comments | « source/i18n/quantityformatter.cpp ('k') | source/i18n/rbt_data.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698