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