diff --git a/Meta/CMake/unicode_data.cmake b/Meta/CMake/unicode_data.cmake index bbb84b479f7..c041577ef54 100644 --- a/Meta/CMake/unicode_data.cmake +++ b/Meta/CMake/unicode_data.cmake @@ -52,6 +52,9 @@ set(CLDR_ZIP_PATH "${CLDR_PATH}/cldr.zip") set(CLDR_CORE_SOURCE cldr-core) set(CLDR_CORE_PATH "${CLDR_PATH}/${CLDR_CORE_SOURCE}") +set(CLDR_DATES_SOURCE cldr-dates-modern) +set(CLDR_DATES_PATH "${CLDR_PATH}/${CLDR_DATES_SOURCE}") + set(CLDR_LOCALES_SOURCE cldr-localenames-modern) set(CLDR_LOCALES_PATH "${CLDR_PATH}/${CLDR_LOCALES_SOURCE}") @@ -140,6 +143,7 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) endif() extract_cldr_file("${CLDR_CORE_SOURCE}" "${CLDR_CORE_PATH}") + extract_cldr_file("${CLDR_DATES_SOURCE}" "${CLDR_DATES_PATH}") extract_cldr_file("${CLDR_LOCALES_SOURCE}" "${CLDR_LOCALES_PATH}") extract_cldr_file("${CLDR_MISC_SOURCE}" "${CLDR_MISC_PATH}") extract_cldr_file("${CLDR_NUMBERS_SOURCE}" "${CLDR_NUMBERS_PATH}") @@ -148,6 +152,9 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) set(UNICODE_DATA_HEADER LibUnicode/UnicodeData.h) set(UNICODE_DATA_IMPLEMENTATION LibUnicode/UnicodeData.cpp) + set(UNICODE_DATE_TIME_FORMAT_HEADER LibUnicode/UnicodeDateTimeFormat.h) + set(UNICODE_DATE_TIME_FORMAT_IMPLEMENTATION LibUnicode/UnicodeDateTimeFormat.cpp) + set(UNICODE_LOCALE_HEADER LibUnicode/UnicodeLocale.h) set(UNICODE_LOCALE_IMPLEMENTATION LibUnicode/UnicodeLocale.cpp) @@ -160,6 +167,9 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) set(UNICODE_DATA_HEADER UnicodeData.h) set(UNICODE_DATA_IMPLEMENTATION UnicodeData.cpp) + set(UNICODE_DATE_TIME_FORMAT_HEADER UnicodeDateTimeFormat.h) + set(UNICODE_DATE_TIME_FORMAT_IMPLEMENTATION UnicodeDateTimeFormat.cpp) + set(UNICODE_LOCALE_HEADER UnicodeLocale.h) set(UNICODE_LOCALE_IMPLEMENTATION UnicodeLocale.cpp) @@ -176,6 +186,13 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) "${UNICODE_DATA_IMPLEMENTATION}" arguments -u "${UNICODE_DATA_PATH}" -s "${SPECIAL_CASING_PATH}" -g "${DERIVED_GENERAL_CATEGORY_PATH}" -p "${PROP_LIST_PATH}" -d "${DERIVED_CORE_PROP_PATH}" -b "${DERIVED_BINARY_PROP_PATH}" -a "${PROP_ALIAS_PATH}" -v "${PROP_VALUE_ALIAS_PATH}" -r "${SCRIPTS_PATH}" -x "${SCRIPT_EXTENSIONS_PATH}" -e "${EMOJI_DATA_PATH}" -m "${NAME_ALIAS_PATH}" -n "${NORM_PROPS_PATH}" ) + invoke_generator( + "UnicodeDateTimeFormat" + Lagom::GenerateUnicodeDateTimeFormat + "${UNICODE_DATE_TIME_FORMAT_HEADER}" + "${UNICODE_DATE_TIME_FORMAT_IMPLEMENTATION}" + arguments -d "${CLDR_DATES_PATH}" + ) invoke_generator( "UnicodeLocale" Lagom::GenerateUnicodeLocale @@ -194,6 +211,8 @@ if (ENABLE_UNICODE_DATABASE_DOWNLOAD) set(UNICODE_DATA_SOURCES ${UNICODE_DATA_HEADER} ${UNICODE_DATA_IMPLEMENTATION} + ${UNICODE_DATE_TIME_FORMAT_HEADER} + ${UNICODE_DATE_TIME_FORMAT_IMPLEMENTATION} ${UNICODE_LOCALE_HEADER} ${UNICODE_LOCALE_IMPLEMENTATION} ${UNICODE_NUMBER_FORMAT_HEADER} diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/CMakeLists.txt b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/CMakeLists.txt index 4aa8417fc3e..ca6301ea113 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/CMakeLists.txt +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/CMakeLists.txt @@ -1,3 +1,4 @@ lagom_tool(GenerateUnicodeData SOURCES GenerateUnicodeData.cpp LIBS LagomMain) +lagom_tool(GenerateUnicodeDateTimeFormat SOURCES GenerateUnicodeDateTimeFormat.cpp LIBS LagomMain) lagom_tool(GenerateUnicodeLocale SOURCES GenerateUnicodeLocale.cpp LIBS LagomMain) lagom_tool(GenerateUnicodeNumberFormat SOURCES GenerateUnicodeNumberFormat.cpp LIBS LagomMain) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp new file mode 100644 index 00000000000..3ddb372d42a --- /dev/null +++ b/Meta/Lagom/Tools/CodeGenerators/LibUnicode/GenerateUnicodeDateTimeFormat.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include "GeneratorUtil.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using StringIndexType = u16; +constexpr auto s_string_index_type = "u16"sv; + +struct Locale { +}; + +struct UnicodeLocaleData { + UniqueStringStorage unique_strings; + HashMap locales; +}; + +static ErrorOr parse_all_locales(String dates_path, UnicodeLocaleData& locale_data) +{ + auto dates_iterator = TRY(path_to_dir_iterator(move(dates_path))); + + auto remove_variants_from_path = [&](String path) -> ErrorOr { + auto parsed_locale = TRY(CanonicalLanguageID::parse(locale_data.unique_strings, LexicalPath::basename(path))); + + StringBuilder builder; + builder.append(locale_data.unique_strings.get(parsed_locale.language)); + if (auto script = locale_data.unique_strings.get(parsed_locale.script); !script.is_empty()) + builder.appendff("-{}", script); + if (auto region = locale_data.unique_strings.get(parsed_locale.region); !region.is_empty()) + builder.appendff("-{}", region); + + return builder.build(); + }; + + while (dates_iterator.has_next()) { + auto dates_path = TRY(next_path_from_dir_iterator(dates_iterator)); + auto language = TRY(remove_variants_from_path(dates_path)); + + [[maybe_unused]] auto& locale = locale_data.locales.ensure(language); + } + + return {}; +} + +static void generate_unicode_locale_header(Core::File& file, UnicodeLocaleData&) +{ + StringBuilder builder; + SourceGenerator generator { builder }; + + generator.append(R"~~~( +#pragma once + +#include +#include + +namespace Unicode { +} +)~~~"); + + VERIFY(file.write(generator.as_string_view())); +} + +static void generate_unicode_locale_implementation(Core::File& file, UnicodeLocaleData& locale_data) +{ + StringBuilder builder; + SourceGenerator generator { builder }; + generator.set("string_index_type"sv, s_string_index_type); + + generator.append(R"~~~( +#include +#include + +namespace Unicode::Detail { +)~~~"); + + locale_data.unique_strings.generate(generator); + + generator.append(R"~~~( +} +)~~~"); + + VERIFY(file.write(generator.as_string_view())); +} + +ErrorOr serenity_main(Main::Arguments arguments) +{ + StringView generated_header_path; + StringView generated_implementation_path; + StringView dates_path; + + Core::ArgsParser args_parser; + args_parser.add_option(generated_header_path, "Path to the Unicode locale header file to generate", "generated-header-path", 'h', "generated-header-path"); + args_parser.add_option(generated_implementation_path, "Path to the Unicode locale implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path"); + args_parser.add_option(dates_path, "Path to cldr-dates directory", "dates-path", 'd', "dates-path"); + args_parser.parse(arguments); + + auto open_file = [&](StringView path) -> ErrorOr> { + if (path.is_empty()) { + args_parser.print_usage(stderr, arguments.argv[0]); + return Error::from_string_literal("Must provide all command line options"sv); + } + + return Core::File::open(path, Core::OpenMode::ReadWrite); + }; + + auto generated_header_file = TRY(open_file(generated_header_path)); + auto generated_implementation_file = TRY(open_file(generated_implementation_path)); + + UnicodeLocaleData locale_data; + TRY(parse_all_locales(dates_path, locale_data)); + + generate_unicode_locale_header(generated_header_file, locale_data); + generate_unicode_locale_implementation(generated_implementation_file, locale_data); + + return 0; +}