From 8aeacccd82208ef3f74c41739978251b12a00ac8 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Thu, 7 Jul 2022 12:05:05 -0400 Subject: [PATCH] LibUnicode: Generate a list of available plural categories per locale Separate lists are generated for cardinal and ordinal form. --- .../LibUnicode/GenerateUnicodePluralRules.cpp | 45 +++++++++++++++++++ Userland/Libraries/LibUnicode/PluralRules.cpp | 6 +++ Userland/Libraries/LibUnicode/PluralRules.h | 1 + 3 files changed, 52 insertions(+) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodePluralRules.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodePluralRules.cpp index 3b8fdc818d..8582b786f3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodePluralRules.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodePluralRules.cpp @@ -503,6 +503,21 @@ static constexpr Array s_@form@_functions { {)~~ )~~~"); }; + auto append_categories = [&](auto const& name, auto const& rules) { + generator.set("name", name); + generator.set("size", String::number(rules.size() + 1)); + + generator.append(R"~~~( +static constexpr Array @name@ { { PluralCategory::Other)~~~"); + + for (auto [category, condition] : rules) { + generator.set("category"sv, format_identifier({}, category)); + generator.append(", PluralCategory::@category@"sv); + } + + generator.append("} };"); + }; + append_string_conversions("PluralCategory"sv, "plural_category"sv, locale_data.categories); for (auto [locale, rules] : locale_data.locales) { @@ -513,6 +528,18 @@ static constexpr Array s_@form@_functions { {)~~ append_lookup_table("cardinal"sv); append_lookup_table("ordinal"sv); + generate_mapping(generator, locales, "PluralCategory"sv, "s_cardinal_categories"sv, "s_cardinal_categories_{}", format_identifier, + [&](auto const& name, auto const& locale) { + auto& rules = locale_data.locales.find(locale)->value; + append_categories(name, rules.rules_for_form("cardinal"sv)); + }); + + generate_mapping(generator, locales, "PluralCategory"sv, "s_ordinal_categories"sv, "s_ordinal_categories_{}", format_identifier, + [&](auto const& name, auto const& locale) { + auto& rules = locale_data.locales.find(locale)->value; + append_categories(name, rules.rules_for_form("ordinal"sv)); + }); + generator.append(R"~~~( PluralCategory determine_plural_category(StringView locale, PluralForm form, PluralOperands operands) { @@ -535,6 +562,24 @@ PluralCategory determine_plural_category(StringView locale, PluralForm form, Plu return decider(move(operands)); } +Span available_plural_categories(StringView locale, PluralForm form) +{ + auto locale_value = locale_from_string(locale); + if (!locale_value.has_value()) + return {}; + + auto locale_index = to_underlying(*locale_value) - 1; // Subtract 1 because 0 == Locale::None. + + switch (form) { + case PluralForm::Cardinal: + return s_cardinal_categories[locale_index]; + case PluralForm::Ordinal: + return s_ordinal_categories[locale_index]; + } + + VERIFY_NOT_REACHED(); +} + } )~~~"); diff --git a/Userland/Libraries/LibUnicode/PluralRules.cpp b/Userland/Libraries/LibUnicode/PluralRules.cpp index a4b8a58a7f..285a49e006 100644 --- a/Userland/Libraries/LibUnicode/PluralRules.cpp +++ b/Userland/Libraries/LibUnicode/PluralRules.cpp @@ -56,4 +56,10 @@ PluralCategory __attribute__((weak)) determine_plural_category(StringView, Plura return PluralCategory::Other; } +Span __attribute__((weak)) available_plural_categories(StringView, PluralForm) +{ + static constexpr Array categories { { PluralCategory::Other } }; + return categories.span(); +} + } diff --git a/Userland/Libraries/LibUnicode/PluralRules.h b/Userland/Libraries/LibUnicode/PluralRules.h index d67f95b805..f56e72321c 100644 --- a/Userland/Libraries/LibUnicode/PluralRules.h +++ b/Userland/Libraries/LibUnicode/PluralRules.h @@ -61,5 +61,6 @@ Optional plural_category_from_string(StringView category); StringView plural_category_to_string(PluralCategory category); PluralCategory determine_plural_category(StringView locale, PluralForm form, PluralOperands operands); +Span available_plural_categories(StringView locale, PluralForm form); }