15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ******************************************************************************* 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 2004-2009, International Business Machines Corporation and * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * others. All Rights Reserved. * 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ******************************************************************************* 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/utypes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !UCONFIG_NO_FORMATTING 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "itrbnfp.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "unicode/umachine.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/tblcoll.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/coleitr.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/ures.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/ustring.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "unicode/decimfmt.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// current macro not in icu1.8.1 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TESTCASE(id,test) \ 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case id: \ 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) name = #test; \ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec) { \ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln(#test "---"); \ 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) logln(); \ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test(); \ 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } \ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IntlTestRBNFParse::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (exec) logln("TestSuite RuleBasedNumberFormatParse"); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (index) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if U_HAVE_RBNF 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TESTCASE(0, TestParse); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TESTCASE(0, TestRBNFParseDisabled); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = ""; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if U_HAVE_RBNF 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IntlTestRBNFParse::TestParse() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try various rule parsing errors. Shouldn't crash. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln("RBNF Parse test starting"); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // these rules make no sense but behave rationally 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* okrules[] = { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "random text", 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%foo:bar", 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%foo: bar", 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0:", 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "0::", 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ";", 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ";;", 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%%foo:;", 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ":", 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "::", 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ":1", 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ":;", 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ":;:;", 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "-", 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "-1", 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "-:", 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ".", 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ".1", 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[", 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "]", 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[]", 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[foo]", 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[[]", 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[]]", 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[[]]", 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "[][]", 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "<", 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "<<", 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "<<<", 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "10:;9:;", 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ">", 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ">>", 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ">>>", 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "=", 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "==", 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "===", 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "=foo=", 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // these rules would throw exceptions when formatting, if we could throw exceptions 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* exceptrules[] = { 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "10:", // formatting any value with a one's digit will fail 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "11: << x", // formating a multiple of 10 causes rollback rule to fail 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "%%foo: 0 foo; 10: =%%bar=; %%bar: 0: bar; 10: =%%foo=;", 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // none of these rules should crash the formatter 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char** allrules[] = { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) okrules, 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) exceptrules, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NULL, 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int j = 0; allrules[j]; ++j) { 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char** rules = allrules[j]; 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (int i = 0; rules[i]; ++i) { 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* rule = rules[i]; 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) logln("rule[%d] \"%s\"", i, rule); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UErrorCode status = U_ZERO_ERROR; 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UParseError perr; 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(rule, Locale::getUS(), perr, status); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (U_SUCCESS(status)) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // format some values 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) testfmt(formatter, 20, status); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) testfmt(formatter, 1.23, status); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) testfmt(formatter, -123, status); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) testfmt(formatter, .123, status); 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) testfmt(formatter, 123, status); 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (status == U_PARSE_ERROR) { 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) logln("perror line: %x offset: %x context: %s|%s", perr.line, perr.offset, perr.preContext, perr.postContext); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete formatter; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, double val, UErrorCode& status) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnicodeString us; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatter->format((const Formattable)val, us, status); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (U_SUCCESS(status)) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) us.insert(0, (UChar)'"'); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) us.append((UChar)'"'); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln(us); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln("error: could not format %g, returned status: %d", val, status); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, int val, UErrorCode& status) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnicodeString us; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) formatter->format((const Formattable)(int32_t)val, us, status); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (U_SUCCESS(status)) { 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) us.insert(0, (UChar)'"'); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) us.append((UChar)'"'); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln(us); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logln("error: could not format %d, returned status: %d", val, status); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* U_HAVE_RBNF */ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IntlTestRBNF::TestRBNFParseDisabled() { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) errln("*** RBNF currently disabled on this platform ***\n"); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* U_HAVE_RBNF */ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)