mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibUnicode: Print error codes when calls to ICU fail
Primary motivation for this change is the `VERIFY(icu_success(status))` line in `Segmenter::create()` that was failing on multiple systems and where we had to ask people to apply a patch to even know what the error was. Since this seems to be a recurring problem, let's just add a little helper function and print the error codes returned by library calls.
This commit is contained in:
committed by
Tim Flynn
parent
77a3de4561
commit
1b2bca7831
Notes:
github-actions[bot]
2026-02-21 21:56:43 +00:00
Author: https://github.com/InvalidUsernameException Commit: https://github.com/LadybirdBrowser/ladybird/commit/1b2bca7831d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8068 Reviewed-by: https://github.com/trflynn89
@@ -45,7 +45,7 @@ static NonnullOwnPtr<icu::Locale> apply_usage_to_locale(icu::Locale const& local
|
||||
break;
|
||||
}
|
||||
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ static Sensitivity sensitivity_for_collator(icu::Collator const& collator)
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
auto attribute = collator.getAttribute(UCOL_STRENGTH, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
switch (attribute) {
|
||||
case UCOL_PRIMARY:
|
||||
attribute = collator.getAttribute(UCOL_CASE_LEVEL, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return attribute == UCOL_ON ? Sensitivity::Case : Sensitivity::Base;
|
||||
|
||||
@@ -156,7 +156,7 @@ static bool ignore_punctuation_for_collator(icu::Collator const& collator)
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
auto attribute = collator.getAttribute(UCOL_ALTERNATE_HANDLING, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return attribute == UCOL_SHIFTED;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ public:
|
||||
auto rhs_it = icu_string_iterator(rhs);
|
||||
|
||||
auto result = m_collator->compare(lhs_it, rhs_it, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
switch (result) {
|
||||
case UCOL_LESS:
|
||||
@@ -221,11 +221,11 @@ NonnullOwnPtr<Collator> Collator::create(
|
||||
auto locale_with_usage = apply_usage_to_locale(locale_data->locale(), usage, collation);
|
||||
|
||||
auto collator = adopt_own(*icu::Collator::createInstance(*locale_with_usage, status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
auto set_attribute = [&](UColAttribute attribute, UColAttributeValue value) {
|
||||
collator->setAttribute(attribute, value, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
};
|
||||
|
||||
if (!sensitivity.has_value())
|
||||
|
||||
@@ -625,7 +625,7 @@ static void apply_time_zone_to_formatter(icu::SimpleDateFormat& formatter, icu::
|
||||
auto time_zone_data = TimeZoneData::for_time_zone(time_zone_identifier);
|
||||
|
||||
auto* calendar = icu::Calendar::createInstance(time_zone_data->time_zone(), locale, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
if (calendar->getDynamicClassID() == icu::GregorianCalendar::getStaticClassID()) {
|
||||
// https://tc39.es/ecma262/#sec-time-values-and-time-range
|
||||
@@ -634,7 +634,7 @@ static void apply_time_zone_to_formatter(icu::SimpleDateFormat& formatter, icu::
|
||||
|
||||
auto* gregorian_calendar = static_cast<icu::GregorianCalendar*>(calendar);
|
||||
gregorian_calendar->setGregorianChange(ECMA_262_MINIMUM_TIME, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
formatter.adoptCalendar(calendar);
|
||||
@@ -903,16 +903,16 @@ NonnullOwnPtr<DateTimeFormat> DateTimeFormat::create_for_date_and_time_style(
|
||||
formatter->toPattern(pattern);
|
||||
|
||||
auto skeleton = icu::DateTimePatternGenerator::staticGetSkeleton(pattern, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
if (apply_hour_cycle_to_skeleton(skeleton, hour_cycle, hour12)) {
|
||||
pattern = locale_data->date_time_pattern_generator().getBestPattern(skeleton, UDATPG_MATCH_ALL_FIELDS_LENGTH, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
apply_hour_cycle_to_skeleton(pattern, hour_cycle, hour12);
|
||||
|
||||
formatter = adopt_own(*new icu::SimpleDateFormat(pattern, locale_data->locale(), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
return adopt_own(*new DateTimeFormatImpl(locale_data->locale(), pattern, time_zone_identifier, move(formatter)));
|
||||
@@ -930,12 +930,12 @@ NonnullOwnPtr<DateTimeFormat> DateTimeFormat::create_for_pattern_options(
|
||||
|
||||
auto skeleton = icu_string(options.to_pattern());
|
||||
auto pattern = locale_data->date_time_pattern_generator().getBestPattern(skeleton, UDATPG_MATCH_ALL_FIELDS_LENGTH, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
apply_hour_cycle_to_skeleton(pattern, options.hour_cycle, {});
|
||||
|
||||
auto formatter = adopt_own(*new icu::SimpleDateFormat(pattern, locale_data->locale(), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return adopt_own(*new DateTimeFormatImpl(locale_data->locale(), pattern, time_zone_identifier, move(formatter)));
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ String LocaleData::to_string()
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
auto result = locale().toLanguageTag<StringBuilder>(status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
m_locale_string = MUST(result.to_string());
|
||||
}
|
||||
@@ -83,7 +83,7 @@ icu::NumberingSystem& LocaleData::numbering_system()
|
||||
status = U_ZERO_ERROR;
|
||||
|
||||
m_numbering_system = adopt_own_if_nonnull(icu::NumberingSystem::createInstance("und", status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ icu::DateTimePatternGenerator& LocaleData::date_time_pattern_generator()
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
m_date_time_pattern_generator = adopt_own(*icu::DateTimePatternGenerator::createInstance(locale(), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
return *m_date_time_pattern_generator;
|
||||
@@ -108,7 +108,7 @@ icu::TimeZoneNames& LocaleData::time_zone_names()
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
m_time_zone_names = adopt_own(*icu::TimeZoneNames::createInstance(locale(), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
return *m_time_zone_names;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/SourceLocation.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringView.h>
|
||||
#include <AK/Utf16String.h>
|
||||
@@ -89,6 +90,14 @@ constexpr bool icu_failure(UErrorCode code)
|
||||
return static_cast<bool>(U_FAILURE(code));
|
||||
}
|
||||
|
||||
inline void verify_icu_success(UErrorCode code, SourceLocation location = SourceLocation::current())
|
||||
{
|
||||
if (icu_failure(code)) [[unlikely]] {
|
||||
dbgln("\033[31;1mICU error\033[0m: {} {}", u_errorName(code), location);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
ALWAYS_INLINE icu::StringPiece icu_string_piece(StringView string)
|
||||
{
|
||||
return { string.characters_without_null_termination(), static_cast<i32>(string.length()) };
|
||||
|
||||
@@ -149,7 +149,7 @@ NonnullOwnPtr<ListFormat> ListFormat::create(StringView locale, ListFormatType t
|
||||
VERIFY(locale_data.has_value());
|
||||
|
||||
auto formatter = adopt_own(*icu::ListFormatter::createInstance(locale_data->locale(), icu_list_format_type(type), icu_list_format_width(style), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return adopt_own(*new ListFormatImpl(move(formatter)));
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@ String canonicalize_unicode_locale_id(StringView locale)
|
||||
VERIFY(locale_data.has_value());
|
||||
|
||||
locale_data->locale().canonicalize(status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return locale_data->to_string();
|
||||
}
|
||||
@@ -497,13 +497,13 @@ String canonicalize_unicode_extension_values(StringView key, StringView value)
|
||||
builder.setUnicodeLocaleKeyword(icu_string_piece(key), icu_string_piece(value));
|
||||
|
||||
auto locale = builder.build(status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
locale.canonicalize(status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
auto result = locale.getUnicodeKeywordValue<StringBuilder>(icu_string_piece(key), status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return MUST(result.to_string());
|
||||
}
|
||||
@@ -602,7 +602,7 @@ static void apply_extensions_to_locale(icu::Locale& locale, icu::Locale const& l
|
||||
builder.setVariant(locale.getVariant());
|
||||
|
||||
locale = builder.build(status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
Optional<String> add_likely_subtags(StringView locale)
|
||||
|
||||
@@ -441,13 +441,13 @@ static void apply_display_options(icu::number::LocalizedNumberFormatter& formatt
|
||||
case NumberFormatStyle::Currency:
|
||||
formatter = formatter.unit(icu::CurrencyUnit(icu_string_piece(*display_options.currency), status));
|
||||
formatter = formatter.unitWidth(icu_currency_display(*display_options.currency_display));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
break;
|
||||
|
||||
case NumberFormatStyle::Unit:
|
||||
formatter = formatter.unit(icu::MeasureUnit::forIdentifier(icu_string_piece(*display_options.unit), status));
|
||||
formatter = formatter.unitWidth(icu_unit_width(*display_options.unit_display));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -655,7 +655,7 @@ public:
|
||||
VERIFY(!m_plural_rules);
|
||||
|
||||
m_plural_rules = adopt_own(*icu::PluralRules::forLocale(m_locale, icu_plural_type(plural_form), status));
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
}
|
||||
|
||||
virtual PluralCategory select_plural(Value const& value) const override
|
||||
@@ -730,7 +730,7 @@ private:
|
||||
auto formattable = value.visit(
|
||||
[&](double number) { return icu::Formattable { number }; },
|
||||
[&](String const& number) { return icu::Formattable(icu_string_piece(number), status); });
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return formattable;
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ NonnullOwnPtr<RelativeTimeFormat> RelativeTimeFormat::create(StringView locale,
|
||||
static_cast<icu::DecimalFormat&>(*number_formatter).setMinimumGroupingDigits(UNUM_MINIMUM_GROUPING_DIGITS_AUTO);
|
||||
|
||||
auto formatter = make<icu::RelativeDateTimeFormatter>(locale_data->locale(), number_formatter, icu_relative_date_time_style(style), UDISPCTX_CAPITALIZATION_NONE, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return make<RelativeTimeFormatImpl>(move(formatter));
|
||||
}
|
||||
|
||||
@@ -155,10 +155,10 @@ public:
|
||||
|
||||
UText utext = UTEXT_INITIALIZER;
|
||||
utext_openUTF8(&utext, view.characters_without_null_termination(), static_cast<i64>(view.length()), &status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
m_segmenter->setText(&utext, status);
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
utext_close(&utext);
|
||||
}
|
||||
@@ -334,7 +334,7 @@ NonnullOwnPtr<Segmenter> Segmenter::create(StringView locale, SegmenterGranulari
|
||||
VERIFY_NOT_REACHED();
|
||||
}());
|
||||
|
||||
VERIFY(icu_success(status));
|
||||
verify_icu_success(status);
|
||||
|
||||
return make<SegmenterImpl>(segmenter.release_nonnull(), segmenter_granularity);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user