mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
X-SVN-Rev: 28696
This commit is contained in:
parent
fe39e343b9
commit
c9f7d5a324
6 changed files with 124 additions and 4 deletions
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -147,6 +147,8 @@ class NumberFormatTest: public CalendarTimeZoneTest {
|
|||
|
||||
void TestDecimal();
|
||||
|
||||
void TestExponentParse();
|
||||
|
||||
private:
|
||||
|
||||
static UBool equalValue(const Formattable& a, const Formattable& b);
|
||||
|
|
Loading…
Add table
Reference in a new issue