164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Copyright (C) 2004-2009, International Business Machines Corporation and * 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * others. All Rights Reserved. * 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************************* 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "itrbnfp.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/umachine.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/tblcoll.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/coleitr.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/decimfmt.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h> 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// current macro not in icu1.8.1 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TESTCASE(id,test) \ 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case id: \ 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = #test; \ 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) { \ 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(#test "---"); \ 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho logln(); \ 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru test(); \ 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } \ 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid IntlTestRBNFParse::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/) 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) logln("TestSuite RuleBasedNumberFormatParse"); 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (index) { 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_HAVE_RBNF 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TESTCASE(0, TestParse); 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TESTCASE(0, TestRBNFParseDisabled); 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = ""; 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if U_HAVE_RBNF 53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruIntlTestRBNFParse::TestParse() { 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Try various rule parsing errors. Shouldn't crash. 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("RBNF Parse test starting"); 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // these rules make no sense but behave rationally 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* okrules[] = { 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "", 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "random text", 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "%foo:bar", 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "%foo: bar", 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "0:", 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "0::", 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ";", 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ";;", 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "%%foo:;", 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ":", 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "::", 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ":1", 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ":;", 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ":;:;", 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "-", 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "-1", 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "-:", 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ".", 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ".1", 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[", 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "]", 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[]", 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[foo]", 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[[]", 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[]]", 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[[]]", 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "[][]", 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<", 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<<", 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "<<<", 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "10:;9:;", 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ">", 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ">>", 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ">>>", 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "=", 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "==", 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "===", 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "=foo=", 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // these rules would throw exceptions when formatting, if we could throw exceptions 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* exceptrules[] = { 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "10:", // formatting any value with a one's digit will fail 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "11: << x", // formating a multiple of 10 causes rollback rule to fail 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "%%foo: 0 foo; 10: =%%bar=; %%bar: 0: bar; 10: =%%foo=;", 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // none of these rules should crash the formatter 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char** allrules[] = { 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru okrules, 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru exceptrules, 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru NULL, 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int j = 0; allrules[j]; ++j) { 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char** rules = allrules[j]; 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int i = 0; rules[i]; ++i) { 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* rule = rules[i]; 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("rule[%d] \"%s\"", i, rule); 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UParseError perr; 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(rule, Locale::getUS(), perr, status); 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) { 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // format some values 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testfmt(formatter, 20, status); 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testfmt(formatter, 1.23, status); 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testfmt(formatter, -123, status); 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testfmt(formatter, .123, status); 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testfmt(formatter, 123, status); 137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (status == U_PARSE_ERROR) { 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("perror line: %x offset: %x context: %s|%s", perr.line, perr.offset, perr.preContext, perr.postContext); 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete formatter; 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruIntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, double val, UErrorCode& status) { 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString us; 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru formatter->format((const Formattable)val, us, status); 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) { 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us.insert(0, (UChar)'"'); 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us.append((UChar)'"'); 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(us); 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("error: could not format %g, returned status: %d", val, status); 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruIntlTestRBNFParse::testfmt(RuleBasedNumberFormat* formatter, int val, UErrorCode& status) { 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString us; 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru formatter->format((const Formattable)(int32_t)val, us, status); 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(status)) { 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us.insert(0, (UChar)'"'); 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru us.append((UChar)'"'); 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(us); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("error: could not format %d, returned status: %d", val, status); 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* U_HAVE_RBNF */ 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruIntlTestRBNF::TestRBNFParseDisabled() { 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("*** RBNF currently disabled on this platform ***\n"); 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* U_HAVE_RBNF */ 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 186