}
UDateFormatHourCycle
-DateTimePatternGenerator::getDefaultHourCycle(UErrorCode& /*status*/) const {
- switch(fDefaultHourFormatChar) {
- case CAP_K:
- return UDAT_HOUR_CYCLE_11;
- case LOW_H:
- return UDAT_HOUR_CYCLE_12;
- case CAP_H:
- return UDAT_HOUR_CYCLE_23;
- case LOW_K:
- return UDAT_HOUR_CYCLE_24;
- default:
- UPRV_UNREACHABLE;
- }
+DateTimePatternGenerator::getDefaultHourCycle(UErrorCode& status) const {
+ if (U_FAILURE(status)) {
+ return UDAT_HOUR_CYCLE_23;
+ }
+ if (fDefaultHourFormatChar == 0) {
+ // We need to return something, but the caller should ignore it
+ // anyways since the returned status is a failure.
+ status = U_UNSUPPORTED_ERROR;
+ return UDAT_HOUR_CYCLE_23;
+ }
+ switch (fDefaultHourFormatChar) {
+ case CAP_K:
+ return UDAT_HOUR_CYCLE_11;
+ case LOW_H:
+ return UDAT_HOUR_CYCLE_12;
+ case CAP_H:
+ return UDAT_HOUR_CYCLE_23;
+ case LOW_K:
+ return UDAT_HOUR_CYCLE_24;
+ default:
+ UPRV_UNREACHABLE;
+ }
}
UnicodeString
#ifndef U_HIDE_DRAFT_API
/**
- * Get the default hour cycle.
- * @param status Output param set to success/failure code on exit,
- * which must not indicate a failure before the function call.
+ * Get the default hour cycle for a locale. Uses the locale that the
+ * DateTimePatternGenerator was initially created with.
+ *
+ * Cannot be used on an empty DateTimePatternGenerator instance.
+ *
+ * @param status Output param set to success/failure code on exit, which
+ * which must not indicate a failure before the function call.
+ * Set to U_UNSUPPORTED_ERROR if used on an empty instance.
* @return the default hour cycle.
* @draft ICU 67
*/
#ifndef U_HIDE_DRAFT_API
/**
- * Return the default hour cycle.
- *
+ * Return the default hour cycle for a locale. Uses the locale that the
+ * UDateTimePatternGenerator was initially created with.
+ *
+ * Cannot be used on an empty UDateTimePatternGenerator instance.
+ *
* @param dtpg a pointer to UDateTimePatternGenerator.
* @param pErrorCode a pointer to the UErrorCode which must not indicate a
- * failure before the function call.
+ * failure before the function call. Set to U_UNSUPPORTED_ERROR
+ * if used on an empty instance.
* @return the default hour cycle.
* @draft ICU 67
*/
static void TestOptions(void);
static void TestGetFieldDisplayNames(void);
static void TestGetDefaultHourCycle(void);
+static void TestGetDefaultHourCycleOnEmptyInstance(void);
void addDateTimePatternGeneratorTest(TestNode** root) {
TESTCASE(TestOpenClose);
TESTCASE(TestOptions);
TESTCASE(TestGetFieldDisplayNames);
TESTCASE(TestGetDefaultHourCycle);
+ TESTCASE(TestGetDefaultHourCycleOnEmptyInstance);
}
/*
}
}
+// Ensure that calling udatpg_getDefaultHourCycle on an empty instance doesn't call UPRV_UNREACHABLE/abort.
+static void TestGetDefaultHourCycleOnEmptyInstance() {
+ UErrorCode status = U_ZERO_ERROR;
+ UDateTimePatternGenerator * dtpgen = udatpg_openEmpty(&status);
+
+ if (U_FAILURE(status)) {
+ log_data_err("ERROR udatpg_openEmpty failed, status: %s \n", myErrorName(status));
+ return;
+ }
+
+ (void)udatpg_getDefaultHourCycle(dtpgen, &status);
+ if (!U_FAILURE(status)) {
+ log_data_err("ERROR expected udatpg_getDefaultHourCycle on an empty instance to fail, status: %s", myErrorName(status));
+ }
+
+ status = U_USELESS_COLLATOR_ERROR;
+ (void)udatpg_getDefaultHourCycle(dtpgen, &status);
+ if (status != U_USELESS_COLLATOR_ERROR) {
+ log_data_err("ERROR udatpg_getDefaultHourCycle shouldn't modify status if it is already failed, status: %s", myErrorName(status));
+ }
+
+ udatpg_close(dtpgen);
+}
+
#endif
TESTCASE(7, testJjMapping);
TESTCASE(8, test20640_HourCyclArsEnNH);
TESTCASE(9, testFallbackWithDefaultRootLocale);
+ TESTCASE(10, testGetDefaultHourCycle_OnEmptyInstance);
default: name = ""; break;
}
}
}
}
+// ICU-21000 Ensure that calling getDefaultHourCycle on an empty instance doesn't call UPRV_UNREACHABLE/abort.
+void IntlTestDateTimePatternGeneratorAPI::testGetDefaultHourCycle_OnEmptyInstance() {
+ UErrorCode status = U_ZERO_ERROR;
+
+ LocalPointer<DateTimePatternGenerator> dtpg(DateTimePatternGenerator::createEmptyInstance(status), status);
+ if (U_FAILURE(status)) {
+ errln("ERROR: createEmptyInstance failed, status: %s", u_errorName(status));
+ return;
+ }
+ (void)dtpg->getDefaultHourCycle(status);
+ if (!U_FAILURE(status)) {
+ errln("ERROR: expected getDefaultHourCycle on an empty instance to fail, status: %s", u_errorName(status));
+ return;
+ }
+
+ status = U_USELESS_COLLATOR_ERROR;
+ (void)dtpg->getDefaultHourCycle(status);
+ if (status != U_USELESS_COLLATOR_ERROR) {
+ errln("ERROR: getDefaultHourCycle shouldn't modify status if it is already failed, status: %s", u_errorName(status));
+ return;
+ }
+}
+
#endif /* #if !UCONFIG_NO_FORMATTING */
void testJjMapping();
void test20640_HourCyclArsEnNH();
void testFallbackWithDefaultRootLocale();
+ void testGetDefaultHourCycle_OnEmptyInstance();
};
#endif /* #if !UCONFIG_NO_FORMATTING */