diff --git a/icu4c/source/i18n/fmtable.cpp b/icu4c/source/i18n/fmtable.cpp index bdb0b6de9df..274b3d782d0 100644 --- a/icu4c/source/i18n/fmtable.cpp +++ b/icu4c/source/i18n/fmtable.cpp @@ -36,13 +36,7 @@ U_NAMESPACE_BEGIN UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Formattable) -struct FmtStackData { - DigitList stackDecimalNum; // 128 - //CharString stackDecimalStr; // 64 - // ----- - // 192 total -}; - +#include "fmtableimp.h" //-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. diff --git a/icu4c/source/i18n/fmtableimp.h b/icu4c/source/i18n/fmtableimp.h new file mode 100644 index 00000000000..db7aa3e9e2e --- /dev/null +++ b/icu4c/source/i18n/fmtableimp.h @@ -0,0 +1,24 @@ +/* +******************************************************************************* +* Copyright (C) 2010-2012, International Business Machines Corporation and * +* others. All Rights Reserved. * +******************************************************************************* +*/ + +#ifndef FMTABLEIMP_H +#define FMTABLEIMP_H + + +/** + * @internal + */ +struct FmtStackData { + DigitList stackDecimalNum; // 128 + //CharString stackDecimalStr; // 64 + // ----- + // 192 total +}; + + + +#endif diff --git a/icu4c/source/i18n/unicode/fmtable.h b/icu4c/source/i18n/unicode/fmtable.h index 845122ed2db..91cc85f348d 100644 --- a/icu4c/source/i18n/unicode/fmtable.h +++ b/icu4c/source/i18n/unicode/fmtable.h @@ -31,6 +31,16 @@ U_NAMESPACE_BEGIN class CharString; class DigitList; +/** + * \def UNUM_INTERNAL_STACKARRAY_SIZE + * @internal + */ +#if U_PLATFORM == U_PF_OS400 +#define UNUM_INTERNAL_STACKARRAY_SIZE 144 +#else +#define UNUM_INTERNAL_STACKARRAY_SIZE 128 +#endif + /** * Formattable objects can be passed to the Format class or * its subclasses for formatting. Formattable is a thin wrapper @@ -649,7 +659,7 @@ private: DigitList *fDecimalNum; - char fStackData[128]; // must be big enough for DigitList + char fStackData[UNUM_INTERNAL_STACKARRAY_SIZE]; // must be big enough for DigitList Type fType; UnicodeString fBogus; // Bogus string when it's needed. diff --git a/icu4c/source/test/cintltst/cnumtst.c b/icu4c/source/test/cintltst/cnumtst.c index 358b0c7c3b2..46964af9d53 100644 --- a/icu4c/source/test/cintltst/cnumtst.c +++ b/icu4c/source/test/cintltst/cnumtst.c @@ -75,40 +75,6 @@ void addNumForTest(TestNode** root) TESTCASE(TestNoExponent); } -/** copy src to dst with unicode-escapes for values < 0x20 and > 0x7e, null terminate if possible */ -static int32_t ustrToAstr(const UChar* src, int32_t srcLength, char* dst, int32_t dstLength) { - static const char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - - char *p = dst; - const char *e = p + dstLength; - if (srcLength < 0) { - const UChar* s = src; - while (*s) { - ++s; - } - srcLength = (int32_t)(s - src); - } - while (p < e && --srcLength >= 0) { - UChar c = *src++; - if (c == 0xd || c == 0xa || c == 0x9 || (c>= 0x20 && c <= 0x7e)) { - *p++ = (char) c & 0x7f; - } else if (e - p >= 6) { - *p++ = '\\'; - *p++ = 'u'; - *p++ = hex[(c >> 12) & 0xf]; - *p++ = hex[(c >> 8) & 0xf]; - *p++ = hex[(c >> 4) & 0xf]; - *p++ = hex[c & 0xf]; - } else { - break; - } - } - if (p < e) { - *p = 0; - } - return (int32_t)(p - dst); -} - /* test Parse int 64 */ static void TestInt64Parse() @@ -297,7 +263,7 @@ static void TestNumberFormat() log_err("Fail: Error in complete number Formatting using unum_format()\nGot: b=%d end=%d\nExpected: b=1 end=12\n", pos1.beginIndex, pos1.endIndex); -free(result); + free(result); result = 0; log_verbose("\nTesting unum_formatDouble()\n"); @@ -333,17 +299,14 @@ free(result); /* Testing unum_parse() and unum_parseDouble() */ log_verbose("\nTesting unum_parseDouble()\n"); /* for (i = 0; i < 100000; i++)*/ - if (result != NULL) - { - parsepos=0; - d1=unum_parseDouble(cur_def, result, u_strlen(result), &parsepos, &status); + parsepos=0; + if (result != NULL) { + d1=unum_parseDouble(cur_def, result, u_strlen(result), &parsepos, &status); + } else { + log_err("result is NULL\n"); } - else { - log_err("result is NULL\n"); - } - if(U_FAILURE(status)) - { - log_err("parse failed. The error is : %s\n", myErrorName(status)); + if(U_FAILURE(status)) { + log_err("parse of '%s' failed. Parsepos=%d. The error is : %s\n", aescstrdup(result,u_strlen(result)),parsepos, myErrorName(status)); } if(d1!=d) @@ -354,7 +317,7 @@ free(result); free(result); result = 0; - + status = U_ZERO_ERROR; /* Testing unum_formatDoubleCurrency / unum_parseDoubleCurrency */ log_verbose("\nTesting unum_formatDoubleCurrency\n"); u_uastrcpy(temp1, "Y1,235"); @@ -392,7 +355,7 @@ free(result); else { d1=unum_parseDoubleCurrency(cur_def, result, u_strlen(result), &parsepos, temp2, &status); if (U_FAILURE(status)) { - log_err("parse failed. The error is : %s\n", myErrorName(status)); + log_err("parseDoubleCurrency '%s' failed. The error is : %s\n", aescstrdup(result, u_strlen(result)), myErrorName(status)); } /* Note: a==1234.56, but on parse expect a1=1235.0 */ if (d1!=a1) { @@ -406,8 +369,9 @@ free(result); log_err("Fail: parsed incorrect currency\n"); } } + status = U_ZERO_ERROR; /* reset */ -free(result); + free(result); result = 0; @@ -421,7 +385,7 @@ free(result); } if(U_FAILURE(status)) { - log_err("parse failed. The error is : %s\n", myErrorName(status)); + log_err("parseDouble('%s') failed. The error is : %s\n", aescstrdup(temp1, resultlength), myErrorName(status)); } /* @@ -805,9 +769,8 @@ free(result); } else { int32_t pp = 0; int32_t parseResult; - char logbuf[256]; - ustrToAstr(buffer, len, logbuf, LENGTH(logbuf)); - log_verbose("formatted %d as '%s', length: %d\n", value, logbuf, len); + /*ustrToAstr(buffer, len, logbuf, LENGTH(logbuf));*/ + log_verbose("formatted %d as '%s', length: %d\n", value, aescstrdup(buffer, len), len); parseResult = unum_parse(spellout_def, buffer, len, &pp, &status); if (U_FAILURE(status)) { diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index 690e74b7fab..963656fd760 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -31,6 +31,7 @@ #include #include "cstring.h" #include "unicode/numsys.h" +#include "fmtableimp.h" //#define NUMFMTST_CACHE_DEBUG 1 #include "stdio.h" /* for sprintf */ @@ -120,6 +121,7 @@ void NumberFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &n CASE(54,Test9087); CASE(55,TestFormatFastpaths); CASE(56,TestEnumSet); + CASE(57,TestFormattableSize); default: name = ""; break; } } @@ -6721,4 +6723,17 @@ void NumberFormatTest::TestEnumSet(void) { } +void NumberFormatTest::TestFormattableSize(void) { + if(sizeof(FmtStackData) > UNUM_INTERNAL_STACKARRAY_SIZE) { + errln("Error: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", + sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); + } else if(sizeof(FmtStackData) < UNUM_INTERNAL_STACKARRAY_SIZE) { + logln("Warning: sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", + sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); + } else { + logln("sizeof(FmtStackData)=%d, UNUM_INTERNAL_STACKARRAY_SIZE=%d\n", + sizeof(FmtStackData), UNUM_INTERNAL_STACKARRAY_SIZE); + } +} + #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/intltest/numfmtst.h b/icu4c/source/test/intltest/numfmtst.h index cc8cb36fe24..d46add7ca3a 100644 --- a/icu4c/source/test/intltest/numfmtst.h +++ b/icu4c/source/test/intltest/numfmtst.h @@ -158,6 +158,8 @@ class NumberFormatTest: public CalendarTimeZoneTest { void Test9087(); void TestFormatFastpaths(); + void TestFormattableSize(); + void TestEnumSet(); private: