summaryrefslogtreecommitdiff
path: root/Meta/Lagom/Tools/CodeGenerators/LibUnicode
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-08-30 14:56:23 -0400
committerLinus Groh <mail@linusgroh.de>2021-09-01 14:14:47 +0100
commit9b118f1f0616108e2cdcf5ce52f03f862e92e508 (patch)
treea15a3fc4e846729df51aa55a82fa110afa12462e /Meta/Lagom/Tools/CodeGenerators/LibUnicode
parentd13142f015d1280c3486ee83e9492536c8e80910 (diff)
downloadserenity-9b118f1f0616108e2cdcf5ce52f03f862e92e508.zip
LibUnicode: Generate Unicode locale alias data
CLDR contains a set of aliases for languages, territories, etc. that no longer are meant to be used (e.g. due to deprecation). For example, the language "aam" is deprecated and should be canonicalized as "aas".
Diffstat (limited to 'Meta/Lagom/Tools/CodeGenerators/LibUnicode')
-rw-r--r--Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp83
1 files changed, 81 insertions, 2 deletions
diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp
index 651581b90b..20fd806cc4 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeLocale.cpp
@@ -37,6 +37,11 @@ struct UnicodeLocaleData {
Vector<String> scripts;
Vector<String> variants;
Vector<String> currencies;
+ HashMap<String, String> language_aliases;
+ HashMap<String, String> territory_aliases;
+ HashMap<String, String> script_aliases;
+ HashMap<String, String> variant_aliases;
+ HashMap<String, String> subdivision_aliases;
};
static void write_to_file_if_different(Core::File& file, StringView contents)
@@ -51,6 +56,36 @@ static void write_to_file_if_different(Core::File& file, StringView contents)
VERIFY(file.write(contents));
}
+static void parse_core_aliases(String core_supplemental_path, UnicodeLocaleData& locale_data)
+{
+ LexicalPath core_aliases_path(move(core_supplemental_path));
+ core_aliases_path = core_aliases_path.append("aliases.json"sv);
+ VERIFY(Core::File::exists(core_aliases_path.string()));
+
+ auto core_aliases_file_or_error = Core::File::open(core_aliases_path.string(), Core::OpenMode::ReadOnly);
+ VERIFY(!core_aliases_file_or_error.is_error());
+
+ auto core_aliases = JsonParser(core_aliases_file_or_error.value()->read_all()).parse();
+ VERIFY(core_aliases.has_value());
+
+ auto const& supplemental_object = core_aliases->as_object().get("supplemental"sv);
+ auto const& metadata_object = supplemental_object.as_object().get("metadata"sv);
+ auto const& alias_object = metadata_object.as_object().get("alias"sv);
+
+ auto append_aliases = [](auto& alias_object, auto& alias_map) {
+ alias_object.as_object().for_each_member([&](auto const& key, JsonValue const& value) {
+ auto alias = value.as_object().get("_replacement"sv).as_string();
+ alias_map.set(key, move(alias));
+ });
+ };
+
+ append_aliases(alias_object.as_object().get("languageAlias"sv), locale_data.language_aliases);
+ append_aliases(alias_object.as_object().get("territoryAlias"sv), locale_data.territory_aliases);
+ append_aliases(alias_object.as_object().get("scriptAlias"sv), locale_data.script_aliases);
+ append_aliases(alias_object.as_object().get("variantAlias"sv), locale_data.variant_aliases);
+ append_aliases(alias_object.as_object().get("subdivisionAlias"sv), locale_data.subdivision_aliases);
+}
+
static void parse_identity(String locale_path, UnicodeLocaleData& locale_data, Locale& locale)
{
LexicalPath languages_path(move(locale_path)); // Note: Every JSON file defines identity data, so we can use any of them.
@@ -195,11 +230,17 @@ static Core::DirIterator path_to_dir_iterator(String path)
return iterator;
}
-static void parse_all_locales(String locale_names_path, String numbers_path, UnicodeLocaleData& locale_data)
+static void parse_all_locales(String core_path, String locale_names_path, String numbers_path, UnicodeLocaleData& locale_data)
{
auto locale_names_iterator = path_to_dir_iterator(move(locale_names_path));
auto numbers_iterator = path_to_dir_iterator(move(numbers_path));
+ LexicalPath core_supplemental_path(move(core_path));
+ core_supplemental_path = core_supplemental_path.append("supplemental"sv);
+ VERIFY(Core::File::is_directory(core_supplemental_path.string()));
+
+ parse_core_aliases(core_supplemental_path.string(), locale_data);
+
while (locale_names_iterator.has_next()) {
auto locale_path = locale_names_iterator.next_full_path();
VERIFY(Core::File::is_directory(locale_path));
@@ -286,16 +327,22 @@ Optional<Locale> locale_from_string(StringView const& locale);
Optional<StringView> get_locale_language_mapping(StringView locale, StringView language);
Optional<Language> language_from_string(StringView const& language);
+Optional<StringView> resolve_language_alias(StringView const& language);
Optional<StringView> get_locale_territory_mapping(StringView locale, StringView territory);
Optional<Territory> territory_from_string(StringView const& territory);
+Optional<StringView> resolve_territory_alias(StringView const& territory);
Optional<StringView> get_locale_script_tag_mapping(StringView locale, StringView script_tag);
Optional<ScriptTag> script_tag_from_string(StringView const& script_tag);
+Optional<StringView> resolve_script_tag_alias(StringView const& script_tag);
Optional<StringView> get_locale_currency_mapping(StringView locale, StringView currency);
Optional<Currency> currency_from_string(StringView const& currency);
+Optional<StringView> resolve_variant_alias(StringView const& variant);
+Optional<StringView> resolve_subdivision_alias(StringView const& subdivision);
+
}
}
@@ -460,20 +507,52 @@ Optional<@enum_title@> @enum_snake@_from_string(StringView const& @enum_snake@)
)~~~");
};
+ auto append_alias_search = [&](StringView enum_snake, HashMap<String, String> const& aliases) {
+ generator.set("enum_snake", enum_snake);
+
+ generator.append(R"~~~(
+Optional<StringView> resolve_@enum_snake@_alias(StringView const& @enum_snake@)
+{
+ static HashMap<StringView, StringView> @enum_snake@_aliases { {)~~~");
+
+ for (auto const& alias : aliases) {
+ generator.set("key"sv, alias.key);
+ generator.set("alias"sv, alias.value);
+
+ generator.append(R"~~~(
+ { "@key@"sv, "@alias@"sv },)~~~");
+ }
+
+ generator.append(R"~~~(
+ } };
+
+ if (auto alias = @enum_snake@_aliases.get(@enum_snake@); alias.has_value())
+ return alias.value();
+ return {};
+}
+)~~~");
+ };
+
append_from_string("Locale"sv, "locale"sv, locale_data.locales.keys());
append_mapping_search("Language"sv, "language"sv, "s_languages"sv);
append_from_string("Language"sv, "language"sv, locale_data.languages);
+ append_alias_search("language"sv, locale_data.language_aliases);
append_mapping_search("Territory"sv, "territory"sv, "s_territories"sv);
append_from_string("Territory"sv, "territory"sv, locale_data.territories);
+ append_alias_search("territory"sv, locale_data.territory_aliases);
append_mapping_search("ScriptTag"sv, "script_tag"sv, "s_scripts"sv);
append_from_string("ScriptTag"sv, "script_tag"sv, locale_data.scripts);
+ append_alias_search("script_tag"sv, locale_data.script_aliases);
append_mapping_search("Currency"sv, "currency"sv, "s_currencies"sv);
append_from_string("Currency"sv, "currency"sv, locale_data.currencies);
+ append_alias_search("variant"sv, locale_data.variant_aliases);
+ append_alias_search("subdivision"sv, locale_data.subdivision_aliases);
+
generator.append(R"~~~(
}
@@ -519,7 +598,7 @@ int main(int argc, char** argv)
auto generated_implementation_file = open_file(generated_implementation_path, "-c/--generated-implementation-path", Core::OpenMode::ReadWrite);
UnicodeLocaleData locale_data;
- parse_all_locales(locale_names_path, numbers_path, locale_data);
+ parse_all_locales(core_path, locale_names_path, numbers_path, locale_data);
generate_unicode_locale_header(generated_header_file, locale_data);
generate_unicode_locale_implementation(generated_implementation_file, locale_data);