+static void TestParseZero(void)
+{
+ UErrorCode errorCode = U_ZERO_ERROR;
+ UChar input[] = {'0', 0}; /* Input text is decimal '0' */
+ UChar pat[] = {'#', ';', '#', 0};
+ double dbl;
+
+#if 0
+ UNumberFormat* unum = unum_open( UNUM_DECIMAL /*or UNUM_DEFAULT*/, NULL, -1, NULL, NULL, &errorCode);
+#else
+ UNumberFormat* unum = unum_open( UNUM_PATTERN_DECIMAL /*needs pattern*/, pat, -1, NULL, NULL, &errorCode);
+#endif
+
+ dbl = unum_parseDouble( unum, input, -1 /*u_strlen(input)*/, 0 /* 0 = start */, &errorCode );
+ if (U_FAILURE(errorCode)) {
+ log_err("Result: %s\n", u_errorName(errorCode));
+ } else {
+ log_verbose("Double: %f\n", dbl);
+ }
+}
+
+typedef struct {
+ const char * testname;
+ const char * locale;
+ UBool lenient;
+ const UChar * source;
+ int32_t startPos;
+ int32_t value;
+ int32_t endPos;
+ UErrorCode status;
+} NumParseTestItem;
+
+static const UChar ustr_zh50d[] = {0x4E94, 0x3007, 0}; /* decimal 50 */
+static const UChar ustr_zh05a[] = {0x96F6, 0x4E94, 0}; /* decimal-alt 05 */
+static const UChar ustr_zh05d[] = {0x3007, 0x4E94, 0}; /* decimal 05 */
+
+static const NumParseTestItem altnumParseTests[] = {
+ /* name loc lenent src start val end status */
+ { "zh@hd,50dL","zh@numbers=hanidec", TRUE, ustr_zh50d, 0, 50, 2, U_ZERO_ERROR },
+ { "zh@hd,05aL","zh@numbers=hanidec", TRUE, ustr_zh05a, 0, 5, 2, U_ZERO_ERROR },
+ { "zh@hd,05dL","zh@numbers=hanidec", TRUE, ustr_zh05d, 0, 5, 2, U_ZERO_ERROR },
+ { NULL, NULL, FALSE, NULL, 0, 0, 0, 0 } /* terminator */
+};
+
+static void TestParseAltNum(void)
+{
+ const NumParseTestItem * testPtr;
+ for (testPtr = altnumParseTests; testPtr->testname != NULL; ++testPtr) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t value, position = testPtr->startPos;
+ UNumberFormat *nf = unum_open(UNUM_DECIMAL, NULL, 0, testPtr->locale, NULL, &status);
+ if (U_FAILURE(status)) {
+ log_err_status(status, "unum_open fails for UNUM_DECIMAL with locale %s, status %s\n", testPtr->locale, myErrorName(status));
+ continue;
+ }
+ unum_setAttribute(nf, UNUM_LENIENT_PARSE, testPtr->lenient);
+ value = unum_parse(nf, testPtr->source, -1, &position, &status);
+ if ( value != testPtr->value || position != testPtr->endPos || status != testPtr->status ) {
+ log_err("unum_parse DECIMAL, locale %s, testname %s, startPos %d: for value / endPos / status, expected %d / %d / %s, got %d / %d / %s\n",
+ testPtr->locale, testPtr->testname, testPtr->startPos,
+ testPtr->value, testPtr->endPos, myErrorName(testPtr->status),
+ value, position, myErrorName(status) );
+ }
+ unum_close(nf);
+ }
+}
+
+static const UChar ustr_en0[] = {0x7A, 0x65, 0x72, 0x6F, 0}; /* zero */
+static const UChar ustr_123[] = {0x31, 0x32, 0x33, 0}; /* 123 */
+static const UChar ustr_en123[] = {0x6f, 0x6e, 0x65, 0x20, 0x68, 0x75, 0x6e, 0x64, 0x72, 0x65, 0x64,
+ 0x20, 0x74, 0x77, 0x65, 0x6e, 0x74, 0x79,
+ 0x2d, 0x74, 0x68, 0x72, 0x65, 0x65, 0}; /* one hundred twenty-three */
+static const UChar ustr_fr123[] = {0x63, 0x65, 0x6e, 0x74, 0x2d, 0x76, 0x69, 0x6e, 0x67, 0x74, 0x2d,
+ 0x74, 0x72, 0x6f, 0x69, 0x73, 0}; /* cent-vingt-trois */
+static const UChar ustr_ja123[] = {0x767e, 0x4e8c, 0x5341, 0x4e09, 0}; /* kanji 100(+)2(*)10(+)3 */
+static const UChar ustr_zh50s[] = {0x4E94, 0x5341, 0}; /* spellout 50 */
+//static const UChar ustr_zh50d[] = [reuse from above] /* decimal 50 */
+//static const UChar ustr_zh05a[] = [reuse from above] /* decimal-alt 05 */
+//static const UChar ustr_zh05d[] = [reuse from above] /* decimal 05 */
+
+#define NUMERIC_STRINGS_NOT_PARSEABLE 1 // ticket/8224
+
+static const NumParseTestItem spelloutParseTests[] = {
+ /* name loc lenent src start val end status */
+ { "en0", "en", FALSE, ustr_en0, 0, 0, 4, U_ZERO_ERROR },
+ { "en0", "en", FALSE, ustr_en0, 2, 0, 2, U_PARSE_ERROR },
+ { "en0", "ja", FALSE, ustr_en0, 0, 0, 0, U_PARSE_ERROR },
+#if NUMERIC_STRINGS_NOT_PARSEABLE
+ { "123", "en", FALSE, ustr_123, 0, 0, 0, U_PARSE_ERROR },
+#else
+ { "123", "en", FALSE, ustr_123, 0, 123, 3, U_ZERO_ERROR },
+#endif
+ { "123L", "en", TRUE, ustr_123, 0, 123, 3, U_ZERO_ERROR },
+ { "en123", "en", FALSE, ustr_en123, 0, 123, 24, U_ZERO_ERROR },
+ { "en123", "en", FALSE, ustr_en123, 12, 23, 24, U_ZERO_ERROR },
+ { "en123", "fr", FALSE, ustr_en123, 16, 0, 16, U_PARSE_ERROR },
+ { "fr123", "fr", FALSE, ustr_fr123, 0, 123, 16, U_ZERO_ERROR },
+ { "fr123", "fr", FALSE, ustr_fr123, 5, 23, 16, U_ZERO_ERROR },
+ { "fr123", "en", FALSE, ustr_fr123, 0, 0, 0, U_PARSE_ERROR },
+ { "ja123", "ja", FALSE, ustr_ja123, 0, 123, 4, U_ZERO_ERROR },
+ { "ja123", "ja", FALSE, ustr_ja123, 1, 23, 4, U_ZERO_ERROR },
+ { "ja123", "fr", FALSE, ustr_ja123, 0, 0, 0, U_PARSE_ERROR },
+ { "zh,50s", "zh", FALSE, ustr_zh50s, 0, 50, 2, U_ZERO_ERROR },
+#if NUMERIC_STRINGS_NOT_PARSEABLE
+ { "zh@hd,50d", "zh@numbers=hanidec", FALSE, ustr_zh50d, 0, 5, 1, U_ZERO_ERROR },
+ { "zh@hd,05a", "zh@numbers=hanidec", FALSE, ustr_zh05a, 0, 0, 1, U_ZERO_ERROR },
+ { "zh@hd,05d", "zh@numbers=hanidec", FALSE, ustr_zh05d, 0, 0, 1, U_ZERO_ERROR },
+#else
+ { "zh@hd,50d", "zh@numbers=hanidec", FALSE, ustr_zh50d, 0, 50, 2, U_ZERO_ERROR },
+ { "zh@hd,05a", "zh@numbers=hanidec", FALSE, ustr_zh05a, 0, 5, 2, U_ZERO_ERROR },
+ { "zh@hd,05d", "zh@numbers=hanidec", FALSE, ustr_zh05d, 0, 5, 2, U_ZERO_ERROR },
+#endif
+ { "zh@hd,50dL","zh@numbers=hanidec", TRUE, ustr_zh50d, 0, 50, 2, U_ZERO_ERROR },
+ { "zh@hd,05aL","zh@numbers=hanidec", TRUE, ustr_zh05a, 0, 5, 2, U_ZERO_ERROR },
+ { "zh@hd,05dL","zh@numbers=hanidec", TRUE, ustr_zh05d, 0, 5, 2, U_ZERO_ERROR },
+ { "zh,50dL","zh", TRUE, ustr_zh50d, 0, 5, 1, U_ZERO_ERROR },
+ { "zh,05aL","zh", TRUE, ustr_zh05a, 0, 0, 1, U_ZERO_ERROR },
+ { "zh,05dL","zh", TRUE, ustr_zh05d, 0, 0, 1, U_ZERO_ERROR },
+ { NULL, NULL, FALSE, NULL, 0, 0, 0, 0 } /* terminator */
+};
+
+static void TestSpelloutNumberParse()
+{
+ const NumParseTestItem * testPtr;
+ for (testPtr = spelloutParseTests; testPtr->testname != NULL; ++testPtr) {
+ UErrorCode status = U_ZERO_ERROR;
+ int32_t value, position = testPtr->startPos;
+ UNumberFormat *nf = unum_open(UNUM_SPELLOUT, NULL, 0, testPtr->locale, NULL, &status);
+ if (U_FAILURE(status)) {
+ log_err_status(status, "unum_open fails for UNUM_SPELLOUT with locale %s, status %s\n", testPtr->locale, myErrorName(status));
+ continue;
+ }
+ unum_setAttribute(nf, UNUM_LENIENT_PARSE, testPtr->lenient);
+ value = unum_parse(nf, testPtr->source, -1, &position, &status);
+ if ( value != testPtr->value || position != testPtr->endPos || status != testPtr->status ) {
+ log_err("unum_parse SPELLOUT, locale %s, testname %s, startPos %d: for value / endPos / status, expected %d / %d / %s, got %d / %d / %s\n",
+ testPtr->locale, testPtr->testname, testPtr->startPos,
+ testPtr->value, testPtr->endPos, myErrorName(testPtr->status),
+ value, position, myErrorName(status) );
+ }
+ unum_close(nf);
+ }
+}
+