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