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)