ICU-7961 merge of r28282 r28299 r28683 r28684 r28685 from #7654 #7911 for milestone:4.4.2

X-SVN-Rev: 28696
This commit is contained in:
Steven R. Loomis 2010-09-24 23:07:51 +00:00
parent fe39e343b9
commit c9f7d5a324
6 changed files with 124 additions and 4 deletions

View file

@ -1924,7 +1924,7 @@ UBool DecimalFormat::subparse(const UnicodeString& text,
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
if (!text.compare(position, tmp->length(), *tmp)) // error code is set below if !sawDigit
{
// Parse sign, if present
int32_t pos = position + tmp->length();

View file

@ -442,10 +442,10 @@ Formattable::getInt64(UErrorCode& status) const
case Formattable::kInt64:
return fValue.fInt64;
case Formattable::kDouble:
if (fValue.fDouble > U_INT64_MAX) {
if (fValue.fDouble >= U_INT64_MAX) {
status = U_INVALID_FORMAT_ERROR;
return U_INT64_MAX;
} else if (fValue.fDouble < U_INT64_MIN) {
} else if (fValue.fDouble <= U_INT64_MIN) {
status = U_INVALID_FORMAT_ERROR;
return U_INT64_MIN;
} else {

View file

@ -1,7 +1,7 @@
/*
*******************************************************************************
*
* Copyright (C) 1998-2006, International Business Machines
* Copyright (C) 1998-2010, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
@ -473,6 +473,8 @@ u_scanf_double_handler(UFILE *input,
return parsePos + skipped;
}
#define UPRINTF_SYMBOL_BUFFER_SIZE 8
static int32_t
u_scanf_scientific_handler(UFILE *input,
u_scanf_spec_info *info,
@ -487,6 +489,9 @@ u_scanf_scientific_handler(UFILE *input,
int32_t parsePos = 0;
int32_t skipped;
UErrorCode status = U_ZERO_ERROR;
UChar srcExpBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
int32_t srcLen, expLen;
UChar expBuf[UPRINTF_SYMBOL_BUFFER_SIZE];
/* skip all ws in the input */
@ -509,6 +514,37 @@ u_scanf_scientific_handler(UFILE *input,
if(format == 0)
return 0;
/* set the appropriate flags on the formatter */
srcLen = unum_getSymbol(format,
UNUM_EXPONENTIAL_SYMBOL,
srcExpBuf,
sizeof(srcExpBuf),
&status);
/* Upper/lower case the e */
if (info->fSpec == (UChar)0x65 /* e */) {
expLen = u_strToLower(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
input->str.fBundle.fLocale,
&status);
}
else {
expLen = u_strToUpper(expBuf, (int32_t)sizeof(expBuf),
srcExpBuf, srcLen,
input->str.fBundle.fLocale,
&status);
}
unum_setSymbol(format,
UNUM_EXPONENTIAL_SYMBOL,
expBuf,
expLen,
&status);
/* Skip the positive prefix. ICU normally can't handle this due to strict parsing. */
skipped += u_scanf_skip_leading_positive_sign(input, format, &status);

View file

@ -36,6 +36,7 @@
void addNumForTest(TestNode** root);
static void TestTextAttributeCrash(void);
static void TestNBSPInPattern(void);
static void TestInt64Parse(void);
#define TESTCASE(x) addTest(root, &x, "tsformat/cnumtst/" #x)
@ -51,6 +52,7 @@ void addNumForTest(TestNode** root)
TESTCASE(TestTextAttributeCrash);
TESTCASE(TestRBNFFormat);
TESTCASE(TestNBSPInPattern);
TESTCASE(TestInt64Parse);
}
/** copy src to dst with unicode-escapes for values < 0x20 and > 0x7e, null terminate if possible */
@ -87,6 +89,51 @@ static int32_t ustrToAstr(const UChar* src, int32_t srcLength, char* dst, int32_
return (int32_t)(p - dst);
}
/* test Parse int 64 */
static void TestInt64Parse()
{
UErrorCode st = U_ZERO_ERROR;
UErrorCode* status = &st;
char* st1 = "009223372036854775808";
const int size = 21;
const int textLength = size;
UChar text[21];
UNumberFormat* nf;
int64_t a;
u_charsToUChars(st1, text, size);
nf = unum_open(UNUM_DEFAULT, NULL, -1, NULL, NULL, status);
if(U_FAILURE(*status))
{
log_err("Error in unum_open() %s \n", myErrorName(*status));
return;
}
log_verbose("About to test unum_parseInt64() with out of range number\n");
a = unum_parseInt64(nf, text, size, 0, status);
if(!U_FAILURE(*status))
{
log_err("Error in unum_parseInt64(): %s \n", myErrorName(*status));
}
else
{
log_verbose("unum_parseInt64() successful\n");
}
unum_close(nf);
return;
}
/* test Number Format API */
static void TestNumberFormat()
{

View file

@ -108,6 +108,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n
CASE(45,TestFormatAttributes);
CASE(46,TestFieldPositionIterator);
CASE(47,TestDecimal);
CASE(49,TestExponentParse);
default: name = ""; break;
}
}
@ -6113,4 +6114,38 @@ void NumberFormatTest::TestDecimal() {
}
void NumberFormatTest::TestExponentParse() {
UErrorCode status = U_ZERO_ERROR;
Formattable result;
ParsePosition parsePos(0);
// set the exponent symbol
status = U_ZERO_ERROR;
DecimalFormatSymbols *symbols = new DecimalFormatSymbols(Locale::getDefault(), status);
if(U_FAILURE(status)) {
errln((UnicodeString)"ERROR: Could not create DecimalFormatSymbols (Default)");
return;
}
symbols->setSymbol(DecimalFormatSymbols::kExponentialSymbol,"e");
// create format instance
status = U_ZERO_ERROR;
DecimalFormat fmt("#####", symbols, status);
if(U_FAILURE(status)) {
errln((UnicodeString)"ERROR: Could not create DecimalFormat (pattern, symbols*)");
}
// parse the text
fmt.parse("123E4", result, parsePos);
if(result.getType() != Formattable::kDouble &&
result.getDouble() != (double)123 &&
parsePos.getIndex() != 3
)
{
errln("ERROR: parse failed - expected 123.0, 3 - returned %d, %i",
result.getDouble(), parsePos);
}
}
#endif /* #if !UCONFIG_NO_FORMATTING */

View file

@ -147,6 +147,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
void TestDecimal();
void TestExponentParse();
private:
static UBool equalValue(const Formattable& a, const Formattable& b);