ICU-7725 Hoist isLenient / setLenient to Format class (from DateFormat, RBNF)

X-SVN-Rev: 28170
This commit is contained in:
Peter Edberg 2010-06-10 20:17:43 +00:00
parent 72d8a8f889
commit 1826002e52
12 changed files with 143 additions and 28 deletions

View file

@ -65,6 +65,7 @@ FieldPosition::clone() const {
Format::Format()
: UObject()
, fLenient(TRUE)
{
*validLocale = *actualLocale = 0;
}
@ -93,6 +94,7 @@ Format::operator=(const Format& that)
if (this != &that) {
uprv_strcpy(validLocale, that.validLocale);
uprv_strcpy(actualLocale, that.actualLocale);
fLenient = that.fLenient;
}
return *this;
}
@ -206,6 +208,16 @@ Format::setLocaleIDs(const char* valid, const char* actual) {
locBased.setLocaleIDs(valid, actual);
}
void
Format::setLenient(UBool lenient) {
fLenient = lenient;
}
UBool
Format::isLenient() const {
return fLenient;
}
U_NAMESPACE_END
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -193,6 +193,7 @@ NumberFormat::NumberFormat()
fParseIntegerOnly(FALSE)
{
fCurrency[0] = 0;
Format::setLenient(FALSE);
}
// -------------------------------------

View file

@ -655,7 +655,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, locale(alocale)
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
, noParse(FALSE) //TODO: to be removed after #6895
@ -672,7 +671,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, locale(Locale::getDefault())
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
, noParse(FALSE) //TODO: to be removed after #6895
@ -689,7 +687,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, locale(alocale)
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
, noParse(FALSE) //TODO: to be removed after #6895
@ -705,7 +702,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, locale(Locale::getDefault())
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
, noParse(FALSE) //TODO: to be removed after #6895
@ -722,7 +718,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description,
, locale(aLocale)
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
, noParse(FALSE) //TODO: to be removed after #6895
@ -736,7 +731,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale&
, locale(alocale)
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
{
@ -810,7 +804,6 @@ RuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs)
, locale(rhs.locale)
, collator(NULL)
, decimalFormatSymbols(NULL)
, lenient(FALSE)
, lenientParseRules(NULL)
, localizations(NULL)
{
@ -825,7 +818,7 @@ RuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs)
UErrorCode status = U_ZERO_ERROR;
dispose();
locale = rhs.locale;
lenient = rhs.lenient;
Format::setLenient( rhs.isLenient() );
UnicodeString rules = rhs.getRules();
UParseError perror;
@ -859,7 +852,7 @@ RuleBasedNumberFormat::clone(void) const
delete result;
result = 0;
} else {
result->lenient = lenient;
result->Format::setLenient( isLenient() );
//TODO: remove below when we fix the parse bug - See #6895 / #6896
result->noParse = noParse;
@ -877,7 +870,7 @@ RuleBasedNumberFormat::operator==(const Format& other) const
if (typeid(*this) == typeid(other)) {
const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other;
if (locale == rhs.locale &&
lenient == rhs.lenient &&
isLenient() == rhs.isLenient() &&
(localizations == NULL
? rhs.localizations == NULL
: (rhs.localizations == NULL
@ -1211,13 +1204,19 @@ RuleBasedNumberFormat::parse(const UnicodeString& text,
void
RuleBasedNumberFormat::setLenient(UBool enabled)
{
lenient = enabled;
Format::setLenient(enabled);
if (!enabled && collator) {
delete collator;
collator = NULL;
}
}
UBool
RuleBasedNumberFormat::isLenient(void) const {
return Format::isLenient();
}
#endif
void
@ -1543,7 +1542,7 @@ RuleBasedNumberFormat::getCollator() const
}
// lazy-evaulate the collator
if (collator == NULL && lenient) {
if (collator == NULL && isLenient()) {
// create a default collator based on the formatter's locale,
// then pull out that collator's rules, append any additional
// rules specified in the description, and create a _new_

View file

@ -86,6 +86,11 @@ U_NAMESPACE_BEGIN
* If there is no match when parsing, a parse failure UErrorCode is
* retured for methods which take no ParsePosition. For the method
* that takes a ParsePosition, the index parameter is left unchanged.
* The Format class can support either strict or lenient parsing where
* appropriate (see isLenient, setLenient). By default parsing is
* lenient in the Format base class; subclasses may have a different
* default (for example, in NumberFormat, parsing is strict by default
* for backwards compatibility).
* <P>
* <em>User subclasses are not supported.</em> While clients may write
* subclasses, such code will not necessarily work and will not be
@ -256,6 +261,28 @@ public:
*/
const char* getLocaleID(ULocDataLocaleType type, UErrorCode &status) const;
/**
* Controls lenient parse behavior. At the Format class level, lenient parse
* is on by default. Format subclasses may have different default behavior
* for lenient parse.
*
* @see #isLenient
* @param lenient Sets lenient parse mode on (if TRUE) or off (if FALSE).
* @draft ICU 4.6
*/
virtual void setLenient(UBool lenient);
/**
* Returns the status of lenient parse mode. At the Format class level,
* lenient parse is on by default. Format subclasses may have different
* default behavior for lenient parse.
*
* @see #setLenient
* @return Lenient parse mode status: TRUE if on, FALSE if off.
* @stable ICU 2.0
*/
virtual UBool isLenient(void) const;
protected:
/** @stable ICU 2.8 */
void setLocaleIDs(const char* valid, const char* actual);
@ -293,6 +320,7 @@ protected:
private:
char actualLocale[ULOC_FULLNAME_CAPACITY];
char validLocale[ULOC_FULLNAME_CAPACITY];
UBool fLenient;
};
U_NAMESPACE_END

View file

@ -102,6 +102,9 @@ class StringEnumeration;
* nf->parse(myString, result, success);
* \endcode
* </pre>
* Note that while lenient parsing is on by default for the Format base class,
* it is off by default for NumberFormat and its subclasses.
* <P>
* Use createInstance to get the normal number format for that country.
* There are other static factory methods available. Use getCurrency
* to get the currency number format for that country. Use getPercent

View file

@ -927,7 +927,7 @@ public:
* @see #setLenient
* @stable ICU 2.0
*/
virtual inline UBool isLenient(void) const;
virtual UBool isLenient(void) const;
#endif
@ -994,7 +994,6 @@ private:
Locale locale;
Collator* collator;
DecimalFormatSymbols* decimalFormatSymbols;
UBool lenient;
UnicodeString* lenientParseRules;
LocalizationInfo* localizations;
@ -1036,15 +1035,6 @@ RuleBasedNumberFormat::parse(const UnicodeString& text, Formattable& result, UEr
NumberFormat::parse(text, result, status);
}
#if !UCONFIG_NO_COLLATION
inline UBool
RuleBasedNumberFormat::isLenient(void) const {
return lenient;
}
#endif
inline NFRuleSet*
RuleBasedNumberFormat::getDefaultRuleSet() const {
return defaultRuleSet;

View file

@ -189,6 +189,23 @@ void IntlTestDecimalFormatAPI::testAPI(/*char *par*/)
logln((UnicodeString)"Testing getters and setters");
// check default value of lenient
if ( def.isLenient() ) {
errln("ERROR: isLenient() not FALSE by default for DecimalFormat");
}
DecimalFormat *defMod = new DecimalFormat(def);
// check setting & comparison of lenient
if (defMod != NULL) {
if ( !(*defMod == def) ) {
errln("ERROR: operator == is FALSE, should be TRUE afer copy");
}
defMod->setLenient(!def.isLenient());
if( defMod->isLenient() == def.isLenient()) {
errln("ERROR: isLenient() after setLenient(!isLenient()) failed");
} // don't check that == fails, not relevant for subclass that does not check lenient
delete defMod;
}
const DecimalFormatSymbols *syms = pat.getDecimalFormatSymbols();
DecimalFormatSymbols *newSyms = new DecimalFormatSymbols(*syms);
def.setDecimalFormatSymbols(*newSyms);

View file

@ -218,7 +218,16 @@ if (fr != NULL && it != NULL && de != NULL)
name = locales[i].getName();
logln(name);
}
// check default value of lenient, and setting/testing
if ( !fr->isLenient() ) {
errln("ERROR: isLenient() not TRUE by default for DateFormat");
} else {
fr->setLenient(FALSE);
if ( fr->isLenient() ) {
errln("ERROR: isLenient() after setLenient(FALSE) failed");
}
}
fr->setLenient(it->isLenient());
if(fr->isLenient() != it->isLenient()) {
errln("ERROR: setLenient() failed");

View file

@ -114,9 +114,14 @@ void DateIntervalFormatTest::testAPI() {
return;
}
// not deleted, test clone
// check default value of lenient
if ( !dtitvfmt->isLenient() ) {
errln("ERROR: isLenient() not TRUE by default for DateIntervalFormat");
}
// ====== Test clone()
// ====== Test clone() and setLenient() (latter from Format superclass)
status = U_ZERO_ERROR;
logln("Testing DateIntervalFormat clone");
@ -125,6 +130,10 @@ void DateIntervalFormatTest::testAPI() {
dataerrln("ERROR: clone failed");
}
another->setLenient(!dtitvfmt->isLenient());
if( another->isLenient() == dtitvfmt->isLenient()) {
errln("ERROR: isLenient() after setLenient(!isLenient()) failed");
} // don't check that == fails, not relevant for subclass that does not check lenient
// ====== Test getDateIntervalInfo, setDateIntervalInfo, adoptDateIntervalInfo
status = U_ZERO_ERROR;

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* Copyright (C) 1996-2010, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -152,6 +152,12 @@ IntlTestRBNF::TestAPI() {
}
logln("RBNF API test starting");
// check default value of lenient
if ( formatter->isLenient() ) {
errln("ERROR: isLenient() not FALSE by default for RuleBasedNumberFormat");
}
// test clone
{
logln("Testing Clone");
@ -160,6 +166,14 @@ IntlTestRBNF::TestAPI() {
if(!(*rbnfClone == *formatter)) {
errln("Clone should be semantically equivalent to the original!");
}
rbnfClone->setLenient(!formatter->isLenient());
if( rbnfClone->isLenient() == formatter->isLenient()) {
errln("ERROR: isLenient() after setLenient(!isLenient()) failed");
#if !UCONFIG_NO_COLLATION
} else if (*rbnfClone == *formatter) {
errln("ERROR: operator == is TRUE, should be FALSE if isLenient() differs");
#endif
}
delete rbnfClone;
} else {
errln("Cloning failed!");

View file

@ -1,6 +1,6 @@
/***********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2009, International Business Machines Corporation
* Copyright (c) 1997-2010, International Business Machines Corporation
* and others. All Rights Reserved.
***********************************************************************/
@ -194,6 +194,20 @@ if (fr != NULL && def != NULL)
logln(name);
}
// check default value of lenient, and setting/testing
if ( def->isLenient() ) {
errln("ERROR: isLenient() not FALSE by default for NumberFormat");
} else {
def->setLenient(TRUE);
if ( !def->isLenient() ) {
errln("ERROR: isLenient() after setLenient(TRUE) failed");
}
}
def->setLenient(fr->isLenient());
if(def->isLenient() != fr->isLenient()) {
errln("ERROR: setLenient() failed");
}
fr->setParseIntegerOnly( def->isParseIntegerOnly() );
if(fr->isParseIntegerOnly() != def->isParseIntegerOnly() ) {
errln("ERROR: setParseIntegerOnly() failed");

View file

@ -1,7 +1,7 @@
/********************************************************************
* COPYRIGHT:
* Copyright (c) 1997-2009, International Business Machines Corporation and
* Copyright (c) 1997-2010, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************/
@ -173,6 +173,25 @@ void IntlTestSimpleDateFormatAPI::testAPI(/*char *par*/)
logln("Testing getters and setters");
// check default value of lenient
if ( !def.isLenient() ) {
errln("ERROR: isLenient() not TRUE by default for SimpleDateFormat");
}
SimpleDateFormat *defMod = new SimpleDateFormat(def);
// check setting & comparison of lenient
if (defMod != NULL) {
if ( !(*defMod == def) ) {
errln("ERROR: operator == is FALSE, should be TRUE after copy");
}
defMod->setLenient(!def.isLenient());
if( defMod->isLenient() == def.isLenient()) {
errln("ERROR: isLenient() after setLenient(!isLenient()) failed");
} else if ( *defMod == def ) {
errln("ERROR: operator == is TRUE, should be FALSE if isLenient() differs");
}
delete defMod;
}
const DateFormatSymbols *syms = pat.getDateFormatSymbols();
if(!syms) {
errln("Couldn't obtain DateFormatSymbols. Quitting test!");