• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2012, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #include "itrbnf.h"
13 
14 #include "unicode/umachine.h"
15 
16 #include "unicode/tblcoll.h"
17 #include "unicode/coleitr.h"
18 #include "unicode/ures.h"
19 #include "unicode/ustring.h"
20 #include "unicode/decimfmt.h"
21 #include "unicode/udata.h"
22 #include "testutil.h"
23 
24 //#include "llong.h"
25 
26 #include <string.h>
27 
28 // import com.ibm.text.RuleBasedNumberFormat;
29 // import com.ibm.test.TestFmwk;
30 
31 // import java.util.Locale;
32 // import java.text.NumberFormat;
33 
34 // current macro not in icu1.8.1
35 #define TESTCASE(id,test)             \
36     case id:                          \
37         name = #test;                 \
38         if (exec) {                   \
39             logln(#test "---");       \
40             logln();                  \
41             test();                   \
42         }                             \
43         break
44 
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)45 void IntlTestRBNF::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
46 {
47     if (exec) logln("TestSuite RuleBasedNumberFormat");
48     switch (index) {
49 #if U_HAVE_RBNF
50         TESTCASE(0, TestEnglishSpellout);
51         TESTCASE(1, TestOrdinalAbbreviations);
52         TESTCASE(2, TestDurations);
53         TESTCASE(3, TestSpanishSpellout);
54         TESTCASE(4, TestFrenchSpellout);
55         TESTCASE(5, TestSwissFrenchSpellout);
56         TESTCASE(6, TestItalianSpellout);
57         TESTCASE(7, TestGermanSpellout);
58         TESTCASE(8, TestThaiSpellout);
59         TESTCASE(9, TestAPI);
60         TESTCASE(10, TestFractionalRuleSet);
61         TESTCASE(11, TestSwedishSpellout);
62         TESTCASE(12, TestBelgianFrenchSpellout);
63         TESTCASE(13, TestSmallValues);
64         TESTCASE(14, TestLocalizations);
65         TESTCASE(15, TestAllLocales);
66         TESTCASE(16, TestHebrewFraction);
67         TESTCASE(17, TestPortugueseSpellout);
68         TESTCASE(18, TestMultiplierSubstitution);
69         TESTCASE(19, TestSetDecimalFormatSymbols);
70 #else
71         TESTCASE(0, TestRBNFDisabled);
72 #endif
73     default:
74         name = "";
75         break;
76     }
77 }
78 
79 #if U_HAVE_RBNF
80 
TestHebrewFraction()81 void IntlTestRBNF::TestHebrewFraction() {
82 
83     // this is the expected output for 123.45, with no '<' in it.
84     UChar text1[] = {
85         0x05de, 0x05d0, 0x05d4, 0x0020,
86         0x05e2, 0x05e9, 0x05e8, 0x05d9, 0x05dd, 0x0020,
87         0x05d5, 0x05e9, 0x05dc, 0x05d5, 0x05e9, 0x0020,
88         0x05e0, 0x05e7, 0x05d5, 0x05d3, 0x05d4, 0x0020,
89         0x05d0, 0x05e8, 0x05d1, 0x05e2, 0x0020,
90         0x05d7, 0x05de, 0x05e9, 0x0000,
91     };
92     UChar text2[] = {
93         0x05DE, 0x05D0, 0x05D4, 0x0020,
94         0x05E2, 0x05E9, 0x05E8, 0x05D9, 0x05DD, 0x0020,
95         0x05D5, 0x05E9, 0x05DC, 0x05D5, 0x05E9, 0x0020,
96         0x05E0, 0x05E7, 0x05D5, 0x05D3, 0x05D4, 0x0020,
97         0x05D0, 0x05E4, 0x05E1, 0x0020,
98         0x05D0, 0x05E4, 0x05E1, 0x0020,
99         0x05D0, 0x05E8, 0x05D1, 0x05E2, 0x0020,
100         0x05D7, 0x05DE, 0x05E9, 0x0000,
101     };
102     UErrorCode status = U_ZERO_ERROR;
103     RuleBasedNumberFormat* formatter = new RuleBasedNumberFormat(URBNF_SPELLOUT, "he_IL", status);
104     if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
105         errcheckln(status, "Failed in constructing RuleBasedNumberFormat - %s", u_errorName(status));
106         delete formatter;
107         return;
108     }
109     UnicodeString result;
110     Formattable parseResult;
111     ParsePosition pp(0);
112     {
113         UnicodeString expected(text1);
114         formatter->format(123.45, result);
115         if (result != expected) {
116             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
117         } else {
118 //            formatter->parse(result, parseResult, pp);
119 //            if (parseResult.getDouble() != 123.45) {
120 //                errln("expected 123.45 but got: %g", parseResult.getDouble());
121 //            }
122         }
123     }
124     {
125         UnicodeString expected(text2);
126         result.remove();
127         formatter->format(123.0045, result);
128         if (result != expected) {
129             errln((UnicodeString)"expected '" + TestUtility::hex(expected) + "'\nbut got: '" + TestUtility::hex(result) + "'");
130         } else {
131             pp.setIndex(0);
132 //            formatter->parse(result, parseResult, pp);
133 //            if (parseResult.getDouble() != 123.0045) {
134 //                errln("expected 123.0045 but got: %g", parseResult.getDouble());
135 //            }
136         }
137     }
138     delete formatter;
139 }
140 
141 void
TestAPI()142 IntlTestRBNF::TestAPI() {
143   // This test goes through the APIs that were not tested before.
144   // These tests are too small to have separate test classes/functions
145 
146   UErrorCode status = U_ZERO_ERROR;
147   RuleBasedNumberFormat* formatter
148       = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
149   if (status == U_MISSING_RESOURCE_ERROR || status == U_FILE_ACCESS_ERROR) {
150     dataerrln("Unable to create formatter. - %s", u_errorName(status));
151     delete formatter;
152     return;
153   }
154 
155   logln("RBNF API test starting");
156   // test clone
157   {
158     logln("Testing Clone");
159     RuleBasedNumberFormat* rbnfClone = (RuleBasedNumberFormat *)formatter->clone();
160     if(rbnfClone != NULL) {
161       if(!(*rbnfClone == *formatter)) {
162         errln("Clone should be semantically equivalent to the original!");
163       }
164       delete rbnfClone;
165     } else {
166       errln("Cloning failed!");
167     }
168   }
169 
170   // test assignment
171   {
172     logln("Testing assignment operator");
173     RuleBasedNumberFormat assignResult(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
174     assignResult = *formatter;
175     if(!(assignResult == *formatter)) {
176       errln("Assignment result should be semantically equivalent to the original!");
177     }
178   }
179 
180   // test rule constructor
181   {
182     logln("Testing rule constructor");
183     LocalUResourceBundlePointer en(ures_open(U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf", "en", &status));
184     if(U_FAILURE(status)) {
185       errln("Unable to access resource bundle with data!");
186     } else {
187       int32_t ruleLen = 0;
188       int32_t len = 0;
189       LocalUResourceBundlePointer rbnfRules(ures_getByKey(en.getAlias(), "RBNFRules", NULL, &status));
190       LocalUResourceBundlePointer ruleSets(ures_getByKey(rbnfRules.getAlias(), "SpelloutRules", NULL, &status));
191       UnicodeString desc;
192       while (ures_hasNext(ruleSets.getAlias())) {
193            const UChar* currentString = ures_getNextString(ruleSets.getAlias(), &len, NULL, &status);
194            ruleLen += len;
195            desc.append(currentString);
196       }
197 
198       const UChar *spelloutRules = desc.getTerminatedBuffer();
199 
200       if(U_FAILURE(status) || ruleLen == 0 || spelloutRules == NULL) {
201         errln("Unable to access the rules string!");
202       } else {
203         UParseError perror;
204         RuleBasedNumberFormat ruleCtorResult(spelloutRules, Locale::getUS(), perror, status);
205         if(!(ruleCtorResult == *formatter)) {
206           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
207         }
208 
209         // Jitterbug 4452, for coverage
210         RuleBasedNumberFormat nf(spelloutRules, (UnicodeString)"", Locale::getUS(), perror, status);
211         if(!(nf == *formatter)) {
212           errln("Formatter constructed from the original rules should be semantically equivalent to the original!");
213         }
214       }
215     }
216   }
217 
218   // test getRules
219   {
220     logln("Testing getRules function");
221     UnicodeString rules = formatter->getRules();
222     UParseError perror;
223     RuleBasedNumberFormat fromRulesResult(rules, Locale::getUS(), perror, status);
224 
225     if(!(fromRulesResult == *formatter)) {
226       errln("Formatter constructed from rules obtained by getRules should be semantically equivalent to the original!");
227     }
228   }
229 
230 
231   {
232     logln("Testing copy constructor");
233     RuleBasedNumberFormat copyCtorResult(*formatter);
234     if(!(copyCtorResult == *formatter)) {
235       errln("Copy constructor result result should be semantically equivalent to the original!");
236     }
237   }
238 
239 #if !UCONFIG_NO_COLLATION
240   // test ruleset names
241   {
242     logln("Testing getNumberOfRuleSetNames, getRuleSetName and format using rule set names");
243     int32_t noOfRuleSetNames = formatter->getNumberOfRuleSetNames();
244     if(noOfRuleSetNames == 0) {
245       errln("Number of rule set names should be more than zero");
246     }
247     UnicodeString ruleSetName;
248     int32_t i = 0;
249     int32_t intFormatNum = 34567;
250     double doubleFormatNum = 893411.234;
251     logln("number of rule set names is %i", noOfRuleSetNames);
252     for(i = 0; i < noOfRuleSetNames; i++) {
253       FieldPosition pos1, pos2;
254       UnicodeString intFormatResult, doubleFormatResult;
255       Formattable intParseResult, doubleParseResult;
256 
257       ruleSetName = formatter->getRuleSetName(i);
258       log("Rule set name %i is ", i);
259       log(ruleSetName);
260       logln(". Format results are: ");
261       intFormatResult = formatter->format(intFormatNum, ruleSetName, intFormatResult, pos1, status);
262       doubleFormatResult = formatter->format(doubleFormatNum, ruleSetName, doubleFormatResult, pos2, status);
263       if(U_FAILURE(status)) {
264         errln("Format using a rule set failed");
265         break;
266       }
267       logln(intFormatResult);
268       logln(doubleFormatResult);
269       formatter->setLenient(TRUE);
270       formatter->parse(intFormatResult, intParseResult, status);
271       formatter->parse(doubleFormatResult, doubleParseResult, status);
272 
273       logln("Parse results for lenient = TRUE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
274 
275       formatter->setLenient(FALSE);
276       formatter->parse(intFormatResult, intParseResult, status);
277       formatter->parse(doubleFormatResult, doubleParseResult, status);
278 
279       logln("Parse results for lenient = FALSE, %i, %f", intParseResult.getLong(), doubleParseResult.getDouble());
280 
281       if(U_FAILURE(status)) {
282         errln("Error during parsing");
283       }
284 
285       intFormatResult = formatter->format(intFormatNum, "BLABLA", intFormatResult, pos1, status);
286       if(U_SUCCESS(status)) {
287         errln("Using invalid rule set name should have failed");
288         break;
289       }
290       status = U_ZERO_ERROR;
291       doubleFormatResult = formatter->format(doubleFormatNum, "TRUC", doubleFormatResult, pos2, status);
292       if(U_SUCCESS(status)) {
293         errln("Using invalid rule set name should have failed");
294         break;
295       }
296       status = U_ZERO_ERROR;
297     }
298     status = U_ZERO_ERROR;
299   }
300 #endif
301 
302   // test API
303   UnicodeString expected("four point five","");
304   logln("Testing format(double)");
305   UnicodeString result;
306   formatter->format(4.5,result);
307   if(result != expected) {
308       errln("Formatted 4.5, expected " + expected + " got " + result);
309   } else {
310       logln("Formatted 4.5, expected " + expected + " got " + result);
311   }
312   result.remove();
313   expected = "four";
314   formatter->format((int32_t)4,result);
315   if(result != expected) {
316       errln("Formatted 4, expected " + expected + " got " + result);
317   } else {
318       logln("Formatted 4, expected " + expected + " got " + result);
319   }
320 
321   result.remove();
322   FieldPosition pos;
323   formatter->format((int64_t)4, result, pos, status = U_ZERO_ERROR);
324   if(result != expected) {
325       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
326   } else {
327       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
328   }
329 
330   //Jitterbug 4452, for coverage
331   result.remove();
332   FieldPosition pos2;
333   formatter->format((int64_t)4, formatter->getRuleSetName(0), result, pos2, status = U_ZERO_ERROR);
334   if(result != expected) {
335       errln("Formatted 4 int64_t, expected " + expected + " got " + result);
336   } else {
337       logln("Formatted 4 int64_t, expected " + expected + " got " + result);
338   }
339 
340   // clean up
341   logln("Cleaning up");
342   delete formatter;
343 }
344 
TestFractionalRuleSet()345 void IntlTestRBNF::TestFractionalRuleSet()
346 {
347     UnicodeString fracRules(
348         "%main:\n"
349                // this rule formats the number if it's 1 or more.  It formats
350                // the integral part using a DecimalFormat ("#,##0" puts
351                // thousands separators in the right places) and the fractional
352                // part using %%frac.  If there is no fractional part, it
353                // just shows the integral part.
354         "    x.0: <#,##0<[ >%%frac>];\n"
355                // this rule formats the number if it's between 0 and 1.  It
356                // shows only the fractional part (0.5 shows up as "1/2," not
357                // "0 1/2")
358         "    0.x: >%%frac>;\n"
359         // the fraction rule set.  This works the same way as the one in the
360         // preceding example: We multiply the fractional part of the number
361         // being formatted by each rule's base value and use the rule that
362         // produces the result closest to 0 (or the first rule that produces 0).
363         // Since we only provide rules for the numbers from 2 to 10, we know
364         // we'll get a fraction with a denominator between 2 and 10.
365         // "<0<" causes the numerator of the fraction to be formatted
366         // using numerals
367         "%%frac:\n"
368         "    2: 1/2;\n"
369         "    3: <0</3;\n"
370         "    4: <0</4;\n"
371         "    5: <0</5;\n"
372         "    6: <0</6;\n"
373         "    7: <0</7;\n"
374         "    8: <0</8;\n"
375         "    9: <0</9;\n"
376         "   10: <0</10;\n");
377 
378     // mondo hack
379     int len = fracRules.length();
380     int change = 2;
381     for (int i = 0; i < len; ++i) {
382         UChar ch = fracRules.charAt(i);
383         if (ch == '\n') {
384             change = 2; // change ok
385         } else if (ch == ':') {
386             change = 1; // change, but once we hit a non-space char, don't change
387         } else if (ch == ' ') {
388             if (change != 0) {
389                 fracRules.setCharAt(i, (UChar)0x200e);
390             }
391         } else {
392             if (change == 1) {
393                 change = 0;
394             }
395         }
396     }
397 
398     UErrorCode status = U_ZERO_ERROR;
399     UParseError perror;
400     RuleBasedNumberFormat formatter(fracRules, Locale::getEnglish(), perror, status);
401     if (U_FAILURE(status)) {
402         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
403     } else {
404         static const char* const testData[][2] = {
405             { "0", "0" },
406             { ".1", "1/10" },
407             { ".11", "1/9" },
408             { ".125", "1/8" },
409             { ".1428", "1/7" },
410             { ".1667", "1/6" },
411             { ".2", "1/5" },
412             { ".25", "1/4" },
413             { ".333", "1/3" },
414             { ".5", "1/2" },
415             { "1.1", "1 1/10" },
416             { "2.11", "2 1/9" },
417             { "3.125", "3 1/8" },
418             { "4.1428", "4 1/7" },
419             { "5.1667", "5 1/6" },
420             { "6.2", "6 1/5" },
421             { "7.25", "7 1/4" },
422             { "8.333", "8 1/3" },
423             { "9.5", "9 1/2" },
424             { ".2222", "2/9" },
425             { ".4444", "4/9" },
426             { ".5555", "5/9" },
427             { "1.2856", "1 2/7" },
428             { NULL, NULL }
429         };
430        doTest(&formatter, testData, FALSE); // exact values aren't parsable from fractions
431     }
432 }
433 
434 #if 0
435 #define LLAssert(a) \
436   if (!(a)) errln("FAIL: " #a)
437 
438 void IntlTestRBNF::TestLLongConstructors()
439 {
440     logln("Testing constructors");
441 
442     // constant (shouldn't really be public)
443     LLAssert(llong(llong::kD32).asDouble() == llong::kD32);
444 
445     // internal constructor (shouldn't really be public)
446     LLAssert(llong(0, 1).asDouble() == 1);
447     LLAssert(llong(1, 0).asDouble() == llong::kD32);
448     LLAssert(llong((uint32_t)-1, (uint32_t)-1).asDouble() == -1);
449 
450     // public empty constructor
451     LLAssert(llong().asDouble() == 0);
452 
453     // public int32_t constructor
454     LLAssert(llong((int32_t)0).asInt() == (int32_t)0);
455     LLAssert(llong((int32_t)1).asInt() == (int32_t)1);
456     LLAssert(llong((int32_t)-1).asInt() == (int32_t)-1);
457     LLAssert(llong((int32_t)0x7fffffff).asInt() == (int32_t)0x7fffffff);
458     LLAssert(llong((int32_t)0xffffffff).asInt() == (int32_t)-1);
459     LLAssert(llong((int32_t)0x80000000).asInt() == (int32_t)0x80000000);
460 
461     // public int16_t constructor
462     LLAssert(llong((int16_t)0).asInt() == (int16_t)0);
463     LLAssert(llong((int16_t)1).asInt() == (int16_t)1);
464     LLAssert(llong((int16_t)-1).asInt() == (int16_t)-1);
465     LLAssert(llong((int16_t)0x7fff).asInt() == (int16_t)0x7fff);
466     LLAssert(llong((int16_t)0xffff).asInt() == (int16_t)0xffff);
467     LLAssert(llong((int16_t)0x8000).asInt() == (int16_t)0x8000);
468 
469     // public int8_t constructor
470     LLAssert(llong((int8_t)0).asInt() == (int8_t)0);
471     LLAssert(llong((int8_t)1).asInt() == (int8_t)1);
472     LLAssert(llong((int8_t)-1).asInt() == (int8_t)-1);
473     LLAssert(llong((int8_t)0x7f).asInt() == (int8_t)0x7f);
474     LLAssert(llong((int8_t)0xff).asInt() == (int8_t)0xff);
475     LLAssert(llong((int8_t)0x80).asInt() == (int8_t)0x80);
476 
477     // public uint16_t constructor
478     LLAssert(llong((uint16_t)0).asUInt() == (uint16_t)0);
479     LLAssert(llong((uint16_t)1).asUInt() == (uint16_t)1);
480     LLAssert(llong((uint16_t)-1).asUInt() == (uint16_t)-1);
481     LLAssert(llong((uint16_t)0x7fff).asUInt() == (uint16_t)0x7fff);
482     LLAssert(llong((uint16_t)0xffff).asUInt() == (uint16_t)0xffff);
483     LLAssert(llong((uint16_t)0x8000).asUInt() == (uint16_t)0x8000);
484 
485     // public uint32_t constructor
486     LLAssert(llong((uint32_t)0).asUInt() == (uint32_t)0);
487     LLAssert(llong((uint32_t)1).asUInt() == (uint32_t)1);
488     LLAssert(llong((uint32_t)-1).asUInt() == (uint32_t)-1);
489     LLAssert(llong((uint32_t)0x7fffffff).asUInt() == (uint32_t)0x7fffffff);
490     LLAssert(llong((uint32_t)0xffffffff).asUInt() == (uint32_t)-1);
491     LLAssert(llong((uint32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
492 
493     // public double constructor
494     LLAssert(llong((double)0).asDouble() == (double)0);
495     LLAssert(llong((double)1).asDouble() == (double)1);
496     LLAssert(llong((double)0x7fffffff).asDouble() == (double)0x7fffffff);
497     LLAssert(llong((double)0x80000000).asDouble() == (double)0x80000000);
498     LLAssert(llong((double)0x80000001).asDouble() == (double)0x80000001);
499 
500     // can't access uprv_maxmantissa, so fake it
501     double maxmantissa = (llong((int32_t)1) << 40).asDouble();
502     LLAssert(llong(maxmantissa).asDouble() == maxmantissa);
503     LLAssert(llong(-maxmantissa).asDouble() == -maxmantissa);
504 
505     // copy constructor
506     LLAssert(llong(llong(0, 1)).asDouble() == 1);
507     LLAssert(llong(llong(1, 0)).asDouble() == llong::kD32);
508     LLAssert(llong(llong(-1, (uint32_t)-1)).asDouble() == -1);
509 
510     // asInt - test unsigned to signed narrowing conversion
511     LLAssert(llong((uint32_t)-1).asInt() == (int32_t)0x7fffffff);
512     LLAssert(llong(-1, 0).asInt() == (int32_t)0x80000000);
513 
514     // asUInt - test signed to unsigned narrowing conversion
515     LLAssert(llong((int32_t)-1).asUInt() == (uint32_t)-1);
516     LLAssert(llong((int32_t)0x80000000).asUInt() == (uint32_t)0x80000000);
517 
518     // asDouble already tested
519 
520 }
521 
522 void IntlTestRBNF::TestLLongSimpleOperators()
523 {
524     logln("Testing simple operators");
525 
526     // operator==
527     LLAssert(llong() == llong(0, 0));
528     LLAssert(llong(1,0) == llong(1, 0));
529     LLAssert(llong(0,1) == llong(0, 1));
530 
531     // operator!=
532     LLAssert(llong(1,0) != llong(1,1));
533     LLAssert(llong(0,1) != llong(1,1));
534     LLAssert(llong(0xffffffff,0xffffffff) != llong(0x7fffffff, 0xffffffff));
535 
536     // unsigned >
537     LLAssert(llong((int32_t)-1).ugt(llong(0x7fffffff, 0xffffffff)));
538 
539     // unsigned <
540     LLAssert(llong(0x7fffffff, 0xffffffff).ult(llong((int32_t)-1)));
541 
542     // unsigned >=
543     LLAssert(llong((int32_t)-1).uge(llong(0x7fffffff, 0xffffffff)));
544     LLAssert(llong((int32_t)-1).uge(llong((int32_t)-1)));
545 
546     // unsigned <=
547     LLAssert(llong(0x7fffffff, 0xffffffff).ule(llong((int32_t)-1)));
548     LLAssert(llong((int32_t)-1).ule(llong((int32_t)-1)));
549 
550     // operator>
551     LLAssert(llong(1, 1) > llong(1, 0));
552     LLAssert(llong(0, 0x80000000) > llong(0, 0x7fffffff));
553     LLAssert(llong(0x80000000, 1) > llong(0x80000000, 0));
554     LLAssert(llong(1, 0) > llong(0, 0x7fffffff));
555     LLAssert(llong(1, 0) > llong(0, 0xffffffff));
556     LLAssert(llong(0, 0) > llong(0x80000000, 1));
557 
558     // operator<
559     LLAssert(llong(1, 0) < llong(1, 1));
560     LLAssert(llong(0, 0x7fffffff) < llong(0, 0x80000000));
561     LLAssert(llong(0x80000000, 0) < llong(0x80000000, 1));
562     LLAssert(llong(0, 0x7fffffff) < llong(1, 0));
563     LLAssert(llong(0, 0xffffffff) < llong(1, 0));
564     LLAssert(llong(0x80000000, 1) < llong(0, 0));
565 
566     // operator>=
567     LLAssert(llong(1, 1) >= llong(1, 0));
568     LLAssert(llong(0, 0x80000000) >= llong(0, 0x7fffffff));
569     LLAssert(llong(0x80000000, 1) >= llong(0x80000000, 0));
570     LLAssert(llong(1, 0) >= llong(0, 0x7fffffff));
571     LLAssert(llong(1, 0) >= llong(0, 0xffffffff));
572     LLAssert(llong(0, 0) >= llong(0x80000000, 1));
573     LLAssert(llong() >= llong(0, 0));
574     LLAssert(llong(1,0) >= llong(1, 0));
575     LLAssert(llong(0,1) >= llong(0, 1));
576 
577     // operator<=
578     LLAssert(llong(1, 0) <= llong(1, 1));
579     LLAssert(llong(0, 0x7fffffff) <= llong(0, 0x80000000));
580     LLAssert(llong(0x80000000, 0) <= llong(0x80000000, 1));
581     LLAssert(llong(0, 0x7fffffff) <= llong(1, 0));
582     LLAssert(llong(0, 0xffffffff) <= llong(1, 0));
583     LLAssert(llong(0x80000000, 1) <= llong(0, 0));
584     LLAssert(llong() <= llong(0, 0));
585     LLAssert(llong(1,0) <= llong(1, 0));
586     LLAssert(llong(0,1) <= llong(0, 1));
587 
588     // operator==(int32)
589     LLAssert(llong() == (int32_t)0);
590     LLAssert(llong(0,1) == (int32_t)1);
591 
592     // operator!=(int32)
593     LLAssert(llong(1,0) != (int32_t)0);
594     LLAssert(llong(0,1) != (int32_t)2);
595     LLAssert(llong(0,0xffffffff) != (int32_t)-1);
596 
597     llong negOne(0xffffffff, 0xffffffff);
598 
599     // operator>(int32)
600     LLAssert(llong(0, 0x80000000) > (int32_t)0x7fffffff);
601     LLAssert(negOne > (int32_t)-2);
602     LLAssert(llong(1, 0) > (int32_t)0x7fffffff);
603     LLAssert(llong(0, 0) > (int32_t)-1);
604 
605     // operator<(int32)
606     LLAssert(llong(0, 0x7ffffffe) < (int32_t)0x7fffffff);
607     LLAssert(llong(0xffffffff, 0xfffffffe) < (int32_t)-1);
608 
609     // operator>=(int32)
610     LLAssert(llong(0, 0x80000000) >= (int32_t)0x7fffffff);
611     LLAssert(negOne >= (int32_t)-2);
612     LLAssert(llong(1, 0) >= (int32_t)0x7fffffff);
613     LLAssert(llong(0, 0) >= (int32_t)-1);
614     LLAssert(llong() >= (int32_t)0);
615     LLAssert(llong(0,1) >= (int32_t)1);
616 
617     // operator<=(int32)
618     LLAssert(llong(0, 0x7ffffffe) <= (int32_t)0x7fffffff);
619     LLAssert(llong(0xffffffff, 0xfffffffe) <= (int32_t)-1);
620     LLAssert(llong() <= (int32_t)0);
621     LLAssert(llong(0,1) <= (int32_t)1);
622 
623     // operator=
624     LLAssert((llong(2,3) = llong((uint32_t)-1)).asUInt() == (uint32_t)-1);
625 
626     // operator <<=
627     LLAssert((llong(1, 1) <<= 0) ==  llong(1, 1));
628     LLAssert((llong(1, 1) <<= 31) == llong(0x80000000, 0x80000000));
629     LLAssert((llong(1, 1) <<= 32) == llong(1, 0));
630     LLAssert((llong(1, 1) <<= 63) == llong(0x80000000, 0));
631     LLAssert((llong(1, 1) <<= 64) == llong(1, 1)); // only lower 6 bits are used
632     LLAssert((llong(1, 1) <<= -1) == llong(0x80000000, 0)); // only lower 6 bits are used
633 
634     // operator <<
635     LLAssert((llong((int32_t)1) << 5).asUInt() == 32);
636 
637     // operator >>= (sign extended)
638     LLAssert((llong(0x7fffa0a0, 0xbcbcdfdf) >>= 16) == llong(0x7fff,0xa0a0bcbc));
639     LLAssert((llong(0x8000789a, 0xbcde0000) >>= 16) == llong(0xffff8000,0x789abcde));
640     LLAssert((llong(0x80000000, 0) >>= 63) == llong(0xffffffff, 0xffffffff));
641     LLAssert((llong(0x80000000, 0) >>= 47) == llong(0xffffffff, 0xffff0000));
642     LLAssert((llong(0x80000000, 0x80000000) >> 64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
643     LLAssert((llong(0x80000000, 0) >>= -1) == llong(0xffffffff, 0xffffffff)); // only lower 6 bits are used
644 
645     // operator >> sign extended)
646     LLAssert((llong(0x8000789a, 0xbcde0000) >> 16) == llong(0xffff8000,0x789abcde));
647 
648     // ushr (right shift without sign extension)
649     LLAssert(llong(0x7fffa0a0, 0xbcbcdfdf).ushr(16) == llong(0x7fff,0xa0a0bcbc));
650     LLAssert(llong(0x8000789a, 0xbcde0000).ushr(16) == llong(0x00008000,0x789abcde));
651     LLAssert(llong(0x80000000, 0).ushr(63) == llong(0, 1));
652     LLAssert(llong(0x80000000, 0).ushr(47) == llong(0, 0x10000));
653     LLAssert(llong(0x80000000, 0x80000000).ushr(64) == llong(0x80000000, 0x80000000)); // only lower 6 bits are used
654     LLAssert(llong(0x80000000, 0).ushr(-1) == llong(0, 1)); // only lower 6 bits are used
655 
656     // operator&(llong)
657     LLAssert((llong(0x55555555, 0x55555555) & llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
658 
659     // operator|(llong)
660     LLAssert((llong(0x55555555, 0x55555555) | llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
661 
662     // operator^(llong)
663     LLAssert((llong(0x55555555, 0x55555555) ^ llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
664 
665     // operator&(uint32)
666     LLAssert((llong(0x55555555, 0x55555555) & (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
667 
668     // operator|(uint32)
669     LLAssert((llong(0x55555555, 0x55555555) | (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
670 
671     // operator^(uint32)
672     LLAssert((llong(0x55555555, 0x55555555) ^ (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
673 
674     // operator~
675     LLAssert(~llong(0x55555555, 0x55555555) == llong(0xaaaaaaaa, 0xaaaaaaaa));
676 
677     // operator&=(llong)
678     LLAssert((llong(0x55555555, 0x55555555) &= llong(0xaaaaffff, 0xffffaaaa)) == llong(0x00005555, 0x55550000));
679 
680     // operator|=(llong)
681     LLAssert((llong(0x55555555, 0x55555555) |= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffffff, 0xffffffff));
682 
683     // operator^=(llong)
684     LLAssert((llong(0x55555555, 0x55555555) ^= llong(0xaaaaffff, 0xffffaaaa)) == llong(0xffffaaaa, 0xaaaaffff));
685 
686     // operator&=(uint32)
687     LLAssert((llong(0x55555555, 0x55555555) &= (uint32_t)0xffffaaaa) == llong(0, 0x55550000));
688 
689     // operator|=(uint32)
690     LLAssert((llong(0x55555555, 0x55555555) |= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xffffffff));
691 
692     // operator^=(uint32)
693     LLAssert((llong(0x55555555, 0x55555555) ^= (uint32_t)0xffffaaaa) == llong(0x55555555, 0xaaaaffff));
694 
695     // prefix inc
696     LLAssert(llong(1, 0) == ++llong(0,0xffffffff));
697 
698     // prefix dec
699     LLAssert(llong(0,0xffffffff) == --llong(1, 0));
700 
701     // postfix inc
702     {
703         llong n(0, 0xffffffff);
704         LLAssert(llong(0, 0xffffffff) == n++);
705         LLAssert(llong(1, 0) == n);
706     }
707 
708     // postfix dec
709     {
710         llong n(1, 0);
711         LLAssert(llong(1, 0) == n--);
712         LLAssert(llong(0, 0xffffffff) == n);
713     }
714 
715     // unary minus
716     LLAssert(llong(0, 0) == -llong(0, 0));
717     LLAssert(llong(0xffffffff, 0xffffffff) == -llong(0, 1));
718     LLAssert(llong(0, 1) == -llong(0xffffffff, 0xffffffff));
719     LLAssert(llong(0x7fffffff, 0xffffffff) == -llong(0x80000000, 1));
720     LLAssert(llong(0x80000000, 0) == -llong(0x80000000, 0)); // !!! we don't handle overflow
721 
722     // operator-=
723     {
724         llong n;
725         LLAssert((n -= llong(0, 1)) == llong(0xffffffff, 0xffffffff));
726         LLAssert(n == llong(0xffffffff, 0xffffffff));
727 
728         n = llong(1, 0);
729         LLAssert((n -= llong(0, 1)) == llong(0, 0xffffffff));
730         LLAssert(n == llong(0, 0xffffffff));
731     }
732 
733     // operator-
734     {
735         llong n;
736         LLAssert((n - llong(0, 1)) == llong(0xffffffff, 0xffffffff));
737         LLAssert(n == llong(0, 0));
738 
739         n = llong(1, 0);
740         LLAssert((n - llong(0, 1)) == llong(0, 0xffffffff));
741         LLAssert(n == llong(1, 0));
742     }
743 
744     // operator+=
745     {
746         llong n(0xffffffff, 0xffffffff);
747         LLAssert((n += llong(0, 1)) == llong(0, 0));
748         LLAssert(n == llong(0, 0));
749 
750         n = llong(0, 0xffffffff);
751         LLAssert((n += llong(0, 1)) == llong(1, 0));
752         LLAssert(n == llong(1, 0));
753     }
754 
755     // operator+
756     {
757         llong n(0xffffffff, 0xffffffff);
758         LLAssert((n + llong(0, 1)) == llong(0, 0));
759         LLAssert(n == llong(0xffffffff, 0xffffffff));
760 
761         n = llong(0, 0xffffffff);
762         LLAssert((n + llong(0, 1)) == llong(1, 0));
763         LLAssert(n == llong(0, 0xffffffff));
764     }
765 
766 }
767 
768 void IntlTestRBNF::TestLLong()
769 {
770     logln("Starting TestLLong");
771 
772     TestLLongConstructors();
773 
774     TestLLongSimpleOperators();
775 
776     logln("Testing operator*=, operator*");
777 
778     // operator*=, operator*
779     // small and large values, positive, &NEGative, zero
780     // also test commutivity
781     {
782         const llong ZERO;
783         const llong ONE(0, 1);
784         const llong NEG_ONE((int32_t)-1);
785         const llong THREE(0, 3);
786         const llong NEG_THREE((int32_t)-3);
787         const llong TWO_TO_16(0, 0x10000);
788         const llong NEG_TWO_TO_16 = -TWO_TO_16;
789         const llong TWO_TO_32(1, 0);
790         const llong NEG_TWO_TO_32 = -TWO_TO_32;
791 
792         const llong NINE(0, 9);
793         const llong NEG_NINE = -NINE;
794 
795         const llong TWO_TO_16X3(0, 0x00030000);
796         const llong NEG_TWO_TO_16X3 = -TWO_TO_16X3;
797 
798         const llong TWO_TO_32X3(3, 0);
799         const llong NEG_TWO_TO_32X3 = -TWO_TO_32X3;
800 
801         const llong TWO_TO_48(0x10000, 0);
802         const llong NEG_TWO_TO_48 = -TWO_TO_48;
803 
804         const int32_t VALUE_WIDTH = 9;
805         const llong* values[VALUE_WIDTH] = {
806             &ZERO, &ONE, &NEG_ONE, &THREE, &NEG_THREE, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32
807         };
808 
809         const llong* answers[VALUE_WIDTH*VALUE_WIDTH] = {
810             &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO, &ZERO,
811             &ZERO, &ONE,  &NEG_ONE, &THREE, &NEG_THREE,  &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_32, &NEG_TWO_TO_32,
812             &ZERO, &NEG_ONE, &ONE, &NEG_THREE, &THREE, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_32, &TWO_TO_32,
813             &ZERO, &THREE, &NEG_THREE, &NINE, &NEG_NINE, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32X3, &NEG_TWO_TO_32X3,
814             &ZERO, &NEG_THREE, &THREE, &NEG_NINE, &NINE, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32X3, &TWO_TO_32X3,
815             &ZERO, &TWO_TO_16, &NEG_TWO_TO_16, &TWO_TO_16X3, &NEG_TWO_TO_16X3, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_48, &NEG_TWO_TO_48,
816             &ZERO, &NEG_TWO_TO_16, &TWO_TO_16, &NEG_TWO_TO_16X3, &TWO_TO_16X3, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_48, &TWO_TO_48,
817             &ZERO, &TWO_TO_32, &NEG_TWO_TO_32, &TWO_TO_32X3, &NEG_TWO_TO_32X3, &TWO_TO_48, &NEG_TWO_TO_48, &ZERO, &ZERO,
818             &ZERO, &NEG_TWO_TO_32, &TWO_TO_32, &NEG_TWO_TO_32X3, &TWO_TO_32X3, &NEG_TWO_TO_48, &TWO_TO_48, &ZERO, &ZERO
819         };
820 
821         for (int i = 0; i < VALUE_WIDTH; ++i) {
822             for (int j = 0; j < VALUE_WIDTH; ++j) {
823                 llong lhs = *values[i];
824                 llong rhs = *values[j];
825                 llong ans = *answers[i*VALUE_WIDTH + j];
826 
827                 llong n = lhs;
828 
829                 LLAssert((n *= rhs) == ans);
830                 LLAssert(n == ans);
831 
832                 n = lhs;
833                 LLAssert((n * rhs) == ans);
834                 LLAssert(n == lhs);
835             }
836         }
837     }
838 
839     logln("Testing operator/=, operator/");
840     // operator/=, operator/
841     // test num = 0, div = 0, pos/neg, > 2^32, div > num
842     {
843         const llong ZERO;
844         const llong ONE(0, 1);
845         const llong NEG_ONE = -ONE;
846         const llong MAX(0x7fffffff, 0xffffffff);
847         const llong MIN(0x80000000, 0);
848         const llong TWO(0, 2);
849         const llong NEG_TWO = -TWO;
850         const llong FIVE(0, 5);
851         const llong NEG_FIVE = -FIVE;
852         const llong TWO_TO_32(1, 0);
853         const llong NEG_TWO_TO_32 = -TWO_TO_32;
854         const llong TWO_TO_32d5 = llong(TWO_TO_32.asDouble()/5.0);
855         const llong NEG_TWO_TO_32d5 = -TWO_TO_32d5;
856         const llong TWO_TO_32X5 = TWO_TO_32 * FIVE;
857         const llong NEG_TWO_TO_32X5 = -TWO_TO_32X5;
858 
859         const llong* tuples[] = { // lhs, rhs, ans
860             &ZERO, &ZERO, &ZERO,
861             &ONE, &ZERO,&MAX,
862             &NEG_ONE, &ZERO, &MIN,
863             &ONE, &ONE, &ONE,
864             &ONE, &NEG_ONE, &NEG_ONE,
865             &NEG_ONE, &ONE, &NEG_ONE,
866             &NEG_ONE, &NEG_ONE, &ONE,
867             &FIVE, &TWO, &TWO,
868             &FIVE, &NEG_TWO, &NEG_TWO,
869             &NEG_FIVE, &TWO, &NEG_TWO,
870             &NEG_FIVE, &NEG_TWO, &TWO,
871             &TWO, &FIVE, &ZERO,
872             &TWO, &NEG_FIVE, &ZERO,
873             &NEG_TWO, &FIVE, &ZERO,
874             &NEG_TWO, &NEG_FIVE, &ZERO,
875             &TWO_TO_32, &TWO_TO_32, &ONE,
876             &TWO_TO_32, &NEG_TWO_TO_32, &NEG_ONE,
877             &NEG_TWO_TO_32, &TWO_TO_32, &NEG_ONE,
878             &NEG_TWO_TO_32, &NEG_TWO_TO_32, &ONE,
879             &TWO_TO_32, &FIVE, &TWO_TO_32d5,
880             &TWO_TO_32, &NEG_FIVE, &NEG_TWO_TO_32d5,
881             &NEG_TWO_TO_32, &FIVE, &NEG_TWO_TO_32d5,
882             &NEG_TWO_TO_32, &NEG_FIVE, &TWO_TO_32d5,
883             &TWO_TO_32X5, &FIVE, &TWO_TO_32,
884             &TWO_TO_32X5, &NEG_FIVE, &NEG_TWO_TO_32,
885             &NEG_TWO_TO_32X5, &FIVE, &NEG_TWO_TO_32,
886             &NEG_TWO_TO_32X5, &NEG_FIVE, &TWO_TO_32,
887             &TWO_TO_32X5, &TWO_TO_32, &FIVE,
888             &TWO_TO_32X5, &NEG_TWO_TO_32, &NEG_FIVE,
889             &NEG_TWO_TO_32X5, &NEG_TWO_TO_32, &FIVE,
890             &NEG_TWO_TO_32X5, &TWO_TO_32, &NEG_FIVE
891         };
892         const int TUPLE_WIDTH = 3;
893         const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WIDTH;
894         for (int i = 0; i < TUPLE_COUNT; ++i) {
895             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
896             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
897             const llong ans = *tuples[i*TUPLE_WIDTH+2];
898 
899             llong n = lhs;
900             if (!((n /= rhs) == ans)) {
901                 errln("fail: (n /= rhs) == ans");
902             }
903             LLAssert(n == ans);
904 
905             n = lhs;
906             LLAssert((n / rhs) == ans);
907             LLAssert(n == lhs);
908         }
909     }
910 
911     logln("Testing operator%%=, operator%%");
912     //operator%=, operator%
913     {
914         const llong ZERO;
915         const llong ONE(0, 1);
916         const llong TWO(0, 2);
917         const llong THREE(0,3);
918         const llong FOUR(0, 4);
919         const llong FIVE(0, 5);
920         const llong SIX(0, 6);
921 
922         const llong NEG_ONE = -ONE;
923         const llong NEG_TWO = -TWO;
924         const llong NEG_THREE = -THREE;
925         const llong NEG_FOUR = -FOUR;
926         const llong NEG_FIVE = -FIVE;
927         const llong NEG_SIX = -SIX;
928 
929         const llong NINETY_NINE(0, 99);
930         const llong HUNDRED(0, 100);
931         const llong HUNDRED_ONE(0, 101);
932 
933         const llong BIG(0x12345678, 0x9abcdef0);
934         const llong BIG_FIVE(BIG * FIVE);
935         const llong BIG_FIVEm1 = BIG_FIVE - ONE;
936         const llong BIG_FIVEp1 = BIG_FIVE + ONE;
937 
938         const llong* tuples[] = {
939             &ZERO, &FIVE, &ZERO,
940             &ONE, &FIVE, &ONE,
941             &TWO, &FIVE, &TWO,
942             &THREE, &FIVE, &THREE,
943             &FOUR, &FIVE, &FOUR,
944             &FIVE, &FIVE, &ZERO,
945             &SIX, &FIVE, &ONE,
946             &ZERO, &NEG_FIVE, &ZERO,
947             &ONE, &NEG_FIVE, &ONE,
948             &TWO, &NEG_FIVE, &TWO,
949             &THREE, &NEG_FIVE, &THREE,
950             &FOUR, &NEG_FIVE, &FOUR,
951             &FIVE, &NEG_FIVE, &ZERO,
952             &SIX, &NEG_FIVE, &ONE,
953             &NEG_ONE, &FIVE, &NEG_ONE,
954             &NEG_TWO, &FIVE, &NEG_TWO,
955             &NEG_THREE, &FIVE, &NEG_THREE,
956             &NEG_FOUR, &FIVE, &NEG_FOUR,
957             &NEG_FIVE, &FIVE, &ZERO,
958             &NEG_SIX, &FIVE, &NEG_ONE,
959             &NEG_ONE, &NEG_FIVE, &NEG_ONE,
960             &NEG_TWO, &NEG_FIVE, &NEG_TWO,
961             &NEG_THREE, &NEG_FIVE, &NEG_THREE,
962             &NEG_FOUR, &NEG_FIVE, &NEG_FOUR,
963             &NEG_FIVE, &NEG_FIVE, &ZERO,
964             &NEG_SIX, &NEG_FIVE, &NEG_ONE,
965             &NINETY_NINE, &FIVE, &FOUR,
966             &HUNDRED, &FIVE, &ZERO,
967             &HUNDRED_ONE, &FIVE, &ONE,
968             &BIG_FIVEm1, &FIVE, &FOUR,
969             &BIG_FIVE, &FIVE, &ZERO,
970             &BIG_FIVEp1, &FIVE, &ONE
971         };
972         const int TUPLE_WIDTH = 3;
973         const int TUPLE_COUNT = (int)(sizeof(tuples)/sizeof(tuples[0]))/TUPLE_WIDTH;
974         for (int i = 0; i < TUPLE_COUNT; ++i) {
975             const llong lhs = *tuples[i*TUPLE_WIDTH+0];
976             const llong rhs = *tuples[i*TUPLE_WIDTH+1];
977             const llong ans = *tuples[i*TUPLE_WIDTH+2];
978 
979             llong n = lhs;
980             if (!((n %= rhs) == ans)) {
981                 errln("fail: (n %= rhs) == ans");
982             }
983             LLAssert(n == ans);
984 
985             n = lhs;
986             LLAssert((n % rhs) == ans);
987             LLAssert(n == lhs);
988         }
989     }
990 
991     logln("Testing pow");
992     // pow
993     LLAssert(llong(0, 0).pow(0) == llong(0, 0));
994     LLAssert(llong(0, 0).pow(2) == llong(0, 0));
995     LLAssert(llong(0, 2).pow(0) == llong(0, 1));
996     LLAssert(llong(0, 2).pow(2) == llong(0, 4));
997     LLAssert(llong(0, 2).pow(32) == llong(1, 0));
998     LLAssert(llong(0, 5).pow(10) == llong((double)5.0 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5));
999 
1000     // absolute value
1001     {
1002         const llong n(0xffffffff,0xffffffff);
1003         LLAssert(n.abs() == llong(0, 1));
1004     }
1005 
1006 #ifdef RBNF_DEBUG
1007     logln("Testing atoll");
1008     // atoll
1009     const char empty[] = "";
1010     const char zero[] = "0";
1011     const char neg_one[] = "-1";
1012     const char neg_12345[] = "-12345";
1013     const char big1[] = "123456789abcdef0";
1014     const char big2[] = "fFfFfFfFfFfFfFfF";
1015     LLAssert(llong::atoll(empty) == llong(0, 0));
1016     LLAssert(llong::atoll(zero) == llong(0, 0));
1017     LLAssert(llong::atoll(neg_one) == llong(0xffffffff, 0xffffffff));
1018     LLAssert(llong::atoll(neg_12345) == -llong(0, 12345));
1019     LLAssert(llong::atoll(big1, 16) == llong(0x12345678, 0x9abcdef0));
1020     LLAssert(llong::atoll(big2, 16) == llong(0xffffffff, 0xffffffff));
1021 #endif
1022 
1023     // u_atoll
1024     const UChar uempty[] = { 0 };
1025     const UChar uzero[] = { 0x30, 0 };
1026     const UChar uneg_one[] = { 0x2d, 0x31, 0 };
1027     const UChar uneg_12345[] = { 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0 };
1028     const UChar ubig1[] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x30, 0 };
1029     const UChar ubig2[] = { 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0x66, 0x46, 0 };
1030     LLAssert(llong::utoll(uempty) == llong(0, 0));
1031     LLAssert(llong::utoll(uzero) == llong(0, 0));
1032     LLAssert(llong::utoll(uneg_one) == llong(0xffffffff, 0xffffffff));
1033     LLAssert(llong::utoll(uneg_12345) == -llong(0, 12345));
1034     LLAssert(llong::utoll(ubig1, 16) == llong(0x12345678, 0x9abcdef0));
1035     LLAssert(llong::utoll(ubig2, 16) == llong(0xffffffff, 0xffffffff));
1036 
1037 #ifdef RBNF_DEBUG
1038     logln("Testing lltoa");
1039     // lltoa
1040     {
1041         char buf[64]; // ascii
1042         LLAssert((llong(0, 0).lltoa(buf, (uint32_t)sizeof(buf)) == 1) && (strcmp(buf, zero) == 0));
1043         LLAssert((llong(0xffffffff, 0xffffffff).lltoa(buf, (uint32_t)sizeof(buf)) == 2) && (strcmp(buf, neg_one) == 0));
1044         LLAssert(((-llong(0, 12345)).lltoa(buf, (uint32_t)sizeof(buf)) == 6) && (strcmp(buf, neg_12345) == 0));
1045         LLAssert((llong(0x12345678, 0x9abcdef0).lltoa(buf, (uint32_t)sizeof(buf), 16) == 16) && (strcmp(buf, big1) == 0));
1046     }
1047 #endif
1048 
1049     logln("Testing u_lltoa");
1050     // u_lltoa
1051     {
1052         UChar buf[64];
1053         LLAssert((llong(0, 0).lltou(buf, (uint32_t)sizeof(buf)) == 1) && (u_strcmp(buf, uzero) == 0));
1054         LLAssert((llong(0xffffffff, 0xffffffff).lltou(buf, (uint32_t)sizeof(buf)) == 2) && (u_strcmp(buf, uneg_one) == 0));
1055         LLAssert(((-llong(0, 12345)).lltou(buf, (uint32_t)sizeof(buf)) == 6) && (u_strcmp(buf, uneg_12345) == 0));
1056         LLAssert((llong(0x12345678, 0x9abcdef0).lltou(buf, (uint32_t)sizeof(buf), 16) == 16) && (u_strcmp(buf, ubig1) == 0));
1057     }
1058 }
1059 
1060 /* if 0 */
1061 #endif
1062 
1063 void
TestEnglishSpellout()1064 IntlTestRBNF::TestEnglishSpellout()
1065 {
1066     UErrorCode status = U_ZERO_ERROR;
1067     RuleBasedNumberFormat* formatter
1068         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getUS(), status);
1069     if (U_FAILURE(status)) {
1070         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1071     } else {
1072         static const char* const testData[][2] = {
1073             { "1", "one" },
1074             { "2", "two" },
1075             { "15", "fifteen" },
1076             { "20", "twenty" },
1077             { "23", "twenty-three" },
1078             { "73", "seventy-three" },
1079             { "88", "eighty-eight" },
1080             { "100", "one hundred" },
1081             { "106", "one hundred six" },
1082             { "127", "one hundred twenty-seven" },
1083             { "200", "two hundred" },
1084             { "579", "five hundred seventy-nine" },
1085             { "1,000", "one thousand" },
1086             { "2,000", "two thousand" },
1087             { "3,004", "three thousand four" },
1088             { "4,567", "four thousand five hundred sixty-seven" },
1089             { "15,943", "fifteen thousand nine hundred forty-three" },
1090             { "2,345,678", "two million three hundred forty-five thousand six hundred seventy-eight" },
1091             { "-36", "minus thirty-six" },
1092             { "234.567", "two hundred thirty-four point five six seven" },
1093             { NULL, NULL}
1094         };
1095 
1096         doTest(formatter, testData, TRUE);
1097 
1098 #if !UCONFIG_NO_COLLATION
1099         formatter->setLenient(TRUE);
1100         static const char* lpTestData[][2] = {
1101             { "fifty-7", "57" },
1102             { " fifty-7", "57" },
1103             { "  fifty-7", "57" },
1104             { "2 thousand six    HUNDRED fifty-7", "2,657" },
1105             { "fifteen hundred and zero", "1,500" },
1106             { "FOurhundred     thiRTY six", "436" },
1107             { NULL, NULL}
1108         };
1109         doLenientParseTest(formatter, lpTestData);
1110 #endif
1111     }
1112     delete formatter;
1113 }
1114 
1115 void
TestOrdinalAbbreviations()1116 IntlTestRBNF::TestOrdinalAbbreviations()
1117 {
1118     UErrorCode status = U_ZERO_ERROR;
1119     RuleBasedNumberFormat* formatter
1120         = new RuleBasedNumberFormat(URBNF_ORDINAL, Locale::getUS(), status);
1121 
1122     if (U_FAILURE(status)) {
1123         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1124     } else {
1125         static const char* const testData[][2] = {
1126             { "1", "1st" },
1127             { "2", "2nd" },
1128             { "3", "3rd" },
1129             { "4", "4th" },
1130             { "7", "7th" },
1131             { "10", "10th" },
1132             { "11", "11th" },
1133             { "13", "13th" },
1134             { "20", "20th" },
1135             { "21", "21st" },
1136             { "22", "22nd" },
1137             { "23", "23rd" },
1138             { "24", "24th" },
1139             { "33", "33rd" },
1140             { "102", "102nd" },
1141             { "312", "312th" },
1142             { "12,345", "12,345th" },
1143             { NULL, NULL}
1144         };
1145 
1146         doTest(formatter, testData, FALSE);
1147     }
1148     delete formatter;
1149 }
1150 
1151 void
TestDurations()1152 IntlTestRBNF::TestDurations()
1153 {
1154     UErrorCode status = U_ZERO_ERROR;
1155     RuleBasedNumberFormat* formatter
1156         = new RuleBasedNumberFormat(URBNF_DURATION, Locale::getUS(), status);
1157 
1158     if (U_FAILURE(status)) {
1159         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1160     } else {
1161         static const char* const testData[][2] = {
1162             { "3,600", "1:00:00" },     //move me and I fail
1163             { "0", "0 sec." },
1164             { "1", "1 sec." },
1165             { "24", "24 sec." },
1166             { "60", "1:00" },
1167             { "73", "1:13" },
1168             { "145", "2:25" },
1169             { "666", "11:06" },
1170             //            { "3,600", "1:00:00" },
1171             { "3,740", "1:02:20" },
1172             { "10,293", "2:51:33" },
1173             { NULL, NULL}
1174         };
1175 
1176         doTest(formatter, testData, TRUE);
1177 
1178 #if !UCONFIG_NO_COLLATION
1179         formatter->setLenient(TRUE);
1180         static const char* lpTestData[][2] = {
1181             { "2-51-33", "10,293" },
1182             { NULL, NULL}
1183         };
1184         doLenientParseTest(formatter, lpTestData);
1185 #endif
1186     }
1187     delete formatter;
1188 }
1189 
1190 void
TestSpanishSpellout()1191 IntlTestRBNF::TestSpanishSpellout()
1192 {
1193     UErrorCode status = U_ZERO_ERROR;
1194     RuleBasedNumberFormat* formatter
1195         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("es", "ES", ""), status);
1196 
1197     if (U_FAILURE(status)) {
1198         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1199     } else {
1200         static const char* const testData[][2] = {
1201             { "1", "uno" },
1202             { "6", "seis" },
1203             { "16", "diecis\\u00e9is" },
1204             { "20", "veinte" },
1205             { "24", "veinticuatro" },
1206             { "26", "veintis\\u00e9is" },
1207             { "73", "setenta y tres" },
1208             { "88", "ochenta y ocho" },
1209             { "100", "cien" },
1210             { "106", "ciento seis" },
1211             { "127", "ciento veintisiete" },
1212             { "200", "doscientos" },
1213             { "579", "quinientos setenta y nueve" },
1214             { "1,000", "mil" },
1215             { "2,000", "dos mil" },
1216             { "3,004", "tres mil cuatro" },
1217             { "4,567", "cuatro mil quinientos sesenta y siete" },
1218             { "15,943", "quince mil novecientos cuarenta y tres" },
1219             { "2,345,678", "dos millones trescientos cuarenta y cinco mil seiscientos setenta y ocho"},
1220             { "-36", "menos treinta y seis" },
1221             { "234.567", "doscientos treinta y cuatro coma cinco seis siete" },
1222             { NULL, NULL}
1223         };
1224 
1225         doTest(formatter, testData, TRUE);
1226     }
1227     delete formatter;
1228 }
1229 
1230 void
TestFrenchSpellout()1231 IntlTestRBNF::TestFrenchSpellout()
1232 {
1233     UErrorCode status = U_ZERO_ERROR;
1234     RuleBasedNumberFormat* formatter
1235         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getFrance(), status);
1236 
1237     if (U_FAILURE(status)) {
1238         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1239     } else {
1240         static const char* const testData[][2] = {
1241             { "1", "un" },
1242             { "15", "quinze" },
1243             { "20", "vingt" },
1244             { "21", "vingt-et-un" },
1245             { "23", "vingt-trois" },
1246             { "62", "soixante-deux" },
1247             { "70", "soixante-dix" },
1248             { "71", "soixante-et-onze" },
1249             { "73", "soixante-treize" },
1250             { "80", "quatre-vingts" },
1251             { "88", "quatre-vingt-huit" },
1252             { "100", "cent" },
1253             { "106", "cent-six" },
1254             { "127", "cent-vingt-sept" },
1255             { "200", "deux-cents" },
1256             { "579", "cinq-cent-soixante-dix-neuf" },
1257             { "1,000", "mille" },
1258             { "1,123", "mille-cent-vingt-trois" },
1259             { "1,594", "mille-cinq-cent-quatre-vingt-quatorze" },
1260             { "2,000", "deux-mille" },
1261             { "3,004", "trois-mille-quatre" },
1262             { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
1263             { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
1264             { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cent-soixante-dix-huit" },
1265             { "-36", "moins trente-six" },
1266             { "234.567", "deux-cent-trente-quatre virgule cinq six sept" },
1267             { NULL, NULL}
1268         };
1269 
1270         doTest(formatter, testData, TRUE);
1271 
1272 #if !UCONFIG_NO_COLLATION
1273         formatter->setLenient(TRUE);
1274         static const char* lpTestData[][2] = {
1275             { "trente-et-un", "31" },
1276             { "un cent quatre vingt dix huit", "198" },
1277             { NULL, NULL}
1278         };
1279         doLenientParseTest(formatter, lpTestData);
1280 #endif
1281     }
1282     delete formatter;
1283 }
1284 
1285 static const char* const swissFrenchTestData[][2] = {
1286     { "1", "un" },
1287     { "15", "quinze" },
1288     { "20", "vingt" },
1289     { "21", "vingt-et-un" },
1290     { "23", "vingt-trois" },
1291     { "62", "soixante-deux" },
1292     { "70", "septante" },
1293     { "71", "septante-et-un" },
1294     { "73", "septante-trois" },
1295     { "80", "huitante" },
1296     { "88", "huitante-huit" },
1297     { "100", "cent" },
1298     { "106", "cent-six" },
1299     { "127", "cent-vingt-sept" },
1300     { "200", "deux-cents" },
1301     { "579", "cinq-cent-septante-neuf" },
1302     { "1,000", "mille" },
1303     { "1,123", "mille-cent-vingt-trois" },
1304     { "1,594", "mille-cinq-cent-nonante-quatre" },
1305     { "2,000", "deux-mille" },
1306     { "3,004", "trois-mille-quatre" },
1307     { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
1308     { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
1309     { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cent-septante-huit" },
1310     { "-36", "moins trente-six" },
1311     { "234.567", "deux-cent-trente-quatre virgule cinq six sept" },
1312     { NULL, NULL}
1313 };
1314 
1315 void
TestSwissFrenchSpellout()1316 IntlTestRBNF::TestSwissFrenchSpellout()
1317 {
1318     UErrorCode status = U_ZERO_ERROR;
1319     RuleBasedNumberFormat* formatter
1320         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "CH", ""), status);
1321 
1322     if (U_FAILURE(status)) {
1323         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1324     } else {
1325         doTest(formatter, swissFrenchTestData, TRUE);
1326     }
1327     delete formatter;
1328 }
1329 
1330 static const char* const belgianFrenchTestData[][2] = {
1331     { "1", "un" },
1332     { "15", "quinze" },
1333     { "20", "vingt" },
1334     { "21", "vingt-et-un" },
1335     { "23", "vingt-trois" },
1336     { "62", "soixante-deux" },
1337     { "70", "septante" },
1338     { "71", "septante-et-un" },
1339     { "73", "septante-trois" },
1340     { "80", "quatre-vingts" },
1341     { "88", "quatre-vingt-huit" },
1342     { "90", "nonante" },
1343     { "91", "nonante-et-un" },
1344     { "95", "nonante-cinq" },
1345     { "100", "cent" },
1346     { "106", "cent-six" },
1347     { "127", "cent-vingt-sept" },
1348     { "200", "deux-cents" },
1349     { "579", "cinq-cent-septante-neuf" },
1350     { "1,000", "mille" },
1351     { "1,123", "mille-cent-vingt-trois" },
1352     { "1,594", "mille-cinq-cent-nonante-quatre" },
1353     { "2,000", "deux-mille" },
1354     { "3,004", "trois-mille-quatre" },
1355     { "4,567", "quatre-mille-cinq-cent-soixante-sept" },
1356     { "15,943", "quinze-mille-neuf-cent-quarante-trois" },
1357     { "2,345,678", "deux millions trois-cent-quarante-cinq-mille-six-cent-septante-huit" },
1358     { "-36", "moins trente-six" },
1359     { "234.567", "deux-cent-trente-quatre virgule cinq six sept" },
1360     { NULL, NULL}
1361 };
1362 
1363 
1364 void
TestBelgianFrenchSpellout()1365 IntlTestRBNF::TestBelgianFrenchSpellout()
1366 {
1367     UErrorCode status = U_ZERO_ERROR;
1368     RuleBasedNumberFormat* formatter
1369         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("fr", "BE", ""), status);
1370 
1371     if (U_FAILURE(status)) {
1372         errcheckln(status, "rbnf status: 0x%x (%s)\n", status, u_errorName(status));
1373         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1374     } else {
1375         // Belgian french should match Swiss french.
1376         doTest(formatter, belgianFrenchTestData, TRUE);
1377     }
1378     delete formatter;
1379 }
1380 
1381 void
TestItalianSpellout()1382 IntlTestRBNF::TestItalianSpellout()
1383 {
1384     UErrorCode status = U_ZERO_ERROR;
1385     RuleBasedNumberFormat* formatter
1386         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getItalian(), status);
1387 
1388     if (U_FAILURE(status)) {
1389         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1390     } else {
1391         static const char* const testData[][2] = {
1392             { "1", "uno" },
1393             { "15", "quindici" },
1394             { "20", "venti" },
1395             { "23", "venti\\u00ADtr\\u00E9" },
1396             { "73", "settanta\\u00ADtr\\u00E9" },
1397             { "88", "ottant\\u00ADotto" },
1398             { "100", "cento" },
1399             { "101", "cento\\u00ADuno" },
1400             { "103", "cento\\u00ADtr\\u00E9" },
1401             { "106", "cento\\u00ADsei" },
1402             { "108", "cent\\u00ADotto" },
1403             { "127", "cento\\u00ADventi\\u00ADsette" },
1404             { "181", "cent\\u00ADottant\\u00ADuno" },
1405             { "200", "due\\u00ADcento" },
1406             { "579", "cinque\\u00ADcento\\u00ADsettanta\\u00ADnove" },
1407             { "1,000", "mille" },
1408             { "2,000", "due\\u00ADmila" },
1409             { "3,004", "tre\\u00ADmila\\u00ADquattro" },
1410             { "4,567", "quattro\\u00ADmila\\u00ADcinque\\u00ADcento\\u00ADsessanta\\u00ADsette" },
1411             { "15,943", "quindici\\u00ADmila\\u00ADnove\\u00ADcento\\u00ADquaranta\\u00ADtr\\u00E9" },
1412             { "-36", "meno trenta\\u00ADsei" },
1413             { "234.567", "due\\u00ADcento\\u00ADtrenta\\u00ADquattro virgola cinque sei sette" },
1414             { NULL, NULL}
1415         };
1416 
1417         doTest(formatter, testData, TRUE);
1418     }
1419     delete formatter;
1420 }
1421 
1422 void
TestPortugueseSpellout()1423 IntlTestRBNF::TestPortugueseSpellout()
1424 {
1425     UErrorCode status = U_ZERO_ERROR;
1426     RuleBasedNumberFormat* formatter
1427         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("pt","BR",""), status);
1428 
1429     if (U_FAILURE(status)) {
1430         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1431     } else {
1432         static const char* const testData[][2] = {
1433             { "1", "um" },
1434             { "15", "quinze" },
1435             { "20", "vinte" },
1436             { "23", "vinte e tr\\u00EAs" },
1437             { "73", "setenta e tr\\u00EAs" },
1438             { "88", "oitenta e oito" },
1439             { "100", "cem" },
1440             { "106", "cento e seis" },
1441             { "108", "cento e oito" },
1442             { "127", "cento e vinte e sete" },
1443             { "181", "cento e oitenta e um" },
1444             { "200", "duzentos" },
1445             { "579", "quinhentos e setenta e nove" },
1446             { "1,000", "mil" },
1447             { "2,000", "dois mil" },
1448             { "3,004", "tr\\u00EAs mil e quatro" },
1449             { "4,567", "quatro mil e quinhentos e sessenta e sete" },
1450             { "15,943", "quinze mil e novecentos e quarenta e tr\\u00EAs" },
1451             { "-36", "menos trinta e seis" },
1452             { "234.567", "duzentos e trinta e quatro v\\u00EDrgula cinco seis sete" },
1453             { NULL, NULL}
1454         };
1455 
1456         doTest(formatter, testData, TRUE);
1457     }
1458     delete formatter;
1459 }
1460 void
TestGermanSpellout()1461 IntlTestRBNF::TestGermanSpellout()
1462 {
1463     UErrorCode status = U_ZERO_ERROR;
1464     RuleBasedNumberFormat* formatter
1465         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale::getGermany(), status);
1466 
1467     if (U_FAILURE(status)) {
1468         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1469     } else {
1470         static const char* const testData[][2] = {
1471             { "1", "eins" },
1472             { "15", "f\\u00fcnfzehn" },
1473             { "20", "zwanzig" },
1474             { "23", "drei\\u00ADund\\u00ADzwanzig" },
1475             { "73", "drei\\u00ADund\\u00ADsiebzig" },
1476             { "88", "acht\\u00ADund\\u00ADachtzig" },
1477             { "100", "ein\\u00ADhundert" },
1478             { "106", "ein\\u00ADhundert\\u00ADsechs" },
1479             { "127", "ein\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADzwanzig" },
1480             { "200", "zwei\\u00ADhundert" },
1481             { "579", "f\\u00fcnf\\u00ADhundert\\u00ADneun\\u00ADund\\u00ADsiebzig" },
1482             { "1,000", "ein\\u00ADtausend" },
1483             { "2,000", "zwei\\u00ADtausend" },
1484             { "3,004", "drei\\u00ADtausend\\u00ADvier" },
1485             { "4,567", "vier\\u00ADtausend\\u00ADf\\u00fcnf\\u00ADhundert\\u00ADsieben\\u00ADund\\u00ADsechzig" },
1486             { "15,943", "f\\u00fcnfzehn\\u00ADtausend\\u00ADneun\\u00ADhundert\\u00ADdrei\\u00ADund\\u00ADvierzig" },
1487             { "2,345,678", "zwei Millionen drei\\u00ADhundert\\u00ADf\\u00fcnf\\u00ADund\\u00ADvierzig\\u00ADtausend\\u00ADsechs\\u00ADhundert\\u00ADacht\\u00ADund\\u00ADsiebzig" },
1488             { NULL, NULL}
1489         };
1490 
1491         doTest(formatter, testData, TRUE);
1492 
1493 #if !UCONFIG_NO_COLLATION
1494         formatter->setLenient(TRUE);
1495         static const char* lpTestData[][2] = {
1496             { "ein Tausend sechs Hundert fuenfunddreissig", "1,635" },
1497             { NULL, NULL}
1498         };
1499         doLenientParseTest(formatter, lpTestData);
1500 #endif
1501     }
1502     delete formatter;
1503 }
1504 
1505 void
TestThaiSpellout()1506 IntlTestRBNF::TestThaiSpellout()
1507 {
1508     UErrorCode status = U_ZERO_ERROR;
1509     RuleBasedNumberFormat* formatter
1510         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("th"), status);
1511 
1512     if (U_FAILURE(status)) {
1513         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1514     } else {
1515         static const char* const testData[][2] = {
1516             { "0", "\\u0e28\\u0e39\\u0e19\\u0e22\\u0e4c" },
1517             { "1", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1518             { "10", "\\u0e2a\\u0e34\\u0e1a" },
1519             { "11", "\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1520             { "21", "\\u0e22\\u0e35\\u0e48\\u200b\\u0e2a\\u0e34\\u0e1a\\u200b\\u0e40\\u0e2d\\u0e47\\u0e14" },
1521             { "101", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e23\\u0e49\\u0e2d\\u0e22\\u200b\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07" },
1522             { "1.234", "\\u0e2b\\u0e19\\u0e36\\u0e48\\u0e07\\u200b\\u0e08\\u0e38\\u0e14\\u200b\\u0e2a\\u0e2d\\u0e07\\u0e2a\\u0e32\\u0e21\\u0e2a\\u0e35\\u0e48" },
1523             { NULL, NULL}
1524         };
1525 
1526         doTest(formatter, testData, TRUE);
1527     }
1528     delete formatter;
1529 }
1530 
1531 void
TestSwedishSpellout()1532 IntlTestRBNF::TestSwedishSpellout()
1533 {
1534     UErrorCode status = U_ZERO_ERROR;
1535     RuleBasedNumberFormat* formatter
1536         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("sv"), status);
1537 
1538     if (U_FAILURE(status)) {
1539         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1540     } else {
1541         static const char* testDataDefault[][2] = {
1542             { "101", "ett\\u00adhundra\\u00adett" },
1543             { "123", "ett\\u00adhundra\\u00adtjugo\\u00adtre" },
1544             { "1,001", "et\\u00adtusen ett" },
1545             { "1,100", "et\\u00adtusen ett\\u00adhundra" },
1546             { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1547             { "1,234", "et\\u00adtusen tv\\u00e5\\u00adhundra\\u00adtrettio\\u00adfyra" },
1548             { "10,001", "tio\\u00adtusen ett" },
1549             { "11,000", "elva\\u00adtusen" },
1550             { "12,000", "tolv\\u00adtusen" },
1551             { "20,000", "tjugo\\u00adtusen" },
1552             { "21,000", "tjugo\\u00adet\\u00adtusen" },
1553             { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1554             { "200,000", "tv\\u00e5\\u00adhundra\\u00adtusen" },
1555             { "201,000", "tv\\u00e5\\u00adhundra\\u00adet\\u00adtusen" },
1556             { "200,200", "tv\\u00e5\\u00adhundra\\u00adtusen tv\\u00e5\\u00adhundra" },
1557             { "2,002,000", "tv\\u00e5 miljoner tv\\u00e5\\u00adtusen" },
1558             { "12,345,678", "tolv miljoner tre\\u00adhundra\\u00adfyrtio\\u00adfem\\u00adtusen sex\\u00adhundra\\u00adsjuttio\\u00ad\\u00e5tta" },
1559             { "123,456.789", "ett\\u00adhundra\\u00adtjugo\\u00adtre\\u00adtusen fyra\\u00adhundra\\u00adfemtio\\u00adsex komma sju \\u00e5tta nio" },
1560             { "-12,345.678", "minus tolv\\u00adtusen tre\\u00adhundra\\u00adfyrtio\\u00adfem komma sex sju \\u00e5tta" },
1561             { NULL, NULL }
1562         };
1563         doTest(formatter, testDataDefault, TRUE);
1564 
1565           static const char* testDataNeutrum[][2] = {
1566               { "101", "ett\\u00adhundra\\u00adett" },
1567               { "1,001", "et\\u00adtusen ett" },
1568               { "1,101", "et\\u00adtusen ett\\u00adhundra\\u00adett" },
1569               { "10,001", "tio\\u00adtusen ett" },
1570               { "21,001", "tjugo\\u00adet\\u00adtusen ett" },
1571               { NULL, NULL }
1572           };
1573 
1574           formatter->setDefaultRuleSet("%spellout-cardinal-neuter", status);
1575           if (U_SUCCESS(status)) {
1576           logln("        testing spellout-cardinal-neuter rules");
1577           doTest(formatter, testDataNeutrum, TRUE);
1578           }
1579           else {
1580           errln("Can't test spellout-cardinal-neuter rules");
1581           }
1582 
1583         static const char* testDataYear[][2] = {
1584             { "101", "ett\\u00adhundra\\u00adett" },
1585             { "900", "nio\\u00adhundra" },
1586             { "1,001", "et\\u00adtusen ett" },
1587             { "1,100", "elva\\u00adhundra" },
1588             { "1,101", "elva\\u00adhundra\\u00adett" },
1589             { "1,234", "tolv\\u00adhundra\\u00adtrettio\\u00adfyra" },
1590             { "2,001", "tjugo\\u00adhundra\\u00adett" },
1591             { "10,001", "tio\\u00adtusen ett" },
1592             { NULL, NULL }
1593         };
1594 
1595         status = U_ZERO_ERROR;
1596         formatter->setDefaultRuleSet("%spellout-numbering-year", status);
1597         if (U_SUCCESS(status)) {
1598             logln("testing year rules");
1599             doTest(formatter, testDataYear, TRUE);
1600         }
1601         else {
1602             errln("Can't test year rules");
1603         }
1604 
1605     }
1606     delete formatter;
1607 }
1608 
1609 void
TestSmallValues()1610 IntlTestRBNF::TestSmallValues()
1611 {
1612     UErrorCode status = U_ZERO_ERROR;
1613     RuleBasedNumberFormat* formatter
1614         = new RuleBasedNumberFormat(URBNF_SPELLOUT, Locale("en_US"), status);
1615 
1616     if (U_FAILURE(status)) {
1617         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1618     } else {
1619         static const char* const testDataDefault[][2] = {
1620         { "0.001", "zero point zero zero one" },
1621         { "0.0001", "zero point zero zero zero one" },
1622         { "0.00001", "zero point zero zero zero zero one" },
1623         { "0.000001", "zero point zero zero zero zero zero one" },
1624         { "0.0000001", "zero point zero zero zero zero zero zero one" },
1625         { "0.00000001", "zero point zero zero zero zero zero zero zero one" },
1626         { "0.000000001", "zero point zero zero zero zero zero zero zero zero one" },
1627         { "0.0000000001", "zero point zero zero zero zero zero zero zero zero zero one" },
1628         { "0.00000000001", "zero point zero zero zero zero zero zero zero zero zero zero one" },
1629         { "0.000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero one" },
1630         { "0.0000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero one" },
1631         { "0.00000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1632         { "0.000000000000001", "zero point zero zero zero zero zero zero zero zero zero zero zero zero zero zero one" },
1633         { "10,000,000.001", "ten million point zero zero one" },
1634         { "10,000,000.0001", "ten million point zero zero zero one" },
1635         { "10,000,000.00001", "ten million point zero zero zero zero one" },
1636         { "10,000,000.000001", "ten million point zero zero zero zero zero one" },
1637         { "10,000,000.0000001", "ten million point zero zero zero zero zero zero one" },
1638 //        { "10,000,000.00000001", "ten million point zero zero zero zero zero zero zero one" },
1639 //        { "10,000,000.000000002", "ten million point zero zero zero zero zero zero zero zero two" },
1640         { "10,000,000", "ten million" },
1641 //        { "1,234,567,890.0987654", "one billion, two hundred and thirty-four million, five hundred and sixty-seven thousand, eight hundred and ninety point zero nine eight seven six five four" },
1642 //        { "123,456,789.9876543", "one hundred and twenty-three million, four hundred and fifty-six thousand, seven hundred and eighty-nine point nine eight seven six five four three" },
1643 //        { "12,345,678.87654321", "twelve million, three hundred and forty-five thousand, six hundred and seventy-eight point eight seven six five four three two one" },
1644         { "1,234,567.7654321", "one million two hundred thirty-four thousand five hundred sixty-seven point seven six five four three two one" },
1645         { "123,456.654321", "one hundred twenty-three thousand four hundred fifty-six point six five four three two one" },
1646         { "12,345.54321", "twelve thousand three hundred forty-five point five four three two one" },
1647         { "1,234.4321", "one thousand two hundred thirty-four point four three two one" },
1648         { "123.321", "one hundred twenty-three point three two one" },
1649         { "0.0000000011754944", "zero point zero zero zero zero zero zero zero zero one one seven five four nine four four" },
1650         { "0.000001175494351", "zero point zero zero zero zero zero one one seven five four nine four three five one" },
1651         { NULL, NULL }
1652         };
1653 
1654         doTest(formatter, testDataDefault, TRUE);
1655 
1656         delete formatter;
1657     }
1658 }
1659 
1660 void
TestLocalizations(void)1661 IntlTestRBNF::TestLocalizations(void)
1662 {
1663     int i;
1664     UnicodeString rules("%main:0:no;1:some;100:a lot;1000:tons;\n"
1665         "%other:0:nada;1:yah, some;100:plenty;1000:more'n you'll ever need");
1666 
1667     UErrorCode status = U_ZERO_ERROR;
1668     UParseError perror;
1669     RuleBasedNumberFormat formatter(rules, perror, status);
1670     if (U_FAILURE(status)) {
1671         errcheckln(status, "FAIL: could not construct formatter - %s", u_errorName(status));
1672     } else {
1673         {
1674             static const char* const testData[][2] = {
1675                 { "0", "nada" },
1676                 { "5", "yah, some" },
1677                 { "423", "plenty" },
1678                 { "12345", "more'n you'll ever need" },
1679                 { NULL, NULL }
1680             };
1681             doTest(&formatter, testData, FALSE);
1682         }
1683 
1684         {
1685             UnicodeString loc("<<%main, %other>,<en, Main, Other>,<fr, leMain, leOther>,<de, 'das Main', 'etwas anderes'>>");
1686             static const char* const testData[][2] = {
1687                 { "0", "no" },
1688                 { "5", "some" },
1689                 { "423", "a lot" },
1690                 { "12345", "tons" },
1691                 { NULL, NULL }
1692             };
1693             RuleBasedNumberFormat formatter0(rules, loc, perror, status);
1694             if (U_FAILURE(status)) {
1695                 errln("failed to build second formatter");
1696             } else {
1697                 doTest(&formatter0, testData, FALSE);
1698 
1699                 {
1700                 // exercise localization info
1701                     Locale locale0("en__VALLEY@turkey=gobblegobble");
1702                     Locale locale1("de_DE_FOO");
1703                     Locale locale2("ja_JP");
1704                     UnicodeString name = formatter0.getRuleSetName(0);
1705                     if ( formatter0.getRuleSetDisplayName(0, locale0) == "Main"
1706                       && formatter0.getRuleSetDisplayName(0, locale1) == "das Main"
1707                       && formatter0.getRuleSetDisplayName(0, locale2) == "%main"
1708                       && formatter0.getRuleSetDisplayName(name, locale0) == "Main"
1709                       && formatter0.getRuleSetDisplayName(name, locale1) == "das Main"
1710                       && formatter0.getRuleSetDisplayName(name, locale2) == "%main"){
1711                           logln("getRuleSetDisplayName tested");
1712                     }else {
1713                         errln("failed to getRuleSetDisplayName");
1714                     }
1715                 }
1716 
1717                 for (i = 0; i < formatter0.getNumberOfRuleSetDisplayNameLocales(); ++i) {
1718                     Locale locale = formatter0.getRuleSetDisplayNameLocale(i, status);
1719                     if (U_SUCCESS(status)) {
1720                         for (int j = 0; j < formatter0.getNumberOfRuleSetNames(); ++j) {
1721                             UnicodeString name = formatter0.getRuleSetName(j);
1722                             UnicodeString lname = formatter0.getRuleSetDisplayName(j, locale);
1723                             UnicodeString msg = locale.getName();
1724                             msg.append(": ");
1725                             msg.append(name);
1726                             msg.append(" = ");
1727                             msg.append(lname);
1728                             logln(msg);
1729                         }
1730                     }
1731                 }
1732             }
1733         }
1734 
1735         {
1736             static const char* goodLocs[] = {
1737                 "", // zero-length ok, same as providing no localization data
1738                 "<<>>", // no public rule sets ok
1739                 "<<%main>>", // no localizations ok
1740                 "<<%main,>,<en, Main,>>", // comma before close angle ok
1741                 "<<%main>,<en, ',<>\" '>>", // quotes everything until next quote
1742                 "<<%main>,<'en', \"it's ok\">>", // double quotes work too
1743                 "  \n <\n  <\n  %main\n  >\n  , \t <\t   en\t  ,  \tfoo \t\t > \n\n >  \n ", // Pattern_White_Space ok
1744            };
1745             int32_t goodLocsLen = sizeof(goodLocs)/sizeof(goodLocs[0]);
1746 
1747             static const char* badLocs[] = {
1748                 " ", // non-zero length
1749                 "<>", // empty array
1750                 "<", // unclosed outer array
1751                 "<<", // unclosed inner array
1752                 "<<,>>", // unexpected comma
1753                 "<<''>>", // empty string
1754                 "  x<<%main>>", // first non space char not open angle bracket
1755                 "<%main>", // missing inner array
1756                 "<<%main %other>>", // elements missing separating commma (spaces must be quoted)
1757                 "<<%main><en, Main>>", // arrays missing separating comma
1758                 "<<%main>,<en, main, foo>>", // too many elements in locale data
1759                 "<<%main>,<en>>", // too few elements in locale data
1760                 "<<<%main>>>", // unexpected open angle
1761                 "<<%main<>>>", // unexpected open angle
1762                 "<<%main, %other>,<en,,>>", // implicit empty strings
1763                 "<<%main>,<en,''>>", // empty string
1764                 "<<%main>, < en, '>>", // unterminated quote
1765                 "<<%main>, < en, \"<>>", // unterminated quote
1766                 "<<%main\">>", // quote in string
1767                 "<<%main'>>", // quote in string
1768                 "<<%main<>>", // open angle in string
1769                 "<<%main>> x", // extra non-space text at end
1770 
1771             };
1772             int32_t badLocsLen = sizeof(badLocs)/sizeof(badLocs[0]);
1773 
1774             for (i = 0; i < goodLocsLen; ++i) {
1775                 logln("[%d] '%s'", i, goodLocs[i]);
1776                 UErrorCode status = U_ZERO_ERROR;
1777                 UnicodeString loc(goodLocs[i]);
1778                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1779                 if (U_FAILURE(status)) {
1780                     errln("Failed parse of good localization string: '%s'", goodLocs[i]);
1781                 }
1782             }
1783 
1784             for (i = 0; i < badLocsLen; ++i) {
1785                 logln("[%d] '%s'", i, badLocs[i]);
1786                 UErrorCode status = U_ZERO_ERROR;
1787                 UnicodeString loc(badLocs[i]);
1788                 RuleBasedNumberFormat fmt(rules, loc, perror, status);
1789                 if (U_SUCCESS(status)) {
1790                     errln("Successful parse of bad localization string: '%s'", badLocs[i]);
1791                 }
1792             }
1793         }
1794     }
1795 }
1796 
1797 void
TestAllLocales()1798 IntlTestRBNF::TestAllLocales()
1799 {
1800     const char* names[] = {
1801         " (spellout) ",
1802         " (ordinal)  ",
1803         " (duration) "
1804     };
1805     double numbers[] = {45.678, 1, 2, 10, 11, 100, 110, 200, 1000, 1111, -1111};
1806 
1807     // RBNF parse is extremely slow when lenient option is enabled.
1808     // For non-exhaustive mode, we only test a few locales.
1809     const char* parseLocales[] = {"en_US", "nl_NL", "be", NULL};
1810 
1811 
1812     int32_t count = 0;
1813     const Locale* locales = Locale::getAvailableLocales(count);
1814     for (int i = 0; i < count; ++i) {
1815         const Locale* loc = &locales[i];
1816         UBool testParse = TRUE;
1817         if (quick) {
1818             testParse = FALSE;
1819             for (int k = 0; parseLocales[k] != NULL; k++) {
1820                 if (strcmp(loc->getLanguage(), parseLocales[k]) == 0) {
1821                     testParse = TRUE;
1822                     break;
1823                 }
1824             }
1825         }
1826 
1827         for (int j = 0; j < 3; ++j) {
1828             UErrorCode status = U_ZERO_ERROR;
1829             RuleBasedNumberFormat* f = new RuleBasedNumberFormat((URBNFRuleSetTag)j, *loc, status);
1830             if (U_FAILURE(status)) {
1831                 errln(UnicodeString(loc->getName()) + names[j]
1832                     + "ERROR could not instantiate -> " + u_errorName(status));
1833                 continue;
1834             }
1835 #if !UCONFIG_NO_COLLATION
1836             for (unsigned int numidx = 0; numidx < sizeof(numbers)/sizeof(double); numidx++) {
1837                 double n = numbers[numidx];
1838                 UnicodeString str;
1839                 f->format(n, str);
1840 
1841                 logln(UnicodeString(loc->getName()) + names[j]
1842                     + "success: " + n + " -> " + str);
1843 
1844                 if (testParse) {
1845                     // We do not validate the result in this test case,
1846                     // because there are cases which do not round trip by design.
1847                     Formattable num;
1848 
1849                     // regular parse
1850                     status = U_ZERO_ERROR;
1851                     f->setLenient(FALSE);
1852                     f->parse(str, num, status);
1853                     if (U_FAILURE(status)) {
1854                         //TODO: We need to fix parse problems - see #6895 / #6896
1855                         if (status == U_INVALID_FORMAT_ERROR) {
1856                             logln(UnicodeString(loc->getName()) + names[j]
1857                                 + "WARNING could not parse '" + str + "' -> " + u_errorName(status));
1858                         } else {
1859                              errln(UnicodeString(loc->getName()) + names[j]
1860                                 + "ERROR could not parse '" + str + "' -> " + u_errorName(status));
1861                        }
1862                     }
1863                     // lenient parse
1864                     status = U_ZERO_ERROR;
1865                     f->setLenient(TRUE);
1866                     f->parse(str, num, status);
1867                     if (U_FAILURE(status)) {
1868                         //TODO: We need to fix parse problems - see #6895 / #6896
1869                         if (status == U_INVALID_FORMAT_ERROR) {
1870                             logln(UnicodeString(loc->getName()) + names[j]
1871                                 + "WARNING could not parse(lenient) '" + str + "' -> " + u_errorName(status));
1872                         } else {
1873                             errln(UnicodeString(loc->getName()) + names[j]
1874                                 + "ERROR could not parse(lenient) '" + str + "' -> " + u_errorName(status));
1875                         }
1876                     }
1877                 }
1878             }
1879 #endif
1880             delete f;
1881         }
1882     }
1883 }
1884 
1885 void
TestMultiplierSubstitution(void)1886 IntlTestRBNF::TestMultiplierSubstitution(void) {
1887   UnicodeString rules("=#,##0=;1,000,000: <##0.###< million;");
1888   UErrorCode status = U_ZERO_ERROR;
1889   UParseError parse_error;
1890   RuleBasedNumberFormat *rbnf =
1891     new RuleBasedNumberFormat(rules, Locale::getUS(), parse_error, status);
1892   if (U_SUCCESS(status)) {
1893     UnicodeString res;
1894     FieldPosition pos;
1895     double n = 1234000.0;
1896     rbnf->format(n, res, pos);
1897     delete rbnf;
1898 
1899     UnicodeString expected = UNICODE_STRING_SIMPLE("1.234 million");
1900     if (expected != res) {
1901       UnicodeString msg = "Expected: ";
1902       msg.append(expected);
1903       msg.append(" but got ");
1904       msg.append(res);
1905       errln(msg);
1906     }
1907   }
1908 }
1909 
1910 void
TestSetDecimalFormatSymbols()1911 IntlTestRBNF::TestSetDecimalFormatSymbols() {
1912     UErrorCode status = U_ZERO_ERROR;
1913 
1914     RuleBasedNumberFormat rbnf(URBNF_ORDINAL, Locale::getEnglish(), status);
1915     if (U_FAILURE(status)) {
1916         dataerrln("Unable to create RuleBasedNumberFormat - " + UnicodeString(u_errorName(status)));
1917         return;
1918     }
1919 
1920     DecimalFormatSymbols dfs(Locale::getEnglish(), status);
1921     if (U_FAILURE(status)) {
1922         errln("Unable to create DecimalFormatSymbols - " + UnicodeString(u_errorName(status)));
1923         return;
1924     }
1925 
1926     UnicodeString expected[] = {
1927             UnicodeString("1,001st"),
1928             UnicodeString("1&001st")
1929     };
1930 
1931     double number = 1001;
1932 
1933     UnicodeString result;
1934 
1935     rbnf.format(number, result);
1936     if (result != expected[0]) {
1937         errln("Format Error - Got: " + result + " Expected: " + expected[0]);
1938     }
1939 
1940     result.remove();
1941 
1942     /* Set new symbol for testing */
1943     dfs.setSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol, UnicodeString("&"), TRUE);
1944     rbnf.setDecimalFormatSymbols(dfs);
1945 
1946     rbnf.format(number, result);
1947     if (result != expected[1]) {
1948         errln("Format Error - Got: " + result + " Expected: " + expected[1]);
1949     }
1950 }
1951 
1952 
1953 void
doTest(RuleBasedNumberFormat * formatter,const char * const testData[][2],UBool testParsing)1954 IntlTestRBNF::doTest(RuleBasedNumberFormat* formatter, const char* const testData[][2], UBool testParsing)
1955 {
1956   // man, error reporting would be easier with printf-style syntax for unicode string and formattable
1957 
1958     UErrorCode status = U_ZERO_ERROR;
1959     DecimalFormatSymbols dfs("en", status);
1960     // NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
1961     DecimalFormat decFmt("#,###.################", dfs, status);
1962     if (U_FAILURE(status)) {
1963         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
1964     } else {
1965         for (int i = 0; testData[i][0]; ++i) {
1966             const char* numString = testData[i][0];
1967             const char* expectedWords = testData[i][1];
1968 
1969             log("[%i] %s = ", i, numString);
1970             Formattable expectedNumber;
1971             decFmt.parse(numString, expectedNumber, status);
1972             if (U_FAILURE(status)) {
1973                 errln("FAIL: decFmt could not parse %s", numString);
1974                 break;
1975             } else {
1976                 UnicodeString actualString;
1977                 FieldPosition pos;
1978                 formatter->format(expectedNumber, actualString/* , pos*/, status);
1979                 if (U_FAILURE(status)) {
1980                     UnicodeString msg = "Fail: formatter could not format ";
1981                     decFmt.format(expectedNumber, msg, status);
1982                     errln(msg);
1983                     break;
1984                 } else {
1985                     UnicodeString expectedString = UnicodeString(expectedWords, -1, US_INV).unescape();
1986                     if (actualString != expectedString) {
1987                         UnicodeString msg = "FAIL: check failed for ";
1988                         decFmt.format(expectedNumber, msg, status);
1989                         msg.append(", expected ");
1990                         msg.append(expectedString);
1991                         msg.append(" but got ");
1992                         msg.append(actualString);
1993                         errln(msg);
1994                         break;
1995                     } else {
1996                         logln(actualString);
1997                         if (testParsing) {
1998                             Formattable parsedNumber;
1999                             formatter->parse(actualString, parsedNumber, status);
2000                             if (U_FAILURE(status)) {
2001                                 UnicodeString msg = "FAIL: formatter could not parse ";
2002                                 msg.append(actualString);
2003                                 msg.append(" status code: " );
2004                                 msg.append(u_errorName(status));
2005                                 errln(msg);
2006                                 break;
2007                             } else {
2008                                 if (parsedNumber != expectedNumber) {
2009                                     UnicodeString msg = "FAIL: parse failed for ";
2010                                     msg.append(actualString);
2011                                     msg.append(", expected ");
2012                                     decFmt.format(expectedNumber, msg, status);
2013                                     msg.append(", but got ");
2014                                     decFmt.format(parsedNumber, msg, status);
2015                                     errln(msg);
2016                                     break;
2017                                 }
2018                             }
2019                         }
2020                     }
2021                 }
2022             }
2023         }
2024     }
2025 }
2026 
2027 void
doLenientParseTest(RuleBasedNumberFormat * formatter,const char * testData[][2])2028 IntlTestRBNF::doLenientParseTest(RuleBasedNumberFormat* formatter, const char* testData[][2])
2029 {
2030     UErrorCode status = U_ZERO_ERROR;
2031     NumberFormat* decFmt = NumberFormat::createInstance(Locale::getUS(), status);
2032     if (U_FAILURE(status)) {
2033         errcheckln(status, "FAIL: could not create NumberFormat - %s", u_errorName(status));
2034     } else {
2035         for (int i = 0; testData[i][0]; ++i) {
2036             const char* spelledNumber = testData[i][0]; // spelled-out number
2037             const char* asciiUSNumber = testData[i][1]; // number as ascii digits formatted for US locale
2038 
2039             UnicodeString spelledNumberString = UnicodeString(spelledNumber).unescape();
2040             Formattable actualNumber;
2041             formatter->parse(spelledNumberString, actualNumber, status);
2042             if (U_FAILURE(status)) {
2043                 UnicodeString msg = "FAIL: formatter could not parse ";
2044                 msg.append(spelledNumberString);
2045                 errln(msg);
2046                 break;
2047             } else {
2048                 // I changed the logic of this test somewhat from Java-- instead of comparing the
2049                 // strings, I compare the Formattables.  Hmmm, but the Formattables don't compare,
2050                 // so change it back.
2051 
2052                 UnicodeString asciiUSNumberString = asciiUSNumber;
2053                 Formattable expectedNumber;
2054                 decFmt->parse(asciiUSNumberString, expectedNumber, status);
2055                 if (U_FAILURE(status)) {
2056                     UnicodeString msg = "FAIL: decFmt could not parse ";
2057                     msg.append(asciiUSNumberString);
2058                     errln(msg);
2059                     break;
2060                 } else {
2061                     UnicodeString actualNumberString;
2062                     UnicodeString expectedNumberString;
2063                     decFmt->format(actualNumber, actualNumberString, status);
2064                     decFmt->format(expectedNumber, expectedNumberString, status);
2065                     if (actualNumberString != expectedNumberString) {
2066                         UnicodeString msg = "FAIL: parsing";
2067                         msg.append(asciiUSNumberString);
2068                         msg.append("\n");
2069                         msg.append("  lenient parse failed for ");
2070                         msg.append(spelledNumberString);
2071                         msg.append(", expected ");
2072                         msg.append(expectedNumberString);
2073                         msg.append(", but got ");
2074                         msg.append(actualNumberString);
2075                         errln(msg);
2076                         break;
2077                     }
2078                 }
2079             }
2080         }
2081         delete decFmt;
2082     }
2083 }
2084 
2085 /* U_HAVE_RBNF */
2086 #else
2087 
2088 void
TestRBNFDisabled()2089 IntlTestRBNF::TestRBNFDisabled() {
2090     errln("*** RBNF currently disabled on this platform ***\n");
2091 }
2092 
2093 /* U_HAVE_RBNF */
2094 #endif
2095 
2096 #endif /* #if !UCONFIG_NO_FORMATTING */
2097