ICU-20577 Restore C MeasureFormat ability to adopt non-decimal number formatter (#789)
diff --git a/icu4c/source/i18n/measfmt.cpp b/icu4c/source/i18n/measfmt.cpp
index 7d9612d..1949f17 100644
--- a/icu4c/source/i18n/measfmt.cpp
+++ b/icu4c/source/i18n/measfmt.cpp
@@ -685,9 +685,19 @@
     }
     auto* df = dynamic_cast<const DecimalFormat*>(&nf);
     if (df == nullptr) {
-        // Don't know how to handle other types of NumberFormat
-        status = U_UNSUPPORTED_ERROR;
-        return appendTo;
+        // Handle other types of NumberFormat using the ICU 63 code, modified to
+        // get the unitPattern from LongNameHandler and handle fallback to OTHER.
+        UnicodeString formattedNumber;
+        StandardPlural::Form pluralForm = QuantityFormatter::selectPlural(
+                amtNumber, nf, **pluralRules, formattedNumber, pos, status);
+        UnicodeString pattern = number::impl::LongNameHandler::getUnitPattern(getLocale(status),
+                amtUnit, getUnitWidth(fWidth), pluralForm, status);
+        // The above  handles fallback from other widths to short, and from other plural forms to OTHER
+        if (U_FAILURE(status)) {
+            return appendTo;
+        }
+        SimpleFormatter formatter(pattern, 0, 1, status);
+        return QuantityFormatter::format(formatter, formattedNumber, appendTo, pos, status);
     }
     number::FormattedNumber result;
     if (auto* lnf = df->toNumberFormatter(status)) {
diff --git a/icu4c/source/i18n/number_longnames.cpp b/icu4c/source/i18n/number_longnames.cpp
index b790ffb..817aa0e 100644
--- a/icu4c/source/i18n/number_longnames.cpp
+++ b/icu4c/source/i18n/number_longnames.cpp
@@ -264,6 +264,26 @@
     return simpleFormats[DNAM_INDEX];
 }
 
+UnicodeString LongNameHandler::getUnitPattern(
+        const Locale& loc,
+        const MeasureUnit& unit,
+        UNumberUnitWidth width,
+        StandardPlural::Form pluralForm,
+        UErrorCode& status) {
+    if (U_FAILURE(status)) {
+        return ICU_Utility::makeBogusString();
+    }
+    UnicodeString simpleFormats[ARRAY_LENGTH];
+    getMeasureData(loc, unit, width, simpleFormats, status);
+    // The above already handles fallback from other widths to short
+    if (U_FAILURE(status)) {
+        return ICU_Utility::makeBogusString();
+    }
+    // Now handle fallback from other plural forms to OTHER
+    return (!(simpleFormats[pluralForm]).isBogus())? simpleFormats[pluralForm]:
+            simpleFormats[StandardPlural::Form::OTHER];
+}
+
 LongNameHandler* LongNameHandler::forCurrencyLongNames(const Locale &loc, const CurrencyUnit &currency,
                                                       const PluralRules *rules,
                                                       const MicroPropsGenerator *parent,
diff --git a/icu4c/source/i18n/number_longnames.h b/icu4c/source/i18n/number_longnames.h
index 38aca26..a19425a 100644
--- a/icu4c/source/i18n/number_longnames.h
+++ b/icu4c/source/i18n/number_longnames.h
@@ -22,6 +22,13 @@
         UNumberUnitWidth width,
         UErrorCode& status);
 
+    static UnicodeString getUnitPattern(
+        const Locale& loc,
+        const MeasureUnit& unit,
+        UNumberUnitWidth width,
+        StandardPlural::Form pluralForm,
+        UErrorCode& status);
+
     static LongNameHandler*
     forCurrencyLongNames(const Locale &loc, const CurrencyUnit &currency, const PluralRules *rules,
                          const MicroPropsGenerator *parent, UErrorCode &status);
diff --git a/icu4c/source/test/intltest/measfmttest.cpp b/icu4c/source/test/intltest/measfmttest.cpp
index c4d0064..cb53d83 100644
--- a/icu4c/source/test/intltest/measfmttest.cpp
+++ b/icu4c/source/test/intltest/measfmttest.cpp
@@ -28,6 +28,7 @@
 #include "charstr.h"
 #include "cstr.h"
 #include "unicode/reldatefmt.h"
+#include "unicode/rbnf.h"
 
 struct ExpectedResult {
     const Measure *measures;
@@ -1699,6 +1700,10 @@
 
 void MeasureFormatTest::TestFormatPeriodEn() {
     UErrorCode status = U_ZERO_ERROR;
+    Measure t_1y[] = {Measure((double)1, MeasureUnit::createYear(status), status)};
+    Measure t_5M[] = {Measure((double)5, MeasureUnit::createMonth(status), status)};
+    Measure t_4d[] = {Measure((double)4, MeasureUnit::createDay(status), status)};
+    Measure t_2h[] = {Measure((double)2, MeasureUnit::createHour(status), status)};
     Measure t_19m[] = {Measure((double)19, MeasureUnit::createMinute(status), status)};
     Measure t_1h_23_5s[] = {
             Measure((double)1.0, MeasureUnit::createHour(status), status),
@@ -1867,6 +1872,20 @@
             {t_6h_56_92m, UPRV_LENGTHOF(t_6h_56_92m), "6:56.92"},
             {t_3h_5h, UPRV_LENGTHOF(t_3h_5h), "3 \\u0998\\u0983, 5 \\u0998\\u0983"}};
 
+    ExpectedResult fullDataSpellout[] = {
+            {t_1y, UPRV_LENGTHOF(t_1y), "one year"},
+            {t_5M, UPRV_LENGTHOF(t_5M), "five months"},
+            {t_4d, UPRV_LENGTHOF(t_4d), "four days"},
+            {t_2h, UPRV_LENGTHOF(t_2h), "two hours"},
+            {t_19m, UPRV_LENGTHOF(t_19m), "nineteen minutes"}};
+
+    ExpectedResult fullDataSpelloutFr[] = {
+            {t_1y, UPRV_LENGTHOF(t_1y), "un\\u00A0an"},
+            {t_5M, UPRV_LENGTHOF(t_5M), "cinq\\u00A0mois"},
+            {t_4d, UPRV_LENGTHOF(t_4d), "quatre\\u00A0jours"},
+            {t_2h, UPRV_LENGTHOF(t_2h), "deux\\u00A0heures"},
+            {t_19m, UPRV_LENGTHOF(t_19m), "dix-neuf minutes"}};
+
     Locale en(Locale::getEnglish());
     LocalPointer<NumberFormat> nf(NumberFormat::createInstance(en, status));
     if (U_FAILURE(status)) {
@@ -1947,6 +1966,30 @@
         return;
     }
     verifyFormat("bn-u-nu-latn NUMERIC", mf, numericDataBnLatn, UPRV_LENGTHOF(numericDataBnLatn));
+
+    status = U_ZERO_ERROR;
+    LocalPointer<RuleBasedNumberFormat> rbnf(new RuleBasedNumberFormat(URBNF_SPELLOUT, en, status));
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating rbnf en object - %s", u_errorName(status));
+        return;
+    }
+    mf = MeasureFormat(en, UMEASFMT_WIDTH_WIDE, rbnf->clone(), status);
+    if (!assertSuccess("Error creating measure format en WIDE with rbnf", status)) {
+        return;
+    }
+    verifyFormat("en WIDE rbnf", mf, fullDataSpellout, UPRV_LENGTHOF(fullDataSpellout));
+
+    Locale fr(Locale::getFrench());
+    LocalPointer<RuleBasedNumberFormat> rbnffr(new RuleBasedNumberFormat(URBNF_SPELLOUT, fr, status));
+    if (U_FAILURE(status)) {
+        dataerrln("Error creating rbnf fr object - %s", u_errorName(status));
+        return;
+    }
+    mf = MeasureFormat(fr, UMEASFMT_WIDTH_WIDE, rbnffr->clone(), status);
+    if (!assertSuccess("Error creating measure format fr WIDE with rbnf", status)) {
+        return;
+    }
+    verifyFormat("fr WIDE rbnf", mf, fullDataSpelloutFr, UPRV_LENGTHOF(fullDataSpellout));
 }
 
 void MeasureFormatTest::Test10219FractionalPlurals() {