mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 13:32:45 +00:00 
			
		
		
		
	LibUnicode: Create a nearly empty generator for relative-time formatting
This sets up the generator plumbing to create the relative-time data files. This data could probably be included in the date-time generator, but that generator is large enough that I'd rather put this tangentially related data in its own file.
This commit is contained in:
		
							parent
							
								
									589e7354fb
								
							
						
					
					
						commit
						27eda77c97
					
				
					 3 changed files with 151 additions and 0 deletions
				
			
		|  | @ -2,3 +2,4 @@ lagom_tool(GenerateUnicodeData SOURCES GenerateUnicodeData.cpp LIBS LagomMain) | |||
| lagom_tool(GenerateUnicodeDateTimeFormat SOURCES GenerateUnicodeDateTimeFormat.cpp LIBS LagomMain LagomTimeZone) | ||||
| lagom_tool(GenerateUnicodeLocale SOURCES GenerateUnicodeLocale.cpp LIBS LagomMain) | ||||
| lagom_tool(GenerateUnicodeNumberFormat SOURCES GenerateUnicodeNumberFormat.cpp LIBS LagomMain) | ||||
| lagom_tool(GenerateUnicodeRelativeTimeFormat SOURCES GenerateUnicodeRelativeTimeFormat.cpp LIBS LagomMain) | ||||
|  |  | |||
|  | @ -0,0 +1,133 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2022, Tim Flynn <trflynn89@pm.me> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
| 
 | ||||
| #include "GeneratorUtil.h" | ||||
| #include <AK/Format.h> | ||||
| #include <AK/HashMap.h> | ||||
| #include <AK/JsonObject.h> | ||||
| #include <AK/JsonParser.h> | ||||
| #include <AK/JsonValue.h> | ||||
| #include <AK/LexicalPath.h> | ||||
| #include <AK/SourceGenerator.h> | ||||
| #include <AK/String.h> | ||||
| #include <AK/StringBuilder.h> | ||||
| #include <LibCore/ArgsParser.h> | ||||
| #include <LibCore/DirIterator.h> | ||||
| #include <LibCore/File.h> | ||||
| 
 | ||||
| using StringIndexType = u16; | ||||
| constexpr auto s_string_index_type = "u16"sv; | ||||
| 
 | ||||
| struct Locale { | ||||
| }; | ||||
| 
 | ||||
| struct UnicodeLocaleData { | ||||
|     UniqueStringStorage<StringIndexType> unique_strings; | ||||
|     HashMap<String, Locale> locales; | ||||
| }; | ||||
| 
 | ||||
| static ErrorOr<void> 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<String> { | ||||
|         auto parsed_locale = TRY(CanonicalLanguageID<StringIndexType>::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 <LibUnicode/Forward.h> | ||||
| 
 | ||||
| namespace Unicode { | ||||
| )~~~"); | ||||
| 
 | ||||
|     generator.append(R"~~~( | ||||
| } | ||||
| )~~~"); | ||||
| 
 | ||||
|     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 <AK/Array.h> | ||||
| #include <AK/StringView.h> | ||||
| #include <LibUnicode/UnicodeRelativeTimeFormat.h> | ||||
| 
 | ||||
| namespace Unicode { | ||||
| )~~~"); | ||||
| 
 | ||||
|     locale_data.unique_strings.generate(generator); | ||||
| 
 | ||||
|     generator.append(R"~~~( | ||||
| } | ||||
| )~~~"); | ||||
| 
 | ||||
|     VERIFY(file.write(generator.as_string_view())); | ||||
| } | ||||
| 
 | ||||
| ErrorOr<int> 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<NonnullRefPtr<Core::File>> { | ||||
|         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; | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Timothy Flynn
						Timothy Flynn