ICU-9613 Merge from branch to trunk

X-SVN-Rev: 32622
This commit is contained in:
Michael Ow 2012-10-12 19:52:43 +00:00
parent adc6f41d0e
commit 799a603abc
10 changed files with 821 additions and 315 deletions

View File

@ -73,6 +73,7 @@
U_NAMESPACE_BEGIN
/* == Fastpath calculation. ==
*/
#if UCONFIG_FORMAT_FASTPATHS_49
@ -350,6 +351,7 @@ DecimalFormat::init(UErrorCode &status) {
fUseExponentialNotation = FALSE;
fMinExponentDigits = 0;
fExponentSignAlwaysShown = FALSE;
fBoolFlags.clear();
fRoundingIncrement = 0;
fRoundingMode = kRoundHalfEven;
fPad = 0;
@ -737,6 +739,7 @@ DecimalFormat::operator=(const DecimalFormat& rhs)
_copy_ptr(&fSymbols, rhs.fSymbols);
fUseExponentialNotation = rhs.fUseExponentialNotation;
fExponentSignAlwaysShown = rhs.fExponentSignAlwaysShown;
fBoolFlags = rhs.fBoolFlags;
/*Bertrand A. D. Update 98.03.17*/
fCurrencySignCount = rhs.fCurrencySignCount;
/*end of Update*/
@ -990,6 +993,15 @@ DecimalFormat::format(int32_t number,
return format((int64_t)number, appendTo, fieldPosition);
}
UnicodeString&
DecimalFormat::format(int32_t number,
UnicodeString& appendTo,
FieldPosition& fieldPosition,
UErrorCode& status) const
{
return format((int64_t)number, appendTo, fieldPosition, status);
}
UnicodeString&
DecimalFormat::format(int32_t number,
UnicodeString& appendTo,
@ -1048,7 +1060,17 @@ DecimalFormat::format(int64_t number,
UnicodeString& appendTo,
FieldPosition& fieldPosition) const
{
UErrorCode status = U_ZERO_ERROR;
UErrorCode status = U_ZERO_ERROR; /* ignored */
FieldPositionOnlyHandler handler(fieldPosition);
return _format(number, appendTo, handler, status);
}
UnicodeString&
DecimalFormat::format(int64_t number,
UnicodeString& appendTo,
FieldPosition& fieldPosition,
UErrorCode& status) const
{
FieldPositionOnlyHandler handler(fieldPosition);
return _format(number, appendTo, handler, status);
}
@ -1115,6 +1137,10 @@ DecimalFormat::_format(int64_t number,
int32_t maxIntDig = getMaximumIntegerDigits();
int32_t destlength = length<=maxIntDig?length:maxIntDig; // dest length pinned to max int digits
if(length>maxIntDig && fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MAX_DIGITS)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
int32_t prependZero = getMinimumIntegerDigits() - destlength;
#ifdef FMT_DEBUG
@ -1158,7 +1184,17 @@ DecimalFormat::format( double number,
UnicodeString& appendTo,
FieldPosition& fieldPosition) const
{
UErrorCode status = U_ZERO_ERROR;
UErrorCode status = U_ZERO_ERROR; /* ignored */
FieldPositionOnlyHandler handler(fieldPosition);
return _format(number, appendTo, handler, status);
}
UnicodeString&
DecimalFormat::format( double number,
UnicodeString& appendTo,
FieldPosition& fieldPosition,
UErrorCode& status) const
{
FieldPositionOnlyHandler handler(fieldPosition);
return _format(number, appendTo, handler, status);
}
@ -1370,7 +1406,7 @@ DecimalFormat::_format(const DigitList &number,
return appendTo;
}
return subformat(appendTo, handler, adjustedNum, FALSE);
return subformat(appendTo, handler, adjustedNum, FALSE, status);
}
@ -1415,7 +1451,8 @@ UnicodeString&
DecimalFormat::subformat(UnicodeString& appendTo,
FieldPositionHandler& handler,
DigitList& digits,
UBool isInteger) const
UBool isInteger,
UErrorCode& status) const
{
// char zero = '0';
// DigitList returns digits as '0' thru '9', so we will need to
@ -1624,6 +1661,9 @@ DecimalFormat::subformat(UnicodeString& appendTo,
if (count > maxIntDig && maxIntDig >= 0) {
count = maxIntDig;
digitIndex = digits.getDecimalAt() - count;
if(fBoolFlags.contains(UNUM_FORMAT_FAIL_IF_MAX_DIGITS)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
}
}
int32_t sizeBeforeIntegerPart = appendTo.length();
@ -2435,61 +2475,67 @@ UBool DecimalFormat::subparse(const UnicodeString& text,
// decimalSet is considered to consist of (ch,ch)
}
else {
const UnicodeString *tmp;
tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
{
// Parse sign, if present
int32_t pos = position + tmp->length();
char exponentSign = '+';
if (pos < textLength)
if(!fBoolFlags.contains(UNUM_PARSE_NO_EXPONENT) || // don't parse if this is set unless..
fUseExponentialNotation /* should be: isScientificNotation() but it is not const (?!) see bug #9619 */) { // .. it's an exponent format - ignore setting and parse anyways
const UnicodeString *tmp;
tmp = &getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
// TODO: CASE
if (!text.caseCompare(position, tmp->length(), *tmp, U_FOLD_CASE_DEFAULT)) // error code is set below if !sawDigit
{
tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
if (!text.compare(pos, tmp->length(), *tmp))
// Parse sign, if present
int32_t pos = position + tmp->length();
char exponentSign = '+';
if (pos < textLength)
{
pos += tmp->length();
}
else {
tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
tmp = &getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
if (!text.compare(pos, tmp->length(), *tmp))
{
exponentSign = '-';
pos += tmp->length();
}
}
}
UBool sawExponentDigit = FALSE;
while (pos < textLength) {
ch = text[(int32_t)pos];
digit = ch - zero;
if (digit < 0 || digit > 9) {
digit = u_charDigitValue(ch);
}
if (0 <= digit && digit <= 9) {
if (!sawExponentDigit) {
parsedNum.append('E', err);
parsedNum.append(exponentSign, err);
sawExponentDigit = TRUE;
else {
tmp = &getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
if (!text.compare(pos, tmp->length(), *tmp))
{
exponentSign = '-';
pos += tmp->length();
}
}
++pos;
parsedNum.append((char)(digit + '0'), err);
} else {
break;
}
}
if (sawExponentDigit) {
position = pos; // Advance past the exponent
}
UBool sawExponentDigit = FALSE;
while (pos < textLength) {
ch = text[(int32_t)pos];
digit = ch - zero;
break; // Whether we fail or succeed, we exit this loop
}
else {
if (digit < 0 || digit > 9) {
digit = u_charDigitValue(ch);
}
if (0 <= digit && digit <= 9) {
if (!sawExponentDigit) {
parsedNum.append('E', err);
parsedNum.append(exponentSign, err);
sawExponentDigit = TRUE;
}
++pos;
parsedNum.append((char)(digit + '0'), err);
} else {
break;
}
}
if (sawExponentDigit) {
position = pos; // Advance past the exponent
}
break; // Whether we fail or succeed, we exit this loop
} else {
break;
}
} else { // not parsing exponent
break;
}
}
}
}
@ -5304,6 +5350,190 @@ DecimalFormat::copyHashForAffixPattern(const Hashtable* source,
}
}
DecimalFormat& DecimalFormat::setAttribute( UNumberFormatAttribute attr,
int32_t newValue,
UErrorCode &status) {
if(U_FAILURE(status)) return *this;
switch(attr) {
case UNUM_LENIENT_PARSE:
setLenient(newValue!=0);
break;
case UNUM_PARSE_INT_ONLY:
setParseIntegerOnly(newValue!=0);
break;
case UNUM_GROUPING_USED:
setGroupingUsed(newValue!=0);
break;
case UNUM_DECIMAL_ALWAYS_SHOWN:
setDecimalSeparatorAlwaysShown(newValue!=0);
break;
case UNUM_MAX_INTEGER_DIGITS:
setMaximumIntegerDigits(newValue);
break;
case UNUM_MIN_INTEGER_DIGITS:
setMinimumIntegerDigits(newValue);
break;
case UNUM_INTEGER_DIGITS:
setMinimumIntegerDigits(newValue);
setMaximumIntegerDigits(newValue);
break;
case UNUM_MAX_FRACTION_DIGITS:
setMaximumFractionDigits(newValue);
break;
case UNUM_MIN_FRACTION_DIGITS:
setMinimumFractionDigits(newValue);
break;
case UNUM_FRACTION_DIGITS:
setMinimumFractionDigits(newValue);
setMaximumFractionDigits(newValue);
break;
case UNUM_SIGNIFICANT_DIGITS_USED:
setSignificantDigitsUsed(newValue!=0);
break;
case UNUM_MAX_SIGNIFICANT_DIGITS:
setMaximumSignificantDigits(newValue);
break;
case UNUM_MIN_SIGNIFICANT_DIGITS:
setMinimumSignificantDigits(newValue);
break;
case UNUM_MULTIPLIER:
setMultiplier(newValue);
break;
case UNUM_GROUPING_SIZE:
setGroupingSize(newValue);
break;
case UNUM_ROUNDING_MODE:
setRoundingMode((DecimalFormat::ERoundingMode)newValue);
break;
case UNUM_FORMAT_WIDTH:
setFormatWidth(newValue);
break;
case UNUM_PADDING_POSITION:
/** The position at which padding will take place. */
setPadPosition((DecimalFormat::EPadPosition)newValue);
break;
case UNUM_SECONDARY_GROUPING_SIZE:
setSecondaryGroupingSize(newValue);
break;
#if UCONFIG_HAVE_PARSEALLINPUT
case UNUM_PARSE_ALL_INPUT:
setParseAllInput((UNumberFormatAttributeValue)newValue);
break;
#endif
/* These are stored in fBoolFlags */
case UNUM_PARSE_NO_EXPONENT:
case UNUM_FORMAT_FAIL_IF_MAX_DIGITS:
if(!fBoolFlags.isValidValue(newValue)) {
status = U_ILLEGAL_ARGUMENT_ERROR;
} else {
fBoolFlags.set(attr, newValue);
}
break;
default:
status = U_UNSUPPORTED_ERROR;
break;
}
return *this;
}
int32_t DecimalFormat::getAttribute( UNumberFormatAttribute attr,
UErrorCode &status ) const {
if(U_FAILURE(status)) return -1;
switch(attr) {
case UNUM_LENIENT_PARSE:
return isLenient();
case UNUM_PARSE_INT_ONLY:
return isParseIntegerOnly();
case UNUM_GROUPING_USED:
return isGroupingUsed();
case UNUM_DECIMAL_ALWAYS_SHOWN:
return isDecimalSeparatorAlwaysShown();
case UNUM_MAX_INTEGER_DIGITS:
return getMaximumIntegerDigits();
case UNUM_MIN_INTEGER_DIGITS:
return getMinimumIntegerDigits();
case UNUM_INTEGER_DIGITS:
// TBD: what should this return?
return getMinimumIntegerDigits();
case UNUM_MAX_FRACTION_DIGITS:
return getMaximumFractionDigits();
case UNUM_MIN_FRACTION_DIGITS:
return getMinimumFractionDigits();
case UNUM_FRACTION_DIGITS:
// TBD: what should this return?
return getMinimumFractionDigits();
case UNUM_SIGNIFICANT_DIGITS_USED:
return areSignificantDigitsUsed();
case UNUM_MAX_SIGNIFICANT_DIGITS:
return getMaximumSignificantDigits();
case UNUM_MIN_SIGNIFICANT_DIGITS:
return getMinimumSignificantDigits();
case UNUM_MULTIPLIER:
return getMultiplier();
case UNUM_GROUPING_SIZE:
return getGroupingSize();
case UNUM_ROUNDING_MODE:
return getRoundingMode();
case UNUM_FORMAT_WIDTH:
return getFormatWidth();
case UNUM_PADDING_POSITION:
return getPadPosition();
case UNUM_SECONDARY_GROUPING_SIZE:
return getSecondaryGroupingSize();
/* These are stored in fBoolFlags */
case UNUM_PARSE_NO_EXPONENT:
case UNUM_FORMAT_FAIL_IF_MAX_DIGITS:
return fBoolFlags.get(attr);
default:
status = U_UNSUPPORTED_ERROR;
break;
}
return -1; /* undefined */
}
#if UCONFIG_HAVE_PARSEALLINPUT
void DecimalFormat::setParseAllInput(UNumberFormatAttributeValue value) {
fParseAllInput = value;

View File

@ -362,6 +362,46 @@ NumberFormat::format(int64_t /* unused number */,
return toAppendTo;
}
// ------------------------------------------
// These functions add the status code, just fall back to the non-status versions
UnicodeString&
NumberFormat::format(double number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const {
if(U_SUCCESS(status)) {
return format(number,appendTo,pos);
} else {
return appendTo;
}
}
UnicodeString&
NumberFormat::format(int32_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const {
if(U_SUCCESS(status)) {
return format(number,appendTo,pos);
} else {
return appendTo;
}
}
UnicodeString&
NumberFormat::format(int64_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const {
if(U_SUCCESS(status)) {
return format(number,appendTo,pos);
} else {
return appendTo;
}
}
// -------------------------------------
// Decimal Number format() default implementation
// Subclasses do not normally override this function, but rather the DigitList

View File

@ -56,6 +56,41 @@ class Hashtable;
class UnicodeSet;
class FieldPositionHandler;
#include <stdio.h>
/**
* enum bitset for boolean fields. Similar to Java EnumSet<>.
* Needs to range check. Not specific to decimal format.
* @internal
*/
template<typename T, uint32_t minValue, uint32_t limitValue>
class EnumSet {
public:
EnumSet() : fBools(0) {}
EnumSet(const EnumSet<T,minValue,limitValue>& other) : fBools(other.fBools) {}
~EnumSet() {}
void clear() { fBools=0; }
void add(T toAdd) { set(toAdd, 1); }
void remove(T toRemove) { set(toRemove, 0); }
int32_t contains(T toCheck) const { return get(toCheck); }
void set(T toSet, int32_t v) { fBools=(fBools&(~flag(toSet)))|(v?(flag(toSet)):0); }
int32_t get(T toCheck) const { return (fBools & flag(toCheck))?1:0; }
UBool isValidEnum(T toCheck) const { return (toCheck>=minValue&&toCheck<limitValue); }
UBool isValidValue(int32_t v) const { return (v==0||v==1); }
const EnumSet<T,minValue,limitValue>& operator=(const EnumSet<T,minValue,limitValue>& other) {
fBools = other.fBools;
return *this;
}
uint32_t getAll() const {
return fBools;
}
private:
uint32_t flag(T toCheck) const { return (1<<(toCheck-minValue)); }
private:
uint32_t fBools;
};
/**
* DecimalFormat is a concrete subclass of NumberFormat that formats decimal
* numbers. It has a variety of features designed to make it possible to parse
@ -757,6 +792,32 @@ public:
UErrorCode& status);
/**
* Set an integer attribute on this DecimalFormat.
* May return U_UNSUPPORTED_ERROR if this instance does not support
* the specified attribute.
* @param attr the attribute to set
* @param newvalue new value
* @param status the error type
* @return *this - for chaining
* @internal ICU 50
*/
virtual DecimalFormat& setAttribute( UNumberFormatAttribute attr,
int32_t newvalue,
UErrorCode &status);
/**
* Get an integer
* May return U_UNSUPPORTED_ERROR if this instance does not support
* the specified attribute.
* @param attr the attribute to set
* @param status the error type
* @return the attribute value. Undefined if there is an error.
* @internal ICU 50
*/
virtual int32_t getAttribute( UNumberFormatAttribute attr,
UErrorCode &status) const;
#if UCONFIG_HAVE_PARSEALLINPUT
/**
* @internal
@ -869,6 +930,24 @@ public:
UnicodeString& appendTo,
FieldPosition& pos) const;
/**
* Format a double or long number using base-10 representation.
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param status
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(double number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const;
/**
* Format a double or long number using base-10 representation.
*
@ -902,6 +981,22 @@ public:
UnicodeString& appendTo,
FieldPosition& pos) const;
/**
* Format a long number using base-10 representation.
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(int32_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const;
/**
* Format a long number using base-10 representation.
*
@ -935,6 +1030,22 @@ public:
UnicodeString& appendTo,
FieldPosition& pos) const;
/**
* Format an int64 number using base-10 representation.
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(int64_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const;
/**
* Format an int64 number using base-10 representation.
*
@ -1954,7 +2065,8 @@ private:
UnicodeString& subformat(UnicodeString& appendTo,
FieldPositionHandler& handler,
DigitList& digits,
UBool isInteger) const;
UBool isInteger,
UErrorCode &status) const;
void parse(const UnicodeString& text,
@ -2162,6 +2274,11 @@ private:
int8_t fMinExponentDigits;
UBool fExponentSignAlwaysShown;
EnumSet<UNumberFormatAttribute,
UNUM_MAX_NONBOOLEAN_ATTRIBUTE+1,
UNUM_LIMIT_BOOLEAN_ATTRIBUTE>
fBoolFlags;
DigitList* fRoundingIncrement; // NULL if no rounding increment specified.
ERoundingMode fRoundingMode;
@ -2362,6 +2479,7 @@ inline const UnicodeString &
DecimalFormat::getConstSymbol(DecimalFormatSymbols::ENumberFormatSymbol symbol) const {
return fSymbols->getConstSymbol(symbol);
}
#endif
U_NAMESPACE_END

View File

@ -358,6 +358,24 @@ public:
virtual UnicodeString& format(double number,
UnicodeString& appendTo,
FieldPosition& pos) const = 0;
/**
* Format a double number. By default, the parent function simply
* calls the base class and does not return an error status.
* Therefore, the status may be ignored in some subclasses.
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param status error status
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(double number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const;
/**
* Format a double number. Subclasses must implement
* this method.
@ -392,6 +410,24 @@ public:
UnicodeString& appendTo,
FieldPosition& pos) const = 0;
/**
* Format a long number. Concrete subclasses may override
* this function to provide status return.
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @param status the output status.
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(int32_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode &status) const;
/**
* Format an int32 number. Subclasses must implement
* this method.
@ -426,6 +462,24 @@ public:
virtual UnicodeString& format(int64_t number,
UnicodeString& appendTo,
FieldPosition& pos) const;
/**
* Format an int64 number. (Not abstract to retain compatibility
* with earlier releases, however subclasses should override this
* method as it just delegates to format(int32_t number...);
*
* @param number The value to be formatted.
* @param appendTo Output parameter to receive result.
* Result is appended to existing contents.
* @param pos On input: an alignment field, if desired.
* On output: the offsets of the alignment field.
* @return Reference to 'appendTo' parameter.
* @internal
*/
virtual UnicodeString& format(int64_t number,
UnicodeString& appendTo,
FieldPosition& pos,
UErrorCode& status) const;
/**
* Format an int64 number. Subclasses must implement
* this method.

View File

@ -375,6 +375,8 @@ public:
*/
UnicodeString& formatOffsetLocalizedGMT(int32_t offset, UnicodeString& result, UErrorCode& status) const;
using Format::format;
/**
* Returns the display name of the time zone at the given date for the style.
* @param style The style (e.g. <code>UTZFMT_STYLE_GENERIC_LONG</code>, <code>UTZFMT_STYLE_LOCALIZED_GMT</code>...)

View File

@ -107,7 +107,7 @@
* formatters.
* <P>
* You can also control the display of numbers with such function as
* unum_getAttribues() and unum_setAtributes(), which let you set the
* unum_getAttributes() and unum_setAttributes(), which let you set the
* miminum fraction digits, grouping, etc.
* @see UNumberFormatAttributes for more details
* <P>
@ -775,15 +775,41 @@ typedef enum UNumberFormatAttribute {
/** Lenient parse mode used by rule-based formats.
* @stable ICU 3.0
*/
UNUM_LENIENT_PARSE
UNUM_LENIENT_PARSE,
#if UCONFIG_HAVE_PARSEALLINPUT
/** Consume all input. (may use fastpath). Set to UNUM_YES (require fastpath), UNUM_NO (skip fastpath), or UNUM_MAYBE (heuristic).
* This is an internal ICU API. Do not use.
* @internal
*/
,UNUM_PARSE_ALL_INPUT
UNUM_PARSE_ALL_INPUT,
#endif
/** Count of "regular" numeric attributes.
* @internal */
UNUM_NUMERIC_ATTRIBUTE_COUNT,
/** One below the first bitfield-boolean item.
* All items after this one are stored in boolean form.
* @internal */
UNUM_MAX_NONBOOLEAN_ATTRIBUTE = 0x0FFF,
/** If 1, specifies that if setting the "max integer digits" attribute would truncate a value, set an error status rather than silently truncating.
* For example, formatting the value 1234 with 4 max int digits would succeed, but formatting 12345 would fail. There is no effect on parsing.
* Default: 0 (not set)
* @draft ICU 50
*/
UNUM_FORMAT_FAIL_IF_MAX_DIGITS,
/**
* if this attribute is set to 1, specifies that, if the pattern doesnt contain an exponent, the exponent will not be parsed. If the pattern does contain an exponent, this attribute has no effect.
* Has no effect on formatting.
* Default: 0 (unset)
* @draft ICU 50
*/
UNUM_PARSE_NO_EXPONENT,
/** Limit of boolean attributes.
* @internal */
UNUM_LIMIT_BOOLEAN_ATTRIBUTE
} UNumberFormatAttribute;
/**

View File

@ -187,8 +187,8 @@ unum_formatInt64(const UNumberFormat* fmt,
if(pos != 0)
fp.setField(pos->field);
((const NumberFormat*)fmt)->format(number, res, fp);
((const NumberFormat*)fmt)->format(number, res, fp, *status);
if(pos != 0) {
pos->beginIndex = fp.getBeginIndex();
pos->endIndex = fp.getEndIndex();
@ -220,7 +220,7 @@ unum_formatDouble( const UNumberFormat* fmt,
if(pos != 0)
fp.setField(pos->field);
((const NumberFormat*)fmt)->format(number, res, fp);
((const NumberFormat*)fmt)->format(number, res, fp, *status);
if(pos != 0) {
pos->beginIndex = fp.getBeginIndex();
@ -468,70 +468,12 @@ unum_getAttribute(const UNumberFormat* fmt,
// Supported for all subclasses
return nf->isLenient();
}
// The remaining attributea are only supported for DecimalFormat
const DecimalFormat* df = dynamic_cast<const DecimalFormat*>(nf);
if (df != NULL) {
switch(attr) {
case UNUM_PARSE_INT_ONLY:
return df->isParseIntegerOnly();
case UNUM_GROUPING_USED:
return df->isGroupingUsed();
case UNUM_DECIMAL_ALWAYS_SHOWN:
return df->isDecimalSeparatorAlwaysShown();
case UNUM_MAX_INTEGER_DIGITS:
return df->getMaximumIntegerDigits();
case UNUM_MIN_INTEGER_DIGITS:
return df->getMinimumIntegerDigits();
case UNUM_INTEGER_DIGITS:
// TBD: what should this return?
return df->getMinimumIntegerDigits();
case UNUM_MAX_FRACTION_DIGITS:
return df->getMaximumFractionDigits();
case UNUM_MIN_FRACTION_DIGITS:
return df->getMinimumFractionDigits();
case UNUM_FRACTION_DIGITS:
// TBD: what should this return?
return df->getMinimumFractionDigits();
case UNUM_SIGNIFICANT_DIGITS_USED:
return df->areSignificantDigitsUsed();
case UNUM_MAX_SIGNIFICANT_DIGITS:
return df->getMaximumSignificantDigits();
case UNUM_MIN_SIGNIFICANT_DIGITS:
return df->getMinimumSignificantDigits();
case UNUM_MULTIPLIER:
return df->getMultiplier();
case UNUM_GROUPING_SIZE:
return df->getGroupingSize();
case UNUM_ROUNDING_MODE:
return df->getRoundingMode();
case UNUM_FORMAT_WIDTH:
return df->getFormatWidth();
case UNUM_PADDING_POSITION:
return df->getPadPosition();
case UNUM_SECONDARY_GROUPING_SIZE:
return df->getSecondaryGroupingSize();
default:
/* enums out of sync? unsupported enum? */
break;
}
UErrorCode ignoredStatus = U_ZERO_ERROR;
return df->getAttribute( attr, ignoredStatus );
}
return -1;
@ -545,97 +487,14 @@ unum_setAttribute( UNumberFormat* fmt,
NumberFormat* nf = reinterpret_cast<NumberFormat*>(fmt);
if ( attr == UNUM_LENIENT_PARSE ) {
// Supported for all subclasses
// keep this here as the class may not be a DecimalFormat
return nf->setLenient(newValue != 0);
}
// The remaining attributea are only supported for DecimalFormat
DecimalFormat* df = dynamic_cast<DecimalFormat*>(nf);
if (df != NULL) {
switch(attr) {
case UNUM_PARSE_INT_ONLY:
df->setParseIntegerOnly(newValue!=0);
break;
case UNUM_GROUPING_USED:
df->setGroupingUsed(newValue!=0);
break;
case UNUM_DECIMAL_ALWAYS_SHOWN:
df->setDecimalSeparatorAlwaysShown(newValue!=0);
break;
case UNUM_MAX_INTEGER_DIGITS:
df->setMaximumIntegerDigits(newValue);
break;
case UNUM_MIN_INTEGER_DIGITS:
df->setMinimumIntegerDigits(newValue);
break;
case UNUM_INTEGER_DIGITS:
df->setMinimumIntegerDigits(newValue);
df->setMaximumIntegerDigits(newValue);
break;
case UNUM_MAX_FRACTION_DIGITS:
df->setMaximumFractionDigits(newValue);
break;
case UNUM_MIN_FRACTION_DIGITS:
df->setMinimumFractionDigits(newValue);
break;
case UNUM_FRACTION_DIGITS:
df->setMinimumFractionDigits(newValue);
df->setMaximumFractionDigits(newValue);
break;
case UNUM_SIGNIFICANT_DIGITS_USED:
df->setSignificantDigitsUsed(newValue!=0);
break;
case UNUM_MAX_SIGNIFICANT_DIGITS:
df->setMaximumSignificantDigits(newValue);
break;
case UNUM_MIN_SIGNIFICANT_DIGITS:
df->setMinimumSignificantDigits(newValue);
break;
case UNUM_MULTIPLIER:
df->setMultiplier(newValue);
break;
case UNUM_GROUPING_SIZE:
df->setGroupingSize(newValue);
break;
case UNUM_ROUNDING_MODE:
df->setRoundingMode((DecimalFormat::ERoundingMode)newValue);
break;
case UNUM_FORMAT_WIDTH:
df->setFormatWidth(newValue);
break;
case UNUM_PADDING_POSITION:
/** The position at which padding will take place. */
df->setPadPosition((DecimalFormat::EPadPosition)newValue);
break;
case UNUM_SECONDARY_GROUPING_SIZE:
df->setSecondaryGroupingSize(newValue);
break;
#if UCONFIG_HAVE_PARSEALLINPUT
case UNUM_PARSE_ALL_INPUT:
df->setParseAllInput((UNumberFormatAttributeValue)newValue);
break;
#endif
default:
/* Shouldn't get here anyway */
break;
}
UErrorCode ignoredStatus = U_ZERO_ERROR;
df->setAttribute(attr, newValue, ignoredStatus);
}
}

View File

@ -32,16 +32,25 @@
#include "cnumtst.h"
#include "cmemory.h"
#include "putilimp.h"
#include <stdio.h>
#define LENGTH(arr) (sizeof(arr)/sizeof(arr[0]))
static const char *tagAssert(const char *f, int32_t l, const char *msg) {
static char _fileline[1000];
sprintf(_fileline, "%s:%d: ASSERT_TRUE(%s)", f, l, msg);
return _fileline;
}
#define ASSERT_TRUE(x) assertTrue(tagAssert(__FILE__, __LINE__, #x), (x))
void addNumForTest(TestNode** root);
static void TestTextAttributeCrash(void);
static void TestNBSPInPattern(void);
static void TestInt64Parse(void);
static void TestParseCurrency(void);
static void TestMaxInt(void);
static void TestNoExponent(void);
#define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x)
@ -63,6 +72,7 @@ void addNumForTest(TestNode** root)
TESTCASE(TestParseCurrency);
TESTCASE(TestCloneWithRBNF);
TESTCASE(TestMaxInt);
TESTCASE(TestNoExponent);
}
/** copy src to dst with unicode-escapes for values < 0x20 and > 0x7e, null terminate if possible */
@ -2032,13 +2042,108 @@ static void TestCloneWithRBNF(void) {
}
}
static void TestNoExponent(void) {
UErrorCode status = U_ZERO_ERROR;
UChar str[100];
const char *cstr;
UNumberFormat *fmt;
int32_t pos;
int32_t expect = 0;
int32_t num;
fmt = unum_open(UNUM_DECIMAL, NULL, -1, "en_US", NULL, &status);
if(U_FAILURE(status) || fmt == NULL) {
log_data_err("%s:%d: unum_open failed with %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status));
return;
}
cstr = "10E6";
u_uastrcpy(str, cstr);
expect = 10000000;
pos = 0;
num = unum_parse(fmt, str, -1, &pos, &status);
ASSERT_TRUE(pos==4);
if(U_FAILURE(status)) {
log_data_err("%s:%d: unum_parse failed with %s for %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status), cstr);
} else if(expect!=num) {
log_data_err("%s:%d: unum_parse failed, got %d expected %d for '%s'(Are you missing data?)\n", __FILE__, __LINE__, num, expect, cstr);
} else {
log_verbose("%s:%d: unum_parse returned %d for '%s'\n", __FILE__, __LINE__, num, cstr);
}
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_PARSE_NO_EXPONENT)==0);
unum_setAttribute(fmt, UNUM_PARSE_NO_EXPONENT, 1); /* no error code */
log_verbose("set UNUM_PARSE_NO_EXPONENT\n");
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_PARSE_NO_EXPONENT)==1);
pos = 0;
expect=10;
num = unum_parse(fmt, str, -1, &pos, &status);
if(num==10000000) {
log_err("%s:%d: FAIL: unum_parse should have returned 10, not 10000000 on %s after UNUM_PARSE_NO_EXPONENT\n", __FILE__, __LINE__, cstr);
} else if(num==expect) {
log_verbose("%s:%d: unum_parse gave %d for %s - good.\n", __FILE__, __LINE__, num, cstr);
}
ASSERT_TRUE(pos==2);
status = U_ZERO_ERROR;
unum_close(fmt);
/* ok, now try scientific */
fmt = unum_open(UNUM_SCIENTIFIC, NULL, -1, "en_US", NULL, &status);
assertSuccess("unum_open(UNUM_SCIENTIFIC, ...)", &status);
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_PARSE_NO_EXPONENT)==0);
cstr = "10E6";
u_uastrcpy(str, cstr);
expect = 10000000;
pos = 0;
num = unum_parse(fmt, str, -1, &pos, &status);
ASSERT_TRUE(pos==4);
if(U_FAILURE(status)) {
log_data_err("%s:%d: unum_parse failed with %s for %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status), cstr);
} else if(expect!=num) {
log_data_err("%s:%d: unum_parse failed, got %d expected %d for '%s'(Are you missing data?)\n", __FILE__, __LINE__, num, expect, cstr);
} else {
log_verbose("%s:%d: unum_parse returned %d for '%s'\n", __FILE__, __LINE__, num, cstr);
}
unum_setAttribute(fmt, UNUM_PARSE_NO_EXPONENT, 1); /* no error code */
log_verbose("set UNUM_PARSE_NO_EXPONENT\n");
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_PARSE_NO_EXPONENT)==1);
cstr = "10E6";
u_uastrcpy(str, cstr);
expect = 10000000;
pos = 0;
num = unum_parse(fmt, str, -1, &pos, &status);
ASSERT_TRUE(pos==4);
if(U_FAILURE(status)) {
log_data_err("%s:%d: unum_parse failed with %s for %s (Are you missing data?)\n", __FILE__, __LINE__, u_errorName(status), cstr);
} else if(expect!=num) {
log_data_err("%s:%d: unum_parse failed, got %d expected %d for '%s'(Are you missing data?)\n", __FILE__, __LINE__, num, expect, cstr);
} else {
log_verbose("%s:%d: unum_parse returned %d for '%s'\n", __FILE__, __LINE__, num, cstr);
}
unum_close(fmt);
}
static void TestMaxInt(void) {
UErrorCode status = U_ZERO_ERROR;
UChar pattern_hash[] = { 0x23, 0x00 }; /* "#" */
UChar result1[1024] = { 0 }, result2[1024] = { 0 };
int32_t len1, len2;
UChar expect[] = { 0x0039, 0x0037, 0 };
UNumberFormat *fmt = unum_open(
UErrorCode status = U_ZERO_ERROR;
UChar pattern_hash[] = { 0x23, 0x00 }; /* "#" */
UChar result1[1024] = { 0 }, result2[1024] = { 0 };
int32_t len1, len2;
UChar expect[] = { 0x0039, 0x0037, 0 };
UNumberFormat *fmt = unum_open(
UNUM_PATTERN_DECIMAL, /* style */
&pattern_hash[0], /* pattern */
u_strlen(pattern_hash), /* patternLength */
@ -2046,30 +2151,62 @@ static void TestMaxInt(void) {
0, /* parseErr */
&status);
if(U_FAILURE(status) || fmt == NULL) {
log_data_err("%s:%d: %s: unum_open failed with %s (Are you missing data?)\n", __FILE__, __LINE__, "TestMaxInt", u_errorName(status));
log_data_err("%s:%d: %s: unum_open failed with %s (Are you missing data?)\n", __FILE__, __LINE__, "TestMaxInt", u_errorName(status));
return;
}
unum_setAttribute(fmt, UNUM_MAX_INTEGER_DIGITS, 2);
unum_setAttribute(fmt, UNUM_MAX_INTEGER_DIGITS, 2);
status = U_ZERO_ERROR;
/* #1 */
len1 = unum_formatInt64(fmt, 1997, result1, 1024, NULL, &status);
result1[len1]=0;
if(U_FAILURE(status) || u_strcmp(expect, result1)) {
log_err("unum_formatInt64 Expected %s but got %s status %s\n", austrdup(expect), austrdup(result1), u_errorName(status));
}
status = U_ZERO_ERROR;
/* #1 */
len1 = unum_formatInt64(fmt, 1997, result1, 1024, NULL, &status);
result1[len1]=0;
if(U_FAILURE(status) || u_strcmp(expect, result1)) {
log_err("unum_formatInt64 Expected %s but got %s status %s\n", austrdup(expect), austrdup(result1), u_errorName(status));
}
status = U_ZERO_ERROR;
/* #2 */
len2 = unum_formatDouble(fmt, 1997.0, result2, 1024, NULL, &status);
result2[len2]=0;
if(U_FAILURE(status) || u_strcmp(expect, result2)) {
log_err("unum_formatDouble Expected %s but got %s status %s\n", austrdup(expect), austrdup(result2), u_errorName(status));
}
status = U_ZERO_ERROR;
/* #2 */
len2 = unum_formatDouble(fmt, 1997.0, result2, 1024, NULL, &status);
result2[len2]=0;
if(U_FAILURE(status) || u_strcmp(expect, result2)) {
log_err("unum_formatDouble Expected %s but got %s status %s\n", austrdup(expect), austrdup(result2), u_errorName(status));
}
unum_close(fmt);
/* test UNUM_FORMAT_FAIL_IF_MAX_DIGITS */
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_FORMAT_FAIL_IF_MAX_DIGITS)==0);
unum_setAttribute(fmt, UNUM_FORMAT_FAIL_IF_MAX_DIGITS, 1);
/* test UNUM_FORMAT_FAIL_IF_MAX_DIGITS */
ASSERT_TRUE(unum_getAttribute(fmt, UNUM_FORMAT_FAIL_IF_MAX_DIGITS)==1);
status = U_ZERO_ERROR;
/* max int digits still '2' */
len1 = unum_formatInt64(fmt, 1997, result1, 1024, NULL, &status);
ASSERT_TRUE(status==U_ILLEGAL_ARGUMENT_ERROR);
status = U_ZERO_ERROR;
/* But, formatting 97->'97' works fine. */
/* #1 */
len1 = unum_formatInt64(fmt, 97, result1, 1024, NULL, &status);
result1[len1]=0;
if(U_FAILURE(status) || u_strcmp(expect, result1)) {
log_err("unum_formatInt64 Expected %s but got %s status %s\n", austrdup(expect), austrdup(result1), u_errorName(status));
}
status = U_ZERO_ERROR;
/* #2 */
len2 = unum_formatDouble(fmt, 97.0, result2, 1024, NULL, &status);
result2[len2]=0;
if(U_FAILURE(status) || u_strcmp(expect, result2)) {
log_err("unum_formatDouble Expected %s but got %s status %s\n", austrdup(expect), austrdup(result2), u_errorName(status));
}
unum_close(fmt);
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -119,6 +119,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
CASE(53,TestRoundingPattern);
CASE(54,Test9087);
CASE(55,TestFormatFastpaths);
CASE(56,TestEnumSet);
default: name = ""; break;
}
}
@ -6583,103 +6584,141 @@ NumberFormatTest::Test9087(void)
void NumberFormatTest::TestFormatFastpaths() {
#if UCONFIG_FORMAT_FASTPATHS_49
logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
logln("Sizeof DecimalFormat = %d, Sizeof DecimalFormatInternal=%d, UNUM_DECIMALFORMAT_INTERNAL_SIZE=%d\n",
sizeof(DecimalFormat), sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
} else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat));
}
if(UNUM_DECIMALFORMAT_INTERNAL_SIZE < sizeof(DecimalFormatInternal)) {
errln("Error: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is only %d. Increase the #define?\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE);
} else if(UNUM_DECIMALFORMAT_INTERNAL_SIZE > (sizeof(DecimalFormatInternal)+16)) {
infoln("Note: sizeof(DecimalFormatInternal)=%d but UNUM_DECIMALFORMAT_INTERNAL_SIZE is %d. Decrease the #define? sizeof(DecimalFormat)=%d\n", sizeof(DecimalFormatInternal), UNUM_DECIMALFORMAT_INTERNAL_SIZE, sizeof(DecimalFormat));
}
#else
infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
infoln("NOTE: UCONFIG_FORMAT_FASTPATHS not set, test skipped.");
#endif
// get some additional case
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000",""),status);
int64_t long_number = 1;
UnicodeString expect = "0001";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
// get some additional case
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000",""),status);
int64_t long_number = 1;
UnicodeString expect = "0001";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),""));
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),""));
}
}
}
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "-9223372036854775808";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MIN; // -9223372036854775808L;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "-9223372036854775808";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775808");
}
}
}
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "9223372036854775807";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MAX; // -9223372036854775808L;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "9223372036854775807";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on U_INT64_MAX");
}
}
}
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = 0;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "0000000000000000000";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = 0;
// uint8_t bits[8];
// memcpy(bits,&long_number,8);
// for(int i=0;i<8;i++) {
// logln("bits: %02X", (unsigned int)bits[i]);
// }
UnicodeString expect = "0000000000000000000";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on 0");
}
}
}
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MIN + 1;
UnicodeString expect = "-9223372036854775807";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
{
UErrorCode status=U_ZERO_ERROR;
DecimalFormat df(UnicodeString("0000000000000000000",""),status);
int64_t long_number = U_INT64_MIN + 1;
UnicodeString expect = "-9223372036854775807";
UnicodeString result;
FieldPosition pos;
df.format(long_number, result, pos);
if(U_FAILURE(status)||expect!=result) {
errcheckln(status, "FAIL: expected '"+expect+"' got '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
} else {
logln("OK: got expected '"+result+"' status "+UnicodeString(u_errorName(status),"")+" on -9223372036854775807");
}
}
}
}
enum myEnum {
MAX_NONBOOLEAN=-1,
THING1,
THING2,
THING3,
LIMIT_BOOLEAN
};
void NumberFormatTest::TestEnumSet(void) {
EnumSet<myEnum,
myEnum::MAX_NONBOOLEAN+1,
myEnum::LIMIT_BOOLEAN>
flags;
infoln("TODO!! This test doesn't fail on error. Convert printf into error assert.\n");
logln("Enum is from [%d..%d]\n", myEnum::MAX_NONBOOLEAN+1,
myEnum::LIMIT_BOOLEAN);
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
logln("Value now: %d\n", flags.getAll());
flags.clear();
logln("clear -Value now: %d\n", flags.getAll());
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
flags.add(myEnum::THING1);
logln("set THING1 -Value now: %d\n", flags.getAll());
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
flags.add(myEnum::THING3);
logln("set THING3 -Value now: %d\n", flags.getAll());
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
flags.remove(myEnum::THING2);
logln("remove THING2 -Value now: %d\n", flags.getAll());
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
flags.remove(myEnum::THING1);
logln("remove THING1 -Value now: %d\n", flags.getAll());
logln("get(thing1)=%d, get(thing2)=%d, get(thing3)=%d\n", flags.get(myEnum::THING1), flags.get(myEnum::THING2), flags.get(myEnum::THING3));
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View File

@ -158,6 +158,7 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void Test9087();
void TestFormatFastpaths();
void TestEnumSet();
private: